Browse Source

fix(restore): get public key error #1272

0xJacky 2 weeks ago
parent
commit
a95b2d77c7

+ 100 - 73
app/src/language/ar/app.po

@@ -100,6 +100,10 @@ msgstr "[Nginx UI] كتابة مفتاح الشهادة الخاص إلى الق
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] كتابة الشهادة على القرص"
 msgstr "[Nginx UI] كتابة الشهادة على القرص"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* يتضمن العقد من مجموعة \"%{groupName}\" والعقد المحددة يدويًا"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "المصادقة الثنائية"
 msgstr "المصادقة الثنائية"
@@ -112,7 +116,7 @@ msgstr "إعدادات المصادقة الثنائية"
 msgid "About"
 msgid "About"
 msgstr "عن"
 msgstr "عن"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "سجل الوصول"
 msgstr "سجل الوصول"
 
 
@@ -139,12 +143,12 @@ msgstr "إجراء"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "الإجراءات"
 msgstr "الإجراءات"
@@ -223,7 +227,7 @@ msgstr "الوضع المتقدم"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "بعد ذلك، قم بتحديث هذه الصفحة وانقر على إضافة مفتاح مرور مرة أخرى."
 msgstr "بعد ذلك، قم بتحديث هذه الصفحة وانقر على إضافة مفتاح مرور مرة أخرى."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "الكل"
 msgstr "الكل"
 
 
@@ -302,7 +306,7 @@ msgstr "هل أنت متأكد أنك تريد الحذف نهائيًا؟"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "هل أنت متأكد أنك تريد إعادة تحميل Nginx على عقد المزامنة التالية؟"
 msgstr "هل أنت متأكد أنك تريد إعادة تحميل Nginx على عقد المزامنة التالية؟"
 
 
@@ -318,7 +322,7 @@ msgstr "هل أنت متأكد أنك تريد إزالة هذا العنصر؟"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "هل أنت متأكد أنك تريد إزالة هذا المكان؟"
 msgstr "هل أنت متأكد أنك تريد إزالة هذا المكان؟"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "هل أنت متأكد أنك تريد إعادة تشغيل Nginx على عقد المزامنة التالية؟"
 msgstr "هل أنت متأكد أنك تريد إعادة تشغيل Nginx على عقد المزامنة التالية؟"
 
 
@@ -1177,7 +1181,7 @@ msgstr ""
 "سيتم تنزيل ملفات النسخ الاحتياطي تلقائيًا إلى جهاز الكمبيوتر الخاص بك."
 "سيتم تنزيل ملفات النسخ الاحتياطي تلقائيًا إلى جهاز الكمبيوتر الخاص بك."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1512,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1794,8 +1798,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1840,7 +1844,7 @@ msgid "Environment variables cleaned"
 msgstr "تم تنظيف متغيرات البيئة"
 msgstr "تم تنظيف متغيرات البيئة"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "البيئات"
 msgstr "البيئات"
@@ -1854,7 +1858,7 @@ msgstr "خطأ"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "خطأ في تهيئة عارض الاختلافات"
 msgstr "خطأ في تهيئة عارض الاختلافات"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "سجل الأخطاء"
 msgstr "سجل الأخطاء"
 
 
@@ -1913,7 +1917,7 @@ msgid "External Notification Test"
 msgstr "اختبار الإشعار الخارجي"
 msgstr "اختبار الإشعار الخارجي"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "إشعار خارجي"
 msgstr "إشعار خارجي"
 
 
@@ -2244,7 +2248,7 @@ msgstr "فشل إلغاء الشهادة: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "فشل حفظ إعدادات أداء Nginx"
 msgstr "فشل حفظ إعدادات أداء Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "فشل إرسال رسالة الاختبار"
 msgstr "فشل إرسال رسالة الاختبار"
 
 
@@ -2839,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2873,7 +2877,7 @@ msgstr ""
 "Docker، يرجى الرجوع إلى "
 "Docker، يرجى الرجوع إلى "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html لمزيد من المعلومات."
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html لمزيد من المعلومات."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "قائمة السجلات"
 msgstr "قائمة السجلات"
 
 
@@ -2911,7 +2915,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "صيانة"
 msgstr "صيانة"
 
 
@@ -3118,22 +3122,22 @@ msgstr "توجيه متعدد الأسطر"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "اسم"
 msgstr "اسم"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "الاسم أو المحتوى"
 msgstr "الاسم أو المحتوى"
 
 
@@ -3393,8 +3397,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "يتضمن Nginx.conf دليل streams-enabled"
 msgstr "يتضمن Nginx.conf دليل streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3406,7 +3410,8 @@ msgstr "يتضمن Nginx.conf دليل streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "لا"
 msgstr "لا"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "لا إجراء"
 msgstr "لا إجراء"
@@ -3415,6 +3420,10 @@ msgstr "لا إجراء"
 msgid "No data"
 msgid "No data"
 msgstr "لا توجد بيانات"
 msgstr "لا توجد بيانات"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "لم يتم تحديد أي عقد"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "لم يتم تحديد أي سجلات"
 msgstr "لم يتم تحديد أي سجلات"
@@ -3431,9 +3440,9 @@ msgstr "لا توجد مصادر علوية مهيأة"
 msgid "Node"
 msgid "Node"
 msgstr "العقدة"
 msgstr "العقدة"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "مجموعة العقد"
 msgstr "مجموعة العقد"
 
 
@@ -3476,8 +3485,8 @@ msgstr "غير صالح قبل: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "ملاحظة"
 msgstr "ملاحظة"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3550,11 +3559,11 @@ msgstr "إيقاف"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "الوثيقة الرسمية"
 msgstr "الوثيقة الرسمية"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "غير متصل"
 msgstr "غير متصل"
@@ -3584,10 +3593,11 @@ msgstr "تشغيل"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "متصل"
 msgstr "متصل"
@@ -3710,7 +3720,7 @@ msgstr "كلمات المرور غير متطابقة"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "مسار"
 msgstr "مسار"
 
 
@@ -3885,6 +3895,10 @@ msgstr "يرجى حفظ رمز الأمان هذا، ستحتاج إليه لل
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "الرجاء تحديد ملف النسخ الاحتياطي"
 msgstr "الرجاء تحديد ملف النسخ الاحتياطي"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "الرجاء تحديد نوع الإشعار"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "الرجاء تحديد ملف %{type} صالح (%{extensions})"
 msgstr "الرجاء تحديد ملف %{type} صالح (%{extensions})"
@@ -3925,7 +3939,8 @@ msgstr "المنفذ"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "ماسح المنافذ"
 msgstr "ماسح المنافذ"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "إجراء ما بعد المزامنة"
 msgstr "إجراء ما بعد المزامنة"
@@ -4006,7 +4021,7 @@ msgstr "وكيل"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "مرور الوكيل"
 msgstr "مرور الوكيل"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "أهداف الوكيل"
 msgstr "أهداف الوكيل"
 
 
@@ -4108,8 +4123,9 @@ msgstr "ملاحظة الإصدار"
 msgid "Reload"
 msgid "Reload"
 msgstr "إعادة تحميل"
 msgstr "إعادة تحميل"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4136,7 +4152,7 @@ msgstr "خطأ في إعادة تحميل Nginx البعيد"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "إعادة تحميل Nginx البعيد بنجاح"
 msgstr "إعادة تحميل Nginx البعيد بنجاح"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "فشل طلب إعادة التحميل، يرجى التحقق من اتصال الشبكة لديك"
 msgstr "فشل طلب إعادة التحميل، يرجى التحقق من اتصال الشبكة لديك"
 
 
@@ -4295,7 +4311,7 @@ msgstr "الردود"
 msgid "Restart"
 msgid "Restart"
 msgstr "إعادة تشغيل"
 msgstr "إعادة تشغيل"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4317,7 +4333,7 @@ msgstr "خطأ في إعادة تشغيل Nginx البعيد"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "إعادة تشغيل Nginx البعيد بنجاح"
 msgstr "إعادة تشغيل Nginx البعيد بنجاح"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "فشل طلب إعادة التشغيل، يرجى التحقق من اتصال الشبكة لديك"
 msgstr "فشل طلب إعادة التشغيل، يرجى التحقق من اتصال الشبكة لديك"
 
 
@@ -4607,7 +4623,7 @@ msgstr "نتائج المسح"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "امسح رمز الاستجابة السريعة بهاتفك المحمول لإضافة الحساب إلى التطبيق."
 msgstr "امسح رمز الاستجابة السريعة بهاتفك المحمول لإضافة الحساب إلى التطبيق."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "جارٍ فحص السجلات..."
 msgstr "جارٍ فحص السجلات..."
 
 
@@ -4624,8 +4640,8 @@ msgid "SDK"
 msgstr "حزمة تطوير البرمجيات SDK"
 msgstr "حزمة تطوير البرمجيات SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "بحث"
 msgstr "بحث"
 
 
@@ -4680,6 +4696,10 @@ msgstr "فشل الفحص الذاتي، قد لا يعمل واجهة NGINX ب
 msgid "Send"
 msgid "Send"
 msgstr "إرسال"
 msgstr "إرسال"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "إرسال رسالة اختبار"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "الخادم"
 msgstr "الخادم"
@@ -4911,8 +4931,8 @@ msgstr "ثابت"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "الحالة"
 msgstr "الحالة"
 
 
@@ -5084,15 +5104,21 @@ msgstr "خطأ في تزامن التكوين"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "تمت مزامنة التكوين بنجاح"
 msgstr "تمت مزامنة التكوين بنجاح"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "مزامنة العقد"
 msgstr "مزامنة العقد"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "معاينة المزامنة"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "استراتيجية المزامنة"
 msgstr "استراتيجية المزامنة"
 
 
@@ -5100,8 +5126,8 @@ msgstr "استراتيجية المزامنة"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "مزامنة إلى"
 msgstr "مزامنة إلى"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "مزامنة"
 msgstr "مزامنة"
 
 
@@ -5150,11 +5176,12 @@ msgstr "طرفية"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "أمر البدء في المحطة الطرفية"
 msgstr "أمر البدء في المحطة الطرفية"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "اختبار"
 msgstr "اختبار"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "تم إرسال رسالة الاختبار بنجاح"
 msgstr "تم إرسال رسالة الاختبار بنجاح"
 
 
@@ -5529,7 +5556,7 @@ msgstr "يتطلب المصادقة الثنائية"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5565,11 +5592,11 @@ msgstr "تم التحديث بنجاح"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "محدث في"
 msgstr "محدث في"
@@ -5690,7 +5717,7 @@ msgstr "تحقق من متطلبات النظام"
 msgid "Version"
 msgid "Version"
 msgstr "إصدار"
 msgstr "إصدار"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "عرض"
 msgstr "عرض"
@@ -5782,8 +5809,8 @@ msgstr ""
 "التشغيل. بشكل عام، لا تقم بتمكين هذا إلا إذا كنت في بيئة تطوير وتستخدم "
 "التشغيل. بشكل عام، لا تقم بتمكين هذا إلا إذا كنت في بيئة تطوير وتستخدم "
 "Pebble كسلطة شهادات."
 "Pebble كسلطة شهادات."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5846,8 +5873,8 @@ msgstr "كتابة مفتاح الشهادة الخاص إلى القرص"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "كتابة الشهادة إلى القرص"
 msgstr "كتابة الشهادة إلى القرص"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 102 - 73
app/src/language/de_DE/app.po

@@ -99,6 +99,12 @@ msgstr "[Nginx UI] Schreibe privaten Zertifikatsschlüssel auf die Festplatte"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Zertifikat wird auf die Festplatte geschrieben"
 msgstr "[Nginx UI] Zertifikat wird auf die Festplatte geschrieben"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr ""
+"* Enthält Knoten aus der Gruppe \"%{groupName}\" und manuell ausgewählte "
+"Knoten"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -111,7 +117,7 @@ msgstr "2FA-Einstellungen"
 msgid "About"
 msgid "About"
 msgstr "Über"
 msgstr "Über"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Zugriffsprotokoll"
 msgstr "Zugriffsprotokoll"
 
 
@@ -138,12 +144,12 @@ msgstr "Aktion"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -224,7 +230,7 @@ msgstr ""
 "Aktualisieren Sie anschließend diese Seite und klicken Sie erneut auf "
 "Aktualisieren Sie anschließend diese Seite und klicken Sie erneut auf "
 "\"Passkey hinzufügen\"."
 "\"Passkey hinzufügen\"."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Alle"
 msgstr "Alle"
 
 
@@ -303,7 +309,7 @@ msgstr "Sind Sie sicher, dass Sie dauerhaft löschen möchten?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Sind Sie sicher, dass Sie löschen möchten?"
 msgstr "Sind Sie sicher, dass Sie löschen möchten?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Sync-Knoten neu laden "
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Sync-Knoten neu laden "
@@ -321,7 +327,7 @@ msgstr "Möchten Sie dieses Element wirklich entfernen?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Sind Sie sicher, dass Sie diesen Standort entfernen möchten?"
 msgstr "Sind Sie sicher, dass Sie diesen Standort entfernen möchten?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Synchronisationsknoten "
 "Sind Sie sicher, dass Sie Nginx auf den folgenden Synchronisationsknoten "
@@ -1193,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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 +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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1812,8 +1818,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1860,7 +1866,7 @@ msgid "Environment variables cleaned"
 msgstr "Umgebungsvariablen gesäubert"
 msgstr "Umgebungsvariablen gesäubert"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Umgebungen"
 msgstr "Umgebungen"
@@ -1874,7 +1880,7 @@ msgstr "Fehler"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Fehler beim Initialisieren des Diff-Viewers"
 msgstr "Fehler beim Initialisieren des Diff-Viewers"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Fehlerprotokoll"
 msgstr "Fehlerprotokoll"
 
 
@@ -1933,7 +1939,7 @@ msgid "External Notification Test"
 msgstr "Externer Benachrichtigungstest"
 msgstr "Externer Benachrichtigungstest"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Externe Benachrichtigung"
 msgstr "Externe Benachrichtigung"
 
 
@@ -2264,7 +2270,7 @@ msgstr "Zertifikat konnte nicht widerrufen werden: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Fehler beim Speichern der Nginx-Leistungseinstellungen"
 msgstr "Fehler beim Speichern der Nginx-Leistungseinstellungen"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Testnachricht konnte nicht gesendet werden"
 msgstr "Testnachricht konnte nicht gesendet werden"
 
 
@@ -2866,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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,7 +2906,7 @@ msgstr ""
 "in einem Docker-Container verwenden, finden Sie weitere Informationen unter "
 "in einem Docker-Container verwenden, finden Sie weitere Informationen unter "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html."
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Protokollliste"
 msgstr "Protokollliste"
 
 
@@ -2938,7 +2944,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Wartung"
 msgstr "Wartung"
 
 
@@ -3146,22 +3152,22 @@ msgstr "Mehrzeilige Direktive"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Name"
 msgstr "Name"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Name oder Inhalt"
 msgstr "Name oder Inhalt"
 
 
@@ -3423,8 +3429,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf enthält das streams-enabled-Verzeichnis"
 msgstr "Nginx.conf enthält das streams-enabled-Verzeichnis"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3436,7 +3442,8 @@ msgstr "Nginx.conf enthält das streams-enabled-Verzeichnis"
 msgid "No"
 msgid "No"
 msgstr "Nein"
 msgstr "Nein"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Keine Aktion"
 msgstr "Keine Aktion"
@@ -3445,6 +3452,10 @@ msgstr "Keine Aktion"
 msgid "No data"
 msgid "No data"
 msgstr "Keine Daten"
 msgstr "Keine Daten"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Keine Knoten ausgewählt"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Keine Datensätze ausgewählt"
 msgstr "Keine Datensätze ausgewählt"
@@ -3461,9 +3472,9 @@ msgstr "Keine Upstreams konfiguriert"
 msgid "Node"
 msgid "Node"
 msgstr "Node"
 msgstr "Node"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Node-Gruppe"
 msgstr "Node-Gruppe"
 
 
@@ -3506,8 +3517,8 @@ msgstr "Nich gültig vor: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Notiz"
 msgstr "Notiz"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3583,11 +3594,11 @@ msgstr "Aus"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Offizielle Dokumentation"
 msgstr "Offizielle Dokumentation"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Offline"
 msgstr "Offline"
@@ -3617,10 +3628,11 @@ msgstr "Ein"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "Online"
 msgstr "Online"
@@ -3743,7 +3755,7 @@ msgstr "Passwörter stimmen nicht überein"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Pfad"
 msgstr "Pfad"
 
 
@@ -3933,6 +3945,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Bitte wählen Sie eine Sicherungsdatei aus"
 msgstr "Bitte wählen Sie eine Sicherungsdatei aus"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Bitte wählen Sie einen Benachrichtigungstyp aus"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Bitte wählen Sie eine gültige %{type}-Datei aus (%{extensions})"
 msgstr "Bitte wählen Sie eine gültige %{type}-Datei aus (%{extensions})"
@@ -3973,7 +3989,8 @@ msgstr "Port"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Port-Scanner"
 msgstr "Port-Scanner"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Aktion nach der Synchronisierung"
 msgstr "Aktion nach der Synchronisierung"
@@ -4055,7 +4072,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Proxy-Weiterleitung"
 msgstr "Proxy-Weiterleitung"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Proxy-Ziele"
 msgstr "Proxy-Ziele"
 
 
@@ -4160,8 +4177,9 @@ msgstr "Änderungsprotokoll"
 msgid "Reload"
 msgid "Reload"
 msgstr "Neu laden"
 msgstr "Neu laden"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4188,7 +4206,7 @@ msgstr "Fehler beim Neuladen von Remote-Nginx"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 msgstr ""
 "Die Neulade-Anfrage ist fehlgeschlagen, bitte überprüfen Sie Ihre "
 "Die Neulade-Anfrage ist fehlgeschlagen, bitte überprüfen Sie Ihre "
@@ -4350,7 +4368,7 @@ msgstr "Antworten"
 msgid "Restart"
 msgid "Restart"
 msgstr "Neustart"
 msgstr "Neustart"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4372,7 +4390,7 @@ msgstr "Fehler beim Neustart von Remote-Nginx"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 msgstr "Neustart von Remote-Nginx erfolgreich"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 msgstr ""
 "Neustart-Anforderung fehlgeschlagen, bitte überprüfen Sie Ihre "
 "Neustart-Anforderung fehlgeschlagen, bitte überprüfen Sie Ihre "
@@ -4664,7 +4682,7 @@ msgstr "Scan-Ergebnisse"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "Scanne den QR-Code mit deinem Handy, um das Konto zur App hinzuzufügen."
 msgstr "Scanne den QR-Code mit deinem Handy, um das Konto zur App hinzuzufügen."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Protokolle werden gescannt..."
 msgstr "Protokolle werden gescannt..."
 
 
@@ -4681,8 +4699,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Suchen"
 msgstr "Suchen"
 
 
