Explorar o código

feat(env_group): add upstream test type: local, remote, mirror

0xJacky hai 2 semanas
pai
achega
152569a2e7

+ 1 - 1
.air.toml

@@ -15,7 +15,7 @@ full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
 # Watch these filename extensions.
 # Watch these filename extensions.
 include_ext = ["go", "tpl", "tmpl", "html", "toml", "po", "conf"]
 include_ext = ["go", "tpl", "tmpl", "html", "toml", "po", "conf"]
 # Ignore these filename extensions or directories.
 # Ignore these filename extensions or directories.
-exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", ".idea", "cmd"]
+exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", ".idea", "cmd", ".go"]
 # Watch these directories if you specified.
 # Watch these directories if you specified.
 include_dir = []
 include_dir = []
 # Exclude files.
 # Exclude files.

+ 1 - 1
.devcontainer/docker-compose.yml

@@ -5,7 +5,7 @@ services:
     container_name: nginx-ui
     container_name: nginx-ui
     volumes:
     volumes:
       - ../..:/workspaces:cached
       - ../..:/workspaces:cached
-      - ./go-path:/root/go
+      - ../.go:/root/go
       - ./data/nginx:/etc/nginx
       - ./data/nginx:/etc/nginx
       - /var/run/docker.sock:/var/run/docker.sock
       - /var/run/docker.sock:/var/run/docker.sock
     command: sleep infinity
     command: sleep infinity

+ 1 - 0
.gitignore

@@ -19,3 +19,4 @@ internal/**/*.gen.go
 .devcontainer/data
 .devcontainer/data
 .devcontainer/casdoor.pem
 .devcontainer/casdoor.pem
 .vscode/.i18n-gettext.secret
 .vscode/.i18n-gettext.secret
+.go/

+ 1 - 1
api/analytic/nodes.go

