main
vue 137 lines 2.85 KB
Raw
1 <template>
2 <div class="soc-alerts-bookmarks">
3 <div class="header flex items-center">
4 <div class="info">
5 Bookmarked:
6 <code>
7 <strong>{{ bookmarksList.length }}</strong>
8 </code>
9 </div>
10 </div>
11
12 <n-spin :show="loadingBookmarks">
13 <div class="min-h-52">
14 <template v-if="bookmarksList.length">
15 <SocAlertItem
16 v-for="alert of bookmarksList"
17 :key="alert.alert_id"
18 :alert-data="alert"
19 class="item-appear item-appear-bottom item-appear-005 mb-2"
20 is-bookmark
21 :users="usersList"
22 @bookmark="bookmark()"
23 @deleted="itemDeleted(alert.alert_id)"
24 />
25 </template>
26 <template v-else>
27 <n-empty v-if="!loadingBookmarks" description="No items found" class="h-48 justify-center" />
28 </template>
29 </div>
30 </n-spin>
31 </div>
32 </template>
33
34 <script setup lang="ts">
35 import type { SocAlert } from "@/types/soc/alert.d"
36 import type { SocUser } from "@/types/soc/user.d"
37 import axios from "axios"
38 import { NEmpty, NSpin, useMessage } from "naive-ui"
39 import { onBeforeMount, onBeforeUnmount, onMounted, ref, toRefs } from "vue"
40 import Api from "@/api"
41 import SocAlertItem from "./SocAlertItem/SocAlertItem.vue"
42
43 const props = defineProps<{
44 usersList?: SocUser[]
45 }>()
46 const emit = defineEmits<{
47 (e: "bookmark"): void
48 (e: "deleted", value?: string): void
49 (e: "loaded", value: SocAlert[]): void
50 (
51 e: "mounted",
52 value: {
53 reload: () => void
54 }
55 ): void
56 }>()
57
58 const { usersList } = toRefs(props)
59
60 let reloadTimeout: NodeJS.Timeout | null = null
61 const message = useMessage()
62 const loadingBookmarks = ref(false)
63 const bookmarksList = ref<SocAlert[]>([])
64
65 let abortController: AbortController | null = null
66
67 function bookmark() {
68 emit("bookmark")
69 safeReload()
70 }
71
72 function getBookmarks() {
73 loadingBookmarks.value = true
74
75 abortController = new AbortController()
76
77 Api.soc
78 .getAlertsBookmark(abortController.signal)
79 .then(res => {
80 if (res.data.success) {
81 bookmarksList.value = res.data.bookmarked_alerts || []
82 emit("loaded", bookmarksList.value)
83 } else {
84 message.error(res.data?.message || "An error occurred. Please try again later.")
85 }
86 })
87 .catch(err => {
88 if (!axios.isCancel(err)) {
89 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
90 }
91 })
92 .finally(() => {
93 loadingBookmarks.value = false
94 })
95 }
96
97 function safeReload() {
98 abortController?.abort()
99
100 if (reloadTimeout) {
101 clearTimeout(reloadTimeout)
102 }
103
104 reloadTimeout = setTimeout(() => {
105 getBookmarks()
106 }, 200)
107 }
108
109 function itemDeleted(alertId: string | number) {
110 getBookmarks()
111 emit("deleted", alertId.toString())
112 }
113
114 onBeforeMount(() => {
115 getBookmarks()
116 })
117
118 onMounted(() => {
119 emit("mounted", {
120 reload: () => {
121 safeReload()
122 }
123 })
124 })
125
126 onBeforeUnmount(() => {
127 abortController?.abort()
128 })
129 </script>
130
131 <style lang="scss" scoped>
132 .soc-alerts-bookmarks {
133 .header {
134 height: 50px;
135 }
136 }
137 </style>