فهرست منبع

feat(scanner): enhance scanning functionality with configurable options and post-scan callbacks

0xJacky 3 روز پیش
والد
کامیت
49623c21c9

+ 2 - 1
.claude/settings.local.json

@@ -20,7 +20,8 @@
       "Bash(pnpm eslint:*)",
       "Read(//workspaces/cosy/settings/**)",
       "Bash(go doc:*)",
-      "Bash(pnpm exec eslint:*)"
+      "Bash(pnpm exec eslint:*)",
+      "Bash(go:*)"
     ],
     "deny": []
   }

+ 11 - 0
app/components.d.ts

@@ -10,6 +10,7 @@ declare module 'vue' {
   export interface GlobalComponents {
     AAlert: typeof import('ant-design-vue/es')['Alert']
     AApp: typeof import('ant-design-vue/es')['App']
+    AAutoComplete: typeof import('ant-design-vue/es')['AutoComplete']
     AAvatar: typeof import('ant-design-vue/es')['Avatar']
     ABadge: typeof import('ant-design-vue/es')['Badge']
     ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
@@ -19,14 +20,19 @@ declare module 'vue' {
     ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
     ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
     ACol: typeof import('ant-design-vue/es')['Col']
+    ACollapse: typeof import('ant-design-vue/es')['Collapse']
+    ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
+    AComment: typeof import('ant-design-vue/es')['Comment']
     AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
     ADivider: typeof import('ant-design-vue/es')['Divider']
     ADrawer: typeof import('ant-design-vue/es')['Drawer']
+    ADropdown: typeof import('ant-design-vue/es')['Dropdown']
     AEmpty: typeof import('ant-design-vue/es')['Empty']
     AForm: typeof import('ant-design-vue/es')['Form']
     AFormItem: typeof import('ant-design-vue/es')['FormItem']
     AInput: typeof import('ant-design-vue/es')['Input']
     AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
+    AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
     ALayout: typeof import('ant-design-vue/es')['Layout']
     ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
     ALayoutFooter: typeof import('ant-design-vue/es')['LayoutFooter']
@@ -36,16 +42,20 @@ declare module 'vue' {
     AListItem: typeof import('ant-design-vue/es')['ListItem']
     AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
     AMenu: typeof import('ant-design-vue/es')['Menu']
+    AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
     AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
     AModal: typeof import('ant-design-vue/es')['Modal']
     APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
     APopover: typeof import('ant-design-vue/es')['Popover']
     AppProviderAppProvider: typeof import('./src/components/AppProvider/AppProvider.vue')['default']
     AProgress: typeof import('ant-design-vue/es')['Progress']
+    ARadio: typeof import('ant-design-vue/es')['Radio']
+    ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
     ARow: typeof import('ant-design-vue/es')['Row']
     ASelect: typeof import('ant-design-vue/es')['Select']
     ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
     ASpace: typeof import('ant-design-vue/es')['Space']
+    ASpin: typeof import('ant-design-vue/es')['Spin']
     AStatistic: typeof import('ant-design-vue/es')['Statistic']
     ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
     ASwitch: typeof import('ant-design-vue/es')['Switch']
@@ -53,6 +63,7 @@ declare module 'vue' {
     ATabPane: typeof import('ant-design-vue/es')['TabPane']
     ATabs: typeof import('ant-design-vue/es')['Tabs']
     ATag: typeof import('ant-design-vue/es')['Tag']
+    ATextarea: typeof import('ant-design-vue/es')['Textarea']
     ATooltip: typeof import('ant-design-vue/es')['Tooltip']
     ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
     AutoCertFormAutoCertForm: typeof import('./src/components/AutoCertForm/AutoCertForm.vue')['default']

+ 1 - 1
app/package.json

@@ -92,4 +92,4 @@
     "vite-svg-loader": "^5.1.0",
     "vue-tsc": "^3.1.0"
   }
-}
+}

+ 27 - 23
app/src/language/ar/app.po

@@ -402,7 +402,7 @@ msgstr "هل أنت متأكد أنك تريد الحذف نهائيًا؟"
 msgid "Are you sure you want to delete?"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "هل أنت متأكد أنك تريد إعادة تحميل Nginx على عقد المزامنة التالية؟"
 
@@ -418,7 +418,7 @@ msgstr "هل أنت متأكد أنك تريد إزالة هذا العنصر؟"
 msgid "Are you sure you want to remove this location?"
 msgstr "هل أنت متأكد أنك تريد إزالة هذا المكان؟"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "هل أنت متأكد أنك تريد إعادة تشغيل Nginx على عقد المزامنة التالية؟"
 
@@ -1752,7 +1752,7 @@ msgstr "محتوى ملف الهضم فارغ"
 msgid "DingTalk"
 msgstr "دينجتوك"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "مباشر"
 
@@ -3082,7 +3082,7 @@ msgstr "مستوى ضغط GZIP"
 msgid "GZIP Min Length"
 msgstr "الحد الأدنى لطول GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "فحص الصحة"
 
@@ -3098,7 +3098,7 @@ msgstr "تم حفظ تكوين فحص الصحة"
 msgid "Health check configuration saved successfully"
 msgstr "تم حفظ تكوين فحص الصحة بنجاح"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "حالة الصحة"
 
@@ -3536,7 +3536,7 @@ msgstr "حالة النسخ الاحتياطي الأخيرة"
 msgid "Last Backup Time"
 msgstr "وقت آخر نسخة احتياطية"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "آخر التحقق"
 
@@ -3670,7 +3670,7 @@ msgstr "جارٍ تحميل البيانات..."
 msgid "Loading..."
 msgstr "جاري التحميل..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4349,8 +4349,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "يتضمن Nginx.conf دليل streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4382,7 +4382,7 @@ msgstr "لا تتوفر بيانات جغرافية للصين"
 msgid "No data"
 msgstr "لا توجد بيانات"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "لا بيانات"
 
@@ -4581,12 +4581,12 @@ msgstr "إيقاف"
 msgid "Official Document"
 msgstr "الوثيقة الرسمية"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "غير متصل"
 
@@ -4619,13 +4619,13 @@ msgstr "تشغيل"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "متصل"
 
@@ -5305,7 +5305,7 @@ msgid "Reload"
 msgstr "إعادة تحميل"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "إعادة تحميل Nginx"
@@ -5330,7 +5330,7 @@ msgstr "خطأ في إعادة تحميل Nginx البعيد"
 msgid "Reload Remote Nginx Success"
 msgstr "إعادة تحميل Nginx البعيد بنجاح"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "فشل طلب إعادة التحميل، يرجى التحقق من اتصال الشبكة لديك"
 
@@ -5517,7 +5517,7 @@ msgstr "الردود"
 msgid "Restart"
 msgstr "إعادة تشغيل"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "إعادة تشغيل Nginx"
@@ -5538,7 +5538,7 @@ msgstr "خطأ في إعادة تشغيل Nginx البعيد"
 msgid "Restart Remote Nginx Success"
 msgstr "إعادة تشغيل Nginx البعيد بنجاح"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "فشل طلب إعادة التشغيل، يرجى التحقق من اتصال الشبكة لديك"
 
@@ -6393,7 +6393,7 @@ msgid "Sync Config Success"
 msgstr "تمت مزامنة التكوين بنجاح"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "مزامنة العقد"
@@ -6892,6 +6892,10 @@ msgstr "أفضل 10 عناوين URL"
 msgid "Total"
 msgstr "الإجمالي"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "إجمالي %{total} عنصر"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "إجمالي المكونات"
@@ -7102,7 +7106,7 @@ msgid "Upload Folders"
 msgstr "تحميل المجلدات"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "أعلى التيار"
 
@@ -7110,7 +7114,7 @@ msgstr "أعلى التيار"
 msgid "Upstream Name"
 msgstr "اسم المنبع"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "المآخذ العلوية"
 
@@ -7406,8 +7410,8 @@ msgstr "كتابة مفتاح الشهادة الخاص إلى القرص"
 msgid "Writing certificate to disk"
 msgstr "كتابة الشهادة إلى القرص"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/de_DE/app.po

@@ -411,7 +411,7 @@ msgstr "Sind Sie sicher, dass Sie dauerhaft löschen möchten?"
 msgid "Are you sure you want to delete?"
 msgstr "Sind Sie sicher, dass Sie löschen möchten?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Sync-Knoten neu laden "
@@ -429,7 +429,7 @@ msgstr "Möchten Sie dieses Element wirklich entfernen?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Sind Sie sicher, dass Sie diesen Standort entfernen möchten?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Synchronisationsknoten "
@@ -1788,7 +1788,7 @@ msgstr "Der Inhalt der Prüfsummen-Datei ist leer"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Direkt"
 
@@ -3129,7 +3129,7 @@ msgstr "GZIP-Komprimierungsstufe"
 msgid "GZIP Min Length"
 msgstr "GZIP-Mindestlänge"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Gesundheitsprüfung"
 
@@ -3145,7 +3145,7 @@ msgstr "Konfiguration der Gesundheitsprüfung gespeichert"
 msgid "Health check configuration saved successfully"
 msgstr "Die Konfiguration der Gesundheitsprüfung wurde erfolgreich gespeichert"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Gesundheitszustand"
 
@@ -3588,7 +3588,7 @@ msgstr "Letzter Backup-Status"
 msgid "Last Backup Time"
 msgstr "Letzter Sicherungszeitpunkt"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Letzte Überprüfung"
 
@@ -3722,7 +3722,7 @@ msgstr "Daten werden geladen..."
 msgid "Loading..."
 msgstr "Wird geladen..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4406,8 +4406,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf enthält das streams-enabled-Verzeichnis"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4439,7 +4439,7 @@ msgstr "Keine geografischen Daten für China verfügbar"
 msgid "No data"
 msgstr "Keine Daten"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Keine Daten"
 
@@ -4642,12 +4642,12 @@ msgstr "Aus"
 msgid "Official Document"
 msgstr "Offizielle Dokumentation"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Offline"
 
@@ -4680,13 +4680,13 @@ msgstr "Ein"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfernt."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "Online"
 
@@ -5385,7 +5385,7 @@ msgid "Reload"
 msgstr "Neu laden"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Nginx neu laden"
@@ -5410,7 +5410,7 @@ msgstr "Fehler beim Neuladen von Remote-Nginx"
 msgid "Reload Remote Nginx Success"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 "Die Neulade-Anfrage ist fehlgeschlagen, bitte überprüfen Sie Ihre "
@@ -5600,7 +5600,7 @@ msgstr "Antworten"
 msgid "Restart"
 msgstr "Neustart"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Nginx neu starten"
@@ -5621,7 +5621,7 @@ msgstr "Fehler beim Neustart von Remote-Nginx"
 msgid "Restart Remote Nginx Success"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 "Neustart-Anforderung fehlgeschlagen, bitte überprüfen Sie Ihre "
@@ -6490,7 +6490,7 @@ msgid "Sync Config Success"
 msgstr "Konfiguration erfolgreich synchronisiert"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Synchrone Knoten"
@@ -7010,6 +7010,10 @@ msgstr "Top 10 URLs"
 msgid "Total"
 msgstr "Gesamt"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Insgesamt %{total} Elemente"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Komponenten insgesamt"
@@ -7222,7 +7226,7 @@ msgid "Upload Folders"
 msgstr "Ordner hochladen"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Upstream"
 
@@ -7230,7 +7234,7 @@ msgstr "Upstream"
 msgid "Upstream Name"
 msgstr "Upstream-Name"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Upstream-Sockets"
 
@@ -7537,8 +7541,8 @@ msgstr "Scrheibe Zertifikat-Privatschlüssel auf die Festplatte"
 msgid "Writing certificate to disk"
 msgstr "Schreibe Zertifikat auf die Festplatte"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/en/app.po

@@ -378,7 +378,7 @@ msgstr ""
 msgid "Are you sure you want to delete?"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 
@@ -394,7 +394,7 @@ msgstr ""
 msgid "Are you sure you want to remove this location?"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 
@@ -1679,7 +1679,7 @@ msgstr ""
 msgid "DingTalk"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr ""
 
@@ -2987,7 +2987,7 @@ msgstr ""
 msgid "GZIP Min Length"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr ""
 
@@ -3003,7 +3003,7 @@ msgstr ""
 msgid "Health check configuration saved successfully"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr ""
 
@@ -3429,7 +3429,7 @@ msgstr ""
 msgid "Last Backup Time"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr ""
 
@@ -3563,7 +3563,7 @@ msgstr ""
 msgid "Loading..."
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4231,8 +4231,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr ""
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4264,7 +4264,7 @@ msgstr ""
 msgid "No data"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr ""
 
@@ -4455,12 +4455,12 @@ msgstr ""
 msgid "Official Document"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr ""
 
@@ -4493,13 +4493,13 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr ""
 
@@ -5168,7 +5168,7 @@ msgid "Reload"
 msgstr ""
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr ""
@@ -5193,7 +5193,7 @@ msgstr ""
 msgid "Reload Remote Nginx Success"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 
@@ -5378,7 +5378,7 @@ msgstr ""
 msgid "Restart"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr ""
@@ -5399,7 +5399,7 @@ msgstr ""
 msgid "Restart Remote Nginx Success"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 
@@ -6237,7 +6237,7 @@ msgid "Sync Config Success"
 msgstr ""
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr ""
@@ -6687,6 +6687,10 @@ msgstr ""
 msgid "Total"
 msgstr ""
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr ""
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr ""
@@ -6895,7 +6899,7 @@ msgid "Upload Folders"
 msgstr ""
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr ""
 
@@ -6903,7 +6907,7 @@ msgstr ""
 msgid "Upstream Name"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr ""
 
@@ -7187,8 +7191,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/es/app.po

@@ -414,7 +414,7 @@ msgstr "¿Estás seguro de que quieres eliminar permanentemente?"
 msgid "Are you sure you want to delete?"
 msgstr "¿Está seguro de que quiere borrar?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "¿Estás seguro de que deseas recargar Nginx en los siguientes nodos de "
@@ -432,7 +432,7 @@ msgstr "¿Está seguro de que desea eliminar este elemento?"
 msgid "Are you sure you want to remove this location?"
 msgstr "¿Está seguro de que quiere borrar esta ubicación?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "¿Estás seguro de que deseas reiniciar Nginx en los siguientes nodos de "
@@ -1793,7 +1793,7 @@ msgstr "El contenido del archivo de resumen está vacío"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Directo"
 
@@ -3135,7 +3135,7 @@ msgstr "Nivel de compresión GZIP"
 msgid "GZIP Min Length"
 msgstr "Longitud mínima de GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Comprobación de salud"
 
@@ -3151,7 +3151,7 @@ msgstr "Configuración de verificación de salud guardada"
 msgid "Health check configuration saved successfully"
 msgstr "Configuración de verificación de salud guardada exitosamente"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Estado de salud"
 
@@ -3591,7 +3591,7 @@ msgstr "Estado del último respaldo"
 msgid "Last Backup Time"
 msgstr "Hora del último respaldo"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Última verificación"
 
@@ -3725,7 +3725,7 @@ msgstr "Cargando datos..."
 msgid "Loading..."
 msgstr "Cargando..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4410,8 +4410,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf incluye el directorio streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4443,7 +4443,7 @@ msgstr "No hay datos geográficos de China disponibles"
 msgid "No data"
 msgstr "Sin datos"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Sin datos"
 
@@ -4647,12 +4647,12 @@ msgstr "Apagado"
 msgid "Official Document"
 msgstr "Documentación oficial"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Desconectado"
 
@@ -4685,13 +4685,13 @@ msgstr "Encendido"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "En línea"
 
@@ -5393,7 +5393,7 @@ msgid "Reload"
 msgstr "Recargar"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Recargar Nginx"
@@ -5418,7 +5418,7 @@ msgstr "Error al recargar Nginx remoto"
 msgid "Reload Remote Nginx Success"
 msgstr "Reinicio remoto de Nginx exitoso"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "La solicitud de recarga falló, por favor verifique su conexión de red"
 
@@ -5606,7 +5606,7 @@ msgstr "Respuestas"
 msgid "Restart"
 msgstr "Reiniciar"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Reiniciar Nginx"
@@ -5627,7 +5627,7 @@ msgstr "Error al reiniciar Nginx remoto"
 msgid "Restart Remote Nginx Success"
 msgstr "Reinicio remoto de Nginx exitoso"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "La solicitud de reinicio falló, por favor verifique su conexión de red"
 
@@ -6493,7 +6493,7 @@ msgid "Sync Config Success"
 msgstr "Configuración de sincronización exitosa"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Nodos de sincronización"
@@ -7011,6 +7011,10 @@ msgstr "Las 10 URL principales"
 msgid "Total"
 msgstr "Total"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Total de %{total} elementos"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Componentes totales"
@@ -7221,7 +7225,7 @@ msgid "Upload Folders"
 msgstr "Subir carpetas"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Aguas arriba"
 
@@ -7229,7 +7233,7 @@ msgstr "Aguas arriba"
 msgid "Upstream Name"
 msgstr "Nombre de la Transmisión"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Conectores Upstream"
 
@@ -7532,8 +7536,8 @@ msgstr "Escribir la clave privada del certificado a disco"
 msgid "Writing certificate to disk"
 msgstr "Escribir certificado a disco"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/fr_FR/app.po

@@ -416,7 +416,7 @@ msgstr "Êtes-vous sûr de vouloir supprimer définitivement ?"
 msgid "Are you sure you want to delete?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Êtes-vous sûr de vouloir recharger Nginx sur les nœuds de synchronisation "
@@ -434,7 +434,7 @@ msgstr "Êtes-vous sûr de vouloir supprimer cet élément ?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Voulez-vous vraiment supprimer cette localisation ?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Êtes-vous sûr de vouloir redémarrer Nginx sur les nœuds de synchronisation "
@@ -1796,7 +1796,7 @@ msgstr "Le contenu du fichier de hachage est vide"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Direct"
 
@@ -3136,7 +3136,7 @@ msgstr "Niveau de compression GZIP"
 msgid "GZIP Min Length"
 msgstr "Longueur minimale GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Vérification de santé"
 
@@ -3152,7 +3152,7 @@ msgstr "Configuration de vérification de santé enregistrée"
 msgid "Health check configuration saved successfully"
 msgstr "Configuration de vérification de santé enregistrée avec succès"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "État de santé"
 
@@ -3596,7 +3596,7 @@ msgstr "Statut de la dernière sauvegarde"
 msgid "Last Backup Time"
 msgstr "Dernière heure de sauvegarde"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Dernière vérification"
 
@@ -3730,7 +3730,7 @@ msgstr "Chargement des données..."
 msgid "Loading..."
 msgstr "Chargement..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4415,8 +4415,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf inclut le répertoire streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4448,7 +4448,7 @@ msgstr "Aucune donnée géographique pour la Chine disponible"
 msgid "No data"
 msgstr "Aucune donnée"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Aucune donnée"
 
@@ -4650,12 +4650,12 @@ msgstr "Désactivé"
 msgid "Official Document"
 msgstr "Documentation officielle"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Hors ligne"
 
@@ -4688,13 +4688,13 @@ msgstr "Activé"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Une fois la vérification terminée, les enregistrements seront supprimés."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "En ligne"
 
@@ -5396,7 +5396,7 @@ msgid "Reload"
 msgstr "Recharger"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Recharger nginx"
@@ -5421,7 +5421,7 @@ msgstr "Erreur de rechargement de Nginx distant"
 msgid "Reload Remote Nginx Success"
 msgstr "Rechargement distant de Nginx réussi"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 "La demande de rechargement a échoué, veuillez vérifier votre connexion "
@@ -5611,7 +5611,7 @@ msgstr "Réponses"
 msgid "Restart"
 msgstr "Redémarrer"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Redémarrer Nginx"
@@ -5632,7 +5632,7 @@ msgstr "Erreur de redémarrage de Nginx distant"
 msgid "Restart Remote Nginx Success"
 msgstr "Redémarrage distant de Nginx réussi"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "La demande de redémarrage a échoué, veuillez vérifier votre connexion réseau"
 
@@ -6500,7 +6500,7 @@ msgid "Sync Config Success"
 msgstr "Synchronisation de la configuration réussie"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Nœuds de synchronisation"
@@ -7026,6 +7026,10 @@ msgstr "Top 10 des URL"
 msgid "Total"
 msgstr "Total"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Total de %{total} éléments"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Total des composants"
@@ -7238,7 +7242,7 @@ msgid "Upload Folders"
 msgstr "Télécharger des dossiers"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Amont"
 
@@ -7246,7 +7250,7 @@ msgstr "Amont"
 msgid "Upstream Name"
 msgstr "Nom de l'amont"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Sockets Upstream"
 
@@ -7552,8 +7556,8 @@ msgstr "Écriture de la clé privée du certificat sur le disque"
 msgid "Writing certificate to disk"
 msgstr "Écriture du certificat sur le disque"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/ja_JP/app.po

@@ -398,7 +398,7 @@ msgstr "完全に削除してもよろしいですか?"
 msgid "Are you sure you want to delete?"
 msgstr "削除してもよろしいですか?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "以下の同期ノードでNginxを再読み込みしてもよろしいですか?"
 
@@ -414,7 +414,7 @@ msgstr "このアイテムを削除してもよろしいですか?"
 msgid "Are you sure you want to remove this location?"
 msgstr "このLocationを削除してもよろしいですか?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "以下の同期ノードでNginxを再起動してもよろしいですか?"
 
@@ -1723,7 +1723,7 @@ msgstr "ダイジェスト ファイルの内容が空です"
 msgid "DingTalk"
 msgstr "ディンタオク"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "ダイレクト"
 
@@ -3035,7 +3035,7 @@ msgstr "GZIP圧縮レベル"
 msgid "GZIP Min Length"
 msgstr "GZIP最小長"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "ヘルスチェック"
 
@@ -3051,7 +3051,7 @@ msgstr "ヘルスチェック設定が保存されました"
 msgid "Health check configuration saved successfully"
 msgstr "ヘルスチェック設定が正常に保存されました"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "健康状態"
 
@@ -3477,7 +3477,7 @@ msgstr "最終バックアップステータス"
 msgid "Last Backup Time"
 msgstr "最終バックアップ時刻"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "最終確認"
 
@@ -3611,7 +3611,7 @@ msgstr "データを読み込んでいます..."
 msgid "Loading..."
 msgstr "読み込み中..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4287,8 +4287,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf には streams-enabled ディレクトリが含まれています"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4320,7 +4320,7 @@ msgstr "中国の地理データが利用できません"
 msgid "No data"
 msgstr "データなし"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "データなし"
 
@@ -4513,12 +4513,12 @@ msgstr "オフ"
 msgid "Official Document"
 msgstr "公式ドキュメント"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "オフライン"
 
@@ -4551,13 +4551,13 @@ msgstr "オン"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "検証が完了すると、レコードは削除されます。"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "オンライン"
 
@@ -5230,7 +5230,7 @@ msgid "Reload"
 msgstr "再読み込み"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Nginx をリロード"
@@ -5255,7 +5255,7 @@ msgstr "リモートNginxの再読み込みエラー"
 msgid "Reload Remote Nginx Success"
 msgstr "リモートNginxのリロード成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "再読み込みリクエストが失敗しました。ネットワーク接続を確認してください"
 
@@ -5440,7 +5440,7 @@ msgstr "レスポンス"
 msgid "Restart"
 msgstr "再起動"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Nginx を再起動"
@@ -5461,7 +5461,7 @@ msgstr "リモートNginxの再起動エラー"
 msgid "Restart Remote Nginx Success"
 msgstr "リモートNginxの再起動成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "再起動リクエストが失敗しました。ネットワーク接続を確認してください"
 
@@ -6306,7 +6306,7 @@ msgid "Sync Config Success"
 msgstr "設定の同期に成功しました"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "同期ノード"
@@ -6773,6 +6773,10 @@ msgstr "トップ10 URL"
 msgid "Total"
 msgstr "合計"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "合計 %{total} 項目"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "コンポーネントの合計"
@@ -6981,7 +6985,7 @@ msgid "Upload Folders"
 msgstr "フォルダをアップロード"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "アップストリーム"
 
@@ -6989,7 +6993,7 @@ msgstr "アップストリーム"
 msgid "Upstream Name"
 msgstr "アップストリーム名"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "アップストリーム ソケット"
 
@@ -7278,8 +7282,8 @@ msgstr "証明書の秘密鍵をディスクに書き込んでいます"
 msgid "Writing certificate to disk"
 msgstr "証明書をディスクに書き込み中"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/ko_KR/app.po

@@ -396,7 +396,7 @@ msgstr "정말 영구적으로 삭제하시겠습니까?"
 msgid "Are you sure you want to delete?"
 msgstr "정말 삭제하시겠습니까?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 로드하시겠습니까?"
 
@@ -412,7 +412,7 @@ msgstr "이 항목을 제거하시겠습니까?"
 msgid "Are you sure you want to remove this location?"
 msgstr "이 위치를 제거하시겠습니까?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 시작하시겠습니까?"
 
@@ -1720,7 +1720,7 @@ msgstr "다이제스트 파일 내용이 비어 있습니다"
 msgid "DingTalk"
 msgstr "딩톡"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "직접"
 
@@ -3034,7 +3034,7 @@ msgstr "GZIP 압축 수준"
 msgid "GZIP Min Length"
 msgstr "GZIP 최소 길이"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "건강 점검"
 
@@ -3050,7 +3050,7 @@ msgstr "헬스 체크 설정이 저장되었습니다"
 msgid "Health check configuration saved successfully"
 msgstr "헬스 체크 구성이 성공적으로 저장되었습니다"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "건강 상태"
 
@@ -3476,7 +3476,7 @@ msgstr "마지막 백업 상태"
 msgid "Last Backup Time"
 msgstr "마지막 백업 시간"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "최종 확인"
 
@@ -3610,7 +3610,7 @@ msgstr "데이터를 불러오는 중..."
 msgid "Loading..."
 msgstr "로드 중..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4283,8 +4283,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf에는 streams-enabled 디렉토리가 포함됩니다"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4316,7 +4316,7 @@ msgstr "중국 지리 데이터를 사용할 수 없음"
 msgid "No data"
 msgstr "데이터 없음"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "데이터 없음"
 
@@ -4509,12 +4509,12 @@ msgstr "끔"
 msgid "Official Document"
 msgstr "공식 문서"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "오프라인"
 
@@ -4547,13 +4547,13 @@ msgstr "켜짐"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "온라인"
 
@@ -5224,7 +5224,7 @@ msgid "Reload"
 msgstr "리로드"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Nginx 다시 로드"
@@ -5249,7 +5249,7 @@ msgstr "원격 Nginx 다시 로드 오류"
 msgid "Reload Remote Nginx Success"
 msgstr "원격 Nginx 다시 로드 성공"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "다시 로드 요청이 실패했습니다. 네트워크 연결을 확인하세요"
 
@@ -5436,7 +5436,7 @@ msgstr "응답"
 msgid "Restart"
 msgstr "재시작"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Nginx 다시 시작"
@@ -5457,7 +5457,7 @@ msgstr "원격 Nginx 재시작 오류"
 msgid "Restart Remote Nginx Success"
 msgstr "원격 Nginx 재시작 성공"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "재시작 요청이 실패했습니다. 네트워크 연결을 확인해 주세요"
 
@@ -6302,7 +6302,7 @@ msgid "Sync Config Success"
 msgstr "구성 동기화 성공"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "동기화 노드"
@@ -6766,6 +6766,10 @@ msgstr "상위 10 개 URL"
 msgid "Total"
 msgstr "총계"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "총 %{total} 항목"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "총 구성 요소"
@@ -6974,7 +6978,7 @@ msgid "Upload Folders"
 msgstr "폴더 업로드"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "업스트림"
 
@@ -6982,7 +6986,7 @@ msgstr "업스트림"
 msgid "Upstream Name"
 msgstr "업스트림 이름"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "업스트림 소켓"
 
@@ -7270,8 +7274,8 @@ msgstr "인증서 개인 키를 디스크에 쓰기"
 msgid "Writing certificate to disk"
 msgstr "인증서를 디스크에 쓰기"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/messages.pot

@@ -381,7 +381,7 @@ msgstr ""
 msgid "Are you sure you want to delete?"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 
@@ -397,7 +397,7 @@ msgstr ""
 msgid "Are you sure you want to remove this location?"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 
@@ -1648,7 +1648,7 @@ msgstr ""
 msgid "DingTalk"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr ""
 
@@ -2943,7 +2943,7 @@ msgstr ""
 msgid "GZIP Min Length"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr ""
 
@@ -2959,7 +2959,7 @@ msgstr ""
 msgid "Health check configuration saved successfully"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr ""
 
@@ -3372,7 +3372,7 @@ msgstr ""
 msgid "Last Backup Time"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr ""
 
@@ -3508,7 +3508,7 @@ msgstr ""
 msgid "Loading..."
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61
 #: src/constants/index.ts:42
@@ -4181,8 +4181,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr ""
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109
@@ -4216,7 +4216,7 @@ msgstr ""
 msgid "No data"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr ""
 
@@ -4400,13 +4400,13 @@ msgstr ""
 msgid "Official Document"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159
 #: src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr ""
 
@@ -4440,14 +4440,14 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152
 #: src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr ""
 
@@ -5104,7 +5104,7 @@ msgid "Reload"
 msgstr ""
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141
 #: src/constants/index.ts:38
 #: src/views/node/Node.vue:208
 #: src/views/node/Node.vue:216
@@ -5131,7 +5131,7 @@ msgstr ""
 msgid "Reload Remote Nginx Success"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 
@@ -5317,7 +5317,7 @@ msgstr ""
 msgid "Restart"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229
 #: src/views/node/Node.vue:237
 msgid "Restart Nginx"
@@ -5339,7 +5339,7 @@ msgstr ""
 msgid "Restart Remote Nginx Success"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 
@@ -6175,7 +6175,7 @@ msgid "Sync Config Success"
 msgstr ""
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17
 #: src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
@@ -6571,6 +6571,10 @@ msgstr ""
 msgid "Total"
 msgstr ""
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr ""
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr ""
@@ -6783,7 +6787,7 @@ msgstr ""
 
 #: src/composables/useUpstreamStatus.ts:132
 #: src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr ""
 
@@ -6791,7 +6795,7 @@ msgstr ""
 msgid "Upstream Name"
 msgstr ""
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr ""
 
@@ -7067,8 +7071,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgstr ""
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/pt_PT/app.po

@@ -408,7 +408,7 @@ msgstr "Tem a certeza de que pretende eliminar permanentemente?"
 msgid "Are you sure you want to delete?"
 msgstr "Tem certeza que pretende eliminar?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Tem a certeza que pretende recarregar o Nginx nos seguintes nós de "
@@ -426,7 +426,7 @@ msgstr "Tem certeza que pretende eliminar este item?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Tem certeza que pretende eliminar este local?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Tem a certeza de que pretende reiniciar o Nginx nos seguintes nós de "
@@ -1776,7 +1776,7 @@ msgstr "O conteúdo do ficheiro de resumo está vazio"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Direto"
 
@@ -3110,7 +3110,7 @@ msgstr "Nível de compressão GZIP"
 msgid "GZIP Min Length"
 msgstr "Comprimento mínimo do GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Verificação de saúde"
 
@@ -3126,7 +3126,7 @@ msgstr "Configuração de verificação de saúde guardada"
 msgid "Health check configuration saved successfully"
 msgstr "Configuração de verificação de saúde salva com sucesso"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Estado de saúde"
 
@@ -3567,7 +3567,7 @@ msgstr "Estado do último backup"
 msgid "Last Backup Time"
 msgstr "Hora do último backup"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Última verificação"
 
@@ -3701,7 +3701,7 @@ msgstr "A carregar dados..."
 msgid "Loading..."
 msgstr "A carregar..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4385,8 +4385,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf inclui o diretório streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4418,7 +4418,7 @@ msgstr "Nenhum dado geográfico da China disponível"
 msgid "No data"
 msgstr "Sem dados"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Sem dados"
 
@@ -4620,12 +4620,12 @@ msgstr "Desligado"
 msgid "Official Document"
 msgstr "Documentação oficial"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Off-line"
 
@@ -4658,13 +4658,13 @@ msgstr "Ligado"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Assim que a verificação estiver concluída, os registos serão removidos."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "On-line"
 
@@ -5360,7 +5360,7 @@ msgid "Reload"
 msgstr "Recarregar"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Recarregar Nginx"
@@ -5385,7 +5385,7 @@ msgstr "Erro ao Recarregar Nginx Remoto"
 msgid "Reload Remote Nginx Success"
 msgstr "Recarregamento remoto do Nginx bem-sucedido"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "O pedido de recarregamento falhou, por favor verifique a sua ligação à rede"
 
@@ -5573,7 +5573,7 @@ msgstr "Respostas"
 msgid "Restart"
 msgstr "Reiniciar"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Reiniciar Nginx"
@@ -5594,7 +5594,7 @@ msgstr "Erro ao reiniciar Nginx remoto"
 msgid "Restart Remote Nginx Success"
 msgstr "Reinício remoto do Nginx bem-sucedido"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "Pedido de reinício falhou, por favor verifique a sua ligação à rede"
 
@@ -6458,7 +6458,7 @@ msgid "Sync Config Success"
 msgstr "Sucesso na configuração da sincronização"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Nós de sincronização"
@@ -6976,6 +6976,10 @@ msgstr "Top 10 URLs"
 msgid "Total"
 msgstr "Total"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Total de %{total} itens"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Componentes totais"
@@ -7188,7 +7192,7 @@ msgid "Upload Folders"
 msgstr "Carregar pastas"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "A montante"
 
@@ -7196,7 +7200,7 @@ msgstr "A montante"
 msgid "Upstream Name"
 msgstr "Nome do Upstream"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Sockets Upstream"
 
@@ -7498,8 +7502,8 @@ msgstr "Escrever chave privada do certificado ao disco"
 msgid "Writing certificate to disk"
 msgstr "Escrevendo certificado no disco"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/ru_RU/app.po

@@ -409,7 +409,7 @@ msgstr "Вы уверены, что хотите удалить безвозвр
 msgid "Are you sure you want to delete?"
 msgstr "Вы уверены, что хотите удалить?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Вы уверены, что хотите перезагрузить Nginx на следующих синхронизированных "
@@ -427,7 +427,7 @@ msgstr "Вы уверены, что хотите удалить этот эле
 msgid "Are you sure you want to remove this location?"
 msgstr "Вы уверены, что хотите удалить location?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Вы уверены, что хотите перезапустить Nginx на следующих синхронизированных "
@@ -1775,7 +1775,7 @@ msgstr "Содержимое файла хеш-суммы пусто"
 msgid "DingTalk"
 msgstr "ДинТок"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Прямой"
 
@@ -3113,7 +3113,7 @@ msgstr "Уровень сжатия GZIP"
 msgid "GZIP Min Length"
 msgstr "Минимальная длина GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Проверка состояния"
 
@@ -3129,7 +3129,7 @@ msgstr "Конфигурация проверки работоспособнос
 msgid "Health check configuration saved successfully"
 msgstr "Конфигурация проверки работоспособности успешно сохранена"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Состояние здоровья"
 
@@ -3568,7 +3568,7 @@ msgstr "Статус последнего резервного копирова
 msgid "Last Backup Time"
 msgstr "Время последнего резервного копирования"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Последняя проверка"
 
@@ -3702,7 +3702,7 @@ msgstr "Загрузка данных..."
 msgid "Loading..."
 msgstr "Загрузка..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4386,8 +4386,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf включает каталог streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4419,7 +4419,7 @@ msgstr "Географические данные по Китаю недосту
 msgid "No data"
 msgstr "Нет данных"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Нет данных"
 
@@ -4621,12 +4621,12 @@ msgstr "Выкл"
 msgid "Official Document"
 msgstr "Официальная документация"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Оффлайн"
 
@@ -4659,13 +4659,13 @@ msgstr "Вкл"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "После завершения проверки записи будут удалены."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "Онлайн"
 
@@ -5366,7 +5366,7 @@ msgid "Reload"
 msgstr "Перегрузить"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Перезагрузить Nginx"
@@ -5391,7 +5391,7 @@ msgstr "Ошибка перезагрузки удаленного Nginx"
 msgid "Reload Remote Nginx Success"
 msgstr "Удаленная перезагрузка Nginx успешно выполнена"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "Не удалось выполнить запрос на перезагрузку, проверьте подключение к сети"
 
@@ -5579,7 +5579,7 @@ msgstr "Ответы"
 msgid "Restart"
 msgstr "Перезапуск"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Перезапустить Nginx"
@@ -5600,7 +5600,7 @@ msgstr "Ошибка перезапуска удаленного Nginx"
 msgid "Restart Remote Nginx Success"
 msgstr "Удалённая перезагрузка Nginx успешно выполнена"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "Запрос на перезапуск не выполнен, проверьте подключение к сети"
 
@@ -6458,7 +6458,7 @@ msgid "Sync Config Success"
 msgstr "Синхронизация конфигурации успешна"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Синхронизированные узлы"
@@ -6970,6 +6970,10 @@ msgstr "Топ 10 URL-адресов"
 msgid "Total"
 msgstr "Всего"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Всего %{total} элементов"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Всего компонентов"
@@ -7180,7 +7184,7 @@ msgid "Upload Folders"
 msgstr "Загрузить папки"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Восходящий поток"
 
@@ -7188,7 +7192,7 @@ msgstr "Восходящий поток"
 msgid "Upstream Name"
 msgstr "Имя Upstream"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Сокеты Upstream"
 
@@ -7491,8 +7495,8 @@ msgstr "Запись закрытого ключа сертификата на 
 msgid "Writing certificate to disk"
 msgstr "Запись сертификата на диск"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/tr_TR/app.po

@@ -407,7 +407,7 @@ msgstr "Kalıcı olarak silmek istediğinizden emin misiniz?"
 msgid "Are you sure you want to delete?"
 msgstr "Silmek istediğine emin misin?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden yüklemek "
@@ -425,7 +425,7 @@ msgstr "Bu öğeyi kaldırmak istediğinizden emin misiniz?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Bu konumu kaldırmak istediğinizden emin misiniz?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden başlatmak "
@@ -1770,7 +1770,7 @@ msgstr "Özet dosyası içeriği boş"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Doğrudan"
 
@@ -3107,7 +3107,7 @@ msgstr "GZIP Sıkıştırma Seviyesi"
 msgid "GZIP Min Length"
 msgstr "GZIP Minimum Uzunluk"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Sağlık Kontrolü"
 
@@ -3123,7 +3123,7 @@ msgstr "Sağlık kontrolü yapılandırması kaydedildi"
 msgid "Health check configuration saved successfully"
 msgstr "Sağlık kontrol yapılandırması başarıyla kaydedildi"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Sağlık Durumu"
 
@@ -3566,7 +3566,7 @@ msgstr "Son Yedekleme Durumu"
 msgid "Last Backup Time"
 msgstr "Son Yedekleme Zamanı"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Son Kontrol"
 
@@ -3700,7 +3700,7 @@ msgstr "Veriler yükleniyor..."
 msgid "Loading..."
 msgstr "Yükleniyor..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4383,8 +4383,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf, streams-enabled dizinini içerir"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4416,7 +4416,7 @@ msgstr "Çin coğrafi verisi mevcut değil"
 msgid "No data"
 msgstr "Veri yok"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Veri yok"
 
@@ -4617,12 +4617,12 @@ msgstr "Kapalı"
 msgid "Official Document"
 msgstr "Resmi Belge"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Çevrimdışı"
 
@@ -4655,13 +4655,13 @@ msgstr "Açık"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Doğrulama tamamlandığında, kayıtlar kaldırılacaktır."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "Çevrimiçi"
 
@@ -5356,7 +5356,7 @@ msgid "Reload"
 msgstr "Yeniden Yükle"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Nginx'i Yeniden Yükle"
@@ -5381,7 +5381,7 @@ msgstr "Uzak Nginx Yeniden Yükleme Hatası"
 msgid "Reload Remote Nginx Success"
 msgstr "Uzak Nginx Yeniden Yükleme Başarılı"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "Yeniden yükleme isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 
@@ -5578,7 +5578,7 @@ msgstr "Yanıtlar"
 msgid "Restart"
 msgstr "Yeniden Başlat"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Nginx'i Yeniden Başlat"
@@ -5599,7 +5599,7 @@ msgstr "Uzak Nginx Yeniden Başlatma Hatası"
 msgid "Restart Remote Nginx Success"
 msgstr "Uzak Nginx Yeniden Başlatma Başarılı"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "Yeniden başlatma isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 
@@ -6457,7 +6457,7 @@ msgid "Sync Config Success"
 msgstr "Yapılandırma Başarıyla Senkronize Edildi"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Senkronizasyon Düğümleri"
@@ -6967,6 +6967,10 @@ msgstr "En İyi 10 URL"
 msgid "Total"
 msgstr "Toplam"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Toplam %{total} öğe"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Toplam Bileşenler"
@@ -7177,7 +7181,7 @@ msgid "Upload Folders"
 msgstr "Klasörleri Yükle"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Yukarı Akış"
 
@@ -7185,7 +7189,7 @@ msgstr "Yukarı Akış"
 msgid "Upstream Name"
 msgstr "Yukarı Akış Adı"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Üst Akım Soketleri"
 
@@ -7487,8 +7491,8 @@ msgstr "Sertifika özel anahtarı diske yazılıyor"
 msgid "Writing certificate to disk"
 msgstr "Sertifika diske yazılıyor"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/uk_UA/app.po

@@ -411,7 +411,7 @@ msgstr "Ви впевнені, що хочете видалити назавжд
 msgid "Are you sure you want to delete?"
 msgstr "Ви впевнені, що хочете видалити?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 "Ви впевнені, що бажаєте перезавантажити Nginx на наступних вузлах "
@@ -429,7 +429,7 @@ msgstr "Ви впевнені, що хочете видалити цей еле
 msgid "Are you sure you want to remove this location?"
 msgstr "Ви впевнені, що хочете видалити цю локацію?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 "Ви впевнені, що хочете перезавантажити Nginx на вказаних синхронізованих "
@@ -1843,7 +1843,7 @@ msgstr "Зміст файлу контрольної суми порожній"
 msgid "DingTalk"
 msgstr "ДінТок"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Пряма"
 
@@ -3179,7 +3179,7 @@ msgstr "Рівень стиснення GZIP"
 msgid "GZIP Min Length"
 msgstr "Мінімальна довжина GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Перевірка стану"
 
@@ -3195,7 +3195,7 @@ msgstr "Конфігурацію перевірки стану збережен
 msgid "Health check configuration saved successfully"
 msgstr "Конфігурацію перевірки стану успішно збережено"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Стан здоров’я"
 
@@ -3634,7 +3634,7 @@ msgstr "Статус останнього резервного копіюван
 msgid "Last Backup Time"
 msgstr "Час останньої резервної копії"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Остання перевірка"
 
@@ -3768,7 +3768,7 @@ msgstr "Завантаження даних..."
 msgid "Loading..."
 msgstr "Завантаження..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4452,8 +4452,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf включає каталог streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4485,7 +4485,7 @@ msgstr "Географічні дані Китаю недоступні"
 msgid "No data"
 msgstr "Немає даних"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Немає даних"
 
@@ -4687,12 +4687,12 @@ msgstr "Вимкнено"
 msgid "Official Document"
 msgstr "Офіційна документація"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Офлайн"
 
@@ -4725,13 +4725,13 @@ msgstr "Увімкнено"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Після завершення перевірки записи будуть видалені."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "Онлайн"
 
@@ -5429,7 +5429,7 @@ msgid "Reload"
 msgstr "Перезавантажити"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Перезавантажити Nginx"
@@ -5454,7 +5454,7 @@ msgstr "Помилка перезавантаження віддаленого N
 msgid "Reload Remote Nginx Success"
 msgstr "Успішне перезавантаження віддаленого Nginx"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
@@ -5644,7 +5644,7 @@ msgstr "Відповіді"
 msgid "Restart"
 msgstr "Перезавантажити"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Перезапустити Nginx"
@@ -5665,7 +5665,7 @@ msgstr "Помилка перезапуску віддаленого Nginx"
 msgid "Restart Remote Nginx Success"
 msgstr "Віддалений перезапуск Nginx успішний"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
@@ -6529,7 +6529,7 @@ msgid "Sync Config Success"
 msgstr "Успішна синхронізація конфігурації"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Синхронізовані вузли"
@@ -7039,6 +7039,10 @@ msgstr "Топ-10 URL-адрес"
 msgid "Total"
 msgstr "Всього"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Всього %{total} елементів"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Всього компонентів"
@@ -7249,7 +7253,7 @@ msgid "Upload Folders"
 msgstr "Завантажити папки"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Вгору за течією"
 
@@ -7257,7 +7261,7 @@ msgstr "Вгору за течією"
 msgid "Upstream Name"
 msgstr "Назва апстріму"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Сокети Upstream"
 
@@ -7559,8 +7563,8 @@ msgstr "Запис приватного ключа сертифіката на 
 msgid "Writing certificate to disk"
 msgstr "Запис сертифіката на диск"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/vi_VN/app.po

@@ -401,7 +401,7 @@ msgstr "Bạn có chắc chắn muốn xóa vĩnh viễn không?"
 msgid "Are you sure you want to delete?"
 msgstr "Bạn có chắc chắn muốn xóa không?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "Bạn có chắc chắn muốn tải lại Nginx trên các nút đồng bộ sau không?"
 
@@ -417,7 +417,7 @@ msgstr "Bạn có chắc chắn muốn xóa mục này không?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Bạn có chắc chắn muốn xóa vị trí này không?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "Bạn có chắc chắn muốn khởi động lại Nginx trên các nút đồng bộ sau không?"
 
@@ -1746,7 +1746,7 @@ msgstr "Nội dung tệp tiêu đề trống"
 msgid "DingTalk"
 msgstr "DingTalk"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "Trực tiếp"
 
@@ -3079,7 +3079,7 @@ msgstr "Mức độ nén GZIP"
 msgid "GZIP Min Length"
 msgstr "Độ dài tối thiểu GZIP"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "Kiểm tra sức khỏe"
 
@@ -3095,7 +3095,7 @@ msgstr "Đã lưu cấu hình kiểm tra trạng thái"
 msgid "Health check configuration saved successfully"
 msgstr "Cấu hình kiểm tra sức khỏe đã được lưu thành công"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "Trạng thái sức khỏe"
 
@@ -3533,7 +3533,7 @@ msgstr "Trạng thái sao lưu cuối cùng"
 msgid "Last Backup Time"
 msgstr "Thời gian sao lưu cuối cùng"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "Lần kiểm tra cuối"
 
@@ -3667,7 +3667,7 @@ msgstr "Đang tải dữ liệu..."
 msgid "Loading..."
 msgstr "Đang tải..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4351,8 +4351,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf bao gồm thư mục streams-enabled"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4384,7 +4384,7 @@ msgstr "Không có dữ liệu địa lý Trung Quốc"
 msgid "No data"
 msgstr "Không có dữ liệu"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "Không có dữ liệu"
 
@@ -4583,12 +4583,12 @@ msgstr "Tắt"
 msgid "Official Document"
 msgstr "Tài liệu chính thức"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "Ngoại tuyến"
 
@@ -4621,13 +4621,13 @@ msgstr "Bật"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "Trực tuyến"
 
@@ -5314,7 +5314,7 @@ msgid "Reload"
 msgstr "Tải lại"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "Tải lại Nginx"
@@ -5339,7 +5339,7 @@ msgstr "Lỗi tải lại Nginx từ xa"
 msgid "Reload Remote Nginx Success"
 msgstr "Tải lại Nginx từ xa thành công"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "Yêu cầu tải lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 
@@ -5527,7 +5527,7 @@ msgstr "Phản hồi"
 msgid "Restart"
 msgstr "Khởi động lại"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "Khởi động lại Nginx"
@@ -5548,7 +5548,7 @@ msgstr "Lỗi khởi động lại Nginx từ xa"
 msgid "Restart Remote Nginx Success"
 msgstr "Khởi động lại Nginx từ xa thành công"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "Yêu cầu khởi động lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 
@@ -6404,7 +6404,7 @@ msgid "Sync Config Success"
 msgstr "Đồng bộ cấu hình thành công"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "Nút đồng bộ"
@@ -6914,6 +6914,10 @@ msgstr "10 URL hàng đầu"
 msgid "Total"
 msgstr "Tổng"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "Tổng %{total} mục"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "Tổng số thành phần"
@@ -7124,7 +7128,7 @@ msgid "Upload Folders"
 msgstr "Tải lên thư mục"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "Ngược dòng"
 
@@ -7132,7 +7136,7 @@ msgstr "Ngược dòng"
 msgid "Upstream Name"
 msgstr "Tên Upstream"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "Các cổng Upstream"
 
@@ -7431,8 +7435,8 @@ msgstr "Ghi Private Key vào disk"
 msgid "Writing certificate to disk"
 msgstr "Ghi chứng chỉ vào disk"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/zh_CN/app.po

@@ -393,7 +393,7 @@ msgstr "确定要永久删除吗?"
 msgid "Are you sure you want to delete?"
 msgstr "您确定要删除吗?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "你确定要在以下同步节点上重载 Nginx?"
 
@@ -409,7 +409,7 @@ msgstr "您确定要删除这个项目吗?"
 msgid "Are you sure you want to remove this location?"
 msgstr "您确定要删除这个 Location?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "你确定要在以下同步节点上重启 Nginx 吗?"
 
@@ -1707,7 +1707,7 @@ msgstr "摘要文件内容为空"
 msgid "DingTalk"
 msgstr "钉钉"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "直接"
 
@@ -3013,7 +3013,7 @@ msgstr "GZIP 压缩级别"
 msgid "GZIP Min Length"
 msgstr "GZIP 最小长度"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "健康检查"
 
@@ -3029,7 +3029,7 @@ msgstr "健康检查配置已保存"
 msgid "Health check configuration saved successfully"
 msgstr "健康检查配置保存成功"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "健康状态"
 
@@ -3455,7 +3455,7 @@ msgstr "上次备份状态"
 msgid "Last Backup Time"
 msgstr "上次备份时间"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "最后检查"
 
@@ -3589,7 +3589,7 @@ msgstr "正在加载数据..."
 msgid "Loading..."
 msgstr "加载中..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4262,8 +4262,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "检查 nginx.conf 是否包含 streams-enabled 的目录"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4295,7 +4295,7 @@ msgstr "无中国地理数据"
 msgid "No data"
 msgstr "没有数据"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "无数据"
 
@@ -4486,12 +4486,12 @@ msgstr "关闭"
 msgid "Official Document"
 msgstr "官方文档"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "离线"
 
@@ -4524,13 +4524,13 @@ msgstr "开启"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "一旦验证完成,这些记录将被删除。"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "在线"
 
@@ -5199,7 +5199,7 @@ msgid "Reload"
 msgstr "重载"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "重载 Nginx"
@@ -5224,7 +5224,7 @@ msgstr "重载远程 Nginx 错误"
 msgid "Reload Remote Nginx Success"
 msgstr "重载远程 Nginx 成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "重载请求失败,请检查网络连接"
 
@@ -5409,7 +5409,7 @@ msgstr "响应"
 msgid "Restart"
 msgstr "重启"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "重启 Nginx"
@@ -5430,7 +5430,7 @@ msgstr "重启远程 Nginx 错误"
 msgid "Restart Remote Nginx Success"
 msgstr "重启远程 Nginx 成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "重启请求失败,请检查网络连接"
 
@@ -6274,7 +6274,7 @@ msgid "Sync Config Success"
 msgstr "同步配置成功"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "同步节点"
@@ -6728,6 +6728,10 @@ msgstr "前 10 个 URL"
 msgid "Total"
 msgstr "总计"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "总计 %{total} 项"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "总组件数"
@@ -6936,7 +6940,7 @@ msgid "Upload Folders"
 msgstr "上传文件夹"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "上游"
 
@@ -6944,7 +6948,7 @@ msgstr "上游"
 msgid "Upstream Name"
 msgstr "Upstream 名称"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "上游套接字"
 
@@ -7230,8 +7234,8 @@ msgstr "正在将证书私钥写入磁盘"
 msgid "Writing certificate to disk"
 msgstr "正在将证书写入磁盘"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 27 - 23
app/src/language/zh_TW/app.po

@@ -397,7 +397,7 @@ msgstr "確定要永久刪除嗎?"
 msgid "Are you sure you want to delete?"
 msgstr "您確定要刪除嗎?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:142
+#: src/components/NamespaceTabs/NamespaceTabs.vue:134
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "您確定要在以下同步節點上重新載入 Nginx 嗎?"
 
@@ -413,7 +413,7 @@ msgstr "您確定要刪除此項目嗎?"
 msgid "Are you sure you want to remove this location?"
 msgstr "您確定要刪除此 Location 嗎?"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:154
+#: src/components/NamespaceTabs/NamespaceTabs.vue:146
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "您確定要在以下同步節點上重新啟動 Nginx 嗎?"
 
@@ -1711,7 +1711,7 @@ msgstr "摘要檔案內容為空"
 msgid "DingTalk"
 msgstr "釘釘"
 
-#: src/views/upstream/SocketList.vue:31
+#: src/views/upstream/SocketList.vue:30
 msgid "Direct"
 msgstr "直接"
 
@@ -3017,7 +3017,7 @@ msgstr "GZIP 壓縮等級"
 msgid "GZIP Min Length"
 msgstr "GZIP 最小長度"
 
-#: src/views/upstream/SocketList.vue:61
+#: src/views/upstream/SocketList.vue:60
 msgid "Health Check"
 msgstr "健康檢查"
 
@@ -3033,7 +3033,7 @@ msgstr "健康檢查配置已保存"
 msgid "Health check configuration saved successfully"
 msgstr "健康檢查配置保存成功"
 
-#: src/views/upstream/SocketList.vue:37
+#: src/views/upstream/SocketList.vue:36
 msgid "Health Status"
 msgstr "健康狀態"
 
@@ -3459,7 +3459,7 @@ msgstr "上次備份狀態"
 msgid "Last Backup Time"
 msgstr "上次備份時間"
 
-#: src/views/upstream/SocketList.vue:52
+#: src/views/upstream/SocketList.vue:51
 msgid "Last Check"
 msgstr "最後檢查"
 
@@ -3593,7 +3593,7 @@ msgstr "資料載入中…"
 msgid "Loading..."
 msgstr "載入中..."
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:124
+#: src/components/NamespaceTabs/NamespaceTabs.vue:116
 #: src/components/NodeIndicator/NodeIndicator.vue:38
 #: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:42
 #: src/constants/index.ts:48 src/views/backup/AutoBackup/AutoBackup.vue:74
@@ -4266,8 +4266,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf 包含 streams-enabled 目錄"
 
 #: src/components/LLM/ChatMessageInput.vue:61
-#: src/components/NamespaceTabs/NamespaceTabs.vue:144
-#: src/components/NamespaceTabs/NamespaceTabs.vue:156
+#: src/components/NamespaceTabs/NamespaceTabs.vue:136
+#: src/components/NamespaceTabs/NamespaceTabs.vue:148
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:102
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:109 src/language/curd.ts:40
@@ -4299,7 +4299,7 @@ msgstr "無中國地理數據"
 msgid "No data"
 msgstr "無數據"
 
-#: src/views/upstream/SocketList.vue:42
+#: src/views/upstream/SocketList.vue:41
 msgid "No Data"
 msgstr "無資料"
 
@@ -4490,12 +4490,12 @@ msgstr "關"
 msgid "Official Document"
 msgstr "官方文件"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:159 src/views/node/nodeColumns.tsx:55
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Offline"
 msgstr "離線"
 
@@ -4528,13 +4528,13 @@ msgstr "開啟"
 msgid "Once the verification is complete, the records will be removed."
 msgstr "驗證完成後,記錄將被刪除。"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:172
+#: src/components/NamespaceTabs/NamespaceTabs.vue:164
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:48
 #: src/views/dashboard/Nodes.vue:152 src/views/node/nodeColumns.tsx:51
-#: src/views/upstream/SocketList.vue:46
+#: src/views/upstream/SocketList.vue:45
 msgid "Online"
 msgstr "線上"
 
@@ -5205,7 +5205,7 @@ msgid "Reload"
 msgstr "重新載入"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:44
-#: src/components/NamespaceTabs/NamespaceTabs.vue:149 src/constants/index.ts:38
+#: src/components/NamespaceTabs/NamespaceTabs.vue:141 src/constants/index.ts:38
 #: src/views/node/Node.vue:208 src/views/node/Node.vue:216
 msgid "Reload Nginx"
 msgstr "重新載入 Nginx"
@@ -5230,7 +5230,7 @@ msgstr "重新載入遠端 Nginx 錯誤"
 msgid "Reload Remote Nginx Success"
 msgstr "遠端 Nginx 重新載入成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:93
+#: src/components/NamespaceTabs/NamespaceTabs.vue:85
 msgid "Reload request failed, please check your network connection"
 msgstr "重新載入請求失敗,請檢查您的網路連線"
 
@@ -5415,7 +5415,7 @@ msgstr "回應"
 msgid "Restart"
 msgstr "重新啟動"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:161
+#: src/components/NamespaceTabs/NamespaceTabs.vue:153
 #: src/views/node/Node.vue:229 src/views/node/Node.vue:237
 msgid "Restart Nginx"
 msgstr "重新啟動 Nginx"
@@ -5436,7 +5436,7 @@ msgstr "遠端 Nginx 重啟錯誤"
 msgid "Restart Remote Nginx Success"
 msgstr "遠端 Nginx 重啟成功"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:113
+#: src/components/NamespaceTabs/NamespaceTabs.vue:105
 msgid "Restart request failed, please check your network connection"
 msgstr "重新啟動請求失敗,請檢查您的網路連線"
 
@@ -6280,7 +6280,7 @@ msgid "Sync Config Success"
 msgstr "同步設定成功"
 
 #: src/components/NamespaceRender/NamespaceRender.vue:53
-#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:127
 #: src/views/namespace/columns.ts:17 src/views/namespace/Namespace.vue:31
 msgid "Sync Nodes"
 msgstr "同步節點"
@@ -6734,6 +6734,10 @@ msgstr "前 10 個 URL"
 msgid "Total"
 msgstr "總計"
 
+#: src/views/upstream/SocketList.vue:149
+msgid "Total %{total} items"
+msgstr "總計 %{total} 項"
+
 #: src/views/system/Licenses.vue:107
 msgid "Total Components"
 msgstr "總元件數"
@@ -6942,7 +6946,7 @@ msgid "Upload Folders"
 msgstr "上傳資料夾"
 
 #: src/composables/useUpstreamStatus.ts:132 src/routes/modules/upstream.ts:10
-#: src/views/upstream/SocketList.vue:25
+#: src/views/upstream/SocketList.vue:24
 msgid "Upstream"
 msgstr "上游"
 
@@ -6950,7 +6954,7 @@ msgstr "上游"
 msgid "Upstream Name"
 msgstr "Upstream 名稱"
 
-#: src/views/upstream/SocketList.vue:134
+#: src/views/upstream/SocketList.vue:133
 msgid "Upstream Sockets"
 msgstr "上游套接字"
 
@@ -7236,8 +7240,8 @@ msgstr "將憑證私鑰寫入磁碟"
 msgid "Writing certificate to disk"
 msgstr "將憑證寫入磁碟"
 
-#: src/components/NamespaceTabs/NamespaceTabs.vue:143
-#: src/components/NamespaceTabs/NamespaceTabs.vue:155
+#: src/components/NamespaceTabs/NamespaceTabs.vue:135
+#: src/components/NamespaceTabs/NamespaceTabs.vue:147
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:101
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/nginx_log/indexing/IndexManagement.vue:31

+ 272 - 151
internal/cache/index.go

@@ -25,6 +25,69 @@ type CallbackInfo struct {
 	Callback ScanCallback
 }
 
+// PostScanCallback is called after all scan callbacks are executed
+type PostScanCallback func()
+
+// ScanConfig holds scanner configuration
+type ScanConfig struct {
+	PeriodicScanInterval    time.Duration
+	InitialScanTimeout      time.Duration
+	ScanTimeoutGrace        time.Duration
+	FileEventDebounce       time.Duration
+	MaxFileSize             int64
+	CallbackTimeout         time.Duration
+	PostCallbackTimeout     time.Duration
+	ShutdownTimeout         time.Duration
+	ForceCleanupTimeout     time.Duration
+	InitialScanWaitTimeout  time.Duration
+}
+
+// DefaultScanConfig returns default configuration
+func DefaultScanConfig() ScanConfig {
+	return ScanConfig{
+		PeriodicScanInterval:   5 * time.Minute,
+		InitialScanTimeout:     15 * time.Second,
+		ScanTimeoutGrace:       2 * time.Second,
+		FileEventDebounce:      100 * time.Millisecond,
+		MaxFileSize:            1024 * 1024, // 1MB
+		CallbackTimeout:        5 * time.Second,
+		PostCallbackTimeout:    10 * time.Second,
+		ShutdownTimeout:        10 * time.Second,
+		ForceCleanupTimeout:    3 * time.Second,
+		InitialScanWaitTimeout: 30 * time.Second,
+	}
+}
+
+var (
+	postScanCallbacks      = make([]PostScanCallback, 0)
+	postScanCallbacksMutex sync.RWMutex
+	scanConfig             = DefaultScanConfig()
+)
+
+// runWithTimeout executes a function with timeout and panic protection
+func runWithTimeout(fn func(), timeout time.Duration, name string) error {
+	done := make(chan struct{})
+	var panicErr error
+
+	go func() {
+		defer func() {
+			if r := recover(); r != nil {
+				panicErr = fmt.Errorf("panic: %v", r)
+				logger.Errorf("%s panic: %v", name, r)
+			}
+			close(done)
+		}()
+		fn()
+	}()
+
+	select {
+	case <-done:
+		return panicErr
+	case <-time.After(timeout):
+		return fmt.Errorf("timeout after %v", timeout)
+	}
+}
+
 // Scanner watches and scans nginx config files
 type Scanner struct {
 	ctx        context.Context
@@ -34,6 +97,56 @@ type Scanner struct {
 	scanning   bool
 	scanMutex  sync.RWMutex
 	wg         sync.WaitGroup // Track running goroutines
+	debouncer  *fileEventDebouncer
+}
+
+// fileEventDebouncer prevents rapid repeated scans of the same file
+type fileEventDebouncer struct {
+	mu      sync.Mutex
+	timers  map[string]*time.Timer
+	stopped bool
+}
+
+func newFileEventDebouncer() *fileEventDebouncer {
+	return &fileEventDebouncer{
+		timers: make(map[string]*time.Timer),
+	}
+}
+
+func (d *fileEventDebouncer) debounce(filePath string, delay time.Duration, fn func()) {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+
+	// Don't create new timers if stopped
+	if d.stopped {
+		return
+	}
+
+	// Cancel existing timer if present
+	if timer, exists := d.timers[filePath]; exists {
+		timer.Stop()
+	}
+
+	// Create new timer
+	d.timers[filePath] = time.AfterFunc(delay, func() {
+		fn()
+		// Cleanup
+		d.mu.Lock()
+		delete(d.timers, filePath)
+		d.mu.Unlock()
+	})
+}
+
+func (d *fileEventDebouncer) stop() {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+
+	d.stopped = true
+	// Stop and clear all pending timers
+	for path, timer := range d.timers {
+		timer.Stop()
+		delete(d.timers, path)
+	}
 }
 
 var (
@@ -42,8 +155,9 @@ var (
 	scanCallbacks      = make([]CallbackInfo, 0)
 	scanCallbacksMutex sync.RWMutex
 	// Channel to signal when initial scan and all callbacks are completed
-	initialScanComplete chan struct{}
-	initialScanOnce     sync.Once
+	initialScanComplete   chan struct{}
+	initialScanOnce       sync.Once
+	initialScanCompleteMu sync.Mutex // Protects initialScanComplete channel access
 )
 
 // InitScanner initializes the config scanner
@@ -64,28 +178,36 @@ func InitScanner(ctx context.Context) {
 	}
 }
 
+var (
+	excludedDirs     []string
+	excludedDirsOnce sync.Once
+)
+
+// getExcludedDirs returns cached list of excluded directories
+func getExcludedDirs() []string {
+	excludedDirsOnce.Do(func() {
+		excludedDirs = []string{
+			nginx.GetConfPath("ssl"),
+			nginx.GetConfPath("cache"),
+			nginx.GetConfPath("logs"),
+			nginx.GetConfPath("temp"),
+			nginx.GetConfPath("proxy_temp"),
+			nginx.GetConfPath("client_body_temp"),
+			nginx.GetConfPath("fastcgi_temp"),
+			nginx.GetConfPath("uwsgi_temp"),
+			nginx.GetConfPath("scgi_temp"),
+		}
+	})
+	return excludedDirs
+}
+
 // shouldSkipPath checks if a path should be skipped during scanning or watching
 func shouldSkipPath(path string) bool {
-	// Define directories to exclude from scanning/watching
-	excludedDirs := []string{
-		nginx.GetConfPath("ssl"),              // SSL certificates and keys
-		nginx.GetConfPath("cache"),            // Nginx cache files
-		nginx.GetConfPath("logs"),             // Log files directory
-		nginx.GetConfPath("temp"),             // Temporary files directory
-		nginx.GetConfPath("proxy_temp"),       // Proxy temporary files
-		nginx.GetConfPath("client_body_temp"), // Client body temporary files
-		nginx.GetConfPath("fastcgi_temp"),     // FastCGI temporary files
-		nginx.GetConfPath("uwsgi_temp"),       // uWSGI temporary files
-		nginx.GetConfPath("scgi_temp"),        // SCGI temporary files
-	}
-
-	// Check if path starts with any excluded directory
-	for _, excludedDir := range excludedDirs {
+	for _, excludedDir := range getExcludedDirs() {
 		if excludedDir != "" && strings.HasPrefix(path, excludedDir) {
 			return true
 		}
 	}
-
 	return false
 }
 
@@ -95,7 +217,9 @@ func GetScanner() *Scanner {
 	defer scannerInitMutex.Unlock()
 
 	if scanner == nil {
-		scanner = &Scanner{}
+		scanner = &Scanner{
+			debouncer: newFileEventDebouncer(),
+		}
 	}
 	return scanner
 }
@@ -111,11 +235,21 @@ func RegisterCallback(name string, callback ScanCallback) {
 	})
 }
 
+// RegisterPostScanCallback adds a callback to be executed after all scan callbacks complete
+func RegisterPostScanCallback(callback PostScanCallback) {
+	postScanCallbacksMutex.Lock()
+	defer postScanCallbacksMutex.Unlock()
+
+	postScanCallbacks = append(postScanCallbacks, callback)
+}
+
 // Initialize sets up the scanner and starts watching
 func (s *Scanner) Initialize(ctx context.Context) error {
-	// Initialize the completion channel for this scan cycle
+	// Initialize the completion channel for this scan cycle with lock protection
+	initialScanCompleteMu.Lock()
 	initialScanComplete = make(chan struct{})
 	initialScanOnce = sync.Once{} // Reset for this initialization
+	initialScanCompleteMu.Unlock()
 
 	// Create cancellable context for this scanner instance
 	s.ctx, s.cancel = context.WithCancel(ctx)
@@ -131,31 +265,18 @@ func (s *Scanner) Initialize(ctx context.Context) error {
 		return err
 	}
 
-	// Start background processes with WaitGroup tracking
+	// Start background processes
 	s.wg.Go(func() {
-		logger.Debug("Started cache watchForChanges goroutine")
 		s.watchForChanges()
-		logger.Info("Cache watchForChanges goroutine completed")
 	})
 
 	s.wg.Go(func() {
-		logger.Debug("Started cache periodicScan goroutine")
 		s.periodicScan()
-		logger.Info("Cache periodicScan goroutine completed")
-	})
-
-	s.wg.Go(func() {
-		logger.Debug("Started cache handleShutdown goroutine")
-		s.handleShutdown()
-		logger.Info("Cache handleShutdown goroutine completed")
 	})
 
 	// Perform initial scan asynchronously to avoid blocking boot process
-	// Pass the context to ensure proper cancellation
 	s.wg.Go(func() {
-		logger.Debug("Started cache initialScanAsync goroutine")
 		s.initialScanAsync(ctx)
-		logger.Debug("Cache initialScanAsync goroutine completed")
 	})
 
 	return nil
@@ -198,9 +319,9 @@ func (s *Scanner) watchAllDirectories() error {
 	})
 }
 
-// periodicScan runs periodic scans every 5 minutes
+// periodicScan runs periodic scans
 func (s *Scanner) periodicScan() {
-	s.scanTicker = time.NewTicker(5 * time.Minute)
+	s.scanTicker = time.NewTicker(scanConfig.PeriodicScanInterval)
 	defer s.scanTicker.Stop()
 
 	for {
@@ -216,14 +337,6 @@ func (s *Scanner) periodicScan() {
 	}
 }
 
-// handleShutdown listens for context cancellation and shuts down gracefully
-func (s *Scanner) handleShutdown() {
-	<-s.ctx.Done()
-	logger.Debug("Shutting down Index Scanner")
-	// Note: Don't call s.Shutdown() here as it would cause deadlock
-	// Shutdown is called externally, this just handles cleanup
-}
-
 // initialScanAsync performs the initial config scan asynchronously
 func (s *Scanner) initialScanAsync(ctx context.Context) {
 	// Always use the provided context, not the scanner's internal context
@@ -278,7 +391,7 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 	logger.Debugf("Scanning config directory: %s", root)
 
 	// Create a timeout context for the scan operation
-	scanCtx, scanCancel := context.WithTimeout(ctx, 15*time.Second)
+	scanCtx, scanCancel := context.WithTimeout(ctx, scanConfig.InitialScanTimeout)
 	defer scanCancel()
 
 	// Scan all files in the config directory and subdirectories
@@ -294,6 +407,13 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 
 	// Run custom directory traversal in a goroutine to avoid WalkDir blocking issues
 	go func() {
+		defer func() {
+			if r := recover(); r != nil {
+				logger.Errorf("Scan goroutine panic: %v", r)
+				resultChan <- scanResult{err: fmt.Errorf("panic during scan: %v", r)}
+			}
+		}()
+
 		fileCount := 0
 		dirCount := 0
 
@@ -309,11 +429,12 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 	}()
 
 	// Wait for scan to complete or timeout
+	var scanErr error
 	select {
 	case result := <-resultChan:
 		logger.Debugf("Scan completed successfully: dirs=%d, files=%d, error=%v",
 			result.dirCount, result.fileCount, result.err)
-		return result.err
+		scanErr = result.err
 	case <-scanCtx.Done():
 		logger.Warnf("Scan timed out after 25 seconds - cancelling")
 		scanCancel()
@@ -322,12 +443,19 @@ func (s *Scanner) scanAllConfigsWithContext(ctx context.Context) error {
 		case result := <-resultChan:
 			logger.Debugf("Scan completed after timeout: dirs=%d, files=%d, error=%v",
 				result.dirCount, result.fileCount, result.err)
-			return result.err
-		case <-time.After(2 * time.Second):
+			scanErr = result.err
+		case <-time.After(scanConfig.ScanTimeoutGrace):
 			logger.Warn("Scan failed to complete even after timeout - forcing return")
-			return ctx.Err()
+			scanErr = ctx.Err()
 		}
 	}
+
+	// Trigger post-scan callbacks once after all files are scanned
+	if scanErr == nil {
+		s.executePostScanCallbacks()
+	}
+
+	return scanErr
 }
 
 // watchForChanges handles file system events
@@ -377,9 +505,12 @@ func (s *Scanner) handleFileEvent(event fsnotify.Event) {
 		}
 	}
 
-	// Handle file changes
+	// Handle file removal - need to trigger rescan to update indices
 	if event.Has(fsnotify.Remove) {
 		logger.Debug("Config removed:", event.Name)
+		// Trigger callbacks with empty content to allow them to clean up their indices
+		// Don't skip post-scan for single file events (manual operations)
+		s.executeCallbacks(event.Name, []byte{}, false)
 		return
 	}
 
@@ -408,13 +539,21 @@ func (s *Scanner) handleFileEvent(event fsnotify.Event) {
 		logger.Debug("Directory changed:", event.Name)
 	} else {
 		logger.Debug("File changed:", event.Name)
-		time.Sleep(100 * time.Millisecond) // Allow file write to complete
-		s.scanSingleFile(event.Name)
+		// Use debouncer to avoid rapid repeated scans
+		s.debouncer.debounce(event.Name, scanConfig.FileEventDebounce, func() {
+			s.scanSingleFile(event.Name)
+		})
 	}
 }
 
 // scanSingleFile scans a single config file without recursion