@@ -107,7 +107,7 @@ func GetNodesAnalytic(c *gin.Context) {
 	defer ws.Close()
 	defer ws.Close()
 
 
 	for {
 	for {
-		// write
+		// Send NodeMap data to client
 		err = ws.WriteJSON(analytic.NodeMap)
 		err = ws.WriteJSON(analytic.NodeMap)
 		if err != nil {
 		if err != nil {
 			if helper.IsUnexpectedWebsocketError(err) {
 			if helper.IsUnexpectedWebsocketError(err) {

+ 8 - 6
api/cluster/group.go

@@ -110,9 +110,10 @@ func RestartNginx(c *gin.Context) {
 func AddGroup(c *gin.Context) {
 func AddGroup(c *gin.Context) {
 	cosy.Core[model.EnvGroup](c).
 	cosy.Core[model.EnvGroup](c).
 		SetValidRules(gin.H{
 		SetValidRules(gin.H{
-			"name":             "required",
-			"sync_node_ids":    "omitempty",
-			"post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
+			"name":               "required",
+			"sync_node_ids":      "omitempty",
+			"post_sync_action":   "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
+			"upstream_test_type": "omitempty,oneof=" + model.UpstreamTestLocal + " " + model.UpstreamTestRemote + " " + model.UpstreamTestMirror,
 		}).
 		}).
 		Create()
 		Create()
 }
 }
@@ -120,9 +121,10 @@ func AddGroup(c *gin.Context) {
 func ModifyGroup(c *gin.Context) {
 func ModifyGroup(c *gin.Context) {
 	cosy.Core[model.EnvGroup](c).
 	cosy.Core[model.EnvGroup](c).
 		SetValidRules(gin.H{
 		SetValidRules(gin.H{
-			"name":             "required",
-			"sync_node_ids":    "omitempty",
-			"post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
+			"name":               "required",
+			"sync_node_ids":      "omitempty",
+			"post_sync_action":   "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
+			"upstream_test_type": "omitempty,oneof=" + model.UpstreamTestLocal + " " + model.UpstreamTestRemote + " " + model.UpstreamTestMirror,
 		}).
 		}).
 		Modify()
 		Modify()
 }
 }

+ 8 - 0
app/src/api/env_group.ts

@@ -7,10 +7,18 @@ export const PostSyncAction = {
   ReloadNginx: 'reload_nginx',
   ReloadNginx: 'reload_nginx',
 }
 }
 
 
+// Upstream test types
+export const UpstreamTestType = {
+  Local: 'local',
+  Remote: 'remote',
+  Mirror: 'mirror',
+}
+
 export interface EnvGroup extends ModelBase {
 export interface EnvGroup extends ModelBase {
   name: string
   name: string
   sync_node_ids: number[]
   sync_node_ids: number[]
   post_sync_action?: string
   post_sync_action?: string
+  upstream_test_type?: string
 }
 }
 
 
 const baseUrl = '/env_groups'
 const baseUrl = '/env_groups'

+ 268 - 40
app/src/components/ProxyTargets/ProxyTargets.vue

@@ -1,16 +1,77 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import type { ProxyTarget } from '@/api/site'
 import type { ProxyTarget } from '@/api/site'
+import { useNodeAvailabilityStore } from '@/pinia/moudule/nodeAvailability'
+import { useNodeGroupStore } from '@/pinia/moudule/nodeGroupStore'
 import { useProxyAvailabilityStore } from '@/pinia/moudule/proxyAvailability'
 import { useProxyAvailabilityStore } from '@/pinia/moudule/proxyAvailability'
 
 
 interface Props {
 interface Props {
   targets: ProxyTarget[]
   targets: ProxyTarget[]
+  envGroupId?: number
 }
 }
 
 
-defineProps<Props>()
+const props = defineProps<Props>()
 
 
 const proxyStore = useProxyAvailabilityStore()
 const proxyStore = useProxyAvailabilityStore()
+const nodeStore = useNodeAvailabilityStore()
+const nodeGroupStore = useNodeGroupStore()
 
 
+// Initialize the stores to start monitoring
+onMounted(() => {
+  proxyStore.startMonitoring()
+  nodeGroupStore.initialize()
+})
+
+onUnmounted(() => {
+  proxyStore.stopMonitoring()
+})
+
+// Check if should show multi-node display based on group configuration
+const shouldShowMultiNodeDisplay = computed(() => {
+  if (!props.envGroupId) {
+    return false
+  }
+
+  const group = nodeGroupStore.getGroupById(props.envGroupId)
+  const testType = group?.upstream_test_type || 'local'
+  return testType === 'remote' || testType === 'mirror'
+})
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
 function getTargetColor(target: ProxyTarget): string {
 function getTargetColor(target: ProxyTarget): string {
+  // Check if we should show multi-node display based on group configuration
+  if (shouldShowMultiNodeDisplay.value) {
+    const multiNodeStatus = proxyStore.getMultiNodeStatus(target)
+    const group = nodeGroupStore.getGroupById(props.envGroupId!)
+    const testType = group?.upstream_test_type || 'local'
+
+    // Calculate total nodes based on test type
+    const totalNodes = testType === 'remote'
+      ? (group?.sync_node_ids?.length || 0) // remote: only sync nodes
+      : (group?.sync_node_ids?.length || 0) + 1 // mirror: sync nodes + main node
+
+    let onlineCount = 0
+
+    if (multiNodeStatus) {
+      // Count online nodes from multi-node data
+      onlineCount = Object.values(multiNodeStatus).filter(status => status.online).length
+    }
+
+    // For mirror mode, also include main node status
+    if (testType === 'mirror') {
+      const mainNodeStatus = proxyStore.getAvailabilityResult(target)
+      if (mainNodeStatus && mainNodeStatus.online) {
+        onlineCount++
+      }
+    }
+
+    if (onlineCount === totalNodes)
+      return 'green'
+    if (onlineCount === 0)
+      return 'red'
+    return 'orange' // Partial online
+  }
+
+  // Fallback to single-node display
   const result = proxyStore.getAvailabilityResult(target)
   const result = proxyStore.getAvailabilityResult(target)
   if (!result)
   if (!result)
     return 'default'
     return 'default'
@@ -18,6 +79,36 @@ function getTargetColor(target: ProxyTarget): string {
 }
 }
 
 
 function getTargetText(target: ProxyTarget): string {
 function getTargetText(target: ProxyTarget): string {
+  // Check if we should show multi-node display based on group configuration
+  if (shouldShowMultiNodeDisplay.value) {
+    const multiNodeStatus = proxyStore.getMultiNodeStatus(target)
+    const group = nodeGroupStore.getGroupById(props.envGroupId!)
+    const testType = group?.upstream_test_type || 'local'
+
+    // Calculate total nodes based on test type
+    const totalNodes = testType === 'remote'
+      ? (group?.sync_node_ids?.length || 0) // remote: only sync nodes
+      : (group?.sync_node_ids?.length || 0) + 1 // mirror: sync nodes + main node
+
+    let onlineCount = 0
+
+    if (multiNodeStatus) {
+      // Count online nodes from multi-node data
+      onlineCount = Object.values(multiNodeStatus).filter(status => status.online).length
+    }
+
+    // For mirror mode, also include main node status
+    if (testType === 'mirror') {
+      const mainNodeStatus = proxyStore.getAvailabilityResult(target)
+      if (mainNodeStatus && mainNodeStatus.online) {
+        onlineCount++
+      }
+    }
+
+    return `${target.host}:${target.port} (${onlineCount}/${totalNodes})`
+  }
+
+  // Fallback to single-node display
   const result = proxyStore.getAvailabilityResult(target)
   const result = proxyStore.getAvailabilityResult(target)
   if (!result)
   if (!result)
     return `${target.host}:${target.port}`
     return `${target.host}:${target.port}`
@@ -33,63 +124,200 @@ function getTargetText(target: ProxyTarget): string {
 function getTargetTitle(target: ProxyTarget): string {
 function getTargetTitle(target: ProxyTarget): string {
   return `${$gettext('Type')}: ${target.type === 'upstream' ? $gettext('Upstream') : $gettext('Proxy Pass')}`
   return `${$gettext('Type')}: ${target.type === 'upstream' ? $gettext('Upstream') : $gettext('Proxy Pass')}`
 }
 }
+
+const showDetailModal = ref(false)
+const selectedTarget = ref<ProxyTarget | null>(null)
+
+function getNodeName(nodeId: string): string {
+  const node = nodeStore.nodes[Number.parseInt(nodeId)]
+  return node?.name || `Node ${nodeId}`
+}
+
+// Get all node statuses including main node for modal display
+function getAllNodeStatuses(target: ProxyTarget) {
+  const group = nodeGroupStore.getGroupById(props.envGroupId!)
+  const testType = group?.upstream_test_type || 'local'
+  const allStatuses: Array<{ nodeId: string, name: string, status: { online: boolean, latency: number }, isMainNode: boolean }> = []
+
+  // Add main node data first for local and mirror modes
+  if (testType === 'local' || testType === 'mirror') {
+    const mainNodeStatus = proxyStore.getAvailabilityResult(target)
+    if (mainNodeStatus) {
+      allStatuses.push({
+        nodeId: 'main',
+        name: $gettext('Main Node'),
+        status: {
+          online: mainNodeStatus.online,
+          latency: mainNodeStatus.latency,
+        },
+        isMainNode: true,
+      })
+    }
+  }
+
+  // Add all child nodes data (both online and offline)
+  if (group?.sync_node_ids) {
+    const multiNodeStatus = proxyStore.getMultiNodeStatus(target)
+
+    for (const nodeId of group.sync_node_ids) {
+      const nodeIdStr = nodeId.toString()
+      const nodeStatus = multiNodeStatus?.[nodeIdStr]
+
+      allStatuses.push({
+        nodeId: nodeIdStr,
+        name: getNodeName(nodeIdStr),
+        status: nodeStatus || {
+          online: false,
+          latency: 0,
+        },
+        isMainNode: false,
+      })
+    }
+  }
+
+  return allStatuses
+}
+
+function handleTargetClick(target: ProxyTarget) {
+  if (shouldShowMultiNodeDisplay.value) {
+    selectedTarget.value = target
+    showDetailModal.value = true
+  }
+}
 </script>
 </script>
 
 
 <template>
 <template>
   <div v-if="targets.length > 0" class="proxy-targets">
   <div v-if="targets.length > 0" class="proxy-targets">
     <ATag
     <ATag
-      v-for="target in targets"
-      :key="proxyStore.getTargetKey(target)"
-      :color="getTargetColor(target)"
-      class="proxy-target-tag"
-      :bordered="false"
+      v-for="target in targets" :key="proxyStore.getTargetKey(target)" :color="getTargetColor(target)"
+      class="proxy-target-tag cursor-pointer" :class="{ clickable: shouldShowMultiNodeDisplay }" :bordered="false"
+      @click="handleTargetClick(target)"
     >
     >
       <template #icon>
       <template #icon>
-        <ATooltip
-          :title="getTargetTitle(target)"
-          placement="bottom"
-          class="cursor-pointer"
-        >
+        <ATooltip :title="getTargetTitle(target)" placement="bottom" class="cursor-pointer">
           <span v-if="target.type === 'upstream'" class="target-type-icon">U</span>
           <span v-if="target.type === 'upstream'" class="target-type-icon">U</span>
           <span v-else class="target-type-icon">P</span>
           <span v-else class="target-type-icon">P</span>
         </ATooltip>
         </ATooltip>
       </template>
       </template>
       {{ getTargetText(target) }}
       {{ getTargetText(target) }}
     </ATag>
     </ATag>
+
+    <!-- Upstream Detail Modal -->
+    <AModal
+      v-model:open="showDetailModal"
+      :title="selectedTarget ? `${selectedTarget.host}:${selectedTarget.port} - ${$gettext('Node Status')}` : ''"
+      :footer="null" width="600px"
+    >
+      <div v-if="selectedTarget" class="upstream-detail">
+        <div class="node-status-list">
+          <div v-for="nodeInfo in getAllNodeStatuses(selectedTarget)" :key="nodeInfo.nodeId" class="node-status-item">
+            <div class="node-info">
+              <span class="node-name">{{ nodeInfo.name }}</span>
+              <ATag :color="nodeInfo.status.online ? 'green' : 'red'" class="status-tag">
+                {{ nodeInfo.status.online ? $gettext('Online') : $gettext('Offline') }}
+              </ATag>
+              <ATag v-if="nodeInfo.isMainNode" color="blue" class="main-node-tag">
+                {{ $gettext('Main') }}
+              </ATag>
+            </div>
+            <div class="node-latency">
+              <span v-if="nodeInfo.status.online">{{ nodeInfo.status.latency.toFixed(2) }}ms</span>
+              <span v-else class="text-gray-400">{{ $gettext('N/A') }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </AModal>
   </div>
   </div>
 </template>
 </template>
 
 
 <style scoped lang="less">
 <style scoped lang="less">
-.proxy-targets {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 4px;
-  max-width: 100%;
-  overflow: hidden;
-}
+  .proxy-targets {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 4px;
+    max-width: 100%;
+    overflow: hidden;
+  }
 
 
-.proxy-target-tag {
-  margin-right: 4px;
-  margin-bottom: 4px;
-  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
-  font-size: 12px;
-  max-width: 100%;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-
-  .target-type-icon {
-    display: inline-block;
-    width: 12px;
-    height: 12px;
-    line-height: 12px;
-    text-align: center;
-    background: rgba(255, 255, 255, 0.2);
-    border-radius: 2px;
+  .proxy-target-tag {
     margin-right: 4px;
     margin-right: 4px;
-    font-weight: bold;
-    font-size: 10px;
-    flex-shrink: 0;
+    margin-bottom: 4px;
+    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
+    font-size: 12px;
+    max-width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+
+    &.clickable {
+      cursor: pointer;
+      transition: all 0.2s ease;
+
+      &:hover {
+        box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.07);
+      }
+    }
+
+    .target-type-icon {
+      display: inline-block;
+      width: 12px;
+      height: 12px;
+      line-height: 12px;
+      text-align: center;
+      background: rgba(255, 255, 255, 0.2);
+      border-radius: 2px;
+      margin-right: 4px;
+      font-weight: bold;
+      font-size: 10px;
+      flex-shrink: 0;
+    }
+  }
+
+  .upstream-detail {
+    .node-status-list {
+      display: flex;
+      flex-direction: column;
+      gap: 12px;
+    }
+
+    .node-status-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 12px;
+      border: 1px solid #e8e9ea;
+      border-radius: 8px;
+      background: #fafafa;
+
+      .node-info {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+
+        .node-name {
+          font-weight: 500;
+          color: #333;
+        }
+
+        .status-tag {
+          font-size: 11px;
+          margin: 0;
+        }
+
+        .main-node-tag {
+          font-size: 10px;
+          margin: 0;
+        }
+      }
+
+      .node-latency {
+        font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
+        font-size: 12px;
+        font-weight: 500;
+        color: #666;
+      }
+
+    }
   }
   }
-}
 </style>
 </style>

+ 11 - 0
app/src/constants/index.ts

@@ -32,6 +32,17 @@ export enum NginxStatus {
   Stopped,
   Stopped,
 }
 }
 
 
+export const PostSyncActionMask = {
+  none: () => $gettext('No Action'),
+  reload_nginx: () => $gettext('Reload Nginx'),
+} as const
+
+export const UpstreamTestTypeMask = {
+  local: () => $gettext('Local'),
+  remote: () => $gettext('Remote'),
+  mirror: () => $gettext('Mirror'),
+} as const
+
 export const PrivateKeyTypeMask = {
 export const PrivateKeyTypeMask = {
   2048: 'RSA2048',
   2048: 'RSA2048',
   3072: 'RSA3072',
   3072: 'RSA3072',

+ 67 - 42
app/src/language/ar/app.po

@@ -141,14 +141,14 @@ msgstr "إجراء"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "الإجراءات"
 msgstr "الإجراءات"
@@ -763,7 +763,7 @@ msgstr "نوع الشهادة"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "شهادات"
 msgstr "شهادات"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "قائمة الشهادات"
 msgstr "قائمة الشهادات"
 
 
@@ -1060,7 +1060,7 @@ msgstr "مسار التكوين فارغ"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "قالب التكوين"
 msgstr "قالب التكوين"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "التكوين"
 msgstr "التكوين"
 
 
@@ -1181,7 +1181,7 @@ msgstr ""
 "سيتم تنزيل ملفات النسخ الاحتياطي تلقائيًا إلى جهاز الكمبيوتر الخاص بك."
 "سيتم تنزيل ملفات النسخ الاحتياطي تلقائيًا إلى جهاز الكمبيوتر الخاص بك."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1516,7 +1516,7 @@ msgstr "تم تعطيل الدفق %{name} من %{node} بنجاح"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1531,8 +1531,8 @@ msgstr "تم التعطيل بنجاح"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "إدخال/إخراج القرص"
 msgstr "إدخال/إخراج القرص"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "بيانات اعتماد DNS"
 msgstr "بيانات اعتماد DNS"
 
 
@@ -1798,7 +1798,7 @@ msgstr "تفعيل TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2521,7 +2521,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "استيراد"
 msgstr "استيراد"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "استيراد شهادة"
 msgstr "استيراد شهادة"
@@ -2843,7 +2843,7 @@ msgid "Loading data..."
 msgstr "جارٍ تحميل البيانات..."
 msgstr "جارٍ تحميل البيانات..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2913,9 +2913,17 @@ msgstr ""
 "يدويًا. سيقوم مجدول المهام crontab الخاص بواجهة Nginx UI بتنفيذ أمر تدوير "
 "يدويًا. سيقوم مجدول المهام crontab الخاص بواجهة Nginx UI بتنفيذ أمر تدوير "
 "السجلات في الفاصل الزمني الذي تحدده بالدقائق."
 "السجلات في الفاصل الزمني الذي تحدده بالدقائق."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "رئيسي"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "العقدة الرئيسية"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "صيانة"
 msgstr "صيانة"
 
 
@@ -3066,6 +3074,10 @@ msgstr "دقيقة"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "دقائق"
 msgstr "دقائق"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "مرآة"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "نموذج"
 msgstr "نموذج"
@@ -3079,7 +3091,7 @@ msgstr "تم التعديل في"
 msgid "Modify"
 msgid "Modify"
 msgstr "تعديل"
 msgstr "تعديل"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "تعديل الشهادة"
 msgstr "تعديل الشهادة"
@@ -3112,17 +3124,21 @@ msgstr "يوميًا في اليوم %{day} الساعة %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "توجيه متعدد الأسطر"
 msgstr "توجيه متعدد الأسطر"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "غير متاح"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3411,8 +3427,7 @@ msgid "No"
 msgstr "لا"
 msgstr "لا"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "لا إجراء"
 msgstr "لا إجراء"
 
 
@@ -3441,7 +3456,7 @@ msgid "Node"
 msgstr "العقدة"
 msgstr "العقدة"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "مجموعة العقد"
 msgstr "مجموعة العقد"
@@ -3459,6 +3474,10 @@ msgstr "اسم العقدة"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "سر العقدة"
 msgstr "سر العقدة"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "حالة العقدة"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "العقد"
 msgstr "العقد"
@@ -3481,7 +3500,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "غير صالح قبل: %{date}"
 msgstr "غير صالح قبل: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "ملاحظة"
 msgstr "ملاحظة"
 
 
@@ -3563,6 +3582,7 @@ msgstr "الوثيقة الرسمية"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3589,7 +3609,7 @@ msgstr "حسنًا"
 msgid "On"
 msgid "On"
 msgstr "تشغيل"
 msgstr "تشغيل"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 
 
@@ -3597,6 +3617,7 @@ msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلا
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3820,7 +3841,7 @@ msgstr "يرجى ملء جميع الحقول بشكل صحيح"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "يرجى ملء حقول تكوين S3 المطلوبة"
 msgstr "يرجى ملء حقول تكوين S3 المطلوبة"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3879,7 +3900,7 @@ msgstr "يرجى إدخال اسم المستخدم الخاص بك!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "الرجاء تسجيل الدخول."
 msgstr "الرجاء تسجيل الدخول."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "يرجى ملاحظة أن تكوين وحدات الوقت أدناه كلها بالثواني."
 msgstr "يرجى ملاحظة أن تكوين وحدات الوقت أدناه كلها بالثواني."
 
 
@@ -3940,8 +3961,7 @@ msgid "Port Scanner"
 msgstr "ماسح المنافذ"
 msgstr "ماسح المنافذ"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "إجراء ما بعد المزامنة"
 msgstr "إجراء ما بعد المزامنة"
 
 
@@ -4005,7 +4025,7 @@ msgstr ""
 "إعدادات البروتوكول تتأثر فقط عند الاتصال المباشر. إذا كنت تستخدم خادم وكيل "
 "إعدادات البروتوكول تتأثر فقط عند الاتصال المباشر. إذا كنت تستخدم خادم وكيل "
 "عكسي، يرجى تكوين البروتوكول بشكل منفصل في خادم الوكيل العكسي."
 "عكسي، يرجى تكوين البروتوكول بشكل منفصل في خادم الوكيل العكسي."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "مزود"
 msgstr "مزود"
 
 
@@ -4017,7 +4037,7 @@ msgstr "لم يتم العثور على المزود: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "وكيل"
 msgstr "وكيل"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "مرور الوكيل"
 msgstr "مرور الوكيل"
 
 
@@ -4124,9 +4144,7 @@ msgid "Reload"
 msgstr "إعادة تحميل"
 msgstr "إعادة تحميل"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4164,6 +4182,10 @@ msgstr "إعادة التحميل"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "إعادة تحميل nginx"
 msgstr "إعادة تحميل nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "عن بُعد"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4670,10 +4692,6 @@ msgstr "معلومات رمز الأمان"
 msgid "Select all"
 msgid "Select all"
 msgstr "تحديد الكل"
 msgstr "تحديد الكل"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "اختر إجراءً بعد المزامنة"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "تم تحديد {count} ملفات"
 msgstr "تم تحديد {count} ملفات"
@@ -4932,7 +4950,7 @@ msgstr "ثابت"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "الحالة"
 msgstr "الحالة"
 
 
@@ -5106,7 +5124,7 @@ msgstr "تمت مزامنة التكوين بنجاح"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "مزامنة العقد"
 msgstr "مزامنة العقد"
@@ -5552,7 +5570,7 @@ msgstr "الثلاثاء"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "يتطلب المصادقة الثنائية"
 msgstr "يتطلب المصادقة الثنائية"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5589,13 +5607,13 @@ msgstr "تم التحديث بنجاح"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5633,7 +5651,7 @@ msgstr "تحميل الملفات"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "تحميل المجلدات"
 msgstr "تحميل المجلدات"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "أعلى التيار"
 msgstr "أعلى التيار"
 
 
@@ -5641,6 +5659,10 @@ msgstr "أعلى التيار"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "اسم المنبع"
 msgstr "اسم المنبع"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "نوع اختبار المنبع"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "مدة التشغيل:"
 msgstr "مدة التشغيل:"
@@ -5761,7 +5783,7 @@ msgstr ""
 "تحذير: ستقوم عملية الاستعادة بالكتابة فوق التكوينات الحالية. تأكد من أن "
 "تحذير: ستقوم عملية الاستعادة بالكتابة فوق التكوينات الحالية. تأكد من أن "
 "لديك ملف نسخ احتياطي صالحًا ورمزًا أمنيًا، واختر بعناية ما تريد استعادته."
 "لديك ملف نسخ احتياطي صالحًا ورمزًا أمنيًا، واختر بعناية ما تريد استعادته."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5943,6 +5965,9 @@ msgstr "رموزك القديمة لن تعمل بعد الآن."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "مفاتيح المرور الخاصة بك"
 msgstr "مفاتيح المرور الخاصة بك"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "اختر إجراءً بعد المزامنة"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "ابدأ الرابط"
 #~ msgstr "ابدأ الرابط"
 
 

+ 67 - 42
app/src/language/de_DE/app.po

@@ -142,14 +142,14 @@ msgstr "Aktion"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Aktionen"
 msgstr "Aktionen"
@@ -775,7 +775,7 @@ msgstr "Zertifikatstyp"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Zertifikate"
 msgstr "Zertifikate"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Zertifikatsliste"
 msgstr "Zertifikatsliste"
 
 
@@ -1075,7 +1075,7 @@ msgstr "Konfigurationspfad ist leer"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Konfigurationsvorlage"
 msgstr "Konfigurationsvorlage"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Konfiguration"
 msgstr "Konfiguration"
 
 
@@ -1199,7 +1199,7 @@ msgstr ""
 "Computer heruntergeladen."
 "Computer heruntergeladen."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1536,7 +1536,7 @@ msgstr "Stream %{name} von %{node} erfolgreich deaktiviert"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1551,8 +1551,8 @@ msgstr "Erfolgreich deaktiviert"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "Festplatten-IO"
 msgstr "Festplatten-IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS-Zugangsdaten"
 msgstr "DNS-Zugangsdaten"
 
 
@@ -1818,7 +1818,7 @@ msgstr "TOTP aktivieren"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2550,7 +2550,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Import"
 msgstr "Import"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Zertifikat importieren"
 msgstr "Zertifikat importieren"
@@ -2872,7 +2872,7 @@ msgid "Loading data..."
 msgstr "Daten werden geladen..."
 msgstr "Daten werden geladen..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2942,9 +2942,17 @@ msgstr ""
 "aktivieren. Der Crontab-Aufgabenplaner von Nginx UI führt den "
 "aktivieren. Der Crontab-Aufgabenplaner von Nginx UI führt den "
 "Logrotate-Befehl in dem von dir in Minuten festgelegten Intervall aus."
 "Logrotate-Befehl in dem von dir in Minuten festgelegten Intervall aus."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Haupt"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Hauptknoten"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Wartung"
 msgstr "Wartung"
 
 
@@ -3096,6 +3104,10 @@ msgstr "Minute"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Minuten"
 msgstr "Minuten"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Spiegel"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Modell"
 msgstr "Modell"
@@ -3109,7 +3121,7 @@ msgstr "Geändert am"
 msgid "Modify"
 msgid "Modify"
 msgstr "Ändern"
 msgstr "Ändern"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Zertifikat ändern"
 msgstr "Zertifikat ändern"
@@ -3142,17 +3154,21 @@ msgstr "Monatlich am %{day}. um %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Mehrzeilige Direktive"
 msgstr "Mehrzeilige Direktive"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "N/V"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3443,8 +3459,7 @@ msgid "No"
 msgstr "Nein"
 msgstr "Nein"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Keine Aktion"
 msgstr "Keine Aktion"
 
 
@@ -3473,7 +3488,7 @@ msgid "Node"
 msgstr "Node"
 msgstr "Node"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Node-Gruppe"
 msgstr "Node-Gruppe"
@@ -3491,6 +3506,10 @@ msgstr "Knotenname"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Node-Secret"
 msgstr "Node-Secret"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Knotenstatus"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Knoten"
 msgstr "Knoten"
@@ -3513,7 +3532,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Nich gültig vor: %{date}"
 msgstr "Nich gültig vor: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Notiz"
 msgstr "Notiz"
 
 
@@ -3598,6 +3617,7 @@ msgstr "Offizielle Dokumentation"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3624,7 +3644,7 @@ msgstr "OK"
 msgid "On"
 msgid "On"
 msgstr "Ein"
 msgstr "Ein"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfernt."
 msgstr "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfernt."
 
 
@@ -3632,6 +3652,7 @@ msgstr "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfer
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3857,7 +3878,7 @@ msgstr "Bitte füllen Sie alle Felder korrekt aus"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Bitte füllen Sie die erforderlichen S3-Konfigurationsfelder aus"
 msgstr "Bitte füllen Sie die erforderlichen S3-Konfigurationsfelder aus"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3925,7 +3946,7 @@ msgstr "Bitte gib deinen Benutzernamen ein!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Bitte melden Sie sich an."
 msgstr "Bitte melden Sie sich an."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Bitte beachte, dass die Zeiteinheiten der unten aufgeführten "
 "Bitte beachte, dass die Zeiteinheiten der unten aufgeführten "
@@ -3990,8 +4011,7 @@ msgid "Port Scanner"
 msgstr "Port-Scanner"
 msgstr "Port-Scanner"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Aktion nach der Synchronisierung"
 msgstr "Aktion nach der Synchronisierung"
 
 
@@ -4056,7 +4076,7 @@ msgstr ""
 "eines Reverse Proxys konfigurieren Sie das Protokoll bitte separat im "
 "eines Reverse Proxys konfigurieren Sie das Protokoll bitte separat im "
 "Reverse Proxy."
 "Reverse Proxy."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Anbieter"
 msgstr "Anbieter"
 
 
@@ -4068,7 +4088,7 @@ msgstr "Anbieter nicht gefunden: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Proxy-Weiterleitung"
 msgstr "Proxy-Weiterleitung"
 
 
@@ -4178,9 +4198,7 @@ msgid "Reload"
 msgstr "Neu laden"
 msgstr "Neu laden"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4220,6 +4238,10 @@ msgstr "Lade neu"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Lade Nginx neu"
 msgstr "Lade Nginx neu"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Remote"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4729,10 +4751,6 @@ msgstr "Sicherheitstoken-Informationen"
 msgid "Select all"
 msgid "Select all"
 msgstr "Alle auswählen"
 msgstr "Alle auswählen"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Aktion nach der Synchronisierung auswählen"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Ausgewählte {count} Dateien"
 msgstr "Ausgewählte {count} Dateien"
@@ -4999,7 +5017,7 @@ msgstr "Statisch"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Status"
 msgstr "Status"
 
 
@@ -5178,7 +5196,7 @@ msgstr "Konfiguration erfolgreich synchronisiert"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Synchrone Knoten"
 msgstr "Synchrone Knoten"
@@ -5640,7 +5658,7 @@ msgstr "Dienstag"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Zwei-Faktor-Authentifizierung erforderlich"
 msgstr "Zwei-Faktor-Authentifizierung erforderlich"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5677,13 +5695,13 @@ msgstr "Erfolgreich aktualisiert"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5721,7 +5739,7 @@ msgstr "Dateien hochladen"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Ordner hochladen"
 msgstr "Ordner hochladen"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Upstream"
 msgstr "Upstream"
 
 
@@ -5729,6 +5747,10 @@ msgstr "Upstream"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Upstream-Name"
 msgstr "Upstream-Name"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Upstream-Testtyp"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Uptime:"
 msgstr "Uptime:"
@@ -5851,7 +5873,7 @@ msgstr ""
 "und ein Sicherheitstoken haben, und wählen Sie sorgfältig aus, was "
 "und ein Sicherheitstoken haben, und wählen Sie sorgfältig aus, was "
 "wiederhergestellt werden soll."
 "wiederhergestellt werden soll."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6045,6 +6067,9 @@ msgstr "Ihre alten Codes funktionieren nicht mehr."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Deine Passkeys"
 msgstr "Deine Passkeys"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Aktion nach der Synchronisierung auswählen"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Link Start"
 #~ msgstr "Link Start"
 
 

+ 64 - 42
app/src/language/en/app.po

@@ -125,14 +125,14 @@ msgstr ""
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr ""
 msgstr ""
@@ -738,7 +738,7 @@ msgstr ""
 msgid "Certificates"
 msgid "Certificates"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr ""
 msgstr ""
 
 
@@ -1000,7 +1000,7 @@ msgstr ""
 msgid "Config Template"
 msgid "Config Template"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr ""
 msgstr ""
 
 
@@ -1119,7 +1119,7 @@ msgid ""
 msgstr ""
 msgstr ""
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1454,7 +1454,7 @@ msgstr ""
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1469,8 +1469,8 @@ msgstr ""
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr ""
 msgstr ""
 
 
@@ -1730,7 +1730,7 @@ msgstr ""
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2449,7 +2449,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr ""
 msgstr ""
@@ -2765,7 +2765,7 @@ msgid "Loading data..."
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2826,9 +2826,17 @@ msgid ""
 "minutes."
 "minutes."
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr ""
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr ""
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr ""
 msgstr ""
 
 
@@ -2977,6 +2985,10 @@ msgstr ""
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr ""
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr ""
 msgstr ""
@@ -2990,7 +3002,7 @@ msgstr ""
 msgid "Modify"
 msgid "Modify"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr ""
 msgstr ""
@@ -3023,17 +3035,21 @@ msgstr ""
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr ""
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3322,8 +3338,7 @@ msgid "No"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr ""
 msgstr ""
 
 
@@ -3352,7 +3367,7 @@ msgid "Node"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr ""
 msgstr ""
@@ -3370,6 +3385,10 @@ msgstr ""
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr ""
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr ""
 msgstr ""
@@ -3392,7 +3411,7 @@ msgid "Not Valid Before: %{date}"
 msgstr ""
 msgstr ""
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr ""
 msgstr ""
 
 
@@ -3470,6 +3489,7 @@ msgstr ""
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3496,7 +3516,7 @@ msgstr ""
 msgid "On"
 msgid "On"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
@@ -3504,6 +3524,7 @@ msgstr ""
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3722,7 +3743,7 @@ msgstr ""
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3779,7 +3800,7 @@ msgstr ""
 msgid "Please log in."
 msgid "Please log in."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid ""
 msgid ""
 "Please note that the unit of time configurations below are all in seconds."
 "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
@@ -3841,8 +3862,7 @@ msgid "Port Scanner"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr ""
 msgstr ""
 
 
@@ -3903,7 +3923,7 @@ msgid ""
 "reverse proxy, please configure the protocol separately in the reverse proxy."
 "reverse proxy, please configure the protocol separately in the reverse proxy."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr ""
 msgstr ""
 
 
@@ -3915,7 +3935,7 @@ msgstr ""
 msgid "Proxy"
 msgid "Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr ""
 msgstr ""
 
 
@@ -4020,9 +4040,7 @@ msgid "Reload"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4060,6 +4078,10 @@ msgstr ""
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr ""
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4562,10 +4584,6 @@ msgstr ""
 msgid "Select all"
 msgid "Select all"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr ""
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr ""
 msgstr ""
@@ -4818,7 +4836,7 @@ msgstr ""
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr ""
 msgstr ""
 
 
@@ -4984,7 +5002,7 @@ msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr ""
 msgstr ""
@@ -5391,7 +5409,7 @@ msgstr ""
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5428,13 +5446,13 @@ msgstr ""
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5472,7 +5490,7 @@ msgstr ""
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr ""
 msgstr ""
 
 
@@ -5480,6 +5498,10 @@ msgstr ""
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr ""
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr ""
 msgstr ""
@@ -5598,7 +5620,7 @@ msgid ""
 "to restore."
 "to restore."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."

+ 67 - 42
app/src/language/es/app.po

@@ -147,14 +147,14 @@ msgstr "Acción"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Acciones"
 msgstr "Acciones"
@@ -785,7 +785,7 @@ msgstr "Tipo de certificado"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Certificados"
 msgstr "Certificados"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Lista de Certificados"
 msgstr "Lista de Certificados"
 
 
@@ -1082,7 +1082,7 @@ msgstr "La ruta de configuración está vacía"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Plantilla de configuración"
 msgstr "Plantilla de configuración"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Configuración"
 msgstr "Configuración"
 
 
@@ -1206,7 +1206,7 @@ msgstr ""
 "automáticamente en tu computadora."
 "automáticamente en tu computadora."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1545,7 +1545,7 @@ msgstr "Deshabilitar el flujo %{name} desde %{node} con éxito"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1560,8 +1560,8 @@ msgstr "Desactivado con éxito"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "I/O del disco"
 msgstr "I/O del disco"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "Credenciales de DNS"
 msgstr "Credenciales de DNS"
 
 
@@ -1825,7 +1825,7 @@ msgstr "Habilitar TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2557,7 +2557,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Importar"
 msgstr "Importar"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Importar Certificado"
 msgstr "Importar Certificado"
@@ -2879,7 +2879,7 @@ msgid "Loading data..."
 msgstr "Cargando datos..."
 msgstr "Cargando datos..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2951,9 +2951,17 @@ msgstr ""
 "de Nginx UI ejecutará el comando logrotate en el intervalo que establezca "
 "de Nginx UI ejecutará el comando logrotate en el intervalo que establezca "
 "en minutos."
 "en minutos."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Principal"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Nodo principal"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Mantenimiento"
 msgstr "Mantenimiento"
 
 
@@ -3104,6 +3112,10 @@ msgstr "Minuto"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Minutos"
 msgstr "Minutos"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Espejo"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Modelo"
 msgstr "Modelo"
@@ -3117,7 +3129,7 @@ msgstr "Modificado el"
 msgid "Modify"
 msgid "Modify"
 msgstr "Modificar"
 msgstr "Modificar"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Modificar Certificado"
 msgstr "Modificar Certificado"
@@ -3150,17 +3162,21 @@ msgstr "Mensualmente el día %{day} a las %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Directiva multilínea"
 msgstr "Directiva multilínea"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "N/A"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3451,8 +3467,7 @@ msgid "No"
 msgstr "No"
 msgstr "No"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Sin acción"
 msgstr "Sin acción"
 
 
@@ -3481,7 +3496,7 @@ msgid "Node"
 msgstr "Nodo"
 msgstr "Nodo"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Grupo de nodos"
 msgstr "Grupo de nodos"
@@ -3499,6 +3514,10 @@ msgstr "Nombre del nodo"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Secreto del nodo"
 msgstr "Secreto del nodo"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Estado del nodo"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Nodos"
 msgstr "Nodos"
@@ -3521,7 +3540,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "No válido antes: %{date}"
 msgstr "No válido antes: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Nota"
 msgstr "Nota"
 
 
@@ -3606,6 +3625,7 @@ msgstr "Documentación oficial"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3632,7 +3652,7 @@ msgstr "OK"
 msgid "On"
 msgid "On"
 msgstr "Encendido"
 msgstr "Encendido"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 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."
 msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 
 
@@ -3640,6 +3660,7 @@ msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3868,7 +3889,7 @@ msgstr "Por favor, complete todos los campos correctamente"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Por favor, complete los campos de configuración de S3 requeridos"
 msgstr "Por favor, complete los campos de configuración de S3 requeridos"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3936,7 +3957,7 @@ msgstr "¡Por favor ingrese su nombre de usuario!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Por favor, inicie sesión."
 msgstr "Por favor, inicie sesión."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Tenga en cuenta que las siguientes configuraciones de unidades de tiempo "
 "Tenga en cuenta que las siguientes configuraciones de unidades de tiempo "
@@ -4001,8 +4022,7 @@ msgid "Port Scanner"
 msgstr "Escáner de puertos"
 msgstr "Escáner de puertos"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Acción posterior a la sincronización"
 msgstr "Acción posterior a la sincronización"
 
 
@@ -4067,7 +4087,7 @@ msgstr ""
 "directamente. Si utiliza un proxy inverso, configure el protocolo por "
 "directamente. Si utiliza un proxy inverso, configure el protocolo por "
 "separado en el proxy inverso."
 "separado en el proxy inverso."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Proveedor"
 msgstr "Proveedor"
 
 
@@ -4079,7 +4099,7 @@ msgstr "Proveedor no encontrado: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Pase de Proxy"
 msgstr "Pase de Proxy"
 
 
@@ -4189,9 +4209,7 @@ msgid "Reload"
 msgstr "Recargar"
 msgstr "Recargar"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4229,6 +4247,10 @@ msgstr "Recargando"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Recargando Nginx"
 msgstr "Recargando Nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Remoto"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4738,10 +4760,6 @@ msgstr "Información del token de seguridad"
 msgid "Select all"
 msgid "Select all"
 msgstr "Seleccionar todo"
 msgstr "Seleccionar todo"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Seleccionar una acción después de sincronizar"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Seleccionados {count} archivos"
 msgstr "Seleccionados {count} archivos"
@@ -5008,7 +5026,7 @@ msgstr "Estático"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Estado"
 msgstr "Estado"
 
 
@@ -5185,7 +5203,7 @@ msgstr "Configuración de sincronización exitosa"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Nodos de sincronización"
 msgstr "Nodos de sincronización"
@@ -5646,7 +5664,7 @@ msgstr "Martes"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Se requiere autenticación de dos factores"
 msgstr "Se requiere autenticación de dos factores"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5683,13 +5701,13 @@ msgstr "Actualización exitosa"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5727,7 +5745,7 @@ msgstr "Subir archivos"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Subir carpetas"
 msgstr "Subir carpetas"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Aguas arriba"
 msgstr "Aguas arriba"
 
 
@@ -5735,6 +5753,10 @@ msgstr "Aguas arriba"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Nombre de la Transmisión"
 msgstr "Nombre de la Transmisión"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Tipo de prueba de upstream"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Tiempo encendido:"
 msgstr "Tiempo encendido:"
@@ -5856,7 +5878,7 @@ msgstr ""
 "actuales. Asegúrese de tener un archivo de respaldo válido y un token de "
 "actuales. Asegúrese de tener un archivo de respaldo válido y un token de "
 "seguridad, y seleccione cuidadosamente qué restaurar."
 "seguridad, y seleccione cuidadosamente qué restaurar."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6048,6 +6070,9 @@ msgstr "Tus códigos antiguos ya no funcionarán."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Sus llaves de acceso"
 msgstr "Sus llaves de acceso"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Seleccionar una acción después de sincronizar"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Iniciar conexión"
 #~ msgstr "Iniciar conexión"
 
 

+ 67 - 42
app/src/language/fr_FR/app.po

@@ -147,14 +147,14 @@ msgstr "Action"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Actions"
 msgstr "Actions"
@@ -779,7 +779,7 @@ msgstr "Type de certificat"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Certificats"
 msgstr "Certificats"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Liste des certificats"
 msgstr "Liste des certificats"
 
 
@@ -1080,7 +1080,7 @@ msgstr "Le chemin de configuration est vide"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Modèle de configuration"
 msgstr "Modèle de configuration"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Configuration"
 msgstr "Configuration"
 
 
@@ -1204,7 +1204,7 @@ msgstr ""
 "téléchargés sur votre ordinateur."
 "téléchargés sur votre ordinateur."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1543,7 +1543,7 @@ msgstr "Désactivation du flux %{name} depuis %{node} réussie"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1558,8 +1558,8 @@ msgstr "Désactivé avec succès"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "E/S disque"
 msgstr "E/S disque"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "Identifiants DNS"
 msgstr "Identifiants DNS"
 
 
@@ -1821,7 +1821,7 @@ msgstr "Activer TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2557,7 +2557,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Importer"
 msgstr "Importer"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Importer un certificat"
 msgstr "Importer un certificat"
@@ -2879,7 +2879,7 @@ msgid "Loading data..."
 msgstr "Chargement des données..."
 msgstr "Chargement des données..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2951,9 +2951,17 @@ msgstr ""
 "planificateur de tâches crontab de Nginx UI exécutera la commande logrotate "
 "planificateur de tâches crontab de Nginx UI exécutera la commande logrotate "
 "à l'intervalle que vous avez défini en minutes."
 "à l'intervalle que vous avez défini en minutes."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Principal"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Nœud principal"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Maintenance"
 msgstr "Maintenance"
 
 
@@ -3104,6 +3112,10 @@ msgstr "Minute"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Minutes"
 msgstr "Minutes"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Miroir"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Modèle"
 msgstr "Modèle"
@@ -3117,7 +3129,7 @@ msgstr "Modifié le"
 msgid "Modify"
 msgid "Modify"
 msgstr "Modifier"
 msgstr "Modifier"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Modifier le certificat"
 msgstr "Modifier le certificat"
@@ -3150,17 +3162,21 @@ msgstr "Mensuellement le jour %{day} à %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Directive multiligne"
 msgstr "Directive multiligne"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "N/D"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3451,8 +3467,7 @@ msgid "No"
 msgstr "Non"
 msgstr "Non"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Aucune action"
 msgstr "Aucune action"
 
 
@@ -3481,7 +3496,7 @@ msgid "Node"
 msgstr "Nœud"
 msgstr "Nœud"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Groupe de nœuds"
 msgstr "Groupe de nœuds"
@@ -3499,6 +3514,10 @@ msgstr "Nom du nœud"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Secret du nœud"
 msgstr "Secret du nœud"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "État du nœud"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Nœuds"
 msgstr "Nœuds"
@@ -3521,7 +3540,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Non valide avant : %{date}"
 msgstr "Non valide avant : %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Note"
 msgstr "Note"
 
 
@@ -3605,6 +3624,7 @@ msgstr "Documentation officielle"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3631,7 +3651,7 @@ msgstr "OK"
 msgid "On"
 msgid "On"
 msgstr "Activé"
 msgstr "Activé"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Une fois la vérification terminée, les enregistrements seront supprimés."
 msgstr "Une fois la vérification terminée, les enregistrements seront supprimés."
 
 
@@ -3639,6 +3659,7 @@ msgstr "Une fois la vérification terminée, les enregistrements seront supprim
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3867,7 +3888,7 @@ msgstr "Veuillez remplir tous les champs correctement"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Veuillez remplir les champs de configuration S3 requis"
 msgstr "Veuillez remplir les champs de configuration S3 requis"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3935,7 +3956,7 @@ msgstr "Veuillez saisir votre nom d'utilisateur !"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Veuillez vous connecter."
 msgstr "Veuillez vous connecter."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Veuillez noter que les unités de temps des configurations ci-dessous sont "
 "Veuillez noter que les unités de temps des configurations ci-dessous sont "
@@ -4000,8 +4021,7 @@ msgid "Port Scanner"
 msgstr "Scanner de ports"
 msgstr "Scanner de ports"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Action post-synchronisation"
 msgstr "Action post-synchronisation"
 
 
@@ -4066,7 +4086,7 @@ msgstr ""
 "directe. Si vous utilisez un proxy inverse, veuillez configurer le "
 "directe. Si vous utilisez un proxy inverse, veuillez configurer le "
 "protocole séparément dans le proxy inverse."
 "protocole séparément dans le proxy inverse."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Fournisseur"
 msgstr "Fournisseur"
 
 
@@ -4078,7 +4098,7 @@ msgstr "Fournisseur introuvable : {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Passe de Proxy"
 msgstr "Passe de Proxy"
 
 
@@ -4188,9 +4208,7 @@ msgid "Reload"
 msgstr "Recharger"
 msgstr "Recharger"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4230,6 +4248,10 @@ msgstr "Rechargement"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Rechargement de nginx"
 msgstr "Rechargement de nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Distant"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4739,10 +4761,6 @@ msgstr "Informations sur le jeton de sécurité"
 msgid "Select all"
 msgid "Select all"
 msgstr "Tout sélectionner"
 msgstr "Tout sélectionner"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Sélectionner une action après la synchronisation"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "{count} fichiers sélectionnés"
 msgstr "{count} fichiers sélectionnés"
@@ -5009,7 +5027,7 @@ msgstr "Statique"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Statut"
 msgstr "Statut"
 
 
@@ -5188,7 +5206,7 @@ msgstr "Synchronisation de la configuration réussie"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Nœuds de synchronisation"
 msgstr "Nœuds de synchronisation"
@@ -5656,7 +5674,7 @@ msgstr "Mardi"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Authentification à deux facteurs requise"
 msgstr "Authentification à deux facteurs requise"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5693,13 +5711,13 @@ msgstr "Mise à jour réussie"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5737,7 +5755,7 @@ msgstr "Téléverser des fichiers"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Télécharger des dossiers"
 msgstr "Télécharger des dossiers"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Amont"
 msgstr "Amont"
 
 
@@ -5745,6 +5763,10 @@ msgstr "Amont"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Nom de l'amont"
 msgstr "Nom de l'amont"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Type de test en amont"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Disponibilité :"
 msgstr "Disponibilité :"
@@ -5866,7 +5888,7 @@ msgstr ""
 "actuelles. Assurez-vous d'avoir un fichier de sauvegarde valide et un jeton "
 "actuelles. Assurez-vous d'avoir un fichier de sauvegarde valide et un jeton "
 "de sécurité, et sélectionnez soigneusement ce qu'il faut restaurer."
 "de sécurité, et sélectionnez soigneusement ce qu'il faut restaurer."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6061,6 +6083,9 @@ msgstr "Vos anciens codes ne fonctionneront plus."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Vos clés d'accès"
 msgstr "Vos clés d'accès"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Sélectionner une action après la synchronisation"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Démarrer la liaison"
 #~ msgstr "Démarrer la liaison"
 
 

+ 67 - 42
app/src/language/ja_JP/app.po

@@ -141,14 +141,14 @@ msgstr "操作"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -754,7 +754,7 @@ msgstr "証明書の種類"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "証明書"
 msgstr "証明書"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "証明書リスト"
 msgstr "証明書リスト"
 
 
@@ -1036,7 +1036,7 @@ msgstr "設定パスが空です"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "設定テンプレート"
 msgstr "設定テンプレート"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "設定"
 msgstr "設定"
 
 
@@ -1155,7 +1155,7 @@ msgid ""
 msgstr "Nginx 設定と Nginx UI 設定を含むシステムバックアップを作成します。バックアップファイルは自動的にコンピュータにダウンロードされます。"
 msgstr "Nginx 設定と Nginx UI 設定を含むシステムバックアップを作成します。バックアップファイルは自動的にコンピュータにダウンロードされます。"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1490,7 +1490,7 @@ msgstr "ストリーム %{name} を %{node} から無効化しました"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1505,8 +1505,8 @@ msgstr "無効化に成功しました"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "ディスク IO"
 msgstr "ディスク IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS 認証情報"
 msgstr "DNS 認証情報"
 
 
@@ -1765,7 +1765,7 @@ msgstr "TOTP を有効にする"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2484,7 +2484,7 @@ msgstr "ドメインにCNAMEレコードがあり、証明書を取得できな
 msgid "Import"
 msgid "Import"
 msgstr "インポート"
 msgstr "インポート"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "証明書をインポート"
 msgstr "証明書をインポート"
@@ -2800,7 +2800,7 @@ msgid "Loading data..."
 msgstr "データを読み込んでいます..."
 msgstr "データを読み込んでいます..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2867,9 +2867,17 @@ msgstr ""
 "Nginx UI をインストールするユーザーは、このオプションを手動で有効にすることができます。Nginx UI の crontab "
 "Nginx UI をインストールするユーザーは、このオプションを手動で有効にすることができます。Nginx UI の crontab "
 "タスクスケジューラは、設定した間隔(分単位)で logrotate コマンドを実行します。"
 "タスクスケジューラは、設定した間隔(分単位)で logrotate コマンドを実行します。"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "メイン"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "メインノード"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "メンテナンス"
 msgstr "メンテナンス"
 
 
@@ -3020,6 +3028,10 @@ msgstr "分"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "分"
 msgstr "分"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "ミラー"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "モデル"
 msgstr "モデル"
@@ -3033,7 +3045,7 @@ msgstr "更新日時"
 msgid "Modify"
 msgid "Modify"
 msgstr "変更"
 msgstr "変更"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "証明書を変更"
 msgstr "証明書を変更"
@@ -3066,17 +3078,21 @@ msgstr "毎月%{day}日%{time}に"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "複数行ディレクティブ"
 msgstr "複数行ディレクティブ"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "該当なし"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3365,8 +3381,7 @@ msgid "No"
 msgstr "いいえ"
 msgstr "いいえ"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "アクションなし"
 msgstr "アクションなし"
 
 
@@ -3395,7 +3410,7 @@ msgid "Node"
 msgstr "ノード"
 msgstr "ノード"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "ノードグループ"
 msgstr "ノードグループ"
@@ -3413,6 +3428,10 @@ msgstr "ノード名"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "ノードシークレット"
 msgstr "ノードシークレット"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "ノードステータス"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "ノード"
 msgstr "ノード"
@@ -3435,7 +3454,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "有効開始日: %{date}"
 msgstr "有効開始日: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "注記"
 msgstr "注記"
 
 
@@ -3513,6 +3532,7 @@ msgstr "公式ドキュメント"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3539,7 +3559,7 @@ msgstr "OK"
 msgid "On"
 msgid "On"
 msgstr "オン"
 msgstr "オン"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "検証が完了すると、レコードは削除されます。"
 msgstr "検証が完了すると、レコードは削除されます。"
 
 
@@ -3547,6 +3567,7 @@ msgstr "検証が完了すると、レコードは削除されます。"
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3767,7 +3788,7 @@ msgstr "すべての項目を正しく入力してください"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "必要なS3設定項目を入力してください"
 msgstr "必要なS3設定項目を入力してください"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3826,7 +3847,7 @@ msgstr "ユーザー名を入力してください!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "ログインしてください。"
 msgstr "ログインしてください。"
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "以下の時間設定の単位はすべて秒であることに注意してください。"
 msgstr "以下の時間設定の単位はすべて秒であることに注意してください。"
 
 
@@ -3887,8 +3908,7 @@ msgid "Port Scanner"
 msgstr "ポートスキャナー"
 msgstr "ポートスキャナー"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同期後のアクション"
 msgstr "同期後のアクション"
 
 
@@ -3950,7 +3970,7 @@ msgid ""
 "proxy."
 "proxy."
 msgstr "プロトコル設定は直接接続時にのみ有効です。リバースプロキシを使用している場合は、リバースプロキシで個別にプロトコルを設定してください。"
 msgstr "プロトコル設定は直接接続時にのみ有効です。リバースプロキシを使用している場合は、リバースプロキシで個別にプロトコルを設定してください。"
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "プロバイダー"
 msgstr "プロバイダー"
 
 
@@ -3962,7 +3982,7 @@ msgstr "プロバイダーが見つかりません: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "プロキシ"
 msgstr "プロキシ"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "プロキシパス"
 msgstr "プロキシパス"
 
 
@@ -4067,9 +4087,7 @@ msgid "Reload"
 msgstr "再読み込み"
 msgstr "再読み込み"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4107,6 +4125,10 @@ msgstr "再読み込み中"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "nginx をリロード中"
 msgstr "nginx をリロード中"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "リモート"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4609,10 +4631,6 @@ msgstr "セキュリティトークン情報"
 msgid "Select all"
 msgid "Select all"
 msgstr "すべて選択"
 msgstr "すべて選択"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "同期後のアクションを選択"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "選択された {count} ファイル"
 msgstr "選択された {count} ファイル"
@@ -4869,7 +4887,7 @@ msgstr "静的"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "ステータス"
 msgstr "ステータス"
 
 
@@ -5041,7 +5059,7 @@ msgstr "設定の同期に成功しました"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同期ノード"
 msgstr "同期ノード"
@@ -5458,7 +5476,7 @@ msgstr "火曜日"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "二要素認証が必要です"
 msgstr "二要素認証が必要です"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5495,13 +5513,13 @@ msgstr "更新に成功しました"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5539,7 +5557,7 @@ msgstr "ファイルをアップロード"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "フォルダをアップロード"
 msgstr "フォルダをアップロード"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "アップストリーム"
 msgstr "アップストリーム"
 
 
@@ -5547,6 +5565,10 @@ msgstr "アップストリーム"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "アップストリーム名"
 msgstr "アップストリーム名"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "アップストリームテストタイプ"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "稼働時間:"
 msgstr "稼働時間:"
@@ -5665,7 +5687,7 @@ msgid ""
 "to restore."
 "to restore."
 msgstr "警告: 復元操作は現在の設定を上書きします。有効なバックアップファイルとセキュリティトークンがあることを確認し、復元する内容を慎重に選択してください。"
 msgstr "警告: 復元操作は現在の設定を上書きします。有効なバックアップファイルとセキュリティトークンがあることを確認し、復元する内容を慎重に選択してください。"
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5836,6 +5858,9 @@ msgstr "以前のコードはもう使えません。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "あなたのパスキー"
 msgstr "あなたのパスキー"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "同期後のアクションを選択"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "リンクスタート"
 #~ msgstr "リンクスタート"
 
 

+ 67 - 42
app/src/language/ko_KR/app.po

@@ -139,14 +139,14 @@ msgstr "작업"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "작업"
 msgstr "작업"
@@ -753,7 +753,7 @@ msgstr "인증서 유형"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "인증서"
 msgstr "인증서"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "인증서 목록"
 msgstr "인증서 목록"
 
 
@@ -1033,7 +1033,7 @@ msgstr "설정 경로가 비어 있습니다"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "설정 템플릿"
 msgstr "설정 템플릿"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "구성"
 msgstr "구성"
 
 
@@ -1152,7 +1152,7 @@ msgid ""
 msgstr "Nginx 구성 및 Nginx UI 설정을 포함한 시스템 백업을 생성합니다. 백업 파일은 자동으로 컴퓨터에 다운로드됩니다."
 msgstr "Nginx 구성 및 Nginx UI 설정을 포함한 시스템 백업을 생성합니다. 백업 파일은 자동으로 컴퓨터에 다운로드됩니다."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1487,7 +1487,7 @@ msgstr "스트림 %{name}을(를) %{node}에서 비활성화했습니다"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1502,8 +1502,8 @@ msgstr "성공적으로 비활성화됨"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "디스크 IO"
 msgstr "디스크 IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS 인증 정보"
 msgstr "DNS 인증 정보"
 
 
@@ -1764,7 +1764,7 @@ msgstr "TOTP 활성화"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2483,7 +2483,7 @@ msgstr "도메인에 CNAME 레코드가 있고 인증서를 얻을 수 없는 
 msgid "Import"
 msgid "Import"
 msgstr "가져오기"
 msgstr "가져오기"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "인증서 가져오기"
 msgstr "인증서 가져오기"
@@ -2799,7 +2799,7 @@ msgid "Loading data..."
 msgstr "데이터를 불러오는 중..."
 msgstr "데이터를 불러오는 중..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2865,9 +2865,17 @@ msgstr ""
 "페이지의 매개 변수를 수정할 필요가 없습니다. 도커 컨테이너를 사용하여 Nginx UI를 설치하는사용자는이 옵션을 수동으로 활성화할 수 "
 "페이지의 매개 변수를 수정할 필요가 없습니다. 도커 컨테이너를 사용하여 Nginx UI를 설치하는사용자는이 옵션을 수동으로 활성화할 수 "
 "있습니다. Nginx UI의 크론탭 작업 스케줄러는설정한 간격 (분 단위)에서 logrotate 명령을 실행합니다."
 "있습니다. Nginx UI의 크론탭 작업 스케줄러는설정한 간격 (분 단위)에서 logrotate 명령을 실행합니다."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "메인"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "메인 노드"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "유지보수"
 msgstr "유지보수"
 
 
@@ -3016,6 +3024,10 @@ msgstr "분"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "분"
 msgstr "분"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "미러"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "모델"
 msgstr "모델"
@@ -3029,7 +3041,7 @@ msgstr "수정일시"
 msgid "Modify"
 msgid "Modify"
 msgstr "수정"
 msgstr "수정"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "인증서 수정"
 msgstr "인증서 수정"
@@ -3062,17 +3074,21 @@ msgstr "매월 %{day}일 %{time}에"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "여러 줄 지시문"
 msgstr "여러 줄 지시문"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "해당 없음"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3361,8 +3377,7 @@ msgid "No"
 msgstr "아니요"
 msgstr "아니요"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "작업 없음"
 msgstr "작업 없음"
 
 
@@ -3391,7 +3406,7 @@ msgid "Node"
 msgstr "노드"
 msgstr "노드"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "노드 그룹"
 msgstr "노드 그룹"
@@ -3409,6 +3424,10 @@ msgstr "노드 이름"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "노드 시크릿"
 msgstr "노드 시크릿"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "노드 상태"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "노드"
 msgstr "노드"
@@ -3431,7 +3450,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "유효 시작일: %{date}"
 msgstr "유효 시작일: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "참고"
 msgstr "참고"
 
 
@@ -3509,6 +3528,7 @@ msgstr "공식 문서"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3535,7 +3555,7 @@ msgstr "확인"
 msgid "On"
 msgid "On"
 msgstr "켜짐"
 msgstr "켜짐"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 
 
@@ -3543,6 +3563,7 @@ msgstr "검증이 완료되면, 레코드는 제거됩니다."
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3763,7 +3784,7 @@ msgstr "모든 필드를 올바르게 작성해 주세요"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "필수 S3 구성 필드를 입력해 주세요"
 msgstr "필수 S3 구성 필드를 입력해 주세요"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3820,7 +3841,7 @@ msgstr "사용자 이름을 입력해주세요!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "로그인해 주세요."
 msgstr "로그인해 주세요."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "아래의 시간 설정 단위는 모두 초 단위임을 유의해주세요."
 msgstr "아래의 시간 설정 단위는 모두 초 단위임을 유의해주세요."
 
 
@@ -3881,8 +3902,7 @@ msgid "Port Scanner"
 msgstr "포트 스캐너"
 msgstr "포트 스캐너"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "동기화 후 작업"
 msgstr "동기화 후 작업"
 
 
@@ -3944,7 +3964,7 @@ msgid ""
 "proxy."
 "proxy."
 msgstr "프로토콜 설정은 직접 연결할 때만 적용됩니다. 리버스 프록시를 사용하는 경우 리버스 프록시에서 별도로 프로토콜을 구성하세요."
 msgstr "프로토콜 설정은 직접 연결할 때만 적용됩니다. 리버스 프록시를 사용하는 경우 리버스 프록시에서 별도로 프로토콜을 구성하세요."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "제공자"
 msgstr "제공자"
 
 
@@ -3956,7 +3976,7 @@ msgstr "공급자를 찾을 수 없음: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "프록시"
 msgstr "프록시"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "프록시 패스"
 msgstr "프록시 패스"
 
 
@@ -4061,9 +4081,7 @@ msgid "Reload"
 msgstr "리로드"
 msgstr "리로드"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4101,6 +4119,10 @@ msgstr "리로딩 중"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Nginx 리로딩 중"
 msgstr "Nginx 리로딩 중"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "원격"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4605,10 +4627,6 @@ msgstr "보안 토큰 정보"
 msgid "Select all"
 msgid "Select all"
 msgstr "모두 선택"
 msgstr "모두 선택"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "동기화 후 작업 선택"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "선택된 {count} 파일"
 msgstr "선택된 {count} 파일"
@@ -4865,7 +4883,7 @@ msgstr "정적"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "상태"
 msgstr "상태"
 
 
@@ -5037,7 +5055,7 @@ msgstr "구성 동기화 성공"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "동기화 노드"
 msgstr "동기화 노드"
@@ -5452,7 +5470,7 @@ msgstr "화요일"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "2단계 인증이 필요합니다"
 msgstr "2단계 인증이 필요합니다"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5489,13 +5507,13 @@ msgstr "성공적으로 업데이트되었습니다"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5533,7 +5551,7 @@ msgstr "파일 업로드"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "폴더 업로드"
 msgstr "폴더 업로드"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "업스트림"
 msgstr "업스트림"
 
 
@@ -5541,6 +5559,10 @@ msgstr "업스트림"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "업스트림 이름"
 msgstr "업스트림 이름"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "업스트림 테스트 유형"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "가동 시간:"
 msgstr "가동 시간:"
@@ -5659,7 +5681,7 @@ msgid ""
 "to restore."
 "to restore."
 msgstr "경고: 복원 작업은 현재 구성을 덮어씁니다. 유효한 백업 파일과 보안 토큰이 있는지 확인하고 복원할 내용을 신중하게 선택하십시오."
 msgstr "경고: 복원 작업은 현재 구성을 덮어씁니다. 유효한 백업 파일과 보안 토큰이 있는지 확인하고 복원할 내용을 신중하게 선택하십시오."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5832,6 +5854,9 @@ msgstr "이전 코드는 더 이상 작동하지 않습니다."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "귀하의 패스키"
 msgstr "귀하의 패스키"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "동기화 후 작업 선택"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "링크 시작"
 #~ msgstr "링크 시작"
 
 

+ 64 - 40
app/src/language/messages.pot

@@ -128,14 +128,14 @@ msgstr ""
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159
+#: src/views/site/site_list/columns.tsx:160
 #: src/views/stream/columns.tsx:123
 #: src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
@@ -744,7 +744,7 @@ msgstr ""
 msgid "Certificates"
 msgid "Certificates"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr ""
 msgstr ""
 
 
@@ -977,7 +977,7 @@ msgstr ""
 msgid "Config Template"
 msgid "Config Template"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr ""
 msgstr ""
 
 
@@ -1095,7 +1095,7 @@ msgid "Create system backups including Nginx configuration and Nginx UI settings
 msgstr ""
 msgstr ""
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1432,7 +1432,7 @@ msgstr ""
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145
+#: src/views/site/site_list/columns.tsx:146
 #: src/views/stream/columns.tsx:112
 #: src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
@@ -1448,8 +1448,8 @@ msgstr ""
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr ""
 msgstr ""
 
 
@@ -1707,7 +1707,7 @@ msgstr ""
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141
+#: src/views/site/site_list/columns.tsx:142
 #: src/views/stream/columns.tsx:108
 #: src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
@@ -2421,7 +2421,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr ""
 msgstr ""
@@ -2733,6 +2733,7 @@ msgstr ""
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/NodeSelector/NodeSelector.vue:61
 #: src/components/NodeSelector/NodeSelector.vue:61
+#: src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2786,9 +2787,17 @@ msgstr ""
 msgid "Logrotate, by default, is enabled in most mainstream Linux distributions for users who install Nginx UI on the host machine, so you don't need to modify the parameters on this page. For users who install Nginx UI using Docker containers, you can manually enable this option. The crontab task scheduler of Nginx UI will execute the logrotate command at the interval you set in minutes."
 msgid "Logrotate, by default, is enabled in most mainstream Linux distributions for users who install Nginx UI on the host machine, so you don't need to modify the parameters on this page. For users who install Nginx UI using Docker containers, you can manually enable this option. The crontab task scheduler of Nginx UI will execute the logrotate command at the interval you set in minutes."
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr ""
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr ""
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr ""
 msgstr ""
 
 
@@ -2938,6 +2947,10 @@ msgstr ""
 msgid "Minutes"
 msgid "Minutes"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr ""
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr ""
 msgstr ""
@@ -2951,7 +2964,7 @@ msgstr ""
 msgid "Modify"
 msgid "Modify"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr ""
 msgstr ""
@@ -2984,17 +2997,21 @@ msgstr ""
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr ""
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3287,8 +3304,7 @@ msgid "No"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr ""
 msgstr ""
 
 
@@ -3317,7 +3333,7 @@ msgid "Node"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90
+#: src/views/site/site_list/columns.tsx:91
 #: src/views/stream/columns.tsx:58
 #: src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
@@ -3336,6 +3352,10 @@ msgstr ""
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr ""
 msgstr ""
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr ""
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr ""
 msgstr ""
@@ -3358,7 +3378,7 @@ msgid "Not Valid Before: %{date}"
 msgstr ""
 msgstr ""
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr ""
 msgstr ""
 
 
@@ -3432,6 +3452,7 @@ msgstr ""
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3459,7 +3480,7 @@ msgstr ""
 msgid "On"
 msgid "On"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
@@ -3467,6 +3488,7 @@ msgstr ""
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3681,7 +3703,7 @@ msgstr ""
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid "Please fill in the API authentication credentials provided by your DNS provider."
 msgid "Please fill in the API authentication credentials provided by your DNS provider."
 msgstr ""
 msgstr ""
 
 
@@ -3730,7 +3752,7 @@ msgstr ""
 msgid "Please log in."
 msgid "Please log in."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 
 
@@ -3791,8 +3813,7 @@ msgid "Port Scanner"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr ""
 msgstr ""
 
 
@@ -3853,7 +3874,7 @@ msgstr ""
 msgid "Protocol configuration only takes effect when directly connecting. If using reverse proxy, please configure the protocol separately in the reverse proxy."
 msgid "Protocol configuration only takes effect when directly connecting. If using reverse proxy, please configure the protocol separately in the reverse proxy."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr ""
 msgstr ""
 
 
@@ -3865,7 +3886,7 @@ msgstr ""
 msgid "Proxy"
 msgid "Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr ""
 msgstr ""
 
 
@@ -3969,8 +3990,7 @@ msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4008,6 +4028,10 @@ msgstr ""
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr ""
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4512,10 +4536,6 @@ msgstr ""
 msgid "Select all"
 msgid "Select all"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr ""
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr ""
 msgstr ""
@@ -4765,7 +4785,7 @@ msgstr ""
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119
+#: src/views/site/site_list/columns.tsx:120
 #: src/views/stream/columns.tsx:87
 #: src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr ""
 msgstr ""
@@ -4929,7 +4949,7 @@ msgstr ""
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr ""
 msgstr ""
@@ -5290,7 +5310,7 @@ msgstr ""
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5327,13 +5347,13 @@ msgstr ""
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:113
 #: src/views/stream/columns.tsx:80
 #: src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
@@ -5373,7 +5393,7 @@ msgstr ""
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr ""
 msgstr ""
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr ""
 msgstr ""
 
 
@@ -5381,6 +5401,10 @@ msgstr ""
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr ""
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr ""
 msgstr ""
@@ -5500,7 +5524,7 @@ msgstr ""
 msgid "Warning: Restore operation will overwrite current configurations. Make sure you have a valid backup file and security token, and carefully select what to restore."
 msgid "Warning: Restore operation will overwrite current configurations. Make sure you have a valid backup file and security token, and carefully select what to restore."
 msgstr ""
 msgstr ""
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid "We will add one or more TXT records to the DNS records of your domain for ownership verification."
 msgid "We will add one or more TXT records to the DNS records of your domain for ownership verification."
 msgstr ""
 msgstr ""
 
 

+ 67 - 42
app/src/language/pt_PT/app.po

@@ -141,14 +141,14 @@ msgstr "Acção"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Ações"
 msgstr "Ações"
@@ -771,7 +771,7 @@ msgstr "Tipo de certificado"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Certificados"
 msgstr "Certificados"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Lista de Certificados"
 msgstr "Lista de Certificados"
 
 
@@ -1069,7 +1069,7 @@ msgstr "O caminho de configuração está vazio"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Modelo de Configuração"
 msgstr "Modelo de Configuração"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Configuração"
 msgstr "Configuração"
 
 
@@ -1193,7 +1193,7 @@ msgstr ""
 "automaticamente para o seu computador."
 "automaticamente para o seu computador."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1530,7 +1530,7 @@ msgstr "Desativar o fluxo %{name} de %{node} com sucesso"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1545,8 +1545,8 @@ msgstr "Desactivado com sucesso"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "E/S de Disco"
 msgstr "E/S de Disco"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "Credenciais DNS"
 msgstr "Credenciais DNS"
 
 
@@ -1808,7 +1808,7 @@ msgstr "Ativar TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2536,7 +2536,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Importar"
 msgstr "Importar"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Importar Certificados"
 msgstr "Importar Certificados"
@@ -2858,7 +2858,7 @@ msgid "Loading data..."
 msgstr "A carregar dados..."
 msgstr "A carregar dados..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2929,9 +2929,17 @@ msgstr ""
 "activar manualmente esta opção. O agendador de tarefas crontab do Nginx UI "
 "activar manualmente esta opção. O agendador de tarefas crontab do Nginx UI "
 "executará o comando logrotate no intervalo que definir em minutos."
 "executará o comando logrotate no intervalo que definir em minutos."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Principal"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Nó principal"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Manutenção"
 msgstr "Manutenção"
 
 
@@ -3082,6 +3090,10 @@ msgstr "Minuto"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Minutos"
 msgstr "Minutos"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Espelho"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Modelo"
 msgstr "Modelo"
@@ -3095,7 +3107,7 @@ msgstr "Modificado em"
 msgid "Modify"
 msgid "Modify"
 msgstr "Modificar"
 msgstr "Modificar"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Modificar Certificado"
 msgstr "Modificar Certificado"
@@ -3128,17 +3140,21 @@ msgstr "Mensalmente no dia %{day} às %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Diretiva Multilinha"
 msgstr "Diretiva Multilinha"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "N/D"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3429,8 +3445,7 @@ msgid "No"
 msgstr "Não"
 msgstr "Não"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Sem ação"
 msgstr "Sem ação"
 
 
@@ -3459,7 +3474,7 @@ msgid "Node"
 msgstr "Nó"
 msgstr "Nó"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Grupo de nós"
 msgstr "Grupo de nós"
@@ -3477,6 +3492,10 @@ msgstr "Nome do nó"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Segredo do Nó"
 msgstr "Segredo do Nó"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Estado do Nó"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Nós"
 msgstr "Nós"
@@ -3499,7 +3518,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Não Válido Antes de: %{date}"
 msgstr "Não Válido Antes de: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Nota"
 msgstr "Nota"
 
 
@@ -3583,6 +3602,7 @@ msgstr "Documentação oficial"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3609,7 +3629,7 @@ msgstr "OK"
 msgid "On"
 msgid "On"
 msgstr "Ligado"
 msgstr "Ligado"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 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."
 msgstr "Assim que a verificação estiver concluída, os registos serão removidos."
 
 
@@ -3617,6 +3637,7 @@ msgstr "Assim que a verificação estiver concluída, os registos serão removid
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3843,7 +3864,7 @@ msgstr "Por favor, preencha todos os campos corretamente"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Por favor, preencha os campos de configuração do S3 necessários"
 msgstr "Por favor, preencha os campos de configuração do S3 necessários"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3910,7 +3931,7 @@ msgstr "Por favor introduza o seu nome de utilizador!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Por favor, faça login."
 msgstr "Por favor, faça login."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "Note que as definições da unidade de tempo abaixo estão todas em segundos."
 msgstr "Note que as definições da unidade de tempo abaixo estão todas em segundos."
 
 
@@ -3973,8 +3994,7 @@ msgid "Port Scanner"
 msgstr "Scanner de portas"
 msgstr "Scanner de portas"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Ação pós-sincronização"
 msgstr "Ação pós-sincronização"
 
 
@@ -4039,7 +4059,7 @@ msgstr ""
 "estiver a usar um proxy inverso, configure o protocolo separadamente no "
 "estiver a usar um proxy inverso, configure o protocolo separadamente no "
 "proxy inverso."
 "proxy inverso."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Provedor"
 msgstr "Provedor"
 
 
@@ -4051,7 +4071,7 @@ msgstr "Fornecedor não encontrado: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Passe de Proxy"
 msgstr "Passe de Proxy"
 
 
@@ -4160,9 +4180,7 @@ msgid "Reload"
 msgstr "Recarregar"
 msgstr "Recarregar"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4200,6 +4218,10 @@ msgstr "Recarregando"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Recarregando Nginx"
 msgstr "Recarregando Nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Remoto"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4711,10 +4733,6 @@ msgstr "Informações do token de segurança"
 msgid "Select all"
 msgid "Select all"
 msgstr "Selecionar tudo"
 msgstr "Selecionar tudo"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Selecionar uma ação após sincronização"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "{count} ficheiros selecionados"
 msgstr "{count} ficheiros selecionados"
@@ -4979,7 +4997,7 @@ msgstr "Estático"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Estado"
 msgstr "Estado"
 
 
@@ -5155,7 +5173,7 @@ msgstr "Sucesso na configuração da sincronização"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Nós de sincronização"
 msgstr "Nós de sincronização"
@@ -5615,7 +5633,7 @@ msgstr "Terça-feira"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Autenticação de dois fatores necessária"
 msgstr "Autenticação de dois fatores necessária"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5652,13 +5670,13 @@ msgstr "Atualização bem-sucedida"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5696,7 +5714,7 @@ msgstr "Carregar ficheiros"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Carregar pastas"
 msgstr "Carregar pastas"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "A montante"
 msgstr "A montante"
 
 
@@ -5704,6 +5722,10 @@ msgstr "A montante"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Nome do Upstream"
 msgstr "Nome do Upstream"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Tipo de teste de upstream"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Uptime:"
 msgstr "Uptime:"
@@ -5825,7 +5847,7 @@ msgstr ""
 "Certifique-se de que tem um ficheiro de cópia de segurança válido e um "
 "Certifique-se de que tem um ficheiro de cópia de segurança válido e um "
 "token de segurança, e selecione cuidadosamente o que restaurar."
 "token de segurança, e selecione cuidadosamente o que restaurar."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6016,6 +6038,9 @@ msgstr "Os seus códigos antigos não funcionarão mais."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "As suas chaves de acesso"
 msgstr "As suas chaves de acesso"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Selecionar uma ação após sincronização"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Início do link"
 #~ msgstr "Início do link"
 
 

+ 67 - 42
app/src/language/ru_RU/app.po

@@ -145,14 +145,14 @@ msgstr "Действие"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Действия"
 msgstr "Действия"
@@ -777,7 +777,7 @@ msgstr "Тип сертификата"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Сертификаты"
 msgstr "Сертификаты"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Список сертификатов"
 msgstr "Список сертификатов"
 
 
@@ -1074,7 +1074,7 @@ msgstr "Путь конфигурации пуст"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Шаблон конфигурации"
 msgstr "Шаблон конфигурации"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Конфигурация"
 msgstr "Конфигурация"
 
 
@@ -1198,7 +1198,7 @@ msgstr ""
 "компьютер."
 "компьютер."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1533,7 +1533,7 @@ msgstr "Поток %{name} отключен от %{node} успешно"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1548,8 +1548,8 @@ msgstr "Отключено успешно"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "Нагрузка на Диск IO"
 msgstr "Нагрузка на Диск IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS учетные данные"
 msgstr "DNS учетные данные"
 
 
@@ -1811,7 +1811,7 @@ msgstr "Включить TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2541,7 +2541,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Импорт"
 msgstr "Импорт"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Импортировать сертификат"
 msgstr "Импортировать сертификат"
@@ -2863,7 +2863,7 @@ msgid "Loading data..."
 msgstr "Загрузка данных..."
 msgstr "Загрузка данных..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2934,9 +2934,17 @@ msgstr ""
 "можете вручную включить эту опцию. Планировщик задач crontab Nginx UI будет "
 "можете вручную включить эту опцию. Планировщик задач crontab Nginx UI будет "
 "выполнять команду logrotate с интервалом, который вы установите в минутах."
 "выполнять команду logrotate с интервалом, который вы установите в минутах."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Основной"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Главный узел"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Техническое обслуживание"
 msgstr "Техническое обслуживание"
 
 
@@ -3087,6 +3095,10 @@ msgstr "Минута"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Минуты"
 msgstr "Минуты"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Зеркало"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Модель"
 msgstr "Модель"
@@ -3100,7 +3112,7 @@ msgstr "Изменено"
 msgid "Modify"
 msgid "Modify"
 msgstr "Изменить"
 msgstr "Изменить"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Изменить сертификат"
 msgstr "Изменить сертификат"
@@ -3133,17 +3145,21 @@ msgstr "Ежемесячно в день %{day} в %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Многострочная директива"
 msgstr "Многострочная директива"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "Н/Д"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3434,8 +3450,7 @@ msgid "No"
 msgstr "Нет"
 msgstr "Нет"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Нет действия"
 msgstr "Нет действия"
 
 
@@ -3464,7 +3479,7 @@ msgid "Node"
 msgstr "Узел"
 msgstr "Узел"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Группа узлов"
 msgstr "Группа узлов"
@@ -3482,6 +3497,10 @@ msgstr "Имя узла"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Секрет узла"
 msgstr "Секрет узла"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Статус узла"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Узлы"
 msgstr "Узлы"
@@ -3504,7 +3523,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Действителен до: %{date}"
 msgstr "Действителен до: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Заметка"
 msgstr "Заметка"
 
 
@@ -3588,6 +3607,7 @@ msgstr "Официальная документация"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3614,7 +3634,7 @@ msgstr "ОК"
 msgid "On"
 msgid "On"
 msgstr "Вкл"
 msgstr "Вкл"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "После завершения проверки записи будут удалены."
 msgstr "После завершения проверки записи будут удалены."
 
 
@@ -3622,6 +3642,7 @@ msgstr "После завершения проверки записи будут
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3850,7 +3871,7 @@ msgstr "Пожалуйста, заполните все поля правиль
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Пожалуйста, заполните обязательные поля конфигурации S3"
 msgstr "Пожалуйста, заполните обязательные поля конфигурации S3"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3918,7 +3939,7 @@ msgstr "Введите ваше имя пользователя!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Пожалуйста, войдите в систему."
 msgstr "Пожалуйста, войдите в систему."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Обратите внимание, что единица измерения времени в конфигурациях ниже "
 "Обратите внимание, что единица измерения времени в конфигурациях ниже "
@@ -3983,8 +4004,7 @@ msgid "Port Scanner"
 msgstr "Сканер портов"
 msgstr "Сканер портов"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Действие после синхронизации"
 msgstr "Действие после синхронизации"
 
 
@@ -4049,7 +4069,7 @@ msgstr ""
 "использовании обратного прокси настройте протокол отдельно в обратном "
 "использовании обратного прокси настройте протокол отдельно в обратном "
 "прокси."
 "прокси."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Провайдер"
 msgstr "Провайдер"
 
 
@@ -4061,7 +4081,7 @@ msgstr "Поставщик не найден: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Прокси"
 msgstr "Прокси"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Прокси-передача"
 msgstr "Прокси-передача"
 
 
@@ -4170,9 +4190,7 @@ msgid "Reload"
 msgstr "Перегрузить"
 msgstr "Перегрузить"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4210,6 +4228,10 @@ msgstr "Перезагружается"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Перезагружается nginx"
 msgstr "Перезагружается nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Удаленный"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4719,10 +4741,6 @@ msgstr "Информация о токене безопасности"
 msgid "Select all"
 msgid "Select all"
 msgstr "Выбрать все"
 msgstr "Выбрать все"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Выберите действие после синхронизации"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Выбрано {count} файлов"
 msgstr "Выбрано {count} файлов"
@@ -4981,7 +4999,7 @@ msgstr "Статический"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Статус"
 msgstr "Статус"
 
 
@@ -5157,7 +5175,7 @@ msgstr "Синхронизация конфигурации успешна"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Синхронизированные узлы"
 msgstr "Синхронизированные узлы"
@@ -5614,7 +5632,7 @@ msgstr "Вторник"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Требуется двухфакторная аутентификация"
 msgstr "Требуется двухфакторная аутентификация"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5651,13 +5669,13 @@ msgstr "Успешно обновлено"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5695,7 +5713,7 @@ msgstr "Загрузить файлы"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Загрузить папки"
 msgstr "Загрузить папки"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Восходящий поток"
 msgstr "Восходящий поток"
 
 
@@ -5703,6 +5721,10 @@ msgstr "Восходящий поток"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Имя Upstream"
 msgstr "Имя Upstream"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Тип теста апстрима"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Аптайм:"
 msgstr "Аптайм:"
@@ -5824,7 +5846,7 @@ msgstr ""
 "Убедитесь, что у вас есть действительный файл резервной копии и токен "
 "Убедитесь, что у вас есть действительный файл резервной копии и токен "
 "безопасности, и тщательно выберите, что восстанавливать."
 "безопасности, и тщательно выберите, что восстанавливать."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6012,6 +6034,9 @@ msgstr "Ваши старые коды больше не будут работа
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Ваши ключи доступа"
 msgstr "Ваши ключи доступа"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Выберите действие после синхронизации"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Начало ссылки"
 #~ msgstr "Начало ссылки"
 
 

+ 67 - 42
app/src/language/tr_TR/app.po

@@ -143,14 +143,14 @@ msgstr "Eylem"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "İşlemler"
 msgstr "İşlemler"
@@ -765,7 +765,7 @@ msgstr "Sertifika Türü"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Sertifikalar"
 msgstr "Sertifikalar"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Sertifika Listesi"
 msgstr "Sertifika Listesi"
 
 
@@ -1065,7 +1065,7 @@ msgstr "Yapılandırma yolu boş"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Yapılandırma Şablonu"
 msgstr "Yapılandırma Şablonu"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Yapılandırma"
 msgstr "Yapılandırma"
 
 
@@ -1188,7 +1188,7 @@ msgstr ""
 "oluşturun. Yedek dosyaları otomatik olarak bilgisayarınıza indirilecektir."
 "oluşturun. Yedek dosyaları otomatik olarak bilgisayarınıza indirilecektir."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1525,7 +1525,7 @@ msgstr "Akış %{name}, %{node} üzerinden başarıyla devre dışı bırakıld
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1540,8 +1540,8 @@ msgstr "Başarıyla devre dışı bırakıldı"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "Disk IO"
 msgstr "Disk IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS Kimlik Bilgileri"
 msgstr "DNS Kimlik Bilgileri"
 
 
@@ -1805,7 +1805,7 @@ msgstr "TOTP'yi Etkinleştir"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2537,7 +2537,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "İçe Aktar"
 msgstr "İçe Aktar"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Sertifika İçe Aktar"
 msgstr "Sertifika İçe Aktar"
@@ -2859,7 +2859,7 @@ msgid "Loading data..."
 msgstr "Veriler yükleniyor..."
 msgstr "Veriler yükleniyor..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2929,9 +2929,17 @@ msgstr ""
 "olarak etkinleştirebilir. Nginx UI'nin crontab görev zamanlayıcısı, "
 "olarak etkinleştirebilir. Nginx UI'nin crontab görev zamanlayıcısı, "
 "belirlediğiniz dakika aralığında logrotate komutunu çalıştıracaktır."
 "belirlediğiniz dakika aralığında logrotate komutunu çalıştıracaktır."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Ana"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Ana Düğüm"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Bakım"
 msgstr "Bakım"
 
 
@@ -3082,6 +3090,10 @@ msgstr "Dakika"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Dakika"
 msgstr "Dakika"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Ayna"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Model"
 msgstr "Model"
@@ -3095,7 +3107,7 @@ msgstr "Değiştirilme Tarihi"
 msgid "Modify"
 msgid "Modify"
 msgstr "Değiştir"
 msgstr "Değiştir"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Sertifikayı Düzenle"
 msgstr "Sertifikayı Düzenle"
@@ -3128,17 +3140,21 @@ msgstr "Her ayın %{day} günü %{time} saatinde"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Çok Satırlı Yönergeler"
 msgstr "Çok Satırlı Yönergeler"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "Yok"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3429,8 +3445,7 @@ msgid "No"
 msgstr "Hayır"
 msgstr "Hayır"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Eylem Yok"
 msgstr "Eylem Yok"
 
 
@@ -3459,7 +3474,7 @@ msgid "Node"
 msgstr "Düğüm"
 msgstr "Düğüm"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Düğüm Grubu"
 msgstr "Düğüm Grubu"
@@ -3477,6 +3492,10 @@ msgstr "Düğüm adı"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Düğüm Sırrı"
 msgstr "Düğüm Sırrı"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Düğüm Durumu"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Düğümler"
 msgstr "Düğümler"
@@ -3499,7 +3518,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Geçerlilik Başlangıç Tarihi: %{date}"
 msgstr "Geçerlilik Başlangıç Tarihi: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Not"
 msgstr "Not"
 
 
@@ -3583,6 +3602,7 @@ msgstr "Resmi Belge"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3609,7 +3629,7 @@ msgstr "Tamam"
 msgid "On"
 msgid "On"
 msgstr "Açık"
 msgstr "Açık"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Doğrulama tamamlandığında, kayıtlar kaldırılacaktır."
 msgstr "Doğrulama tamamlandığında, kayıtlar kaldırılacaktır."
 
 
@@ -3617,6 +3637,7 @@ msgstr "Doğrulama tamamlandığında, kayıtlar kaldırılacaktır."
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3842,7 +3863,7 @@ msgstr "Lütfen tüm alanları doğru şekilde doldurun"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Lütfen gerekli S3 yapılandırma alanlarını doldurun"
 msgstr "Lütfen gerekli S3 yapılandırma alanlarını doldurun"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3908,7 +3929,7 @@ msgstr "Lütfen kullanıcı adınızı girin!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Lütfen giriş yapın."
 msgstr "Lütfen giriş yapın."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Lütfen aşağıdaki zaman yapılandırmalarının birimlerinin saniye cinsinden "
 "Lütfen aşağıdaki zaman yapılandırmalarının birimlerinin saniye cinsinden "
@@ -3973,8 +3994,7 @@ msgid "Port Scanner"
 msgstr "Port Tarayıcı"
 msgstr "Port Tarayıcı"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Senkronizasyon Sonrası İşlem"
 msgstr "Senkronizasyon Sonrası İşlem"
 
 
@@ -4038,7 +4058,7 @@ msgstr ""
 "Protokol yapılandırması yalnızca doğrudan bağlantı sırasında geçerlidir. "
 "Protokol yapılandırması yalnızca doğrudan bağlantı sırasında geçerlidir. "
 "Ters proxy kullanıyorsanız, protokolü ters proxyda ayrı olarak yapılandırın."
 "Ters proxy kullanıyorsanız, protokolü ters proxyda ayrı olarak yapılandırın."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Sağlayıcı"
 msgstr "Sağlayıcı"
 
 
@@ -4050,7 +4070,7 @@ msgstr "Sağlayıcı bulunamadı: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Proxy Geçişi"
 msgstr "Proxy Geçişi"
 
 
@@ -4159,9 +4179,7 @@ msgid "Reload"
 msgstr "Yeniden Yükle"
 msgstr "Yeniden Yükle"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4199,6 +4217,10 @@ msgstr "Yeniden Yükleniyor"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "nginx yeniden yükleniyor"
 msgstr "nginx yeniden yükleniyor"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Uzak"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4715,10 +4737,6 @@ msgstr "Güvenlik Belirteci Bilgileri"
 msgid "Select all"
 msgid "Select all"
 msgstr "Tümünü seç"
 msgstr "Tümünü seç"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Senkronizasyon sonrası eylem seçin"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Seçilen {count} dosya"
 msgstr "Seçilen {count} dosya"
@@ -4979,7 +4997,7 @@ msgstr "Statik"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Durum"
 msgstr "Durum"
 
 
@@ -5157,7 +5175,7 @@ msgstr "Yapılandırma Başarıyla Senkronize Edildi"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Senkronizasyon Düğümleri"
 msgstr "Senkronizasyon Düğümleri"
@@ -5613,7 +5631,7 @@ msgstr "Salı"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "İki faktörlü kimlik doğrulama gerekiyor"
 msgstr "İki faktörlü kimlik doğrulama gerekiyor"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5650,13 +5668,13 @@ msgstr "Başarıyla güncellendi"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5694,7 +5712,7 @@ msgstr "Dosyaları Yükle"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Klasörleri Yükle"
 msgstr "Klasörleri Yükle"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Yukarı Akış"
 msgstr "Yukarı Akış"
 
 
@@ -5702,6 +5720,10 @@ msgstr "Yukarı Akış"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Yukarı Akış Adı"
 msgstr "Yukarı Akış Adı"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Yukarı Akış Test Türü"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Çalışma Süresi:"
 msgstr "Çalışma Süresi:"
@@ -5823,7 +5845,7 @@ msgstr ""
 "Geçerli bir yedekleme dosyasına ve güvenlik belirtecine sahip olduğunuzdan "
 "Geçerli bir yedekleme dosyasına ve güvenlik belirtecine sahip olduğunuzdan "
 "emin olun ve neyi geri yükleyeceğinizi dikkatlice seçin."
 "emin olun ve neyi geri yükleyeceğinizi dikkatlice seçin."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6013,6 +6035,9 @@ msgstr "Eski kodlarınız artık çalışmayacak."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Geçiş Anahtarlarınız"
 msgstr "Geçiş Anahtarlarınız"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Senkronizasyon sonrası eylem seçin"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Bağlantı Başlat"
 #~ msgstr "Bağlantı Başlat"
 
 

+ 67 - 42
app/src/language/uk_UA/app.po

@@ -145,14 +145,14 @@ msgstr "Дія"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Дії"
 msgstr "Дії"
@@ -773,7 +773,7 @@ msgstr "Тип сертифіката"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Сертифікати"
 msgstr "Сертифікати"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Список сертифікатів"
 msgstr "Список сертифікатів"
 
 
@@ -1068,7 +1068,7 @@ msgstr "Конфігурація порожній"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Шаблон конфігурації"
 msgstr "Шаблон конфігурації"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Конфігурація"
 msgstr "Конфігурація"
 
 
@@ -1192,7 +1192,7 @@ msgstr ""
 "комп’ютер."
 "комп’ютер."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1599,7 +1599,7 @@ msgstr "Потік %{name} успішно вимкнено з %{node}"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1614,8 +1614,8 @@ msgstr "Успішно вимкнено"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "Дисковий ввід/вивід"
 msgstr "Дисковий ввід/вивід"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS облікові дані"
 msgstr "DNS облікові дані"
 
 
@@ -1877,7 +1877,7 @@ msgstr "Увімкнути TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2607,7 +2607,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Імпорт"
 msgstr "Імпорт"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Імпортувати сертифікат"
 msgstr "Імпортувати сертифікат"
@@ -2929,7 +2929,7 @@ msgid "Loading data..."
 msgstr "Завантаження даних..."
 msgstr "Завантаження даних..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -3000,9 +3000,17 @@ msgstr ""
 "можете вручну активувати цю опцію. Планувальник завдань crontab у Nginx UI "
 "можете вручну активувати цю опцію. Планувальник завдань crontab у Nginx UI "
 "виконуватиме команду logrotate з інтервалом, який ви встановите у хвилинах."
 "виконуватиме команду logrotate з інтервалом, який ви встановите у хвилинах."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Головний"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Головний вузол"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Технічне обслуговування"
 msgstr "Технічне обслуговування"
 
 
@@ -3153,6 +3161,10 @@ msgstr "Хвилина"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Хвилини"
 msgstr "Хвилини"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Дзеркало"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Модель"
 msgstr "Модель"
@@ -3166,7 +3178,7 @@ msgstr "Змінено"
 msgid "Modify"
 msgid "Modify"
 msgstr "Змінити"
 msgstr "Змінити"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Редагувати сертифікат"
 msgstr "Редагувати сертифікат"
@@ -3199,17 +3211,21 @@ msgstr "Щомісяця %{day} числа о %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Багаторядкова директива"
 msgstr "Багаторядкова директива"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "Н/Д"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3500,8 +3516,7 @@ msgid "No"
 msgstr "Ні"
 msgstr "Ні"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Без дії"
 msgstr "Без дії"
 
 
@@ -3530,7 +3545,7 @@ msgid "Node"
 msgstr "Вузол"
 msgstr "Вузол"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Група вузлів"
 msgstr "Група вузлів"
@@ -3548,6 +3563,10 @@ msgstr "Ім’я вузла"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Секрет вузла"
 msgstr "Секрет вузла"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Стан вузла"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Вузли"
 msgstr "Вузли"
@@ -3570,7 +3589,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Не дійсний до: %{date}"
 msgstr "Не дійсний до: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Примітка"
 msgstr "Примітка"
 
 
@@ -3654,6 +3673,7 @@ msgstr "Офіційна документація"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3680,7 +3700,7 @@ msgstr "Гаразд"
 msgid "On"
 msgid "On"
 msgstr "Увімкнено"
 msgstr "Увімкнено"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Після завершення перевірки записи будуть видалені."
 msgstr "Після завершення перевірки записи будуть видалені."
 
 
@@ -3688,6 +3708,7 @@ msgstr "Після завершення перевірки записи буду
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3914,7 +3935,7 @@ msgstr "Будь ласка, заповніть усі поля правильн
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Будь ласка, заповніть обов’язкові поля конфігурації S3"
 msgstr "Будь ласка, заповніть обов’язкові поля конфігурації S3"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3980,7 +4001,7 @@ msgstr "Будь ласка, введіть ваше ім'я користува
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Будь ласка, увійдіть."
 msgstr "Будь ласка, увійдіть."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr ""
 msgstr ""
 "Будь ласка, зверніть увагу, що одиницею виміру часу в наведених нижче "
 "Будь ласка, зверніть увагу, що одиницею виміру часу в наведених нижче "
@@ -4045,8 +4066,7 @@ msgid "Port Scanner"
 msgstr "Сканер портів"
 msgstr "Сканер портів"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Дія після синхронізації"
 msgstr "Дія після синхронізації"
 
 
@@ -4111,7 +4131,7 @@ msgstr ""
 "використовуєте зворотний проксі, налаштуйте протокол окремо у зворотному "
 "використовуєте зворотний проксі, налаштуйте протокол окремо у зворотному "
 "проксі."
 "проксі."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Провайдер"
 msgstr "Провайдер"
 
 
@@ -4123,7 +4143,7 @@ msgstr "Постачальника не знайдено: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Проксі"
 msgstr "Проксі"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Проксі-передача"
 msgstr "Проксі-передача"
 
 
@@ -4233,9 +4253,7 @@ msgid "Reload"
 msgstr "Перезавантажити"
 msgstr "Перезавантажити"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4275,6 +4293,10 @@ msgstr "Перезавантаження"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Перезавантаження nginx"
 msgstr "Перезавантаження nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Віддалено"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4786,10 +4808,6 @@ msgstr "Інформація про токен безпеки"
 msgid "Select all"
 msgid "Select all"
 msgstr "Вибрати все"
 msgstr "Вибрати все"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Виберіть дію після синхронізації"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Вибрано {count} файлів"
 msgstr "Вибрано {count} файлів"
@@ -5052,7 +5070,7 @@ msgstr "Статичний"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Статус"
 msgstr "Статус"
 
 
@@ -5228,7 +5246,7 @@ msgstr "Успішна синхронізація конфігурації"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Синхронізовані вузли"
 msgstr "Синхронізовані вузли"
@@ -5684,7 +5702,7 @@ msgstr "Вівторок"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Потрібна двофакторна аутентифікація"
 msgstr "Потрібна двофакторна аутентифікація"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5721,13 +5739,13 @@ msgstr "Успішно оновлено"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5765,7 +5783,7 @@ msgstr "Завантажити файли"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Завантажити папки"
 msgstr "Завантажити папки"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Вгору за течією"
 msgstr "Вгору за течією"
 
 
@@ -5773,6 +5791,10 @@ msgstr "Вгору за течією"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Назва апстріму"
 msgstr "Назва апстріму"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Тип тестування апстриму"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Час роботи:"
 msgstr "Час роботи:"
@@ -5894,7 +5916,7 @@ msgstr ""
 "Переконайтеся, що у вас є дійсний файл резервної копії та токен безпеки, і "
 "Переконайтеся, що у вас є дійсний файл резервної копії та токен безпеки, і "
 "ретельно виберіть, що відновлювати."
 "ретельно виберіть, що відновлювати."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -6081,6 +6103,9 @@ msgstr "Ваші старі коди більше не працюватимут
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Ваші ключі доступу"
 msgstr "Ваші ключі доступу"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Виберіть дію після синхронізації"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Почати зв’язок"
 #~ msgstr "Почати зв’язок"
 
 

+ 67 - 42
app/src/language/vi_VN/app.po

@@ -136,14 +136,14 @@ msgstr "Hành động"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Hành động"
 msgstr "Hành động"
@@ -753,7 +753,7 @@ msgstr "Loại chứng chỉ"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "Chứng chỉ"
 msgstr "Chứng chỉ"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "Danh sách chứng chỉ"
 msgstr "Danh sách chứng chỉ"
 
 
@@ -1047,7 +1047,7 @@ msgstr "Đường dẫn cấu hình trống"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "Mẫu cấu hình"
 msgstr "Mẫu cấu hình"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "Cấu hình"
 msgstr "Cấu hình"
 
 
@@ -1168,7 +1168,7 @@ msgstr ""
 "tệp sao lưu sẽ tự động được tải xuống máy tính của bạn."
 "tệp sao lưu sẽ tự động được tải xuống máy tính của bạn."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1503,7 +1503,7 @@ msgstr "Đã vô hiệu hóa luồng %{name} từ %{node} thành công"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1518,8 +1518,8 @@ msgstr "Đã tắt thành công"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "Disk IO"
 msgstr "Disk IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "Xác thực DNS"
 msgstr "Xác thực DNS"
 
 
@@ -1782,7 +1782,7 @@ msgstr "Bật TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2507,7 +2507,7 @@ msgstr ""
 msgid "Import"
 msgid "Import"
 msgstr "Nhập"
 msgstr "Nhập"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "Nhập chứng chỉ"
 msgstr "Nhập chứng chỉ"
@@ -2829,7 +2829,7 @@ msgid "Loading data..."
 msgstr "Đang tải dữ liệu..."
 msgstr "Đang tải dữ liệu..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2900,9 +2900,17 @@ msgstr ""
 "chọn này. Bộ lập lịch tác vụ crontab của Nginx UI sẽ thực thi lệnh "
 "chọn này. Bộ lập lịch tác vụ crontab của Nginx UI sẽ thực thi lệnh "
 "logrotate theo khoảng thời gian bạn đặt (tính bằng phút)."
 "logrotate theo khoảng thời gian bạn đặt (tính bằng phút)."
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "Chính"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "Nút chính"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Bảo trì"
 msgstr "Bảo trì"
 
 
@@ -3053,6 +3061,10 @@ msgstr "Phút"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "Phút"
 msgstr "Phút"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "Gương"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "Mô hình"
 msgstr "Mô hình"
@@ -3066,7 +3078,7 @@ msgstr "Đã sửa đổi lúc"
 msgid "Modify"
 msgid "Modify"
 msgstr "Sửa đổi"
 msgstr "Sửa đổi"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "Sửa đổi chứng chỉ"
 msgstr "Sửa đổi chứng chỉ"
@@ -3099,17 +3111,21 @@ msgstr "Hàng tháng vào ngày %{day} lúc %{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "Chỉ thị nhiều dòng"
 msgstr "Chỉ thị nhiều dòng"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "Không có"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3400,8 +3416,7 @@ msgid "No"
 msgstr "Không"
 msgstr "Không"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "Không hành động"
 msgstr "Không hành động"
 
 
@@ -3430,7 +3445,7 @@ msgid "Node"
 msgstr "Nút"
 msgstr "Nút"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Nhóm nút"
 msgstr "Nhóm nút"
@@ -3448,6 +3463,10 @@ msgstr "Tên nút"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "Bí mật nút"
 msgstr "Bí mật nút"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "Trạng thái nút"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "Nút"
 msgstr "Nút"
@@ -3470,7 +3489,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "Không hợp lệ trước: %{date}"
 msgstr "Không hợp lệ trước: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "Ghi chú"
 msgstr "Ghi chú"
 
 
@@ -3552,6 +3571,7 @@ msgstr "Tài liệu chính thức"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3578,7 +3598,7 @@ msgstr "Đồng ý"
 msgid "On"
 msgid "On"
 msgstr "Bật"
 msgstr "Bật"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 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."
 msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 
 
@@ -3586,6 +3606,7 @@ msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3812,7 +3833,7 @@ msgstr "Vui lòng điền đầy đủ và chính xác tất cả các trường
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "Vui lòng điền vào các trường cấu hình S3 bắt buộc"
 msgstr "Vui lòng điền vào các trường cấu hình S3 bắt buộc"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3873,7 +3894,7 @@ msgstr "Vui lòng nhập username!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "Vui lòng đăng nhập."
 msgstr "Vui lòng đăng nhập."
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "Lưu ý đơn vị cấu hình thời gian bên dưới được tính bằng giây."
 msgstr "Lưu ý đơn vị cấu hình thời gian bên dưới được tính bằng giây."
 
 
@@ -3934,8 +3955,7 @@ msgid "Port Scanner"
 msgstr "Trình quét cổng"
 msgstr "Trình quét cổng"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Hành động sau đồng bộ"
 msgstr "Hành động sau đồng bộ"
 
 
@@ -3999,7 +4019,7 @@ msgstr ""
 "Cấu hình giao thức chỉ có hiệu lực khi kết nối trực tiếp. Nếu sử dụng proxy "
 "Cấu hình giao thức chỉ có hiệu lực khi kết nối trực tiếp. Nếu sử dụng proxy "
 "ngược, vui lòng cấu hình giao thức riêng trong proxy ngược."
 "ngược, vui lòng cấu hình giao thức riêng trong proxy ngược."
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "Nhà cung cấp"
 msgstr "Nhà cung cấp"
 
 
@@ -4011,7 +4031,7 @@ msgstr "Không tìm thấy nhà cung cấp: {0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "Proxy"
 msgstr "Proxy"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Chuyển tiếp Proxy"
 msgstr "Chuyển tiếp Proxy"
 
 
@@ -4120,9 +4140,7 @@ msgid "Reload"
 msgstr "Tải lại"
 msgstr "Tải lại"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4160,6 +4178,10 @@ msgstr "Đang tải lại"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "Tải lại nginx"
 msgstr "Tải lại nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "Từ xa"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4667,10 +4689,6 @@ msgstr "Thông tin mã bảo mật"
 msgid "Select all"
 msgid "Select all"
 msgstr "Chọn tất cả"
 msgstr "Chọn tất cả"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "Chọn hành động sau khi đồng bộ"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "Đã chọn {count} tệp"
 msgstr "Đã chọn {count} tệp"
@@ -4929,7 +4947,7 @@ msgstr "Tĩnh"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Trạng thái"
 msgstr "Trạng thái"
 
 
@@ -5105,7 +5123,7 @@ msgstr "Đồng bộ cấu hình thành công"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Nút đồng bộ"
 msgstr "Nút đồng bộ"
@@ -5561,7 +5579,7 @@ msgstr "Thứ Ba"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "Yêu cầu xác thực hai yếu tố"
 msgstr "Yêu cầu xác thực hai yếu tố"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5598,13 +5616,13 @@ msgstr "Cập nhật thành công"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5642,7 +5660,7 @@ msgstr "Tải lên tệp"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "Tải lên thư mục"
 msgstr "Tải lên thư mục"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "Ngược dòng"
 msgstr "Ngược dòng"
 
 
@@ -5650,6 +5668,10 @@ msgstr "Ngược dòng"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Tên Upstream"
 msgstr "Tên Upstream"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "Loại kiểm tra upstream"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "Thời gian hoạt động:"
 msgstr "Thời gian hoạt động:"
@@ -5771,7 +5793,7 @@ msgstr ""
 "có tệp sao lưu hợp lệ và mã bảo mật, đồng thời cẩn thận chọn nội dung cần "
 "có tệp sao lưu hợp lệ và mã bảo mật, đồng thời cẩn thận chọn nội dung cần "
 "khôi phục."
 "khôi phục."
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5956,6 +5978,9 @@ msgstr "Mã cũ của bạn sẽ không còn hoạt động nữa."
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Khóa truy cập của bạn"
 msgstr "Khóa truy cập của bạn"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "Chọn hành động sau khi đồng bộ"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "Liên kết bắt đầu"
 #~ msgstr "Liên kết bắt đầu"
 
 

+ 68 - 43
app/src/language/zh_CN/app.po

@@ -140,14 +140,14 @@ msgstr "操作"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -751,7 +751,7 @@ msgstr "证书类型"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "证书"
 msgstr "证书"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "证书列表"
 msgstr "证书列表"
 
 
@@ -1027,7 +1027,7 @@ msgstr "配置路径为空"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "配置模板"
 msgstr "配置模板"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "配置"
 msgstr "配置"
 
 
@@ -1146,7 +1146,7 @@ msgid ""
 msgstr "创建系统备份,包括 Nginx 配置和 Nginx UI 设置。备份文件将自动下载到你的电脑。"
 msgstr "创建系统备份,包括 Nginx 配置和 Nginx UI 设置。备份文件将自动下载到你的电脑。"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1481,7 +1481,7 @@ msgstr "在 %{node} 上禁用 %{name} 成功"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1496,8 +1496,8 @@ msgstr "禁用成功"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "磁盘 IO"
 msgstr "磁盘 IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS 凭证"
 msgstr "DNS 凭证"
 
 
@@ -1756,7 +1756,7 @@ msgstr "启用 TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2475,7 +2475,7 @@ msgstr "如果您的域名有 CNAME 记录且无法获取证书,则需要启
 msgid "Import"
 msgid "Import"
 msgstr "导入"
 msgstr "导入"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "导入证书"
 msgstr "导入证书"
@@ -2791,7 +2791,7 @@ msgid "Loading data..."
 msgstr "正在加载数据..."
 msgstr "正在加载数据..."
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2857,9 +2857,17 @@ msgstr ""
 "定时任务,因此您无需修改本页面的参数。对于使用 Docker 容器安装 Nginx 用户界面的用户,您可以手动启用该选项。Nginx UI "
 "定时任务,因此您无需修改本页面的参数。对于使用 Docker 容器安装 Nginx 用户界面的用户,您可以手动启用该选项。Nginx UI "
 "的定时任务任务调度器将按照您设置的时间间隔(以分钟为单位)执行 logrotate 命令。"
 "的定时任务任务调度器将按照您设置的时间间隔(以分钟为单位)执行 logrotate 命令。"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "主"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "主节点"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "维护模式"
 msgstr "维护模式"
 
 
@@ -3008,6 +3016,10 @@ msgstr "分钟"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "分钟"
 msgstr "分钟"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "镜像"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "模型"
 msgstr "模型"
@@ -3021,7 +3033,7 @@ msgstr "修改时间"
 msgid "Modify"
 msgid "Modify"
 msgstr "修改"
 msgstr "修改"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "修改证书"
 msgstr "修改证书"
@@ -3054,17 +3066,21 @@ msgstr "每月%{day}日%{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "多行指令"
 msgstr "多行指令"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "不适用"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3353,8 +3369,7 @@ msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "无操作"
 msgstr "无操作"
 
 
@@ -3383,7 +3398,7 @@ msgid "Node"
 msgstr "节点"
 msgstr "节点"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "节点组"
 msgstr "节点组"
@@ -3391,7 +3406,7 @@ msgstr "节点组"
 #: src/routes/modules/environments.ts:33
 #: src/routes/modules/environments.ts:33
 #: src/views/environments/group/EnvGroup.vue:19
 #: src/views/environments/group/EnvGroup.vue:19
 msgid "Node Groups"
 msgid "Node Groups"
-msgstr "环境组"
+msgstr "节点组"
 
 
 #: src/views/preference/tabs/NodeSettings.vue:15
 #: src/views/preference/tabs/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
@@ -3401,6 +3416,10 @@ msgstr "节点名称"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "节点密钥"
 msgstr "节点密钥"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "节点状态"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "节点"
 msgstr "节点"
@@ -3423,7 +3442,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "此前无效: %{date}"
 msgstr "此前无效: %{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "注意"
 msgstr "注意"
 
 
@@ -3501,6 +3520,7 @@ msgstr "官方文档"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3527,7 +3547,7 @@ msgstr "确定"
 msgid "On"
 msgid "On"
 msgstr "开启"
 msgstr "开启"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "一旦验证完成,这些记录将被删除。"
 msgstr "一旦验证完成,这些记录将被删除。"
 
 
@@ -3535,6 +3555,7 @@ msgstr "一旦验证完成,这些记录将被删除。"
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3753,7 +3774,7 @@ msgstr "请正确填写所有字段"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "请填写必填的 S3 配置字段"
 msgstr "请填写必填的 S3 配置字段"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3810,7 +3831,7 @@ msgstr "请输入您的用户名!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "请登录。"
 msgstr "请登录。"
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "请注意,下面的时间单位配置均以秒为单位。"
 msgstr "请注意,下面的时间单位配置均以秒为单位。"
 
 
@@ -3871,8 +3892,7 @@ msgid "Port Scanner"
 msgstr "端口检测"
 msgstr "端口检测"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同步后操作"
 msgstr "同步后操作"
 
 
@@ -3934,7 +3954,7 @@ msgid ""
 "proxy."
 "proxy."
 msgstr "协议配置仅在直接连接时生效。如果使用反向代理,请在反向代理中单独配置协议。"
 msgstr "协议配置仅在直接连接时生效。如果使用反向代理,请在反向代理中单独配置协议。"
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "提供商"
 msgstr "提供商"
 
 
@@ -3946,7 +3966,7 @@ msgstr "未找到提供商:{0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "代理"
 msgstr "代理"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "代理传递"
 msgstr "代理传递"
 
 
@@ -4051,9 +4071,7 @@ msgid "Reload"
 msgstr "重载"
 msgstr "重载"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4091,6 +4109,10 @@ msgstr "重载中"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "正在重载 Nginx"
 msgstr "正在重载 Nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "远程"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4593,10 +4615,6 @@ msgstr "安全令牌信息"
 msgid "Select all"
 msgid "Select all"
 msgstr "全选"
 msgstr "全选"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "选择同步后的操作"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "已选择 {count} 个文件"
 msgstr "已选择 {count} 个文件"
@@ -4853,7 +4871,7 @@ msgstr "静态"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "状态"
 msgstr "状态"
 
 
@@ -5023,7 +5041,7 @@ msgstr "同步配置成功"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同步节点"
 msgstr "同步节点"
@@ -5432,7 +5450,7 @@ msgstr "星期二"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "需要两步验证"
 msgstr "需要两步验证"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5469,13 +5487,13 @@ msgstr "更新成功"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5513,7 +5531,7 @@ msgstr "上传文件"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "上传文件夹"
 msgstr "上传文件夹"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "上游"
 msgstr "上游"
 
 
@@ -5521,6 +5539,10 @@ msgstr "上游"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Upstream 名称"
 msgstr "Upstream 名称"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "上游测试类型"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "运行时间:"
 msgstr "运行时间:"
@@ -5639,7 +5661,7 @@ msgid ""
 "to restore."
 "to restore."
 msgstr "警告:还原操作将覆盖当前配置。请确保您有有效的备份文件和安全令牌,并仔细选择要还原的内容。"
 msgstr "警告:还原操作将覆盖当前配置。请确保您有有效的备份文件和安全令牌,并仔细选择要还原的内容。"
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5808,6 +5830,9 @@ msgstr "您的旧代码将不再有效。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "你的 Passkeys"
 msgstr "你的 Passkeys"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "选择同步后的操作"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "链接"
 #~ msgstr "链接"
 
 

+ 67 - 42
app/src/language/zh_TW/app.po

@@ -144,14 +144,14 @@ msgstr "操作"
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/backup/AutoBackup/AutoBackup.vue:273
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/ACMEUser.vue:90
 #: src/views/certificate/CertificateList/certColumns.tsx:92
 #: src/views/certificate/CertificateList/certColumns.tsx:92
-#: src/views/certificate/DNSCredential.vue:44
+#: src/views/certificate/DNSCredential.vue:71
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:71
+#: src/views/environments/group/columns.ts:84
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/nginx_log/NginxLogList.vue:68
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/notification/notificationColumns.tsx:72
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
 #: src/views/preference/components/ExternalNotify/columns.tsx:73
-#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
+#: src/views/site/site_list/columns.tsx:160 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -755,7 +755,7 @@ msgstr "證書類型"
 msgid "Certificates"
 msgid "Certificates"
 msgstr "憑證"
 msgstr "憑證"
 
 
-#: src/routes/modules/certificates.ts:28
+#: src/routes/modules/certificates.ts:36
 msgid "Certificates List"
 msgid "Certificates List"
 msgstr "憑證列表"
 msgstr "憑證列表"
 
 
@@ -1031,7 +1031,7 @@ msgstr "設定路徑為空"
 msgid "Config Template"
 msgid "Config Template"
 msgstr "配置模板"
 msgstr "配置模板"
 
 
-#: src/views/certificate/DNSCredential.vue:25
+#: src/views/certificate/DNSCredential.vue:52
 msgid "Configuration"
 msgid "Configuration"
 msgstr "配置"
 msgstr "配置"
 
 
@@ -1150,7 +1150,7 @@ msgid ""
 msgstr "建立系統備份,包括 Nginx 設定與 Nginx UI 設定。備份檔案將自動下載至您的電腦。"
 msgstr "建立系統備份,包括 Nginx 設定與 Nginx UI 設定。備份檔案將自動下載至您的電腦。"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:59
+#: src/views/environments/group/columns.ts:72
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/notification/notificationColumns.tsx:51
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/AuthSettings/Passkey.vue:95
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
 #: src/views/preference/components/ExternalNotify/columns.tsx:68
@@ -1485,7 +1485,7 @@ msgstr "已成功從 %{node} 停用串流 %{name}"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/components/SiteStatusSelect.vue:162
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:62
-#: src/views/site/site_list/columns.tsx:145 src/views/stream/columns.tsx:112
+#: src/views/site/site_list/columns.tsx:146 src/views/stream/columns.tsx:112
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/stream/components/StreamEditor.vue:32
 #: src/views/user/userColumns.tsx:39
 #: src/views/user/userColumns.tsx:39
 msgid "Disabled"
 msgid "Disabled"
@@ -1500,8 +1500,8 @@ msgstr "成功停用"
 msgid "Disk IO"
 msgid "Disk IO"
 msgstr "磁碟 IO"
 msgstr "磁碟 IO"
 
 
-#: src/routes/modules/certificates.ts:56
-#: src/views/certificate/DNSCredential.vue:52
+#: src/routes/modules/certificates.ts:28
+#: src/views/certificate/DNSCredential.vue:79
 msgid "DNS Credentials"
 msgid "DNS Credentials"
 msgstr "DNS 認證"
 msgstr "DNS 認證"
 
 
@@ -1760,7 +1760,7 @@ msgstr "啟用 TOTP"
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/preference/tabs/NodeSettings.vue:30
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/components/SiteStatusSelect.vue:159
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:56
-#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: src/views/site/site_list/columns.tsx:142 src/views/stream/columns.tsx:108
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/RightPanel/Basic.vue:24
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/stream/components/StreamEditor.vue:26
 #: src/views/user/userColumns.tsx:36
 #: src/views/user/userColumns.tsx:36
@@ -2479,7 +2479,7 @@ msgstr "如果您的域名有 CNAME 記錄且無法取得證書,您需要啟
 msgid "Import"
 msgid "Import"
 msgstr "匯入"
 msgstr "匯入"
 
 
-#: src/routes/modules/certificates.ts:46
+#: src/routes/modules/certificates.ts:54
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Import Certificate"
 msgid "Import Certificate"
 msgstr "匯入憑證"
 msgstr "匯入憑證"
@@ -2795,7 +2795,7 @@ msgid "Loading data..."
 msgstr "資料載入中…"
 msgstr "資料載入中…"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:61
+#: src/components/NodeSelector/NodeSelector.vue:61 src/constants/index.ts:41
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:74
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/AutoBackup.vue:83
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
 #: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:48
@@ -2861,9 +2861,17 @@ msgstr ""
 "logrotate,因此您無需修改此頁面的參數。對於使用 Docker 容器安裝 Nginx UI 的使用者,您可以手動啟用此選項。Nginx UI "
 "logrotate,因此您無需修改此頁面的參數。對於使用 Docker 容器安裝 Nginx UI 的使用者,您可以手動啟用此選項。Nginx UI "
 "的 crontab 任務排程器將按照您設定的分鐘間隔執行 logrotate 命令。"
 "的 crontab 任務排程器將按照您設定的分鐘間隔執行 logrotate 命令。"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:220
+msgid "Main"
+msgstr "主"
+
+#: src/components/ProxyTargets/ProxyTargets.vue:148
+msgid "Main Node"
+msgstr "主節點"
+
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/components/SiteStatusSelect.vue:165
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
 #: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:68
-#: src/views/site/site_list/columns.tsx:149
+#: src/views/site/site_list/columns.tsx:150
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "維護"
 msgstr "維護"
 
 
@@ -3012,6 +3020,10 @@ msgstr "分鐘"
 msgid "Minutes"
 msgid "Minutes"
 msgstr "分鐘"
 msgstr "分鐘"
 
 
+#: src/constants/index.ts:43
+msgid "Mirror"
+msgstr "鏡像"
+
 #: src/views/preference/tabs/OpenAISettings.vue:20
 #: src/views/preference/tabs/OpenAISettings.vue:20
 msgid "Model"
 msgid "Model"
 msgstr "模型"
 msgstr "模型"
@@ -3025,7 +3037,7 @@ msgstr "修改於"
 msgid "Modify"
 msgid "Modify"
 msgstr "修改"
 msgstr "修改"
 
 
-#: src/routes/modules/certificates.ts:36
+#: src/routes/modules/certificates.ts:44
 #: src/views/certificate/CertificateEditor.vue:86
 #: src/views/certificate/CertificateEditor.vue:86
 msgid "Modify Certificate"
 msgid "Modify Certificate"
 msgstr "修改憑證"
 msgstr "修改憑證"
@@ -3058,17 +3070,21 @@ msgstr "每月%{day}日%{time}"
 msgid "Multi-line Directive"
 msgid "Multi-line Directive"
 msgstr "多行指令"
 msgstr "多行指令"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:225
+msgid "N/A"
+msgstr "不適用"
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/components/NgxConfigEditor/NgxUpstream.vue:199
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/backup/AutoBackup/AutoBackup.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/ACMEUser.vue:11
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/CertificateList/certColumns.tsx:9
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
 #: src/views/certificate/components/CertificateBasicInfo.vue:23
-#: src/views/certificate/DNSCredential.vue:9
+#: src/views/certificate/DNSCredential.vue:17
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/ConfigRightPanel/Basic.vue:34
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Delete.vue:123
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:17
 #: src/views/config/configColumns.tsx:17
-#: src/views/environments/group/columns.ts:8
+#: src/views/environments/group/columns.ts:9
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
@@ -3357,8 +3373,7 @@ msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
 #: src/components/EnvGroupRender/EnvGroupRender.vue:41
-#: src/views/environments/group/columns.ts:49
-#: src/views/environments/group/EnvGroup.vue:47
+#: src/constants/index.ts:36
 msgid "No Action"
 msgid "No Action"
 msgstr "無行動"
 msgstr "無行動"
 
 
@@ -3387,7 +3402,7 @@ msgid "Node"
 msgstr "節點"
 msgstr "節點"
 
 
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:42
-#: src/views/site/site_list/columns.tsx:90 src/views/stream/columns.tsx:58
+#: src/views/site/site_list/columns.tsx:91 src/views/stream/columns.tsx:58
 #: src/views/stream/components/RightPanel/Basic.vue:39
 #: src/views/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "節點群組"
 msgstr "節點群組"
@@ -3405,6 +3420,10 @@ msgstr "節點名稱"
 msgid "Node Secret"
 msgid "Node Secret"
 msgstr "節點金鑰"
 msgstr "節點金鑰"
 
 
+#: src/components/ProxyTargets/ProxyTargets.vue:208
+msgid "Node Status"
+msgstr "節點狀態"
+
 #: src/routes/modules/environments.ts:25
 #: src/routes/modules/environments.ts:25
 msgid "Nodes"
 msgid "Nodes"
 msgstr "節點"
 msgstr "節點"
@@ -3427,7 +3446,7 @@ msgid "Not Valid Before: %{date}"
 msgstr "此前無效:%{date}"
 msgstr "此前無效:%{date}"
 
 
 #: src/components/AutoCertForm/AutoCertForm.vue:39
 #: src/components/AutoCertForm/AutoCertForm.vue:39
-#: src/views/certificate/DNSCredential.vue:62
+#: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgid "Note"
 msgstr "備註"
 msgstr "備註"
 
 
@@ -3505,6 +3524,7 @@ msgstr "官方文件"
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:84
 #: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:106
 #: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
@@ -3531,7 +3551,7 @@ msgstr "確定"
 msgid "On"
 msgid "On"
 msgstr "開啟"
 msgstr "開啟"
 
 
-#: src/views/certificate/DNSCredential.vue:72
+#: src/views/certificate/DNSCredential.vue:99
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "驗證完成後,記錄將被刪除。"
 msgstr "驗證完成後,記錄將被刪除。"
 
 
@@ -3539,6 +3559,7 @@ msgstr "驗證完成後,記錄將被刪除。"
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeCard/NodeCard.vue:51
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:64
 #: src/components/NodeSelector/NodeSelector.vue:78
 #: src/components/NodeSelector/NodeSelector.vue:78
+#: src/components/ProxyTargets/ProxyTargets.vue:217
 #: src/views/dashboard/Environments.vue:99
 #: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
@@ -3759,7 +3780,7 @@ msgstr "請正確填寫所有欄位"
 msgid "Please fill in required S3 configuration fields"
 msgid "Please fill in required S3 configuration fields"
 msgstr "請填寫必填的 S3 配置欄位"
 msgstr "請填寫必填的 S3 配置欄位"
 
 
-#: src/views/certificate/DNSCredential.vue:66
+#: src/views/certificate/DNSCredential.vue:93
 msgid ""
 msgid ""
 "Please fill in the API authentication credentials provided by your DNS "
 "Please fill in the API authentication credentials provided by your DNS "
 "provider."
 "provider."
@@ -3816,7 +3837,7 @@ msgstr "請輸入您的使用者名稱!"
 msgid "Please log in."
 msgid "Please log in."
 msgstr "請登入。"
 msgstr "請登入。"
 
 
-#: src/views/certificate/DNSCredential.vue:75
+#: src/views/certificate/DNSCredential.vue:102
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "請注意,以下時間設定單位均為秒。"
 msgstr "請注意,以下時間設定單位均為秒。"
 
 
@@ -3877,8 +3898,7 @@ msgid "Port Scanner"
 msgstr "端口掃描器"
 msgstr "端口掃描器"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
 #: src/components/EnvGroupRender/EnvGroupRender.vue:38
-#: src/views/environments/group/columns.ts:45
-#: src/views/environments/group/EnvGroup.vue:39
+#: src/views/environments/group/columns.ts:46
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同步後動作"
 msgstr "同步後動作"
 
 
@@ -3940,7 +3960,7 @@ msgid ""
 "proxy."
 "proxy."
 msgstr "協議配置僅在直接連接時生效。如果使用反向代理,請在反向代理中單獨配置協議。"
 msgstr "協議配置僅在直接連接時生效。如果使用反向代理,請在反向代理中單獨配置協議。"
 
 
-#: src/views/certificate/DNSCredential.vue:17
+#: src/views/certificate/DNSCredential.vue:26
 msgid "Provider"
 msgid "Provider"
 msgstr "供應商"
 msgstr "供應商"
 
 
@@ -3952,7 +3972,7 @@ msgstr "未找到提供者:{0}"
 msgid "Proxy"
 msgid "Proxy"
 msgstr "代理伺服器"
 msgstr "代理伺服器"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "代理傳遞"
 msgstr "代理傳遞"
 
 
@@ -4057,9 +4077,7 @@ msgid "Reload"
 msgstr "重新載入"
 msgstr "重新載入"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
 #: src/components/EnvGroupRender/EnvGroupRender.vue:44
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104
-#: src/views/environments/group/columns.ts:52
-#: src/views/environments/group/EnvGroup.vue:50
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:104 src/constants/index.ts:37
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:209
 #: src/views/environments/list/Environment.vue:217
 #: src/views/environments/list/Environment.vue:217
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -4097,6 +4115,10 @@ msgstr "重新載入中"
 msgid "Reloading nginx"
 msgid "Reloading nginx"
 msgstr "正在重新載入 Nginx"
 msgstr "正在重新載入 Nginx"
 
 
+#: src/constants/index.ts:42
+msgid "Remote"
+msgstr "遠端"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/certificate/components/DNSIssueCertificate.vue:146
 #: src/views/preference/tabs/AuthSettings.vue:137
 #: src/views/preference/tabs/AuthSettings.vue:137
 msgid "Remove"
 msgid "Remove"
@@ -4599,10 +4621,6 @@ msgstr "安全代碼資訊"
 msgid "Select all"
 msgid "Select all"
 msgstr "全選"
 msgstr "全選"
 
 
-#: src/views/environments/group/EnvGroup.vue:42
-msgid "Select an action after sync"
-msgstr "同步後選擇操作"
-
 #: src/language/curd.ts:59
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
 msgid "Selected {count} files"
 msgstr "已選擇 {count} 個檔案"
 msgstr "已選擇 {count} 個檔案"
@@ -4859,7 +4877,7 @@ msgstr "靜態"
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/dashboard/components/ModulesTable.vue:96
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/environments/list/envColumns.tsx:43
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:29
-#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
+#: src/views/site/site_list/columns.tsx:120 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "狀態"
 msgstr "狀態"
 
 
@@ -5029,7 +5047,7 @@ msgstr "同步設定成功"
 
 
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupRender/EnvGroupRender.vue:53
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:17
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同步節點"
 msgstr "同步節點"
@@ -5438,7 +5456,7 @@ msgstr "星期二"
 msgid "Two-factor authentication required"
 msgid "Two-factor authentication required"
 msgstr "需要多重因素驗證"
 msgstr "需要多重因素驗證"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/certificate/CertificateList/certColumns.tsx:24
 #: src/views/config/components/Delete.vue:122
 #: src/views/config/components/Delete.vue:122
 #: src/views/dashboard/components/ModulesTable.vue:83
 #: src/views/dashboard/components/ModulesTable.vue:83
@@ -5475,13 +5493,13 @@ msgstr "更新成功"
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/backup/AutoBackup/AutoBackup.vue:236
 #: src/views/certificate/ACMEUser.vue:83
 #: src/views/certificate/ACMEUser.vue:83
-#: src/views/certificate/DNSCredential.vue:38
+#: src/views/certificate/DNSCredential.vue:65
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/components/ConfigRightPanel/Basic.vue:54
 #: src/views/config/configColumns.tsx:43
 #: src/views/config/configColumns.tsx:43
-#: src/views/environments/group/columns.ts:65
+#: src/views/environments/group/columns.ts:78
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
 #: src/views/site/site_edit/components/RightPanel/Basic.vue:39
-#: src/views/site/site_list/columns.tsx:112 src/views/stream/columns.tsx:80
+#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:80
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
@@ -5519,7 +5537,7 @@ msgstr "上傳檔案"
 msgid "Upload Folders"
 msgid "Upload Folders"
 msgstr "上傳資料夾"
 msgstr "上傳資料夾"
 
 
-#: src/components/ProxyTargets/ProxyTargets.vue:34
+#: src/components/ProxyTargets/ProxyTargets.vue:125
 msgid "Upstream"
 msgid "Upstream"
 msgstr "上游"
 msgstr "上游"
 
 
@@ -5527,6 +5545,10 @@ msgstr "上游"
 msgid "Upstream Name"
 msgid "Upstream Name"
 msgstr "Upstream 名稱"
 msgstr "Upstream 名稱"
 
 
+#: src/views/environments/group/columns.ts:59
+msgid "Upstream Test Type"
+msgstr "上游測試類型"
+
 #: src/views/dashboard/ServerAnalytic.vue:183
 #: src/views/dashboard/ServerAnalytic.vue:183
 msgid "Uptime:"
 msgid "Uptime:"
 msgstr "運作時間:"
 msgstr "運作時間:"
@@ -5645,7 +5667,7 @@ msgid ""
 "to restore."
 "to restore."
 msgstr "警告:恢復操作將覆蓋目前設定。請確保您擁有有效的備份檔案和安全令牌,並謹慎選擇要恢復的內容。"
 msgstr "警告:恢復操作將覆蓋目前設定。請確保您擁有有效的備份檔案和安全令牌,並謹慎選擇要恢復的內容。"
 
 
-#: src/views/certificate/DNSCredential.vue:69
+#: src/views/certificate/DNSCredential.vue:96
 msgid ""
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "
 "We will add one or more TXT records to the DNS records of your domain for "
 "ownership verification."
 "ownership verification."
@@ -5814,6 +5836,9 @@ msgstr "您的舊代碼將不再有效。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "您的通行金鑰"
 msgstr "您的通行金鑰"
 
 
+#~ msgid "Select an action after sync"
+#~ msgstr "同步後選擇操作"
+
 #~ msgid "Link Start"
 #~ msgid "Link Start"
 #~ msgstr "連結開始"
 #~ msgstr "連結開始"
 
 

+ 91 - 0
app/src/pinia/moudule/nodeGroupStore.ts

@@ -0,0 +1,91 @@
+import type { EnvGroup } from '@/api/env_group'
+import { defineStore } from 'pinia'
+import env_group from '@/api/env_group'
+
+export const useNodeGroupStore = defineStore('nodeGroup', () => {
+  const envGroups = ref<EnvGroup[]>([])
+  const envGroupMap = ref<Record<number, EnvGroup>>({})
+  const isLoading = ref(false)
+  const isInitialized = ref(false)
+  const lastUpdateTime = ref<string>('')
+
+  // Initialize the store with data
+  async function initialize() {
+    if (isInitialized.value) {
+      return
+    }
+
+    await loadAll()
+    isInitialized.value = true
+  }
+
+  // Load all environment groups by cycling through pages
+  async function loadAll() {
+    if (isLoading.value) {
+      return
+    }
+
+    isLoading.value = true
+
+    try {
+      const allGroups: EnvGroup[] = []
+      let currentPage = 1
+      let hasMorePages = true
+
+      while (hasMorePages) {
+        const response = await env_group.getList({
+          page: currentPage,
+          page_size: 100, // Use a reasonable page size
+        })
+
+        const pageData = response.data || []
+        allGroups.push(...pageData)
+
+        // Check if there are more pages
+        if (response.pagination) {
+          hasMorePages = currentPage < response.pagination.total_pages
+        }
+        else {
+          // Fallback: if no pagination info, check if we got a full page
+          hasMorePages = pageData.length === 100
+        }
+
+        currentPage++
+      }
+
+      envGroups.value = allGroups
+      lastUpdateTime.value = new Date().toISOString()
+      envGroupMap.value = allGroups.reduce((acc, group) => {
+        acc[group.id] = group
+        return acc
+      }, {} as Record<number, EnvGroup>)
+    }
+    catch (error) {
+      console.error('Failed to load environment groups:', error)
+    }
+    finally {
+      isLoading.value = false
+    }
+  }
+
+  // Get environment group by ID
+  function getGroupById(id: number): EnvGroup | undefined {
+    return envGroupMap.value[id]
+  }
+
+  // Refresh all data
+  async function refresh() {
+    await loadAll()
+  }
+
+  return {
+    envGroups: readonly(envGroups),
+    isLoading: readonly(isLoading),
+    isInitialized: readonly(isInitialized),
+    lastUpdateTime: readonly(lastUpdateTime),
+    initialize,
+    loadAll,
+    getGroupById,
+    refresh,
+  }
+})

+ 143 - 0
app/src/pinia/moudule/proxyAvailability.ts

@@ -2,19 +2,40 @@ import type ReconnectingWebSocket from 'reconnecting-websocket'
 import type { ProxyTarget } from '@/api/site'
 import type { ProxyTarget } from '@/api/site'
 import type { UpstreamAvailabilityResponse, UpstreamStatus } from '@/api/upstream'
 import type { UpstreamAvailabilityResponse, UpstreamStatus } from '@/api/upstream'
 import { defineStore } from 'pinia'
 import { defineStore } from 'pinia'
+import analytic from '@/api/analytic'
 import upstream from '@/api/upstream'
 import upstream from '@/api/upstream'
+import { useNodeAvailabilityStore } from './nodeAvailability'
+
+// Extended types for multi-node support
+export interface NodeUpstreamStatus {
+  online: boolean
+  latency: number
+}
+
+export interface MultiNodeUpstreamStatus {
+  [nodeId: number]: NodeUpstreamStatus
+}
+
+export interface UpstreamStatusMap {
+  [targetKey: string]: MultiNodeUpstreamStatus
+}
 
 
 // Alias for consistency with existing code
 // Alias for consistency with existing code
 export type ProxyAvailabilityResult = UpstreamStatus
 export type ProxyAvailabilityResult = UpstreamStatus
 
 
 export const useProxyAvailabilityStore = defineStore('proxyAvailability', () => {
 export const useProxyAvailabilityStore = defineStore('proxyAvailability', () => {
   const availabilityResults = ref<Record<string, ProxyAvailabilityResult>>({})
   const availabilityResults = ref<Record<string, ProxyAvailabilityResult>>({})
+  const upstreamStatusMap = ref<UpstreamStatusMap>({})
   const websocket = shallowRef<ReconnectingWebSocket | WebSocket>()
   const websocket = shallowRef<ReconnectingWebSocket | WebSocket>()
+  const nodeAnalyticsWebsocket = shallowRef<ReconnectingWebSocket | WebSocket>()
   const isConnected = ref(false)
   const isConnected = ref(false)
+  const isNodeAnalyticsConnected = ref(false)
   const isInitialized = ref(false)
   const isInitialized = ref(false)
   const lastUpdateTime = ref<string>('')
   const lastUpdateTime = ref<string>('')
   const targetCount = ref(0)
   const targetCount = ref(0)
 
 
+  const nodeStore = useNodeAvailabilityStore()
+
   function getTargetKey(target: ProxyTarget): string {
   function getTargetKey(target: ProxyTarget): string {
     return `${target.host}:${target.port}`
     return `${target.host}:${target.port}`
   }
   }
@@ -32,6 +53,7 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
       availabilityResults.value = data.results || {}
       availabilityResults.value = data.results || {}
       lastUpdateTime.value = data.last_update_time || ''
       lastUpdateTime.value = data.last_update_time || ''
       targetCount.value = data.target_count || 0
       targetCount.value = data.target_count || 0
+
       isInitialized.value = true
       isInitialized.value = true
     }
     }
     catch (error) {
     catch (error) {
@@ -85,10 +107,70 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
     }
     }
   }
   }
 
 
+  // Connect to node analytics WebSocket for multi-node upstream data
+  function connectNodeAnalyticsWebSocket() {
+    if (nodeAnalyticsWebsocket.value && isNodeAnalyticsConnected.value) {
+      return
+    }
+
+    // Close existing connection if any
+    if (nodeAnalyticsWebsocket.value) {
+      nodeAnalyticsWebsocket.value.close()
+    }
+
+    try {
+      // Create new WebSocket connection to node analytics
+      const ws = analytic.nodes()
+      nodeAnalyticsWebsocket.value = ws
+
+      ws.onopen = () => {
+        isNodeAnalyticsConnected.value = true
+      }
+
+      ws.onmessage = (e: MessageEvent) => {
+        try {
+          const nodeData = JSON.parse(e.data)
+
+          // Process each node's data
+          for (const [nodeIdStr, nodeInfo] of Object.entries(nodeData)) {
+            const nodeId = Number.parseInt(nodeIdStr)
+            if (nodeInfo && typeof nodeInfo === 'object' && 'upstream_status_map' in nodeInfo) {
+              const upstreamData = nodeInfo.upstream_status_map as Record<string, NodeUpstreamStatus>
+              updateUpstreamStatusMapFromNode(nodeId, upstreamData)
+            }
+          }
+
+          lastUpdateTime.value = new Date().toISOString()
+        }
+        catch (error) {
+          console.error('Failed to parse node analytics WebSocket message:', error)
+        }
+      }
+
+      ws.onclose = () => {
+        isNodeAnalyticsConnected.value = false
+      }
+
+      ws.onerror = error => {
+        console.error('Node analytics WebSocket error:', error)
+        isNodeAnalyticsConnected.value = false
+      }
+    }
+    catch (error) {
+      console.error('Failed to create node analytics WebSocket connection:', error)
+    }
+  }
+
   // Start monitoring (initialize + WebSocket)
   // Start monitoring (initialize + WebSocket)
   async function startMonitoring() {
   async function startMonitoring() {
+    // Initialize node store first
+    if (!nodeStore.isInitialized) {
+      nodeStore.initialize()
+    }
+
     await initialize()
     await initialize()
     connectWebSocket()
     connectWebSocket()
+    connectNodeAnalyticsWebSocket()
   }
   }
 
 
   // Stop monitoring and cleanup
   // Stop monitoring and cleanup
@@ -98,6 +180,11 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
       websocket.value = undefined
       websocket.value = undefined
       isConnected.value = false
       isConnected.value = false
     }
     }
+    if (nodeAnalyticsWebsocket.value) {
+      nodeAnalyticsWebsocket.value.close()
+      nodeAnalyticsWebsocket.value = undefined
+      isNodeAnalyticsConnected.value = false
+    }
   }
   }
 
 
   // Get availability result for a specific target
   // Get availability result for a specific target
@@ -117,6 +204,56 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
     return Object.keys(availabilityResults.value)
     return Object.keys(availabilityResults.value)
   }
   }
 
 
+  // Update upstream status map from node data
+  function updateUpstreamStatusMapFromNode(nodeId: number, upstreamData: Record<string, NodeUpstreamStatus>) {
+    if (!upstreamData)
+      return
+
+    for (const [targetKey, status] of Object.entries(upstreamData)) {
+      if (!upstreamStatusMap.value[targetKey]) {
+        upstreamStatusMap.value[targetKey] = {}
+      }
+
+      // Update the status for this specific node
+      upstreamStatusMap.value[targetKey][nodeId] = {
+        online: status.online,
+        latency: status.latency,
+      }
+    }
+  }
+
+  // Get multi-node status for a target
+  function getMultiNodeStatus(target: ProxyTarget): MultiNodeUpstreamStatus | undefined {
+    const key = getTargetKey(target)
+    return upstreamStatusMap.value[key]
+  }
+
+  // Get aggregated status for a target (online nodes / total nodes)
+  function getAggregatedStatus(target: ProxyTarget): { online: number, total: number, testType: string } {
+    const multiNodeStatus = getMultiNodeStatus(target)
+    if (!multiNodeStatus) {
+      // Fallback to single-node status
+      const singleStatus = getAvailabilityResult(target)
+      if (singleStatus) {
+        return {
+          online: singleStatus.online ? 1 : 0,
+          total: 1,
+          testType: 'local',
+        }
+      }
+      return { online: 0, total: 0, testType: 'local' }
+    }
+
+    const statuses = Object.values(multiNodeStatus)
+    const onlineCount = statuses.filter(status => status.online).length
+
+    return {
+      online: onlineCount,
+      total: statuses.length,
+      testType: 'multi-node',
+    }
+  }
+
   // Auto-cleanup WebSocket on page unload
   // Auto-cleanup WebSocket on page unload
   if (typeof window !== 'undefined') {
   if (typeof window !== 'undefined') {
     window.addEventListener('beforeunload', () => {
     window.addEventListener('beforeunload', () => {
@@ -126,7 +263,9 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
 
 
   return {
   return {
     availabilityResults: readonly(availabilityResults),
     availabilityResults: readonly(availabilityResults),
+    upstreamStatusMap: readonly(upstreamStatusMap),
     isConnected: readonly(isConnected),
     isConnected: readonly(isConnected),
+    isNodeAnalyticsConnected: readonly(isNodeAnalyticsConnected),
     isInitialized: readonly(isInitialized),
     isInitialized: readonly(isInitialized),
     lastUpdateTime: readonly(lastUpdateTime),
     lastUpdateTime: readonly(lastUpdateTime),
     targetCount: readonly(targetCount),
     targetCount: readonly(targetCount),
@@ -134,9 +273,13 @@ export const useProxyAvailabilityStore = defineStore('proxyAvailability', () =>
     startMonitoring,
     startMonitoring,
     stopMonitoring,
     stopMonitoring,
     connectWebSocket,
     connectWebSocket,
+    connectNodeAnalyticsWebSocket,
     getAvailabilityResult,
     getAvailabilityResult,
     hasAvailabilityData,
     hasAvailabilityData,
     getAllTargets,
     getAllTargets,
     getTargetKey,
     getTargetKey,
+    updateUpstreamStatusMapFromNode,
+    getMultiNodeStatus,
+    getAggregatedStatus,
   }
   }
 })
 })

+ 8 - 8
app/src/routes/modules/certificates.ts

@@ -20,6 +20,14 @@ export const certificatesRoutes: RouteRecordRaw[] = [
           name: () => $gettext('ACME User'),
           name: () => $gettext('ACME User'),
         },
         },
       },
       },
+      {
+        path: 'dns_credential',
+        name: 'DNS Credentials',
+        component: () => import('@/views/certificate/DNSCredential.vue'),
+        meta: {
+          name: () => $gettext('DNS Credentials'),
+        },
+      },
       {
       {
         path: 'list',
         path: 'list',
         name: 'Certificates List',
         name: 'Certificates List',
@@ -48,14 +56,6 @@ export const certificatesRoutes: RouteRecordRaw[] = [
           lastRouteName: 'Certificates List',
           lastRouteName: 'Certificates List',
         },
         },
       },
       },
-      {
-        path: 'dns_credential',
-        name: 'DNS Credentials',
-        component: () => import('@/views/certificate/DNSCredential.vue'),
-        meta: {
-          name: () => $gettext('DNS Credentials'),
-        },
-      },
     ],
     ],
   },
   },
 ]
 ]