@@ -4739,6 +4757,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr "Senden"
 msgstr "Senden"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Testnachricht senden"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Server"
 msgstr "Server"
@@ -4976,8 +4998,8 @@ msgstr "Statisch"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Status"
 msgstr "Status"
 
 
@@ -5154,15 +5176,21 @@ msgstr "Fehler beim Synchronisieren der Konfiguration"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Konfiguration erfolgreich synchronisiert"
 msgstr "Konfiguration erfolgreich synchronisiert"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Synchronisierungsvorschau"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Synchronisierungsstrategie"
 msgstr "Synchronisierungsstrategie"
 
 
@@ -5170,8 +5198,8 @@ msgstr "Synchronisierungsstrategie"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Synchronisieren mit"
 msgstr "Synchronisieren mit"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Synchronisation"
 msgstr "Synchronisation"
 
 
@@ -5220,11 +5248,12 @@ msgstr "Terminal"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Terminal-Startbefehl"
 msgstr "Terminal-Startbefehl"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Test"
 msgstr "Test"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Testnachricht erfolgreich gesendet"
 msgstr "Testnachricht erfolgreich gesendet"
 
 
@@ -5615,7 +5644,7 @@ msgstr "Zwei-Faktor-Authentifizierung erforderlich"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5651,11 +5680,11 @@ msgstr "Erfolgreich aktualisiert"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Aktualisiert am"
 msgstr "Aktualisiert am"
@@ -5776,7 +5805,7 @@ msgstr "Überprüfen Sie die Systemanforderungen"
 msgid "Version"
 msgid "Version"
 msgstr "Version"
 msgstr "Version"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Anzeigen"
 msgstr "Anzeigen"
@@ -5873,8 +5902,8 @@ msgstr ""
 "denn, du befindest dich in einer Entwicklerumgebung und verwendest Pebble "
 "denn, du befindest dich in einer Entwicklerumgebung und verwendest Pebble "
 "als CA."
 "als CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5942,8 +5971,8 @@ msgstr "Scrheibe Zertifikat-Privatschlüssel auf die Festplatte"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Schreibe Zertifikat auf die Festplatte"
 msgstr "Schreibe Zertifikat auf die Festplatte"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 101 - 73
app/src/language/en/app.po

@@ -83,6 +83,11 @@ msgstr ""
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr ""
 msgstr ""
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid ""
+"* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr ""
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr ""
 msgstr ""
@@ -95,7 +100,7 @@ msgstr ""
 msgid "About"
 msgid "About"
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr ""
 msgstr ""
 
 
@@ -122,12 +127,12 @@ msgstr ""
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr ""
 msgstr ""
@@ -206,7 +211,7 @@ msgstr ""
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
@@ -283,7 +288,7 @@ msgstr ""
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 
 
@@ -299,7 +304,7 @@ msgstr ""
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 
 
@@ -1114,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1449,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1725,8 +1730,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1771,7 +1776,7 @@ msgid "Environment variables cleaned"
 msgstr ""
 msgstr ""
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr ""
 msgstr ""
@@ -1785,7 +1790,7 @@ msgstr ""
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr ""
 msgstr ""
 
 
@@ -1844,7 +1849,7 @@ msgid "External Notification Test"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr ""
 msgstr ""
 
 
@@ -2175,7 +2180,7 @@ msgstr ""
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr ""
 msgstr ""
 
 
@@ -2760,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2791,7 +2796,7 @@ msgid ""
 "nginx-log.html for more information."
 "nginx-log.html for more information."
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr ""
 msgstr ""
 
 
@@ -2823,7 +2828,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr ""
 msgstr ""
 
 
@@ -3028,22 +3033,22 @@ msgstr ""
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr ""
 msgstr ""
 
 
@@ -3303,8 +3308,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3316,7 +3321,8 @@ msgstr ""
 msgid "No"
 msgid "No"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr ""
 msgstr ""
@@ -3325,6 +3331,10 @@ msgstr ""
 msgid "No data"
 msgid "No data"
 msgstr ""
 msgstr ""
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr ""
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr ""
 msgstr ""
@@ -3341,9 +3351,9 @@ msgstr ""
 msgid "Node"
 msgid "Node"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr ""
 msgstr ""
 
 
@@ -3386,8 +3396,8 @@ msgstr ""
 msgid "Note"
 msgid "Note"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3456,11 +3466,11 @@ msgstr ""
 msgid "Official Document"
 msgid "Official Document"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr ""
 msgstr ""
@@ -3490,10 +3500,11 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr ""
 msgstr ""
@@ -3613,7 +3624,7 @@ msgstr ""
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr ""
 msgstr ""
 
 
@@ -3785,6 +3796,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr ""
 msgstr ""
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr ""
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr ""
 msgstr ""
@@ -3825,7 +3840,8 @@ msgstr ""
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr ""
 msgstr ""
@@ -3903,7 +3919,7 @@ msgstr ""
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr ""
 msgstr ""
 
 
@@ -4003,8 +4019,9 @@ msgstr ""
 msgid "Reload"
 msgid "Reload"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4031,7 +4048,7 @@ msgstr ""
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 msgstr ""
 
 
@@ -4188,7 +4205,7 @@ msgstr ""
 msgid "Restart"
 msgid "Restart"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4210,7 +4227,7 @@ msgstr ""
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 msgstr ""
 
 
@@ -4498,7 +4515,7 @@ msgstr ""
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr ""
 msgstr ""
 
 
@@ -4515,8 +4532,8 @@ msgid "SDK"
 msgstr ""
 msgstr ""
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr ""
 msgstr ""
 
 
@@ -4571,6 +4588,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr ""
 msgstr ""
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr ""
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr ""
 msgstr ""
@@ -4796,8 +4817,8 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr ""
 msgstr ""
 
 
@@ -4961,15 +4982,21 @@ msgstr ""
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr ""
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr ""
 msgstr ""
 
 
@@ -4977,8 +5004,8 @@ msgstr ""
 msgid "Sync to"
 msgid "Sync to"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr ""
 msgstr ""
 
 
@@ -5027,11 +5054,12 @@ msgstr ""
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr ""
 msgstr ""
 
 
@@ -5367,7 +5395,7 @@ msgstr ""
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5403,11 +5431,11 @@ msgstr ""
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr ""
 msgstr ""
@@ -5528,7 +5556,7 @@ msgstr ""
 msgid "Version"
 msgid "Version"
 msgstr ""
 msgstr ""
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr ""
 msgstr ""
@@ -5613,8 +5641,8 @@ msgid ""
 "Pebble as CA."
 "Pebble as CA."
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5675,8 +5703,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/es/app.po

@@ -106,6 +106,10 @@ msgstr "[Nginx UI] Escribiendo la clave privada del certificado en el disco"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Escribiendo certificado en el disco"
 msgstr "[Nginx UI] Escribiendo certificado en el disco"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* Incluye nodos del grupo \"%{groupName}\" y nodos seleccionados manualmente"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -118,7 +122,7 @@ msgstr "Configuración de 2FA"
 msgid "About"
 msgid "About"
 msgstr "Acerca de"
 msgstr "Acerca de"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Registro de acceso"
 msgstr "Registro de acceso"
 
 
@@ -145,12 +149,12 @@ msgstr "Acción"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -231,7 +235,7 @@ msgstr ""
 "Después, actualice esta página y haga clic en agregar clave de acceso "
 "Después, actualice esta página y haga clic en agregar clave de acceso "
 "nuevamente."
 "nuevamente."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Todos"
 msgstr "Todos"
 
 
@@ -310,7 +314,7 @@ msgstr "¿Estás seguro de que quieres eliminar permanentemente?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "¿Está seguro de que quiere borrar?"
 msgstr "¿Está seguro de que quiere borrar?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "¿Estás seguro de que deseas recargar Nginx en los siguientes nodos de "
 "¿Estás seguro de que deseas recargar Nginx en los siguientes nodos de "
@@ -328,7 +332,7 @@ msgstr "¿Está seguro de que desea eliminar este elemento?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "¿Está seguro de que quiere borrar esta ubicación?"
 msgstr "¿Está seguro de que quiere borrar esta ubicación?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "¿Estás seguro de que deseas reiniciar Nginx en los siguientes nodos de "
 "¿Estás seguro de que deseas reiniciar Nginx en los siguientes nodos de "
@@ -1202,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1541,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1821,8 +1825,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1871,7 +1875,7 @@ msgid "Environment variables cleaned"
 msgstr "Variables de entorno limpiadas"
 msgstr "Variables de entorno limpiadas"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Entornos"
 msgstr "Entornos"
@@ -1885,7 +1889,7 @@ msgstr "Error"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Error al inicializar el visor de diferencias"
 msgstr "Error al inicializar el visor de diferencias"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Registro de errores"
 msgstr "Registro de errores"
 
 
@@ -1944,7 +1948,7 @@ msgid "External Notification Test"
 msgstr "Prueba de notificación externa"
 msgstr "Prueba de notificación externa"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Notificación Externa"
 msgstr "Notificación Externa"
 
 
@@ -2277,7 +2281,7 @@ msgstr "No se pudo revocar el certificado: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Error al guardar la configuración de rendimiento de Nginx"
 msgstr "Error al guardar la configuración de rendimiento de Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Error al enviar el mensaje de prueba"
 msgstr "Error al enviar el mensaje de prueba"
 
 
@@ -2875,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2910,7 +2914,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html para obtener más "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html para obtener más "
 "información."
 "información."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Lista de registros"
 msgstr "Lista de registros"
 
 
@@ -2949,7 +2953,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Mantenimiento"
 msgstr "Mantenimiento"
 
 
@@ -3156,22 +3160,22 @@ msgstr "Directiva multilínea"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Nombre"
 msgstr "Nombre"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Nombre o contenido"
 msgstr "Nombre o contenido"
 
 
@@ -3433,8 +3437,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf incluye el directorio streams-enabled"
 msgstr "Nginx.conf incluye el directorio streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3446,7 +3450,8 @@ msgstr "Nginx.conf incluye el directorio streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "No"
 msgstr "No"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Sin acción"
 msgstr "Sin acción"
@@ -3455,6 +3460,10 @@ msgstr "Sin acción"
 msgid "No data"
 msgid "No data"
 msgstr "Sin datos"
 msgstr "Sin datos"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "No se han seleccionado nodos"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "No se han seleccionado registros"
 msgstr "No se han seleccionado registros"
@@ -3471,9 +3480,9 @@ msgstr "No hay upstreams configurados"
 msgid "Node"
 msgid "Node"
 msgstr "Nodo"
 msgstr "Nodo"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Grupo de nodos"
 msgstr "Grupo de nodos"
 
 
@@ -3516,8 +3525,8 @@ msgstr "No válido antes: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Nota"
 msgstr "Nota"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3593,11 +3602,11 @@ msgstr "Apagado"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Documentación oficial"
 msgstr "Documentación oficial"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Desconectado"
 msgstr "Desconectado"
@@ -3627,10 +3636,11 @@ msgstr "Encendido"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "En línea"
 msgstr "En línea"
@@ -3754,7 +3764,7 @@ msgstr "Las contraseñas no coinciden"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Ruta"
 msgstr "Ruta"
 
 
@@ -3946,6 +3956,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Por favor, seleccione un archivo de respaldo"
 msgstr "Por favor, seleccione un archivo de respaldo"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Por favor, seleccione un tipo de notificación"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Por favor, seleccione un archivo %{type} válido (%{extensions})"
 msgstr "Por favor, seleccione un archivo %{type} válido (%{extensions})"
@@ -3986,7 +4000,8 @@ msgstr "Puerto"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Escáner de puertos"
 msgstr "Escáner de puertos"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Acción posterior a la sincronización"
 msgstr "Acción posterior a la sincronización"
@@ -4068,7 +4083,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Pase de Proxy"
 msgstr "Pase de Proxy"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Objetivos del proxy"
 msgstr "Objetivos del proxy"
 
 
@@ -4173,8 +4188,9 @@ msgstr "Nota de versión"
 msgid "Reload"
 msgid "Reload"
 msgstr "Recargar"
 msgstr "Recargar"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4201,7 +4217,7 @@ msgstr "Error al recargar Nginx remoto"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Reinicio remoto de Nginx exitoso"
 msgstr "Reinicio remoto de Nginx exitoso"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "La solicitud de recarga falló, por favor verifique su conexión de red"
 msgstr "La solicitud de recarga falló, por favor verifique su conexión de red"
 
 
@@ -4361,7 +4377,7 @@ msgstr "Respuestas"
 msgid "Restart"
 msgid "Restart"
 msgstr "Reiniciar"
 msgstr "Reiniciar"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4383,7 +4399,7 @@ msgstr "Error al reiniciar Nginx remoto"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Reinicio remoto de Nginx exitoso"
 msgstr "Reinicio remoto de Nginx exitoso"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "La solicitud de reinicio falló, por favor verifique su conexión de red"
 msgstr "La solicitud de reinicio falló, por favor verifique su conexión de red"
 
 
@@ -4675,7 +4691,7 @@ msgstr ""
 "Escanee el código QR con su teléfono móvil para agregar la cuenta a la "
 "Escanee el código QR con su teléfono móvil para agregar la cuenta a la "
 "aplicación."
 "aplicación."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Escaneando registros..."
 msgstr "Escaneando registros..."
 
 
@@ -4692,8 +4708,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Buscar"
 msgstr "Buscar"
 
 
@@ -4750,6 +4766,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr "Enviado"
 msgstr "Enviado"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Enviar mensaje de prueba"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Servidor"
 msgstr "Servidor"
@@ -4987,8 +5007,8 @@ msgstr "Estático"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Estado"
 msgstr "Estado"
 
 
@@ -5163,15 +5183,21 @@ msgstr "Error de Configuración de Sincronización"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Configuración de sincronización exitosa"
 msgstr "Configuración de sincronización exitosa"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Vista previa de sincronización"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Estrategia de sincronización"
 msgstr "Estrategia de sincronización"
 
 
@@ -5179,8 +5205,8 @@ msgstr "Estrategia de sincronización"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Sincronizar con"
 msgstr "Sincronizar con"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Sincronización"
 msgstr "Sincronización"
 
 
@@ -5229,11 +5255,12 @@ msgstr "Terminal"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Comando de inicio de terminal"
 msgstr "Comando de inicio de terminal"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Prueba"
 msgstr "Prueba"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Mensaje de prueba enviado con éxito"
 msgstr "Mensaje de prueba enviado con éxito"
 
 
@@ -5623,7 +5650,7 @@ msgstr "Se requiere autenticación de dos factores"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5659,11 +5686,11 @@ msgstr "Actualización exitosa"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Actualizado a"
 msgstr "Actualizado a"
@@ -5784,7 +5811,7 @@ msgstr "Verificar los requisitos del sistema"
 msgid "Version"
 msgid "Version"
 msgstr "Versión"
 msgstr "Versión"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Ver"
 msgstr "Ver"
@@ -5879,8 +5906,8 @@ msgstr ""
 "los usuarios al iniciarse. Por lo general, no habilite esta opción a menos "
 "los usuarios al iniciarse. Por lo general, no habilite esta opción a menos "
 "que se encuentre en un entorno de desarrollo y utilice Pebble como CA."
 "que se encuentre en un entorno de desarrollo y utilice Pebble como CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5946,8 +5973,8 @@ msgstr "Escribir la clave privada del certificado a disco"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Escribir certificado a disco"
 msgstr "Escribir certificado a disco"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 102 - 73
app/src/language/fr_FR/app.po

@@ -104,6 +104,12 @@ msgstr "[Nginx UI] Écriture de la clé privée du certificat sur le disque"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Écriture du certificat sur le disque"
 msgstr "[Nginx UI] Écriture du certificat sur le disque"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr ""
+"* Inclut les nœuds du groupe \"%{groupName}\" et les nœuds sélectionnés "
+"manuellement"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2fa"
 msgstr "2fa"
@@ -116,7 +122,7 @@ msgstr "Options 2FA"
 msgid "About"
 msgid "About"
 msgstr "À propos"
 msgstr "À propos"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Journal d'accès"
 msgstr "Journal d'accès"
 
 
@@ -143,12 +149,12 @@ msgstr "Action"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -229,7 +235,7 @@ msgstr ""
 "Ensuite, rafraîchissez cette page et cliquez à nouveau sur ajouter une clé "
 "Ensuite, rafraîchissez cette page et cliquez à nouveau sur ajouter une clé "
 "d'accès."
 "d'accès."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Tous"
 msgstr "Tous"
 
 
@@ -308,7 +314,7 @@ msgstr "Êtes-vous sûr de vouloir supprimer définitivement ?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Êtes-vous sûr de vouloir recharger Nginx sur les nœuds de synchronisation "
 "Êtes-vous sûr de vouloir recharger Nginx sur les nœuds de synchronisation "
@@ -326,7 +332,7 @@ msgstr "Êtes-vous sûr de vouloir supprimer cet élément ?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Voulez-vous vraiment supprimer cette localisation ?"
 msgstr "Voulez-vous vraiment supprimer cette localisation ?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Êtes-vous sûr de vouloir redémarrer Nginx sur les nœuds de synchronisation "
 "Êtes-vous sûr de vouloir redémarrer Nginx sur les nœuds de synchronisation "
@@ -1198,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1537,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1815,8 +1821,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1865,7 +1871,7 @@ msgid "Environment variables cleaned"
 msgstr "Variables d'environnement nettoyées"
 msgstr "Variables d'environnement nettoyées"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Environnements"
 msgstr "Environnements"
@@ -1879,7 +1885,7 @@ msgstr "Erreur"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Erreur lors de l'initialisation du visualiseur de différences"
 msgstr "Erreur lors de l'initialisation du visualiseur de différences"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Journal des erreurs"
 msgstr "Journal des erreurs"
 
 
@@ -1938,7 +1944,7 @@ msgid "External Notification Test"
 msgstr "Test de notification externe"
 msgstr "Test de notification externe"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Notification Externe"
 msgstr "Notification Externe"
 
 
@@ -2271,7 +2277,7 @@ msgstr "Échec de la révocation du certificat : %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Échec de l'enregistrement des paramètres de performance de Nginx"
 msgstr "Échec de l'enregistrement des paramètres de performance de Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Échec de l'envoi du message de test"
 msgstr "Échec de l'envoi du message de test"
 
 
@@ -2873,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2908,7 +2914,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html pour plus "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html pour plus "
 "d'informations."
 "d'informations."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Liste des journaux"
 msgstr "Liste des journaux"
 
 
@@ -2947,7 +2953,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Maintenance"
 msgstr "Maintenance"
 
 
@@ -3154,22 +3160,22 @@ msgstr "Directive multiligne"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Nom"
 msgstr "Nom"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Nom ou contenu"
 msgstr "Nom ou contenu"
 
 
@@ -3431,8 +3437,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf inclut le répertoire streams-enabled"
 msgstr "Nginx.conf inclut le répertoire streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3444,7 +3450,8 @@ msgstr "Nginx.conf inclut le répertoire streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "Non"
 msgstr "Non"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Aucune action"
 msgstr "Aucune action"
