main
vue 106 lines 2.69 KB
Raw
1 <template>
2 <n-spin :show="loading">
3 <div class="flex min-h-52 flex-col gap-2 py-0.5">
4 <template v-if="list.length">
5 <CardEntity
6 v-for="item of list"
7 :key="item.hostname"
8 embedded
9 clickable
10 hoverable
11 :highlighted="item.hostname === selected?.hostname"
12 size="small"
13 @click="setItem(item)"
14 >
15 <template #headerMain>
16 {{ item.hostname }}
17 </template>
18 <template #headerExtra>
19 <code class="text-primary cursor-pointer" @click.stop="routeAgent(item.agent_id).navigate()">
20 {{ item.agent_id }}
21 <Icon :name="LinkIcon" :size="13" class="relative top-0.5" />
22 </code>
23 </template>
24 <template #default>
25 {{ item.ip_address }}
26 <code>{{ item.label }}</code>
27 </template>
28 <template #footer>
29 <div class="flex flex-wrap items-center gap-2">
30 <Icon :name="iconFromOs(item.os)" :size="14" />
31 <span>
32 {{ item.os }}
33 </span>
34 </div>
35 </template>
36 </CardEntity>
37 </template>
38 <template v-else>
39 <n-empty v-if="!loading" description="No items found" class="h-48 justify-center" />
40 </template>
41 </div>
42 </n-spin>
43 </template>
44
45 <script setup lang="ts">
46 import type { Agent } from "@/types/agents.d"
47 import { NEmpty, NSpin, useMessage } from "naive-ui"
48 import { onBeforeMount, ref } from "vue"
49 import Api from "@/api"
50 import CardEntity from "@/components/common/cards/CardEntity.vue"
51 import Icon from "@/components/common/Icon.vue"
52 import { useNavigation } from "@/composables/useNavigation"
53 import { iconFromOs } from "@/utils"
54
55 const { agentsList, filter } = defineProps<{
56 agentsList?: Agent[] | null
57 filter?: (agent: Agent) => boolean
58 }>()
59
60 const emit = defineEmits<{
61 (e: "loaded", value: Agent[]): void
62 }>()
63
64 const selected = defineModel<Agent | null>("selected", { default: null })
65
66 const LinkIcon = "carbon:launch"
67
68 const { routeAgent } = useNavigation()
69 const message = useMessage()
70 const loading = ref(false)
71 const list = ref<Agent[]>([])
72
73 function getList() {
74 loading.value = true
75
76 Api.agents
77 .getAgents()
78 .then(res => {
79 if (res.data.success) {
80 const tmpList = res.data?.agents || []
81 list.value = filter ? tmpList.filter(filter) : tmpList
82 emit("loaded", list.value)
83 } else {
84 message.warning(res.data?.message || "An error occurred. Please try again later.")
85 }
86 })
87 .catch(err => {
88 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
89 })
90 .finally(() => {
91 loading.value = false
92 })
93 }
94
95 function setItem(item: Agent) {
96 selected.value = selected.value?.hostname === item.hostname ? null : item
97 }
98
99 onBeforeMount(() => {
100 if (agentsList?.length) {
101 list.value = agentsList
102 } else {
103 getList()
104 }
105 })
106 </script>