+ 1 - 19
app/src/views/environments/group/EnvGroup.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import type { UpdateOrderRequest } from '@/api/curd'
 import type { UpdateOrderRequest } from '@/api/curd'
 import { StdCurd } from '@uozi-admin/curd'
 import { StdCurd } from '@uozi-admin/curd'
-import env_group, { PostSyncAction } from '@/api/env_group'
+import env_group from '@/api/env_group'
 import NodeSelector from '@/components/NodeSelector'
 import NodeSelector from '@/components/NodeSelector'
 import columns from '@/views/environments/group/columns'
 import columns from '@/views/environments/group/columns'
 
 
@@ -34,24 +34,6 @@ async function handleDragEnd(data: UpdateOrderRequest) {
         v-model:target="record.sync_node_ids"
         v-model:target="record.sync_node_ids"
         hidden-local
         hidden-local
       />
       />
-
-      <AForm class="mt-4" layout="vertical">
-        <AFormItem :label="$gettext('Post-sync Action')">
-          <ASelect
-            v-model:value="record.post_sync_action"
-            :placeholder="$gettext('Select an action after sync')"
-            :default-value="PostSyncAction.ReloadNginx"
-            class="w-full"
-          >
-            <ASelectOption :value="PostSyncAction.None">
-              {{ $gettext('No Action') }}
-            </ASelectOption>
-            <ASelectOption :value="PostSyncAction.ReloadNginx">
-              {{ $gettext('Reload Nginx') }}
-            </ASelectOption>
-          </ASelect>
-        </AFormItem>
-      </AForm>
     </template>
     </template>
   </StdCurd>
   </StdCurd>
 </template>
 </template>

+ 23 - 10
app/src/views/environments/group/columns.ts

@@ -1,6 +1,7 @@
 import type { StdTableColumn } from '@uozi-admin/curd'
 import type { StdTableColumn } from '@uozi-admin/curd'
-import { datetimeRender } from '@uozi-admin/curd'
-import { PostSyncAction } from '@/api/env_group'
+import { datetimeRender, maskRender } from '@uozi-admin/curd'
+import { PostSyncAction, UpstreamTestType } from '@/api/env_group'
+import { PostSyncActionMask, UpstreamTestTypeMask } from '@/constants'
 import { useNodeAvailabilityStore } from '@/pinia/moudule/nodeAvailability'
 import { useNodeAvailabilityStore } from '@/pinia/moudule/nodeAvailability'
 
 
 const columns: StdTableColumn[] = [{
 const columns: StdTableColumn[] = [{
@@ -44,14 +45,26 @@ const columns: StdTableColumn[] = [{
 }, {
 }, {
   title: () => $gettext('Post-sync Action'),
   title: () => $gettext('Post-sync Action'),
   dataIndex: 'post_sync_action',
   dataIndex: 'post_sync_action',
-  customRender: ({ text }) => {
-    if (!text || text === PostSyncAction.None) {
-      return $gettext('No Action')
-    }
-    else if (text === PostSyncAction.ReloadNginx) {
-      return $gettext('Reload Nginx')
-    }
-    return text
+  customRender: maskRender(PostSyncActionMask),
+  edit: {
+    type: 'select',
+    select: {
+      mask: PostSyncActionMask,
+      defaultValue: PostSyncAction.ReloadNginx,
+    },
+  },
+  pure: true,
+  width: 150,
+}, {
+  title: () => $gettext('Upstream Test Type'),
+  dataIndex: 'upstream_test_type',
+  customRender: maskRender(UpstreamTestTypeMask),
+  edit: {
+    type: 'select',
+    select: {
+      mask: UpstreamTestTypeMask,
+      defaultValue: UpstreamTestType.Local,
+    },
   },
   },
   pure: true,
   pure: true,
   width: 150,
   width: 150,

+ 1 - 0
app/src/views/site/site_list/columns.tsx

@@ -81,6 +81,7 @@ const columns: StdTableColumn[] = [{
   customRender: ({ record }: CustomRenderArgs) => {
   customRender: ({ record }: CustomRenderArgs) => {
     if (record.proxy_targets && record.proxy_targets.length > 0) {
     if (record.proxy_targets && record.proxy_targets.length > 0) {
       return h(ProxyTargets, {
       return h(ProxyTargets, {
+        envGroupId: record.env_group_id,
         targets: record.proxy_targets,
         targets: record.proxy_targets,
       })
       })
     }
     }

+ 9 - 7
internal/analytic/node.go

@@ -10,6 +10,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/0xJacky/Nginx-UI/internal/transport"
 	"github.com/0xJacky/Nginx-UI/internal/transport"
+	"github.com/0xJacky/Nginx-UI/internal/upstream"
 	"github.com/0xJacky/Nginx-UI/internal/version"
 	"github.com/0xJacky/Nginx-UI/internal/version"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/shirou/gopsutil/v4/load"
 	"github.com/shirou/gopsutil/v4/load"
@@ -26,13 +27,14 @@ type NodeInfo struct {
 }
 }
 
 
 type NodeStat struct {
 type NodeStat struct {
-	AvgLoad       *load.AvgStat      `json:"avg_load"`
-	CPUPercent    float64            `json:"cpu_percent"`
-	MemoryPercent float64            `json:"memory_percent"`
-	DiskPercent   float64            `json:"disk_percent"`
-	Network       net.IOCountersStat `json:"network"`
-	Status        bool               `json:"status"`
-	ResponseAt    time.Time          `json:"response_at"`
+	AvgLoad           *load.AvgStat                        `json:"avg_load"`
+	CPUPercent        float64                              `json:"cpu_percent"`
+	MemoryPercent     float64                              `json:"memory_percent"`
+	DiskPercent       float64                              `json:"disk_percent"`
+	Network           net.IOCountersStat                   `json:"network"`
+	Status            bool                                 `json:"status"`
+	ResponseAt        time.Time                            `json:"response_at"`
+	UpstreamStatusMap map[string]*upstream.Status `json:"upstream_status_map"`
 }
 }
 
 
 type Node struct {
 type Node struct {

+ 2 - 8
internal/analytic/node_record.go

@@ -681,26 +681,20 @@ func nodeAnalyticRecord(env *model.Environment, ctx context.Context) error {
 						env.ID, oldVersion, fullNode.Version)
 						env.ID, oldVersion, fullNode.Version)
 				}
 				}
 
 
-				// This is a complete Node with version info - update everything
+				// Update complete Node with version info
 				NodeMap[env.ID].NodeInfo = fullNode.NodeInfo
 				NodeMap[env.ID].NodeInfo = fullNode.NodeInfo
 				NodeMap[env.ID].NodeStat = fullNode.NodeStat
 				NodeMap[env.ID].NodeStat = fullNode.NodeStat
 				// Ensure status and response time are set
 				// Ensure status and response time are set
 				NodeMap[env.ID].NodeStat.Status = true
 				NodeMap[env.ID].NodeStat.Status = true
 				NodeMap[env.ID].NodeStat.ResponseAt = time.Now()
 				NodeMap[env.ID].NodeStat.ResponseAt = time.Now()
-
-				logger.Debugf("nodeAnalyticRecord: Updated complete Node info for environment ID: %d, Version: %s, Status: %t",
-					env.ID, fullNode.Version, NodeMap[env.ID].NodeStat.Status)
 			} else {
 			} else {
 				// Fall back to NodeStat only
 				// Fall back to NodeStat only
 				var nodeStat NodeStat
 				var nodeStat NodeStat
 				if err := json.Unmarshal(rawMsg, &nodeStat); err == nil {
 				if err := json.Unmarshal(rawMsg, &nodeStat); err == nil {
-					// set online
+					// Set node online status
 					nodeStat.Status = true
 					nodeStat.Status = true
 					nodeStat.ResponseAt = time.Now()
 					nodeStat.ResponseAt = time.Now()
-
 					NodeMap[env.ID].NodeStat = nodeStat
 					NodeMap[env.ID].NodeStat = nodeStat
-					logger.Debugf("nodeAnalyticRecord: Updated NodeStat for environment ID: %d, Status: %t",
-						env.ID, nodeStat.Status)
 				} else {
 				} else {
 					logger.Debugf("nodeAnalyticRecord: Failed to unmarshal message for environment ID: %d, error: %v", env.ID, err)
 					logger.Debugf("nodeAnalyticRecord: Failed to unmarshal message for environment ID: %d, error: %v", env.ID, err)
 				}
 				}

+ 17 - 5
internal/analytic/node_stat.go

@@ -5,6 +5,7 @@ import (
 	"runtime"
 	"runtime"
 	"time"
 	"time"
 
 
+	"github.com/0xJacky/Nginx-UI/internal/upstream"
 	"github.com/shirou/gopsutil/v4/cpu"
 	"github.com/shirou/gopsutil/v4/cpu"
 	"github.com/shirou/gopsutil/v4/load"
 	"github.com/shirou/gopsutil/v4/load"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
@@ -43,11 +44,22 @@ func GetNodeStat() (data NodeStat) {
 		return
 		return
 	}
 	}
 
 
+	// Get upstream status for current node
+	upstreamService := upstream.GetUpstreamService()
+	
+	// Ensure upstream availability test is performed if targets exist
+	if upstreamService.GetTargetCount() > 0 {
+		upstreamService.PerformAvailabilityTest()
+	}
+	
+	upstreamStatusMap := upstreamService.GetAvailabilityMap()
+
 	return NodeStat{
 	return NodeStat{
-		AvgLoad:       loadAvg,
-		CPUPercent:    math.Min((cpuUserUsage+cpuSystemUsage)*100, 100),
-		MemoryPercent: memory.Pressure,
-		DiskPercent:   diskStat.Percentage,
-		Network:       *network,
+		AvgLoad:           loadAvg,
+		CPUPercent:        math.Min((cpuUserUsage+cpuSystemUsage)*100, 100),
+		MemoryPercent:     memory.Pressure,
+		DiskPercent:       diskStat.Percentage,
+		Network:           *network,
+		UpstreamStatusMap: upstreamStatusMap,
 	}
 	}
 }
 }

+ 15 - 4
model/env_group.go

@@ -8,11 +8,22 @@ const (
 	PostSyncActionReloadNginx = "reload_nginx"
 	PostSyncActionReloadNginx = "reload_nginx"
 )
 )
 
 
+// UpstreamTestType defines the type of upstream test
+const (
+	// UpstreamTestLocal indicates local upstream test
+	UpstreamTestLocal = "local"
+	// UpstreamTestRemote indicates remote upstream test
+	UpstreamTestRemote = "remote"
+	// UpstreamTestMirror indicates mirror upstream test
+	UpstreamTestMirror = "mirror"
+)
+
 // EnvGroup represents a group of environments that can be synced across nodes
 // EnvGroup represents a group of environments that can be synced across nodes
 type EnvGroup struct {
 type EnvGroup struct {
 	Model
 	Model
-	Name           string   `json:"name"`
-	SyncNodeIds    []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
-	OrderID        int      `json:"-" gorm:"default:0"`
-	PostSyncAction string   `json:"post_sync_action" gorm:"default:'reload_nginx'"`
+	Name             string   `json:"name"`
+	SyncNodeIds      []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
+	OrderID          int      `json:"-" gorm:"default:0"`
+	PostSyncAction   string   `json:"post_sync_action" gorm:"default:'reload_nginx'"`
+	UpstreamTestType string   `json:"upstream_test_type" gorm:"default:'local'"`
 }
 }