@@ -3453,6 +3460,10 @@ msgstr "Aucune action"
 msgid "No data"
 msgid "No data"
 msgstr "Aucune donnée"
 msgstr "Aucune donnée"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Aucun nœud sélectionné"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Aucun enregistrement sélectionné"
 msgstr "Aucun enregistrement sélectionné"
@@ -3469,9 +3480,9 @@ msgstr "Aucun amont configuré"
 msgid "Node"
 msgid "Node"
 msgstr "Nœud"
 msgstr "Nœud"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Groupe de nœuds"
 msgstr "Groupe de nœuds"
 
 
@@ -3514,8 +3525,8 @@ msgstr "Non valide avant : %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Note"
 msgstr "Note"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3590,11 +3601,11 @@ msgstr "Désactivé"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Documentation officielle"
 msgstr "Documentation officielle"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Hors ligne"
 msgstr "Hors ligne"
@@ -3624,10 +3635,11 @@ msgstr "Activé"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "En ligne"
 msgstr "En ligne"
@@ -3751,7 +3763,7 @@ msgstr "Les mots de passe ne correspondent pas"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Chemin"
 msgstr "Chemin"
 
 
@@ -3943,6 +3955,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Veuillez sélectionner un fichier de sauvegarde"
 msgstr "Veuillez sélectionner un fichier de sauvegarde"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Veuillez sélectionner un type de notification"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Veuillez sélectionner un fichier %{type} valide (%{extensions})"
 msgstr "Veuillez sélectionner un fichier %{type} valide (%{extensions})"
@@ -3983,7 +3999,8 @@ msgstr "Port"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Scanner de ports"
 msgstr "Scanner de ports"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Action post-synchronisation"
 msgstr "Action post-synchronisation"
@@ -4065,7 +4082,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Passe de Proxy"
 msgstr "Passe de Proxy"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Cibles du proxy"
 msgstr "Cibles du proxy"
 
 
@@ -4170,8 +4187,9 @@ msgstr "Note de version"
 msgid "Reload"
 msgid "Reload"
 msgstr "Recharger"
 msgstr "Recharger"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4198,7 +4216,7 @@ msgstr "Erreur de rechargement de Nginx distant"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Rechargement distant de Nginx réussi"
 msgstr "Rechargement distant de Nginx réussi"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 msgstr ""
 "La demande de rechargement a échoué, veuillez vérifier votre connexion "
 "La demande de rechargement a échoué, veuillez vérifier votre connexion "
@@ -4360,7 +4378,7 @@ msgstr "Réponses"
 msgid "Restart"
 msgid "Restart"
 msgstr "Redémarrer"
 msgstr "Redémarrer"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4382,7 +4400,7 @@ msgstr "Erreur de redémarrage de Nginx distant"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Redémarrage distant de Nginx réussi"
 msgstr "Redémarrage distant de Nginx réussi"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "La demande de redémarrage a échoué, veuillez vérifier votre connexion réseau"
 msgstr "La demande de redémarrage a échoué, veuillez vérifier votre connexion réseau"
 
 
@@ -4674,7 +4692,7 @@ msgstr ""
 "Scannez le code QR avec votre téléphone portable pour ajouter le compte à "
 "Scannez le code QR avec votre téléphone portable pour ajouter le compte à "
 "l'application."
 "l'application."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Analyse des journaux en cours..."
 msgstr "Analyse des journaux en cours..."
 
 
@@ -4691,8 +4709,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Rechercher"
 msgstr "Rechercher"
 
 
@@ -4749,6 +4767,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr "Envoyer"
 msgstr "Envoyer"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Envoyer un message test"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Serveur"
 msgstr "Serveur"
@@ -4986,8 +5008,8 @@ msgstr "Statique"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Statut"
 msgstr "Statut"
 
 
@@ -5164,15 +5186,21 @@ msgstr "Erreur de synchronisation de la configuration"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Synchronisation de la configuration réussie"
 msgstr "Synchronisation de la configuration réussie"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Aperçu de la synchronisation"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Stratégie de synchronisation"
 msgstr "Stratégie de synchronisation"
 
 
@@ -5180,8 +5208,8 @@ msgstr "Stratégie de synchronisation"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Synchroniser vers"
 msgstr "Synchroniser vers"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Synchronisation"
 msgstr "Synchronisation"
 
 
@@ -5230,11 +5258,12 @@ msgstr "Terminal"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Commande de démarrage du terminal"
 msgstr "Commande de démarrage du terminal"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Test"
 msgstr "Test"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Message de test envoyé avec succès"
 msgstr "Message de test envoyé avec succès"
 
 
@@ -5631,7 +5660,7 @@ msgstr "Authentification à deux facteurs requise"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5667,11 +5696,11 @@ msgstr "Mise à jour réussie"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Mis à jour le"
 msgstr "Mis à jour le"
@@ -5792,7 +5821,7 @@ msgstr "Vérifiez les exigences du système"
 msgid "Version"
 msgid "Version"
 msgstr "Version"
 msgstr "Version"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Voir"
 msgstr "Voir"
@@ -5888,8 +5917,8 @@ msgstr ""
 "êtes dans un environnement de développement et que vous utilisez Pebble "
 "êtes dans un environnement de développement et que vous utilisez Pebble "
 "comme CA."
 "comme CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5957,8 +5986,8 @@ msgstr "Écriture de la clé privée du certificat sur le disque"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Écriture du certificat sur le disque"
 msgstr "Écriture du certificat sur le disque"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/ja_JP/app.po

@@ -100,6 +100,10 @@ msgstr "[Nginx UI] 証明書の秘密鍵をディスクに書き込んでいま
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] 証明書をディスクに書き込み中"
 msgstr "[Nginx UI] 証明書をディスクに書き込み中"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* グループ \"%{groupName}\" のノードと手動で選択したノードを含む"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "二要素認証"
 msgstr "二要素認証"
@@ -112,7 +116,7 @@ msgstr "ニ要素認証設定"
 msgid "About"
 msgid "About"
 msgstr "Nginx UI について"
 msgstr "Nginx UI について"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "アクセスログ"
 msgstr "アクセスログ"
 
 
@@ -139,12 +143,12 @@ msgstr "操作"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -223,7 +227,7 @@ msgstr "アドバンスモード"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "その後、このページを更新し、再度パスキーを追加をクリックしてください。"
 msgstr "その後、このページを更新し、再度パスキーを追加をクリックしてください。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "すべて"
 msgstr "すべて"
 
 
@@ -300,7 +304,7 @@ msgstr "完全に削除してもよろしいですか?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "削除してもよろしいですか?"
 msgstr "削除してもよろしいですか?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "以下の同期ノードでNginxを再読み込みしてもよろしいですか?"
 msgstr "以下の同期ノードでNginxを再読み込みしてもよろしいですか?"
 
 
@@ -316,7 +320,7 @@ msgstr "このアイテムを削除してもよろしいですか?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "このLocationを削除してもよろしいですか?"
 msgstr "このLocationを削除してもよろしいですか?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "以下の同期ノードでNginxを再起動してもよろしいですか?"
 msgstr "以下の同期ノードでNginxを再起動してもよろしいですか?"
 
 
@@ -1151,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1486,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1761,8 +1765,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1807,7 +1811,7 @@ msgid "Environment variables cleaned"
 msgstr "環境変数をクリーンアップしました"
 msgstr "環境変数をクリーンアップしました"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "環境"
 msgstr "環境"
@@ -1821,7 +1825,7 @@ msgstr "エラー"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "差分ビューアの初期化エラー"
 msgstr "差分ビューアの初期化エラー"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "エラーログ"
 msgstr "エラーログ"
 
 
@@ -1880,7 +1884,7 @@ msgid "External Notification Test"
 msgstr "外部通知テスト"
 msgstr "外部通知テスト"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "外部通知"
 msgstr "外部通知"
 
 
@@ -2211,7 +2215,7 @@ msgstr "証明書の失効に失敗しました: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Nginxのパフォーマンス設定の保存に失敗しました"
 msgstr "Nginxのパフォーマンス設定の保存に失敗しました"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "テストメッセージの送信に失敗しました"
 msgstr "テストメッセージの送信に失敗しました"
 
 
@@ -2796,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2829,7 +2833,7 @@ msgstr ""
 "ログファイル %{log_path} は通常のファイルではありません。Docker コンテナで nginx-ui を使用している場合は、詳細について "
 "ログファイル %{log_path} は通常のファイルではありません。Docker コンテナで nginx-ui を使用している場合は、詳細について "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html を参照してください。"
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html を参照してください。"
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "ログリスト"
 msgstr "ログリスト"
 
 
@@ -2865,7 +2869,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "メンテナンス"
 msgstr "メンテナンス"
 
 
@@ -3072,22 +3076,22 @@ msgstr "複数行ディレクティブ"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "名前"
 msgstr "名前"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "名前または内容"
 msgstr "名前または内容"
 
 
@@ -3347,8 +3351,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf には streams-enabled ディレクトリが含まれています"
 msgstr "Nginx.conf には streams-enabled ディレクトリが含まれています"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3360,7 +3364,8 @@ msgstr "Nginx.conf には streams-enabled ディレクトリが含まれてい
 msgid "No"
 msgid "No"
 msgstr "いいえ"
 msgstr "いいえ"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "アクションなし"
 msgstr "アクションなし"
@@ -3369,6 +3374,10 @@ msgstr "アクションなし"
 msgid "No data"
 msgid "No data"
 msgstr "データなし"
 msgstr "データなし"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "ノードが選択されていません"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "選択されたレコードがありません"
 msgstr "選択されたレコードがありません"
@@ -3385,9 +3394,9 @@ msgstr "アップストリームが設定されていません"
 msgid "Node"
 msgid "Node"
 msgstr "ノード"
 msgstr "ノード"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "ノードグループ"
 msgstr "ノードグループ"
 
 
@@ -3430,8 +3439,8 @@ msgstr "有効開始日: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "注記"
 msgstr "注記"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3500,11 +3509,11 @@ msgstr "オフ"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "公式ドキュメント"
 msgstr "公式ドキュメント"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "オフライン"
 msgstr "オフライン"
@@ -3534,10 +3543,11 @@ msgstr "オン"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "検証が完了すると、レコードは削除されます。"
 msgstr "検証が完了すると、レコードは削除されます。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "オンライン"
 msgstr "オンライン"
@@ -3659,7 +3669,7 @@ msgstr "パスワードが一致しません"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "パス"
 msgstr "パス"
 
 
@@ -3832,6 +3842,10 @@ msgstr "このセキュリティトークンを保存してください。復元
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "バックアップファイルを選択してください"
 msgstr "バックアップファイルを選択してください"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "通知タイプを選択してください"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "有効な%{type}ファイルを選択してください(%{extensions})"
 msgstr "有効な%{type}ファイルを選択してください(%{extensions})"
@@ -3872,7 +3886,8 @@ msgstr "ポート"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "ポートスキャナー"
 msgstr "ポートスキャナー"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同期後のアクション"
 msgstr "同期後のアクション"
@@ -3951,7 +3966,7 @@ msgstr "プロキシ"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "プロキシパス"
 msgstr "プロキシパス"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "プロキシターゲット"
 msgstr "プロキシターゲット"
 
 
@@ -4051,8 +4066,9 @@ msgstr "リリースノート"
 msgid "Reload"
 msgid "Reload"
 msgstr "再読み込み"
 msgstr "再読み込み"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4079,7 +4095,7 @@ msgstr "リモートNginxの再読み込みエラー"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "リモートNginxのリロード成功"
 msgstr "リモートNginxのリロード成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "再読み込みリクエストが失敗しました。ネットワーク接続を確認してください"
 msgstr "再読み込みリクエストが失敗しました。ネットワーク接続を確認してください"
 
 
@@ -4236,7 +4252,7 @@ msgstr "レスポンス"
 msgid "Restart"
 msgid "Restart"
 msgstr "再起動"
 msgstr "再起動"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4258,7 +4274,7 @@ msgstr "リモートNginxの再起動エラー"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "リモートNginxの再起動成功"
 msgstr "リモートNginxの再起動成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "再起動リクエストが失敗しました。ネットワーク接続を確認してください"
 msgstr "再起動リクエストが失敗しました。ネットワーク接続を確認してください"
 
 
@@ -4546,7 +4562,7 @@ msgstr "スキャン結果"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "スマートフォンでQRコードをスキャンして、アプリにアカウントを追加します。"
 msgstr "スマートフォンでQRコードをスキャンして、アプリにアカウントを追加します。"
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "ログをスキャン中..."
 msgstr "ログをスキャン中..."
 
 
@@ -4563,8 +4579,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "検索"
 msgstr "検索"
 
 
@@ -4619,6 +4635,10 @@ msgstr "自己チェックに失敗しました、Nginx UIが正常に動作し
 msgid "Send"
 msgid "Send"
 msgstr "送信"
 msgstr "送信"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "テストメッセージを送信"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "サーバー"
 msgstr "サーバー"
@@ -4848,8 +4868,8 @@ msgstr "静的"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "ステータス"
 msgstr "ステータス"
 
 
@@ -5019,15 +5039,21 @@ msgstr "設定同期エラー"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "設定の同期に成功しました"
 msgstr "設定の同期に成功しました"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同期ノード"
 msgstr "同期ノード"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "同期プレビュー"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "同期戦略"
 msgstr "同期戦略"
 
 
@@ -5035,8 +5061,8 @@ msgstr "同期戦略"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "同期先"
 msgstr "同期先"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "同期"
 msgstr "同期"
 
 
@@ -5085,11 +5111,12 @@ msgstr "ターミナル"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "ターミナル起動コマンド"
 msgstr "ターミナル起動コマンド"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "テスト"
 msgstr "テスト"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "テストメッセージが正常に送信されました"
 msgstr "テストメッセージが正常に送信されました"
 
 
@@ -5435,7 +5462,7 @@ msgstr "二要素認証が必要です"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5471,11 +5498,11 @@ msgstr "更新に成功しました"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "更新日時"
 msgstr "更新日時"
@@ -5596,7 +5623,7 @@ msgstr "システム要件を確認する"
 msgid "Version"
 msgid "Version"
 msgstr "バージョン"
 msgstr "バージョン"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "ビュー"
 msgstr "ビュー"
@@ -5683,8 +5710,8 @@ msgstr ""
 "有効にすると、Nginx UI は起動時に自動的にユーザーを再登録します。一般的に、開発環境で Pebble を CA "
 "有効にすると、Nginx UI は起動時に自動的にユーザーを再登録します。一般的に、開発環境で Pebble を CA "
 "として使用している場合以外は、これを有効にしないでください。"
 "として使用している場合以外は、これを有効にしないでください。"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5745,8 +5772,8 @@ msgstr "証明書の秘密鍵をディスクに書き込んでいます"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "証明書をディスクに書き込み中"
 msgstr "証明書をディスクに書き込み中"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/ko_KR/app.po

@@ -98,6 +98,10 @@ msgstr "[Nginx UI] 인증서 개인 키를 디스크에 기록 중"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] 인증서를 디스크에 작성 중"
 msgstr "[Nginx UI] 인증서를 디스크에 작성 중"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* 그룹 \"%{groupName}\"의 노드와 수동으로 선택한 노드 포함"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -110,7 +114,7 @@ msgstr "2FA 설정"
 msgid "About"
 msgid "About"
 msgstr "대하여"
 msgstr "대하여"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "액세스 로그"
 msgstr "액세스 로그"
 
 
@@ -137,12 +141,12 @@ msgstr "작업"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "작업"
 msgstr "작업"
@@ -221,7 +225,7 @@ msgstr "고급 모드"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "이후에 이 페이지를 새로 고치고 패스키 추가를 다시 클릭하세요."
 msgstr "이후에 이 페이지를 새로 고치고 패스키 추가를 다시 클릭하세요."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "모두"
 msgstr "모두"
 
 
@@ -298,7 +302,7 @@ msgstr "정말 영구적으로 삭제하시겠습니까?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "정말 삭제하시겠습니까?"
 msgstr "정말 삭제하시겠습니까?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 로드하시겠습니까?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 로드하시겠습니까?"
 
 
@@ -314,7 +318,7 @@ msgstr "이 항목을 제거하시겠습니까?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "이 위치를 제거하시겠습니까?"
 msgstr "이 위치를 제거하시겠습니까?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 시작하시겠습니까?"
 msgstr "다음 동기화 노드에서 Nginx를 다시 시작하시겠습니까?"
 
 
@@ -1148,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1483,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1760,8 +1764,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1806,7 +1810,7 @@ msgid "Environment variables cleaned"
 msgstr "환경 변수가 정리되었습니다"
 msgstr "환경 변수가 정리되었습니다"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "환경"
 msgstr "환경"
@@ -1820,7 +1824,7 @@ msgstr "오류"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "차이점 뷰어 초기화 오류"
 msgstr "차이점 뷰어 초기화 오류"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "오류 로그"
 msgstr "오류 로그"
 
 
@@ -1879,7 +1883,7 @@ msgid "External Notification Test"
 msgstr "외부 알림 테스트"
 msgstr "외부 알림 테스트"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "외부 알림"
 msgstr "외부 알림"
 
 
@@ -2210,7 +2214,7 @@ msgstr "인증서 취소 실패: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Nginx 성능 설정 저장 실패"
 msgstr "Nginx 성능 설정 저장 실패"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "테스트 메시지 전송 실패"
 msgstr "테스트 메시지 전송 실패"
 
 
@@ -2795,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2828,7 +2832,7 @@ msgstr ""
 "로그 파일 %{log_path}은(는) 일반 파일이 아닙니다. Docker 컨테이너에서 nginx-ui를 사용 중이라면 자세한 내용은 "
 "로그 파일 %{log_path}은(는) 일반 파일이 아닙니다. Docker 컨테이너에서 nginx-ui를 사용 중이라면 자세한 내용은 "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html을 참조하십시오."
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html을 참조하십시오."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "로그 목록"
 msgstr "로그 목록"
 
 
@@ -2863,7 +2867,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "유지보수"
 msgstr "유지보수"
 
 
@@ -3068,22 +3072,22 @@ msgstr "여러 줄 지시문"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "이름"
 msgstr "이름"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "이름 또는 내용"
 msgstr "이름 또는 내용"
 
 
@@ -3343,8 +3347,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf에는 streams-enabled 디렉토리가 포함됩니다"
 msgstr "Nginx.conf에는 streams-enabled 디렉토리가 포함됩니다"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3356,7 +3360,8 @@ msgstr "Nginx.conf에는 streams-enabled 디렉토리가 포함됩니다"
 msgid "No"
 msgid "No"
 msgstr "아니요"
 msgstr "아니요"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "작업 없음"
 msgstr "작업 없음"
