kodadot/nft-gallery

View on GitHub
components/shared/TransactionSteps/TransactionSteps.vue

Summary

Maintainability
Test Coverage
<template>
  <div>
    <TransactionStepsItem
      v-for="(step, index) in stepsWithActive"
      :key="index"
      class="mb-5"
      :step="getStepItem(step)"
      with-action
      @try-again="tryAgain(step)"
    />
  </div>
</template>

<script setup lang="ts">
import { type Prefix } from '@kodadot1/static'
import TransactionStepsItem, {
  type TransactionStepItem,
} from './TransactionStepsItem.vue'
import { TransactionStepStatus, getTransactionStepDetails } from './utils'
import { TransactionStatus } from '@/composables/useTransactionStatus'

export type TransactionStep = {
  txId?: string | null
  blockNumber?: string | null
  isError?: boolean
  status?: TransactionStatus
  stepStatus?: TransactionStepStatus
  title: string
  tooltip?: string
  prefix?: Prefix
  retry?: () => void
  stepStatusTextOverride?: Partial<Record<TransactionStepStatus, string>>
}

export type TransactionStepWithActive = TransactionStep & {
  isActive: boolean
}

const emit = defineEmits(['active'])
const props = defineProps<{
  steps: TransactionStep[]
}>()

const { $i18n } = useNuxtApp()

const stepsWithActive = computed<TransactionStepWithActive[]>(() =>
  props.steps.map((step, index, array) => {
    const prevStep = array[index - 1]
    const isStepStatusCompleted
      = prevStep && prevStep.stepStatus === TransactionStepStatus.COMPLETED
    const isStatusFinalized
      = prevStep && prevStep.status === TransactionStatus.Finalized

    return {
      ...step,
      isActive: index === 0 || isStepStatusCompleted || isStatusFinalized,
    }
  }),
)

watch(
  stepsWithActive,
  () => {
    const index = stepsWithActive.value.findLastIndex(step => step.isActive)
    emit('active', index)
  },
  { immediate: true },
)

const tryAgain = (step: TransactionStepWithActive) => {
  if (step.retry) {
    step.retry()
  }
}

const getStepItem = (step: TransactionStepWithActive): TransactionStepItem => {
  const baseStep = {
    txId: step.txId as string | null,
    blockNumber: step.blockNumber as string | null,
    isError: step.isError,
    prefix: step.prefix,
    isActive: step.isActive,
    tooltip: step.tooltip,
  }

  const { status, text } = getTransactionStepDetails(step, $i18n.t)
  let tsxText = text

  const withCustomSubtitle = step.stepStatusTextOverride && status in step.stepStatusTextOverride

  if (withCustomSubtitle) {
    tsxText = step.stepStatusTextOverride?.[status] || ''
  }

  return {
    ...baseStep,
    status: step.stepStatus ? step.stepStatus : status,
    title: step.title,
    subtitle: tsxText,
    withCustomSubtitle,
  }
}
</script>