刘光辉
8 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<script setup lang="ts">
import type { StepProgress } from '../domain/types';
 
import { ArrowLeftOutlined, CheckCircleFilled, ClockCircleOutlined, ExclamationCircleFilled, SearchOutlined } from '@ant-design/icons-vue';
import { computed, ref } from 'vue';
 
import { STEP_PROGRESS_LABELS } from '../domain/types';
 
const props = defineProps<{
  currentStepId: null | string;
  progress: StepProgress[];
}>();
const emit = defineEmits<{ close: []; select: [stepId: string] }>();
 
const search = ref('');
const items = computed(() => {
  const query = search.value.trim().toLocaleLowerCase();
  return props.progress
    .filter(({ step }) => !query || step.name.toLocaleLowerCase().includes(query))
    .sort((left, right) => left.step.order - right.step.order || left.step.id.localeCompare(right.step.id));
});
 
const counts = computed(() => ({
  complete: props.progress.filter((item) => item.status === 'complete').length,
  problem: props.progress.filter((item) => item.status === 'problem').length,
  total: props.progress.length,
}));
</script>
 
<template>
  <section class="step-directory" aria-label="填写目录">
    <div class="directory-summary">
      <a-tooltip title="返回当前步骤">
        <a-button type="text" size="small" aria-label="返回当前步骤" @click="emit('close')">
          <template #icon><ArrowLeftOutlined /></template>
        </a-button>
      </a-tooltip>
      <strong>填写目录</strong>
      <span>{{ counts.complete }}/{{ counts.total }} 已完整</span>
      <span v-if="counts.problem" class="directory-problem">{{ counts.problem }} 个问题</span>
    </div>
    <a-input v-model:value="search" allow-clear aria-label="搜索步骤" placeholder="搜索步骤">
      <template #prefix><SearchOutlined /></template>
    </a-input>
 
    <a-empty v-if="!items.length" :image="false" description="没有匹配的步骤" />
    <div v-else class="directory-steps">
      <button
        v-for="item in items"
        :key="item.step.id"
        type="button"
        class="directory-step"
        :class="{ 'directory-step-current': item.step.id === currentStepId }"
        :data-step-id="item.step.id"
        @click="emit('select', item.step.id)">
        <CheckCircleFilled v-if="item.status === 'complete'" class="status-complete" />
        <ExclamationCircleFilled v-else-if="item.status === 'problem'" class="status-problem" />
        <ClockCircleOutlined v-else class="status-progress" />
        <span class="directory-step-name">{{ item.step.name }}</span>
        <a-tag v-if="item.step.id === currentStepId" color="blue">当前</a-tag>
        <span class="directory-step-status">{{ STEP_PROGRESS_LABELS[item.status] }}</span>
      </button>
    </div>
  </section>
</template>