@@ -3365,6 +3370,10 @@ msgstr "작업 없음"
 msgid "No data"
 msgid "No data"
 msgstr "데이터 없음"
 msgstr "데이터 없음"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "선택된 노드 없음"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "선택된 기록이 없습니다"
 msgstr "선택된 기록이 없습니다"
@@ -3381,9 +3390,9 @@ msgstr "업스트림이 구성되지 않았습니다"
 msgid "Node"
 msgid "Node"
 msgstr "노드"
 msgstr "노드"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "노드 그룹"
 msgstr "노드 그룹"
 
 
@@ -3426,8 +3435,8 @@ msgstr "유효 시작일: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "참고"
 msgstr "참고"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3496,11 +3505,11 @@ msgstr "끔"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "공식 문서"
 msgstr "공식 문서"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "오프라인"
 msgstr "오프라인"
@@ -3530,10 +3539,11 @@ msgstr "켜짐"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "온라인"
 msgstr "온라인"
@@ -3655,7 +3665,7 @@ msgstr "비밀번호가 일치하지 않습니다"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "경로"
 msgstr "경로"
 
 
@@ -3826,6 +3836,10 @@ msgstr "이 보안 토큰을 저장해 두세요. 복원 시 필요합니다:"
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "백업 파일을 선택해 주세요"
 msgstr "백업 파일을 선택해 주세요"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "알림 유형을 선택해 주세요"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "유효한 %{type} 파일을 선택하세요 (%{extensions})"
 msgstr "유효한 %{type} 파일을 선택하세요 (%{extensions})"
@@ -3866,7 +3880,8 @@ msgstr "포트"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "포트 스캐너"
 msgstr "포트 스캐너"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "동기화 후 작업"
 msgstr "동기화 후 작업"
@@ -3945,7 +3960,7 @@ msgstr "프록시"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "프록시 패스"
 msgstr "프록시 패스"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "프록시 대상"
 msgstr "프록시 대상"
 
 
@@ -4045,8 +4060,9 @@ msgstr "릴리스 노트"
 msgid "Reload"
 msgid "Reload"
 msgstr "리로드"
 msgstr "리로드"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4073,7 +4089,7 @@ msgstr "원격 Nginx 다시 로드 오류"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "원격 Nginx 다시 로드 성공"
 msgstr "원격 Nginx 다시 로드 성공"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "다시 로드 요청이 실패했습니다. 네트워크 연결을 확인하세요"
 msgstr "다시 로드 요청이 실패했습니다. 네트워크 연결을 확인하세요"
 
 
@@ -4232,7 +4248,7 @@ msgstr "응답"
 msgid "Restart"
 msgid "Restart"
 msgstr "재시작"
 msgstr "재시작"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4254,7 +4270,7 @@ msgstr "원격 Nginx 재시작 오류"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "원격 Nginx 재시작 성공"
 msgstr "원격 Nginx 재시작 성공"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "재시작 요청이 실패했습니다. 네트워크 연결을 확인해 주세요"
 msgstr "재시작 요청이 실패했습니다. 네트워크 연결을 확인해 주세요"
 
 
@@ -4542,7 +4558,7 @@ msgstr "스캔 결과"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "휴대폰으로 QR 코드를 스캔하여 앱에 계정을 추가하세요."
 msgstr "휴대폰으로 QR 코드를 스캔하여 앱에 계정을 추가하세요."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "로그 스캔 중..."
 msgstr "로그 스캔 중..."
 
 
@@ -4559,8 +4575,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "검색"
 msgstr "검색"
 
 
@@ -4615,6 +4631,10 @@ msgstr "자체 점검 실패, Nginx UI가 제대로 작동하지 않을 수 있
 msgid "Send"
 msgid "Send"
 msgstr "보내기"
 msgstr "보내기"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "테스트 메시지 전송"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "서버"
 msgstr "서버"
@@ -4844,8 +4864,8 @@ msgstr "정적"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "상태"
 msgstr "상태"
 
 
@@ -5015,15 +5035,21 @@ msgstr "구성 동기화 오류"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "구성 동기화 성공"
 msgstr "구성 동기화 성공"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "동기화 노드"
 msgstr "동기화 노드"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "동기화 미리보기"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "동기화 전략"
 msgstr "동기화 전략"
 
 
@@ -5031,8 +5057,8 @@ msgstr "동기화 전략"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "동기화 대상"
 msgstr "동기화 대상"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "동기화"
 msgstr "동기화"
 
 
@@ -5081,11 +5107,12 @@ msgstr "터미널"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "터미널 시작 명령"
 msgstr "터미널 시작 명령"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "테스트"
 msgstr "테스트"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "테스트 메시지가 성공적으로 전송되었습니다"
 msgstr "테스트 메시지가 성공적으로 전송되었습니다"
 
 
@@ -5429,7 +5456,7 @@ msgstr "2단계 인증이 필요합니다"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5465,11 +5492,11 @@ msgstr "성공적으로 업데이트되었습니다"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "업데이트됨"
 msgstr "업데이트됨"
@@ -5590,7 +5617,7 @@ msgstr "시스템 요구 사항을 확인하십시오"
 msgid "Version"
 msgid "Version"
 msgstr "버전"
 msgstr "버전"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "보기"
 msgstr "보기"
@@ -5677,8 +5704,8 @@ msgstr ""
 "활성화하면 Nginx UI가 시작 시 사용자를 자동으로 재등록합니다. 일반적으로 개발 환경에서 Pebble을 CA로 사용하는 경우가 "
 "활성화하면 Nginx UI가 시작 시 사용자를 자동으로 재등록합니다. 일반적으로 개발 환경에서 Pebble을 CA로 사용하는 경우가 "
 "아니면 이 기능을 활성화하지 마십시오."
 "아니면 이 기능을 활성화하지 마십시오."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5739,8 +5766,8 @@ msgstr "인증서 개인 키를 디스크에 쓰기"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "인증서를 디스크에 쓰기"
 msgstr "인증서를 디스크에 쓰기"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 108 - 81
app/src/language/messages.pot

@@ -86,6 +86,10 @@ msgstr ""
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr ""
 msgstr ""
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr ""
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr ""
 msgstr ""
@@ -98,7 +102,7 @@ msgstr ""
 msgid "About"
 msgid "About"
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr ""
 msgstr ""
 
 
@@ -126,13 +130,13 @@ msgstr ""
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153
-#: src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159
+#: src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr ""
 msgstr ""
@@ -214,7 +218,7 @@ msgstr ""
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
@@ -290,7 +294,7 @@ msgstr ""
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 
 
@@ -306,7 +310,7 @@ msgstr ""
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 
 
@@ -1091,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1428,8 +1432,8 @@ 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:139
-#: src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145
+#: 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"
@@ -1703,9 +1707,9 @@ 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:135
-#: src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141
+#: src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1750,7 +1754,7 @@ msgid "Environment variables cleaned"
 msgstr ""
 msgstr ""
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr ""
 msgstr ""
@@ -1765,7 +1769,7 @@ msgstr ""
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr ""
 msgstr ""
 
 
@@ -1824,7 +1828,7 @@ msgid "External Notification Test"
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr ""
 msgstr ""
 
 
@@ -2155,7 +2159,7 @@ msgstr ""
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr ""
 msgstr ""
 
 
@@ -2728,7 +2732,7 @@ msgid "Loading data..."
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2757,7 +2761,7 @@ msgid "Log file %{log_path} is not a regular file. If you are using nginx-ui in
 msgstr ""
 msgstr ""
 
 
 #: src/routes/modules/nginx_log.ts:39
 #: src/routes/modules/nginx_log.ts:39
-#: src/views/nginx_log/NginxLogList.vue:87
+#: src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr ""
 msgstr ""
 
 
@@ -2784,7 +2788,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr ""
 msgstr ""
 
 
@@ -2990,23 +2994,23 @@ msgstr ""
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21
-#: src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22
+#: src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr ""
 msgstr ""
 
 
@@ -3268,8 +3272,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108
 #: src/components/Notification/Notification.vue:108
@@ -3282,7 +3286,8 @@ msgstr ""
 msgid "No"
 msgid "No"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr ""
 msgstr ""
@@ -3291,6 +3296,10 @@ msgstr ""
 msgid "No data"
 msgid "No data"
 msgstr ""
 msgstr ""
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr ""
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr ""
 msgstr ""
@@ -3307,10 +3316,10 @@ msgstr ""
 msgid "Node"
 msgid "Node"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88
-#: src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr ""
 msgstr ""
 
 
@@ -3353,8 +3362,8 @@ msgstr ""
 msgid "Note"
 msgid "Note"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid "Note, if the configuration file include other configurations or certificates, please synchronize them to the remote nodes in advance."
 msgid "Note, if the configuration file include other configurations or certificates, please synchronize them to the remote nodes in advance."
 msgstr ""
 msgstr ""
 
 
@@ -3419,11 +3428,11 @@ msgstr ""
 msgid "Official Document"
 msgid "Official Document"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr ""
 msgstr ""
@@ -3454,10 +3463,11 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr ""
 msgstr ""
@@ -3576,7 +3586,7 @@ msgstr ""
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr ""
 msgstr ""
 
 
@@ -3736,6 +3746,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr ""
 msgstr ""
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr ""
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr ""
 msgstr ""
@@ -3776,7 +3790,8 @@ msgstr ""
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr ""
 msgstr ""
@@ -3854,8 +3869,8 @@ msgstr ""
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_list/columns.tsx:76
-#: src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78
+#: src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr ""
 msgstr ""
 
 
@@ -3952,8 +3967,9 @@ msgstr ""
 msgid "Reload"
 msgid "Reload"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -3980,7 +3996,7 @@ msgstr ""
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 msgstr ""
 
 
@@ -4137,7 +4153,7 @@ msgstr ""
 msgid "Restart"
 msgid "Restart"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4159,7 +4175,7 @@ msgstr ""
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 msgstr ""
 
 
@@ -4447,7 +4463,7 @@ msgstr ""
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr ""
 msgstr ""
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr ""
 msgstr ""
 
 
@@ -4466,8 +4482,8 @@ msgstr ""
 #: src/language/constants.ts:62
 #: src/language/constants.ts:62
 #: src/language/curd.ts:12
 #: src/language/curd.ts:12
 #: src/views/config/configColumns.tsx:5
 #: src/views/config/configColumns.tsx:5
-#: src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr ""
 msgstr ""
 
 
@@ -4523,6 +4539,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr ""
 msgstr ""
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr ""
+
 #: src/routes/modules/dashboard.ts:19
 #: src/routes/modules/dashboard.ts:19
 #: src/views/preference/Preference.vue:46
 #: src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
@@ -4744,9 +4764,9 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113
-#: src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119
+#: src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr ""
 msgstr ""
 
 
@@ -4907,15 +4927,21 @@ msgstr ""
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr ""
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr ""
 msgstr ""
 
 
@@ -4923,8 +4949,8 @@ msgstr ""
 msgid "Sync to"
 msgid "Sync to"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr ""
 msgstr ""
 
 
@@ -4974,11 +5000,12 @@ msgstr ""
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr ""
 msgstr ""
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr ""
 msgstr ""
 
 
@@ -5267,7 +5294,7 @@ msgstr ""
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5303,12 +5330,12 @@ msgstr ""
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106
-#: src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr ""
 msgstr ""
@@ -5433,7 +5460,7 @@ msgid "Version"
 msgstr ""
 msgstr ""
 
 
 #: src/language/curd.ts:7
 #: src/language/curd.ts:7
-#: src/views/nginx_log/NginxLogList.vue:105
+#: src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr ""
 msgstr ""
@@ -5509,8 +5536,8 @@ msgstr ""
 msgid "When Enabled, Nginx UI will automatically re-register users upon startup. Generally, do not enable this unless you are in a dev environment and using Pebble as CA."
 msgid "When Enabled, Nginx UI will automatically re-register users upon startup. Generally, do not enable this unless you are in a dev environment and using Pebble as CA."
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid "When you enable/disable, delete, or save this site, the nodes set in the Node Group and the nodes selected below will be synchronized."
 msgid "When you enable/disable, delete, or save this site, the nodes set in the Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
@@ -5568,8 +5595,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr ""
 msgstr ""
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/pt_PT/app.po

@@ -100,6 +100,10 @@ msgstr "[Nginx UI] A gravar a chave privada do certificado no disco"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] A escrever o certificado no disco"
 msgstr "[Nginx UI] A escrever o certificado no disco"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* Inclui nós do grupo \"%{groupName}\" e nós selecionados manualmente"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -112,7 +116,7 @@ msgstr "Definições 2FA"
 msgid "About"
 msgid "About"
 msgstr "Sobre"
 msgstr "Sobre"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Registo de Acesso"
 msgstr "Registo de Acesso"
 
 
@@ -139,12 +143,12 @@ msgstr "Acção"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -225,7 +229,7 @@ msgstr ""
 "Depois, atualize esta página e clique em adicionar chave de acesso "
 "Depois, atualize esta página e clique em adicionar chave de acesso "
 "novamente."
 "novamente."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Todos"
 msgstr "Todos"
 
 
@@ -304,7 +308,7 @@ msgstr "Tem a certeza de que pretende eliminar permanentemente?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Tem certeza que pretende eliminar?"
 msgstr "Tem certeza que pretende eliminar?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Tem a certeza que pretende recarregar o Nginx nos seguintes nós de "
 "Tem a certeza que pretende recarregar o Nginx nos seguintes nós de "
@@ -322,7 +326,7 @@ msgstr "Tem certeza que pretende eliminar este item?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Tem certeza que pretende eliminar este local?"
 msgstr "Tem certeza que pretende eliminar este local?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Tem a certeza de que pretende reiniciar o Nginx nos seguintes nós de "
 "Tem a certeza de que pretende reiniciar o Nginx nos seguintes nós de "
@@ -1189,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1526,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1804,8 +1808,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1850,7 +1854,7 @@ msgid "Environment variables cleaned"
 msgstr "Variáveis de ambiente limpas"
 msgstr "Variáveis de ambiente limpas"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Ambientes"
 msgstr "Ambientes"
@@ -1864,7 +1868,7 @@ msgstr "Erro"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Erro ao inicializar o visualizador de diferenças"
 msgstr "Erro ao inicializar o visualizador de diferenças"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Registo de erros"
 msgstr "Registo de erros"
 
 
@@ -1923,7 +1927,7 @@ msgid "External Notification Test"
 msgstr "Teste de notificação externa"
 msgstr "Teste de notificação externa"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Notificação Externa"
 msgstr "Notificação Externa"
 
 
@@ -2254,7 +2258,7 @@ msgstr "Falha ao revogar o certificado: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Falha ao guardar as definições de desempenho do Nginx"
 msgstr "Falha ao guardar as definições de desempenho do Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Falha ao enviar mensagem de teste"
 msgstr "Falha ao enviar mensagem de teste"
 
 
@@ -2854,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2889,7 +2893,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html para obter mais "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html para obter mais "
 "informações."
 "informações."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Lista de registos"
 msgstr "Lista de registos"
 
 
@@ -2927,7 +2931,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Manutenção"
 msgstr "Manutenção"
 
 
@@ -3134,22 +3138,22 @@ msgstr "Diretiva Multilinha"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Nome"
 msgstr "Nome"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Nome ou conteúdo"
 msgstr "Nome ou conteúdo"
 
 
@@ -3411,8 +3415,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf inclui o diretório streams-enabled"
 msgstr "Nginx.conf inclui o diretório streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3424,7 +3428,8 @@ msgstr "Nginx.conf inclui o diretório streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "Não"
 msgstr "Não"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Sem ação"
 msgstr "Sem ação"
@@ -3433,6 +3438,10 @@ msgstr "Sem ação"
 msgid "No data"
 msgid "No data"
 msgstr "Sem dados"
 msgstr "Sem dados"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Nenhum nó selecionado"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Nenhum registo selecionado"
 msgstr "Nenhum registo selecionado"
@@ -3449,9 +3458,9 @@ msgstr "Nenhum upstream configurado"
 msgid "Node"
 msgid "Node"
 msgstr "Nó"
 msgstr "Nó"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Grupo de nós"
 msgstr "Grupo de nós"
 
 
@@ -3494,8 +3503,8 @@ msgstr "Não Válido Antes de: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Nota"
 msgstr "Nota"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3570,11 +3579,11 @@ msgstr "Desligado"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Documentação oficial"
 msgstr "Documentação oficial"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Off-line"
 msgstr "Off-line"
@@ -3604,10 +3613,11 @@ msgstr "Ligado"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "On-line"
 msgstr "On-line"
@@ -3731,7 +3741,7 @@ msgstr "As palavras-passe não coincidem"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Caminho"
 msgstr "Caminho"
 
 
@@ -3918,6 +3928,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Por favor, selecione um ficheiro de cópia de segurança"
 msgstr "Por favor, selecione um ficheiro de cópia de segurança"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Por favor, selecione um tipo de notificação"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Por favor, selecione um ficheiro %{type} válido (%{extensions})"
 msgstr "Por favor, selecione um ficheiro %{type} válido (%{extensions})"
@@ -3958,7 +3972,8 @@ msgstr "Porta"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Scanner de portas"
 msgstr "Scanner de portas"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Ação pós-sincronização"
 msgstr "Ação pós-sincronização"
@@ -4040,7 +4055,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Passe de Proxy"
 msgstr "Passe de Proxy"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Destinos do proxy"
 msgstr "Destinos do proxy"
 
 
@@ -4144,8 +4159,9 @@ msgstr "Nota de Lançamento"
 msgid "Reload"
 msgid "Reload"
 msgstr "Recarregar"
 msgstr "Recarregar"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4172,7 +4188,7 @@ msgstr "Erro ao Recarregar Nginx Remoto"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Recarregamento remoto do Nginx bem-sucedido"
 msgstr "Recarregamento remoto do Nginx bem-sucedido"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "O pedido de recarregamento falhou, por favor verifique a sua ligação à rede"
 msgstr "O pedido de recarregamento falhou, por favor verifique a sua ligação à rede"
 
 
@@ -4334,7 +4350,7 @@ msgstr "Respostas"
 msgid "Restart"
 msgid "Restart"
 msgstr "Reiniciar"
 msgstr "Reiniciar"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4356,7 +4372,7 @@ msgstr "Erro ao reiniciar Nginx remoto"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Reinício remoto do Nginx bem-sucedido"
 msgstr "Reinício remoto do Nginx bem-sucedido"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "Pedido de reinício falhou, por favor verifique a sua ligação à rede"
 msgstr "Pedido de reinício falhou, por favor verifique a sua ligação à rede"
 
 
@@ -4648,7 +4664,7 @@ msgstr ""
 "Digitalize o código QR com o seu telemóvel para adicionar a conta à "
 "Digitalize o código QR com o seu telemóvel para adicionar a conta à "
 "aplicação."
 "aplicação."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "A verificar registros..."
 msgstr "A verificar registros..."
 
 
@@ -4665,8 +4681,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Pesquisar"
 msgstr "Pesquisar"
 
 