+// skipPostScan: if true, skip post-scan callbacks (used during batch scans)
 func (s *Scanner) scanSingleFile(filePath string) error {
+	return s.scanSingleFileInternal(filePath, false)
+}
+
+// scanSingleFileInternal is the internal implementation with post-scan control
+func (s *Scanner) scanSingleFileInternal(filePath string, skipPostScan bool) error {
 	s.setScanningState(true)
 	defer s.setScanningState(false)
 
@@ -462,8 +601,8 @@ func (s *Scanner) scanSingleFile(filePath string) error {
 		return nil
 	}
 
-	// Skip files larger than 1MB before reading
-	if fileInfo.Size() > 1024*1024 {
+	// Skip files larger than max size before reading
+	if fileInfo.Size() > scanConfig.MaxFileSize {
 		logger.Debugf("Skipping large file: %s (size: %d bytes)", filePath, fileInfo.Size())
 		return nil
 	}
@@ -476,7 +615,7 @@ func (s *Scanner) scanSingleFile(filePath string) error {
 	}
 
 	// Execute callbacks
-	s.executeCallbacks(filePath, content)
+	s.executeCallbacks(filePath, content, skipPostScan)
 
 	return nil
 }
@@ -496,11 +635,13 @@ func (s *Scanner) setScanningState(scanning bool) {
 }
 
 // executeCallbacks runs all registered callbacks
-func (s *Scanner) executeCallbacks(filePath string, content []byte) {
+func (s *Scanner) executeCallbacks(filePath string, content []byte, skipPostScan bool) {
 	scanCallbacksMutex.RLock()
-	defer scanCallbacksMutex.RUnlock()
+	callbacksCopy := make([]CallbackInfo, len(scanCallbacks))
+	copy(callbacksCopy, scanCallbacks)
+	scanCallbacksMutex.RUnlock()
 
-	for i, callbackInfo := range scanCallbacks {
+	for i, callbackInfo := range callbacksCopy {
 		// Add timeout protection for each callback
 		done := make(chan error, 1)
 		go func() {
@@ -512,11 +653,31 @@ func (s *Scanner) executeCallbacks(filePath string, content []byte) {
 			if err != nil {
 				logger.Errorf("Callback error for %s in '%s': %v", filePath, callbackInfo.Name, err)
 			}
-		case <-time.After(5 * time.Second):
-			logger.Errorf("Callback [%d/%d] '%s' timed out after 5 seconds for: %s", i+1, len(scanCallbacks), callbackInfo.Name, filePath)
+		case <-time.After(scanConfig.CallbackTimeout):
+			logger.Errorf("Callback [%d/%d] '%s' timed out after %v for: %s", i+1, len(callbacksCopy), callbackInfo.Name, scanConfig.CallbackTimeout, filePath)
 			// Continue with next callback instead of blocking forever
 		}
 	}
+
+	// Execute post-scan callbacks only if not skipped (used for batch scans)
+	if !skipPostScan {
+		s.executePostScanCallbacks()
+	}
+}
+
+// executePostScanCallbacks runs all registered post-scan callbacks
+func (s *Scanner) executePostScanCallbacks() {
+	postScanCallbacksMutex.RLock()
+	postCallbacksCopy := make([]PostScanCallback, len(postScanCallbacks))
+	copy(postCallbacksCopy, postScanCallbacks)
+	postScanCallbacksMutex.RUnlock()
+
+	for i, callback := range postCallbacksCopy {
+		name := fmt.Sprintf("Post-scan callback [%d/%d]", i+1, len(postCallbacksCopy))
+		if err := runWithTimeout(callback, scanConfig.PostCallbackTimeout, name); err != nil {
+			logger.Errorf("%s error: %v", name, err)
+		}
+	}
 }
 
 // ScanAllConfigs scans all nginx configuration files
@@ -525,48 +686,31 @@ func (s *Scanner) ScanAllConfigs() error {
 	defer s.setScanningState(false)
 
 	root := nginx.GetConfPath()
+	fileCount := 0
+	dirCount := 0
 
-	// Scan all files in the config directory and subdirectories
-	return filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
-		if err != nil {
-			return err
-		}
-
-		// Skip excluded directories (ssl, cache, logs, temp, etc.)
-		if d.IsDir() && shouldSkipPath(path) {
-			return filepath.SkipDir
-		}
-
-		// Handle symlinks to directories specially
-		if d.Type()&os.ModeSymlink != 0 {
-			if targetInfo, err := os.Stat(path); err == nil && targetInfo.IsDir() {
-				// This is a symlink to a directory, we should traverse its contents
-				// but not process the symlink itself as a file
-				logger.Debug("Found symlink to directory, will traverse contents:", path)
+	// Use the unified recursive scan logic with no timeout
+	err := s.scanDirectoryRecursive(context.Background(), root, &fileCount, &dirCount)
 
-				// Manually scan the symlink target directory since WalkDir doesn't follow symlinks
-				if err := s.scanSymlinkDirectory(path); err != nil {
-					logger.Error("Failed to scan symlink directory:", path, err)
-				}
-				return nil
-			}
-		}
+	logger.Debugf("Scan completed: %d directories, %d files processed", dirCount, fileCount)
 
-		// Only process regular files (not directories, not symlinks to directories)
-		if !d.IsDir() {
-			if err := s.scanSingleFile(path); err != nil {
-				logger.Error("Failed to scan config:", path, err)
-			}
-		}
+	// Trigger post-scan callbacks once after all files are scanned
+	if err == nil {
+		s.executePostScanCallbacks()
+	}
 
-		return nil
-	})
+	return err
 }
 
 // scanDirectoryRecursive implements custom recursive directory traversal
 // to avoid filepath.WalkDir blocking issues on restart
 func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileCount, dirCount *int) error {
+	visited := make(map[string]bool)
+	return s.scanDirectoryRecursiveInternal(ctx, root, fileCount, dirCount, visited)
+}
 
+// scanDirectoryRecursiveInternal is the internal implementation with symlink loop detection
+func (s *Scanner) scanDirectoryRecursiveInternal(ctx context.Context, root string, fileCount, dirCount *int, visited map[string]bool) error {
 	// Check for context cancellation
 	select {
 	case <-ctx.Done():
@@ -574,6 +718,20 @@ func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileC
 	default:
 	}
 
+	// Resolve symlinks and check for loops
+	realPath, err := filepath.EvalSymlinks(root)
+	if err != nil {
+		// If we can't resolve, use original path
+		realPath = root
+	}
+
+	// Check if already visited (prevents symlink loops)
+	if visited[realPath] {
+		logger.Debugf("Skipping already visited path (symlink loop): %s -> %s", root, realPath)
+		return nil
+	}
+	visited[realPath] = true
+
 	// Read directory entries
 	entries, err := os.ReadDir(root)
 	if err != nil {
@@ -608,10 +766,10 @@ func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileC
 				continue
 			}
 
-			// Recursively scan subdirectory
-			if err := s.scanDirectoryRecursive(ctx, fullPath, fileCount, dirCount); err != nil {
+			// Recursively scan subdirectory - continue on error to scan other directories
+			if err := s.scanDirectoryRecursiveInternal(ctx, fullPath, fileCount, dirCount, visited); err != nil {
 				logger.Errorf("Failed to scan subdirectory %s: %v", fullPath, err)
-				return err
+				// Continue with other directories instead of failing completely
 			}
 		} else {
 			(*fileCount)++
@@ -621,10 +779,9 @@ func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileC
 				targetInfo, err := os.Stat(fullPath)
 				if err == nil {
 					if targetInfo.IsDir() {
-						// Recursively scan symlink directory
-						if err := s.scanDirectoryRecursive(ctx, fullPath, fileCount, dirCount); err != nil {
+						// Recursively scan symlink directory (with loop detection)
+						if err := s.scanDirectoryRecursiveInternal(ctx, fullPath, fileCount, dirCount, visited); err != nil {
 							logger.Errorf("Failed to scan symlink directory %s: %v", fullPath, err)
-							// Continue with other entries instead of failing completely
 						}
 						continue
 					}
@@ -633,10 +790,9 @@ func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileC
 				}
 			}
 
-			// Process regular files
-			if err := s.scanSingleFile(fullPath); err != nil {
+			// Process regular files - skip post-scan during batch scan
+			if err := s.scanSingleFileInternal(fullPath, true); err != nil {
 				logger.Errorf("Failed to scan file %s: %v", fullPath, err)
-				// Continue with other files instead of failing completely
 			}
 		}
 	}
@@ -644,51 +800,6 @@ func (s *Scanner) scanDirectoryRecursive(ctx context.Context, root string, fileC
 	return nil
 }
 
-// scanSymlinkDirectory recursively scans a symlink directory and its contents
-func (s *Scanner) scanSymlinkDirectory(symlinkPath string) error {
-	logger.Debugf("scanSymlinkDirectory START: %s", symlinkPath)
-	// Resolve the symlink to get the actual target path
-	targetPath, err := filepath.EvalSymlinks(symlinkPath)
-	if err != nil {
-		logger.Errorf("Failed to resolve symlink %s: %v", symlinkPath, err)
-		return fmt.Errorf("failed to resolve symlink %s: %w", symlinkPath, err)
-	}
-
-	logger.Debug("Scanning symlink directory contents:", symlinkPath, "->", targetPath)
-
-	// Use WalkDir on the resolved target path
-	walkErr := filepath.WalkDir(targetPath, func(path string, d fs.DirEntry, err error) error {
-		logger.Debugf("scanSymlinkDirectory callback: %s (type: %s)", path, d.Type().String())
-		if err != nil {
-			return err
-		}
-
-		// Skip excluded directories
-		if d.IsDir() && shouldSkipPath(path) {
-			return filepath.SkipDir
-		}
-
-		// Only process regular files (not directories, not symlinks to directories)
-		if !d.IsDir() {
-			// Handle symlinks to directories (skip them)
-			if d.Type()&os.ModeSymlink != 0 {
-				if targetInfo, err := os.Stat(path); err == nil && targetInfo.IsDir() {
-					logger.Debug("Skipping symlink to directory in symlink scan:", path)
-					return nil
-				}
-			}
-
-			if err := s.scanSingleFile(path); err != nil {
-				logger.Error("Failed to scan config in symlink directory:", path, err)
-			}
-		}
-		logger.Debugf("scanSymlinkDirectory callback exit: %s", path)
-		return nil
-	})
-	logger.Debugf("scanSymlinkDirectory END: %s -> %s (error: %v)", symlinkPath, targetPath, walkErr)
-	return walkErr
-}
-
 // Shutdown cleans up scanner resources
 func (s *Scanner) Shutdown() {
 	logger.Info("Starting scanner shutdown...")
@@ -698,6 +809,11 @@ func (s *Scanner) Shutdown() {
 		s.cancel()
 	}
 
+	// Stop debouncer to prevent new scans
+	if s.debouncer != nil {
+		s.debouncer.stop()
+	}
+
 	// Close watcher first to stop file events
 	if s.watcher != nil {
 		s.watcher.Close()
@@ -720,7 +836,7 @@ func (s *Scanner) Shutdown() {
 	select {
 	case <-done:
 		logger.Info("All scanner goroutines completed successfully")
-	case <-time.After(10 * time.Second):
+	case <-time.After(scanConfig.ShutdownTimeout):
 		logger.Warn("Timeout waiting for scanner goroutines to complete")
 	}
 
@@ -786,7 +902,7 @@ func ForceReleaseResources() {
 		select {
 		case <-done:
 			logger.Info("All scanner goroutines terminated successfully")
-		case <-time.After(3 * time.Second):
+		case <-time.After(scanConfig.ForceCleanupTimeout):
 			logger.Warn("Timeout waiting for scanner goroutines - proceeding with force cleanup")
 		}
 
@@ -797,7 +913,12 @@ func ForceReleaseResources() {
 // WaitForInitialScanComplete waits for the initial config scan and all callbacks to complete
 // This is useful for services that depend on site indexing to be ready
 func WaitForInitialScanComplete() {
-	if initialScanComplete == nil {
+	// Get channel reference with lock to avoid race
+	initialScanCompleteMu.Lock()
+	ch := initialScanComplete
+	initialScanCompleteMu.Unlock()
+
+	if ch == nil {
 		logger.Debug("Initial scan completion channel not initialized, returning immediately")
 		return
 	}
@@ -806,9 +927,9 @@ func WaitForInitialScanComplete() {
 
 	// Add timeout to prevent infinite waiting
 	select {
-	case <-initialScanComplete:
+	case <-ch:
 		logger.Debug("Initial config scan completion confirmed")
-	case <-time.After(30 * time.Second):
+	case <-time.After(scanConfig.InitialScanWaitTimeout):
 		logger.Warn("Timeout waiting for initial config scan completion - proceeding anyway")
 	}
 }

+ 10 - 18
internal/site/index.go

@@ -20,26 +20,33 @@ type Index struct {
 }
 
 var (
-	IndexedSites = make(map[string]*Index)
+	IndexedSites   = make(map[string]*Index)
 	siteIndexMutex sync.RWMutex
 )
 
 func GetIndexedSite(path string) *Index {
 	siteIndexMutex.RLock()
 	defer siteIndexMutex.RUnlock()
-	
+
 	if site, ok := IndexedSites[path]; ok {
 		return site
 	}
 	return &Index{}
 }
 
-
 func init() {
 	cache.RegisterCallback("site.scanForSite", scanForSite)
 }
 
 func scanForSite(configPath string, content []byte) error {
+	// Handle file removal - clean up the index entry
+	if len(content) == 0 {
+		siteIndexMutex.Lock()
+		delete(IndexedSites, filepath.Base(configPath))
+		siteIndexMutex.Unlock()
+		return nil
+	}
+
 	// Regular expressions for server_name and listen directives
 	serverNameRegex := regexp.MustCompile(`(?m)server_name\s+([^;]+);`)
 	listenRegex := regexp.MustCompile(`(?m)listen\s+([^;]+);`)
@@ -60,7 +67,6 @@ func scanForSite(configPath string, content []byte) error {
 	type hostInfo struct {
 		hasSSL      bool
 		port        int
-		isPublic    bool // Whether this is a public-facing port
 		priority    int  // Higher priority for public ports
 		hasRedirect bool // Whether this server block has HTTPS redirect
 	}
@@ -113,7 +119,6 @@ func scanForSite(configPath string, content []byte) error {
 				listenValue := strings.TrimSpace(string(match[1]))
 				hasSSL := strings.Contains(listenValue, "ssl")
 				port := 80 // Default HTTP port
-				isPublic := true
 				priority := 1
 
 				if hasSSL {
@@ -136,13 +141,6 @@ func scanForSite(configPath string, content []byte) error {
 				if len(listenParts) > 0 {
 					addressPart := listenParts[0]
 
-					// Check if it's bound to a specific IP (not public)
-					if strings.Contains(addressPart, "127.0.0.1") ||
-						strings.Contains(addressPart, "localhost") {
-						isPublic = false
-						priority = 0 // Internal ports have lowest priority
-					}
-
 					// Extract port from various formats
 					var extractedPort int
 					var err error
@@ -186,7 +184,6 @@ func scanForSite(configPath string, content []byte) error {
 						hostMap[name] = hostInfo{
 							hasSSL:      hasSSL,
 							port:        port,
-							isPublic:    isPublic,
 							priority:    priority,
 							hasRedirect: hasRedirect,
 						}
@@ -198,11 +195,6 @@ func scanForSite(configPath string, content []byte) error {
 
 	// Generate URLs from the host map
 	for host, info := range hostMap {
-		// Skip internal/private addresses for URL generation
-		if !info.isPublic {
-			continue
-		}
-
 		protocol := "http"
 		defaultPort := 80
 

+ 9 - 3
internal/sitecheck/service.go

@@ -28,6 +28,13 @@ var (
 func Init(ctx context.Context) {
 	globalService = NewService(ctx, DefaultCheckOptions())
 
+	// Register post-scan callback to refresh sites when configs change
+	cache.RegisterPostScanCallback(func() {
+		if globalService != nil && globalService.IsRunning() {
+			globalService.RefreshSites()
+		}
+	})
+
 	globalService.Start()
 }
 
@@ -198,11 +205,10 @@ func (s *Service) periodicCheck() {
 func (s *Service) RefreshSites() {
 	go func() {
 		sl := logger.NewSessionLogger(s.ctx)
-		sl.Debug("Started sitecheck manual refresh goroutine")
-		logger.Info("Manually refreshing sites")
+		sl.Debug("Started sitecheck refresh goroutine")
 		s.checker.CollectSites()
 		s.checker.CheckAllSites(s.ctx)
-		sl.Debug("Sitecheck manual refresh goroutine completed")
+		sl.Debug("Sitecheck refresh goroutine completed")
 	}()
 }
 

+ 7 - 0
internal/upstream/service.go

@@ -87,6 +87,13 @@ func init() {
 
 // scanForProxyTargets is the callback function for cache scanner
 func scanForProxyTargets(configPath string, content []byte) error {
+	// Handle file removal - clean up targets from this config
+	if len(content) == 0 {
+		service := GetUpstreamService()
+		service.RemoveConfigTargets(configPath)
+		return nil
+	}
+
 	// logger.Debug("scanForProxyTargets", configPath)
 	// Parse proxy targets and upstream definitions from config content
 	result := ParseProxyTargetsAndUpstreamsFromRawContent(string(content))