main
vue 98 lines 3.1 KB
Raw
1 <template>
2 <n-card size="small" title="Recent reviews" embedded>
3 <p v-if="!stats.recent_reviews.length" class="text-sm">No reviews yet.</p>
4 <div v-else class="flex flex-col gap-2">
5 <CardEntity
6 v-for="r of stats.recent_reviews"
7 :key="r.id"
8 size="small"
9 hoverable
10 clickable
11 @click="openDrawer(r)"
12 >
13 <template #headerMain>
14 Report #{{ r.report_id }}
15 <span v-if="r.template_used" class="text-secondary ml-2 text-sm">· {{ r.template_used }}</span>
16 </template>
17 <template #headerExtra>
18 <span class="text-secondary text-sm">
19 {{ formatDate(r.updated_at ?? r.created_at, "MMM D, YYYY HH:mm") }}
20 </span>
21 </template>
22 <template #default>
23 <div class="flex flex-wrap items-center gap-3">
24 <Badge
25 v-if="r.overall_verdict"
26 type="splitted"
27 bright
28 :color="r.overall_verdict === 'up' ? 'success' : 'danger'"
29 >
30 <template #label>Verdict</template>
31 <template #value>
32 {{ r.overall_verdict === "up" ? "Up" : "Down" }}
33 </template>
34 </Badge>
35 <Badge
36 v-if="r.template_choice"
37 type="splitted"
38 bright
39 :color="tplChoiceColor(r.template_choice)"
40 >
41 <template #label>Template</template>
42 <template #value>{{ r.template_choice }}</template>
43 </Badge>
44 <Badge v-if="r.rating_instructions" type="splitted">
45 <template #label>Instr</template>
46 <template #value>{{ r.rating_instructions }}/5</template>
47 </Badge>
48 <Badge v-if="r.rating_artifacts" type="splitted">
49 <template #label>Artifacts</template>
50 <template #value>{{ r.rating_artifacts }}/5</template>
51 </Badge>
52 <Badge v-if="r.rating_severity" type="splitted">
53 <template #label>Severity</template>
54 <template #value>{{ r.rating_severity }}/5</template>
55 </Badge>
56 <Badge v-if="r.ioc_reviews.length" type="splitted">
57 <template #label>IOC corrections</template>
58 <template #value>{{ r.ioc_reviews.length }}</template>
59 </Badge>
60 </div>
61 </template>
62 </CardEntity>
63 </div>
64
65 <FeedbackDashboardRecentReviewDetail v-model:show="showDrawer" :review="drawerReview" />
66 </n-card>
67 </template>
68
69 <script setup lang="ts">
70 import type { AiAnalystReview, AiAnalystReviewStats } from "@/types/aiAnalyst.d"
71 import { NCard } from "naive-ui"
72 import { ref, toRefs } from "vue"
73 import Badge from "@/components/common/Badge.vue"
74 import CardEntity from "@/components/common/cards/CardEntity.vue"
75 import { formatDate } from "@/utils/format"
76 import FeedbackDashboardRecentReviewDetail from "./FeedbackDashboardRecentReviewDetail.vue"
77
78 const props = defineProps<{
79 stats: AiAnalystReviewStats
80 }>()
81
82 const { stats } = toRefs(props)
83
84 const showDrawer = ref(false)
85 const drawerReview = ref<AiAnalystReview | null>(null)
86
87 function tplChoiceColor(choice: string): "success" | "warning" | "danger" | undefined {
88 if (choice === "correct") return "success"
89 if (choice === "partial") return "warning"
90 if (choice === "wrong") return "danger"
91 return undefined
92 }
93
94 function openDrawer(r: AiAnalystReview) {
95 drawerReview.value = r
96 showDrawer.value = true
97 }
98 </script>