@@ -4723,6 +4739,10 @@ msgstr ""
 msgid "Send"
 msgid "Send"
 msgstr "Enviar"
 msgstr "Enviar"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Enviar mensagem de teste"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Servidor"
 msgstr "Servidor"
@@ -4958,8 +4978,8 @@ msgstr "Estático"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Estado"
 msgstr "Estado"
 
 
@@ -5133,15 +5153,21 @@ msgstr "Erro de Configuração de Sincronização"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Sucesso na configuração da sincronização"
 msgstr "Sucesso na configuração da sincronização"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Pré-visualização de sincronização"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Estratégia de sincronização"
 msgstr "Estratégia de sincronização"
 
 
@@ -5149,8 +5175,8 @@ msgstr "Estratégia de sincronização"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Sincronizar para"
 msgstr "Sincronizar para"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Sincronização"
 msgstr "Sincronização"
 
 
@@ -5199,11 +5225,12 @@ msgstr "Terminal"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Comando de Inicialização do Terminal"
 msgstr "Comando de Inicialização do Terminal"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Teste"
 msgstr "Teste"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Mensagem de teste enviada com sucesso"
 msgstr "Mensagem de teste enviada com sucesso"
 
 
@@ -5592,7 +5619,7 @@ msgstr "Autenticação de dois fatores necessária"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5628,11 +5655,11 @@ msgstr "Atualização bem-sucedida"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Actualizado em"
 msgstr "Actualizado em"
@@ -5753,7 +5780,7 @@ msgstr "Verificar requisitos do sistema"
 msgid "Version"
 msgid "Version"
 msgstr "Versão"
 msgstr "Versão"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Ver"
 msgstr "Ver"
@@ -5848,8 +5875,8 @@ msgstr ""
 "arranque. Geralmente, não ative isto a menos que esteja num ambiente de "
 "arranque. Geralmente, não ative isto a menos que esteja num ambiente de "
 "desenvolvimento e a utilizar o Pebble como CA."
 "desenvolvimento e a utilizar o Pebble como CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5914,8 +5941,8 @@ msgstr "Escrever chave privada do certificado ao disco"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Escrevendo certificado no disco"
 msgstr "Escrevendo certificado no disco"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/ru_RU/app.po

@@ -104,6 +104,10 @@ msgstr "[Nginx UI] Запись закрытого ключа сертифика
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Запись сертификата на диск"
 msgstr "[Nginx UI] Запись сертификата на диск"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* Включает узлы из группы \"%{groupName}\" и узлы, выбранные вручную"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -116,7 +120,7 @@ msgstr "Настройки 2FA"
 msgid "About"
 msgid "About"
 msgstr "О проекте"
 msgstr "О проекте"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Журнал доступа"
 msgstr "Журнал доступа"
 
 
@@ -143,12 +147,12 @@ msgstr "Действие"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Действия"
 msgstr "Действия"
@@ -227,7 +231,7 @@ msgstr "Расширенный режим"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "После этого обновите эту страницу и снова нажмите «Добавить ключ доступа»."
 msgstr "После этого обновите эту страницу и снова нажмите «Добавить ключ доступа»."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Все"
 msgstr "Все"
 
 
@@ -306,7 +310,7 @@ msgstr "Вы уверены, что хотите удалить безвозвр
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Вы уверены, что хотите удалить?"
 msgstr "Вы уверены, что хотите удалить?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Вы уверены, что хотите перезагрузить Nginx на следующих синхронизированных "
 "Вы уверены, что хотите перезагрузить Nginx на следующих синхронизированных "
@@ -324,7 +328,7 @@ msgstr "Вы уверены, что хотите удалить этот эле
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Вы уверены, что хотите удалить location?"
 msgstr "Вы уверены, что хотите удалить location?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Вы уверены, что хотите перезапустить Nginx на следующих синхронизированных "
 "Вы уверены, что хотите перезапустить Nginx на следующих синхронизированных "
@@ -1194,7 +1198,7 @@ msgstr ""
 "компьютер."
 "компьютер."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1529,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1807,8 +1811,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1857,7 +1861,7 @@ msgid "Environment variables cleaned"
 msgstr "Переменные окружения очищены"
 msgstr "Переменные окружения очищены"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Окружения"
 msgstr "Окружения"
@@ -1871,7 +1875,7 @@ msgstr "Ошибка"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Ошибка инициализации просмотрщика различий"
 msgstr "Ошибка инициализации просмотрщика различий"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Журнал ошибок"
 msgstr "Журнал ошибок"
 
 
@@ -1930,7 +1934,7 @@ msgid "External Notification Test"
 msgstr "Тест внешнего уведомления"
 msgstr "Тест внешнего уведомления"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Внешнее уведомление"
 msgstr "Внешнее уведомление"
 
 
@@ -2261,7 +2265,7 @@ msgstr "Не удалось отозвать сертификат: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Не удалось сохранить настройки производительности Nginx"
 msgstr "Не удалось сохранить настройки производительности Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Не удалось отправить тестовое сообщение"
 msgstr "Не удалось отправить тестовое сообщение"
 
 
@@ -2859,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2894,7 +2898,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html для получения "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html для получения "
 "дополнительной информации."
 "дополнительной информации."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Список журналов"
 msgstr "Список журналов"
 
 
@@ -2932,7 +2936,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Техническое обслуживание"
 msgstr "Техническое обслуживание"
 
 
@@ -3139,22 +3143,22 @@ msgstr "Многострочная директива"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Имя"
 msgstr "Имя"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Имя или содержание"
 msgstr "Имя или содержание"
 
 
@@ -3416,8 +3420,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf включает каталог streams-enabled"
 msgstr "Nginx.conf включает каталог streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3429,7 +3433,8 @@ msgstr "Nginx.conf включает каталог streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "Нет"
 msgstr "Нет"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Нет действия"
 msgstr "Нет действия"
@@ -3438,6 +3443,10 @@ msgstr "Нет действия"
 msgid "No data"
 msgid "No data"
 msgstr "Нет данных"
 msgstr "Нет данных"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Нет выбранных узлов"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Нет выбранных записей"
 msgstr "Нет выбранных записей"
@@ -3454,9 +3463,9 @@ msgstr "Нет настроенных апстримов"
 msgid "Node"
 msgid "Node"
 msgstr "Узел"
 msgstr "Узел"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Группа узлов"
 msgstr "Группа узлов"
 
 
@@ -3499,8 +3508,8 @@ msgstr "Действителен до: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Заметка"
 msgstr "Заметка"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3575,11 +3584,11 @@ msgstr "Выкл"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Официальная документация"
 msgstr "Официальная документация"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Оффлайн"
 msgstr "Оффлайн"
@@ -3609,10 +3618,11 @@ msgstr "Вкл"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "После завершения проверки записи будут удалены."
 msgstr "После завершения проверки записи будут удалены."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "Онлайн"
 msgstr "Онлайн"
@@ -3736,7 +3746,7 @@ msgstr "Пароли не совпадают"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Путь"
 msgstr "Путь"
 
 
@@ -3928,6 +3938,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Пожалуйста, выберите файл резервной копии"
 msgstr "Пожалуйста, выберите файл резервной копии"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Пожалуйста, выберите тип уведомления"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Пожалуйста, выберите действительный файл %{type} (%{extensions})"
 msgstr "Пожалуйста, выберите действительный файл %{type} (%{extensions})"
@@ -3968,7 +3982,8 @@ msgstr "Порт"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Сканер портов"
 msgstr "Сканер портов"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Действие после синхронизации"
 msgstr "Действие после синхронизации"
@@ -4050,7 +4065,7 @@ msgstr "Прокси"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Прокси-передача"
 msgstr "Прокси-передача"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Цели прокси"
 msgstr "Цели прокси"
 
 
@@ -4154,8 +4169,9 @@ msgstr "Что нового"
 msgid "Reload"
 msgid "Reload"
 msgstr "Перегрузить"
 msgstr "Перегрузить"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4182,7 +4198,7 @@ msgstr "Ошибка перезагрузки удаленного Nginx"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Удаленная перезагрузка Nginx успешно выполнена"
 msgstr "Удаленная перезагрузка Nginx успешно выполнена"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "Не удалось выполнить запрос на перезагрузку, проверьте подключение к сети"
 msgstr "Не удалось выполнить запрос на перезагрузку, проверьте подключение к сети"
 
 
@@ -4342,7 +4358,7 @@ msgstr "Ответы"
 msgid "Restart"
 msgid "Restart"
 msgstr "Перезапуск"
 msgstr "Перезапуск"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4364,7 +4380,7 @@ msgstr "Ошибка перезапуска удаленного Nginx"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Удалённая перезагрузка Nginx успешно выполнена"
 msgstr "Удалённая перезагрузка Nginx успешно выполнена"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "Запрос на перезапуск не выполнен, проверьте подключение к сети"
 msgstr "Запрос на перезапуск не выполнен, проверьте подключение к сети"
 
 
@@ -4656,7 +4672,7 @@ msgstr ""
 "Отсканируйте QR-код с помощью мобильного телефона, чтобы добавить учетную "
 "Отсканируйте QR-код с помощью мобильного телефона, чтобы добавить учетную "
 "запись в приложение."
 "запись в приложение."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Сканирование журналов..."
 msgstr "Сканирование журналов..."
 
 
@@ -4673,8 +4689,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Поиск"
 msgstr "Поиск"
 
 
@@ -4729,6 +4745,10 @@ msgstr "Самопроверка не удалась, Nginx UI может раб
 msgid "Send"
 msgid "Send"
 msgstr "Отправлено"
 msgstr "Отправлено"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Отправить тестовое сообщение"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Сервер"
 msgstr "Сервер"
@@ -4960,8 +4980,8 @@ msgstr "Статический"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Статус"
 msgstr "Статус"
 
 
@@ -5135,15 +5155,21 @@ msgstr "Ошибка синхронизации конфигурации"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Синхронизация конфигурации успешна"
 msgstr "Синхронизация конфигурации успешна"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Синхронизированные узлы"
 msgstr "Синхронизированные узлы"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Предпросмотр синхронизации"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Стратегия синхронизации"
 msgstr "Стратегия синхронизации"
 
 
@@ -5151,8 +5177,8 @@ msgstr "Стратегия синхронизации"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Синхронизировать с"
 msgstr "Синхронизировать с"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Синхронизация"
 msgstr "Синхронизация"
 
 
@@ -5201,11 +5227,12 @@ msgstr "Терминал"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Терминальная команда запуска"
 msgstr "Терминальная команда запуска"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Тест"
 msgstr "Тест"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Тестовое сообщение успешно отправлено"
 msgstr "Тестовое сообщение успешно отправлено"
 
 
@@ -5591,7 +5618,7 @@ msgstr "Требуется двухфакторная аутентификаци
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5627,11 +5654,11 @@ msgstr "Успешно обновлено"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Обновлено в"
 msgstr "Обновлено в"
@@ -5752,7 +5779,7 @@ msgstr "Проверьте системные требования"
 msgid "Version"
 msgid "Version"
 msgstr "Версия"
 msgstr "Версия"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Просмотр"
 msgstr "Просмотр"
@@ -5847,8 +5874,8 @@ msgstr ""
 "при запуске. Обычно не включайте эту функцию, если только вы не находитесь "
 "при запуске. Обычно не включайте эту функцию, если только вы не находитесь "
 "в среде разработки и используете Pebble в качестве CA."
 "в среде разработки и используете Pebble в качестве CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5913,8 +5940,8 @@ msgstr "Запись закрытого ключа сертификата на 
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Запись сертификата на диск"
 msgstr "Запись сертификата на диск"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 102 - 73
app/src/language/tr_TR/app.po

@@ -100,6 +100,12 @@ msgstr "[Nginx UI] Sertifika özel anahtarı diske yazılıyor"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Sertifika diske yazılıyor"
 msgstr "[Nginx UI] Sertifika diske yazılıyor"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr ""
+"* \"%{groupName}\" grubundaki düğümler ve manuel olarak seçilen düğümler "
+"dahil"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "İki aşamalı kimlik doğrulaması(2FA)"
 msgstr "İki aşamalı kimlik doğrulaması(2FA)"
@@ -112,7 +118,7 @@ msgstr "2FA Ayarları"
 msgid "About"
 msgid "About"
 msgstr "Hakkında"
 msgstr "Hakkında"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Erişim Kayıtları"
 msgstr "Erişim Kayıtları"
 
 
@@ -139,12 +145,12 @@ msgstr "Eylem"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -223,7 +229,7 @@ msgstr "Gelişmiş Mod"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "Daha sonra bu sayfayı yenileyin ve tekrar parola anahtarı ekle'ye tıklayın."
 msgstr "Daha sonra bu sayfayı yenileyin ve tekrar parola anahtarı ekle'ye tıklayın."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Tümü"
 msgstr "Tümü"
 
 
@@ -302,7 +308,7 @@ msgstr "Kalıcı olarak silmek istediğinizden emin misiniz?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Silmek istediğine emin misin?"
 msgstr "Silmek istediğine emin misin?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden yüklemek "
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden yüklemek "
@@ -320,7 +326,7 @@ msgstr "Bu öğeyi kaldırmak istediğinizden emin misiniz?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Bu konumu kaldırmak istediğinizden emin misiniz?"
 msgstr "Bu konumu kaldırmak istediğinizden emin misiniz?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden başlatmak "
 "Aşağıdaki senkronizasyon düğümlerinde Nginx'i yeniden başlatmak "
@@ -1182,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1519,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1799,8 +1805,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1847,7 +1853,7 @@ msgid "Environment variables cleaned"
 msgstr "Ortam değişkenleri temizlendi"
 msgstr "Ortam değişkenleri temizlendi"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Ortamlar"
 msgstr "Ortamlar"
@@ -1861,7 +1867,7 @@ msgstr "Hata"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Fark görüntüleyici başlatılırken hata"
 msgstr "Fark görüntüleyici başlatılırken hata"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Hata Günlüğü"
 msgstr "Hata Günlüğü"
 
 
@@ -1920,7 +1926,7 @@ msgid "External Notification Test"
 msgstr "Harici Bildirim Testi"
 msgstr "Harici Bildirim Testi"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Harici Bildirim"
 msgstr "Harici Bildirim"
 
 
@@ -2251,7 +2257,7 @@ msgstr "Sertifika iptal edilemedi: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Nginx performans ayarları kaydedilemedi"
 msgstr "Nginx performans ayarları kaydedilemedi"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Test mesajı gönderilemedi"
 msgstr "Test mesajı gönderilemedi"
 
 
@@ -2853,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2887,7 +2893,7 @@ msgstr ""
 "nginx-ui kullanıyorsanız, daha fazla bilgi için "
 "nginx-ui kullanıyorsanız, daha fazla bilgi için "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html adresine bakın."
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html adresine bakın."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Günlük Listesi"
 msgstr "Günlük Listesi"
 
 
@@ -2925,7 +2931,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Bakım"
 msgstr "Bakım"
 
 
@@ -3132,22 +3138,22 @@ msgstr "Çok Satırlı Yönergeler"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "İsim"
 msgstr "İsim"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Ad veya içerik"
 msgstr "Ad veya içerik"
 
 
@@ -3409,8 +3415,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf, streams-enabled dizinini içerir"
 msgstr "Nginx.conf, streams-enabled dizinini içerir"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3422,7 +3428,8 @@ msgstr "Nginx.conf, streams-enabled dizinini içerir"
 msgid "No"
 msgid "No"
 msgstr "Hayır"
 msgstr "Hayır"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Eylem Yok"
 msgstr "Eylem Yok"
@@ -3431,6 +3438,10 @@ msgstr "Eylem Yok"
 msgid "No data"
 msgid "No data"
 msgstr "Veri yok"
 msgstr "Veri yok"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Hiçbir düğüm seçilmedi"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Hiçbir kayıt seçilmedi"
 msgstr "Hiçbir kayıt seçilmedi"
@@ -3447,9 +3458,9 @@ msgstr "Yapılandırılmış yukarı akış yok"
 msgid "Node"
 msgid "Node"
 msgstr "Düğüm"
 msgstr "Düğüm"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Düğüm Grubu"
 msgstr "Düğüm Grubu"
 
 
@@ -3492,8 +3503,8 @@ msgstr "Geçerlilik Başlangıç Tarihi: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Not"
 msgstr "Not"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3568,11 +3579,11 @@ msgstr "Kapalı"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Resmi Belge"
 msgstr "Resmi Belge"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Çevrimdışı"
 msgstr "Çevrimdışı"
@@ -3602,10 +3613,11 @@ msgstr "Açık"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "Çevrimiçi"
 msgstr "Çevrimiçi"
@@ -3728,7 +3740,7 @@ msgstr "Şifreler eşleşmiyor"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Yol"
 msgstr "Yol"
 
 
@@ -3916,6 +3928,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Lütfen bir yedekleme dosyası seçin"
 msgstr "Lütfen bir yedekleme dosyası seçin"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Lütfen bir bildirim türü seçin"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Lütfen geçerli bir %{type} dosyası seçin (%{extensions})"
 msgstr "Lütfen geçerli bir %{type} dosyası seçin (%{extensions})"
@@ -3956,7 +3972,8 @@ msgstr "Port"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Port Tarayıcı"
 msgstr "Port Tarayıcı"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Senkronizasyon Sonrası İşlem"
 msgstr "Senkronizasyon Sonrası İşlem"
@@ -4037,7 +4054,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Proxy Geçişi"
 msgstr "Proxy Geçişi"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Proxy Hedefleri"
 msgstr "Proxy Hedefleri"
 
 
@@ -4141,8 +4158,9 @@ msgstr "Sürüm Notları"
 msgid "Reload"
 msgid "Reload"
 msgstr "Yeniden Yükle"
 msgstr "Yeniden Yükle"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4169,7 +4187,7 @@ msgstr "Uzak Nginx Yeniden Yükleme Hatası"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Uzak Nginx Yeniden Yükleme Başarılı"
 msgstr "Uzak Nginx Yeniden Yükleme Başarılı"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "Yeniden yükleme isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 msgstr "Yeniden yükleme isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 
 
@@ -4338,7 +4356,7 @@ msgstr "Yanıtlar"
 msgid "Restart"
 msgid "Restart"
 msgstr "Yeniden Başlat"
 msgstr "Yeniden Başlat"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4360,7 +4378,7 @@ msgstr "Uzak Nginx Yeniden Başlatma Hatası"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Uzak Nginx Yeniden Başlatma Başarılı"
 msgstr "Uzak Nginx Yeniden Başlatma Başarılı"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "Yeniden başlatma isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 msgstr "Yeniden başlatma isteği başarısız oldu, lütfen ağ bağlantınızı kontrol edin"
 
 
@@ -4650,7 +4668,7 @@ msgstr "Tarama Sonuçları"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "Hesabı uygulamaya eklemek için telefonunuzla QR kodunu tarayın."
 msgstr "Hesabı uygulamaya eklemek için telefonunuzla QR kodunu tarayın."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Günlükler taranıyor..."
 msgstr "Günlükler taranıyor..."
 
 
