main
vue 131 lines 3.98 KB
Raw
1 <template>
2 <div>
3 <CardEntity hoverable clickable @click.stop="showDetails = true">
4 <template #headerMain>#{{ note.note_id }} - {{ note.note_details.note_uuid }}</template>
5 <template #headerExtra>
6 <n-popover overlap placement="top-end">
7 <template #trigger>
8 <div class="hover:text-primary flex cursor-help items-center gap-2">
9 <span>
10 {{ formatDateTime(note.note_details.note_creationdate) }}
11 </span>
12 <Icon :name="TimeIcon" :size="16" />
13 </div>
14 </template>
15 <div class="flex flex-col px-1 py-2">
16 <SocCaseNoteTimeline :note />
17 </div>
18 </n-popover>
19 </template>
20
21 <template #default>
22 <div class="flex flex-col gap-1">
23 <div v-html="note.note_title"></div>
24 <p v-if="note.note_details.note_content">
25 {{ excerpt }}
26 </p>
27 </div>
28 </template>
29
30 <!--
31 <template #mainExtra>
32 <div class="flex flex-wrap items-center gap-3">
33 <Badge type="splitted" color="primary">
34 <template #label>Status</template>
35 <template #value>{{ asset.analysis_status }}</template>
36 </Badge>
37 <Badge type="splitted" color="primary">
38 <template #label>Type</template>
39 <template #value>{{ asset.asset_type }}</template>
40 </Badge>
41 <Badge v-for="tag of tags" :key="tag.key" type="splitted" color="primary">
42 <template #label>{{ tag.key }}</template>
43 <template v-if="tag.value !== undefined" #value>{{ tag.value || "-" }}</template>
44 </Badge>
45 </div>
46 </template>
47 -->
48 </CardEntity>
49
50 <n-modal
51 v-model:show="showDetails"
52 preset="card"
53 content-class="p-0!"
54 :style="{ maxWidth: 'min(800px, 90vw)', minHeight: 'min(600px, 90vh)', overflow: 'hidden' }"
55 :title="`Note: #${note.note_id} - ${note.note_details.note_uuid}`"
56 :bordered="false"
57 segmented
58 >
59 <n-tabs type="line" animated :tabs-padding="24">
60 <n-tab-pane name="Info" tab="Info" display-directive="show">
61 <div v-if="properties" class="grid-auto-fit-200 grid gap-2 p-6 pt-3">
62 <CardKV v-for="(value, key) of properties" :key>
63 <template #key>
64 {{ key }}
65 </template>
66 <template #value>
67 {{ value || "-" }}
68 </template>
69 </CardKV>
70 </div>
71 </n-tab-pane>
72 <n-tab-pane name="Content" tab="Content" display-directive="show">
73 <div class="p-6 pt-3">
74 <n-input
75 :value="note.note_details.note_content"
76 type="textarea"
77 readonly
78 placeholder="Empty"
79 size="large"
80 :autosize="{
81 minRows: 3,
82 maxRows: 10
83 }"
84 />
85 </div>
86 </n-tab-pane>
87 <n-tab-pane name="History" tab="History" display-directive="show:lazy">
88 <div class="p-6 pt-3">
89 <SocCaseNoteTimeline :note />
90 </div>
91 </n-tab-pane>
92 </n-tabs>
93 </n-modal>
94 </div>
95 </template>
96
97 <script setup lang="ts">
98 import type { SocNote } from "@/types/soc/note.d"
99 import _omit from "lodash/omit"
100 import { NInput, NModal, NPopover, NTabPane, NTabs } from "naive-ui"
101 import { computed, defineAsyncComponent, ref } from "vue"
102 import CardEntity from "@/components/common/cards/CardEntity.vue"
103 import CardKV from "@/components/common/cards/CardKV.vue"
104 import Icon from "@/components/common/Icon.vue"
105 import { useSettingsStore } from "@/stores/settings"
106 import dayjs from "@/utils/dayjs"
107
108 const { note } = defineProps<{ note: SocNote }>()
109
110 const SocCaseNoteTimeline = defineAsyncComponent(() => import("./SocCaseNoteTimeline.vue"))
111
112 const TimeIcon = "carbon:time"
113
114 const showDetails = ref(false)
115 const dFormats = useSettingsStore().dateFormat
116
117 function formatDateTime(timestamp: string | number | Date, utc: boolean = true): string {
118 return dayjs(timestamp).utc(utc).format(dFormats.datetimesec)
119 }
120
121 const excerpt = computed(() => {
122 const text = note.note_details.note_content
123 const truncated = text.split(" ").slice(0, 30).join(" ")
124
125 return truncated + (truncated !== text ? "..." : "")
126 })
127
128 const properties = computed(() => {
129 return _omit(note.note_details, ["note_content", "custom_attributes", "note_creationdate", "note_lastupdate"])
130 })
131 </script>