Browse Source

feat(env_group): add post-sync action to environment and stream configurations #725

Jacky 3 months ago
parent
commit
94fcbf6362

+ 6 - 4
api/cluster/group.go

@@ -54,8 +54,9 @@ func RestartNginx(c *gin.Context) {
 func AddGroup(c *gin.Context) {
 func AddGroup(c *gin.Context) {
 	cosy.Core[model.EnvGroup](c).
 	cosy.Core[model.EnvGroup](c).
 		SetValidRules(gin.H{
 		SetValidRules(gin.H{
-			"name":          "required",
-			"sync_node_ids": "omitempty",
+			"name":             "required",
+			"sync_node_ids":    "omitempty",
+			"post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
 		}).
 		}).
 		Create()
 		Create()
 }
 }
@@ -63,8 +64,9 @@ func AddGroup(c *gin.Context) {
 func ModifyGroup(c *gin.Context) {
 func ModifyGroup(c *gin.Context) {
 	cosy.Core[model.EnvGroup](c).
 	cosy.Core[model.EnvGroup](c).
 		SetValidRules(gin.H{
 		SetValidRules(gin.H{
-			"name":          "required",
-			"sync_node_ids": "omitempty",
+			"name":             "required",
+			"sync_node_ids":    "omitempty",
+			"post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx,
 		}).
 		}).
 		Modify()
 		Modify()
 }
 }

+ 2 - 1
api/sites/site.go

@@ -118,13 +118,14 @@ func SaveSite(c *gin.Context) {
 		EnvGroupID  uint64   `json:"env_group_id"`
 		EnvGroupID  uint64   `json:"env_group_id"`
 		SyncNodeIDs []uint64 `json:"sync_node_ids"`
 		SyncNodeIDs []uint64 `json:"sync_node_ids"`
 		Overwrite   bool     `json:"overwrite"`
 		Overwrite   bool     `json:"overwrite"`
+		PostAction  string   `json:"post_action"`
 	}
 	}
 
 
 	if !cosy.BindAndValid(c, &json) {
 	if !cosy.BindAndValid(c, &json) {
 		return
 		return
 	}
 	}
 
 
-	err := site.Save(name, json.Content, json.Overwrite, json.EnvGroupID, json.SyncNodeIDs)
+	err := site.Save(name, json.Content, json.Overwrite, json.EnvGroupID, json.SyncNodeIDs, json.PostAction)
 	if err != nil {
 	if err != nil {
 		cosy.ErrHandler(c, err)
 		cosy.ErrHandler(c, err)
 		return
 		return

+ 9 - 8
api/streams/streams.go

@@ -60,7 +60,7 @@ func GetStreams(c *gin.Context) {
 
 
 	var configs []config.Config
 	var configs []config.Config
 
 
-	// Get all streams map for environment group lookup
+	// Get all streams map for Node Group lookup
 	s := query.Stream
 	s := query.Stream
 	var streams []*model.Stream
 	var streams []*model.Stream
 	if queryEnvGroupId != 0 {
 	if queryEnvGroupId != 0 {
@@ -73,21 +73,21 @@ func GetStreams(c *gin.Context) {
 		return
 		return
 	}
 	}
 
 
-	// Retrieve environment groups data
+	// Retrieve Node Groups data
 	eg := query.EnvGroup
 	eg := query.EnvGroup
 	envGroups, err := eg.Find()
 	envGroups, err := eg.Find()
 	if err != nil {
 	if err != nil {
 		cosy.ErrHandler(c, err)
 		cosy.ErrHandler(c, err)
 		return
 		return
 	}
 	}
-	// Create a map of environment groups for quick lookup by ID
+	// Create a map of Node Groups for quick lookup by ID
 	envGroupMap := lo.SliceToMap(envGroups, func(item *model.EnvGroup) (uint64, *model.EnvGroup) {
 	envGroupMap := lo.SliceToMap(envGroups, func(item *model.EnvGroup) (uint64, *model.EnvGroup) {
 		return item.ID, item
 		return item.ID, item
 	})
 	})
 
 
 	// Convert streams slice to map for efficient lookups
 	// Convert streams slice to map for efficient lookups
 	streamsMap := lo.SliceToMap(streams, func(item *model.Stream) (string, *model.Stream) {
 	streamsMap := lo.SliceToMap(streams, func(item *model.Stream) (string, *model.Stream) {
-		// Associate each stream with its corresponding environment group
+		// Associate each stream with its corresponding Node Group
 		if item.EnvGroupID > 0 {
 		if item.EnvGroupID > 0 {
 			item.EnvGroup = envGroupMap[item.EnvGroupID]
 			item.EnvGroup = envGroupMap[item.EnvGroupID]
 		}
 		}
@@ -121,13 +121,13 @@ func GetStreams(c *gin.Context) {
 			envGroup   *model.EnvGroup
 			envGroup   *model.EnvGroup
 		)
 		)
 
 
-		// Lookup stream in the streams map to get environment group info
+		// Lookup stream in the streams map to get Node Group info
 		if stream, ok := streamsMap[file.Name()]; ok {
 		if stream, ok := streamsMap[file.Name()]; ok {
 			envGroupId = stream.EnvGroupID
 			envGroupId = stream.EnvGroupID
 			envGroup = stream.EnvGroup
 			envGroup = stream.EnvGroup
 		}
 		}
 
 
-		// Apply environment group filter if specified
+		// Apply Node Group filter if specified
 		if queryEnvGroupId != 0 && envGroupId != queryEnvGroupId {
 		if queryEnvGroupId != 0 && envGroupId != queryEnvGroupId {
 			continue
 			continue
 		}
 		}
@@ -245,6 +245,7 @@ func SaveStream(c *gin.Context) {
 		EnvGroupID  uint64   `json:"env_group_id"`
 		EnvGroupID  uint64   `json:"env_group_id"`
 		SyncNodeIDs []uint64 `json:"sync_node_ids"`
 		SyncNodeIDs []uint64 `json:"sync_node_ids"`
 		Overwrite   bool     `json:"overwrite"`
 		Overwrite   bool     `json:"overwrite"`
+		PostAction  string   `json:"post_action"`
 	}
 	}
 
 
 	// Validate input JSON
 	// Validate input JSON
@@ -261,7 +262,7 @@ func SaveStream(c *gin.Context) {
 		return
 		return
 	}
 	}
 
 
-	// Update environment group ID if provided
+	// Update Node Group ID if provided
 	if json.EnvGroupID > 0 {
 	if json.EnvGroupID > 0 {
 		streamModel.EnvGroupID = json.EnvGroupID
 		streamModel.EnvGroupID = json.EnvGroupID
 	}
 	}
@@ -279,7 +280,7 @@ func SaveStream(c *gin.Context) {
 	}
 	}
 
 
 	// Save the stream configuration file
 	// Save the stream configuration file
-	err = stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs)
+	err = stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs, json.PostAction)
 	if err != nil {
 	if err != nil {
 		cosy.ErrHandler(c, err)
 		cosy.ErrHandler(c, err)
 		return
 		return

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

@@ -1,11 +1,16 @@
 import type { ModelBase } from '@/api/curd'
 import type { ModelBase } from '@/api/curd'
 import Curd from '@/api/curd'
 import Curd from '@/api/curd'
 
 
+// Post-sync action types
+export const PostSyncAction = {
+  None: 'none',
+  ReloadNginx: 'reload_nginx',
+}
+
 export interface EnvGroup extends ModelBase {
 export interface EnvGroup extends ModelBase {
   name: string
   name: string
   sync_node_ids: number[]
   sync_node_ids: number[]
+  post_sync_action?: string
 }
 }
 
 
-const env_group = new Curd<EnvGroup>('env_groups')
-
-export default env_group
+export default new Curd<EnvGroup>('/env_groups')

+ 1 - 1
app/src/components/EnvGroupTabs/EnvGroupTabs.vue

@@ -68,7 +68,7 @@ function disconnectSSE() {
   }
   }
 }
 }
 
 
-// Get the current environment group data
+// Get the current Node Group data
 const currentEnvGroup = computed(() => {
 const currentEnvGroup = computed(() => {
   if (!modelValue.value || modelValue.value === 0)
   if (!modelValue.value || modelValue.value === 0)
     return null
     return null

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

@@ -43,7 +43,7 @@ msgstr "مستخدم ACME"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -642,7 +642,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1115,19 +1115,6 @@ msgstr "تم التفعيل بنجاح"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "تشفير الموقع باستخدام Let's Encrypt"
 msgstr "تشفير الموقع باستخدام Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "بيئة"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "البيئات"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "تم تنظيف متغيرات البيئة"
 msgstr "تم تنظيف متغيرات البيئة"
@@ -1536,10 +1523,6 @@ msgstr "جارٍ الحصول على الشهادة، يرجى الانتظار.
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "وكيل Github"
 msgstr "وكيل Github"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1964,7 +1947,7 @@ msgstr "توجيه متعدد الأسطر"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2162,11 +2145,31 @@ msgstr "خطأ في تحليل تكوين Nginx"
 msgid "No"
 msgid "No"
 msgstr "لا"
 msgstr "لا"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "إجراء"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "اسم العقدة"
 msgstr "اسم العقدة"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "بيئة"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "البيئات"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
 msgstr "اسم العقدة"
 msgstr "اسم العقدة"
@@ -2507,6 +2510,12 @@ msgstr "يرجى اختيار عقدة واحدة على الأقل للترقي
 msgid "Port"
 msgid "Port"
 msgstr "منفذ HTTP"
 msgstr "منفذ HTTP"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "إجراء"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2639,6 +2648,8 @@ msgid "Reload"
 msgstr "إعادة تحميل"
 msgstr "إعادة تحميل"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -2980,6 +2991,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "رمز 2FA أو الاسترداد غير صالح"
 msgstr "رمز 2FA أو الاسترداد غير صالح"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "المحدد"
 msgstr "المحدد"
@@ -3613,7 +3628,7 @@ msgstr "تم التحديث بنجاح"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3782,7 +3797,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "عند تفعيل/تعطيل، حذف، أو حفظ هذا الموقع، سيتم مزامنة العقد المحددة في فئة "
 "عند تفعيل/تعطيل، حذف، أو حفظ هذا الموقع، سيتم مزامنة العقد المحددة في فئة "
 "الموقع والعقد المحددة أدناه."
 "الموقع والعقد المحددة أدناه."
@@ -3791,7 +3806,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "عند تفعيل/تعطيل، حذف، أو حفظ هذا الموقع، سيتم مزامنة العقد المحددة في فئة "
 "عند تفعيل/تعطيل، حذف، أو حفظ هذا الموقع، سيتم مزامنة العقد المحددة في فئة "
 "الموقع والعقد المحددة أدناه."
 "الموقع والعقد المحددة أدناه."

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

@@ -40,7 +40,7 @@ msgstr "Benutzername"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -665,7 +665,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1162,19 +1162,6 @@ msgstr "Erfolgreich aktiviert"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Webseite mit Let's Encrypt verschlüsseln"
 msgstr "Webseite mit Let's Encrypt verschlüsseln"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Umgebung"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Kommentare"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "Umgebungsvariablen gesäubert"
 msgstr "Umgebungsvariablen gesäubert"
@@ -1588,10 +1575,6 @@ msgstr "Hole das Zertifikat, bitte warten..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -2039,7 +2022,7 @@ msgstr "Einzelne Anweisung"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2243,11 +2226,31 @@ msgstr "Name der Konfiguration"
 msgid "No"
 msgid "No"
 msgstr "Nein"
 msgstr "Nein"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Aktion"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Benuztername"
 msgstr "Benuztername"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Umgebung"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Kommentare"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2606,6 +2609,12 @@ msgstr "Bitte wähle mindestens einen Knoten zum Upgrade aus"
 msgid "Port"
 msgid "Port"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Aktionen"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2746,6 +2755,8 @@ msgid "Reload"
 msgstr "Neu laden"
 msgstr "Neu laden"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3106,6 +3117,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Ungültiger 2FA- oder Wiederherstellungscode"
 msgstr "Ungültiger 2FA- oder Wiederherstellungscode"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "Auswähler"
 msgstr "Auswähler"
@@ -3752,7 +3767,7 @@ msgstr "Speichern erfolgreich"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3930,7 +3945,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "Wenn du diese Seite aktivierst/deaktivierst, löschst oder speicherst, werden "
 "Wenn du diese Seite aktivierst/deaktivierst, löschst oder speicherst, werden "
 "die Knoten, die in der Seitenkategorie festgelegt sind, und die unten "
 "die Knoten, die in der Seitenkategorie festgelegt sind, und die unten "
@@ -3939,7 +3954,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "Wenn du diese Seite aktivierst/deaktivierst, löschst oder speicherst, werden "
 "Wenn du diese Seite aktivierst/deaktivierst, löschst oder speicherst, werden "
 "die Knoten, die in der Seitenkategorie festgelegt sind, und die unten "
 "die Knoten, die in der Seitenkategorie festgelegt sind, und die unten "

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

@@ -41,7 +41,7 @@ msgstr "Username"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -657,7 +657,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1148,19 +1148,6 @@ msgstr "Enabled successfully"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Encrypt website with Let's Encrypt"
 msgstr "Encrypt website with Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Comments"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Comments"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr ""
 msgstr ""
@@ -1575,10 +1562,6 @@ msgstr "Getting the certificate, please wait..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -2016,7 +1999,7 @@ msgstr "Single Directive"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2219,11 +2202,31 @@ msgstr "Configuration Name"
 msgid "No"
 msgid "No"
 msgstr "No"
 msgstr "No"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Action"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Username"
 msgstr "Username"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Comments"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Comments"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2559,6 +2562,12 @@ msgstr ""
 msgid "Port"
 msgid "Port"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Action"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2699,6 +2708,8 @@ msgid "Reload"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -3056,6 +3067,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Invalid E-mail!"
 msgstr "Invalid E-mail!"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #, fuzzy
 #, fuzzy
 msgid "Selector"
 msgid "Selector"
@@ -3681,7 +3696,7 @@ msgstr "Saved successfully"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3852,13 +3867,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

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

@@ -46,7 +46,7 @@ msgstr "Usuario ACME"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -641,7 +641,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1118,19 +1118,6 @@ msgstr "Habilitado con éxito"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Encriptar sitio web con Let's Encrypt"
 msgstr "Encriptar sitio web con Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Entorno"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Entornos"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "Variables de entorno limpiadas"
 msgstr "Variables de entorno limpiadas"
@@ -1537,10 +1524,6 @@ msgstr "Obteniendo el certificado, por favor espere..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Proxy Github"
 msgstr "Proxy Github"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1967,7 +1950,7 @@ msgstr "Directiva multilínea"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2168,11 +2151,31 @@ msgstr "Error de análisis de configuración de Nginx"
 msgid "No"
 msgid "No"
 msgstr "No"
 msgstr "No"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Acción"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Nuevo nombre"
 msgstr "Nuevo nombre"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Entorno"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Entornos"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2527,6 +2530,12 @@ msgstr "Seleccione al menos un nodo para actualizar"
 msgid "Port"
 msgid "Port"
 msgstr "Puerto HTTP"
 msgstr "Puerto HTTP"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Acción"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2664,6 +2673,8 @@ msgid "Reload"
 msgstr "Recargar"
 msgstr "Recargar"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3012,6 +3023,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Código 2FA o de recuperación inválido"
 msgstr "Código 2FA o de recuperación inválido"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "Seleccionador"
 msgstr "Seleccionador"
@@ -3655,7 +3670,7 @@ msgstr "Actualización exitosa"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3826,7 +3841,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "Cuando habilite/deshabilite, elimine o guarde este sitio, los nodos "
 "Cuando habilite/deshabilite, elimine o guarde este sitio, los nodos "
 "configurados en la categoría del sitio y los nodos seleccionados a "
 "configurados en la categoría del sitio y los nodos seleccionados a "
@@ -3836,7 +3851,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "Cuando habilite/deshabilite, elimine o guarde este sitio, los nodos "
 "Cuando habilite/deshabilite, elimine o guarde este sitio, los nodos "
 "configurados en la categoría del sitio y los nodos seleccionados a "
 "configurados en la categoría del sitio y los nodos seleccionados a "

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

@@ -45,7 +45,7 @@ msgstr "Nom d'utilisateur"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -669,7 +669,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1166,19 +1166,6 @@ msgstr "Activé avec succès"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Crypter le site Web avec Let's Encrypt"
 msgstr "Crypter le site Web avec Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Commentaires"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Commentaires"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 #, fuzzy
 #, fuzzy
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
@@ -1598,10 +1585,6 @@ msgstr "Obtention du certificat, veuillez patienter..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Proxy Github"
 msgstr "Proxy Github"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -2047,7 +2030,7 @@ msgstr "Directive multiligne"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2252,11 +2235,31 @@ msgstr "Erreur d'analyse de configuration Nginx"
 msgid "No"
 msgid "No"
 msgstr "Non"
 msgstr "Non"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Action"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Nom d'utilisateur"
 msgstr "Nom d'utilisateur"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Commentaires"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Commentaires"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2596,6 +2599,12 @@ msgstr ""
 msgid "Port"
 msgid "Port"
 msgstr "Port HTTP"
 msgstr "Port HTTP"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Action"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2738,6 +2747,8 @@ msgid "Reload"
 msgstr "Recharger"
 msgstr "Recharger"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3096,6 +3107,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Format de la requête invalide"
 msgstr "Format de la requête invalide"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "Sélecteur"
 msgstr "Sélecteur"
@@ -3729,7 +3744,7 @@ msgstr "Mis à jour avec succés"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3898,13 +3913,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

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

@@ -44,7 +44,7 @@ msgstr "ACME 사용자"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -638,7 +638,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1116,19 +1116,6 @@ msgstr "성공적으로 활성화됨"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Let's Encrypt로 웹사이트 암호화"
 msgstr "Let's Encrypt로 웹사이트 암호화"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "환경"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "환경"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 #, fuzzy
 #, fuzzy
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
@@ -1537,10 +1524,6 @@ msgstr "인증서를 가져오는 중입니다. 잠시 기다려 주세요..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Github 프록시"
 msgstr "Github 프록시"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1978,7 +1961,7 @@ msgstr "단일 지시문"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2183,11 +2166,31 @@ msgstr "Nginx 구성 오류름"
 msgid "No"
 msgid "No"
 msgstr "아니요"
 msgstr "아니요"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "작업"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "이름 변경"
 msgstr "이름 변경"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "환경"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "환경"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2527,6 +2530,12 @@ msgstr "적어도 하나의 노드를 선택해주세요!"
 msgid "Port"
 msgid "Port"
 msgstr "HTTP 포트"
 msgstr "HTTP 포트"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "작업"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2668,6 +2677,8 @@ msgid "Reload"
 msgstr "리로드"
 msgstr "리로드"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3027,6 +3038,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "선택"
 msgstr "선택"
@@ -3651,7 +3666,7 @@ msgstr "성공적으로 저장되었습니다"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3825,13 +3840,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

+ 34 - 21
app/src/language/messages.pot

@@ -33,7 +33,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -602,7 +602,7 @@ msgstr ""
 msgid "Create system backups including Nginx configuration and Nginx UI settings. Backup files will be automatically downloaded to your computer."
 msgid "Create system backups including Nginx configuration and Nginx UI settings. Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1056,17 +1056,6 @@ msgstr ""
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr ""
 msgstr ""
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-msgid "Environment Group"
-msgstr ""
-
-#: src/views/environments/group/EnvGroup.vue:10
-msgid "Environment Groups"
-msgstr ""
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr ""
 msgstr ""
@@ -1436,10 +1425,6 @@ msgstr ""
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1834,7 +1819,7 @@ msgstr ""
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7
 #: src/views/config/configColumns.tsx:7
 #: src/views/config/ConfigEditor.vue:256
 #: src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2024,10 +2009,27 @@ msgstr ""
 msgid "No"
 msgid "No"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+msgid "No Action"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 msgid "Node"
 msgid "Node"
 msgstr ""
 msgstr ""
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+msgid "Node Group"
+msgstr ""
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+msgid "Node Groups"
+msgstr ""
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
 msgstr ""
 msgstr ""
@@ -2336,6 +2338,11 @@ msgstr ""
 msgid "Port"
 msgid "Port"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+msgid "Post-sync Action"
+msgstr ""
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:194
@@ -2465,6 +2472,8 @@ msgid "Reload"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -2784,6 +2793,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr ""
 msgstr ""
@@ -3316,7 +3329,7 @@ msgstr ""
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34
 #: src/views/config/configColumns.tsx:34
 #: src/views/config/ConfigEditor.vue:276
 #: src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3468,11 +3481,11 @@ msgid "When Enabled, Nginx UI will automatically re-register users upon startup.
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
-msgid "When you enable/disable, delete, or save this site, the nodes set in the environment 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 ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
-msgid "When you enable/disable, delete, or save this stream, the nodes set in the environment group and the nodes selected below will be synchronized."
+msgid "When you enable/disable, delete, or save this stream, the nodes set in the Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

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

@@ -46,7 +46,7 @@ msgstr "Пользователь ACME"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -628,7 +628,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1102,19 +1102,6 @@ msgstr "Активировано успешно"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Использовать для сайта Let's Encrypt"
 msgstr "Использовать для сайта Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Окружение"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Окружения"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "Переменные окружения очищены"
 msgstr "Переменные окружения очищены"
@@ -1520,10 +1507,6 @@ msgstr "Получение сертификата, пожалуйста, под
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Прокси Github"
 msgstr "Прокси Github"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1947,7 +1930,7 @@ msgstr "Многострочная директива"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2147,11 +2130,31 @@ msgstr "Ошибка разбора конфигурации Nginx"
 msgid "No"
 msgid "No"
 msgstr "Нет"
 msgstr "Нет"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Действие"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Имя узла"
 msgstr "Имя узла"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Окружение"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Окружения"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
 msgstr "Имя узла"
 msgstr "Имя узла"
@@ -2497,6 +2500,12 @@ msgstr "Пожалуйста, выберите хотя бы один узел"
 msgid "Port"
 msgid "Port"
 msgstr "Порт HTTP"
 msgstr "Порт HTTP"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Действие"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2633,6 +2642,8 @@ msgid "Reload"
 msgstr "Перегрузить"
 msgstr "Перегрузить"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -2977,6 +2988,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Неверный код восстановления"
 msgstr "Неверный код восстановления"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "Выбор"
 msgstr "Выбор"
@@ -3611,7 +3626,7 @@ msgstr "Успешно обновлено"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3779,13 +3794,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

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

@@ -42,7 +42,7 @@ msgstr "ACME Kullanıcısı"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -634,7 +634,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1131,19 +1131,6 @@ msgstr "Başarıyla etkinleştirildi"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Let's Encrypt ile web sitesini şifreleyin"
 msgstr "Let's Encrypt ile web sitesini şifreleyin"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Ortam"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Ortamlar"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "Ortam değişkenleri temizlendi"
 msgstr "Ortam değişkenleri temizlendi"
@@ -1549,10 +1536,6 @@ msgstr "Sertifika alınıyor, lütfen bekleyin..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Github Proxy"
 msgstr "Github Proxy"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1994,7 +1977,7 @@ msgstr "Çok Hatlı Direktif"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2213,11 +2196,31 @@ msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 msgid "No"
 msgid "No"
 msgstr "Hayır"
 msgstr "Hayır"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Eylem"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Yeni Ad"
 msgstr "Yeni Ad"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Ortam"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Ortamlar"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2611,6 +2614,12 @@ msgstr "Lütfen yükseltmek için en az bir düğüm seçin"
 msgid "Port"
 msgid "Port"
 msgstr "HTTP bağlantı noktası"
 msgstr "HTTP bağlantı noktası"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Eylem"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2771,6 +2780,8 @@ msgid "Reload"
 msgstr "Tekrar yükle"
 msgstr "Tekrar yükle"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3155,6 +3166,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "Geçersiz 2FA veya kurtarma kodu"
 msgstr "Geçersiz 2FA veya kurtarma kodu"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #, fuzzy
 #, fuzzy
 msgid "Selector"
 msgid "Selector"
@@ -3858,7 +3873,7 @@ msgstr "Güncellendi"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -4052,13 +4067,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

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

@@ -40,7 +40,7 @@ msgstr "Người dùng"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -660,7 +660,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1152,19 +1152,6 @@ msgstr "Đã bật"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "Bảo mật trang web với Let's Encrypt"
 msgstr "Bảo mật trang web với Let's Encrypt"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "Environment"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "Environments"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 #, fuzzy
 #, fuzzy
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
@@ -1575,10 +1562,6 @@ msgstr "Đang lấy chứng chỉ, vui lòng đợi..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr ""
 msgstr ""
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -2010,7 +1993,7 @@ msgstr "Single Directive"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2213,11 +2196,31 @@ msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 msgid "No"
 msgid "No"
 msgstr "Không"
 msgstr "Không"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "Hành động"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "Username"
 msgstr "Username"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "Environment"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "Environments"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 #, fuzzy
 #, fuzzy
 msgid "Node name"
 msgid "Node name"
@@ -2556,6 +2559,12 @@ msgstr ""
 msgid "Port"
 msgid "Port"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "Hành động"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2696,6 +2705,8 @@ msgid "Reload"
 msgstr "Tải lại"
 msgstr "Tải lại"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -3055,6 +3066,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr ""
 msgstr ""
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "Bộ chọn"
 msgstr "Bộ chọn"
@@ -3672,7 +3687,7 @@ msgstr "Cập nhật thành công"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3846,13 +3861,13 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 
 
 #: src/views/preference/components/RecoveryCodes.vue:140
 #: src/views/preference/components/RecoveryCodes.vue:140

+ 48 - 32
app/src/language/zh_CN/app.po

@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
 "POT-Creation-Date: \n"
 "POT-Creation-Date: \n"
-"PO-Revision-Date: 2025-04-05 15:35+0800\n"
+"PO-Revision-Date: 2025-04-05 17:43+0800\n"
 "Last-Translator: 0xJacky <me@jackyu.cn>\n"
 "Last-Translator: 0xJacky <me@jackyu.cn>\n"
 "Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
 "Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
 "projects/nginx-ui/frontend/zh_Hans/>\n"
 "projects/nginx-ui/frontend/zh_Hans/>\n"
@@ -44,7 +44,7 @@ msgstr "ACME 用户"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -616,7 +616,7 @@ msgid ""
 msgstr ""
 msgstr ""
 "创建系统备份,包括 Nginx 配置和 Nginx UI 设置。备份文件将自动下载到你的电脑。"
 "创建系统备份,包括 Nginx 配置和 Nginx UI 设置。备份文件将自动下载到你的电脑。"
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1062,17 +1062,6 @@ msgstr "启用成功"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "用 Let's Encrypt 对网站进行加密"
 msgstr "用 Let's Encrypt 对网站进行加密"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-msgid "Environment Group"
-msgstr "环境组"
-
-#: src/views/environments/group/EnvGroup.vue:10
-msgid "Environment Groups"
-msgstr "环境组"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "环境变量已清理"
 msgstr "环境变量已清理"
@@ -1441,10 +1430,6 @@ msgstr "正在获取证书,请稍等..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Github 代理"
 msgstr "Github 代理"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr "组"
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr "哈希验证失败:文件完整性受损"
 msgstr "哈希验证失败:文件完整性受损"
@@ -1856,7 +1841,7 @@ msgstr "多行指令"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2046,10 +2031,27 @@ msgstr "Nginx UI 配置已恢复,几秒钟后将自动重启。"
 msgid "No"
 msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+msgid "No Action"
+msgstr "无操作"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 msgid "Node"
 msgid "Node"
 msgstr "节点"
 msgstr "节点"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+msgid "Node Group"
+msgstr "节点组"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+msgid "Node Groups"
+msgstr "环境组"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
 msgstr "节点名称"
 msgstr "节点名称"
@@ -2375,6 +2377,11 @@ msgstr "请至少选择一个节点进行升级"
 msgid "Port"
 msgid "Port"
 msgstr "端口"
 msgstr "端口"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+msgid "Post-sync Action"
+msgstr "同步后操作"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2508,6 +2515,8 @@ msgid "Reload"
 msgstr "重载"
 msgstr "重载"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 msgid "Reload Nginx"
 msgid "Reload Nginx"
@@ -2821,6 +2830,10 @@ msgstr "安全 Token"
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "安全令牌信息"
 msgstr "安全令牌信息"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr "选择同步后的操作"
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "选择器"
 msgstr "选择器"
@@ -2874,19 +2887,19 @@ msgstr "使用 HTTP01 challenge provider"
 
 
 #: src/constants/errors/nginx_log.ts:8
 #: src/constants/errors/nginx_log.ts:8
 msgid ""
 msgid ""
-"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://"
+"nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
 msgstr ""
-"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://nginxui."
-"com/guide/config-nginx.html"
+"Settings.NginxLogSettings.AccessLogPath 为空,更多信息请参阅 https://"
+"nginxui.com/guide/config-nginx.html"
 
 
 #: src/constants/errors/nginx_log.ts:7
 #: src/constants/errors/nginx_log.ts:7
 msgid ""
 msgid ""
-"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://"
+"nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
 msgstr ""
-"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://nginxui."
-"com/guide/config-nginx.html"
+"Settings.NginxLogSettings.ErrorLogPath为空,更多信息请参阅 https://"
+"nginxui.com/guide/config-nginx.html"
 
 
 #: src/components/SensitiveString/SensitiveString.vue:40
 #: src/components/SensitiveString/SensitiveString.vue:40
 msgid "Show"
 msgid "Show"
@@ -3412,7 +3425,7 @@ msgstr "更新成功"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3577,7 +3590,7 @@ msgstr ""
 #: src/views/site/site_edit/RightSettings.vue:116
 #: src/views/site/site_edit/RightSettings.vue:116
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "启用/禁用、删除或保存此站点时,环境组中设置的节点和下面选择的节点将同步执行操"
 "启用/禁用、删除或保存此站点时,环境组中设置的节点和下面选择的节点将同步执行操"
 "作。"
 "作。"
@@ -3585,7 +3598,7 @@ msgstr ""
 #: src/views/stream/components/RightSettings.vue:114
 #: src/views/stream/components/RightSettings.vue:114
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "启用/禁用、删除或保存此站点时,环境组中设置的节点和下面选择的节点将同步执行操"
 "启用/禁用、删除或保存此站点时,环境组中设置的节点和下面选择的节点将同步执行操"
 "作。"
 "作。"
@@ -3671,6 +3684,9 @@ msgstr "您的旧代码将不再有效。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "你的 Passkeys"
 msgstr "你的 Passkeys"
 
 
+#~ msgid "Groups"
+#~ msgstr "组"
+
 #~ msgid "Nginx has been reloaded on all sync nodes"
 #~ msgid "Nginx has been reloaded on all sync nodes"
 #~ msgstr "已在所有同步节点上重新加载 Nginx"
 #~ msgstr "已在所有同步节点上重新加载 Nginx"
 
 
@@ -3715,8 +3731,8 @@ msgstr "你的 Passkeys"
 #~ msgstr "请将远程 Nginx UI 升级到最新版本"
 #~ msgstr "请将远程 Nginx UI 升级到最新版本"
 
 
 #~ msgid ""
 #~ msgid ""
-#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
-#~ "%{resp}"
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %"
+#~ "{resp}"
 #~ msgstr ""
 #~ msgstr ""
 #~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"
 #~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"
 
 

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

@@ -49,7 +49,7 @@ msgstr "ACME 用戶"
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/CertificateList/certColumns.tsx:97
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/config/configColumns.tsx:42
-#: src/views/environments/group/columns.ts:28
+#: src/views/environments/group/columns.ts:42
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/environments/list/envColumns.tsx:97
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/notification/notificationColumns.tsx:66
@@ -629,7 +629,7 @@ msgid ""
 "Backup files will be automatically downloaded to your computer."
 "Backup files will be automatically downloaded to your computer."
 msgstr ""
 msgstr ""
 
 
-#: src/views/environments/group/columns.ts:16
+#: src/views/environments/group/columns.ts:30
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/notification/notificationColumns.tsx:59
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/preference/components/Passkey.vue:95
 #: src/views/user/userColumns.tsx:48
 #: src/views/user/userColumns.tsx:48
@@ -1086,19 +1086,6 @@ msgstr "成功啟用"
 msgid "Encrypt website with Let's Encrypt"
 msgid "Encrypt website with Let's Encrypt"
 msgstr "用 Let's Encrypt 對網站進行加密"
 msgstr "用 Let's Encrypt 對網站進行加密"
 
 
-#: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:25
-#: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
-#, fuzzy
-msgid "Environment Group"
-msgstr "環境"
-
-#: src/views/environments/group/EnvGroup.vue:10
-#, fuzzy
-msgid "Environment Groups"
-msgstr "環境"
-
 #: src/language/constants.ts:22
 #: src/language/constants.ts:22
 msgid "Environment variables cleaned"
 msgid "Environment variables cleaned"
 msgstr "環境變數已清理"
 msgstr "環境變數已清理"
@@ -1503,10 +1490,6 @@ msgstr "正在取得憑證,請稍候..."
 msgid "Github Proxy"
 msgid "Github Proxy"
 msgstr "Github 代理"
 msgstr "Github 代理"
 
 
-#: src/routes/modules/environments.ts:33
-msgid "Groups"
-msgstr ""
-
 #: src/constants/errors/backup.ts:59
 #: src/constants/errors/backup.ts:59
 msgid "Hash verification failed: file integrity compromised"
 msgid "Hash verification failed: file integrity compromised"
 msgstr ""
 msgstr ""
@@ -1925,7 +1908,7 @@ msgstr "多行指令"
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
 #: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
-#: src/views/environments/group/columns.ts:7
+#: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/nginx_log/NginxLogList.vue:37
 #: src/views/preference/components/AddPasskey.vue:75
 #: src/views/preference/components/AddPasskey.vue:75
@@ -2123,11 +2106,31 @@ msgstr "Nginx 設定解析錯誤"
 msgid "No"
 msgid "No"
 msgstr "取消"
 msgstr "取消"
 
 
+#: src/views/environments/group/columns.ts:21
+#: src/views/environments/group/EnvGroup.vue:34
+#, fuzzy
+msgid "No Action"
+msgstr "操作"
+
 #: src/views/preference/Preference.vue:168
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 #, fuzzy
 msgid "Node"
 msgid "Node"
 msgstr "節點名稱"
 msgstr "節點名稱"
 
 
+#: src/views/site/site_edit/RightSettings.vue:91
+#: src/views/site/site_list/columns.tsx:25
+#: src/views/stream/components/RightSettings.vue:90
+#: src/views/stream/StreamList.vue:28
+#, fuzzy
+msgid "Node Group"
+msgstr "環境"
+
+#: src/routes/modules/environments.ts:33
+#: src/views/environments/group/EnvGroup.vue:10
+#, fuzzy
+msgid "Node Groups"
+msgstr "環境"
+
 #: src/views/preference/NodeSettings.vue:15
 #: src/views/preference/NodeSettings.vue:15
 msgid "Node name"
 msgid "Node name"
 msgstr "節點名稱"
 msgstr "節點名稱"
@@ -2460,6 +2463,12 @@ msgstr "請至少選擇一個節點進行升級"
 msgid "Port"
 msgid "Port"
 msgstr "HTTP 監聽埠"
 msgstr "HTTP 監聽埠"
 
 
+#: src/views/environments/group/columns.ts:17
+#: src/views/environments/group/EnvGroup.vue:26
+#, fuzzy
+msgid "Post-sync Action"
+msgstr "批次操作"
+
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:167
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/environments/list/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:194 src/views/system/Upgrade.vue:245
@@ -2592,6 +2601,8 @@ msgid "Reload"
 msgstr "重新載入"
 msgstr "重新載入"
 
 
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
 #: src/components/EnvGroupTabs/EnvGroupTabs.vue:156
+#: src/views/environments/group/columns.ts:23
+#: src/views/environments/group/EnvGroup.vue:37
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:120
 #: src/views/environments/list/Environment.vue:128
 #: src/views/environments/list/Environment.vue:128
 #, fuzzy
 #, fuzzy
@@ -2933,6 +2944,10 @@ msgstr ""
 msgid "Security Token Information"
 msgid "Security Token Information"
 msgstr "無效的請求格式"
 msgstr "無效的請求格式"
 
 
+#: src/views/environments/group/EnvGroup.vue:29
+msgid "Select an action after sync"
+msgstr ""
+
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 #: src/components/StdDesign/StdDataEntry/components/StdSelector.vue:189
 msgid "Selector"
 msgid "Selector"
 msgstr "選擇器"
 msgstr "選擇器"
@@ -3540,7 +3555,7 @@ msgstr "更新成功"
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
 #: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
-#: src/views/environments/group/columns.ts:22
+#: src/views/environments/group/columns.ts:36
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_edit/RightSettings.vue:100
 #: src/views/site/site_list/columns.tsx:69
 #: src/views/site/site_list/columns.tsx:69
@@ -3705,7 +3720,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 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 "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "當您啟用/禁用、刪除或儲存此網站時,網站類別中設定的節點以及下方選擇的節點將會"
 "當您啟用/禁用、刪除或儲存此網站時,網站類別中設定的節點以及下方選擇的節點將會"
 "同步。"
 "同步。"
@@ -3714,7 +3729,7 @@ msgstr ""
 #, fuzzy
 #, fuzzy
 msgid ""
 msgid ""
 "When you enable/disable, delete, or save this stream, the nodes set in the "
 "When you enable/disable, delete, or save this stream, the nodes set in the "
-"environment group and the nodes selected below will be synchronized."
+"Node Group and the nodes selected below will be synchronized."
 msgstr ""
 msgstr ""
 "當您啟用/禁用、刪除或儲存此網站時,網站類別中設定的節點以及下方選擇的節點將會"
 "當您啟用/禁用、刪除或儲存此網站時,網站類別中設定的節點以及下方選擇的節點將會"
 "同步。"
 "同步。"

+ 1 - 1
app/src/routes/modules/environments.ts

@@ -30,7 +30,7 @@ export const environmentsRoutes: RouteRecordRaw[] = [
         name: 'env.groups',
         name: 'env.groups',
         component: () => import('@/views/environments/group/EnvGroup.vue'),
         component: () => import('@/views/environments/group/EnvGroup.vue'),
         meta: {
         meta: {
-          name: () => $gettext('Groups'),
+          name: () => $gettext('Node Groups'),
         },
         },
       },
       },
     ],
     ],

+ 20 - 2
app/src/views/environments/group/EnvGroup.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
 <script setup lang="ts">
-import env_group from '@/api/env_group'
+import env_group, { PostSyncAction } from '@/api/env_group'
 import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
 import NodeSelector from '@/components/NodeSelector/NodeSelector.vue'
 import { StdCurd } from '@/components/StdDesign/StdDataDisplay'
 import { StdCurd } from '@/components/StdDesign/StdDataDisplay'
 import columns from '@/views/environments/group/columns'
 import columns from '@/views/environments/group/columns'
@@ -7,7 +7,7 @@ import columns from '@/views/environments/group/columns'
 
 
 <template>
 <template>
   <StdCurd
   <StdCurd
-    :title="$gettext('Environment Groups')"
+    :title="$gettext('Node Groups')"
     :api="env_group"
     :api="env_group"
     :columns="columns"
     :columns="columns"
     :scroll-x="600"
     :scroll-x="600"
@@ -21,6 +21,24 @@ import columns from '@/views/environments/group/columns'
         v-model:target="data.sync_node_ids"
         v-model:target="data.sync_node_ids"
         hidden-local
         hidden-local
       />
       />
+
+      <AForm class="mt-4" layout="vertical">
+        <AFormItem :label="$gettext('Post-sync Action')">
+          <ASelect
+            v-model:value="data.post_sync_action"
+            :placeholder="$gettext('Select an action after sync')"
+            :default-value="PostSyncAction.ReloadNginx"
+            class="w-full"
+          >
+            <ASelectOption :value="PostSyncAction.None">
+              {{ $gettext('No Action') }}
+            </ASelectOption>
+            <ASelectOption :value="PostSyncAction.ReloadNginx">
+              {{ $gettext('Reload Nginx') }}
+            </ASelectOption>
+          </ASelect>
+        </AFormItem>
+      </AForm>
     </template>
     </template>
   </StdCurd>
   </StdCurd>
 </template>
 </template>

+ 15 - 0
app/src/views/environments/group/columns.ts

@@ -1,4 +1,5 @@
 import type { Column } from '@/components/StdDesign/types'
 import type { Column } from '@/components/StdDesign/types'
+import { PostSyncAction } from '@/api/env_group'
 import { datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import { datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
 import { input } from '@/components/StdDesign/StdDataEntry'
 import { input } from '@/components/StdDesign/StdDataEntry'
 
 
@@ -12,6 +13,20 @@ const columns: Column[] = [{
   handle: true,
   handle: true,
   pithy: true,
   pithy: true,
   width: 120,
   width: 120,
+}, {
+  title: () => $gettext('Post-sync Action'),
+  dataIndex: 'post_sync_action',
+  customRender: ({ text }) => {
+    if (!text || text === PostSyncAction.None) {
+      return $gettext('No Action')
+    }
+    else if (text === PostSyncAction.ReloadNginx) {
+      return $gettext('Reload Nginx')
+    }
+    return text
+  },
+  pithy: true,
+  width: 150,
 }, {
 }, {
   title: () => $gettext('Created at'),
   title: () => $gettext('Created at'),
   dataIndex: 'created_at',
   dataIndex: 'created_at',

+ 2 - 2
app/src/views/site/site_edit/RightSettings.vue

@@ -88,7 +88,7 @@ function onChangeEnabled(checked: CheckedType) {
           <AFormItem :label="$gettext('Name')">
           <AFormItem :label="$gettext('Name')">
             <ConfigName v-if="name" :name />
             <ConfigName v-if="name" :name />
           </AFormItem>
           </AFormItem>
-          <AFormItem :label="$gettext('Environment Group')">
+          <AFormItem :label="$gettext('Node Group')">
             <StdSelector
             <StdSelector
               v-model:selected-key="data.env_group_id"
               v-model:selected-key="data.env_group_id"
               :api="envGroup"
               :api="envGroup"
@@ -114,7 +114,7 @@ function onChangeEnabled(checked: CheckedType) {
             <template #content>
             <template #content>
               <div class="max-w-200px mb-2">
               <div class="max-w-200px mb-2">
                 {{ $gettext('When you enable/disable, delete, or save this site, '
                 {{ $gettext('When you enable/disable, delete, or save this site, '
-                  + 'the nodes set in the environment group and the nodes selected below will be synchronized.') }}
+                  + 'the nodes set in the Node Group and the nodes selected below will be synchronized.') }}
               </div>
               </div>
               <div class="max-w-200px">
               <div class="max-w-200px">
                 {{ $gettext('Note, if the configuration file include other configurations or certificates, '
                 {{ $gettext('Note, if the configuration file include other configurations or certificates, '

+ 1 - 0
app/src/views/site/site_edit/SiteEdit.vue

@@ -143,6 +143,7 @@ async function save() {
     overwrite: true,
     overwrite: true,
     env_group_id: data.value.env_group_id,
     env_group_id: data.value.env_group_id,
     sync_node_ids: data.value.sync_node_ids,
     sync_node_ids: data.value.sync_node_ids,
+    post_action: 'reload_nginx',
   }).then(r => {
   }).then(r => {
     handleResponse(r)
     handleResponse(r)
     router.push({
     router.push({

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

@@ -22,7 +22,7 @@ const columns: Column[] = [{
   search: true,
   search: true,
   width: 120,
   width: 120,
 }, {
 }, {
-  title: () => $gettext('Environment Group'),
+  title: () => $gettext('Node Group'),
   dataIndex: 'env_group_id',
   dataIndex: 'env_group_id',
   customRender: actualValueRender('env_group.name'),
   customRender: actualValueRender('env_group.name'),
   edit: {
   edit: {

+ 1 - 0
app/src/views/stream/StreamEdit.vue

@@ -131,6 +131,7 @@ async function save() {
     overwrite: true,
     overwrite: true,
     env_group_id: data.value?.env_group_id,
     env_group_id: data.value?.env_group_id,
     sync_node_ids: data.value?.sync_node_ids,
     sync_node_ids: data.value?.sync_node_ids,
+    post_action: 'reload_nginx',
   }).then(r => {
   }).then(r => {
     handleResponse(r)
     handleResponse(r)
     router.push({
     router.push({

+ 1 - 1
app/src/views/stream/StreamList.vue

@@ -25,7 +25,7 @@ const columns: Column[] = [{
   },
   },
   search: true,
   search: true,
 }, {
 }, {
-  title: () => $gettext('Environment Group'),
+  title: () => $gettext('Node Group'),
   dataIndex: 'env_group_id',
   dataIndex: 'env_group_id',
   customRender: actualValueRender('env_group.name'),
   customRender: actualValueRender('env_group.name'),
   edit: {
   edit: {

+ 2 - 2
app/src/views/stream/components/RightSettings.vue

@@ -87,7 +87,7 @@ function onChangeEnabled(checked: CheckedType) {
         <AFormItem :label="$gettext('Name')">
         <AFormItem :label="$gettext('Name')">
           <ConfigName :name="name" />
           <ConfigName :name="name" />
         </AFormItem>
         </AFormItem>
-        <AFormItem :label="$gettext('Environment Group')">
+        <AFormItem :label="$gettext('Node Group')">
           <StdSelector
           <StdSelector
             v-model:selected-key="data.env_group_id"
             v-model:selected-key="data.env_group_id"
             :api="envGroup"
             :api="envGroup"
@@ -112,7 +112,7 @@ function onChangeEnabled(checked: CheckedType) {
             <template #content>
             <template #content>
               <div class="max-w-200px mb-2">
               <div class="max-w-200px mb-2">
                 {{ $gettext('When you enable/disable, delete, or save this stream, '
                 {{ $gettext('When you enable/disable, delete, or save this stream, '
-                  + 'the nodes set in the environment group and the nodes selected below will be synchronized.') }}
+                  + 'the nodes set in the Node Group and the nodes selected below will be synchronized.') }}
               </div>
               </div>
               <div class="max-w-200px">
               <div class="max-w-200px">
                 {{ $gettext('Note, if the configuration file include other configurations or certificates, '
                 {{ $gettext('Note, if the configuration file include other configurations or certificates, '

+ 21 - 10
internal/site/save.go

@@ -17,7 +17,7 @@ import (
 )
 )
 
 
 // Save saves a site configuration file
 // Save saves a site configuration file
-func Save(name string, content string, overwrite bool, envGroupId uint64, syncNodeIds []uint64) (err error) {
+func Save(name string, content string, overwrite bool, envGroupId uint64, syncNodeIds []uint64, postAction string) (err error) {
 	path := nginx.GetConfPath("sites-available", name)
 	path := nginx.GetConfPath("sites-available", name)
 	if !overwrite && helper.FileExists(path) {
 	if !overwrite && helper.FileExists(path) {
 		return ErrDstFileExists
 		return ErrDstFileExists
@@ -37,10 +37,11 @@ func Save(name string, content string, overwrite bool, envGroupId uint64, syncNo
 			return fmt.Errorf("%s", output)
 			return fmt.Errorf("%s", output)
 		}
 		}
 
 
-		output = nginx.Reload()
-
-		if nginx.GetLogLevel(output) > nginx.Warn {
-			return fmt.Errorf("%s", output)
+		if postAction == model.PostSyncActionReloadNginx {
+			output = nginx.Reload()
+			if nginx.GetLogLevel(output) > nginx.Warn {
+				return fmt.Errorf("%s", output)
+			}
 		}
 		}
 	}
 	}
 
 
@@ -61,13 +62,17 @@ func Save(name string, content string, overwrite bool, envGroupId uint64, syncNo
 }
 }
 
 
 func syncSave(name string, content string) {
 func syncSave(name string, content string) {
-	nodes := getSyncNodes(name)
+	nodes, postSyncAction := getSyncData(name)
 
 
 	wg := &sync.WaitGroup{}
 	wg := &sync.WaitGroup{}
 	wg.Add(len(nodes))
 	wg.Add(len(nodes))
 
 
+	// Map to track successful nodes for potential post-sync action
+	successfulNodes := make([]*model.Environment, 0)
+	var nodesMutex sync.Mutex
+
 	for _, node := range nodes {
 	for _, node := range nodes {
-		go func() {
+		go func(node *model.Environment) {
 			defer func() {
 			defer func() {
 				if err := recover(); err != nil {
 				if err := recover(); err != nil {
 					buf := make([]byte, 1024)
 					buf := make([]byte, 1024)
@@ -82,8 +87,9 @@ func syncSave(name string, content string) {
 			resp, err := client.R().
 			resp, err := client.R().
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				SetBody(map[string]interface{}{
 				SetBody(map[string]interface{}{
-					"content":   content,
-					"overwrite": true,
+					"content":     content,
+					"overwrite":   true,
+					"post_action": postSyncAction,
 				}).
 				}).
 				Post(fmt.Sprintf("/api/sites/%s", name))
 				Post(fmt.Sprintf("/api/sites/%s", name))
 			if err != nil {
 			if err != nil {
@@ -96,12 +102,17 @@ func syncSave(name string, content string) {
 			}
 			}
 			notification.Success("Save Remote Site Success", "Save site %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 			notification.Success("Save Remote Site Success", "Save site %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 
 
+			// Track successful sync for post-sync action
+			nodesMutex.Lock()
+			successfulNodes = append(successfulNodes, node)
+			nodesMutex.Unlock()
+
 			// Check if the site is enabled, if so then enable it on the remote node
 			// Check if the site is enabled, if so then enable it on the remote node
 			enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
 			enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
 			if helper.FileExists(enabledConfigFilePath) {
 			if helper.FileExists(enabledConfigFilePath) {
 				syncEnable(name)
 				syncEnable(name)
 			}
 			}
-		}()
+		}(node)
 	}
 	}
 
 
 	wg.Wait()
 	wg.Wait()

+ 10 - 2
internal/site/sync.go

@@ -2,6 +2,7 @@ package site
 
 
 import (
 import (
 	"encoding/json"
 	"encoding/json"
+
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/query"
@@ -11,8 +12,8 @@ import (
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
 )
 )
 
 
-// getSyncNodes returns the nodes that need to be synchronized by site name
-func getSyncNodes(name string) (nodes []*model.Environment) {
+// getSyncData returns the nodes that need to be synchronized by site name and the post-sync action
+func getSyncData(name string) (nodes []*model.Environment, postSyncAction string) {
 	configFilePath := nginx.GetConfPath("sites-available", name)
 	configFilePath := nginx.GetConfPath("sites-available", name)
 	s := query.Site
 	s := query.Site
 	site, err := s.Where(s.Path.Eq(configFilePath)).
 	site, err := s.Where(s.Path.Eq(configFilePath)).
@@ -26,6 +27,7 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
 	// inherit sync node ids from site category
 	// inherit sync node ids from site category
 	if site.EnvGroup != nil {
 	if site.EnvGroup != nil {
 		syncNodeIds = append(syncNodeIds, site.EnvGroup.SyncNodeIds...)
 		syncNodeIds = append(syncNodeIds, site.EnvGroup.SyncNodeIds...)
+		postSyncAction = site.EnvGroup.PostSyncAction
 	}
 	}
 	syncNodeIds = lo.Uniq(syncNodeIds)
 	syncNodeIds = lo.Uniq(syncNodeIds)
 
 
@@ -38,6 +40,12 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
 	return
 	return
 }
 }
 
 
+// getSyncNodes returns the nodes that need to be synchronized by site name (for backward compatibility)
+func getSyncNodes(name string) (nodes []*model.Environment) {
+	nodes, _ = getSyncData(name)
+	return
+}
+
 type SyncResult struct {
 type SyncResult struct {
 	StatusCode int    `json:"status_code"`
 	StatusCode int    `json:"status_code"`
 	Node       string `json:"node"`
 	Node       string `json:"node"`

+ 21 - 10
internal/stream/save.go

@@ -17,7 +17,7 @@ import (
 )
 )
 
 
 // Save saves a site configuration file
 // Save saves a site configuration file
-func Save(name string, content string, overwrite bool, syncNodeIds []uint64) (err error) {
+func Save(name string, content string, overwrite bool, syncNodeIds []uint64, postAction string) (err error) {
 	path := nginx.GetConfPath("streams-available", name)
 	path := nginx.GetConfPath("streams-available", name)
 	if !overwrite && helper.FileExists(path) {
 	if !overwrite && helper.FileExists(path) {
 		return ErrDstFileExists
 		return ErrDstFileExists
@@ -37,10 +37,11 @@ func Save(name string, content string, overwrite bool, syncNodeIds []uint64) (er
 			return fmt.Errorf("%s", output)
 			return fmt.Errorf("%s", output)
 		}
 		}
 
 
-		output = nginx.Reload()
-
-		if nginx.GetLogLevel(output) > nginx.Warn {
-			return fmt.Errorf("%s", output)
+		if postAction == model.PostSyncActionReloadNginx {
+			output = nginx.Reload()
+			if nginx.GetLogLevel(output) > nginx.Warn {
+				return fmt.Errorf("%s", output)
+			}
 		}
 		}
 	}
 	}
 
 
@@ -60,13 +61,17 @@ func Save(name string, content string, overwrite bool, syncNodeIds []uint64) (er
 }
 }
 
 
 func syncSave(name string, content string) {
 func syncSave(name string, content string) {
-	nodes := getSyncNodes(name)
+	nodes, postSyncAction := getSyncData(name)
 
 
 	wg := &sync.WaitGroup{}
 	wg := &sync.WaitGroup{}
 	wg.Add(len(nodes))
 	wg.Add(len(nodes))
 
 
+	// Map to track successful nodes for potential post-sync action
+	successfulNodes := make([]*model.Environment, 0)
+	var nodesMutex sync.Mutex
+
 	for _, node := range nodes {
 	for _, node := range nodes {
-		go func() {
+		go func(node *model.Environment) {
 			defer func() {
 			defer func() {
 				if err := recover(); err != nil {
 				if err := recover(); err != nil {
 					buf := make([]byte, 1024)
 					buf := make([]byte, 1024)
@@ -81,8 +86,9 @@ func syncSave(name string, content string) {
 			resp, err := client.R().
 			resp, err := client.R().
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				SetBody(map[string]interface{}{
 				SetBody(map[string]interface{}{
-					"content":   content,
-					"overwrite": true,
+					"content":     content,
+					"overwrite":   true,
+					"post_action": postSyncAction,
 				}).
 				}).
 				Post(fmt.Sprintf("/api/streams/%s", name))
 				Post(fmt.Sprintf("/api/streams/%s", name))
 			if err != nil {
 			if err != nil {
@@ -95,12 +101,17 @@ func syncSave(name string, content string) {
 			}
 			}
 			notification.Success("Save Remote Stream Success", "Save stream %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 			notification.Success("Save Remote Stream Success", "Save stream %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 
 
+			// Track successful sync for post-sync action
+			nodesMutex.Lock()
+			successfulNodes = append(successfulNodes, node)
+			nodesMutex.Unlock()
+
 			// Check if the site is enabled, if so then enable it on the remote node
 			// Check if the site is enabled, if so then enable it on the remote node
 			enabledConfigFilePath := nginx.GetConfPath("streams-enabled", name)
 			enabledConfigFilePath := nginx.GetConfPath("streams-enabled", name)
 			if helper.FileExists(enabledConfigFilePath) {
 			if helper.FileExists(enabledConfigFilePath) {
 				syncEnable(name)
 				syncEnable(name)
 			}
 			}
-		}()
+		}(node)
 	}
 	}
 
 
 	wg.Wait()
 	wg.Wait()

+ 10 - 3
internal/stream/sync.go

@@ -11,8 +11,8 @@ import (
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
 )
 )
 
 
-// getSyncNodes returns the nodes that need to be synchronized by site name
-func getSyncNodes(name string) (nodes []*model.Environment) {
+// getSyncData returns the nodes that need to be synchronized by stream name and the post-sync action
+func getSyncData(name string) (nodes []*model.Environment, postSyncAction string) {
 	configFilePath := nginx.GetConfPath("streams-available", name)
 	configFilePath := nginx.GetConfPath("streams-available", name)
 	s := query.Stream
 	s := query.Stream
 	stream, err := s.Where(s.Path.Eq(configFilePath)).
 	stream, err := s.Where(s.Path.Eq(configFilePath)).
@@ -23,9 +23,10 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
 	}
 	}
 
 
 	syncNodeIds := stream.SyncNodeIDs
 	syncNodeIds := stream.SyncNodeIDs
-	// inherit sync node ids from site category
+	// inherit sync node ids from stream category
 	if stream.EnvGroup != nil {
 	if stream.EnvGroup != nil {
 		syncNodeIds = append(syncNodeIds, stream.EnvGroup.SyncNodeIds...)
 		syncNodeIds = append(syncNodeIds, stream.EnvGroup.SyncNodeIds...)
+		postSyncAction = stream.EnvGroup.PostSyncAction
 	}
 	}
 
 
 	e := query.Environment
 	e := query.Environment
@@ -37,6 +38,12 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
 	return
 	return
 }
 }
 
 
+// getSyncNodes returns the nodes that need to be synchronized by stream name (for backward compatibility)
+func getSyncNodes(name string) (nodes []*model.Environment) {
+	nodes, _ = getSyncData(name)
+	return
+}
+
 type SyncResult struct {
 type SyncResult struct {
 	StatusCode int    `json:"status_code"`
 	StatusCode int    `json:"status_code"`
 	Node       string `json:"node"`
 	Node       string `json:"node"`

+ 12 - 3
model/env_group.go

@@ -1,9 +1,18 @@
 package model
 package model
 
 
+// PostSyncActionType defines the type of action after synchronization
+const (
+	// PostSyncActionNone indicates no operation after sync
+	PostSyncActionNone = "none"
+	// PostSyncActionReloadNginx indicates reload Nginx after sync
+	PostSyncActionReloadNginx = "reload_nginx"
+)
+
 // EnvGroup represents a group of environments that can be synced across nodes
 // EnvGroup represents a group of environments that can be synced across nodes
 type EnvGroup struct {
 type EnvGroup struct {
 	Model
 	Model
-	Name        string   `json:"name"`
-	SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
-	OrderID     int      `json:"-" gorm:"default:0"`
+	Name           string   `json:"name"`
+	SyncNodeIds    []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
+	OrderID        int      `json:"-" gorm:"default:0"`
+	PostSyncAction string   `json:"post_sync_action" gorm:"default:'reload_nginx'"`
 }
 }