@@ -4667,8 +4685,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Ara"
 msgstr "Ara"
 
 
@@ -4723,6 +4741,10 @@ msgstr "Kendi kendine kontrol başarısız oldu, Nginx UI düzgün çalışmayab
 msgid "Send"
 msgid "Send"
 msgstr "Gönder"
 msgstr "Gönder"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Test mesajı gönder"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Sunucu"
 msgstr "Sunucu"
@@ -4956,8 +4978,8 @@ msgstr "Statik"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Durum"
 msgstr "Durum"
 
 
@@ -5133,15 +5155,21 @@ msgstr "Yapılandırma Senkronizasyon Hatası"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Yapılandırma Başarıyla Senkronize Edildi"
 msgstr "Yapılandırma Başarıyla Senkronize Edildi"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Senkronizasyon Önizleme"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Senkronizasyon stratejisi"
 msgstr "Senkronizasyon stratejisi"
 
 
@@ -5149,8 +5177,8 @@ msgstr "Senkronizasyon stratejisi"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Senkronize Et"
 msgstr "Senkronize Et"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Senkronizasyon"
 msgstr "Senkronizasyon"
 
 
@@ -5199,11 +5227,12 @@ msgstr "Terminal"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Terminal Başlatma Komutu"
 msgstr "Terminal Başlatma Komutu"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Test"
 msgstr "Test"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Test mesajı başarıyla gönderildi"
 msgstr "Test mesajı başarıyla gönderildi"
 
 
@@ -5588,7 +5617,7 @@ msgstr "İki faktörlü kimlik doğrulama gerekiyor"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5624,11 +5653,11 @@ msgstr "Başarıyla güncellendi"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Güncellenme Tarihi"
 msgstr "Güncellenme Tarihi"
@@ -5749,7 +5778,7 @@ msgstr "Sistem Gereksinimlerini Doğrulun"
 msgid "Version"
 msgid "Version"
 msgstr "Sürüm"
 msgstr "Sürüm"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Görüntüle"
 msgstr "Görüntüle"
@@ -5844,8 +5873,8 @@ msgstr ""
 "yeniden kaydedecektir. Genellikle, bir geliştirme ortamında değilseniz ve "
 "yeniden kaydedecektir. Genellikle, bir geliştirme ortamında değilseniz ve "
 "Pebble'ı CA olarak kullanmıyorsanız bunu etkinleştirmeyin."
 "Pebble'ı CA olarak kullanmıyorsanız bunu etkinleştirmeyin."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5911,8 +5940,8 @@ msgstr "Sertifika özel anahtarı diske yazılıyor"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Sertifika diske yazılıyor"
 msgstr "Sertifika diske yazılıyor"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/uk_UA/app.po

@@ -104,6 +104,10 @@ msgstr "[Nginx UI] Запис приватного ключа сертифіка
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Запис сертифіката на диск"
 msgstr "[Nginx UI] Запис сертифіката на диск"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* Включає вузли з групи \"%{groupName}\" та вручну вибрані вузли"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -116,7 +120,7 @@ msgstr "2FA Налаштування"
 msgid "About"
 msgid "About"
 msgstr "Про программу"
 msgstr "Про программу"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Логи доступу"
 msgstr "Логи доступу"
 
 
@@ -143,12 +147,12 @@ msgstr "Дія"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "Дії"
 msgstr "Дії"
@@ -227,7 +231,7 @@ msgstr "Розширений режим"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "Після цього оновіть цю сторінку та натисніть «Додати ключ доступу» знову."
 msgstr "Після цього оновіть цю сторінку та натисніть «Додати ключ доступу» знову."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Усі"
 msgstr "Усі"
 
 
@@ -306,7 +310,7 @@ msgstr "Ви впевнені, що хочете видалити назавжд
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Ви впевнені, що хочете видалити?"
 msgstr "Ви впевнені, що хочете видалити?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Ви впевнені, що бажаєте перезавантажити Nginx на наступних вузлах "
 "Ви впевнені, що бажаєте перезавантажити Nginx на наступних вузлах "
@@ -324,7 +328,7 @@ msgstr "Ви впевнені, що хочете видалити цей еле
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Ви впевнені, що хочете видалити цю локацію?"
 msgstr "Ви впевнені, що хочете видалити цю локацію?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr ""
 msgstr ""
 "Ви впевнені, що хочете перезавантажити Nginx на вказаних синхронізованих "
 "Ви впевнені, що хочете перезавантажити Nginx на вказаних синхронізованих "
@@ -1188,7 +1192,7 @@ msgstr ""
 "комп’ютер."
 "комп’ютер."
 
 
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
 #: src/views/backup/AutoBackup/AutoBackup.vue:229
-#: src/views/environments/group/columns.ts:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1595,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1873,8 +1877,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1923,7 +1927,7 @@ msgid "Environment variables cleaned"
 msgstr "Змінні середовища очищено"
 msgstr "Змінні середовища очищено"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Середовища"
 msgstr "Середовища"
@@ -1937,7 +1941,7 @@ msgstr "Помилка"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Помилка ініціалізації переглядача різниць"
 msgstr "Помилка ініціалізації переглядача різниць"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Журнал помилок"
 msgstr "Журнал помилок"
 
 
@@ -1996,7 +2000,7 @@ msgid "External Notification Test"
 msgstr "Тест зовнішнього сповіщення"
 msgstr "Тест зовнішнього сповіщення"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Зовнішнє сповіщення"
 msgstr "Зовнішнє сповіщення"
 
 
@@ -2327,7 +2331,7 @@ msgstr "Не вдалося відкликати сертифікат: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Не вдалося зберегти налаштування продуктивності Nginx"
 msgstr "Не вдалося зберегти налаштування продуктивності Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Не вдалося надіслати тестове повідомлення"
 msgstr "Не вдалося надіслати тестове повідомлення"
 
 
@@ -2925,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2960,7 +2964,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html для отримання "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html для отримання "
 "додаткової інформації."
 "додаткової інформації."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Список журналів"
 msgstr "Список журналів"
 
 
@@ -2998,7 +3002,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Технічне обслуговування"
 msgstr "Технічне обслуговування"
 
 
@@ -3205,22 +3209,22 @@ msgstr "Багаторядкова директива"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Ім'я"
 msgstr "Ім'я"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Ім’я або вміст"
 msgstr "Ім’я або вміст"
 
 
@@ -3482,8 +3486,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf включає каталог streams-enabled"
 msgstr "Nginx.conf включає каталог streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3495,7 +3499,8 @@ msgstr "Nginx.conf включає каталог streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "Ні"
 msgstr "Ні"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Без дії"
 msgstr "Без дії"
@@ -3504,6 +3509,10 @@ msgstr "Без дії"
 msgid "No data"
 msgid "No data"
 msgstr "Немає даних"
 msgstr "Немає даних"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Не вибрано жодного вузла"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Не вибрано жодного запису"
 msgstr "Не вибрано жодного запису"
@@ -3520,9 +3529,9 @@ msgstr "Не налаштовано жодного апстріму"
 msgid "Node"
 msgid "Node"
 msgstr "Вузол"
 msgstr "Вузол"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Група вузлів"
 msgstr "Група вузлів"
 
 
@@ -3565,8 +3574,8 @@ msgstr "Не дійсний до: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Примітка"
 msgstr "Примітка"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3641,11 +3650,11 @@ msgstr "Вимкнено"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Офіційна документація"
 msgstr "Офіційна документація"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Офлайн"
 msgstr "Офлайн"
@@ -3675,10 +3684,11 @@ msgstr "Увімкнено"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Після завершення перевірки записи будуть видалені."
 msgstr "Після завершення перевірки записи будуть видалені."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "Онлайн"
 msgstr "Онлайн"
@@ -3802,7 +3812,7 @@ msgstr "Паролі не збігаються"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Шлях"
 msgstr "Шлях"
 
 
@@ -3990,6 +4000,10 @@ msgstr ""
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Будь ласка, виберіть файл резервної копії"
 msgstr "Будь ласка, виберіть файл резервної копії"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Будь ласка, виберіть тип сповіщення"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Будь ласка, виберіть дійсний файл %{type} (%{extensions})"
 msgstr "Будь ласка, виберіть дійсний файл %{type} (%{extensions})"
@@ -4030,7 +4044,8 @@ msgstr "Порт"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Сканер портів"
 msgstr "Сканер портів"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Дія після синхронізації"
 msgstr "Дія після синхронізації"
@@ -4112,7 +4127,7 @@ msgstr "Проксі"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Проксі-передача"
 msgstr "Проксі-передача"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Цілі проксі"
 msgstr "Цілі проксі"
 
 
@@ -4217,8 +4232,9 @@ msgstr "Примітки до версії"
 msgid "Reload"
 msgid "Reload"
 msgstr "Перезавантажити"
 msgstr "Перезавантажити"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4245,7 +4261,7 @@ msgstr "Помилка перезавантаження віддаленого N
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Успішне перезавантаження віддаленого Nginx"
 msgstr "Успішне перезавантаження віддаленого Nginx"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr ""
 msgstr ""
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
@@ -4407,7 +4423,7 @@ msgstr "Відповіді"
 msgid "Restart"
 msgid "Restart"
 msgstr "Перезавантажити"
 msgstr "Перезавантажити"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4429,7 +4445,7 @@ msgstr "Помилка перезапуску віддаленого Nginx"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Віддалений перезапуск Nginx успішний"
 msgstr "Віддалений перезапуск Nginx успішний"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr ""
 msgstr ""
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
 "Не вдалося виконати запит на перезавантаження, будь ласка, перевірте "
@@ -4723,7 +4739,7 @@ msgstr ""
 "Відскануйте QR-код за допомогою мобільного телефону, щоб додати обліковий "
 "Відскануйте QR-код за допомогою мобільного телефону, щоб додати обліковий "
 "запис до програми."
 "запис до програми."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Сканування журналів..."
 msgstr "Сканування журналів..."
 
 
@@ -4740,8 +4756,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Пошук"
 msgstr "Пошук"
 
 
@@ -4796,6 +4812,10 @@ msgstr "Самоперевірка не вдалася, інтерфейс Nginx
 msgid "Send"
 msgid "Send"
 msgstr "Надіслати"
 msgstr "Надіслати"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Надіслати тестове повідомлення"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Сервер"
 msgstr "Сервер"
@@ -5031,8 +5051,8 @@ msgstr "Статичний"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Статус"
 msgstr "Статус"
 
 
@@ -5206,15 +5226,21 @@ msgstr "Помилка синхронізації конфігурації"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Успішна синхронізація конфігурації"
 msgstr "Успішна синхронізація конфігурації"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "Синхронізовані вузли"
 msgstr "Синхронізовані вузли"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Попередній перегляд синхронізації"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Стратегія синхронізації"
 msgstr "Стратегія синхронізації"
 
 
@@ -5222,8 +5248,8 @@ msgstr "Стратегія синхронізації"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Синхронізувати з"
 msgstr "Синхронізувати з"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Синхронізація"
 msgstr "Синхронізація"
 
 
@@ -5272,11 +5298,12 @@ msgstr "Термінал"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Команда запуску терміналу"
 msgstr "Команда запуску терміналу"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Тест"
 msgstr "Тест"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Тестове повідомлення успішно надіслано"
 msgstr "Тестове повідомлення успішно надіслано"
 
 
@@ -5661,7 +5688,7 @@ msgstr "Потрібна двофакторна аутентифікація"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5697,11 +5724,11 @@ msgstr "Успішно оновлено"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Оновлено"
 msgstr "Оновлено"
@@ -5822,7 +5849,7 @@ msgstr "Перевірте системні вимоги"
 msgid "Version"
 msgid "Version"
 msgstr "Версія"
 msgstr "Версія"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Переглянути"
 msgstr "Переглянути"
@@ -5917,8 +5944,8 @@ msgstr ""
 "запуску. Як правило, не вмикайте цю функцію, якщо ви не перебуваєте у "
 "запуску. Як правило, не вмикайте цю функцію, якщо ви не перебуваєте у "
 "середовищі розробки та використовуєте Pebble як CA."
 "середовищі розробки та використовуєте Pebble як CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5983,8 +6010,8 @@ msgstr "Запис приватного ключа сертифіката на 
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Запис сертифіката на диск"
 msgstr "Запис сертифіката на диск"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/vi_VN/app.po

@@ -95,6 +95,10 @@ msgstr "[Nginx UI] Đang ghi khóa riêng của chứng chỉ vào ổ đĩa"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] Đang ghi chứng chỉ vào ổ đĩa"
 msgstr "[Nginx UI] Đang ghi chứng chỉ vào ổ đĩa"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* Bao gồm các nút từ nhóm \"%{groupName}\" và các nút được chọn thủ công"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2fa"
 msgstr "2fa"
@@ -107,7 +111,7 @@ msgstr "Cài đặt 2FA"
 msgid "About"
 msgid "About"
 msgstr "Tác giả"
 msgstr "Tác giả"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "Nhật ký truy cập"
 msgstr "Nhật ký truy cập"
 
 
@@ -134,12 +138,12 @@ msgstr "Hành động"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 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"
@@ -218,7 +222,7 @@ msgstr "Nâng cao"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "Sau đó, làm mới trang này và nhấp vào thêm khóa truy cập một lần nữa."
 msgstr "Sau đó, làm mới trang này và nhấp vào thêm khóa truy cập một lần nữa."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "Tất cả"
 msgstr "Tất cả"
 
 
@@ -297,7 +301,7 @@ msgstr "Bạn có chắc chắn muốn xóa vĩnh viễn không?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "Bạn có chắc chắn muốn xóa không?"
 msgstr "Bạn có chắc chắn muốn xóa không?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "Bạn có chắc chắn muốn tải lại Nginx trên các nút đồng bộ sau không?"
 msgstr "Bạn có chắc chắn muốn tải lại Nginx trên các nút đồng bộ sau không?"
 
 
@@ -313,7 +317,7 @@ msgstr "Bạn có chắc chắn muốn xóa mục này không?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "Bạn có chắc chắn muốn xóa vị trí này không?"
 msgstr "Bạn có chắc chắn muốn xóa vị trí này không?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "Bạn có chắc chắn muốn khởi động lại Nginx trên các nút đồng bộ sau không?"
 msgstr "Bạn có chắc chắn muốn khởi động lại Nginx trên các nút đồng bộ sau không?"
 
 
@@ -1164,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1499,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1778,8 +1782,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1824,7 +1828,7 @@ msgid "Environment variables cleaned"
 msgstr "Đã dọn dẹp biến môi trường"
 msgstr "Đã dọn dẹp biến môi trường"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "Môi trường"
 msgstr "Môi trường"
@@ -1838,7 +1842,7 @@ msgstr "Lỗi"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "Lỗi khởi tạo trình xem khác biệt"
 msgstr "Lỗi khởi tạo trình xem khác biệt"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "Nhật ký lỗi"
 msgstr "Nhật ký lỗi"
 
 
@@ -1897,7 +1901,7 @@ msgid "External Notification Test"
 msgstr "Kiểm tra thông báo bên ngoài"
 msgstr "Kiểm tra thông báo bên ngoài"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "Thông báo bên ngoài"
 msgstr "Thông báo bên ngoài"
 
 
@@ -2228,7 +2232,7 @@ msgstr "Không thể thu hồi chứng chỉ: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "Không thể lưu cài đặt hiệu suất Nginx"
 msgstr "Không thể lưu cài đặt hiệu suất Nginx"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "Gửi tin nhắn kiểm tra thất bại"
 msgstr "Gửi tin nhắn kiểm tra thất bại"
 
 
@@ -2825,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2860,7 +2864,7 @@ msgstr ""
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html để biết thêm thông "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html để biết thêm thông "
 "tin."
 "tin."
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "Danh sách nhật ký"
 msgstr "Danh sách nhật ký"
 
 
@@ -2898,7 +2902,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "Bảo trì"
 msgstr "Bảo trì"
 
 
@@ -3105,22 +3109,22 @@ msgstr "Chỉ thị nhiều dòng"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "Tên"
 msgstr "Tên"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "Tên hoặc nội dung"
 msgstr "Tên hoặc nội dung"
 
 
@@ -3382,8 +3386,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf bao gồm thư mục streams-enabled"
 msgstr "Nginx.conf bao gồm thư mục streams-enabled"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3395,7 +3399,8 @@ msgstr "Nginx.conf bao gồm thư mục streams-enabled"
 msgid "No"
 msgid "No"
 msgstr "Không"
 msgstr "Không"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "Không hành động"
 msgstr "Không hành động"
@@ -3404,6 +3409,10 @@ msgstr "Không hành động"
 msgid "No data"
 msgid "No data"
 msgstr "Không có dữ liệu"
 msgstr "Không có dữ liệu"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "Không có nút nào được chọn"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "Không có bản ghi nào được chọn"
 msgstr "Không có bản ghi nào được chọn"
@@ -3420,9 +3429,9 @@ msgstr "Không có upstream nào được cấu hình"
 msgid "Node"
 msgid "Node"
 msgstr "Nút"
 msgstr "Nút"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "Nhóm nút"
 msgstr "Nhóm nút"
 
 
@@ -3465,8 +3474,8 @@ msgstr "Không hợp lệ trước: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "Ghi chú"
 msgstr "Ghi chú"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3539,11 +3548,11 @@ msgstr "Tắt"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "Tài liệu chính thức"
 msgstr "Tài liệu chính thức"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "Ngoại tuyến"
 msgstr "Ngoại tuyến"
@@ -3573,10 +3582,11 @@ msgstr "Bật"
 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."
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "Trực tuyến"
 msgstr "Trực tuyến"
@@ -3700,7 +3710,7 @@ msgstr "Mật khẩu không khớp"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "Đường dẫn"
 msgstr "Đường dẫn"
 
 
@@ -3879,6 +3889,10 @@ msgstr "Vui lòng lưu token bảo mật này, bạn sẽ cần nó để khôi
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "Vui lòng chọn tệp sao lưu"
 msgstr "Vui lòng chọn tệp sao lưu"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "Vui lòng chọn loại thông báo"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "Vui lòng chọn tệp %{type} hợp lệ (%{extensions})"
 msgstr "Vui lòng chọn tệp %{type} hợp lệ (%{extensions})"
@@ -3919,7 +3933,8 @@ msgstr "Cổng"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "Trình quét cổng"
 msgstr "Trình quét cổng"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "Hành động sau đồng bộ"
 msgstr "Hành động sau đồng bộ"
@@ -4000,7 +4015,7 @@ msgstr "Proxy"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "Chuyển tiếp Proxy"
 msgstr "Chuyển tiếp Proxy"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "Mục tiêu proxy"
 msgstr "Mục tiêu proxy"
 
 
