main
vue 192 lines 5.34 KB
Raw
1 <template>
2 <div>
3 <CardEntity hoverable :embedded>
4 <template #headerMain>
5 <div class="flex items-center gap-2">
6 <Icon :name="UserIcon" :size="14" />
7 {{ input.creator_user_id }}
8 </div>
9 </template>
10 <template #headerExtra>{{ formatDateTime(input.created_at) }}</template>
11 <template #default>
12 <div class="flex flex-col gap-1">
13 {{ input.title }}
14 <p>
15 {{ input.name }}
16 </p>
17 </div>
18 </template>
19 <template #footerMain>
20 <div class="flex flex-wrap items-center gap-3">
21 <Badge :type="input.global ? 'active' : 'muted'">
22 <template #iconRight>
23 <Icon :name="input.global ? GlobalIcon : DisabledIcon" :size="14" />
24 </template>
25 <template #label>Global</template>
26 </Badge>
27 <n-tooltip trigger="hover" :disabled="!isRunning">
28 <template #trigger>
29 <Badge :type="isRunning ? 'active' : 'muted'" :hint-cursor="isRunning">
30 <template #iconRight>
31 <Icon :name="isRunning ? TimeIcon : DisabledIcon" :size="14" />
32 </template>
33 <template #label>Running</template>
34 </Badge>
35 </template>
36 {{ formatDateTime(input.started_at) }}
37 </n-tooltip>
38 </div>
39 </template>
40 <template #footerExtra>
41 <div class="flex flex-wrap items-center justify-end gap-3">
42 <n-button size="small" @click.stop="showDetails = true">
43 <template #icon>
44 <Icon :name="InfoIcon" />
45 </template>
46 Details
47 </n-button>
48 <n-button v-if="isRunning" :loading type="warning" size="small" secondary @click="stop()">
49 <template #icon>
50 <Icon :name="StopIcon" />
51 </template>
52 Stop input
53 </n-button>
54 <n-button v-else :loading type="success" secondary size="small" @click="start()">
55 <template #icon>
56 <Icon :name="StartIcon" />
57 </template>
58 Start input
59 </n-button>
60 </div>
61 </template>
62 </CardEntity>
63
64 <n-modal
65 v-model:show="showDetails"
66 preset="card"
67 content-class="p-0!"
68 :style="{ maxWidth: 'min(600px, 90vw)', overflow: 'hidden' }"
69 :title="input.title"
70 :bordered="false"
71 segmented
72 >
73 <n-tabs type="line" animated :tabs-padding="24">
74 <n-tab-pane name="info" tab="Info" display-directive="show:lazy">
75 <div class="p-6 pt-3">
76 <div class="mb-2">
77 Id :
78 <code>{{ input.id }}</code>
79 </div>
80 <div class="mb-2">
81 Node :
82 <code>{{ input.node }}</code>
83 </div>
84 <div class="mb-2">
85 Type :
86 <code>{{ input.type }}</code>
87 </div>
88 <div class="mb-2">
89 Content pack :
90 <code>{{ input.content_pack || "-" }}</code>
91 </div>
92 <div class="mb-2">Static fields :</div>
93 <SimpleJsonViewer
94 class="vuesjv-override"
95 :model-value="input.static_fields"
96 :initial-expanded-depth="1"
97 />
98 </div>
99 </n-tab-pane>
100 <n-tab-pane name="attributes" tab="Attributes" display-directive="show:lazy">
101 <div class="p-6 pt-3">
102 <SimpleJsonViewer
103 class="vuesjv-override"
104 :model-value="input.attributes"
105 :initial-expanded-depth="1"
106 />
107 </div>
108 </n-tab-pane>
109 </n-tabs>
110 </n-modal>
111 </div>
112 </template>
113
114 <script setup lang="ts">
115 import type { InputExtended } from "@/types/graylog/inputs.d"
116 import { NButton, NModal, NTabPane, NTabs, NTooltip, useMessage } from "naive-ui"
117 import { computed, ref } from "vue"
118 import { SimpleJsonViewer } from "vue-sjv"
119 import Api from "@/api"
120 import Badge from "@/components/common/Badge.vue"
121 import CardEntity from "@/components/common/cards/CardEntity.vue"
122 import Icon from "@/components/common/Icon.vue"
123 import { useSettingsStore } from "@/stores/settings"
124 import { formatDate } from "@/utils/format"
125 import "@/assets/scss/overrides/vuesjv-override.scss"
126
127 const { input, embedded } = defineProps<{ input: InputExtended; embedded?: boolean }>()
128
129 const emit = defineEmits<{
130 (e: "updated"): void
131 }>()
132
133 const UserIcon = "carbon:user"
134 const InfoIcon = "carbon:information"
135 const DisabledIcon = "carbon:subtract"
136 const TimeIcon = "carbon:time"
137 const GlobalIcon = "ph:globe-light"
138 const StopIcon = "carbon:stop"
139 const StartIcon = "carbon:play"
140
141 const message = useMessage()
142 const loading = ref(false)
143 const showDetails = ref(false)
144 const isRunning = computed(() => input?.state === "RUNNING")
145 const dFormats = useSettingsStore().dateFormat
146
147 function formatDateTime(timestamp: string): string {
148 return formatDate(timestamp, dFormats.datetimesec).toString()
149 }
150
151 function stop() {
152 loading.value = true
153
154 Api.graylog
155 .stopInput(input.id)
156 .then(res => {
157 if (res.data.success) {
158 emit("updated")
159 message.success(res.data?.message || "Successfully stopped input.")
160 } else {
161 message.warning(res.data?.message || "An error occurred. Please try again later.")
162 }
163 })
164 .catch(err => {
165 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
166 })
167 .finally(() => {
168 loading.value = false
169 })
170 }
171
172 function start() {
173 loading.value = true
174
175 Api.graylog
176 .startInput(input.id)
177 .then(res => {
178 if (res.data.success) {
179 emit("updated")
180 message.success(res.data?.message || "Successfully started input.")
181 } else {
182 message.warning(res.data?.message || "An error occurred. Please try again later.")
183 }
184 })
185 .catch(err => {
186 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
187 })
188 .finally(() => {
189 loading.value = false
190 })
191 }
192 </script>