| 1 | <template> |
| 2 | <div class="flex flex-col gap-3"> |
| 3 | <div class="flex flex-wrap items-center gap-2"> |
| 4 | <Badge v-if="report.severity_assessment" type="splitted" bright :color="severityColor"> |
| 5 | <template #label>Severity</template> |
| 6 | <template #value>{{ report.severity_assessment }}</template> |
| 7 | </Badge> |
| 8 | <Badge type="splitted"> |
| 9 | <template #label>Report</template> |
| 10 | <template #value>#{{ report.id }}</template> |
| 11 | </Badge> |
| 12 | <Badge type="splitted"> |
| 13 | <template #label>Created</template> |
| 14 | <template #value>{{ formatDate(report.created_at, "MMM D, YYYY HH:mm") }}</template> |
| 15 | </Badge> |
| 16 | </div> |
| 17 | |
| 18 | <CardKV v-if="report.summary"> |
| 19 | <template #key>Summary</template> |
| 20 | <template #value>{{ report.summary }}</template> |
| 21 | </CardKV> |
| 22 | |
| 23 | <CardKV v-if="report.recommended_actions"> |
| 24 | <template #key>Recommended actions</template> |
| 25 | <template #value>{{ report.recommended_actions }}</template> |
| 26 | </CardKV> |
| 27 | |
| 28 | <n-button text size="large" @click="showFullReport = !showFullReport"> |
| 29 | <template #icon> |
| 30 | <Icon |
| 31 | name="carbon:chevron-right" |
| 32 | class="transition-transform duration-300" |
| 33 | :class="{ 'rotate-90': showFullReport }" |
| 34 | /> |
| 35 | </template> |
| 36 | Full report |
| 37 | </n-button> |
| 38 | |
| 39 | <n-collapse-transition :show="showFullReport"> |
| 40 | <div v-if="report.report_markdown"> |
| 41 | <Markdown :source="report.report_markdown" breaks /> |
| 42 | </div> |
| 43 | <n-empty v-else description="No report content" class="min-h-20 justify-center" /> |
| 44 | </n-collapse-transition> |
| 45 | </div> |
| 46 | </template> |
| 47 | |
| 48 | <script setup lang="ts"> |
| 49 | import type { AiAnalystReport } from "@/types/aiAnalyst.d" |
| 50 | import { NButton, NCollapseTransition, NEmpty } from "naive-ui" |
| 51 | import { computed, toRefs } from "vue" |
| 52 | import Badge from "@/components/common/Badge.vue" |
| 53 | import CardKV from "@/components/common/cards/CardKV.vue" |
| 54 | import Icon from "@/components/common/Icon.vue" |
| 55 | import Markdown from "@/components/common/Markdown.vue" |
| 56 | import { formatDate } from "@/utils/format" |
| 57 | |
| 58 | const props = defineProps<{ |
| 59 | report: AiAnalystReport |
| 60 | }>() |
| 61 | |
| 62 | const { report } = toRefs(props) |
| 63 | |
| 64 | const showFullReport = defineModel<boolean>("showFullReport", { required: true }) |
| 65 | |
| 66 | const severityColor = computed(() => { |
| 67 | const severity = report.value.severity_assessment |
| 68 | if (severity === "Critical" || severity === "High") return "danger" |
| 69 | if (severity === "Medium") return "warning" |
| 70 | if (severity === "Low" || severity === "Informational") return "success" |
| 71 | return undefined |
| 72 | }) |
| 73 | </script> |