@@ -4104,8 +4119,9 @@ msgstr "Ghi chú phát hành"
 msgid "Reload"
 msgid "Reload"
 msgstr "Tải lại"
 msgstr "Tải lại"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4132,7 +4148,7 @@ msgstr "Lỗi tải lại Nginx từ xa"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "Tải lại Nginx từ xa thành công"
 msgstr "Tải lại Nginx từ xa thành công"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "Yêu cầu tải lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 msgstr "Yêu cầu tải lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 
 
@@ -4292,7 +4308,7 @@ msgstr "Phản hồi"
 msgid "Restart"
 msgid "Restart"
 msgstr "Khởi động lại"
 msgstr "Khởi động lại"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4314,7 +4330,7 @@ msgstr "Lỗi khởi động lại Nginx từ xa"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "Khởi động lại Nginx từ xa thành công"
 msgstr "Khởi động lại Nginx từ xa thành công"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "Yêu cầu khởi động lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 msgstr "Yêu cầu khởi động lại thất bại, vui lòng kiểm tra kết nối mạng của bạn"
 
 
@@ -4604,7 +4620,7 @@ msgstr "Kết quả quét"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "Quét mã QR bằng điện thoại di động của bạn để thêm tài khoản vào ứng dụng."
 msgstr "Quét mã QR bằng điện thoại di động của bạn để thêm tài khoản vào ứng dụng."
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "Đang quét nhật ký..."
 msgstr "Đang quét nhật ký..."
 
 
@@ -4621,8 +4637,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "Tìm kiếm"
 msgstr "Tìm kiếm"
 
 
@@ -4677,6 +4693,10 @@ msgstr "Tự kiểm tra thất bại, giao diện Nginx có thể không hoạt
 msgid "Send"
 msgid "Send"
 msgstr "Gửi"
 msgstr "Gửi"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "Gửi tin nhắn kiểm tra"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "Máy chủ"
 msgstr "Máy chủ"
@@ -4908,8 +4928,8 @@ msgstr "Tĩnh"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "Trạng thái"
 msgstr "Trạng thái"
 
 
@@ -5083,15 +5103,21 @@ msgstr "Lỗi đồng bộ cấu hình"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Đồng bộ cấu hình thành công"
 msgstr "Đồng bộ cấu hình thành công"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: 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ộ"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "Xem trước đồng bộ"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "Chiến lược đồng bộ hóa"
 msgstr "Chiến lược đồng bộ hóa"
 
 
@@ -5099,8 +5125,8 @@ msgstr "Chiến lược đồng bộ hóa"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "Đồng bộ tới"
 msgstr "Đồng bộ tới"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "Đồng bộ hóa"
 msgstr "Đồng bộ hóa"
 
 
@@ -5149,11 +5175,12 @@ msgstr "Thiết bị đầu cuối"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "Lệnh Khởi động Terminal"
 msgstr "Lệnh Khởi động Terminal"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "Kiểm tra"
 msgstr "Kiểm tra"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "Gửi tin nhắn kiểm tra thành công"
 msgstr "Gửi tin nhắn kiểm tra thành công"
 
 
@@ -5538,7 +5565,7 @@ msgstr "Yêu cầu xác thực hai yếu tố"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5574,11 +5601,11 @@ msgstr "Cập nhật thành công"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Ngày cập nhật"
 msgstr "Ngày cập nhật"
@@ -5699,7 +5726,7 @@ msgstr "Xác minh các yêu cầu hệ thống"
 msgid "Version"
 msgid "Version"
 msgstr "Phiên bản"
 msgstr "Phiên bản"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "Xem"
 msgstr "Xem"
@@ -5794,8 +5821,8 @@ msgstr ""
 "chung, không bật tính năng này trừ khi bạn đang ở trong môi trường phát "
 "chung, không bật tính năng này trừ khi bạn đang ở trong môi trường phát "
 "triển và sử dụng Pebble làm CA."
 "triển và sử dụng Pebble làm CA."
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5858,8 +5885,8 @@ msgstr "Ghi Private Key vào disk"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "Ghi chứng chỉ vào disk"
 msgstr "Ghi chứng chỉ vào disk"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/zh_CN/app.po

@@ -99,6 +99,10 @@ msgstr "[Nginx UI] 正在将证书私钥写入磁盘"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] 正在将证书写入磁盘"
 msgstr "[Nginx UI] 正在将证书写入磁盘"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* 包含来自组 \"%{groupName}\" 的节点和手动选择的节点"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "2FA"
 msgstr "2FA"
@@ -111,7 +115,7 @@ msgstr "2FA 设置"
 msgid "About"
 msgid "About"
 msgstr "关于"
 msgstr "关于"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "访问日志"
 msgstr "访问日志"
 
 
@@ -138,12 +142,12 @@ msgstr "操作"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -222,7 +226,7 @@ msgstr "高级模式"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "之后,请刷新此页面并再次点击添加通行密钥。"
 msgstr "之后,请刷新此页面并再次点击添加通行密钥。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "全部"
 msgstr "全部"
 
 
@@ -299,7 +303,7 @@ msgstr "确定要永久删除吗?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "您确定要删除吗?"
 msgstr "您确定要删除吗?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "你确定要在以下同步节点上重载 Nginx?"
 msgstr "你确定要在以下同步节点上重载 Nginx?"
 
 
@@ -315,7 +319,7 @@ msgstr "您确定要删除这个项目吗?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "您确定要删除这个 Location?"
 msgstr "您确定要删除这个 Location?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "你确定要在以下同步节点上重启 Nginx 吗?"
 msgstr "你确定要在以下同步节点上重启 Nginx 吗?"
 
 
@@ -1142,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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
@@ -1477,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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1752,8 +1756,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1798,7 +1802,7 @@ msgid "Environment variables cleaned"
 msgstr "环境变量已清理"
 msgstr "环境变量已清理"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "环境"
 msgstr "环境"
@@ -1812,7 +1816,7 @@ msgstr "错误"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "差异查看器初始化出错"
 msgstr "差异查看器初始化出错"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "错误日志"
 msgstr "错误日志"
 
 
@@ -1871,7 +1875,7 @@ msgid "External Notification Test"
 msgstr "外部通知测试"
 msgstr "外部通知测试"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "外部通知"
 msgstr "外部通知"
 
 
@@ -2202,7 +2206,7 @@ msgstr "撤销证书失败:%{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "保存 Nginx 性能参数失败"
 msgstr "保存 Nginx 性能参数失败"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "发送测试消息失败"
 msgstr "发送测试消息失败"
 
 
@@ -2787,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2820,7 +2824,7 @@ msgstr ""
 "日志文件 %{log_path} 不是常规文件。如果在 Docker 容器中使用 Nginx UI,请参阅 "
 "日志文件 %{log_path} 不是常规文件。如果在 Docker 容器中使用 Nginx UI,请参阅 "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html 获取更多信息。"
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html 获取更多信息。"
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "日志列表"
 msgstr "日志列表"
 
 
@@ -2855,7 +2859,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "维护模式"
 msgstr "维护模式"
 
 
@@ -3060,22 +3064,22 @@ msgstr "多行指令"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "名称"
 msgstr "名称"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "名称或内容"
 msgstr "名称或内容"
 
 
@@ -3335,8 +3339,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "检查 nginx.conf 是否包含 streams-enabled 的目录"
 msgstr "检查 nginx.conf 是否包含 streams-enabled 的目录"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3348,7 +3352,8 @@ msgstr "检查 nginx.conf 是否包含 streams-enabled 的目录"
 msgid "No"
 msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "无操作"
 msgstr "无操作"
@@ -3357,6 +3362,10 @@ msgstr "无操作"
 msgid "No data"
 msgid "No data"
 msgstr "没有数据"
 msgstr "没有数据"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "未选择节点"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "未选择记录"
 msgstr "未选择记录"
@@ -3373,9 +3382,9 @@ msgstr "未配置上游"
 msgid "Node"
 msgid "Node"
 msgstr "节点"
 msgstr "节点"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "节点组"
 msgstr "节点组"
 
 
@@ -3418,8 +3427,8 @@ msgstr "此前无效: %{date}"
 msgid "Note"
 msgid "Note"
 msgstr "注意"
 msgstr "注意"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3488,11 +3497,11 @@ msgstr "关闭"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "官方文档"
 msgstr "官方文档"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "离线"
 msgstr "离线"
@@ -3522,10 +3531,11 @@ msgstr "开启"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "一旦验证完成,这些记录将被删除。"
 msgstr "一旦验证完成,这些记录将被删除。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "在线"
 msgstr "在线"
@@ -3645,7 +3655,7 @@ msgstr "密码不匹配"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "路径"
 msgstr "路径"
 
 
@@ -3816,6 +3826,10 @@ msgstr "请保存此安全令牌,恢复时会用到它:"
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "请选择备份文件"
 msgstr "请选择备份文件"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "请选择通知类型"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "请选择有效的%{type}文件(%{extensions})"
 msgstr "请选择有效的%{type}文件(%{extensions})"
@@ -3856,7 +3870,8 @@ msgstr "端口"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "端口检测"
 msgstr "端口检测"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同步后操作"
 msgstr "同步后操作"
@@ -3935,7 +3950,7 @@ msgstr "代理"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "代理传递"
 msgstr "代理传递"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "代理目标"
 msgstr "代理目标"
 
 
@@ -4035,8 +4050,9 @@ msgstr "发行日志"
 msgid "Reload"
 msgid "Reload"
 msgstr "重载"
 msgstr "重载"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4063,7 +4079,7 @@ msgstr "重载远程 Nginx 错误"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "重载远程 Nginx 成功"
 msgstr "重载远程 Nginx 成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "重载请求失败,请检查网络连接"
 msgstr "重载请求失败,请检查网络连接"
 
 
@@ -4220,7 +4236,7 @@ msgstr "响应"
 msgid "Restart"
 msgid "Restart"
 msgstr "重启"
 msgstr "重启"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4242,7 +4258,7 @@ msgstr "重启远程 Nginx 错误"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "重启远程 Nginx 成功"
 msgstr "重启远程 Nginx 成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "重启请求失败,请检查网络连接"
 msgstr "重启请求失败,请检查网络连接"
 
 
@@ -4530,7 +4546,7 @@ msgstr "扫描结果"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "用手机扫描二维码,将账户添加到应用程序中。"
 msgstr "用手机扫描二维码,将账户添加到应用程序中。"
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "正在扫描日志..."
 msgstr "正在扫描日志..."
 
 
@@ -4547,8 +4563,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "搜索"
 msgstr "搜索"
 
 
@@ -4603,6 +4619,10 @@ msgstr "自检失败,Nginx UI 可能无法正常工作"
 msgid "Send"
 msgid "Send"
 msgstr "上传"
 msgstr "上传"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "发送测试消息"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "服务器"
 msgstr "服务器"
@@ -4832,8 +4852,8 @@ msgstr "静态"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "状态"
 msgstr "状态"
 
 
@@ -5001,15 +5021,21 @@ msgstr "同步配置错误"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "同步配置成功"
 msgstr "同步配置成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同步节点"
 msgstr "同步节点"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "同步预览"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "同步策略"
 msgstr "同步策略"
 
 
@@ -5017,8 +5043,8 @@ msgstr "同步策略"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "同步到"
 msgstr "同步到"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "同步"
 msgstr "同步"
 
 
@@ -5067,11 +5093,12 @@ msgstr "终端"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "终端启动命令"
 msgstr "终端启动命令"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "测试"
 msgstr "测试"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "测试消息发送成功"
 msgstr "测试消息发送成功"
 
 
@@ -5409,7 +5436,7 @@ msgstr "需要两步验证"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5445,11 +5472,11 @@ msgstr "更新成功"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "修改时间"
 msgstr "修改时间"
@@ -5570,7 +5597,7 @@ msgstr "验证系统要求"
 msgid "Version"
 msgid "Version"
 msgstr "版本"
 msgstr "版本"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "查看"
 msgstr "查看"
@@ -5655,8 +5682,8 @@ msgid ""
 "Pebble as CA."
 "Pebble as CA."
 msgstr "启用后,Nginx UI 将在启动时自动重新注册用户。一般情况下,除非在开发环境中使用 Pebble 作为 CA,否则不要启用此功能。"
 msgstr "启用后,Nginx UI 将在启动时自动重新注册用户。一般情况下,除非在开发环境中使用 Pebble 作为 CA,否则不要启用此功能。"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5717,8 +5744,8 @@ msgstr "正在将证书私钥写入磁盘"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "正在将证书写入磁盘"
 msgstr "正在将证书写入磁盘"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 100 - 73
app/src/language/zh_TW/app.po

@@ -103,6 +103,10 @@ msgstr "[Nginx UI] 正在將證書私鑰寫入磁碟"
 msgid "[Nginx UI] Writing certificate to disk"
 msgid "[Nginx UI] Writing certificate to disk"
 msgstr "[Nginx UI] 正在將憑證寫入磁碟"
 msgstr "[Nginx UI] 正在將憑證寫入磁碟"
 
 
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:59
+msgid "* Includes nodes from group \"%{groupName}\" and manually selected nodes"
+msgstr "* 包含來自群組 \"%{groupName}\" 的節點和手動選擇的節點"
+
 #: src/views/user/userColumns.tsx:30
 #: src/views/user/userColumns.tsx:30
 msgid "2FA"
 msgid "2FA"
 msgstr "雙因素驗證"
 msgstr "雙因素驗證"
@@ -115,7 +119,7 @@ msgstr "多重要素驗證設定"
 msgid "About"
 msgid "About"
 msgstr "關於"
 msgstr "關於"
 
 
-#: src/views/nginx_log/NginxLogList.vue:38
+#: src/views/nginx_log/NginxLogList.vue:39
 msgid "Access Log"
 msgid "Access Log"
 msgstr "存取日誌"
 msgstr "存取日誌"
 
 
@@ -142,12 +146,12 @@ msgstr "操作"
 #: 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:44
 #: src/views/config/configColumns.tsx:50
 #: src/views/config/configColumns.tsx:50
-#: src/views/environments/group/columns.ts:41
+#: src/views/environments/group/columns.ts:71
 #: src/views/environments/list/envColumns.tsx:96
 #: src/views/environments/list/envColumns.tsx:96
-#: src/views/nginx_log/NginxLogList.vue:67
+#: 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:153 src/views/stream/columns.tsx:117
+#: src/views/site/site_list/columns.tsx:159 src/views/stream/columns.tsx:123
 #: src/views/user/userColumns.tsx:58
 #: src/views/user/userColumns.tsx:58
 msgid "Actions"
 msgid "Actions"
 msgstr "操作"
 msgstr "操作"
@@ -226,7 +230,7 @@ msgstr "進階模式"
 msgid "Afterwards, refresh this page and click add passkey again."
 msgid "Afterwards, refresh this page and click add passkey again."
 msgstr "之後,請重新整理此頁面並再次點擊新增通行金鑰。"
 msgstr "之後,請重新整理此頁面並再次點擊新增通行金鑰。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:141
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:83
 msgid "All"
 msgid "All"
 msgstr "全部"
 msgstr "全部"
 
 
@@ -303,7 +307,7 @@ msgstr "確定要永久刪除嗎?"
 msgid "Are you sure you want to delete?"
 msgid "Are you sure you want to delete?"
 msgstr "您確定要刪除嗎?"
 msgstr "您確定要刪除嗎?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:155
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:97
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgid "Are you sure you want to reload Nginx on the following sync nodes?"
 msgstr "您確定要在以下同步節點上重新載入 Nginx 嗎?"
 msgstr "您確定要在以下同步節點上重新載入 Nginx 嗎?"
 
 
@@ -319,7 +323,7 @@ msgstr "您確定要刪除此項目嗎?"
 msgid "Are you sure you want to remove this location?"
 msgid "Are you sure you want to remove this location?"
 msgstr "您確定要刪除此 Location 嗎?"
 msgstr "您確定要刪除此 Location 嗎?"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:167
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:109
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgid "Are you sure you want to restart Nginx on the following sync nodes?"
 msgstr "您確定要在以下同步節點上重新啟動 Nginx 嗎?"
 msgstr "您確定要在以下同步節點上重新啟動 Nginx 嗎?"
 
 
@@ -1146,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:29
+#: src/views/environments/group/columns.ts:59
 #: 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 +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:139 src/views/stream/columns.tsx:106
+#: src/views/site/site_list/columns.tsx:145 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"
@@ -1756,8 +1760,8 @@ 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:135 src/views/stream/columns.tsx:102
-#: src/views/stream/components/RightPanel/Basic.vue:23
+#: src/views/site/site_list/columns.tsx:141 src/views/stream/columns.tsx:108
+#: 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
 msgid "Enabled"
 msgid "Enabled"
@@ -1802,7 +1806,7 @@ msgid "Environment variables cleaned"
 msgstr "環境變數已清理"
 msgstr "環境變數已清理"
 
 
 #: src/routes/modules/environments.ts:11
 #: src/routes/modules/environments.ts:11
-#: src/views/dashboard/Environments.vue:75
+#: src/views/dashboard/Environments.vue:80
 #: src/views/environments/list/Environment.vue:131
 #: src/views/environments/list/Environment.vue:131
 msgid "Environments"
 msgid "Environments"
 msgstr "環境"
 msgstr "環境"
@@ -1816,7 +1820,7 @@ msgstr "錯誤"
 msgid "Error initializing diff viewer"
 msgid "Error initializing diff viewer"
 msgstr "初始化差異檢視器時發生錯誤"
 msgstr "初始化差異檢視器時發生錯誤"
 
 
-#: src/views/nginx_log/NginxLogList.vue:42
+#: src/views/nginx_log/NginxLogList.vue:43
 msgid "Error Log"
 msgid "Error Log"
 msgstr "錯誤日誌"
 msgstr "錯誤日誌"
 
 
@@ -1875,7 +1879,7 @@ msgid "External Notification Test"
 msgstr "外部通知測試"
 msgstr "外部通知測試"
 
 
 #: src/views/preference/Preference.vue:58
 #: src/views/preference/Preference.vue:58
-#: src/views/preference/tabs/ExternalNotify.vue:31
+#: src/views/preference/tabs/ExternalNotify.vue:36
 msgid "External Notify"
 msgid "External Notify"
 msgstr "外部通知"
 msgstr "外部通知"
 
 
@@ -2206,7 +2210,7 @@ msgstr "撤銷憑證失敗: %{error}"
 msgid "Failed to save Nginx performance settings"
 msgid "Failed to save Nginx performance settings"
 msgstr "儲存 Nginx 效能設定失敗"
 msgstr "儲存 Nginx 效能設定失敗"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:21
+#: src/views/preference/tabs/ExternalNotify.vue:26
 msgid "Failed to send test message"
 msgid "Failed to send test message"
 msgstr "發送測試消息失敗"
 msgstr "發送測試消息失敗"
 
 
@@ -2791,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:84
+#: src/components/NodeSelector/NodeSelector.vue:61
 #: 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
