Browse Source

feat(site): enhance site list with SSE integration and URL display using tags

Jacky 2 months ago
parent
commit
440982fc76

+ 1 - 1
app/src/views/nginx_log/NginxLogList.vue

@@ -14,7 +14,7 @@ import { useRouter } from 'vue-router'
 const router = useRouter()
 const isScanning = ref(false)
 const stdCurdRef = ref()
-const sse = ref<SSE | null>(null)
+const sse = ref<SSE>()
 
 const columns: Column[] = [
   {

+ 57 - 0
app/src/views/site/site_list/SiteList.vue

@@ -2,6 +2,8 @@
 import type { EnvGroup } from '@/api/env_group'
 import type { Site } from '@/api/site'
 import type { Column } from '@/components/StdDesign/types'
+import type { SSE, SSEvent } from 'sse.js'
+import cacheIndex from '@/api/cache_index'
 import env_group from '@/api/env_group'
 import site from '@/api/site'
 import EnvGroupTabs from '@/components/EnvGroupTabs/EnvGroupTabs.vue'
@@ -10,6 +12,7 @@ import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
 import InspectConfig from '@/views/config/InspectConfig.vue'
 import columns from '@/views/site/site_list/columns'
 import SiteDuplicate from '@/views/site/site_list/SiteDuplicate.vue'
+import { CheckCircleOutlined, LoadingOutlined } from '@ant-design/icons-vue'
 import { message } from 'ant-design-vue'
 
 const route = useRoute()
@@ -20,6 +23,8 @@ const inspect_config = ref()
 
 const envGroupId = ref(Number.parseInt(route.query.env_group_id as string) || 0)
 const envGroups = ref([]) as Ref<EnvGroup[]>
+const isScanning = ref(false)
+const sse = ref<SSE>()
 
 watch(route, () => {
   inspect_config.value?.test()
@@ -39,6 +44,48 @@ onMounted(async () => {
     catch {
       return
     }
+
+    setupSSE()
+  }
+})
+
+// Connect to SSE endpoint and setup handlers
+async function setupSSE() {
+  if (sse.value) {
+    sse.value.close()
+  }
+
+  sse.value = cacheIndex.index_status()
+
+  // Handle incoming messages
+  if (sse.value) {
+    sse.value.onmessage = (e: SSEvent) => {
+      try {
+        if (!e.data)
+          return
+
+        const data = JSON.parse(e.data)
+        isScanning.value = data.scanning
+
+        table.value.get_list()
+      }
+      catch (error) {
+        console.error('Error parsing SSE message:', error)
+      }
+    }
+
+    sse.value.onerror = () => {
+      // Reconnect on error
+      setTimeout(() => {
+        setupSSE()
+      }, 5000)
+    }
+  }
+}
+
+onUnmounted(() => {
+  if (sse.value) {
+    sse.value.close()
   }
 })
 
@@ -93,6 +140,16 @@ function handleBatchUpdated() {
 
 <template>
   <ACard :title="$gettext('Manage Sites')">
+    <template #extra>
+      <div class="flex items-center cursor-default">
+        <template v-if="isScanning">
+          <LoadingOutlined class="mr-2" spin />{{ $gettext('Indexing...') }}
+        </template>
+        <template v-else>
+          <CheckCircleOutlined class="mr-2" />{{ $gettext('Indexed') }}
+        </template>
+      </div>
+    </template>
     <InspectConfig ref="inspect_config" />
 
     <EnvGroupTabs v-model:active-key="envGroupId" :env-groups="envGroups" />

+ 12 - 6
app/src/views/site/site_list/columns.tsx

@@ -9,7 +9,7 @@ import {
 } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import { input, select, selector } from '@/components/StdDesign/StdDataEntry'
 import envGroupColumns from '@/views/environments/group/columns'
-import { Badge } from 'ant-design-vue'
+import { Badge, Tag } from 'ant-design-vue'
 
 const columns: Column[] = [{
   title: () => $gettext('Name'),
@@ -28,15 +28,21 @@ const columns: Column[] = [{
     const template: JSXElements = []
     if (record.enabled) {
       text?.forEach((url: string) => {
-        template.push(<a href={url} target="_blank" rel="noopener noreferrer">{url}</a>)
-        template.push(<span>, </span>)
+        const displayUrl = url.replace(/^https?:\/\//, '')
+        template.push(
+          <Tag style="margin-right: 8px; margin-bottom: 4px;">
+            <a href={url} target="_blank" rel="noopener noreferrer">{displayUrl}</a>
+          </Tag>,
+        )
       })
-      template.pop() // Remove last comma
     }
     else {
-      template.push(<span>{text?.join(', ')}</span>)
+      text?.forEach((url: string) => {
+        const displayUrl = url.replace(/^https?:\/\//, '')
+        template.push(<Tag style="margin-right: 8px; margin-bottom: 4px;">{displayUrl}</Tag>)
+      })
     }
-    return h('div', template)
+    return h('div', { style: { display: 'flex', flexWrap: 'wrap' } }, template)
   },
   width: 120,
 }, {