@@ -2824,7 +2828,7 @@ msgstr ""
 "日誌文件 %{log_path} 不是常規文件。如果您在 docker 容器中使用 nginx-ui,請參考 "
 "日誌文件 %{log_path} 不是常規文件。如果您在 docker 容器中使用 nginx-ui,請參考 "
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html 獲取更多信息。"
 "https://nginxui.com/zh_CN/guide/config-nginx-log.html 獲取更多信息。"
 
 
-#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:87
+#: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
 msgid "Log List"
 msgstr "日誌列表"
 msgstr "日誌列表"
 
 
@@ -2859,7 +2863,7 @@ 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:143
+#: src/views/site/site_list/columns.tsx:149
 msgid "Maintenance"
 msgid "Maintenance"
 msgstr "維護"
 msgstr "維護"
 
 
@@ -3064,22 +3068,22 @@ msgstr "多行指令"
 #: 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:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:8
 #: src/views/environments/list/envColumns.tsx:8
-#: src/views/nginx_log/NginxLogList.vue:51
+#: src/views/nginx_log/NginxLogList.vue:52
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
 #: src/views/preference/components/AuthSettings/AddPasskey.vue:80
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:35
-#: src/views/site/site_list/columns.tsx:29
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:36
+#: src/views/site/site_list/columns.tsx:30
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
-#: src/views/stream/columns.tsx:25
-#: src/views/stream/components/RightPanel/Basic.vue:30
+#: src/views/stream/columns.tsx:26
+#: src/views/stream/components/RightPanel/Basic.vue:31
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:145
 #: src/views/stream/StreamList.vue:145
 msgid "Name"
 msgid "Name"
 msgstr "名稱"
 msgstr "名稱"
 
 
 #: src/views/config/configColumns.tsx:10
 #: src/views/config/configColumns.tsx:10
-#: src/views/site/site_list/columns.tsx:21 src/views/stream/columns.tsx:17
+#: src/views/site/site_list/columns.tsx:22 src/views/stream/columns.tsx:18
 msgid "Name or content"
 msgid "Name or content"
 msgstr "名稱或內容"
 msgstr "名稱或內容"
 
 
@@ -3339,8 +3343,8 @@ msgid "Nginx.conf includes streams-enabled directory"
 msgstr "Nginx.conf 包含 streams-enabled 目錄"
 msgstr "Nginx.conf 包含 streams-enabled 目錄"
 
 
 #: src/components/ChatGPT/ChatMessageInput.vue:17
 #: src/components/ChatGPT/ChatMessageInput.vue:17
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:157
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:169
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:111
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:99
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/NgxConfigEditor/LocationEditor.vue:89
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
 #: src/components/Notification/Notification.vue:108 src/language/curd.ts:40
@@ -3352,7 +3356,8 @@ msgstr "Nginx.conf 包含 streams-enabled 目錄"
 msgid "No"
 msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
-#: src/views/environments/group/columns.ts:19
+#: src/components/EnvGroupRender/EnvGroupRender.vue:41
+#: src/views/environments/group/columns.ts:49
 #: src/views/environments/group/EnvGroup.vue:47
 #: src/views/environments/group/EnvGroup.vue:47
 msgid "No Action"
 msgid "No Action"
 msgstr "無行動"
 msgstr "無行動"
@@ -3361,6 +3366,10 @@ msgstr "無行動"
 msgid "No data"
 msgid "No data"
 msgstr "無數據"
 msgstr "無數據"
 
 
+#: src/components/EnvGroupRender/EnvGroupRender.vue:55
+msgid "No nodes selected"
+msgstr "未選擇節點"
+
 #: src/components/ConfigHistory/DiffViewer.vue:47
 #: src/components/ConfigHistory/DiffViewer.vue:47
 msgid "No records selected"
 msgid "No records selected"
 msgstr "未選取任何記錄"
 msgstr "未選取任何記錄"
@@ -3377,9 +3386,9 @@ msgstr "未配置上游"
 msgid "Node"
 msgid "Node"
 msgstr "節點"
 msgstr "節點"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:41
-#: src/views/site/site_list/columns.tsx:88 src/views/stream/columns.tsx:56
-#: src/views/stream/components/RightPanel/Basic.vue:38
+#: 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/stream/components/RightPanel/Basic.vue:39
 msgid "Node Group"
 msgid "Node Group"
 msgstr "節點群組"
 msgstr "節點群組"
 
 
@@ -3422,8 +3431,8 @@ msgstr "此前無效:%{date}"
 msgid "Note"
 msgid "Note"
 msgstr "備註"
 msgstr "備註"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:65
-#: src/views/stream/components/RightPanel/Basic.vue:60
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:66
+#: src/views/stream/components/RightPanel/Basic.vue:61
 msgid ""
 msgid ""
 "Note, if the configuration file include other configurations or "
 "Note, if the configuration file include other configurations or "
 "certificates, please synchronize them to the remote nodes in advance."
 "certificates, please synchronize them to the remote nodes in advance."
@@ -3492,11 +3501,11 @@ msgstr "關"
 msgid "Official Document"
 msgid "Official Document"
 msgstr "官方文件"
 msgstr "官方文件"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
 #: src/components/NgxConfigEditor/NgxUpstream.vue:151
-#: src/components/NodeSelector/NodeSelector.vue:107
-#: src/components/ProxyTargets/ProxyTargets.vue:29
-#: src/views/dashboard/Environments.vue:101
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:84
+#: src/views/dashboard/Environments.vue:106
 #: src/views/environments/list/envColumns.tsx:55
 #: src/views/environments/list/envColumns.tsx:55
 msgid "Offline"
 msgid "Offline"
 msgstr "離線"
 msgstr "離線"
@@ -3526,10 +3535,11 @@ msgstr "開啟"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "驗證完成後,記錄將被刪除。"
 msgstr "驗證完成後,記錄將被刪除。"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:185
-#: src/components/NodeSelector/NodeSelector.vue:101
-#: src/components/NodeSelector/NodeSelector.vue:87
-#: src/views/dashboard/Environments.vue:94
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:127
+#: src/components/NodeCard/NodeCard.vue:51
+#: src/components/NodeSelector/NodeSelector.vue:64
+#: src/components/NodeSelector/NodeSelector.vue:78
+#: src/views/dashboard/Environments.vue:99
 #: src/views/environments/list/envColumns.tsx:51
 #: src/views/environments/list/envColumns.tsx:51
 msgid "Online"
 msgid "Online"
 msgstr "線上"
 msgstr "線上"
@@ -3651,7 +3661,7 @@ msgstr "密碼不匹配"
 #: src/language/curd.ts:61
 #: src/language/curd.ts:61
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/ConfigRightPanel/Basic.vue:41
 #: src/views/config/components/Delete.vue:124
 #: src/views/config/components/Delete.vue:124
-#: src/views/nginx_log/NginxLogList.vue:59
+#: src/views/nginx_log/NginxLogList.vue:60
 msgid "Path"
 msgid "Path"
 msgstr "路徑"
 msgstr "路徑"
 
 
@@ -3822,6 +3832,10 @@ msgstr "請儲存此安全令牌,您將需要它進行恢復:"
 msgid "Please select a backup file"
 msgid "Please select a backup file"
 msgstr "請選擇備份檔案"
 msgstr "請選擇備份檔案"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:41
+msgid "Please select a notification type"
+msgstr "請選擇通知類型"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 #: src/views/certificate/components/CertificateFileUpload.vue:45
 msgid "Please select a valid %{type} file (%{extensions})"
 msgid "Please select a valid %{type} file (%{extensions})"
 msgstr "請選擇有效的%{type}檔案(%{extensions})"
 msgstr "請選擇有效的%{type}檔案(%{extensions})"
@@ -3862,7 +3876,8 @@ msgstr "監聽埠"
 msgid "Port Scanner"
 msgid "Port Scanner"
 msgstr "端口掃描器"
 msgstr "端口掃描器"
 
 
-#: src/views/environments/group/columns.ts:15
+#: src/components/EnvGroupRender/EnvGroupRender.vue:38
+#: src/views/environments/group/columns.ts:45
 #: src/views/environments/group/EnvGroup.vue:39
 #: src/views/environments/group/EnvGroup.vue:39
 msgid "Post-sync Action"
 msgid "Post-sync Action"
 msgstr "同步後動作"
 msgstr "同步後動作"
@@ -3941,7 +3956,7 @@ msgstr "代理伺服器"
 msgid "Proxy Pass"
 msgid "Proxy Pass"
 msgstr "代理傳遞"
 msgstr "代理傳遞"
 
 
-#: src/views/site/site_list/columns.tsx:76 src/views/stream/columns.tsx:44
+#: src/views/site/site_list/columns.tsx:78 src/views/stream/columns.tsx:46
 msgid "Proxy Targets"
 msgid "Proxy Targets"
 msgstr "代理目標"
 msgstr "代理目標"
 
 
@@ -4041,8 +4056,9 @@ msgstr "發行公告"
 msgid "Reload"
 msgid "Reload"
 msgstr "重新載入"
 msgstr "重新載入"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:162
-#: src/views/environments/group/columns.ts:22
+#: 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/views/environments/group/EnvGroup.vue:50
 #: 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
@@ -4069,7 +4085,7 @@ msgstr "重新載入遠端 Nginx 錯誤"
 msgid "Reload Remote Nginx Success"
 msgid "Reload Remote Nginx Success"
 msgstr "遠端 Nginx 重新載入成功"
 msgstr "遠端 Nginx 重新載入成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:52
 msgid "Reload request failed, please check your network connection"
 msgid "Reload request failed, please check your network connection"
 msgstr "重新載入請求失敗,請檢查您的網路連線"
 msgstr "重新載入請求失敗,請檢查您的網路連線"
 
 
@@ -4226,7 +4242,7 @@ msgstr "回應"
 msgid "Restart"
 msgid "Restart"
 msgstr "重新啟動"
 msgstr "重新啟動"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:174
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:116
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:230
 #: src/views/environments/list/Environment.vue:238
 #: src/views/environments/list/Environment.vue:238
 msgid "Restart Nginx"
 msgid "Restart Nginx"
@@ -4248,7 +4264,7 @@ msgstr "遠端 Nginx 重啟錯誤"
 msgid "Restart Remote Nginx Success"
 msgid "Restart Remote Nginx Success"
 msgstr "遠端 Nginx 重啟成功"
 msgstr "遠端 Nginx 重啟成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:130
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:72
 msgid "Restart request failed, please check your network connection"
 msgid "Restart request failed, please check your network connection"
 msgstr "重新啟動請求失敗,請檢查您的網路連線"
 msgstr "重新啟動請求失敗,請檢查您的網路連線"
 
 
@@ -4536,7 +4552,7 @@ msgstr "掃描結果"
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgid "Scan the QR code with your mobile phone to add the account to the app."
 msgstr "用手機掃描二維碼將賬戶新增到應用程式中。"
 msgstr "用手機掃描二維碼將賬戶新增到應用程式中。"
 
 
-#: src/views/nginx_log/NginxLogList.vue:100
+#: src/views/nginx_log/NginxLogList.vue:101
 msgid "Scanning logs..."
 msgid "Scanning logs..."
 msgstr "正在掃描日誌..."
 msgstr "正在掃描日誌..."
 
 
@@ -4553,8 +4569,8 @@ msgid "SDK"
 msgstr "SDK"
 msgstr "SDK"
 
 
 #: src/language/constants.ts:62 src/language/curd.ts:12
 #: src/language/constants.ts:62 src/language/curd.ts:12
-#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:16
-#: src/views/stream/columns.tsx:12
+#: src/views/config/configColumns.tsx:5 src/views/site/site_list/columns.tsx:17
+#: src/views/stream/columns.tsx:13
 msgid "Search"
 msgid "Search"
 msgstr "搜尋"
 msgstr "搜尋"
 
 
@@ -4609,6 +4625,10 @@ msgstr "自我檢查失敗,Nginx UI 可能無法正常運作"
 msgid "Send"
 msgid "Send"
 msgstr "傳送"
 msgstr "傳送"
 
 
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:77
+msgid "Send test message"
+msgstr "發送測試訊息"
+
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 #: src/routes/modules/dashboard.ts:19 src/views/preference/Preference.vue:46
 msgid "Server"
 msgid "Server"
 msgstr "伺服器"
 msgstr "伺服器"
@@ -4838,8 +4858,8 @@ msgstr "靜態"
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: src/views/certificate/CertificateList/certColumns.tsx:63
 #: 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:28
-#: src/views/site/site_list/columns.tsx:113 src/views/stream/columns.tsx:81
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:29
+#: src/views/site/site_list/columns.tsx:119 src/views/stream/columns.tsx:87
 msgid "Status"
 msgid "Status"
 msgstr "狀態"
 msgstr "狀態"
 
 
@@ -5007,15 +5027,21 @@ msgstr "同步設定錯誤"
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "同步設定成功"
 msgstr "同步設定成功"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:148
+#: src/components/EnvGroupRender/EnvGroupRender.vue:53
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:90
+#: src/views/environments/group/columns.ts:16
 #: src/views/environments/group/EnvGroup.vue:31
 #: src/views/environments/group/EnvGroup.vue:31
 msgid "Sync Nodes"
 msgid "Sync Nodes"
 msgstr "同步節點"
 msgstr "同步節點"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:58
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:71
-#: src/views/stream/components/RightPanel/Basic.vue:53
-#: src/views/stream/components/RightPanel/Basic.vue:66
+#: src/components/SyncNodesPreview/SyncNodesPreview.vue:45
+msgid "Sync Preview"
+msgstr "同步預覽"
+
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:59
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:72
+#: src/views/stream/components/RightPanel/Basic.vue:54
+#: src/views/stream/components/RightPanel/Basic.vue:67
 msgid "Sync strategy"
 msgid "Sync strategy"
 msgstr "同步策略"
 msgstr "同步策略"
 
 
@@ -5023,8 +5049,8 @@ msgstr "同步策略"
 msgid "Sync to"
 msgid "Sync to"
 msgstr "同步到"
 msgstr "同步到"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:56
-#: src/views/stream/components/RightPanel/Basic.vue:51
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:57
+#: src/views/stream/components/RightPanel/Basic.vue:52
 msgid "Synchronization"
 msgid "Synchronization"
 msgstr "同步"
 msgstr "同步"
 
 
@@ -5073,11 +5099,12 @@ msgstr "終端"
 msgid "Terminal Start Command"
 msgid "Terminal Start Command"
 msgstr "終端機啟動指令"
 msgstr "終端機啟動指令"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:46
+#: src/views/preference/tabs/ExternalNotify.vue:51
 msgid "Test"
 msgid "Test"
 msgstr "測試"
 msgstr "測試"
 
 
-#: src/views/preference/tabs/ExternalNotify.vue:17
+#: src/views/preference/components/ExternalNotify/ExternalNotifyEditor.vue:52
+#: src/views/preference/tabs/ExternalNotify.vue:22
 msgid "Test message sent successfully"
 msgid "Test message sent successfully"
 msgstr "測試訊息發送成功"
 msgstr "測試訊息發送成功"
 
 
@@ -5415,7 +5442,7 @@ msgstr "需要多重因素驗證"
 #: 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
-#: src/views/nginx_log/NginxLogList.vue:27
+#: src/views/nginx_log/NginxLogList.vue:28
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/notification/notificationColumns.tsx:8
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 #: src/views/preference/components/ExternalNotify/columns.tsx:18
 msgid "Type"
 msgid "Type"
@@ -5451,11 +5478,11 @@ msgstr "更新成功"
 #: src/views/certificate/DNSCredential.vue:38
 #: src/views/certificate/DNSCredential.vue:38
 #: 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:35
+#: src/views/environments/group/columns.ts:65
 #: src/views/environments/list/envColumns.tsx:89
 #: src/views/environments/list/envColumns.tsx:89
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:38
-#: src/views/site/site_list/columns.tsx:106 src/views/stream/columns.tsx:74
-#: src/views/stream/components/RightPanel/Basic.vue:34
+#: 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/stream/components/RightPanel/Basic.vue:35
 #: src/views/user/userColumns.tsx:52
 #: src/views/user/userColumns.tsx:52
 msgid "Updated at"
 msgid "Updated at"
 msgstr "更新時間"
 msgstr "更新時間"
@@ -5576,7 +5603,7 @@ msgstr "驗證系統要求"
 msgid "Version"
 msgid "Version"
 msgstr "版本"
 msgstr "版本"
 
 
-#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:105
+#: src/language/curd.ts:7 src/views/nginx_log/NginxLogList.vue:106
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 #: src/views/site/site_edit/components/ConfigTemplate/ConfigTemplate.vue:83
 msgid "View"
 msgid "View"
 msgstr "檢視"
 msgstr "檢視"
@@ -5661,8 +5688,8 @@ msgid ""
 "Pebble as CA."
 "Pebble as CA."
 msgstr "啟用後,Nginx UI 將在啟動時自動重新註冊使用者。通常,除非您處於開發環境並使用 Pebble 作為 CA,否則不建議啟用此功能。"
 msgstr "啟用後,Nginx UI 將在啟動時自動重新註冊使用者。通常,除非您處於開發環境並使用 Pebble 作為 CA,否則不建議啟用此功能。"
 
 
-#: src/views/site/site_edit/components/RightPanel/Basic.vue:61
-#: src/views/stream/components/RightPanel/Basic.vue:56
+#: src/views/site/site_edit/components/RightPanel/Basic.vue:62
+#: src/views/stream/components/RightPanel/Basic.vue:57
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "When you enable/disable, delete, or save this site, the nodes set in the "
 "Node Group and the nodes selected below will be synchronized."
 "Node Group and the nodes selected below will be synchronized."
@@ -5723,8 +5750,8 @@ msgstr "將憑證私鑰寫入磁碟"
 msgid "Writing certificate to disk"
 msgid "Writing certificate to disk"
 msgstr "將憑證寫入磁碟"
 msgstr "將憑證寫入磁碟"
 
 
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
-#: src/components/EnvGroupTabs/EnvGroupTabs.vue:168
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:110
+#: src/components/EnvGroupTabs/EnvGroupTabs.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue:98
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/components/NgxConfigEditor/LocationEditor.vue:88
 #: src/views/preference/tabs/AuthSettings.vue:131
 #: src/views/preference/tabs/AuthSettings.vue:131

+ 5 - 1
app/src/lib/http/interceptors.ts

@@ -34,7 +34,11 @@ async function encryptJsonData(data: any): Promise<string> {
 
 
 // Helper function for handling encrypted form data
 // Helper function for handling encrypted form data
 async function handleEncryptedFormData(formData: FormData): Promise<FormData> {
 async function handleEncryptedFormData(formData: FormData): Promise<FormData> {
-  const cryptoParams = await http.get('/crypto/public_key')
+  const fingerprint = await getBrowserFingerprint()
+  const cryptoParams = await http.post('/crypto/public_key', {
+    timestamp: dayjs().unix(),
+    fingerprint,
+  })
   const { public_key } = await cryptoParams
   const { public_key } = await cryptoParams
 
 
   // Extract form parameters that are not files
   // Extract form parameters that are not files