Browse Source

refactor: notification module

Jacky 2 months ago
parent
commit
ab46d1de7e
41 changed files with 3980 additions and 2402 deletions
  1. 2 2
      api/certificate/certificate.go
  2. 8 0
      api/certificate/notifications.ts
  3. 2 1
      app/src/components/Notification/Notification.vue
  4. 0 15
      app/src/components/Notification/cert.ts
  5. 0 96
      app/src/components/Notification/config.ts
  6. 0 65
      app/src/components/Notification/detailRender.ts
  7. 26 0
      app/src/components/Notification/detailRender.tsx
  8. 126 0
      app/src/components/Notification/notifications.ts
  9. 305 177
      app/src/language/ar/app.po
  10. 291 170
      app/src/language/de_DE/app.po
  11. 286 173
      app/src/language/en/app.po
  12. 305 181
      app/src/language/es/app.po
  13. 286 173
      app/src/language/fr_FR/app.po
  14. 287 166
      app/src/language/ko_KR/app.po
  15. 183 140
      app/src/language/messages.pot
  16. 304 182
      app/src/language/ru_RU/app.po
  17. 324 186
      app/src/language/tr_TR/app.po
  18. 288 170
      app/src/language/vi_VN/app.po
  19. 267 175
      app/src/language/zh_CN/app.po
  20. 297 169
      app/src/language/zh_TW/app.po
  21. 245 0
      cmd/notification/generate.go
  22. 3 0
      gen.sh
  23. 6 6
      internal/cert/auto_cert.go
  24. 10 12
      internal/cert/sync.go
  25. 14 23
      internal/config/sync.go
  26. 8 55
      internal/notification/notification.go
  27. 54 0
      internal/notification/subscribe.go
  28. 7 6
      internal/site/delete.go
  29. 3 3
      internal/site/disable.go
  30. 8 7
      internal/site/enable.go
  31. 5 5
      internal/site/rename.go
  32. 10 9
      internal/site/save.go
  33. 0 8
      internal/site/sync.go
  34. 3 3
      internal/stream/delete.go
  35. 3 3
      internal/stream/disable.go
  36. 3 3
      internal/stream/enable.go
  37. 5 5
      internal/stream/rename.go
  38. 3 3
      internal/stream/save.go
  39. 0 8
      internal/stream/sync.go
  40. 1 1
      internal/user/otp.go
  41. 2 1
      model/notification.go

+ 2 - 2
api/certificate/certificate.go

@@ -133,7 +133,7 @@ func AddCert(c *gin.Context) {
 
 
 	err = cert.SyncToRemoteServer(certModel)
 	err = cert.SyncToRemoteServer(certModel)
 	if err != nil {
 	if err != nil {
-		notification.Error("Sync Certificate Error", err.Error())
+		notification.Error("Sync Certificate Error", err.Error(), nil)
 		return
 		return
 	}
 	}
 
 
@@ -188,7 +188,7 @@ func ModifyCert(c *gin.Context) {
 
 
 	err = cert.SyncToRemoteServer(certModel)
 	err = cert.SyncToRemoteServer(certModel)
 	if err != nil {
 	if err != nil {
-		notification.Error("Sync Certificate Error", err.Error())
+		notification.Error("Sync Certificate Error", err.Error(), nil)
 		return
 		return
 	}
 	}
 
 

+ 8 - 0
api/certificate/notifications.ts

@@ -0,0 +1,8 @@
+// Auto-generated notification messages
+// Do not edit manually
+
+const notifications: Record<string, string> = {
+  "Sync_Certificate_Error_Error": "err.Error()",
+};
+
+export default notifications;

+ 2 - 1
app/src/components/Notification/Notification.vue

@@ -12,6 +12,7 @@ import { message, notification } from 'ant-design-vue'
 import dayjs from 'dayjs'
 import dayjs from 'dayjs'
 import relativeTime from 'dayjs/plugin/relativeTime'
 import relativeTime from 'dayjs/plugin/relativeTime'
 import { SSE } from 'sse.js'
 import { SSE } from 'sse.js'
+import notifications from './notifications'
 
 
 defineProps<{
 defineProps<{
   headerRef: HTMLElement
   headerRef: HTMLElement
@@ -181,7 +182,7 @@ function viewAll() {
                 <template #description>
                 <template #description>
                   <div class="flex justify-between items-center">
                   <div class="flex justify-between items-center">
                     <div>
                     <div>
-                      {{ detailRender({ text: item.details, record: item } as CustomRender) }}
+                      {{ notifications[item.title].content(item.details) }}
                     </div>
                     </div>
                     <span
                     <span
                       key="list-loadmore-remove"
                       key="list-loadmore-remove"

+ 0 - 15
app/src/components/Notification/cert.ts

@@ -1,15 +0,0 @@
-export function syncCertificateSuccess(text: string) {
-  const data = JSON.parse(text)
-
-  return $gettext('Sync Certificate %{cert_name} to %{env_name} successfully', { cert_name: data.cert_name, env_name: data.env_name })
-}
-
-export function syncCertificateError(text: string) {
-  const data = JSON.parse(text)
-
-  if (data.status_code === 404) {
-    return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the remote Nginx UI to the latest version', { cert_name: data.cert_name, env_name: data.env_name }, true)
-  }
-
-  return $gettext('Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}', { cert_name: data.cert_name, env_name: data.env_name, resp: data.resp_body }, true)
-}

+ 0 - 96
app/src/components/Notification/config.ts

@@ -1,96 +0,0 @@
-export function syncConfigSuccess(text: string) {
-  const data = JSON.parse(text)
-
-  return $gettext('Sync Config %{config_name} to %{env_name} successfully', { config_name: data.config_name, env_name: data.env_name })
-}
-
-export function syncConfigError(text: string) {
-  const data = JSON.parse(text)
-
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-
-  return $gettext('Sync config %{config_name} to %{env_name} failed, response: %{resp}', { config_name: data.config_name, env_name: data.env_name, resp: data.resp_body }, true)
-}
-
-export function syncRenameConfigSuccess(text: string) {
-  const data = JSON.parse(text)
-
-  return $gettext('Rename %{orig_path} to %{new_path} on %{env_name} successfully', { orig_path: data.orig_path, new_path: data.new_path, env_name: data.env_name })
-}
-
-export function syncRenameConfigError(text: string) {
-  const data = JSON.parse(text)
-
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-
-  return $gettext('Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}', { orig_path: data.orig_path, new_path: data.new_path, resp: data.resp_body, env_name: data.env_name }, true)
-}
-
-export function saveSiteSuccess(text: string) {
-  const data = JSON.parse(text)
-  return $gettext('Save Site %{site} to %{node} successfully', { site: data.name, node: data.node })
-}
-
-export function saveSiteError(text: string) {
-  const data = JSON.parse(text)
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-  return $gettext('Save site %{site} to %{node} error, response: %{resp}', { site: data.name, node: data.node, resp: JSON.stringify(data.response) }, true)
-}
-
-export function deleteSiteSuccess(text: string) {
-  const data = JSON.parse(text)
-  return $gettext('Remove Site %{site} from %{node} successfully', { site: data.name, node: data.node })
-}
-
-export function deleteSiteError(text: string) {
-  const data = JSON.parse(text)
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-  return $gettext('Remove site %{site} from %{node} error, response: %{resp}', { site: data.name, node: data.node, resp: JSON.stringify(data.response) }, true)
-}
-
-export function enableSiteSuccess(text: string) {
-  const data = JSON.parse(text)
-  return $gettext('Enable Site %{site} on %{node} successfully', { site: data.name, node: data.node })
-}
-
-export function enableSiteError(text: string) {
-  const data = JSON.parse(text)
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-  return $gettext('Enable site %{site} on %{node} error, response: %{resp}', { site: data.name, node: data.node, resp: JSON.stringify(data.response) }, true)
-}
-
-export function disableSiteSuccess(text: string) {
-  const data = JSON.parse(text)
-  return $gettext('Disable Site %{site} on %{node} successfully', { site: data.name, node: data.node })
-}
-
-export function disableSiteError(text: string) {
-  const data = JSON.parse(text)
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-  return $gettext('Disable site %{site} on %{node} error, response: %{resp}', { site: data.name, node: data.node, resp: JSON.stringify(data.response) }, true)
-}
-
-export function renameSiteSuccess(text: string) {
-  const data = JSON.parse(text)
-  return $gettext('Rename Site %{site} to %{new_site} on %{node} successfully', { site: data.name, new_site: data.new_name, node: data.node })
-}
-
-export function renameSiteError(text: string) {
-  const data = JSON.parse(text)
-  if (data.status_code === 404) {
-    return $gettext('Please upgrade the remote Nginx UI to the latest version')
-  }
-  return $gettext('Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}', { site: data.name, new_site: data.new_name, node: data.node, resp: JSON.stringify(data.response) }, true)
-}

+ 0 - 65
app/src/components/Notification/detailRender.ts

@@ -1,65 +0,0 @@
-import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
-import { syncCertificateError, syncCertificateSuccess } from '@/components/Notification/cert'
-import {
-  deleteSiteError,
-  deleteSiteSuccess,
-  disableSiteError,
-  disableSiteSuccess,
-  enableSiteError,
-  enableSiteSuccess,
-  renameSiteError,
-  renameSiteSuccess,
-  saveSiteError,
-  saveSiteSuccess,
-  syncConfigError,
-  syncConfigSuccess,
-  syncRenameConfigError,
-  syncRenameConfigSuccess,
-} from '@/components/Notification/config'
-
-export function detailRender(args: CustomRender) {
-  try {
-    switch (args.record.title) {
-      case 'Sync Certificate Success':
-        return syncCertificateSuccess(args.text)
-      case 'Sync Certificate Error':
-        return syncCertificateError(args.text)
-      case 'Rename Remote Config Success':
-        return syncRenameConfigSuccess(args.text)
-      case 'Rename Remote Config Error':
-        return syncRenameConfigError(args.text)
-
-      case 'Save Remote Site Success':
-        return saveSiteSuccess(args.text)
-      case 'Save Remote Site Error':
-        return saveSiteError(args.text)
-      case 'Delete Remote Site Success':
-        return deleteSiteSuccess(args.text)
-      case 'Delete Remote Site Error':
-        return deleteSiteError(args.text)
-      case 'Enable Remote Site Success':
-        return enableSiteSuccess(args.text)
-      case 'Enable Remote Site Error':
-        return enableSiteError(args.text)
-      case 'Disable Remote Site Success':
-        return disableSiteSuccess(args.text)
-      case 'Disable Remote Site Error':
-        return disableSiteError(args.text)
-      case 'Rename Remote Site Success':
-        return renameSiteSuccess(args.text)
-      case 'Rename Remote Site Error':
-        return renameSiteError(args.text)
-
-      case 'Sync Config Success':
-        return syncConfigSuccess(args.text)
-      case 'Sync Config Error':
-        return syncConfigError(args.text)
-      default:
-        return args.text
-    }
-  }
-  // eslint-disable-next-line sonarjs/no-ignored-exceptions,unused-imports/no-unused-vars
-  catch (e) {
-    return args.text
-  }
-}

+ 26 - 0
app/src/components/Notification/detailRender.tsx

@@ -0,0 +1,26 @@
+import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
+import { NotificationTypeT } from '@/constants'
+import notifications from './notifications'
+
+export function detailRender(args: CustomRender) {
+  try {
+    return (
+      <div>
+        <div class="mb-2">
+          {
+            notifications[args.record.title].content(args.record.details)
+          }
+        </div>
+        {args.record.type !== NotificationTypeT.Success && (
+          <div>
+            { JSON.stringify(args.record.details.response) }
+          </div>
+        )}
+      </div>
+    )
+  }
+  // eslint-disable-next-line sonarjs/no-ignored-exceptions,unused-imports/no-unused-vars
+  catch (e) {
+    return args.text
+  }
+}

+ 126 - 0
app/src/components/Notification/notifications.ts

@@ -0,0 +1,126 @@
+// Auto-generated notification texts
+// Extracted from Go source code notification function calls
+/* eslint-disable ts/no-explicit-any */
+
+const notifications: Record<string, { title: () => string, content: (args: any) => string }> = {
+
+  // cert module notifications
+  'Sync Certificate Error': {
+    title: () => $gettext('Sync Certificate Error'),
+    content: (args: any) => $gettext('Sync Certificate %{cert_name} to %{env_name} failed', args),
+  },
+  'Sync Certificate Success': {
+    title: () => $gettext('Sync Certificate Success'),
+    content: (args: any) => $gettext('Sync Certificate %{cert_name} to %{env_name} successfully', args),
+  },
+
+  // config module notifications
+  'Sync Config Error': {
+    title: () => $gettext('Sync Config Error'),
+    content: (args: any) => $gettext('Sync config %{config_name} to %{env_name} failed', args),
+  },
+  'Sync Config Success': {
+    title: () => $gettext('Sync Config Success'),
+    content: (args: any) => $gettext('Sync config %{config_name} to %{env_name} successfully', args),
+  },
+  'Rename Remote Config Error': {
+    title: () => $gettext('Rename Remote Config Error'),
+    content: (args: any) => $gettext('Rename %{orig_path} to %{new_path} on %{env_name} failed', args),
+  },
+  'Rename Remote Config Success': {
+    title: () => $gettext('Rename Remote Config Success'),
+    content: (args: any) => $gettext('Rename %{orig_path} to %{new_path} on %{env_name} successfully', args),
+  },
+
+  // site module notifications
+  'Delete Remote Site Error': {
+    title: () => $gettext('Delete Remote Site Error'),
+    content: (args: any) => $gettext('Delete site %{name} from %{node} failed', args),
+  },
+  'Delete Remote Site Success': {
+    title: () => $gettext('Delete Remote Site Success'),
+    content: (args: any) => $gettext('Delete site %{name} from %{node} successfully', args),
+  },
+  'Disable Remote Site Error': {
+    title: () => $gettext('Disable Remote Site Error'),
+    content: (args: any) => $gettext('Disable site %{name} from %{node} failed', args),
+  },
+  'Disable Remote Site Success': {
+    title: () => $gettext('Disable Remote Site Success'),
+    content: (args: any) => $gettext('Disable site %{name} from %{node} successfully', args),
+  },
+  'Enable Remote Site Error': {
+    title: () => $gettext('Enable Remote Site Error'),
+    content: (args: any) => $gettext('Enable site %{name} on %{node} failed', args),
+  },
+  'Enable Remote Site Success': {
+    title: () => $gettext('Enable Remote Site Success'),
+    content: (args: any) => $gettext('Enable site %{name} on %{node} successfully', args),
+  },
+  'Rename Remote Site Error': {
+    title: () => $gettext('Rename Remote Site Error'),
+    content: (args: any) => $gettext('Rename site %{name} to %{new_name} on %{node} failed', args),
+  },
+  'Rename Remote Site Success': {
+    title: () => $gettext('Rename Remote Site Success'),
+    content: (args: any) => $gettext('Rename site %{name} to %{new_name} on %{node} successfully', args),
+  },
+  'Save Remote Site Error': {
+    title: () => $gettext('Save Remote Site Error'),
+    content: (args: any) => $gettext('Save site %{name} to %{node} failed', args),
+  },
+  'Save Remote Site Success': {
+    title: () => $gettext('Save Remote Site Success'),
+    content: (args: any) => $gettext('Save site %{name} to %{node} successfully', args),
+  },
+
+  // stream module notifications
+  'Delete Remote Stream Error': {
+    title: () => $gettext('Delete Remote Stream Error'),
+    content: (args: any) => $gettext('Delete stream %{name} from %{node} failed', args),
+  },
+  'Delete Remote Stream Success': {
+    title: () => $gettext('Delete Remote Stream Success'),
+    content: (args: any) => $gettext('Delete stream %{name} from %{node} successfully', args),
+  },
+  'Disable Remote Stream Error': {
+    title: () => $gettext('Disable Remote Stream Error'),
+    content: (args: any) => $gettext('Disable stream %{name} from %{node} failed', args),
+  },
+  'Disable Remote Stream Success': {
+    title: () => $gettext('Disable Remote Stream Success'),
+    content: (args: any) => $gettext('Disable stream %{name} from %{node} successfully', args),
+  },
+  'Enable Remote Stream Error': {
+    title: () => $gettext('Enable Remote Stream Error'),
+    content: (args: any) => $gettext('Enable stream %{name} on %{node} failed', args),
+  },
+  'Enable Remote Stream Success': {
+    title: () => $gettext('Enable Remote Stream Success'),
+    content: (args: any) => $gettext('Enable stream %{name} on %{node} successfully', args),
+  },
+  'Rename Remote Stream Error': {
+    title: () => $gettext('Rename Remote Stream Error'),
+    content: (args: any) => $gettext('Rename stream %{name} to %{new_name} on %{node} failed', args),
+  },
+  'Rename Remote Stream Success': {
+    title: () => $gettext('Rename Remote Stream Success'),
+    content: (args: any) => $gettext('Rename stream %{name} to %{new_name} on %{node} successfully', args),
+  },
+  'Save Remote Stream Error': {
+    title: () => $gettext('Save Remote Stream Error'),
+    content: (args: any) => $gettext('Save stream %{name} to %{node} failed', args),
+  },
+  'Save Remote Stream Success': {
+    title: () => $gettext('Save Remote Stream Success'),
+    content: (args: any) => $gettext('Save stream %{name} to %{node} successfully', args),
+  },
+
+  // user module notifications
+  'All Recovery Codes Have Been Used': {
+    title: () => $gettext('All Recovery Codes Have Been Used'),
+    content: (args: any) => $gettext('Please generate new recovery codes in the preferences immediately to prevent lockout.', args),
+  },
+}
+
+export default notifications

+ 305 - 177
app/src/language/ar/app.po

@@ -93,7 +93,7 @@ msgid "Additional"
 msgstr "إضافي"
 msgstr "إضافي"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "الوضع المتقدم"
 msgstr "الوضع المتقدم"
 
 
@@ -106,6 +106,7 @@ msgstr "بعد ذلك، قم بتحديث هذه الصفحة وانقر فوق
 msgid "All"
 msgid "All"
 msgstr "الكل"
 msgstr "الكل"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -167,7 +168,7 @@ msgstr "هل أنت متأكد أنك تريد الحذف؟"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "هل أنت متأكد أنك تريد مسح كافة التنبيهات؟"
 msgstr "هل أنت متأكد أنك تريد مسح كافة التنبيهات؟"
@@ -255,7 +256,7 @@ msgstr "تم تمكين التجديد التلقائي لـ‏%{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "رجوع"
 msgstr "رجوع"
 
 
@@ -291,7 +292,7 @@ msgid "Basic"
 msgstr "أساسي"
 msgstr "أساسي"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "الوضع الأساسي"
 msgstr "الوضع الأساسي"
 
 
@@ -339,17 +340,16 @@ msgstr "مجلد سلطة التصديق"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "إلغاء"
 msgstr "إلغاء"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "حظر تغيير كلمة مرور root في العرض التوضيحي"
 msgstr "حظر تغيير كلمة مرور root في العرض التوضيحي"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 #, fuzzy
 #, fuzzy
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "مستخدم النظام الأولي"
 msgstr "مستخدم النظام الأولي"
@@ -461,12 +461,12 @@ msgid "Cleaning environment variables"
 msgstr "تنظيف متغيرات البيئة"
 msgstr "تنظيف متغيرات البيئة"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "مسح"
 msgstr "مسح"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "تم المسح بنجاح"
 msgstr "تم المسح بنجاح"
@@ -640,18 +640,48 @@ msgstr "حذف"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "حذف نهائي"
 msgstr "حذف نهائي"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "خطأ حذف الموقع البعيد"
 msgstr "خطأ حذف الموقع البعيد"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "نجح حذف الموقع البعيد"
 msgstr "نجح حذف الموقع البعيد"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "خطأ حذف الموقع البعيد"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "نجح حذف الموقع البعيد"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "فشل نشر {conf_name}% إلى {node_name}%"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "تمت إزالة الموقع %{site} من %{node} بنجاح"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "حذف الموقع: ‎%{site_name}"
 msgstr "حذف الموقع: ‎%{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "فشل نشر {conf_name}% إلى {node_name}%"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "تمت إزالة الموقع %{site} من %{node} بنجاح"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "حذف البث: ‎%{stream_name}"
 msgstr "حذف البث: ‎%{stream_name}"
@@ -661,29 +691,15 @@ msgid "Deleted successfully"
 msgstr "تم الحذف بنجاح"
 msgstr "تم الحذف بنجاح"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "نشر"
 msgstr "نشر"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "فشل نشر {conf_name}% إلى {node_name}%"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "تم نشر %{conf_name} إلى %{node_name} بنجاح"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "تم النشر بنجاح"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "وصف"
 msgstr "وصف"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -724,28 +740,50 @@ msgstr "تعطيل"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "فشل تعطيل التجديد التلقائي لـ {name}%"
 msgstr "فشل تعطيل التجديد التلقائي لـ {name}%"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "خطأ في تعطيل الموقع البعيد"
 msgstr "خطأ في تعطيل الموقع البعيد"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "تعطيل الموقع البعيد بنجاح"
 msgstr "تعطيل الموقع البعيد بنجاح"
 
 
-#: src/components/Notification/config.ts:82
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
-msgstr "حدث خطأ في تعطيل الموقع %{site} على %{node}، الاستجابة: %{resp}"
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "خطأ في تعطيل الموقع البعيد"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "تعطيل الموقع البعيد بنجاح"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:50
+#, fuzzy
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "فشل تفعيل %{conf_name} في %{node_name}"
 
 
-#: src/components/Notification/config.ts:74
-msgid "Disable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
 msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "معطل"
 msgstr "معطل"
 
 
@@ -777,16 +815,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "لا تقم بتمكين هذا الخيار إلا إذا كنت متأكدًا من أنك بحاجة إليه."
 msgstr "لا تقم بتمكين هذا الخيار إلا إذا كنت متأكدًا من أنك بحاجة إليه."
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "صفر؟"
-msgstr[1] "هل تريد نشر هذا الملف إلى خادم بعيد؟"
-msgstr[2] "هل تريد نشر هذا الملف إلى الخادمين البعيدة؟"
-msgstr[3] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
-msgstr[4] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
-msgstr[5] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "هل تريد تعطيل التجديد التلقائي للشهادة؟"
 msgstr "هل تريد تعطيل التجديد التلقائي للشهادة؟"
@@ -865,25 +893,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "مكرر"
 msgstr "مكرر"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "تم نسخ %{conf_name} إلى %{node_name} بنجاح"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "فشل التكرار"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr "تم التكرار بنجاح"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "تم النسخ إلى المحلي بنجاح"
 msgstr "تم النسخ إلى المحلي بنجاح"
 
 
@@ -893,7 +909,7 @@ msgid "Edit"
 msgstr "تعديل %{n}"
 msgstr "تعديل %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "تعديل %{n}"
 msgstr "تعديل %{n}"
 
 
@@ -918,19 +934,10 @@ msgid "Email (*)"
 msgstr "البريد الإلكتروني (*)"
 msgstr "البريد الإلكتروني (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "تفعيل"
 msgstr "تفعيل"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "فشل تفعيل %{conf_name} في %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "تم تفعيل %{conf_name} في %{node_name} بنجاح"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "تم تفعيل المصادقة الثنائية بنجاح"
 msgstr "تم تفعيل المصادقة الثنائية بنجاح"
@@ -943,25 +950,43 @@ msgstr "فشل تفعيل التجديد التلقائي لـ %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "فشل التفعيل"
 msgstr "فشل التفعيل"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "خطأ في تفعيل الموقع البعيد"
 msgstr "خطأ في تفعيل الموقع البعيد"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "نجح تفعيل الموقع البعيد"
 msgstr "نجح تفعيل الموقع البعيد"
 
 
-#: src/components/Notification/config.ts:69
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "خطأ في تفعيل الموقع %{site} على %{node}، الاستجابة: %{resp}"
+#: src/components/Notification/notifications.ts:95
+#, fuzzy
+msgid "Enable Remote Stream Error"
+msgstr "خطأ في تفعيل الموقع البعيد"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "نجح تفعيل الموقع البعيد"
 
 
-#: src/components/Notification/config.ts:61
-msgid "Enable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
+msgstr "فشل تفعيل %{conf_name} في %{node_name}"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "تم تفعيل الموقع %{site} على %{node} بنجاح"
 msgstr "تم تفعيل الموقع %{site} على %{node} بنجاح"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "تم التفعيل بنجاح"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "فشل تفعيل %{conf_name} في %{node_name}"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "تم تفعيل الموقع %{site} على %{node} بنجاح"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -979,7 +1004,7 @@ msgstr "تفعيل TOTP"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "مفعل"
 msgstr "مفعل"
@@ -987,7 +1012,6 @@ msgstr "مفعل"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "تم التفعيل بنجاح"
 msgstr "تم التفعيل بنجاح"
@@ -1352,6 +1376,10 @@ msgstr "اتركه فارغًا إذا لم تكن بحاجة إلى ذلك."
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "تركه فارغًا لن يغير شيئًا"
 msgstr "تركه فارغًا لن يغير شيئًا"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "تعطيل دعم ‏Lego CNAME"
 msgstr "تعطيل دعم ‏Lego CNAME"
@@ -1382,7 +1410,7 @@ msgid "Load successfully"
 msgstr "تم التحميل بنجاح"
 msgstr "تم التحميل بنجاح"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "محلي"
 msgstr "محلي"
 
 
@@ -1517,7 +1545,7 @@ msgstr "توجيه متعدد الأسطر"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "اسم"
 msgstr "اسم"
@@ -1589,7 +1617,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "خطأ في تحليل تكوين Nginx"
 msgstr "خطأ في تحليل تكوين Nginx"
 
 
@@ -1638,7 +1666,7 @@ msgid "Nginx restarted successfully"
 msgstr "تم إعادة تشغيل Nginx بنجاح"
 msgstr "تم إعادة تشغيل Nginx بنجاح"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1691,7 +1719,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "إشعار"
 msgstr "إشعار"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr "الإشعارات"
 msgstr "الإشعارات"
 
 
@@ -1715,7 +1743,7 @@ msgstr ""
 "قد يتسبب وجوب تثبيت OCSP في حدوث أخطاء لبعض المستخدمين عند الوصول لأول مرة "
 "قد يتسبب وجوب تثبيت OCSP في حدوث أخطاء لبعض المستخدمين عند الوصول لأول مرة "
 "باستخدام Firefox."
 "باستخدام Firefox."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1730,7 +1758,7 @@ msgid "Ok"
 msgstr "حسنًا"
 msgstr "حسنًا"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1739,7 +1767,6 @@ msgstr "حسنًا"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1749,8 +1776,8 @@ msgstr "حسنًا"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 msgstr "بمجرد اكتمال التحقق، سيتم إزالة السجلات."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1780,18 +1807,16 @@ msgstr "نظام التشغيل"
 msgid "OS:"
 msgid "OS:"
 msgstr "نظام التشغيل:"
 msgstr "نظام التشغيل:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 #, fuzzy
 #, fuzzy
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "استخدم رمز الاسترداد"
 msgstr "استخدم رمز الاسترداد"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "الكتابة فوق"
 msgstr "الكتابة فوق"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "الكتابة فوق الملف الموجود"
 msgstr "الكتابة فوق الملف الموجود"
 
 
@@ -1889,6 +1914,7 @@ msgstr ""
 "يرجى أولاً إضافة بيانات الاعتماد في الشهادات > بيانات اعتماد DNS، ثم اختيار "
 "يرجى أولاً إضافة بيانات الاعتماد في الشهادات > بيانات اعتماد DNS، ثم اختيار "
 "أحد بيانات الاعتماد أدناه لطلب API لمزود DNS."
 "أحد بيانات الاعتماد أدناه لطلب API لمزود DNS."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1904,7 +1930,7 @@ msgstr "يرجى إدخال اسم الملف"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "يرجى إدخال اسم المجلد"
 msgstr "يرجى إدخال اسم المجلد"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1937,20 +1963,6 @@ msgstr "يرجى ملاحظة أن تكوين وحدات الوقت أدناه 
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "يرجى اختيار عقدة واحدة على الأقل للترقية"
 msgstr "يرجى اختيار عقدة واحدة على الأقل للترقية"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "يرجى اختيار عقدة واحدة على الأقل!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "يرجى ترقية واجهة Nginx البعيدة إلى أحدث إصدار"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2094,20 +2106,12 @@ msgstr "إعادة تحميل nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr "إزالة"
 msgstr "إزالة"
 
 
-#: src/components/Notification/config.ts:56
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "خطأ في إزالة الموقع %{site} من %{node}، الاستجابة: %{resp}"
-
-#: src/components/Notification/config.ts:48
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "تمت إزالة الموقع %{site} من %{node} بنجاح"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "إزالة بنجاح"
 msgstr "إزالة بنجاح"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "تمت الإزالة بنجاح"
 msgstr "تمت الإزالة بنجاح"
 
 
@@ -2116,44 +2120,63 @@ msgstr "تمت الإزالة بنجاح"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr "إعادة تسمية"
 msgstr "إعادة تسمية"
 
 
-#: src/components/Notification/config.ts:30
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
-msgstr ""
-"فشل إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name}، الاستجابة: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:28
+#, fuzzy
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
+msgstr "تم إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name} بنجاح"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "تم إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name} بنجاح"
 msgstr "تم إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name} بنجاح"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "خطأ في إعادة تسمية التكوين البعيد"
 msgstr "خطأ في إعادة تسمية التكوين البعيد"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "إعادة تسمية تكوين البعيد بنجاح"
 msgstr "إعادة تسمية تكوين البعيد بنجاح"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "خطأ في إعادة تسمية الموقع البعيد"
 msgstr "خطأ في إعادة تسمية الموقع البعيد"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "تم إعادة تسمية الموقع البعيد بنجاح"
 msgstr "تم إعادة تسمية الموقع البعيد بنجاح"
 
 
-#: src/components/Notification/config.ts:95
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
-msgstr ""
-"خطأ في إعادة تسمية الموقع %{site} إلى %{new_site} على %{node}، الاستجابة: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "خطأ في إعادة تسمية الموقع البعيد"
 
 
-#: src/components/Notification/config.ts:87
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "تم إعادة تسمية الموقع البعيد بنجاح"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "إعادة تسمية الموقع %{site} إلى %{new_site} على %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "إعادة تسمية الموقع %{site} إلى %{new_site} على %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:104
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr "إعادة تسمية الموقع %{site} إلى %{new_site} على %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:108
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "إعادة تسمية الموقع %{site} إلى %{new_site} على %{node} بنجاح"
 msgstr "إعادة تسمية الموقع %{site} إلى %{new_site} على %{node} بنجاح"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2162,6 +2185,7 @@ msgstr "إعادة التسمية بنجاح"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "تمت إعادة التسمية بنجاح"
 msgstr "تمت إعادة التسمية بنجاح"
 
 
@@ -2238,7 +2262,8 @@ msgstr "يعمل"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "حفظ"
 msgstr "حفظ"
 
 
@@ -2252,20 +2277,42 @@ msgstr "حفظ التوجيه"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "خطأ في الحفظ %{msg}"
 msgstr "خطأ في الحفظ %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "خطأ في حفظ الموقع البعيد"
 msgstr "خطأ في حفظ الموقع البعيد"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "حفظ الموقع البعيد بنجاح"
 msgstr "حفظ الموقع البعيد بنجاح"
 
 
-#: src/components/Notification/config.ts:43
-msgid "Save site %{site} to %{node} error, response: %{resp}"
-msgstr "خطأ في حفظ الموقع %{site} إلى %{node}، الاستجابة: %{resp}"
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "خطأ في حفظ الموقع البعيد"
 
 
-#: src/components/Notification/config.ts:35
-msgid "Save Site %{site} to %{node} successfully"
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "حفظ الموقع البعيد بنجاح"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
+msgstr "فشل نشر {conf_name}% إلى {node_name}%"
+
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
 msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2278,7 +2325,7 @@ msgstr "تم الحفظ بنجاح"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "تم الحفظ بنجاح"
 msgstr "تم الحفظ بنجاح"
 
 
@@ -2323,7 +2370,7 @@ msgstr "عامل server_name مطلوب"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "لم يتم العثور على الملف"
 msgstr "لم يتم العثور على الملف"
@@ -2438,7 +2485,7 @@ msgstr "مستقر"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "الحالة"
 msgstr "الحالة"
 
 
@@ -2451,6 +2498,16 @@ msgstr "متوقف"
 msgid "Storage"
 msgid "Storage"
 msgstr "تخزين"
 msgstr "تخزين"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "معطل"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "لم يتم العثور على الملف"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2492,6 +2549,7 @@ msgid "Switch to light theme"
 msgstr "التبديل إلى الوضع الفاتح"
 msgstr "التبديل إلى الوضع الفاتح"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "مزامنة"
 msgstr "مزامنة"
 
 
@@ -2499,43 +2557,38 @@ msgstr "مزامنة"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "مزامنة الشهادة"
 msgstr "مزامنة الشهادة"
 
 
-#: src/components/Notification/cert.ts:11
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، يرجى ترقية واجهة Nginx "
-"البعيدة إلى أحدث إصدار"
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr "فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، الاستجابة: %{resp}"
+#: src/components/Notification/notifications.ts:10
+#, fuzzy
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "نجح مزامنة الشهادة %{cert_name} إلى %{env_name}"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "نجح مزامنة الشهادة %{cert_name} إلى %{env_name}"
 msgstr "نجح مزامنة الشهادة %{cert_name} إلى %{env_name}"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "خطأ في مزامنة الشهادة"
 msgstr "خطأ في مزامنة الشهادة"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "تمت مزامنة الشهادة بنجاح"
 msgstr "تمت مزامنة الشهادة بنجاح"
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr "فشل مزامنة التكوين %{config_name} إلى %{env_name}، الاستجابة: %{resp}"
+#: src/components/Notification/notifications.ts:20
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "تمت مزامنة التكوين %{config_name} إلى %{env_name} بنجاح"
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "تمت مزامنة التكوين %{config_name} إلى %{env_name} بنجاح"
 msgstr "تمت مزامنة التكوين %{config_name} إلى %{env_name} بنجاح"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "خطأ في تزامن التكوين"
 msgstr "خطأ في تزامن التكوين"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "تمت مزامنة التكوين بنجاح"
 msgstr "تمت مزامنة التكوين بنجاح"
 
 
@@ -2564,10 +2617,6 @@ msgstr "نظام"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "مستخدم النظام الأولي"
 msgstr "مستخدم النظام الأولي"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "الهدف"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2709,7 +2758,7 @@ msgstr "يجب أن يكون هذا الحقل عنوان بريد إلكترو
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "يجب أن يكون هذا الحقل اسم مضيف صالحًا"
 msgstr "يجب أن يكون هذا الحقل اسم مضيف صالحًا"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "يجب ألا يكون هذا الحقل فارغًا"
 msgstr "يجب ألا يكون هذا الحقل فارغًا"
@@ -2832,7 +2881,7 @@ msgstr "تم التحديث بنجاح"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "محدث في"
 msgstr "محدث في"
 
 
@@ -2886,7 +2935,7 @@ msgstr "مستخدم"
 msgid "User banned"
 msgid "User banned"
 msgstr "المستخدم محظور"
 msgstr "المستخدم محظور"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -2913,7 +2962,7 @@ msgstr "إصدار"
 msgid "View"
 msgid "View"
 msgstr "عرض"
 msgstr "عرض"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "عرض جميع التنبيهات"
 msgstr "عرض جميع التنبيهات"
 
 
@@ -2960,7 +3009,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr "ويب أوثن"
 msgstr "ويب أوثن"
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3046,6 +3095,85 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "مفاتيح المرور الخاصة بك"
 msgstr "مفاتيح المرور الخاصة بك"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "تم نشر %{conf_name} إلى %{node_name} بنجاح"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "تم النشر بنجاح"
+
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "حدث خطأ في تعطيل الموقع %{site} على %{node}، الاستجابة: %{resp}"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "صفر؟"
+#~ msgstr[1] "هل تريد نشر هذا الملف إلى خادم بعيد؟"
+#~ msgstr[2] "هل تريد نشر هذا الملف إلى الخادمين البعيدة؟"
+#~ msgstr[3] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
+#~ msgstr[4] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
+#~ msgstr[5] "هل تريد نشر هذا الملف إلى الخوادم البعيدة؟"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "تم نسخ %{conf_name} إلى %{node_name} بنجاح"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "فشل التكرار"
+
+#~ msgid "Duplicate successfully"
+#~ msgstr "تم التكرار بنجاح"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "تم تفعيل %{conf_name} في %{node_name} بنجاح"
+
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "خطأ في تفعيل الموقع %{site} على %{node}، الاستجابة: %{resp}"
+
+#~ msgid "Enable successfully"
+#~ msgstr "تم التفعيل بنجاح"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "يرجى اختيار عقدة واحدة على الأقل!"
+
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "يرجى ترقية واجهة Nginx البعيدة إلى أحدث إصدار"
+
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "خطأ في إزالة الموقع %{site} من %{node}، الاستجابة: %{resp}"
+
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "فشل إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name}، الاستجابة: "
+#~ "%{resp}"
+
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "خطأ في إعادة تسمية الموقع %{site} إلى %{new_site} على %{node}، الاستجابة: "
+#~ "%{resp}"
+
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "خطأ في حفظ الموقع %{site} إلى %{node}، الاستجابة: %{resp}"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، يرجى ترقية واجهة Nginx "
+#~ "البعيدة إلى أحدث إصدار"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، الاستجابة: %{resp}"
+
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "فشل مزامنة التكوين %{config_name} إلى %{env_name}، الاستجابة: %{resp}"
+
+#~ msgid "Target"
+#~ msgstr "الهدف"
+
 #~ msgid ""
 #~ msgid ""
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "your 2FA."
 #~ "your 2FA."

+ 291 - 170
app/src/language/de_DE/app.po

@@ -94,7 +94,7 @@ msgid "Additional"
 msgstr "Ort hinzufügen"
 msgstr "Ort hinzufügen"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Erweiterter Modus"
 msgstr "Erweiterter Modus"
 
 
@@ -109,6 +109,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr "Alle"
 msgstr "Alle"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -171,7 +172,7 @@ msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 #, fuzzy
 #, fuzzy
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
@@ -268,7 +269,7 @@ msgstr "Automatische Verlängerung aktiviert für %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Zurück"
 msgstr "Zurück"
 
 
@@ -306,7 +307,7 @@ msgid "Basic"
 msgstr "Basic-Modus"
 msgstr "Basic-Modus"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Basic-Modus"
 msgstr "Basic-Modus"
 
 
@@ -356,17 +357,16 @@ msgstr "CA-Verzeichnis"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Abbrechen"
 msgstr "Abbrechen"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Verhindere das Ändern des Root-Passworts in der Demo"
 msgstr "Verhindere das Ändern des Root-Passworts in der Demo"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 #, fuzzy
 #, fuzzy
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "System-Startbenutzer"
 msgstr "System-Startbenutzer"
@@ -477,12 +477,12 @@ msgid "Cleaning environment variables"
 msgstr "Säuberung von Umgebungsvariablen"
 msgstr "Säuberung von Umgebungsvariablen"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Säubern"
 msgstr "Säubern"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 #, fuzzy
 #, fuzzy
 msgid "Cleared successfully"
 msgid "Cleared successfully"
@@ -664,20 +664,50 @@ msgstr "Löschen"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "Permanent löschen"
 msgstr "Permanent löschen"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Speichern erfolgreich"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Seite löschen: %{site_name}"
 msgstr "Seite löschen: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Speichern erfolgreich"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "Stream löschen: %{stream_name}"
 msgstr "Stream löschen: %{stream_name}"
@@ -688,30 +718,15 @@ msgid "Deleted successfully"
 msgstr "Erfolgreich deaktiviert"
 msgstr "Erfolgreich deaktiviert"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Ausführen"
 msgstr "Ausführen"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Ausführen von %{conf_name} auf %{node_name} erfolgreich"
-
-#: src/views/stream/components/Deploy.vue:34
-#, fuzzy
-msgid "Deploy successfully"
-msgstr "Speichern erfolgreich"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Beschreibung"
 msgstr "Beschreibung"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -753,32 +768,52 @@ msgstr "Deaktiviert"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Automatische Verlängerung deaktiviert für %{name}"
 msgstr "Automatische Verlängerung deaktiviert für %{name}"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:91
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable Remote Stream Success"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:50
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Speichern erfolgreich"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "Aktivieren von %{conf_name} in %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Deaktiviert"
 msgstr "Deaktiviert"
 
 
@@ -812,13 +847,6 @@ msgstr ""
 "Aktiviere diese Option nicht, es sei denn, du bist sicher, dass du sie "
 "Aktiviere diese Option nicht, es sei denn, du bist sicher, dass du sie "
 "benötigst."
 "benötigst."
 
 
-#: src/views/stream/components/Deploy.vue:16
-#, fuzzy
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
-msgstr[1] "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "Möchtest du die automatische Zertifikatsverlängerung deaktivieren?"
 msgstr "Möchtest du die automatische Zertifikatsverlängerung deaktivieren?"
@@ -903,28 +931,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Duplizieren"
 msgstr "Duplizieren"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-#, fuzzy
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Erfolgreich dupliziert"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-#, fuzzy
-msgid "Duplicate failed"
-msgstr "Anlegen fehlgeschlagen"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "Erfolgreich dupliziert"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 #, fuzzy
 #, fuzzy
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Erfolgreich dupliziert"
 msgstr "Erfolgreich dupliziert"
@@ -935,7 +948,7 @@ msgid "Edit"
 msgstr "Bearbeiten %{n}"
 msgstr "Bearbeiten %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Bearbeiten %{n}"
 msgstr "Bearbeiten %{n}"
 
 
@@ -962,20 +975,11 @@ msgid "Email (*)"
 msgstr "Email (*)"
 msgstr "Email (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 #, fuzzy
 #, fuzzy
 msgid "Enable"
 msgid "Enable"
 msgstr "Aktivieren"
 msgstr "Aktivieren"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Aktivieren von %{conf_name} in %{node_name} fehlgeschlagen"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Aktivieren von %{conf_name} in %{node_name} erfolgreich"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 #, fuzzy
 #, fuzzy
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
@@ -989,30 +993,45 @@ msgstr "Aktiviere automatische Verlängerung fehlgeschlagen für %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Aktivieren fehlgeschlagen"
 msgstr "Aktivieren fehlgeschlagen"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "Erfolgreich gespeichert"
+msgid "Enable Remote Stream Error"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:54
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} failed"
+msgstr "Aktivieren von %{conf_name} in %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Erfolgreich gespeichert"
 msgstr "Erfolgreich gespeichert"
 
 
-#: src/views/stream/components/Deploy.vue:41
+#: src/components/Notification/notifications.ts:96
 #, fuzzy
 #, fuzzy
-msgid "Enable successfully"
-msgstr "Erfolgreich aktiviert"
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Aktivieren von %{conf_name} in %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Erfolgreich gespeichert"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -1031,7 +1050,7 @@ msgstr "Aktiviere TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Aktiviert"
 msgstr "Aktiviert"
@@ -1039,7 +1058,6 @@ msgstr "Aktiviert"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Erfolgreich aktiviert"
 msgstr "Erfolgreich aktiviert"
@@ -1426,6 +1444,10 @@ msgstr "Leeer lassen, wenn du dies nicht benötigst."
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Leeer lassen, wenn du dies nicht benötigst."
 msgstr "Leeer lassen, wenn du dies nicht benötigst."
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Legoe deaktiviert CNAME-Unterstützung"
 msgstr "Legoe deaktiviert CNAME-Unterstützung"
@@ -1459,7 +1481,7 @@ msgid "Load successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 #, fuzzy
 #, fuzzy
 msgid "Local"
 msgid "Local"
 msgstr "Ort"
 msgstr "Ort"
@@ -1605,7 +1627,7 @@ msgstr "Einzelne Anweisung"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Name"
 msgstr "Name"
@@ -1679,7 +1701,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 #, fuzzy
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Name der Konfiguration"
 msgstr "Name der Konfiguration"
@@ -1732,7 +1754,7 @@ msgid "Nginx restarted successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1788,7 +1810,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
@@ -1814,7 +1836,7 @@ msgstr ""
 "OCSP Must Staple kann bei einigen Benutzern beim ersten Zugriff mit Firefox "
 "OCSP Must Staple kann bei einigen Benutzern beim ersten Zugriff mit Firefox "
 "Fehler verursachen."
 "Fehler verursachen."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1829,7 +1851,7 @@ msgid "Ok"
 msgstr "OK"
 msgstr "OK"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1838,7 +1860,6 @@ msgstr "OK"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1849,8 +1870,8 @@ msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfernt."
 "Sobaöd die Überprüfung abgeschlossen ist, werden die Einträge entfernt."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1881,18 +1902,16 @@ msgstr "OS:"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS:"
 msgstr "OS:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 #, fuzzy
 #, fuzzy
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "Benuzte Wiederherstellungscode"
 msgstr "Benuzte Wiederherstellungscode"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "Überschreiben"
 msgstr "Überschreiben"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "Zu überschreibende Datei existiert"
 msgstr "Zu überschreibende Datei existiert"
 
 
@@ -1994,6 +2013,7 @@ msgstr ""
 "Anmeldeinformationen hinzu und wähle dann eine der unten aufgeführten "
 "Anmeldeinformationen hinzu und wähle dann eine der unten aufgeführten "
 "Anmeldeinformationen aus, um die API des DNS-Anbieters anzufordern."
 "Anmeldeinformationen aus, um die API des DNS-Anbieters anzufordern."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -2011,7 +2031,7 @@ msgstr "Bitte Benutzernamen eingeben!"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Bitte Benutzernamen eingeben!"
 msgstr "Bitte Benutzernamen eingeben!"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -2050,21 +2070,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "Bitte wähle mindestens einen Knoten zum Upgrade aus"
 msgstr "Bitte wähle mindestens einen Knoten zum Upgrade aus"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "Bitte wähle mindestens einen Knoten aus!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "Speichern erfolgreich"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2216,23 +2221,13 @@ msgstr "Lade Nginx neu"
 msgid "Remove"
 msgid "Remove"
 msgstr "Löschen"
 msgstr "Löschen"
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Speichern erfolgreich"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Speichern erfolgreich"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
@@ -2242,49 +2237,69 @@ msgstr "Speichern erfolgreich"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "Benuztername"
 msgstr "Benuztername"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Speichern erfolgreich"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Speichern erfolgreich"
+
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2294,6 +2309,7 @@ msgstr "Aktivierung erfolgreich"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Aktivierung erfolgreich"
 msgstr "Aktivierung erfolgreich"
@@ -2376,7 +2392,8 @@ msgstr "Arbeite"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Speichern"
 msgstr "Speichern"
 
 
@@ -2390,24 +2407,44 @@ msgstr "Anweisung speichern"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Fehler beim Speichern %{msg}"
 msgstr "Fehler beim Speichern %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save Remote Stream Error"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Zertifikat ist gültig"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:74
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Speichern erfolgreich"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
+msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
+
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2421,7 +2458,7 @@ msgstr "Speichern erfolgreich"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
@@ -2467,7 +2504,7 @@ msgstr "server_name-Parameter ist erforderlich"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "File Not Found"
 msgstr "File Not Found"
@@ -2587,7 +2624,7 @@ msgstr "Altiviert"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Status"
 msgstr "Status"
 
 
@@ -2600,6 +2637,16 @@ msgstr "Gestoppt"
 msgid "Storage"
 msgid "Storage"
 msgstr "Speicher"
 msgstr "Speicher"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Deaktiviert"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "File Not Found"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2639,6 +2686,7 @@ msgid "Switch to light theme"
 msgstr "Zum hellen Thema wechseln"
 msgstr "Zum hellen Thema wechseln"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "Synchronisieren"
 msgstr "Synchronisieren"
 
 
@@ -2647,49 +2695,42 @@ msgstr "Synchronisieren"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/cert.ts:11
-#, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr "Speichern erfolgreich"
-
-#: src/components/Notification/cert.ts:14
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Speichern erfolgreich"
 msgstr "Speichern erfolgreich"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
@@ -2720,10 +2761,6 @@ msgstr "System"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "System-Startbenutzer"
 msgstr "System-Startbenutzer"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "Ziel"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2868,7 +2905,7 @@ msgstr "Dieses Feld sollte eine gültige E-Mail-Adresse sein"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "Dieses Feld sollte ein gültiger Hostname sein"
 msgstr "Dieses Feld sollte ein gültiger Hostname sein"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "Dieses Feld darf nicht leer sein"
 msgstr "Dieses Feld darf nicht leer sein"
@@ -2991,7 +3028,7 @@ msgstr "Speichern erfolgreich"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Aktualisiert am"
 msgstr "Aktualisiert am"
 
 
@@ -3049,7 +3086,7 @@ msgstr "Benuztername"
 msgid "User banned"
 msgid "User banned"
 msgstr "Benuzter ist gesperrt"
 msgstr "Benuzter ist gesperrt"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -3076,7 +3113,7 @@ msgstr ""
 msgid "View"
 msgid "View"
 msgstr "Anzeigen"
 msgstr "Anzeigen"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Zertifikat ist gültig"
 msgstr "Zertifikat ist gültig"
@@ -3127,7 +3164,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr "Webauthn"
 msgstr "Webauthn"
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3216,6 +3253,90 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Deine Passkeys"
 msgstr "Deine Passkeys"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Ausführen von %{conf_name} auf %{node_name} erfolgreich"
+
+#, fuzzy
+#~ msgid "Deploy successfully"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
+#~ msgstr[1] "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
+
+#, fuzzy
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Erfolgreich dupliziert"
+
+#, fuzzy
+#~ msgid "Duplicate failed"
+#~ msgstr "Anlegen fehlgeschlagen"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "Erfolgreich dupliziert"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Aktivieren von %{conf_name} in %{node_name} erfolgreich"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Erfolgreich gespeichert"
+
+#, fuzzy
+#~ msgid "Enable successfully"
+#~ msgstr "Erfolgreich aktiviert"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "Bitte wähle mindestens einen Knoten aus!"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Speichern erfolgreich"
+
+#~ msgid "Target"
+#~ msgstr "Ziel"
+
 #~ msgid "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 #~ msgid "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 #~ msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 #~ msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 
 

+ 286 - 173
app/src/language/en/app.po

@@ -95,7 +95,7 @@ msgid "Additional"
 msgstr "Add Location"
 msgstr "Add Location"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Advance Mode"
 msgstr "Advance Mode"
 
 
@@ -108,6 +108,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -171,7 +172,7 @@ msgstr "Are you sure you want to remove this directive?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Are you sure you want to remove this directive?"
 msgstr "Are you sure you want to remove this directive?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 #, fuzzy
 #, fuzzy
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
@@ -266,7 +267,7 @@ msgstr "Auto-renewal enabled for %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Back"
 msgstr "Back"
 
 
@@ -304,7 +305,7 @@ msgid "Basic"
 msgstr "Basic Mode"
 msgstr "Basic Mode"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Basic Mode"
 msgstr "Basic Mode"
 
 
@@ -353,16 +354,15 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Cancel"
 msgstr "Cancel"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr ""
 msgstr ""
 
 
@@ -472,12 +472,12 @@ msgid "Cleaning environment variables"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 #, fuzzy
 #, fuzzy
 msgid "Cleared successfully"
 msgid "Cleared successfully"
@@ -657,20 +657,50 @@ msgstr ""
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr ""
 msgstr ""
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Saved successfully"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Saved successfully"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr ""
 msgstr ""
@@ -681,32 +711,15 @@ msgid "Deleted successfully"
 msgstr "Disabled successfully"
 msgstr "Disabled successfully"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:57
-#, fuzzy
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Saved successfully"
-
-#: src/views/stream/components/Deploy.vue:36
-#, fuzzy
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Saved successfully"
-
-#: src/views/stream/components/Deploy.vue:34
-#, fuzzy
-msgid "Deploy successfully"
-msgstr "Saved successfully"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -748,32 +761,52 @@ msgstr "Disabled"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Disable auto-renewal failed for %{name}"
 msgstr "Disable auto-renewal failed for %{name}"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:50
+#, fuzzy
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:88
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable stream %{name} from %{node} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:92
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Disabled"
 msgstr "Disabled"
 
 
@@ -805,13 +838,6 @@ msgstr ""
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:16
-#, fuzzy
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Are you sure you want to remove this directive?"
-msgstr[1] "Are you sure you want to remove this directive?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 #, fuzzy
 #, fuzzy
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
@@ -892,29 +918,14 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 #, fuzzy
 #, fuzzy
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Enable failed"
 msgstr "Enable failed"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-#, fuzzy
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Saved successfully"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-#, fuzzy
-msgid "Duplicate failed"
-msgstr "Enable failed"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "Saved successfully"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 #, fuzzy
 #, fuzzy
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
@@ -925,7 +936,7 @@ msgid "Edit"
 msgstr "Edit %{n}"
 msgstr "Edit %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Edit %{n}"
 msgstr "Edit %{n}"
 
 
@@ -952,22 +963,11 @@ msgid "Email (*)"
 msgstr "Email (*)"
 msgstr "Email (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 #, fuzzy
 #, fuzzy
 msgid "Enable"
 msgid "Enable"
 msgstr "Enabled"
 msgstr "Enabled"
 
 
-#: src/views/stream/components/Deploy.vue:47
-#, fuzzy
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Saved successfully"
-
-#: src/views/stream/components/Deploy.vue:43
-#, fuzzy
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Saved successfully"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 #, fuzzy
 #, fuzzy
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
@@ -981,30 +981,45 @@ msgstr "Enable auto-renewal failed for %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Enable failed"
 msgstr "Enable failed"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
+#, fuzzy
+msgid "Enable Remote Stream Error"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:99
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
+msgid "Enable Remote Stream Success"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:58
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/views/stream/components/Deploy.vue:41
+#: src/components/Notification/notifications.ts:96
 #, fuzzy
 #, fuzzy
-msgid "Enable successfully"
-msgstr "Enabled successfully"
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Saved successfully"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -1023,7 +1038,7 @@ msgstr "Enable TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Enabled"
 msgstr "Enabled"
@@ -1031,7 +1046,6 @@ msgstr "Enabled"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Enabled successfully"
 msgstr "Enabled successfully"
@@ -1412,6 +1426,10 @@ msgstr "Leave blank for no change"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Leave blank for no change"
 msgstr "Leave blank for no change"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr ""
 msgstr ""
@@ -1445,7 +1463,7 @@ msgid "Load successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 #, fuzzy
 #, fuzzy
 msgid "Local"
 msgid "Local"
 msgstr "Location"
 msgstr "Location"
@@ -1584,7 +1602,7 @@ msgstr "Single Directive"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Name"
 msgstr "Name"
@@ -1658,7 +1676,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 #, fuzzy
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Configuration Name"
 msgstr "Configuration Name"
@@ -1712,7 +1730,7 @@ msgid "Nginx restarted successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1766,7 +1784,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
@@ -1791,7 +1809,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1806,7 +1824,7 @@ msgid "Ok"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1815,7 +1833,6 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1825,8 +1842,8 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1857,17 +1874,15 @@ msgstr "OS:"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS:"
 msgstr "OS:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr ""
 msgstr ""
 
 
@@ -1960,6 +1975,7 @@ msgid ""
 "select one of the credentialsbelow to request the API of the DNS provider."
 "select one of the credentialsbelow to request the API of the DNS provider."
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1977,7 +1993,7 @@ msgstr "Please input your username!"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Please input your username!"
 msgstr "Please input your username!"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -2010,21 +2026,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr ""
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "Saved successfully"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2176,23 +2177,13 @@ msgstr ""
 msgid "Remove"
 msgid "Remove"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Saved successfully"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Saved successfully"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
@@ -2202,49 +2193,69 @@ msgstr "Saved successfully"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "Username"
 msgstr "Username"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2254,6 +2265,7 @@ msgstr "Enabled successfully"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Enabled successfully"
 msgstr "Enabled successfully"
@@ -2336,7 +2348,8 @@ msgstr ""
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Save"
 msgstr "Save"
 
 
@@ -2350,24 +2363,44 @@ msgstr "Save Directive"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Save error %{msg}"
 msgstr "Save error %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Certificate is valid"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Saved successfully"
+
+#: src/components/Notification/notifications.ts:112
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save stream %{name} to %{node} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:116
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2381,7 +2414,7 @@ msgstr "Saved successfully"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
@@ -2427,7 +2460,7 @@ msgstr "server_name parameter is required"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "File Not Found"
 msgstr "File Not Found"
@@ -2547,7 +2580,7 @@ msgstr "Enabled"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Status"
 msgstr "Status"
 
 
@@ -2560,6 +2593,16 @@ msgstr ""
 msgid "Storage"
 msgid "Storage"
 msgstr "Storage"
 msgstr "Storage"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Disabled"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "File Not Found"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2601,6 +2644,7 @@ msgid "Switch to light theme"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr ""
 msgstr ""
 
 
@@ -2609,49 +2653,42 @@ msgstr ""
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/cert.ts:11
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr "Saved successfully"
-
-#: src/components/Notification/cert.ts:14
-#, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Saved successfully"
 msgstr "Saved successfully"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
@@ -2683,10 +2720,6 @@ msgstr ""
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr ""
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2823,7 +2856,7 @@ msgstr ""
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr ""
 msgstr ""
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr ""
 msgstr ""
@@ -2931,7 +2964,7 @@ msgstr "Saved successfully"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Updated at"
 msgstr "Updated at"
 
 
@@ -2989,7 +3022,7 @@ msgstr "Username"
 msgid "User banned"
 msgid "User banned"
 msgstr "Username"
 msgstr "Username"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -3018,7 +3051,7 @@ msgstr ""
 msgid "View"
 msgid "View"
 msgstr "Basic Mode"
 msgstr "Basic Mode"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
@@ -3065,7 +3098,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3147,6 +3180,86 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr ""
 msgstr ""
 
 
+#, fuzzy
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Deploy successfully"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Are you sure you want to remove this directive?"
+#~ msgstr[1] "Are you sure you want to remove this directive?"
+
+#, fuzzy
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Duplicate failed"
+#~ msgstr "Enable failed"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Enable successfully"
+#~ msgstr "Enabled successfully"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Saved successfully"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Saved successfully"
+
 #, fuzzy
 #, fuzzy
 #~ msgid "Directory"
 #~ msgid "Directory"
 #~ msgstr "Directive"
 #~ msgstr "Directive"

+ 305 - 181
app/src/language/es/app.po

@@ -96,7 +96,7 @@ msgid "Additional"
 msgstr "Adicional"
 msgstr "Adicional"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Modo avanzado"
 msgstr "Modo avanzado"
 
 
@@ -111,6 +111,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr "Todo"
 msgstr "Todo"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -172,7 +173,7 @@ msgstr "¿Está seguro de que quiere borrar?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "¿Está seguro de que quiere borrar?"
 msgstr "¿Está seguro de que quiere borrar?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "¿Está seguro de que desea borrar todas las notificaciones?"
 msgstr "¿Está seguro de que desea borrar todas las notificaciones?"
@@ -260,7 +261,7 @@ msgstr "Renovación automática habilitada por %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Volver"
 msgstr "Volver"
 
 
@@ -296,7 +297,7 @@ msgid "Basic"
 msgstr "Básico"
 msgstr "Básico"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Modo Básico"
 msgstr "Modo Básico"
 
 
@@ -346,17 +347,16 @@ msgstr "Directorio CA"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Cancelar"
 msgstr "Cancelar"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Prohibir cambiar la contraseña de root en la demostración"
 msgstr "Prohibir cambiar la contraseña de root en la demostración"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 #, fuzzy
 #, fuzzy
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "Usuario inicial del sistema"
 msgstr "Usuario inicial del sistema"
@@ -460,12 +460,12 @@ msgid "Cleaning environment variables"
 msgstr "Borrar las variables de entorno"
 msgstr "Borrar las variables de entorno"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Borrar"
 msgstr "Borrar"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "Limpiado exitoso"
 msgstr "Limpiado exitoso"
@@ -641,18 +641,48 @@ msgstr "Eliminar"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "Eliminar Permanentemente"
 msgstr "Eliminar Permanentemente"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Error al eliminar sitio remoto"
 msgstr "Error al eliminar sitio remoto"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Borrado del sitio remoto correcto"
 msgstr "Borrado del sitio remoto correcto"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Error al eliminar sitio remoto"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Borrado del sitio remoto correcto"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Eliminar sitio: %{site_name}"
 msgstr "Eliminar sitio: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "Eliminar stream: %{site_name}"
 msgstr "Eliminar stream: %{site_name}"
@@ -662,29 +692,15 @@ msgid "Deleted successfully"
 msgstr "Borrado exitoso"
 msgstr "Borrado exitoso"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Desplegar"
 msgstr "Desplegar"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Desplegado de %{conf_name} a %{node_name} exitoso"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "Desplegado con éxito"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Descripción"
 msgstr "Descripción"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -725,29 +741,50 @@ msgstr "Desactivar"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "No se pudo desactivar la renovación automática por %{name}"
 msgstr "No se pudo desactivar la renovación automática por %{name}"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Error al deshabilitar el sitio remoto"
 msgstr "Error al deshabilitar el sitio remoto"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Deshabilitado de sitio remoto exitoso"
 msgstr "Deshabilitado de sitio remoto exitoso"
 
 
-#: src/components/Notification/config.ts:82
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
-msgstr "Error al deshabilitar el sitio %{site} en %{node}, respuesta: %{resp}"
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Error al deshabilitar el sitio remoto"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Deshabilitado de sitio remoto exitoso"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
+
+#: src/components/Notification/notifications.ts:50
+#, fuzzy
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "Falló el habilitado de %{conf_name} en %{node_name}"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:92
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Desactivado"
 msgstr "Desactivado"
 
 
@@ -779,12 +816,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "No habilite esta opción a menos que esté seguro de que la necesita."
 msgstr "No habilite esta opción a menos que esté seguro de que la necesita."
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "¿Desea desplegar este archivo en un servidor remoto?"
-msgstr[1] "¿Desea desplegar este archivo en los servidores remotos?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "¿Desea deshabilitar la renovación automática de certificado?"
 msgstr "¿Desea deshabilitar la renovación automática de certificado?"
@@ -862,25 +893,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Duplicar"
 msgstr "Duplicar"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "Duplicado fallido"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr "Duplicado con éxito"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Duplicado con éxito a local"
 msgstr "Duplicado con éxito a local"
 
 
@@ -890,7 +909,7 @@ msgid "Edit"
 msgstr "Editar %{n}"
 msgstr "Editar %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Editar %{n}"
 msgstr "Editar %{n}"
 
 
@@ -915,19 +934,10 @@ msgid "Email (*)"
 msgstr "Correo (*)"
 msgstr "Correo (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "Habilitar"
 msgstr "Habilitar"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Falló el habilitado de %{conf_name} en %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "Habilitar 2FA exitoso"
 msgstr "Habilitar 2FA exitoso"
@@ -940,29 +950,45 @@ msgstr "No se pudo activar la renovación automática por %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Falló la habilitación"
 msgstr "Falló la habilitación"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Error al renombrar la configuración remota"
 msgstr "Error al renombrar la configuración remota"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Renombrar Configuración Remota Exitosa"
 msgstr "Renombrar Configuración Remota Exitosa"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
+msgid "Enable Remote Stream Error"
+msgstr "Error al renombrar la configuración remota"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "Renombrar Configuración Remota Exitosa"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:54
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} failed"
+msgstr "Falló el habilitado de %{conf_name} en %{node_name}"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "Habilitado con Éxito"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Falló el habilitado de %{conf_name} en %{node_name}"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -981,7 +1007,7 @@ msgstr "Habilitar TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Habilitado"
 msgstr "Habilitado"
@@ -989,7 +1015,6 @@ msgstr "Habilitado"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Habilitado con éxito"
 msgstr "Habilitado con éxito"
@@ -1359,6 +1384,10 @@ msgstr "Déjelo en blanco si no lo necesita."
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Dejarlo en blanco no cambiará nada"
 msgstr "Dejarlo en blanco no cambiará nada"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Lego deshabilita el soporte de CNAME"
 msgstr "Lego deshabilita el soporte de CNAME"
@@ -1389,7 +1418,7 @@ msgid "Load successfully"
 msgstr "Cargado con éxito"
 msgstr "Cargado con éxito"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "Local"
 msgstr "Local"
 
 
@@ -1525,7 +1554,7 @@ msgstr "Directiva multilínea"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Nombre"
 msgstr "Nombre"
@@ -1597,7 +1626,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Error de análisis de configuración de Nginx"
 msgstr "Error de análisis de configuración de Nginx"
 
 
@@ -1649,7 +1678,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx reiniciado con éxito"
 msgstr "Nginx reiniciado con éxito"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1704,7 +1733,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Notificación"
 msgstr "Notificación"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Notificaciones"
 msgstr "Notificaciones"
 
 
@@ -1728,7 +1757,7 @@ msgstr ""
 "OCSP Must Staple puede causar errores para algunos usuarios en el primer "
 "OCSP Must Staple puede causar errores para algunos usuarios en el primer "
 "acceso usando Firefox."
 "acceso usando Firefox."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1743,7 +1772,7 @@ msgid "Ok"
 msgstr "Ok"
 msgstr "Ok"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1752,7 +1781,6 @@ msgstr "Ok"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1762,8 +1790,8 @@ msgstr "OK"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1793,18 +1821,16 @@ msgstr "SO"
 msgid "OS:"
 msgid "OS:"
 msgstr "SO:"
 msgstr "SO:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 #, fuzzy
 #, fuzzy
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "Usar código de recuperación"
 msgstr "Usar código de recuperación"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "Sobrescribir"
 msgstr "Sobrescribir"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "Sobrescribir archivo existente"
 msgstr "Sobrescribir archivo existente"
 
 
@@ -1908,6 +1934,7 @@ msgstr ""
 "luego seleccione una de las credenciales de aquí debajo para llamar a la API "
 "luego seleccione una de las credenciales de aquí debajo para llamar a la API "
 "del proveedor de DNS."
 "del proveedor de DNS."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1923,7 +1950,7 @@ msgstr "Por favor, ingrese un nombre de archivo"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Por favor, introduzca un nombre de carpeta"
 msgstr "Por favor, introduzca un nombre de carpeta"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1962,24 +1989,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "Seleccione al menos un nodo para actualizar"
 msgstr "Seleccione al menos un nodo para actualizar"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "¡Seleccione al menos un nodo!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr ""
-"Sincronización de la configuración %{cert_name} a %{env_name} falló, por "
-"favor actualiza la interfaz de usuario de Nginx en el servidor remoto a la "
-"última versión"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2128,22 +2137,12 @@ msgstr "Recargando Nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr "Eliminar"
 msgstr "Eliminar"
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Eliminar sitio: %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Eliminado con éxito"
 msgstr "Eliminado con éxito"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Eliminado con éxito"
 msgstr "Eliminado con éxito"
 
 
@@ -2152,45 +2151,65 @@ msgstr "Eliminado con éxito"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr "Renombrar"
 msgstr "Renombrar"
 
 
-#: src/components/Notification/config.ts:30
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
-msgstr ""
-"Renombrar %{orig_path} a %{new_path} en %{env_name} falló, respuesta: %{resp}"
+#: src/components/Notification/notifications.ts:28
+#, fuzzy
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
+msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Error al renombrar la configuración remota"
 msgstr "Error al renombrar la configuración remota"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Renombrar Configuración Remota Exitosa"
 msgstr "Renombrar Configuración Remota Exitosa"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Error al renombrar la configuración remota"
 msgstr "Error al renombrar la configuración remota"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Renombrar Configuración Remota Exitosa"
 msgstr "Renombrar Configuración Remota Exitosa"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "Error al renombrar la configuración remota"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Renombrar Configuración Remota Exitosa"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
+
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2199,6 +2218,7 @@ msgstr "Renombrado con éxito"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Renombrado con éxito"
 msgstr "Renombrado con éxito"
@@ -2276,7 +2296,8 @@ msgstr "Corriendo"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Guardar"
 msgstr "Guardar"
 
 
@@ -2290,26 +2311,44 @@ msgstr "Guardar Directiva"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Error al guardar %{msg}"
 msgstr "Error al guardar %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Error al renombrar la configuración remota"
 msgstr "Error al renombrar la configuración remota"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Renombrar Configuración Remota Exitosa"
 msgstr "Renombrar Configuración Remota Exitosa"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
-msgstr ""
-"Sincronización del Certificado %{cert_name} a %{env_name} falló, respuesta: "
-"%{resp}"
+msgid "Save Remote Stream Error"
+msgstr "Error al renombrar la configuración remota"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:115
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save Remote Stream Success"
+msgstr "Renombrar Configuración Remota Exitosa"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
+msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
+
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2322,7 +2361,7 @@ msgstr "Guardado con éxito"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Guardado con éxito"
 msgstr "Guardado con éxito"
 
 
@@ -2369,7 +2408,7 @@ msgstr "Se requiere el parámetro server_name"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "Archivo no Encontrado"
 msgstr "Archivo no Encontrado"
@@ -2482,7 +2521,7 @@ msgstr "Estable"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Estado"
 msgstr "Estado"
 
 
@@ -2495,6 +2534,16 @@ msgstr "Detenido"
 msgid "Storage"
 msgid "Storage"
 msgstr "Almacenamiento"
 msgstr "Almacenamiento"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Certificado automático"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "Archivo no Encontrado"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2535,6 +2584,7 @@ msgid "Switch to light theme"
 msgstr "Cambiar al tema claro"
 msgstr "Cambiar al tema claro"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "Sincronizar"
 msgstr "Sincronizar"
 
 
@@ -2542,47 +2592,38 @@ msgstr "Sincronizar"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Sincronizar Certificado"
 msgstr "Sincronizar Certificado"
 
 
-#: src/components/Notification/cert.ts:11
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"Sincronización del Certificado %{cert_name} a %{env_name} fallida, por favor "
-"actualice la interfaz de Nginx remota a la última versión"
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Sincronización del Certificado %{cert_name} a %{env_name} falló, respuesta: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:10
+#, fuzzy
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "Sincronización del Certificado %{cert_name} a %{env_name} exitosa"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Sincronización del Certificado %{cert_name} a %{env_name} exitosa"
 msgstr "Sincronización del Certificado %{cert_name} a %{env_name} exitosa"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Error de Certificado de Sincronización"
 msgstr "Error de Certificado de Sincronización"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Sincronización del Certificado exitosa"
 msgstr "Sincronización del Certificado exitosa"
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Sincronización de la configuración %{config_name} a %{env_name} fallida, "
-"respuesta: %{resp}"
+#: src/components/Notification/notifications.ts:20
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "Sincronizar configuración %{config_name} con %{env_name} exitosamente"
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Sincronizar configuración %{config_name} con %{env_name} exitosamente"
 msgstr "Sincronizar configuración %{config_name} con %{env_name} exitosamente"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Error de Configuración de Sincronización"
 msgstr "Error de Configuración de Sincronización"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Configuración de sincronización exitosa"
 msgstr "Configuración de sincronización exitosa"
 
 
@@ -2613,10 +2654,6 @@ msgstr "Sistema"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "Usuario inicial del sistema"
 msgstr "Usuario inicial del sistema"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "Objetivo"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2765,7 +2802,7 @@ msgstr "Este campo no debe estar vacío"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "Este campo no debe estar vacío"
 msgstr "Este campo no debe estar vacío"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "Este campo no debe estar vacío"
 msgstr "Este campo no debe estar vacío"
@@ -2892,7 +2929,7 @@ msgstr "Actualización exitosa"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Actualizado a"
 msgstr "Actualizado a"
 
 
@@ -2946,7 +2983,7 @@ msgstr "Usuario"
 msgid "User banned"
 msgid "User banned"
 msgstr "El usuario está bloqueado"
 msgstr "El usuario está bloqueado"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -2973,7 +3010,7 @@ msgstr "Versión"
 msgid "View"
 msgid "View"
 msgstr "Ver"
 msgstr "Ver"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Ver todas las notificaciones"
 msgstr "Ver todas las notificaciones"
 
 
@@ -3022,7 +3059,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr "Webauthn"
 msgstr "Webauthn"
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3111,6 +3148,93 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Sus llaves de acceso"
 msgstr "Sus llaves de acceso"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Desplegado de %{conf_name} a %{node_name} exitoso"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "Desplegado con éxito"
+
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "Error al deshabilitar el sitio %{site} en %{node}, respuesta: %{resp}"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "¿Desea desplegar este archivo en un servidor remoto?"
+#~ msgstr[1] "¿Desea desplegar este archivo en los servidores remotos?"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "Duplicado fallido"
+
+#~ msgid "Duplicate successfully"
+#~ msgstr "Duplicado con éxito"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
+
+#~ msgid "Enable successfully"
+#~ msgstr "Habilitado con Éxito"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "¡Seleccione al menos un nodo!"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "Sincronización de la configuración %{cert_name} a %{env_name} falló, por "
+#~ "favor actualiza la interfaz de usuario de Nginx en el servidor remoto a "
+#~ "la última versión"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Eliminar sitio: %{site_name}"
+
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "Renombrar %{orig_path} a %{new_path} en %{env_name} falló, respuesta: "
+#~ "%{resp}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Renombrar %{orig_path} a %{new_path} en %{env_name} con éxito"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "Sincronización del Certificado %{cert_name} a %{env_name} falló, "
+#~ "respuesta: %{resp}"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "Sincronización del Certificado %{cert_name} a %{env_name} fallida, por "
+#~ "favor actualice la interfaz de Nginx remota a la última versión"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Sincronización del Certificado %{cert_name} a %{env_name} falló, "
+#~ "respuesta: %{resp}"
+
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Sincronización de la configuración %{config_name} a %{env_name} fallida, "
+#~ "respuesta: %{resp}"
+
+#~ msgid "Target"
+#~ msgstr "Objetivo"
+
 #~ msgid "Can't scan? Use text key binding"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "¿No puede escanear? Utilice la vinculación con una llave de texto"
 #~ msgstr "¿No puede escanear? Utilice la vinculación con una llave de texto"
 
 

+ 286 - 173
app/src/language/fr_FR/app.po

@@ -99,7 +99,7 @@ msgid "Additional"
 msgstr "Supplémentaire"
 msgstr "Supplémentaire"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Mode avancé"
 msgstr "Mode avancé"
 
 
@@ -113,6 +113,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr "Tous"
 msgstr "Tous"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr "Tous les codes de récupération ont été utilisés"
 msgstr "Tous les codes de récupération ont été utilisés"
@@ -178,7 +179,7 @@ msgstr "Etes-vous sûr que vous voulez supprimer ?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 #, fuzzy
 #, fuzzy
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
@@ -272,7 +273,7 @@ msgstr "Renouvellement automatique activé pour %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Retour"
 msgstr "Retour"
 
 
@@ -308,7 +309,7 @@ msgid "Basic"
 msgstr "Basique"
 msgstr "Basique"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Mode simple"
 msgstr "Mode simple"
 
 
@@ -359,17 +360,16 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Annuler"
 msgstr "Annuler"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Interdire la modification du mot de passe root dans la démo"
 msgstr "Interdire la modification du mot de passe root dans la démo"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "Impossible de retirer l'utilisateur initial"
 msgstr "Impossible de retirer l'utilisateur initial"
 
 
@@ -483,12 +483,12 @@ msgid "Cleaning environment variables"
 msgstr "Nettoyage des variables d'environnement"
 msgstr "Nettoyage des variables d'environnement"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Effacer"
 msgstr "Effacer"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 #, fuzzy
 #, fuzzy
 msgid "Cleared successfully"
 msgid "Cleared successfully"
@@ -669,20 +669,50 @@ msgstr "Supprimer"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "Supprimer définitivement"
 msgstr "Supprimer définitivement"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Dupliqué avec succès"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Supprimer le site : %{site_name}"
 msgstr "Supprimer le site : %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Dupliqué avec succès"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 #, fuzzy
 #, fuzzy
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
@@ -694,32 +724,15 @@ msgid "Deleted successfully"
 msgstr "Désactivé avec succès"
 msgstr "Désactivé avec succès"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Déployer"
 msgstr "Déployer"
 
 
-#: src/views/stream/components/Deploy.vue:57
-#, fuzzy
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Dupliqué avec succès"
-
-#: src/views/stream/components/Deploy.vue:36
-#, fuzzy
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Dupliqué avec succès"
-
-#: src/views/stream/components/Deploy.vue:34
-#, fuzzy
-msgid "Deploy successfully"
-msgstr "Sauvegarde réussie"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Description"
 msgstr "Description"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr "Le fichier de destination existe déjà"
 msgstr "Le fichier de destination existe déjà"
 
 
@@ -762,32 +775,52 @@ msgstr "Désactivé"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "La désactivation du renouvellement automatique a échoué pour %{name}"
 msgstr "La désactivation du renouvellement automatique a échoué pour %{name}"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable Remote Stream Error"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:50
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Désactivé"
 msgstr "Désactivé"
 
 
@@ -820,13 +853,6 @@ msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 msgstr ""
 "N'activez pas cette option sauf si vous êtes sûr d'en avoir avez besoin."
 "N'activez pas cette option sauf si vous êtes sûr d'en avoir avez besoin."
 
 
-#: src/views/stream/components/Deploy.vue:16
-#, fuzzy
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Voulez-vous supprimer ce serveur ?"
-msgstr[1] "Voulez-vous supprimer ce serveur ?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "Voulez-vous désactiver le renouvellement automatique des certificats ?"
 msgstr "Voulez-vous désactiver le renouvellement automatique des certificats ?"
@@ -909,28 +935,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Dupliquer"
 msgstr "Dupliquer"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-#, fuzzy
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Dupliqué avec succès"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-#, fuzzy
-msgid "Duplicate failed"
-msgstr "Dupliquer"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "Dupliqué avec succès"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 #, fuzzy
 #, fuzzy
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
@@ -941,7 +952,7 @@ msgid "Edit"
 msgstr "Modifier %{n}"
 msgstr "Modifier %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Modifier %{n}"
 msgstr "Modifier %{n}"
 
 
@@ -968,22 +979,11 @@ msgid "Email (*)"
 msgstr "Email (*)"
 msgstr "Email (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 #, fuzzy
 #, fuzzy
 msgid "Enable"
 msgid "Enable"
 msgstr "Activé"
 msgstr "Activé"
 
 
-#: src/views/stream/components/Deploy.vue:47
-#, fuzzy
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Dupliqué avec succès"
-
-#: src/views/stream/components/Deploy.vue:43
-#, fuzzy
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Dupliqué avec succès"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 #, fuzzy
 #, fuzzy
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
@@ -997,30 +997,45 @@ msgstr "Échec de l'activation du renouvellement automatique pour %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Échec de l'activation"
 msgstr "Échec de l'activation"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
+#, fuzzy
+msgid "Enable Remote Stream Error"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:54
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
+msgid "Enable site %{name} on %{node} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:58
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/views/stream/components/Deploy.vue:41
+#: src/components/Notification/notifications.ts:96
 #, fuzzy
 #, fuzzy
-msgid "Enable successfully"
-msgstr "Activé avec succès"
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Dupliqué avec succès"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -1039,7 +1054,7 @@ msgstr "Activer TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Activé"
 msgstr "Activé"
@@ -1047,7 +1062,6 @@ msgstr "Activé"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Activé avec succès"
 msgstr "Activé avec succès"
@@ -1436,6 +1450,10 @@ msgstr "Laisser vide pour aucun changement"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Laisser vide pour aucun changement"
 msgstr "Laisser vide pour aucun changement"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr ""
 msgstr ""
@@ -1469,7 +1487,7 @@ msgid "Load successfully"
 msgstr "Enregistré avec succès"
 msgstr "Enregistré avec succès"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 #, fuzzy
 #, fuzzy
 msgid "Local"
 msgid "Local"
 msgstr "Localisation"
 msgstr "Localisation"
@@ -1608,7 +1626,7 @@ msgstr "Directive multiligne"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Nom"
 msgstr "Nom"
@@ -1683,7 +1701,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Erreur d'analyse de configuration Nginx"
 msgstr "Erreur d'analyse de configuration Nginx"
 
 
@@ -1737,7 +1755,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx a redémarré avec succès"
 msgstr "Nginx a redémarré avec succès"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1791,7 +1809,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Certification"
 msgstr "Certification"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Certification"
 msgstr "Certification"
@@ -1814,7 +1832,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1829,7 +1847,7 @@ msgid "Ok"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1838,7 +1856,6 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1848,8 +1865,8 @@ msgstr "OK"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1879,17 +1896,15 @@ msgstr "OS"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS :"
 msgstr "OS :"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr ""
 msgstr ""
 
 
@@ -1986,6 +2001,7 @@ msgstr ""
 "des informations d'identification ci-dessous pour demander l'API du "
 "des informations d'identification ci-dessous pour demander l'API du "
 "fournisseur DNS."
 "fournisseur DNS."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -2001,7 +2017,7 @@ msgstr "Veuillez renseigner un nom de fichier"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Veuillez renseigner un nom de répertoire"
 msgstr "Veuillez renseigner un nom de répertoire"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -2038,21 +2054,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr ""
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "Dupliqué avec succès"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2206,23 +2207,13 @@ msgstr "Rechargement de nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Supprimer le site : %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Dupliqué avec succès"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Enregistré avec succès"
 msgstr "Enregistré avec succès"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Enregistré avec succès"
 msgstr "Enregistré avec succès"
@@ -2232,49 +2223,69 @@ msgstr "Enregistré avec succès"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "Nom d'utilisateur"
 msgstr "Nom d'utilisateur"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2284,6 +2295,7 @@ msgstr "Activé avec succès"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Activé avec succès"
 msgstr "Activé avec succès"
@@ -2366,7 +2378,8 @@ msgstr "En cours d'éxécution"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Enregistrer"
 msgstr "Enregistrer"
 
 
@@ -2380,24 +2393,44 @@ msgstr "Enregistrer la directive"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Enregistrer l'erreur %{msg}"
 msgstr "Enregistrer l'erreur %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Changer de certificat"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Dupliqué avec succès"
+
+#: src/components/Notification/notifications.ts:112
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save stream %{name} to %{node} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:116
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2410,7 +2443,7 @@ msgstr "Sauvegarde réussie"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Enregistré avec succès"
 msgstr "Enregistré avec succès"
 
 
@@ -2455,7 +2488,7 @@ msgstr "Le paramètre server_name est obligatoire"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "Fichier introuvable"
 msgstr "Fichier introuvable"
@@ -2574,7 +2607,7 @@ msgstr "Tableau"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Statut"
 msgstr "Statut"
 
 
@@ -2587,6 +2620,16 @@ msgstr "Arrêté"
 msgid "Storage"
 msgid "Storage"
 msgstr "Stockage"
 msgstr "Stockage"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Auto Cert"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "Fichier introuvable"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2629,6 +2672,7 @@ msgid "Switch to light theme"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr ""
 msgstr ""
 
 
@@ -2637,49 +2681,42 @@ msgstr ""
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/cert.ts:11
-#, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr "Dupliqué avec succès"
-
-#: src/components/Notification/cert.ts:14
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Dupliqué avec succès"
 msgstr "Dupliqué avec succès"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Changer de certificat"
 msgstr "Changer de certificat"
@@ -2711,10 +2748,6 @@ msgstr "Système"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr ""
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2854,7 +2887,7 @@ msgstr ""
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr ""
 msgstr ""
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr ""
 msgstr ""
@@ -2966,7 +2999,7 @@ msgstr "Mis à jour avec succés"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Mis à jour le"
 msgstr "Mis à jour le"
 
 
@@ -3022,7 +3055,7 @@ msgstr "Nom d'utilisateur"
 msgid "User banned"
 msgid "User banned"
 msgstr "Nom d'utilisateur"
 msgstr "Nom d'utilisateur"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -3050,7 +3083,7 @@ msgstr "Version actuelle"
 msgid "View"
 msgid "View"
 msgstr "Voir"
 msgstr "Voir"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Certification"
 msgstr "Certification"
@@ -3098,7 +3131,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3179,6 +3212,86 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr ""
 msgstr ""
 
 
+#, fuzzy
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Deploy successfully"
+#~ msgstr "Sauvegarde réussie"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Voulez-vous supprimer ce serveur ?"
+#~ msgstr[1] "Voulez-vous supprimer ce serveur ?"
+
+#, fuzzy
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Duplicate failed"
+#~ msgstr "Dupliquer"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Enable successfully"
+#~ msgstr "Activé avec succès"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Supprimer le site : %{site_name}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Dupliqué avec succès"
+
 #, fuzzy
 #, fuzzy
 #~ msgid "Directory"
 #~ msgid "Directory"
 #~ msgstr "Directive"
 #~ msgstr "Directive"

+ 287 - 166
app/src/language/ko_KR/app.po

@@ -94,7 +94,7 @@ msgid "Additional"
 msgstr "추가적인"
 msgstr "추가적인"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "고급 모드"
 msgstr "고급 모드"
 
 
@@ -107,6 +107,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -169,7 +170,7 @@ msgstr "정말 삭제하시겠습니까?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "정말 삭제하시겠습니까?"
 msgstr "정말 삭제하시겠습니까?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "모든 알림을 지우시겠습니까?"
 msgstr "모든 알림을 지우시겠습니까?"
@@ -257,7 +258,7 @@ msgstr "%{name}에 대한 자동 갱신 활성화됨"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "뒤로"
 msgstr "뒤로"
 
 
@@ -293,7 +294,7 @@ msgid "Basic"
 msgstr "기본"
 msgstr "기본"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "기본 모드"
 msgstr "기본 모드"
 
 
@@ -341,17 +342,16 @@ msgstr "CA 디렉토리"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "취소"
 msgstr "취소"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "데모에서 루트 비밀번호 변경 금지"
 msgstr "데모에서 루트 비밀번호 변경 금지"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr ""
 msgstr ""
 
 
@@ -457,12 +457,12 @@ msgid "Cleaning environment variables"
 msgstr "환경 변수 정리"
 msgstr "환경 변수 정리"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "클리어"
 msgstr "클리어"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "성공적으로 제거됨"
 msgstr "성공적으로 제거됨"
@@ -638,20 +638,50 @@ msgstr "삭제"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr ""
 msgstr ""
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "인증서 갱신 오류"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "인증서 갱신 성공"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "사이트 삭제: %{site_name}"
 msgstr "사이트 삭제: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "스트림 삭제: %{stream_name}"
 msgstr "스트림 삭제: %{stream_name}"
@@ -661,29 +691,15 @@ msgid "Deleted successfully"
 msgstr "성공적으로 삭제됨"
 msgstr "성공적으로 삭제됨"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "배포"
 msgstr "배포"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 성공"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "성공적으로 배포됨"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "설명"
 msgstr "설명"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -724,32 +740,52 @@ msgstr "비활성화"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "%{name}의 자동 갱신 비활성화 실패"
 msgstr "%{name}의 자동 갱신 비활성화 실패"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable Remote Stream Error"
+msgstr "인증서 갱신 오류"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "인증서 갱신 성공"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
+
+#: src/components/Notification/notifications.ts:50
+#, fuzzy
+msgid "Disable site %{name} from %{node} successfully"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:88
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "%{node_name}에서 %{conf_name} 활성화 실패"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "비활성화됨"
 msgstr "비활성화됨"
 
 
@@ -781,12 +817,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "이 지시문을 정말로 제거하시겠습니까?"
-msgstr[1] "이 지시문들을 정말로 제거하시겠습니까?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "자동 인증서 갱신을 비활성화하시겠습니까?"
 msgstr "자동 인증서 갱신을 비활성화하시겠습니까?"
@@ -860,26 +890,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "복제"
 msgstr "복제"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "복제 실패"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "성공적으로 복제됨"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "로컬로 성공적으로 복제됨"
 msgstr "로컬로 성공적으로 복제됨"
 
 
@@ -889,7 +906,7 @@ msgid "Edit"
 msgstr "%{n} 편집"
 msgstr "%{n} 편집"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "%{n} 편집"
 msgstr "%{n} 편집"
 
 
@@ -915,19 +932,10 @@ msgid "Email (*)"
 msgstr "이메일 (*)"
 msgstr "이메일 (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "활성화"
 msgstr "활성화"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "%{node_name}에서 %{conf_name} 활성화 실패"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 #, fuzzy
 #, fuzzy
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
@@ -941,29 +949,45 @@ msgstr "%{name}에 대한 자동 갱신 활성화 실패"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "활성화 실패"
 msgstr "활성화 실패"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
+msgid "Enable Remote Stream Error"
+msgstr "인증서 갱신 오류"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:99
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable Remote Stream Success"
+msgstr "인증서 갱신 성공"
+
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
+msgstr "%{node_name}에서 %{conf_name} 활성화 실패"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "성공적으로 활성화"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "%{node_name}에서 %{conf_name} 활성화 실패"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -982,7 +1006,7 @@ msgstr "TLS 활성화"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "활성화됨"
 msgstr "활성화됨"
@@ -990,7 +1014,6 @@ msgstr "활성화됨"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "성공적으로 활성화됨"
 msgstr "성공적으로 활성화됨"
@@ -1364,6 +1387,10 @@ msgstr "Leave blank for no change"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "변경사항이 없으면 비워두세요"
 msgstr "변경사항이 없으면 비워두세요"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr ""
 msgstr ""
@@ -1397,7 +1424,7 @@ msgid "Load successfully"
 msgstr "성공적으로 저장됨"
 msgstr "성공적으로 저장됨"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 #, fuzzy
 #, fuzzy
 msgid "Local"
 msgid "Local"
 msgstr "지역"
 msgstr "지역"
@@ -1541,7 +1568,7 @@ msgstr "단일 지시문"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "이름"
 msgstr "이름"
@@ -1615,7 +1642,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 #, fuzzy
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 구성 오류름"
 msgstr "Nginx 구성 오류름"
@@ -1670,7 +1697,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx가 성공적으로 재시작됨"
 msgstr "Nginx가 성공적으로 재시작됨"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1723,7 +1750,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "알림"
 msgstr "알림"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "알림"
 msgstr "알림"
@@ -1747,7 +1774,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1762,7 +1789,7 @@ msgid "Ok"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1771,7 +1798,6 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1781,8 +1807,8 @@ msgstr "확인"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 msgstr "검증이 완료되면, 레코드는 제거됩니다."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1813,17 +1839,15 @@ msgstr "OS"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS:"
 msgstr "OS:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "덮어쓰기"
 msgstr "덮어쓰기"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "기존 파일 덮어쓰기"
 msgstr "기존 파일 덮어쓰기"
 
 
@@ -1917,6 +1941,7 @@ msgstr ""
 "먼저 인증서 > DNS 자격 증명에 자격 증명을 추가한 다음,DNS 제공자의 API를 요청"
 "먼저 인증서 > DNS 자격 증명에 자격 증명을 추가한 다음,DNS 제공자의 API를 요청"
 "하려면 아래 자격 증명 중 하나를 선택해주세요."
 "하려면 아래 자격 증명 중 하나를 선택해주세요."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1934,7 +1959,7 @@ msgstr "사용자 이름을 입력해주세요!"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "사용자 이름을 입력해주세요!"
 msgstr "사용자 이름을 입력해주세요!"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1969,21 +1994,6 @@ msgstr "아래의 시간 설정 단위는 모두 초 단위임을 유의해주
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "적어도 하나의 노드를 선택해주세요!"
 msgstr "적어도 하나의 노드를 선택해주세요!"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "적어도 하나의 노드를 선택해주세요!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2136,23 +2146,13 @@ msgstr "Nginx 리로딩 중"
 msgid "Remove"
 msgid "Remove"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "사이트 삭제: %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "성공적으로 제거됨"
 msgstr "성공적으로 제거됨"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "성공적으로 제거됨"
 msgstr "성공적으로 제거됨"
@@ -2162,49 +2162,69 @@ msgstr "성공적으로 제거됨"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "이름 변경"
 msgstr "이름 변경"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename Remote Stream Error"
+msgstr "인증서 갱신 오류"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "인증서 갱신 성공"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:66
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#: src/components/Notification/notifications.ts:104
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#: src/components/Notification/notifications.ts:108
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2214,6 +2234,7 @@ msgstr "성공적으로 갱신됨"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "성공적으로 갱신됨"
 msgstr "성공적으로 갱신됨"
@@ -2297,7 +2318,8 @@ msgstr "실행 중"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "저장"
 msgstr "저장"
 
 
@@ -2311,24 +2333,44 @@ msgstr "지시문 저장"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "저장 오류 %{msg}"
 msgstr "저장 오류 %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "인증서 갱신 오류"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "인증서 갱신 성공"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#: src/components/Notification/notifications.ts:74
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save site %{name} to %{node} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:112
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} failed"
+msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
+
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2342,7 +2384,7 @@ msgstr "성공적으로 저장됨"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "성공적으로 저장됨"
 msgstr "성공적으로 저장됨"
 
 
@@ -2387,7 +2429,7 @@ msgstr "server_name 매개변수가 필요합니다"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "파일을 찾을 수 없음"
 msgstr "파일을 찾을 수 없음"
@@ -2504,7 +2546,7 @@ msgstr "활성화됨"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "상태"
 msgstr "상태"
 
 
@@ -2517,6 +2559,16 @@ msgstr "정지됨"
 msgid "Storage"
 msgid "Storage"
 msgstr "저장소"
 msgstr "저장소"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "비활성화됨"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "파일을 찾을 수 없음"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2557,6 +2609,7 @@ msgid "Switch to light theme"
 msgstr "라이트 테마로 변경"
 msgstr "라이트 테마로 변경"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr ""
 msgstr ""
 
 
@@ -2565,49 +2618,42 @@ msgstr ""
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "인증서 갱신"
 msgstr "인증서 갱신"
 
 
-#: src/components/Notification/cert.ts:11
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/components/Notification/cert.ts:14
-#, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
-
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "인증서 갱신 오류"
 msgstr "인증서 갱신 오류"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "인증서 갱신 성공"
 msgstr "인증서 갱신 성공"
@@ -2638,10 +2684,6 @@ msgstr "시스템"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "대상"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2779,7 +2821,7 @@ msgstr "이 필드는 비워둘 수 없습니다"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "이 필드는 비워둘 수 없습니다"
 msgstr "이 필드는 비워둘 수 없습니다"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "이 필드는 비워둘 수 없습니다"
 msgstr "이 필드는 비워둘 수 없습니다"
@@ -2889,7 +2931,7 @@ msgstr "성공적으로 저장되었습니다"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "업데이트됨"
 msgstr "업데이트됨"
 
 
@@ -2947,7 +2989,7 @@ msgstr "사용자 이름"
 msgid "User banned"
 msgid "User banned"
 msgstr "사용자 이름"
 msgstr "사용자 이름"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -2975,7 +3017,7 @@ msgstr "현재 버전"
 msgid "View"
 msgid "View"
 msgstr "보기"
 msgstr "보기"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Certificate is valid"
 msgstr "Certificate is valid"
@@ -3026,7 +3068,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3107,6 +3149,85 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr ""
 msgstr ""
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 성공"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "성공적으로 배포됨"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "이 지시문을 정말로 제거하시겠습니까?"
+#~ msgstr[1] "이 지시문들을 정말로 제거하시겠습니까?"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "복제 실패"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "성공적으로 복제됨"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
+
+#~ msgid "Enable successfully"
+#~ msgstr "성공적으로 활성화"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "적어도 하나의 노드를 선택해주세요!"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "사이트 삭제: %{site_name}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
+
+#~ msgid "Target"
+#~ msgstr "대상"
+
 #~ msgid "Directory"
 #~ msgid "Directory"
 #~ msgstr "디렉토리"
 #~ msgstr "디렉토리"
 
 

+ 183 - 140
app/src/language/messages.pot

@@ -87,7 +87,7 @@ msgid "Additional"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr ""
 msgstr ""
 
 
@@ -100,6 +100,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -156,7 +157,7 @@ msgstr ""
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr ""
 msgstr ""
@@ -245,7 +246,7 @@ msgstr ""
 #: src/views/config/ConfigList.vue:180
 #: src/views/config/ConfigList.vue:180
 #: src/views/nginx_log/NginxLog.vue:173
 #: src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr ""
 msgstr ""
 
 
@@ -281,7 +282,7 @@ msgid "Basic"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr ""
 msgstr ""
 
 
@@ -328,16 +329,15 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr ""
 msgstr ""
 
 
@@ -435,12 +435,12 @@ msgid "Cleaning environment variables"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr ""
 msgstr ""
@@ -614,18 +614,44 @@ msgstr ""
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:37
 #: src/language/constants.ts:49
 #: src/language/constants.ts:49
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:41
 #: src/language/constants.ts:48
 #: src/language/constants.ts:48
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:79
+msgid "Delete Remote Stream Error"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:83
+msgid "Delete Remote Stream Success"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:38
+msgid "Delete site %{name} from %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:42
+msgid "Delete site %{name} from %{node} successfully"
+msgstr ""
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:80
+msgid "Delete stream %{name} from %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:84
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr ""
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr ""
 msgstr ""
@@ -635,29 +661,16 @@ msgid "Deleted successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr ""
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr ""
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr ""
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr ""
 msgstr ""
 
 
 #: src/constants/errors/site.ts:3
 #: src/constants/errors/site.ts:3
+#: src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -698,20 +711,38 @@ msgstr ""
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:45
 #: src/language/constants.ts:51
 #: src/language/constants.ts:51
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:49
 #: src/language/constants.ts:50
 #: src/language/constants.ts:50
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:82
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#: src/components/Notification/notifications.ts:87
+msgid "Disable Remote Stream Error"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:74
-msgid "Disable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:91
+msgid "Disable Remote Stream Success"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:46
+msgid "Disable site %{name} from %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:50
+msgid "Disable site %{name} from %{node} successfully"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:88
+msgid "Disable stream %{name} from %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:92
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
@@ -719,8 +750,8 @@ msgstr ""
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:62
 #: src/views/site/site_list/columns.tsx:62
-#: src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34
+#: src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33
 #: src/views/user/userColumns.tsx:41
 #: src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr ""
 msgstr ""
@@ -754,12 +785,6 @@ msgstr ""
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] ""
-msgstr[1] ""
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr ""
 msgstr ""
@@ -830,25 +855,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr ""
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr ""
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr ""
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr ""
 msgstr ""
 
 
@@ -857,7 +870,7 @@ msgid "Edit"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr ""
 msgstr ""
 
 
@@ -883,19 +896,10 @@ msgid "Email (*)"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr ""
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr ""
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr ""
 msgstr ""
@@ -908,24 +912,38 @@ msgstr ""
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:53
 #: src/language/constants.ts:53
 #: src/language/constants.ts:53
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:57
 #: src/language/constants.ts:52
 #: src/language/constants.ts:52
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:69
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#: src/components/Notification/notifications.ts:95
+msgid "Enable Remote Stream Error"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:61
-msgid "Enable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:99
+msgid "Enable Remote Stream Success"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
+#: src/components/Notification/notifications.ts:54
+msgid "Enable site %{name} on %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:58
+msgid "Enable site %{name} on %{node} successfully"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:96
+msgid "Enable stream %{name} on %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:100
+msgid "Enable stream %{name} on %{node} successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
@@ -944,8 +962,8 @@ msgstr ""
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169
-#: src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170
+#: src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr ""
 msgstr ""
@@ -954,7 +972,6 @@ msgstr ""
 #: src/views/site/site_list/SiteList.vue:46
 #: src/views/site/site_list/SiteList.vue:46
 #: src/views/site/SiteAdd.vue:40
 #: src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr ""
 msgstr ""
@@ -1307,6 +1324,10 @@ msgstr ""
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr ""
 msgstr ""
@@ -1337,7 +1358,7 @@ msgid "Load successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr ""
 msgstr ""
 
 
@@ -1465,7 +1486,7 @@ msgstr ""
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13
 #: src/views/stream/StreamList.vue:13
 #: src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
@@ -1538,7 +1559,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr ""
 msgstr ""
 
 
@@ -1588,7 +1609,7 @@ msgid "Nginx restarted successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1637,7 +1658,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:126
+#: src/components/Notification/Notification.vue:131
 #: src/routes/index.ts:248
 #: src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr ""
 msgstr ""
@@ -1658,7 +1679,7 @@ msgstr ""
 msgid "OCSP Must Staple may cause errors for some users on first access using Firefox."
 msgid "OCSP Must Staple may cause errors for some users on first access using Firefox."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1673,7 +1694,7 @@ msgid "Ok"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1682,7 +1703,6 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1692,8 +1712,8 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1724,17 +1744,15 @@ msgstr ""
 msgid "OS:"
 msgid "OS:"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr ""
 msgstr ""
 
 
@@ -1818,6 +1836,7 @@ msgstr ""
 msgid "Please first add credentials in Certification > DNS Credentials, and then select one of the credentialsbelow to request the API of the DNS provider."
 msgid "Please first add credentials in Certification > DNS Credentials, and then select one of the credentialsbelow to request the API of the DNS provider."
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid "Please generate new recovery codes in the preferences immediately to prevent lockout."
 msgid "Please generate new recovery codes in the preferences immediately to prevent lockout."
 msgstr ""
 msgstr ""
@@ -1831,7 +1850,7 @@ msgstr ""
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid "Please input name, this will be used as the filename of the new configuration!"
 msgid "Please input name, this will be used as the filename of the new configuration!"
 msgstr ""
 msgstr ""
 
 
@@ -1861,20 +1880,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr ""
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr ""
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220
 #: src/views/environment/BatchUpgrader.vue:220
 #: src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:194
@@ -2015,20 +2020,12 @@ msgstr ""
 msgid "Remove"
 msgid "Remove"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:56
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr ""
-
-#: src/components/Notification/config.ts:48
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr ""
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr ""
 msgstr ""
 
 
@@ -2037,39 +2034,60 @@ msgstr ""
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:30
-msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+#: src/components/Notification/notifications.ts:28
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:27
 #: src/language/constants.ts:41
 #: src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:31
 #: src/language/constants.ts:40
 #: src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:61
 #: src/language/constants.ts:55
 #: src/language/constants.ts:55
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:65
 #: src/language/constants.ts:54
 #: src/language/constants.ts:54
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:95
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#: src/components/Notification/notifications.ts:103
+msgid "Rename Remote Stream Error"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:107
+msgid "Rename Remote Stream Success"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:62
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:66
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:87
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:104
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:108
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2078,6 +2096,7 @@ msgstr ""
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr ""
 msgstr ""
 
 
@@ -2154,7 +2173,8 @@ msgstr ""
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr ""
 msgstr ""
 
 
@@ -2168,20 +2188,38 @@ msgstr ""
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:69
 #: src/language/constants.ts:47
 #: src/language/constants.ts:47
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:73
 #: src/language/constants.ts:46
 #: src/language/constants.ts:46
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:43
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+#: src/components/Notification/notifications.ts:111
+msgid "Save Remote Stream Error"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:115
+msgid "Save Remote Stream Success"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:70
+msgid "Save site %{name} to %{node} failed"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:35
-msgid "Save Site %{site} to %{node} successfully"
+#: src/components/Notification/notifications.ts:74
+msgid "Save site %{name} to %{node} successfully"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:112
+msgid "Save stream %{name} to %{node} failed"
+msgstr ""
+
+#: src/components/Notification/notifications.ts:116
+msgid "Save stream %{name} to %{node} successfully"
 msgstr ""
 msgstr ""
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2195,7 +2233,7 @@ msgstr ""
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152
 #: src/views/site/site_edit/SiteEdit.vue:152
 #: src/views/site/SiteAdd.vue:37
 #: src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr ""
 msgstr ""
 
 
@@ -2241,7 +2279,7 @@ msgstr ""
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 msgid "Session not found"
 msgid "Session not found"
 msgstr ""
 msgstr ""
 
 
@@ -2345,7 +2383,7 @@ msgstr ""
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
 #: src/views/site/site_list/columns.tsx:42
 #: src/views/site/site_list/columns.tsx:42
-#: src/views/stream/StreamList.vue:23
+#: src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr ""
 msgstr ""
 
 
@@ -2358,6 +2396,14 @@ msgstr ""
 msgid "Storage"
 msgid "Storage"
 msgstr ""
 msgstr ""
 
 
+#: src/constants/errors/stream.ts:4
+msgid "Stream is enabled"
+msgstr ""
+
+#: src/constants/errors/stream.ts:2
+msgid "Stream not found"
+msgstr ""
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 msgid "Streams Directory"
 msgid "Streams Directory"
 msgstr ""
 msgstr ""
@@ -2393,6 +2439,7 @@ msgid "Switch to light theme"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr ""
 msgstr ""
 
 
@@ -2400,38 +2447,38 @@ msgstr ""
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/cert.ts:11
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the remote Nginx UI to the latest version"
-msgstr ""
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#: src/components/Notification/notifications.ts:10
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:9
 #: src/language/constants.ts:38
 #: src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:13
 #: src/language/constants.ts:37
 #: src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#: src/components/Notification/notifications.ts:20
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:19
 #: src/language/constants.ts:44
 #: src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:23
 #: src/language/constants.ts:43
 #: src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr ""
 msgstr ""
@@ -2461,10 +2508,6 @@ msgstr ""
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr ""
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 msgid "Task not found"
 msgid "Task not found"
 msgstr ""
 msgstr ""
@@ -2570,7 +2613,7 @@ msgstr ""
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr ""
 msgstr ""
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr ""
 msgstr ""
@@ -2661,7 +2704,7 @@ msgstr ""
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43
+#: src/views/stream/StreamList.vue:42
 #: src/views/user/userColumns.tsx:54
 #: src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr ""
 msgstr ""
@@ -2718,7 +2761,7 @@ msgstr ""
 msgid "User banned"
 msgid "User banned"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -2746,7 +2789,7 @@ msgstr ""
 msgid "View"
 msgid "View"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr ""
 msgstr ""
 
 
@@ -2786,7 +2829,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 

+ 304 - 182
app/src/language/ru_RU/app.po

@@ -95,7 +95,7 @@ msgid "Additional"
 msgstr "Дополнительно"
 msgstr "Дополнительно"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Расширенный режим"
 msgstr "Расширенный режим"
 
 
@@ -108,6 +108,7 @@ msgstr "Затем, обновите эту страницу и снова на
 msgid "All"
 msgid "All"
 msgstr "Все"
 msgstr "Все"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -170,7 +171,7 @@ msgstr "Вы уверены, что хотите удалить?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Вы уверены, что хотите удалить?"
 msgstr "Вы уверены, что хотите удалить?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "Вы уверены, что хотите очистить все уведомления?"
 msgstr "Вы уверены, что хотите очистить все уведомления?"
@@ -259,7 +260,7 @@ msgstr "Автообновление включено для %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Назад"
 msgstr "Назад"
 
 
@@ -296,7 +297,7 @@ msgid "Basic"
 msgstr "Простой режим"
 msgstr "Простой режим"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Простой режим"
 msgstr "Простой режим"
 
 
@@ -344,17 +345,16 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Отмена"
 msgstr "Отмена"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Запретить изменение пароля root в демо"
 msgstr "Запретить изменение пароля root в демо"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 #, fuzzy
 #, fuzzy
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "Первоначальный пользователь системы"
 msgstr "Первоначальный пользователь системы"
@@ -459,12 +459,12 @@ msgid "Cleaning environment variables"
 msgstr "Очистка переменных среды"
 msgstr "Очистка переменных среды"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Очистить"
 msgstr "Очистить"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "Очищено успешно"
 msgstr "Очищено успешно"
@@ -642,20 +642,50 @@ msgstr "Удалить"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "Удалить навсегда"
 msgstr "Удалить навсегда"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Ошибка переименования удаленной конфигурации"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Переименование удаленной конфигурации прошло успешно"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Продублированно %{conf_name} в %{node_name}"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Удалить сайт: %{site_name}"
 msgstr "Удалить сайт: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Продублированно %{conf_name} в %{node_name}"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "Удалить поток: %{stream_name}"
 msgstr "Удалить поток: %{stream_name}"
@@ -665,29 +695,15 @@ msgid "Deleted successfully"
 msgstr "Удалено успешно"
 msgstr "Удалено успешно"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Развернуть"
 msgstr "Развернуть"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Успешно развернуто %{conf_name} на %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "Успешное развертывание"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Описание"
 msgstr "Описание"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -728,32 +744,52 @@ msgstr "Отключить"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Не удалось отключить автоматическое продление для %{name}"
 msgstr "Не удалось отключить автоматическое продление для %{name}"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Ошибка переименования удаленной конфигурации"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Переименование удаленной конфигурации прошло успешно"
+
+#: src/components/Notification/notifications.ts:46
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable site %{name} from %{node} failed"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:50
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Включение %{conf_name} in %{node_name} успешно"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "Включение %{conf_name} in %{node_name} нипалучилася"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Отключено"
 msgstr "Отключено"
 
 
@@ -785,12 +821,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "Не включайте эту опцию, если не уверены, что она вам нужна."
 msgstr "Не включайте эту опцию, если не уверены, что она вам нужна."
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Вы хотите развернуть этот файл на удаленном сервере?"
-msgstr[1] "Вы хотите развернуть этот файл на удаленных серверах?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "Вы хотите отключить автоматическое обновление сертификата?"
 msgstr "Вы хотите отключить автоматическое обновление сертификата?"
@@ -868,27 +898,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Дублировать"
 msgstr "Дублировать"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-#, fuzzy
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Продублированно %{conf_name} в %{node_name}"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "Дублирование не удалось"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "Продублированно"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Успешно дублировано на локальный"
 msgstr "Успешно дублировано на локальный"
 
 
@@ -898,7 +914,7 @@ msgid "Edit"
 msgstr "Редактировать %{n}"
 msgstr "Редактировать %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Редактировать %{n}"
 msgstr "Редактировать %{n}"
 
 
@@ -923,19 +939,10 @@ msgid "Email (*)"
 msgstr "Email (*)"
 msgstr "Email (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "Включить"
 msgstr "Включить"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Включение %{conf_name} in %{node_name} нипалучилася"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Включение %{conf_name} in %{node_name} успешно"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "Двухфакторная аутентификация успешно включена"
 msgstr "Двухфакторная аутентификация успешно включена"
@@ -948,29 +955,45 @@ msgstr "Не удалось включить автоматическое про
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Включить не удалось"
 msgstr "Включить не удалось"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "Включение %{conf_name} in %{node_name} успешно"
+msgid "Enable Remote Stream Error"
+msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:99
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable Remote Stream Success"
+msgstr "Переименование удаленной конфигурации прошло успешно"
+
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
+msgstr "Включение %{conf_name} in %{node_name} нипалучилася"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 msgstr "Включение %{conf_name} in %{node_name} успешно"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "Включено успешно"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Включение %{conf_name} in %{node_name} нипалучилася"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Включение %{conf_name} in %{node_name} успешно"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -989,7 +1012,7 @@ msgstr "Включить TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Включено"
 msgstr "Включено"
@@ -997,7 +1020,6 @@ msgstr "Включено"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Активировано успешно"
 msgstr "Активировано успешно"
@@ -1366,6 +1388,10 @@ msgstr "Оставьте пустым без изменений."
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Если оставить пустым, ничего не изменится"
 msgstr "Если оставить пустым, ничего не изменится"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Lego отключает поддержку CNAME"
 msgstr "Lego отключает поддержку CNAME"
@@ -1396,7 +1422,7 @@ msgid "Load successfully"
 msgstr "Загружено успешно"
 msgstr "Загружено успешно"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "Локальный"
 msgstr "Локальный"
 
 
@@ -1531,7 +1557,7 @@ msgstr "Многострочная директива"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Имя"
 msgstr "Имя"
@@ -1603,7 +1629,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Ошибка разбора конфигурации Nginx"
 msgstr "Ошибка разбора конфигурации Nginx"
 
 
@@ -1655,7 +1681,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx успешно перезапущен"
 msgstr "Nginx успешно перезапущен"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1707,7 +1733,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Уведомление"
 msgstr "Уведомление"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Уведомления"
 msgstr "Уведомления"
 
 
@@ -1731,7 +1757,7 @@ msgstr ""
 "OCSP Must Staple может вызвать ошибки у некоторых пользователей при первом "
 "OCSP Must Staple может вызвать ошибки у некоторых пользователей при первом "
 "доступе через Firefox."
 "доступе через Firefox."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1746,7 +1772,7 @@ msgid "Ok"
 msgstr "Ок"
 msgstr "Ок"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1755,7 +1781,6 @@ msgstr "Ок"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1765,8 +1790,8 @@ msgstr "ОК"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "После завершения проверки записи будут удалены."
 msgstr "После завершения проверки записи будут удалены."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1796,18 +1821,16 @@ msgstr "ОС"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS:"
 msgstr "OS:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 #, fuzzy
 #, fuzzy
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "Использовать код восстановления"
 msgstr "Использовать код восстановления"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "Перезаписать"
 msgstr "Перезаписать"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "Перезаписать существующий файл"
 msgstr "Перезаписать существующий файл"
 
 
@@ -1905,6 +1928,7 @@ msgstr ""
 "Credentials, а затем выберите одну из учетных данных ниже, чтобы запросить "
 "Credentials, а затем выберите одну из учетных данных ниже, чтобы запросить "
 "API провайдера DNS."
 "API провайдера DNS."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1920,7 +1944,7 @@ msgstr "Пожалуйста, введите имя файла"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Пожалуйста, введите имя папки"
 msgstr "Пожалуйста, введите имя папки"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1959,23 +1983,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "Пожалуйста, выберите хотя бы один узел"
 msgstr "Пожалуйста, выберите хотя бы один узел"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "Пожалуйста, выберите хотя бы один узел!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr ""
-"Синхронизация конфигурации %{cert_name} с %{env_name} не удалась, "
-"пожалуйста, обновите удаленный Nginx UI до последней версии"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2121,22 +2128,12 @@ msgstr "Перезагружается nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr "Удалить"
 msgstr "Удалить"
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Удалить сайт: %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Продублированно %{conf_name} в %{node_name}"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Удалено успешно"
 msgstr "Удалено успешно"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Успешно удалено"
 msgstr "Успешно удалено"
 
 
@@ -2145,46 +2142,65 @@ msgstr "Успешно удалено"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr "Переименовать"
 msgstr "Переименовать"
 
 
-#: src/components/Notification/config.ts:30
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
-msgstr ""
-"Переименование %{orig_path} в %{new_path} на %{env_name} не удалось, ответ: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:28
+#, fuzzy
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
+msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "Ошибка переименования удаленной конфигурации"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Переименование удаленной конфигурации прошло успешно"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
+
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2193,6 +2209,7 @@ msgstr "Переименовано успешно"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Переименовано успешно"
 msgstr "Переименовано успешно"
@@ -2270,7 +2287,8 @@ msgstr "Выполняется"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Сохранить"
 msgstr "Сохранить"
 
 
@@ -2284,26 +2302,44 @@ msgstr "Сохранить директиву"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Ошибка сохранения %{msg}"
 msgstr "Ошибка сохранения %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Ошибка переименования удаленной конфигурации"
 msgstr "Ошибка переименования удаленной конфигурации"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 msgstr "Переименование удаленной конфигурации прошло успешно"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
-msgstr ""
-"Синхронизация сертификата %{cert_name} с %{env_name} не удалась, ответ: "
-"%{resp}"
+msgid "Save Remote Stream Error"
+msgstr "Ошибка переименования удаленной конфигурации"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Переименование удаленной конфигурации прошло успешно"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "Продублированно %{conf_name} в %{node_name}"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Продублированно %{conf_name} в %{node_name}"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:112
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} failed"
+msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
+
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Продублированно %{conf_name} в %{node_name}"
 msgstr "Продублированно %{conf_name} в %{node_name}"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2316,7 +2352,7 @@ msgstr "Сохранено успешно"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Успешно сохранено"
 msgstr "Успешно сохранено"
 
 
@@ -2363,7 +2399,7 @@ msgstr "server_name параметр обязателен"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "Файл не найден"
 msgstr "Файл не найден"
@@ -2476,7 +2512,7 @@ msgstr "Стабильный"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Статус"
 msgstr "Статус"
 
 
@@ -2489,6 +2525,16 @@ msgstr "Остановлен"
 msgid "Storage"
 msgid "Storage"
 msgstr "Хранилище"
 msgstr "Хранилище"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Авто Сертификат"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "Файл не найден"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2529,6 +2575,7 @@ msgid "Switch to light theme"
 msgstr "Переключиться на светлую тему"
 msgstr "Переключиться на светлую тему"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "Синхронизация"
 msgstr "Синхронизация"
 
 
@@ -2536,47 +2583,38 @@ msgstr "Синхронизация"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Синхронизировать сертификат"
 msgstr "Синхронизировать сертификат"
 
 
-#: src/components/Notification/cert.ts:11
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"Синхронизация сертификата %{cert_name} с %{env_name} не удалась, пожалуйста, "
-"обновите удаленный интерфейс Nginx до последней версии"
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Синхронизация сертификата %{cert_name} с %{env_name} не удалась, ответ: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:10
+#, fuzzy
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "Сертификат %{cert_name} успешно синхронизирован с %{env_name}"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Сертификат %{cert_name} успешно синхронизирован с %{env_name}"
 msgstr "Сертификат %{cert_name} успешно синхронизирован с %{env_name}"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Ошибка синхронизации сертификата"
 msgstr "Ошибка синхронизации сертификата"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Сертификат успешно синхронизирован"
 msgstr "Сертификат успешно синхронизирован"
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Синхронизация конфигурации %{config_name} с %{env_name} не удалась, ответ: "
-"%{resp}"
+#: src/components/Notification/notifications.ts:20
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "Конфигурация синхронизирована %{config_name} с %{env_name} успешно"
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Конфигурация синхронизирована %{config_name} с %{env_name} успешно"
 msgstr "Конфигурация синхронизирована %{config_name} с %{env_name} успешно"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Ошибка синхронизации конфигурации"
 msgstr "Ошибка синхронизации конфигурации"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Синхронизация конфигурации успешна"
 msgstr "Синхронизация конфигурации успешна"
 
 
@@ -2607,10 +2645,6 @@ msgstr "Система"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "Первоначальный пользователь системы"
 msgstr "Первоначальный пользователь системы"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "Цель"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2758,7 +2792,7 @@ msgstr "Это поле обязательно к заполнению"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "Это поле обязательно к заполнению"
 msgstr "Это поле обязательно к заполнению"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "Это поле обязательно к заполнению"
 msgstr "Это поле обязательно к заполнению"
@@ -2878,7 +2912,7 @@ msgstr "Успешно обновлено"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Обновлено в"
 msgstr "Обновлено в"
 
 
@@ -2932,7 +2966,7 @@ msgstr "Пользователь"
 msgid "User banned"
 msgid "User banned"
 msgstr "Пользователь заблокирован"
 msgstr "Пользователь заблокирован"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -2959,7 +2993,7 @@ msgstr "Версия"
 msgid "View"
 msgid "View"
 msgstr "Просмотр"
 msgstr "Просмотр"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Просмотреть все уведомления"
 msgstr "Просмотреть все уведомления"
 
 
@@ -3009,7 +3043,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3090,6 +3124,94 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr ""
 msgstr ""
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Успешно развернуто %{conf_name} на %{node_name}"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "Успешное развертывание"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Включение %{conf_name} in %{node_name} успешно"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Вы хотите развернуть этот файл на удаленном сервере?"
+#~ msgstr[1] "Вы хотите развернуть этот файл на удаленных серверах?"
+
+#, fuzzy
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Продублированно %{conf_name} в %{node_name}"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "Дублирование не удалось"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "Продублированно"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Включение %{conf_name} in %{node_name} успешно"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Включение %{conf_name} in %{node_name} успешно"
+
+#~ msgid "Enable successfully"
+#~ msgstr "Включено успешно"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "Пожалуйста, выберите хотя бы один узел!"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "Синхронизация конфигурации %{cert_name} с %{env_name} не удалась, "
+#~ "пожалуйста, обновите удаленный Nginx UI до последней версии"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Удалить сайт: %{site_name}"
+
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "Переименование %{orig_path} в %{new_path} на %{env_name} не удалось, "
+#~ "ответ: %{resp}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Переименование %{orig_path} в %{new_path} на %{env_name} успешно"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "Синхронизация сертификата %{cert_name} с %{env_name} не удалась, ответ: "
+#~ "%{resp}"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "Синхронизация сертификата %{cert_name} с %{env_name} не удалась, "
+#~ "пожалуйста, обновите удаленный интерфейс Nginx до последней версии"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Синхронизация сертификата %{cert_name} с %{env_name} не удалась, ответ: "
+#~ "%{resp}"
+
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Синхронизация конфигурации %{config_name} с %{env_name} не удалась, "
+#~ "ответ: %{resp}"
+
+#~ msgid "Target"
+#~ msgstr "Цель"
+
 #~ msgid "Directory"
 #~ msgid "Directory"
 #~ msgstr "Каталог"
 #~ msgstr "Каталог"
 
 

+ 324 - 186
app/src/language/tr_TR/app.po

@@ -92,7 +92,7 @@ msgid "Additional"
 msgstr "İlave bilgi"
 msgstr "İlave bilgi"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Gelişmiş Mod"
 msgstr "Gelişmiş Mod"
 
 
@@ -106,6 +106,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -167,7 +168,7 @@ msgstr "Silmek istediğine emin misin?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Silmek istediğine emin misin?"
 msgstr "Silmek istediğine emin misin?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "Tüm bildirimleri temizlemek istediğinizden emin misiniz?"
 msgstr "Tüm bildirimleri temizlemek istediğinizden emin misiniz?"
@@ -255,7 +256,7 @@ msgstr "Otomatik yenileme %{name} için etkinleştirildi"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Geri"
 msgstr "Geri"
 
 
@@ -291,7 +292,7 @@ msgid "Basic"
 msgstr "Temel"
 msgstr "Temel"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Temel Mod"
 msgstr "Temel Mod"
 
 
@@ -339,17 +340,16 @@ msgstr "CADizini"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "İptal"
 msgstr "İptal"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Demoda kök parolasını değiştirmeyi yasakla"
 msgstr "Demoda kök parolasını değiştirmeyi yasakla"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 #, fuzzy
 #, fuzzy
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "Sistem İlk Kullanıcısı"
 msgstr "Sistem İlk Kullanıcısı"
@@ -453,12 +453,12 @@ msgid "Cleaning environment variables"
 msgstr "Ortam değişkenlerini temizleme"
 msgstr "Ortam değişkenlerini temizleme"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Temizle"
 msgstr "Temizle"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "Başarıyla temizlendi"
 msgstr "Başarıyla temizlendi"
@@ -633,20 +633,52 @@ msgstr "Sil"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "Kalıcı Olarak Sil"
 msgstr "Kalıcı Olarak Sil"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümüne dağıtma başarısız oldu"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Siteyi sil: %{site_name}"
 msgstr "Siteyi sil: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümüne dağıtma başarısız oldu"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "Akışı sil: %{stream_name}"
 msgstr "Akışı sil: %{stream_name}"
@@ -656,30 +688,15 @@ msgid "Deleted successfully"
 msgstr "Başarıyla silindi"
 msgstr "Başarıyla silindi"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Yayınla"
 msgstr "Yayınla"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr ""
-"%{conf_name} yapılandırmasını %{node_name} düğümüne dağıtma başarısız oldu"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "%{conf_name} yapılandırması başarıyla %{node_name} düğümüne dağıtıldı"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "Başarıyla Dağıtıldı"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Açıklama"
 msgstr "Açıklama"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -720,26 +737,50 @@ msgstr "Devre Dışı"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "%{name} için otomatik yenilemeyi devre dışı bırakma başarısız oldu"
 msgstr "%{name} için otomatik yenilemeyi devre dışı bırakma başarısız oldu"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
+"oldu"
+
+#: src/components/Notification/notifications.ts:50
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable site %{name} from %{node} successfully"
 msgstr ""
 msgstr ""
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "oldu"
 "oldu"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:88
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable stream %{name} from %{node} failed"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarısız "
+"oldu"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr ""
 msgstr ""
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "oldu"
 "oldu"
@@ -748,8 +789,8 @@ msgstr ""
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Devre dışı"
 msgstr "Devre dışı"
 
 
@@ -781,12 +822,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "Bu seçeneği, ihtiyacınız olduğundan emin olmadıkça etkinleştirmeyin."
 msgstr "Bu seçeneği, ihtiyacınız olduğundan emin olmadıkça etkinleştirmeyin."
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Bu dosyayı uzak sunucuya dağıtmak istiyor musunuz?"
-msgstr[1] "Bu dosyayı uzak sunuculara dağıtmak istiyor musunuz?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "Otomatik sertifika yenilemeyi devre dışı bırakmak istiyor musunuz?"
 msgstr "Otomatik sertifika yenilemeyi devre dışı bırakmak istiyor musunuz?"
@@ -864,25 +899,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Kopyala"
 msgstr "Kopyala"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "Kopyalama başarısız oldu"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr "Başarıyla kopyalandı"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Başarıyla yerel kopya oluşturuldu"
 msgstr "Başarıyla yerel kopya oluşturuldu"
 
 
@@ -892,7 +915,7 @@ msgid "Edit"
 msgstr "Düzenle %{n}"
 msgstr "Düzenle %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Düzenle %{n}"
 msgstr "Düzenle %{n}"
 
 
@@ -917,23 +940,10 @@ msgid "Email (*)"
 msgstr "E-posta(*)"
 msgstr "E-posta(*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "Etkinleştir"
 msgstr "Etkinleştir"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr ""
-"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarısız "
-"oldu"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr ""
-"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
-"oldu"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "2FA'yı başarıyla etkinleştirildi"
 msgstr "2FA'yı başarıyla etkinleştirildi"
@@ -946,33 +956,53 @@ msgstr "%{name} için otomatik yenilemeyi etkinleştirme başarısız oldu"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Etkinleştirme başarısız"
 msgstr "Etkinleştirme başarısız"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
+msgid "Enable Remote Stream Error"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
+
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
 msgstr ""
 msgstr ""
-"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
+"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarısız "
 "oldu"
 "oldu"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:58
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} successfully"
 msgstr ""
 msgstr ""
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
 "oldu"
 "oldu"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "Başarıyla etkinleştirildi"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarısız "
+"oldu"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr ""
+"%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme başarılı "
+"oldu"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -990,7 +1020,7 @@ msgstr "TOTP'yi Etkinleştir"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Etkin"
 msgstr "Etkin"
@@ -998,7 +1028,6 @@ msgstr "Etkin"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Başarıyla etkinleştirildi"
 msgstr "Başarıyla etkinleştirildi"
@@ -1367,6 +1396,10 @@ msgstr "Buna ihtiyacınız yoksa boş bırakın."
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Boş bırakmak hiçbir şeyi değiştirmeyecektir"
 msgstr "Boş bırakmak hiçbir şeyi değiştirmeyecektir"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Lego CNAME desteğini devre dışı bırak"
 msgstr "Lego CNAME desteğini devre dışı bırak"
@@ -1397,7 +1430,7 @@ msgid "Load successfully"
 msgstr "Başarıyla yüklendi"
 msgstr "Başarıyla yüklendi"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "Yerel"
 msgstr "Yerel"
 
 
@@ -1548,7 +1581,7 @@ msgstr "Çok Hatlı Direktif"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #, fuzzy
 #, fuzzy
 msgid "Name"
 msgid "Name"
@@ -1631,7 +1664,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 #, fuzzy
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
@@ -1690,7 +1723,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx başarıyla yeniden başlatıldı"
 msgstr "Nginx başarıyla yeniden başlatıldı"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1749,7 +1782,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Bildirim"
 msgstr "Bildirim"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Bildirimler"
 msgstr "Bildirimler"
@@ -1778,7 +1811,7 @@ msgstr ""
 "OCSP Must Staple, Firefox kullanarak ilk erişimde bazı kullanıcılar için "
 "OCSP Must Staple, Firefox kullanarak ilk erişimde bazı kullanıcılar için "
 "hatalara neden olabilir."
 "hatalara neden olabilir."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 #, fuzzy
 #, fuzzy
@@ -1795,7 +1828,7 @@ msgid "Ok"
 msgstr "Tamam"
 msgstr "Tamam"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1804,7 +1837,6 @@ msgstr "Tamam"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 #, fuzzy
 #, fuzzy
@@ -1816,8 +1848,8 @@ msgstr "Tamam"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Doğrulama tamamlandıktan sonra kayıtlar kaldırılacaktır."
 msgstr "Doğrulama tamamlandıktan sonra kayıtlar kaldırılacaktır."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 #, fuzzy
 #, fuzzy
@@ -1853,19 +1885,17 @@ msgstr "OS"
 msgid "OS:"
 msgid "OS:"
 msgstr "İŞLETIM SISTEMI:"
 msgstr "İŞLETIM SISTEMI:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 #, fuzzy
 #, fuzzy
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "Kurtarma kodunu kullanın"
 msgstr "Kurtarma kodunu kullanın"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 #, fuzzy
 #, fuzzy
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "Üzerine yaz"
 msgstr "Üzerine yaz"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 #, fuzzy
 #, fuzzy
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "Mevcut dosyanın üzerine yaz"
 msgstr "Mevcut dosyanın üzerine yaz"
@@ -1982,6 +2012,7 @@ msgstr ""
 "ekleyin ve ardından DNS sağlayıcısının API'sini istemek için aşağıdaki "
 "ekleyin ve ardından DNS sağlayıcısının API'sini istemek için aşağıdaki "
 "kimlik bilgilerinden birini seçin."
 "kimlik bilgilerinden birini seçin."
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1999,7 +2030,7 @@ msgstr "Lütfen bir dosya adı girin"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Lütfen bir klasör adı girin"
 msgstr "Lütfen bir klasör adı girin"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 #, fuzzy
 #, fuzzy
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
@@ -2043,24 +2074,6 @@ msgstr ""
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "Lütfen yükseltmek için en az bir düğüm seçin"
 msgstr "Lütfen yükseltmek için en az bir düğüm seçin"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-#, fuzzy
-msgid "Please select at least one node!"
-msgstr "Lütfen en az bir düğüm seçin!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr ""
-"0] yapılandırmasını %{env_name} ile eşitleme başarısız oldu, lütfen uzak "
-"Nginx kullanıcı arayüzünü en son sürüme yükseltin"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2235,23 +2248,13 @@ msgstr "Nginx'i yeniden yükleme"
 msgid "Remove"
 msgid "Remove"
 msgstr "Kaldır"
 msgstr "Kaldır"
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Siteyi sil: %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Başarıyla kaldırıldı"
 msgstr "Başarıyla kaldırıldı"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Başarıyla kaldırıldı"
 msgstr "Başarıyla kaldırıldı"
@@ -2261,53 +2264,74 @@ msgstr "Başarıyla kaldırıldı"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "Yeniden Adlandır"
 msgstr "Yeniden Adlandır"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr ""
 msgstr ""
-"2] üzerinde %{orig_path}'ı %{new_path} olarak yeniden adlandırma başarısız "
-"oldu, yanıt: %{resp}"
+"2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr ""
 msgstr ""
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename Remote Stream Error"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr ""
+"2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
 msgstr ""
 msgstr ""
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:104
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr ""
+"2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
+
+#: src/components/Notification/notifications.ts:108
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr ""
 msgstr ""
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
 
 
@@ -2318,6 +2342,7 @@ msgstr "Yeniden adlandırma başarıyla"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Yeniden adlandırma başarıyla"
 msgstr "Yeniden adlandırma başarıyla"
@@ -2406,7 +2431,8 @@ msgstr "Çalışıyor"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 #, fuzzy
 #, fuzzy
 msgid "Save"
 msgid "Save"
 msgstr "Kaydet"
 msgstr "Kaydet"
@@ -2423,26 +2449,45 @@ msgstr "Direktifi Kaydet"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Hatayı kaydet %{msg}"
 msgstr "Hatayı kaydet %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandır Hatası"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Uzak Yapılandırmayı Yeniden Adlandırma Başarılı"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
+
+#: src/components/Notification/notifications.ts:74
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save site %{name} to %{node} successfully"
+msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
 msgstr ""
 msgstr ""
-"Sertifika %{cert_name} ile %{env_name} arasında senkronizasyon başarısız "
-"oldu, yanıt: %{resp}"
+"%{conf_name} yapılandırmasını %{node_name} düğümüne dağıtma başarısız oldu"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:116
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
 msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2456,7 +2501,7 @@ msgstr "Başarıyla kaydedin"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 #, fuzzy
 #, fuzzy
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Başarıyla Kaydedildi"
 msgstr "Başarıyla Kaydedildi"
@@ -2510,7 +2555,7 @@ msgstr "server_name parametresi gereklidir"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "Dosya bulunamadı"
 msgstr "Dosya bulunamadı"
@@ -2638,7 +2683,7 @@ msgstr "Stabil"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 #, fuzzy
 #, fuzzy
 msgid "Status"
 msgid "Status"
 msgstr "Durum"
 msgstr "Durum"
@@ -2654,6 +2699,16 @@ msgstr "Durduruldu"
 msgid "Storage"
 msgid "Storage"
 msgstr "Depolama"
 msgstr "Depolama"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Devre dışı"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "Dosya bulunamadı"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2698,6 +2753,7 @@ msgid "Switch to light theme"
 msgstr "Işık temasına geçin"
 msgstr "Işık temasına geçin"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 #, fuzzy
 #, fuzzy
 msgid "Sync"
 msgid "Sync"
 msgstr "Eşitle"
 msgstr "Eşitle"
@@ -2707,55 +2763,42 @@ msgstr "Eşitle"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Senkronizasyon Sertifikası"
 msgstr "Senkronizasyon Sertifikası"
 
 
-#: src/components/Notification/cert.ts:11
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"Sertifika %{cert_name}'dan %{env_name}'e senkronizasyon başarısız oldu, "
-"lütfen uzak Nginx kullanıcı arayüzünü en son sürüme yükseltin"
-
-#: src/components/Notification/cert.ts:14
-#, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Sertifika %{cert_name} ile %{env_name} arasında senkronizasyon başarısız "
-"oldu, yanıt: %{resp}"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "Sertifika %{cert_name}'ı %{env_name} ile başarıyla senkronize edin"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Sertifika %{cert_name}'ı %{env_name} ile başarıyla senkronize edin"
 msgstr "Sertifika %{cert_name}'ı %{env_name} ile başarıyla senkronize edin"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Senkronizasyon Sertifikası Hatası"
 msgstr "Senkronizasyon Sertifikası Hatası"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Senkronizasyon Sertifikası Başarısı"
 msgstr "Senkronizasyon Sertifikası Başarısı"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr ""
-"Yapılandırma %{config_name} ile %{env_name} arasında eşitleme başarısız "
-"oldu, yanıt: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "Config %{config_name} ile %{env_name}'i başarıyla senkronize edin"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Config %{config_name} ile %{env_name}'i başarıyla senkronize edin"
 msgstr "Config %{config_name} ile %{env_name}'i başarıyla senkronize edin"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Senkronizasyon Yapılandırma Hatası"
 msgstr "Senkronizasyon Yapılandırma Hatası"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Senkronizasyon Yapılandırması Başarılı"
 msgstr "Senkronizasyon Yapılandırması Başarılı"
@@ -2790,11 +2833,6 @@ msgstr "Sistem"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "Sistem İlk Kullanıcısı"
 msgstr "Sistem İlk Kullanıcısı"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-#, fuzzy
-msgid "Target"
-msgstr "Hedef"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2955,7 +2993,7 @@ msgstr "Bu alan boş bırakılmamalıdır"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "Bu alan boş bırakılmamalıdır"
 msgstr "Bu alan boş bırakılmamalıdır"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 #, fuzzy
 #, fuzzy
 msgid "This field should not be empty"
 msgid "This field should not be empty"
@@ -3094,7 +3132,7 @@ msgstr "Güncellendi"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 #, fuzzy
 #, fuzzy
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Güncelleme"
 msgstr "Güncelleme"
@@ -3160,7 +3198,7 @@ msgstr "Kullanıcı"
 msgid "User banned"
 msgid "User banned"
 msgstr "Kullanıcı yasaklandı"
 msgstr "Kullanıcı yasaklandı"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -3192,7 +3230,7 @@ msgstr "Versiyon"
 msgid "View"
 msgid "View"
 msgstr "Görünüm"
 msgstr "Görünüm"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Tüm bildirimleri görüntüle"
 msgstr "Tüm bildirimleri görüntüle"
@@ -3247,7 +3285,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3342,6 +3380,106 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "Geçiş anahtarlarınız"
 msgstr "Geçiş anahtarlarınız"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr ""
+#~ "%{conf_name} yapılandırması başarıyla %{node_name} düğümüne dağıtıldı"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "Başarıyla Dağıtıldı"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme "
+#~ "başarılı oldu"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Bu dosyayı uzak sunucuya dağıtmak istiyor musunuz?"
+#~ msgstr[1] "Bu dosyayı uzak sunuculara dağıtmak istiyor musunuz?"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "Kopyalama başarısız oldu"
+
+#~ msgid "Duplicate successfully"
+#~ msgstr "Başarıyla kopyalandı"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr ""
+#~ "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme "
+#~ "başarılı oldu"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "%{conf_name} yapılandırmasını %{node_name} düğümünde etkinleştirme "
+#~ "başarılı oldu"
+
+#~ msgid "Enable successfully"
+#~ msgstr "Başarıyla etkinleştirildi"
+
+#, fuzzy
+#~ msgid "Please select at least one node!"
+#~ msgstr "Lütfen en az bir düğüm seçin!"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "0] yapılandırmasını %{env_name} ile eşitleme başarısız oldu, lütfen uzak "
+#~ "Nginx kullanıcı arayüzünü en son sürüme yükseltin"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Siteyi sil: %{site_name}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "2] üzerinde %{orig_path}'ı %{new_path} olarak yeniden adlandırma "
+#~ "başarısız oldu, yanıt: %{resp}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "2] üzerinde %{orig_path}'ı %{new_path} olarak başarıyla yeniden adlandırın"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "Sertifika %{cert_name} ile %{env_name} arasında senkronizasyon başarısız "
+#~ "oldu, yanıt: %{resp}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "Sertifika %{cert_name}'dan %{env_name}'e senkronizasyon başarısız oldu, "
+#~ "lütfen uzak Nginx kullanıcı arayüzünü en son sürüme yükseltin"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Sertifika %{cert_name} ile %{env_name} arasında senkronizasyon başarısız "
+#~ "oldu, yanıt: %{resp}"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr ""
+#~ "Yapılandırma %{config_name} ile %{env_name} arasında eşitleme başarısız "
+#~ "oldu, yanıt: %{resp}"
+
+#, fuzzy
+#~ msgid "Target"
+#~ msgstr "Hedef"
+
 #~ msgid "Can't scan? Use text key binding"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "Tarayamıyor musunuz? Metin anahtar bağlamasını kullanın"
 #~ msgstr "Tarayamıyor musunuz? Metin anahtar bağlamasını kullanın"
 
 

+ 288 - 170
app/src/language/vi_VN/app.po

@@ -94,7 +94,7 @@ msgid "Additional"
 msgstr "Tùy chọn bổ sung"
 msgstr "Tùy chọn bổ sung"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "Nâng cao"
 msgstr "Nâng cao"
 
 
@@ -107,6 +107,7 @@ msgstr ""
 msgid "All"
 msgid "All"
 msgstr ""
 msgstr ""
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr ""
 msgstr ""
@@ -170,7 +171,7 @@ msgstr "Bạn chắc chắn muốn xóa nó "
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "Bạn chắc chắn muốn xóa nó "
 msgstr "Bạn chắc chắn muốn xóa nó "
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 #, fuzzy
 #, fuzzy
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
@@ -266,7 +267,7 @@ msgstr "Đã bật tự động gia hạn SSL cho %{name}"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "Quay lại"
 msgstr "Quay lại"
 
 
@@ -304,7 +305,7 @@ msgid "Basic"
 msgstr "Cơ bản"
 msgstr "Cơ bản"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "Cơ bản"
 msgstr "Cơ bản"
 
 
@@ -354,17 +355,16 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "Huỷ"
 msgstr "Huỷ"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 #, fuzzy
 #, fuzzy
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Cấm thay đổi mật khẩu root trong demo"
 msgstr "Cấm thay đổi mật khẩu root trong demo"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr ""
 msgstr ""
 
 
@@ -475,12 +475,12 @@ msgid "Cleaning environment variables"
 msgstr "Xoá các biến môi trường"
 msgstr "Xoá các biến môi trường"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "Xoá"
 msgstr "Xoá"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 #, fuzzy
 #, fuzzy
 msgid "Cleared successfully"
 msgid "Cleared successfully"
@@ -660,20 +660,50 @@ msgstr "Xoá"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr ""
 msgstr ""
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 #, fuzzy
 #, fuzzy
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "Gia hạn chứng chỉ SSL thất bại"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "Gia hạn chứng chỉ SSL thành công"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "Xoá trang web: %{site_name}"
 msgstr "Xoá trang web: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 #, fuzzy
 #, fuzzy
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
@@ -685,30 +715,15 @@ msgid "Deleted successfully"
 msgstr "Đã xoá thành công"
 msgstr "Đã xoá thành công"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "Triển khai"
 msgstr "Triển khai"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "Triển khai %{conf_name} tới %{node_name} thành công"
-
-#: src/views/stream/components/Deploy.vue:34
-#, fuzzy
-msgid "Deploy successfully"
-msgstr "Triển khai thành công"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "Mô tả"
 msgstr "Mô tả"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr ""
 msgstr ""
 
 
@@ -750,32 +765,52 @@ msgstr "Tắt"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "Tắt tự động gia hạn SSL cho %{name} thất bại"
 msgstr "Tắt tự động gia hạn SSL cho %{name} thất bại"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 #, fuzzy
 #, fuzzy
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:82
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "Gia hạn chứng chỉ SSL thất bại"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "Gia hạn chứng chỉ SSL thành công"
+
+#: src/components/Notification/notifications.ts:46
 #, fuzzy
 #, fuzzy
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
+msgid "Disable site %{name} from %{node} failed"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 
 
-#: src/components/Notification/config.ts:74
+#: src/components/Notification/notifications.ts:50
 #, fuzzy
 #, fuzzy
-msgid "Disable Site %{site} on %{node} successfully"
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "Đã bật %{conf_name} trên %{node_name}"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "Không thể bật %{conf_name} trên %{node_name}"
+
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "Đã tắt"
 msgstr "Đã tắt"
 
 
@@ -807,13 +842,6 @@ msgstr ""
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/Deploy.vue:16
-#, fuzzy
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "Bạn có muốn triển khai tệp này đến máy chủ từ xa không?"
-msgstr[1] "Bạn có muốn triển khai tệp này đến máy chủ từ xa không?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "Bạn muốn tắt tự động gia hạn chứng chỉ SSL ?"
 msgstr "Bạn muốn tắt tự động gia hạn chứng chỉ SSL ?"
@@ -895,28 +923,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "Nhân bản"
 msgstr "Nhân bản"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-#, fuzzy
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-#, fuzzy
-msgid "Duplicate failed"
-msgstr "Nhân bản thất bại"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-#, fuzzy
-msgid "Duplicate successfully"
-msgstr "Nhân bản thành công"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 #, fuzzy
 #, fuzzy
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "Đã sao chép thành công vào máy cục bộ"
 msgstr "Đã sao chép thành công vào máy cục bộ"
@@ -927,7 +940,7 @@ msgid "Edit"
 msgstr "Sửa %{n}"
 msgstr "Sửa %{n}"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "Sửa %{n}"
 msgstr "Sửa %{n}"
 
 
@@ -954,20 +967,11 @@ msgid "Email (*)"
 msgstr "Email (*)"
 msgstr "Email (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 #, fuzzy
 #, fuzzy
 msgid "Enable"
 msgid "Enable"
 msgstr "Đã bật"
 msgstr "Đã bật"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "Không thể bật %{conf_name} trên %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "Đã bật %{conf_name} trên %{node_name}"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 #, fuzzy
 #, fuzzy
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
@@ -981,30 +985,45 @@ msgstr "Không thể bật tự động gia hạn SSL cho %{name}"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "Bật không thành công"
 msgstr "Bật không thành công"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 #, fuzzy
 #, fuzzy
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:69
+#: src/components/Notification/notifications.ts:95
 #, fuzzy
 #, fuzzy
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "Đã bật %{conf_name} trên %{node_name}"
+msgid "Enable Remote Stream Error"
+msgstr "Gia hạn chứng chỉ SSL thất bại"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:61
+#: src/components/Notification/notifications.ts:54
 #, fuzzy
 #, fuzzy
-msgid "Enable Site %{site} on %{node} successfully"
+msgid "Enable site %{name} on %{node} failed"
+msgstr "Không thể bật %{conf_name} trên %{node_name}"
+
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 msgstr "Đã bật %{conf_name} trên %{node_name}"
 
 
-#: src/views/stream/components/Deploy.vue:41
+#: src/components/Notification/notifications.ts:96
 #, fuzzy
 #, fuzzy
-msgid "Enable successfully"
-msgstr "Đã bật"
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "Không thể bật %{conf_name} trên %{node_name}"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "Đã bật %{conf_name} trên %{node_name}"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -1023,7 +1042,7 @@ msgstr "Bật TLS"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "Đã bật"
 msgstr "Đã bật"
@@ -1031,7 +1050,6 @@ msgstr "Đã bật"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "Đã bật"
 msgstr "Đã bật"
@@ -1409,6 +1427,10 @@ msgstr "Bỏ trống nếu không thay đổi"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "Bỏ trống nếu không thay đổi"
 msgstr "Bỏ trống nếu không thay đổi"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr ""
 msgstr ""
@@ -1442,7 +1464,7 @@ msgid "Load successfully"
 msgstr "Lưu thành công"
 msgstr "Lưu thành công"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 #, fuzzy
 #, fuzzy
 msgid "Local"
 msgid "Local"
 msgstr "Location"
 msgstr "Location"
@@ -1580,7 +1602,7 @@ msgstr "Single Directive"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "Tên"
 msgstr "Tên"
@@ -1654,7 +1676,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr ""
 msgstr ""
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 #, fuzzy
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
@@ -1708,7 +1730,7 @@ msgid "Nginx restarted successfully"
 msgstr "Restart Nginx thành công"
 msgstr "Restart Nginx thành công"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1761,7 +1783,7 @@ msgstr ""
 msgid "Notification"
 msgid "Notification"
 msgstr "Thông báo"
 msgstr "Thông báo"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 #, fuzzy
 #, fuzzy
 msgid "Notifications"
 msgid "Notifications"
 msgstr "Thông báo"
 msgstr "Thông báo"
@@ -1785,7 +1807,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr ""
 msgstr ""
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1800,7 +1822,7 @@ msgid "Ok"
 msgstr ""
 msgstr ""
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1809,7 +1831,6 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1819,8 +1840,8 @@ msgstr ""
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1851,17 +1872,15 @@ msgstr "Hệ điều hành"
 msgid "OS:"
 msgid "OS:"
 msgstr "Hệ điều hành:"
 msgstr "Hệ điều hành:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr ""
 msgstr ""
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "Ghi đè"
 msgstr "Ghi đè"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "Ghi đè tập tin đã tồn tại"
 msgstr "Ghi đè tập tin đã tồn tại"
 
 
@@ -1956,6 +1975,7 @@ msgstr ""
 "Trước tiên, vui lòng thêm thông tin xác thực trong Chứng chỉ > Thông tin xác "
 "Trước tiên, vui lòng thêm thông tin xác thực trong Chứng chỉ > Thông tin xác "
 "thực DNS, sau đó chọn nhà cung cấp DNS"
 "thực DNS, sau đó chọn nhà cung cấp DNS"
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1973,7 +1993,7 @@ msgstr "Vui lòng nhập username!"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "Vui lòng nhập username!"
 msgstr "Vui lòng nhập username!"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -2009,21 +2029,6 @@ msgstr "Lưu ý đơn vị cấu hình thời gian bên dưới được tính b
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr ""
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-#, fuzzy
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2175,23 +2180,13 @@ msgstr "Tải lại nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr ""
 msgstr ""
 
 
-#: src/components/Notification/config.ts:56
-#, fuzzy
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "Xoá trang web: %{site_name}"
-
-#: src/components/Notification/config.ts:48
-#, fuzzy
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 #, fuzzy
 #, fuzzy
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "Xoá thành công"
 msgstr "Xoá thành công"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 #, fuzzy
 #, fuzzy
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "Xoá thành công"
 msgstr "Xoá thành công"
@@ -2201,49 +2196,69 @@ msgstr "Xoá thành công"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 #, fuzzy
 #, fuzzy
 msgid "Rename"
 msgid "Rename"
 msgstr "Username"
 msgstr "Username"
 
 
-#: src/components/Notification/config.ts:30
+#: src/components/Notification/notifications.ts:28
 #, fuzzy
 #, fuzzy
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 #, fuzzy
 #, fuzzy
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 #, fuzzy
 #, fuzzy
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:95
+#: src/components/Notification/notifications.ts:103
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+msgid "Rename Remote Stream Error"
+msgstr "Gia hạn chứng chỉ SSL thất bại"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "Gia hạn chứng chỉ SSL thành công"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#: src/components/Notification/notifications.ts:104
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/components/Notification/config.ts:87
+#: src/components/Notification/notifications.ts:108
 #, fuzzy
 #, fuzzy
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2253,6 +2268,7 @@ msgstr "Gia hạn chứng chỉ SSL"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 #, fuzzy
 #, fuzzy
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "Gia hạn chứng chỉ SSL"
 msgstr "Gia hạn chứng chỉ SSL"
@@ -2336,7 +2352,8 @@ msgstr "Running"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "Lưu"
 msgstr "Lưu"
 
 
@@ -2350,24 +2367,44 @@ msgstr "Lưu Directive"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "Đã xảy ra lỗi khi lưu %{msg}"
 msgstr "Đã xảy ra lỗi khi lưu %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 #, fuzzy
 #, fuzzy
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:43
+#: src/components/Notification/notifications.ts:111
 #, fuzzy
 #, fuzzy
-msgid "Save site %{site} to %{node} error, response: %{resp}"
+msgid "Save Remote Stream Error"
+msgstr "Gia hạn chứng chỉ SSL thất bại"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "Gia hạn chứng chỉ SSL thành công"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/components/Notification/config.ts:35
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
+msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
+
+#: src/components/Notification/notifications.ts:116
 #, fuzzy
 #, fuzzy
-msgid "Save Site %{site} to %{node} successfully"
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2381,7 +2418,7 @@ msgstr "Lưu thành công"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "Lưu thành công"
 msgstr "Lưu thành công"
 
 
@@ -2426,7 +2463,7 @@ msgstr "Tham số server_name là bắt buộc"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 #, fuzzy
 #, fuzzy
 msgid "Session not found"
 msgid "Session not found"
 msgstr "Không tìm thấy tệp tin"
 msgstr "Không tìm thấy tệp tin"
@@ -2540,7 +2577,7 @@ msgstr "Ổn định"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "Trạng thái"
 msgstr "Trạng thái"
 
 
@@ -2553,6 +2590,16 @@ msgstr "Đã dừng"
 msgid "Storage"
 msgid "Storage"
 msgstr "Storage"
 msgstr "Storage"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "Đã tắt"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "Không tìm thấy tệp tin"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 #, fuzzy
 #, fuzzy
 msgid "Streams Directory"
 msgid "Streams Directory"
@@ -2593,6 +2640,7 @@ msgid "Switch to light theme"
 msgstr "Sử dụng Light theme"
 msgstr "Sử dụng Light theme"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr ""
 msgstr ""
 
 
@@ -2601,49 +2649,42 @@ msgstr ""
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "Gia hạn chứng chỉ SSL"
 msgstr "Gia hạn chứng chỉ SSL"
 
 
-#: src/components/Notification/cert.ts:11
-#, fuzzy
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
-
-#: src/components/Notification/cert.ts:14
+#: src/components/Notification/notifications.ts:10
 #, fuzzy
 #, fuzzy
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 #, fuzzy
 #, fuzzy
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 
 
-#: src/components/Notification/config.ts:14
+#: src/components/Notification/notifications.ts:20
 #, fuzzy
 #, fuzzy
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+msgid "Sync config %{config_name} to %{env_name} failed"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/components/Notification/config.ts:4
+#: src/components/Notification/notifications.ts:24
 #, fuzzy
 #, fuzzy
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 msgstr "Gia hạn chứng chỉ SSL thất bại"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 #, fuzzy
 #, fuzzy
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "Gia hạn chứng chỉ SSL thành công"
 msgstr "Gia hạn chứng chỉ SSL thành công"
@@ -2674,10 +2715,6 @@ msgstr "Thông tin"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr ""
 msgstr ""
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "Mục tiêu"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 #, fuzzy
 #, fuzzy
 msgid "Task not found"
 msgid "Task not found"
@@ -2810,7 +2847,7 @@ msgstr "Trường này không được để trống"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "Trường này không được để trống"
 msgstr "Trường này không được để trống"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "Trường này không được để trống"
 msgstr "Trường này không được để trống"
@@ -2921,7 +2958,7 @@ msgstr "Cập nhật thành công"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "Ngày cập nhật"
 msgstr "Ngày cập nhật"
 
 
@@ -2979,7 +3016,7 @@ msgstr "Người dùng"
 msgid "User banned"
 msgid "User banned"
 msgstr "Username"
 msgstr "Username"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr ""
 msgstr ""
 
 
@@ -3007,7 +3044,7 @@ msgstr "Phiên bản hiện tại"
 msgid "View"
 msgid "View"
 msgstr "Xem"
 msgstr "Xem"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 #, fuzzy
 #, fuzzy
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "Xem tất cả thông báo"
 msgstr "Xem tất cả thông báo"
@@ -3058,7 +3095,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr ""
 msgstr ""
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr ""
 msgstr ""
 
 
@@ -3139,6 +3176,87 @@ msgstr ""
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr ""
 msgstr ""
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "Triển khai %{conf_name} tới %{node_name} thành công"
+
+#, fuzzy
+#~ msgid "Deploy successfully"
+#~ msgstr "Triển khai thành công"
+
+#, fuzzy
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Đã bật %{conf_name} trên %{node_name}"
+
+#, fuzzy
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "Bạn có muốn triển khai tệp này đến máy chủ từ xa không?"
+#~ msgstr[1] "Bạn có muốn triển khai tệp này đến máy chủ từ xa không?"
+
+#, fuzzy
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid "Duplicate failed"
+#~ msgstr "Nhân bản thất bại"
+
+#, fuzzy
+#~ msgid "Duplicate successfully"
+#~ msgstr "Nhân bản thành công"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "Đã bật %{conf_name} trên %{node_name}"
+
+#, fuzzy
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "Đã bật %{conf_name} trên %{node_name}"
+
+#, fuzzy
+#~ msgid "Enable successfully"
+#~ msgstr "Đã bật"
+
+#, fuzzy
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "Xoá trang web: %{site_name}"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#, fuzzy
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
+
+#~ msgid "Target"
+#~ msgstr "Mục tiêu"
+
 #, fuzzy
 #, fuzzy
 #~ msgid "Directory"
 #~ msgid "Directory"
 #~ msgstr "Thư mục"
 #~ msgstr "Thư mục"

+ 267 - 175
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-02-12 03:28+0000\n"
+"PO-Revision-Date: 2025-02-25 19:05+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"
@@ -12,7 +12,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 5.9.2\n"
+"X-Generator: Poedit 3.5\n"
 "Generated-By: easygettext\n"
 "Generated-By: easygettext\n"
 
 
 #: src/views/user/userColumns.tsx:32
 #: src/views/user/userColumns.tsx:32
@@ -95,7 +95,7 @@ msgid "Additional"
 msgstr "额外选项"
 msgstr "额外选项"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "高级模式"
 msgstr "高级模式"
 
 
@@ -108,6 +108,7 @@ msgstr "然后,刷新此页面并再次点击添加 Passkey。"
 msgid "All"
 msgid "All"
 msgstr "全部"
 msgstr "全部"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr "所有恢复码都已被使用"
 msgstr "所有恢复码都已被使用"
@@ -164,7 +165,7 @@ msgstr "您确定要重设双重身份验证?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "您确定要应用于所有选定的对象吗?"
 msgstr "您确定要应用于所有选定的对象吗?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "您确定要清除所有通知吗?"
 msgstr "您确定要清除所有通知吗?"
@@ -251,7 +252,7 @@ msgstr "成功启用 %{name} 自动续签"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "返回"
 msgstr "返回"
 
 
@@ -287,7 +288,7 @@ msgid "Basic"
 msgstr "基本"
 msgstr "基本"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "基本模式"
 msgstr "基本模式"
 
 
@@ -334,16 +335,15 @@ msgstr "CADir"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "取消"
 msgstr "取消"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "不可在 Demo 中修改初始用户的密码"
 msgstr "不可在 Demo 中修改初始用户的密码"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "不可删除初始用户"
 msgstr "不可删除初始用户"
 
 
@@ -443,12 +443,12 @@ msgid "Cleaning environment variables"
 msgstr "正在清理环境变量"
 msgstr "正在清理环境变量"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "清空"
 msgstr "清空"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "清除成功"
 msgstr "清除成功"
@@ -620,18 +620,42 @@ msgstr "删除"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "彻底删除"
 msgstr "彻底删除"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "删除远程站点错误"
 msgstr "删除远程站点错误"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "删除远程站点成功"
 msgstr "删除远程站点成功"
 
 
+#: src/components/Notification/notifications.ts:79
+msgid "Delete Remote Stream Error"
+msgstr "删除远程 Stream 错误"
+
+#: src/components/Notification/notifications.ts:83
+msgid "Delete Remote Stream Success"
+msgstr "删除远程 Stream 成功"
+
+#: src/components/Notification/notifications.ts:38
+msgid "Delete site %{name} from %{node} failed"
+msgstr "部署 %{name} 到 %{node} 失败"
+
+#: src/components/Notification/notifications.ts:42
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "成功从 %{node} 中删除站点 %{name}"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "删除站点: %{site_name}"
 msgstr "删除站点: %{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "部署 %{name} 到 %{node} 失败"
+
+#: src/components/Notification/notifications.ts:84
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "成功从 %{node} 中删除站点 %{name}"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "删除 Stream: %{stream_name}"
 msgstr "删除 Stream: %{stream_name}"
@@ -641,29 +665,15 @@ msgid "Deleted successfully"
 msgstr "删除成功"
 msgstr "删除成功"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "部署"
 msgstr "部署"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "部署 %{conf_name} 到 %{node_name} 失败"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "部署 %{conf_name} 到 %{node_name} 成功"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "部署成功"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "描述"
 msgstr "描述"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr "目标文件已存在"
 msgstr "目标文件已存在"
 
 
@@ -704,28 +714,44 @@ msgstr "禁用"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "关闭 %{name} 自动续签失败"
 msgstr "关闭 %{name} 自动续签失败"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "禁用远程站点错误"
 msgstr "禁用远程站点错误"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "禁用远程站点成功"
 msgstr "禁用远程站点成功"
 
 
-#: src/components/Notification/config.ts:82
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
-msgstr "在 %{node} 上禁用 %{site} 失败, 响应: %{resp}"
+#: src/components/Notification/notifications.ts:87
+msgid "Disable Remote Stream Error"
+msgstr "禁用远程 Stream 错误"
+
+#: src/components/Notification/notifications.ts:91
+msgid "Disable Remote Stream Success"
+msgstr "禁用远程 Stream成功"
+
+#: src/components/Notification/notifications.ts:46
+msgid "Disable site %{name} from %{node} failed"
+msgstr "在 %{node} 上禁用 %{name} 成功"
 
 
-#: src/components/Notification/config.ts:74
-msgid "Disable Site %{site} on %{node} successfully"
-msgstr "在 %{node} 上禁用 %{site} 成功"
+#: src/components/Notification/notifications.ts:50
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "在 %{node} 上禁用 %{name} 成功"
+
+#: src/components/Notification/notifications.ts:88
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "在 %{node} 中启用 %{name} 失败"
+
+#: src/components/Notification/notifications.ts:92
+msgid "Disable stream %{name} from %{node} successfully"
+msgstr "在 %{node} 上禁用 %{name} 成功"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "禁用"
 msgstr "禁用"
 
 
@@ -757,11 +783,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "除非确定需要,否则不要启用该选项。"
 msgstr "除非确定需要,否则不要启用该选项。"
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "你想把这个文件部署到远程服务器上吗?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "你想禁用自动更新证书吗?"
 msgstr "你想禁用自动更新证书吗?"
@@ -834,25 +855,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "复制"
 msgstr "复制"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "成功地将%{conf_name}复制到%{node_name}"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "复制失败"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr "复制成功"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "成功复制到本地"
 msgstr "成功复制到本地"
 
 
@@ -861,7 +870,7 @@ msgid "Edit"
 msgstr "编辑"
 msgstr "编辑"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
 msgstr "编辑 %{n}"
 
 
@@ -886,19 +895,10 @@ msgid "Email (*)"
 msgstr "邮箱 (*)"
 msgstr "邮箱 (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "启用"
 msgstr "启用"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "在%{node_name}中启用%{conf_name}失败"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "成功启用%{node_name}中的%{conf_name}"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "二步验证启用成功"
 msgstr "二步验证启用成功"
@@ -911,25 +911,37 @@ msgstr "启用 %{name} 自动续签失败"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "启用失败"
 msgstr "启用失败"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "启用远程站点错误"
 msgstr "启用远程站点错误"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "启用远程站点成功"
 msgstr "启用远程站点成功"
 
 
-#: src/components/Notification/config.ts:69
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "在 %{node} 上启用 %{site} 失败,响应:%{resp}"
+#: src/components/Notification/notifications.ts:95
+msgid "Enable Remote Stream Error"
+msgstr "启用远程 Steam 错误"
 
 
-#: src/components/Notification/config.ts:61
-msgid "Enable Site %{site} on %{node} successfully"
-msgstr "在 %{node} 上启用 %{site} 成功"
+#: src/components/Notification/notifications.ts:99
+msgid "Enable Remote Stream Success"
+msgstr "启用远程 Stream 成功"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "启用成功"
+#: src/components/Notification/notifications.ts:54
+msgid "Enable site %{name} on %{node} failed"
+msgstr "在 %{node} 中启用 %{name} 失败"
+
+#: src/components/Notification/notifications.ts:58
+msgid "Enable site %{name} on %{node} successfully"
+msgstr "在 %{node} 上启用 %{name} 成功"
+
+#: src/components/Notification/notifications.ts:96
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "在 %{node} 中启用 %{name} 失败"
+
+#: src/components/Notification/notifications.ts:100
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "在 %{node} 上启用 %{name} 成功"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -947,7 +959,7 @@ msgstr "启用 TOTP"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "启用"
 msgstr "启用"
@@ -955,7 +967,6 @@ msgstr "启用"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "启用成功"
 msgstr "启用成功"
@@ -1311,6 +1322,10 @@ msgstr "如果不需要,请留空。"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "留空不做任何更改"
 msgstr "留空不做任何更改"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr "由于未启用 TOTP,因此不允许使用传统恢复代码"
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Lego 禁用 CNAME 支持"
 msgstr "Lego 禁用 CNAME 支持"
@@ -1341,7 +1356,7 @@ msgid "Load successfully"
 msgstr "加载成功"
 msgstr "加载成功"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "本地"
 msgstr "本地"
 
 
@@ -1474,7 +1489,7 @@ msgstr "多行指令"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "名称"
 msgstr "名称"
@@ -1546,7 +1561,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr "Nginx Conf 中未引用 stream-enabled"
 msgstr "Nginx Conf 中未引用 stream-enabled"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 配置解析错误"
 msgstr "Nginx 配置解析错误"
 
 
@@ -1595,7 +1610,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx 重启成功"
 msgstr "Nginx 重启成功"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1646,7 +1661,7 @@ msgstr "注意,如果配置文件中包含其他配置或证书,请提前将
 msgid "Notification"
 msgid "Notification"
 msgstr "通知"
 msgstr "通知"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr "通知"
 msgstr "通知"
 
 
@@ -1668,7 +1683,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr "某些用户在使用 Firefox 首次访问时,OCSP Must Staple 可能会导致错误。"
 msgstr "某些用户在使用 Firefox 首次访问时,OCSP Must Staple 可能会导致错误。"
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1683,7 +1698,7 @@ msgid "Ok"
 msgstr "确定"
 msgstr "确定"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1692,7 +1707,6 @@ msgstr "确定"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1702,8 +1716,8 @@ msgstr "确定"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "一旦验证完成,这些记录将被删除。"
 msgstr "一旦验证完成,这些记录将被删除。"
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1733,17 +1747,15 @@ msgstr "OS"
 msgid "OS:"
 msgid "OS:"
 msgstr "OS:"
 msgstr "OS:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "OTP 或恢复代码为空"
 msgstr "OTP 或恢复代码为空"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "覆盖"
 msgstr "覆盖"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "覆盖现有文件"
 msgstr "覆盖现有文件"
 
 
@@ -1838,6 +1850,7 @@ msgstr ""
 "请首先在 “证书”> “DNS 凭证” 中添加凭证,然后在下方选择一个凭证,请求 DNS 提供"
 "请首先在 “证书”> “DNS 凭证” 中添加凭证,然后在下方选择一个凭证,请求 DNS 提供"
 "商的 API。"
 "商的 API。"
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1853,7 +1866,7 @@ msgstr "请输入文件名"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "请输入文件夹名称"
 msgstr "请输入文件夹名称"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1886,20 +1899,6 @@ msgstr "请注意,下面的时间单位配置均以秒为单位。"
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "请至少选择一个节点进行升级"
 msgstr "请至少选择一个节点进行升级"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "请至少选择一个节点!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "请将远程 Nginx UI 升级到最新版本"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2044,20 +2043,12 @@ msgstr "正在重载 Nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr "删除"
 msgstr "删除"
 
 
-#: src/components/Notification/config.ts:56
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "从 %{node} 中删除站点 %{site} 错误,响应:%{resp}"
-
-#: src/components/Notification/config.ts:48
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "成功从 %{node} 中删除站点 %{site}"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "移除成功"
 msgstr "移除成功"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "删除成功"
 msgstr "删除成功"
 
 
@@ -2066,42 +2057,57 @@ msgstr "删除成功"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr "重命名"
 msgstr "重命名"
 
 
-#: src/components/Notification/config.ts:30
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
-msgstr ""
-"将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"
+#: src/components/Notification/notifications.ts:28
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
+msgstr "成功将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path}"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "成功将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path}"
 msgstr "成功将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path}"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "远程配置重命名错误"
 msgstr "远程配置重命名错误"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "重命名远程配置成功"
 msgstr "重命名远程配置成功"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "重命名远程站点错误"
 msgstr "重命名远程站点错误"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "重命名远程站点成功"
 msgstr "重命名远程站点成功"
 
 
-#: src/components/Notification/config.ts:95
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
-msgstr "在 %{node} 上将站点 %{site} 重命名为 %{new_site} 失败,响应:%{resp}"
+#: src/components/Notification/notifications.ts:103
+msgid "Rename Remote Stream Error"
+msgstr "重命名远程 Stream 错误"
+
+#: src/components/Notification/notifications.ts:107
+msgid "Rename Remote Stream Success"
+msgstr "重命名远程 Stream成功"
+
+#: src/components/Notification/notifications.ts:62
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "在 %{node} 上将站点 %{name} 重命名为 %{new_name} 成功"
+
+#: src/components/Notification/notifications.ts:66
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "在 %{node} 上将站点 %{name} 重命名为 %{new_name} 成功"
 
 
-#: src/components/Notification/config.ts:87
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
-msgstr "在 %{node} 上将站点 %{site} 重命名为 %{new_site} 成功"
+#: src/components/Notification/notifications.ts:104
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr "在 %{node} 上将站点 %{name} 重命名为 %{new_name} 成功"
+
+#: src/components/Notification/notifications.ts:108
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
+msgstr "在 %{node} 上将站点 %{name} 重命名为 %{new_name} 成功"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
 msgid "Rename successfully"
 msgid "Rename successfully"
@@ -2109,6 +2115,7 @@ msgstr "重命名成功"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "重命名成功"
 msgstr "重命名成功"
 
 
@@ -2185,7 +2192,8 @@ msgstr "运行中"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "保存"
 msgstr "保存"
 
 
@@ -2199,21 +2207,37 @@ msgstr "保存指令"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "保存错误 %{msg}"
 msgstr "保存错误 %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "保存远程站点错误"
 msgstr "保存远程站点错误"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "保存远程站点成功"
 msgstr "保存远程站点成功"
 
 
-#: src/components/Notification/config.ts:43
-msgid "Save site %{site} to %{node} error, response: %{resp}"
-msgstr "保存站点 %{site} 到 %{node} 错误,响应: %{resp}"
+#: src/components/Notification/notifications.ts:111
+msgid "Save Remote Stream Error"
+msgstr "保存远程 Stream 错误"
+
+#: src/components/Notification/notifications.ts:115
+msgid "Save Remote Stream Success"
+msgstr "保存远程 Stream 成功"
+
+#: src/components/Notification/notifications.ts:70
+msgid "Save site %{name} to %{node} failed"
+msgstr "成功将站点 %{name} 保存到 %{node} 中"
 
 
-#: src/components/Notification/config.ts:35
-msgid "Save Site %{site} to %{node} successfully"
-msgstr "成功将站点 %{site} 保存到 %{node} 中"
+#: src/components/Notification/notifications.ts:74
+msgid "Save site %{name} to %{node} successfully"
+msgstr "成功将站点 %{name} 保存到 %{node} 中"
+
+#: src/components/Notification/notifications.ts:112
+msgid "Save stream %{name} to %{node} failed"
+msgstr "部署 %{name} 到 %{node} 失败"
+
+#: src/components/Notification/notifications.ts:116
+msgid "Save stream %{name} to %{node} successfully"
+msgstr "成功将站点 %{name} 保存到 %{node} 中"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:97
@@ -2225,7 +2249,7 @@ msgstr "保存成功"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "保存成功"
 msgstr "保存成功"
 
 
@@ -2270,7 +2294,7 @@ msgstr "必须为 server_name 指令指明参数"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr "Server Index 超出范围"
 msgstr "Server Index 超出范围"
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 msgid "Session not found"
 msgid "Session not found"
 msgstr "未找到会话"
 msgstr "未找到会话"
 
 
@@ -2381,7 +2405,7 @@ msgstr "稳定"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "状态"
 msgstr "状态"
 
 
@@ -2394,6 +2418,14 @@ msgstr "已停止"
 msgid "Storage"
 msgid "Storage"
 msgstr "存储"
 msgstr "存储"
 
 
+#: src/constants/errors/stream.ts:4
+msgid "Stream is enabled"
+msgstr "Stream 已启用"
+
+#: src/constants/errors/stream.ts:2
+msgid "Stream not found"
+msgstr "Stream 未找到"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 msgid "Streams Directory"
 msgid "Streams Directory"
 msgstr "Streams 目录"
 msgstr "Streams 目录"
@@ -2434,6 +2466,7 @@ msgid "Switch to light theme"
 msgstr "切换到浅色"
 msgstr "切换到浅色"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "同步"
 msgstr "同步"
 
 
@@ -2441,43 +2474,35 @@ msgstr "同步"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "同步证书"
 msgstr "同步证书"
 
 
-#: src/components/Notification/cert.ts:11
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"同步证书 %{cert_name} 到 %{env_name} 失败,请先将远程的 Nginx UI 升级到最新版"
-"本"
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr "同步证书 %{cert_name} 到 %{env_name} 失败,响应:%{resp}"
+#: src/components/Notification/notifications.ts:10
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "证书 %{cert_name} 已成功同步到 %{env_name}"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "证书 %{cert_name} 已成功同步到 %{env_name}"
 msgstr "证书 %{cert_name} 已成功同步到 %{env_name}"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "同步证书错误"
 msgstr "同步证书错误"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "同步证书成功"
 msgstr "同步证书成功"
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr "同步配置 %{config_name} 到 %{env_name} 失败,响应:%{resp}"
+#: src/components/Notification/notifications.ts:20
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "配置 %{config_name} 成功同步到 %{env_name}"
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "配置 %{config_name} 成功同步到 %{env_name}"
 msgstr "配置 %{config_name} 成功同步到 %{env_name}"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "同步配置错误"
 msgstr "同步配置错误"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "同步配置成功"
 msgstr "同步配置成功"
 
 
@@ -2506,10 +2531,6 @@ msgstr "系统"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "系统初始用户"
 msgstr "系统初始用户"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "目标"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 msgid "Task not found"
 msgid "Task not found"
 msgstr "未找到任务"
 msgstr "未找到任务"
@@ -2640,7 +2661,7 @@ msgstr "该字段应是有效的电子邮件地址"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "该字段应是有效的主机名"
 msgstr "该字段应是有效的主机名"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "该字段不能为空"
 msgstr "该字段不能为空"
@@ -2752,7 +2773,7 @@ msgstr "更新成功"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "修改时间"
 msgstr "修改时间"
 
 
@@ -2805,7 +2826,7 @@ msgstr "用户"
 msgid "User banned"
 msgid "User banned"
 msgstr "用户被禁止"
 msgstr "用户被禁止"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr "用户未启用 OTP 作为 2FA"
 msgstr "用户未启用 OTP 作为 2FA"
 
 
@@ -2832,7 +2853,7 @@ msgstr "版本"
 msgid "View"
 msgid "View"
 msgstr "查看"
 msgstr "查看"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "查看全部通知"
 msgstr "查看全部通知"
 
 
@@ -2876,7 +2897,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr "Webauthn"
 msgstr "Webauthn"
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr "WebAuthn 未配置"
 msgstr "WebAuthn 未配置"
 
 
@@ -2961,6 +2982,77 @@ msgstr "您的旧代码将不再有效。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "你的 Passkeys"
 msgstr "你的 Passkeys"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "部署 %{conf_name} 到 %{node_name} 成功"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "部署成功"
+
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "在 %{node} 上禁用 %{site} 失败, 响应: %{resp}"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "你想把这个文件部署到远程服务器上吗?"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "成功地将%{conf_name}复制到%{node_name}"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "复制失败"
+
+#~ msgid "Duplicate successfully"
+#~ msgstr "复制成功"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "成功启用%{node_name}中的%{conf_name}"
+
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "在 %{node} 上启用 %{site} 失败,响应:%{resp}"
+
+#~ msgid "Enable successfully"
+#~ msgstr "启用成功"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "请至少选择一个节点!"
+
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "请将远程 Nginx UI 升级到最新版本"
+
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "从 %{node} 中删除站点 %{site} 错误,响应:%{resp}"
+
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "将 %{env_name} 上的 %{orig_path} 重命名为 %{new_path} 失败,响应:%{resp}"
+
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "在 %{node} 上将站点 %{site} 重命名为 %{new_site} 失败,响应:%{resp}"
+
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "保存站点 %{site} 到 %{node} 错误,响应: %{resp}"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "同步证书 %{cert_name} 到 %{env_name} 失败,请先将远程的 Nginx UI 升级到最"
+#~ "新版本"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "同步证书 %{cert_name} 到 %{env_name} 失败,响应:%{resp}"
+
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "同步配置 %{config_name} 到 %{env_name} 失败,响应:%{resp}"
+
+#~ msgid "Target"
+#~ msgstr "目标"
+
 #~ msgid ""
 #~ msgid ""
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "your 2FA."
 #~ "your 2FA."

+ 297 - 169
app/src/language/zh_TW/app.po

@@ -99,7 +99,7 @@ msgid "Additional"
 msgstr "其他設定"
 msgstr "其他設定"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:205
 #: src/views/site/site_edit/SiteEdit.vue:205
-#: src/views/stream/StreamEdit.vue:189
+#: src/views/stream/StreamEdit.vue:190
 msgid "Advance Mode"
 msgid "Advance Mode"
 msgstr "進階模式"
 msgstr "進階模式"
 
 
@@ -112,6 +112,7 @@ msgstr "然後,重新整理此頁面並再次點選新增通行密鑰。"
 msgid "All"
 msgid "All"
 msgstr "全部"
 msgstr "全部"
 
 
+#: src/components/Notification/notifications.ts:121
 #: src/language/constants.ts:57
 #: src/language/constants.ts:57
 msgid "All Recovery Codes Have Been Used"
 msgid "All Recovery Codes Have Been Used"
 msgstr "所有恢復碼都已使用完畢"
 msgstr "所有恢復碼都已使用完畢"
@@ -168,7 +169,7 @@ msgstr "您確定要重設 2FA 嗎?"
 msgid "Are you sure you want to apply to all selected?"
 msgid "Are you sure you want to apply to all selected?"
 msgstr "您確定要應用於所有選擇項目嗎?"
 msgstr "您確定要應用於所有選擇項目嗎?"
 
 
-#: src/components/Notification/Notification.vue:130
+#: src/components/Notification/Notification.vue:135
 #: src/views/notification/Notification.vue:39
 #: src/views/notification/Notification.vue:39
 msgid "Are you sure you want to clear all notifications?"
 msgid "Are you sure you want to clear all notifications?"
 msgstr "您確定要清除所有通知嗎?"
 msgstr "您確定要清除所有通知嗎?"
@@ -255,7 +256,7 @@ msgstr "已啟用 %{name} 的自動續簽"
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
 #: src/views/site/site_edit/SiteEdit.vue:264
 #: src/views/site/site_edit/SiteEdit.vue:264
-#: src/views/stream/StreamEdit.vue:245
+#: src/views/stream/StreamEdit.vue:246
 msgid "Back"
 msgid "Back"
 msgstr "返回"
 msgstr "返回"
 
 
@@ -291,7 +292,7 @@ msgid "Basic"
 msgstr "基本"
 msgstr "基本"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:208
 #: src/views/site/site_edit/SiteEdit.vue:208
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/stream/StreamEdit.vue:193
 msgid "Basic Mode"
 msgid "Basic Mode"
 msgstr "基本模式"
 msgstr "基本模式"
 
 
@@ -338,16 +339,15 @@ msgstr "CADir"
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxServer.vue:80
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/ngx_conf/NgxUpstream.vue:34
 #: src/views/site/site_edit/RightSettings.vue:55
 #: src/views/site/site_edit/RightSettings.vue:55
-#: src/views/stream/components/Deploy.vue:20
 #: src/views/stream/components/RightSettings.vue:51
 #: src/views/stream/components/RightSettings.vue:51
 msgid "Cancel"
 msgid "Cancel"
 msgstr "取消"
 msgstr "取消"
 
 
-#: src/constants/errors/user.ts:10
+#: src/constants/errors/user.ts:11
 msgid "Cannot change initial user password in demo mode"
 msgid "Cannot change initial user password in demo mode"
 msgstr "無法在示範模式下更改初始使用者密碼"
 msgstr "無法在示範模式下更改初始使用者密碼"
 
 
-#: src/constants/errors/user.ts:9
+#: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgid "Cannot remove initial user"
 msgstr "無法移除初始使用者"
 msgstr "無法移除初始使用者"
 
 
@@ -449,12 +449,12 @@ msgid "Cleaning environment variables"
 msgstr "清理環境變數"
 msgstr "清理環境變數"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:380
 #: src/components/ChatGPT/ChatGPT.vue:380
-#: src/components/Notification/Notification.vue:135
+#: src/components/Notification/Notification.vue:140
 #: src/views/notification/Notification.vue:44
 #: src/views/notification/Notification.vue:44
 msgid "Clear"
 msgid "Clear"
 msgstr "清除"
 msgstr "清除"
 
 
-#: src/components/Notification/Notification.vue:88
+#: src/components/Notification/Notification.vue:93
 #: src/views/notification/Notification.vue:13
 #: src/views/notification/Notification.vue:13
 msgid "Cleared successfully"
 msgid "Cleared successfully"
 msgstr "清除成功"
 msgstr "清除成功"
@@ -626,18 +626,48 @@ msgstr "刪除"
 msgid "Delete Permanently"
 msgid "Delete Permanently"
 msgstr "永久刪除"
 msgstr "永久刪除"
 
 
-#: src/language/constants.ts:49
+#: src/components/Notification/notifications.ts:37 src/language/constants.ts:49
 msgid "Delete Remote Site Error"
 msgid "Delete Remote Site Error"
 msgstr "刪除遠端網站錯誤"
 msgstr "刪除遠端網站錯誤"
 
 
-#: src/language/constants.ts:48
+#: src/components/Notification/notifications.ts:41 src/language/constants.ts:48
 msgid "Delete Remote Site Success"
 msgid "Delete Remote Site Success"
 msgstr "刪除遠端網站成功"
 msgstr "刪除遠端網站成功"
 
 
+#: src/components/Notification/notifications.ts:79
+#, fuzzy
+msgid "Delete Remote Stream Error"
+msgstr "刪除遠端網站錯誤"
+
+#: src/components/Notification/notifications.ts:83
+#, fuzzy
+msgid "Delete Remote Stream Success"
+msgstr "刪除遠端網站成功"
+
+#: src/components/Notification/notifications.ts:38
+#, fuzzy
+msgid "Delete site %{name} from %{node} failed"
+msgstr "部署 %{conf_name} 至 %{node_name} 失敗"
+
+#: src/components/Notification/notifications.ts:42
+#, fuzzy
+msgid "Delete site %{name} from %{node} successfully"
+msgstr "成功從 %{node} 移除站點 %{site}"
+
 #: src/views/site/site_list/SiteList.vue:67
 #: src/views/site/site_list/SiteList.vue:67
 msgid "Delete site: %{site_name}"
 msgid "Delete site: %{site_name}"
 msgstr "刪除網站:%{site_name}"
 msgstr "刪除網站:%{site_name}"
 
 
+#: src/components/Notification/notifications.ts:80
+#, fuzzy
+msgid "Delete stream %{name} from %{node} failed"
+msgstr "部署 %{conf_name} 至 %{node_name} 失敗"
+
+#: src/components/Notification/notifications.ts:84
+#, fuzzy
+msgid "Delete stream %{name} from %{node} successfully"
+msgstr "成功從 %{node} 移除站點 %{site}"
+
 #: src/views/stream/StreamList.vue:82
 #: src/views/stream/StreamList.vue:82
 msgid "Delete stream: %{stream_name}"
 msgid "Delete stream: %{stream_name}"
 msgstr "刪除 Stream:%{stream_name}"
 msgstr "刪除 Stream:%{stream_name}"
@@ -647,29 +677,15 @@ msgid "Deleted successfully"
 msgstr "刪除成功"
 msgstr "刪除成功"
 
 
 #: src/views/config/ConfigEditor.vue:285
 #: src/views/config/ConfigEditor.vue:285
-#: src/views/stream/components/Deploy.vue:100
-#: src/views/stream/components/RightSettings.vue:92
 msgid "Deploy"
 msgid "Deploy"
 msgstr "部署"
 msgstr "部署"
 
 
-#: src/views/stream/components/Deploy.vue:57
-msgid "Deploy %{conf_name} to %{node_name} failed"
-msgstr "部署 %{conf_name} 至 %{node_name} 失敗"
-
-#: src/views/stream/components/Deploy.vue:36
-msgid "Deploy %{conf_name} to %{node_name} successfully"
-msgstr "成功部署 %{conf_name} 至 %{node_name}"
-
-#: src/views/stream/components/Deploy.vue:34
-msgid "Deploy successfully"
-msgstr "部署成功"
-
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:107
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:121
 msgid "Description"
 msgid "Description"
 msgstr "描述"
 msgstr "描述"
 
 
-#: src/constants/errors/site.ts:3
+#: src/constants/errors/site.ts:3 src/constants/errors/stream.ts:3
 msgid "Destination file already exists"
 msgid "Destination file already exists"
 msgstr "目的檔案已存在"
 msgstr "目的檔案已存在"
 
 
@@ -710,28 +726,50 @@ msgstr "停用"
 msgid "Disable auto-renewal failed for %{name}"
 msgid "Disable auto-renewal failed for %{name}"
 msgstr "關閉 %{name} 自動續簽失敗"
 msgstr "關閉 %{name} 自動續簽失敗"
 
 
-#: src/language/constants.ts:51
+#: src/components/Notification/notifications.ts:45 src/language/constants.ts:51
 msgid "Disable Remote Site Error"
 msgid "Disable Remote Site Error"
 msgstr "禁用遠端站点錯誤"
 msgstr "禁用遠端站点錯誤"
 
 
-#: src/language/constants.ts:50
+#: src/components/Notification/notifications.ts:49 src/language/constants.ts:50
 msgid "Disable Remote Site Success"
 msgid "Disable Remote Site Success"
 msgstr "禁用遠端站点成功"
 msgstr "禁用遠端站点成功"
 
 
-#: src/components/Notification/config.ts:82
-msgid "Disable site %{site} on %{node} error, response: %{resp}"
-msgstr "禁用網站 %{site} 在 %{node} 時發生錯誤,回應:%{resp}"
+#: src/components/Notification/notifications.ts:87
+#, fuzzy
+msgid "Disable Remote Stream Error"
+msgstr "禁用遠端站点錯誤"
+
+#: src/components/Notification/notifications.ts:91
+#, fuzzy
+msgid "Disable Remote Stream Success"
+msgstr "禁用遠端站点成功"
+
+#: src/components/Notification/notifications.ts:46
+#, fuzzy
+msgid "Disable site %{name} from %{node} failed"
+msgstr "成功禁用 %{node} 中的站点 %{site}"
+
+#: src/components/Notification/notifications.ts:50
+#, fuzzy
+msgid "Disable site %{name} from %{node} successfully"
+msgstr "成功禁用 %{node} 中的站点 %{site}"
+
+#: src/components/Notification/notifications.ts:88
+#, fuzzy
+msgid "Disable stream %{name} from %{node} failed"
+msgstr "在 %{node_name} 啟用 %{conf_name} 失敗"
 
 
-#: src/components/Notification/config.ts:74
-msgid "Disable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:92
+#, fuzzy
+msgid "Disable stream %{name} from %{node} successfully"
 msgstr "成功禁用 %{node} 中的站点 %{site}"
 msgstr "成功禁用 %{node} 中的站点 %{site}"
 
 
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:61
 #: src/views/environment/envColumns.tsx:79
 #: src/views/environment/envColumns.tsx:79
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_edit/SiteEdit.vue:190
 #: src/views/site/site_list/columns.tsx:53
 #: src/views/site/site_list/columns.tsx:53
-#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:175
-#: src/views/stream/StreamList.vue:34 src/views/user/userColumns.tsx:41
+#: src/views/site/site_list/columns.tsx:62 src/views/stream/StreamEdit.vue:176
+#: src/views/stream/StreamList.vue:33 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgid "Disabled"
 msgstr "停用"
 msgstr "停用"
 
 
@@ -763,11 +801,6 @@ msgstr "DNS01"
 msgid "Do not enable this option unless you are sure that you need it."
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "除非您確定需要,否則不要啟用此選項。"
 msgstr "除非您確定需要,否則不要啟用此選項。"
 
 
-#: src/views/stream/components/Deploy.vue:16
-msgid "Do you want to deploy this file to remote server?"
-msgid_plural "Do you want to deploy this file to remote servers?"
-msgstr[0] "您要將此檔案部署至遠端伺服器嗎?"
-
 #: src/views/site/cert/components/ObtainCert.vue:136
 #: src/views/site/cert/components/ObtainCert.vue:136
 msgid "Do you want to disable auto-cert renewal?"
 msgid "Do you want to disable auto-cert renewal?"
 msgstr "您要停用自動憑證續訂嗎?"
 msgstr "您要停用自動憑證續訂嗎?"
@@ -840,25 +873,13 @@ msgstr ""
 
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:140
 #: src/views/site/site_list/SiteList.vue:140
-#: src/views/stream/components/StreamDuplicate.vue:121
+#: src/views/stream/components/StreamDuplicate.vue:64
 #: src/views/stream/StreamList.vue:160
 #: src/views/stream/StreamList.vue:160
 msgid "Duplicate"
 msgid "Duplicate"
 msgstr "複製"
 msgstr "複製"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:82
-msgid "Duplicate %{conf_name} to %{node_name} successfully"
-msgstr "成功複製 %{conf_name} 到 %{node_name}"
-
-#: src/views/stream/components/StreamDuplicate.vue:86
-msgid "Duplicate failed"
-msgstr "複製失敗"
-
-#: src/views/stream/components/StreamDuplicate.vue:80
-msgid "Duplicate successfully"
-msgstr "複製成功"
-
 #: src/views/site/site_list/SiteDuplicate.vue:48
 #: src/views/site/site_list/SiteDuplicate.vue:48
-#: src/views/stream/components/StreamDuplicate.vue:63
+#: src/views/stream/components/StreamDuplicate.vue:40
 msgid "Duplicate to local successfully"
 msgid "Duplicate to local successfully"
 msgstr "成功複製至本機"
 msgstr "成功複製至本機"
 
 
@@ -867,7 +888,7 @@ msgid "Edit"
 msgstr "編輯"
 msgstr "編輯"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:179
 #: src/views/site/site_edit/SiteEdit.vue:179
-#: src/views/stream/StreamEdit.vue:164
+#: src/views/stream/StreamEdit.vue:165
 msgid "Edit %{n}"
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
 msgstr "編輯 %{n}"
 
 
@@ -892,19 +913,10 @@ msgid "Email (*)"
 msgstr "電子郵件 (*)"
 msgstr "電子郵件 (*)"
 
 
 #: src/views/site/site_list/SiteList.vue:133
 #: src/views/site/site_list/SiteList.vue:133
-#: src/views/stream/components/Deploy.vue:80
 #: src/views/stream/StreamList.vue:153
 #: src/views/stream/StreamList.vue:153
 msgid "Enable"
 msgid "Enable"
 msgstr "啟用"
 msgstr "啟用"
 
 
-#: src/views/stream/components/Deploy.vue:47
-msgid "Enable %{conf_name} in %{node_name} failed"
-msgstr "在 %{node_name} 啟用 %{conf_name} 失敗"
-
-#: src/views/stream/components/Deploy.vue:43
-msgid "Enable %{conf_name} in %{node_name} successfully"
-msgstr "成功在 %{node_name} 啟用 %{conf_name}"
-
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:45
 msgid "Enable 2FA successfully"
 msgid "Enable 2FA successfully"
 msgstr "啟用多因素身份驗證成功"
 msgstr "啟用多因素身份驗證成功"
@@ -917,25 +929,43 @@ msgstr "啟用 %{name} 自動續簽失敗"
 msgid "Enable failed"
 msgid "Enable failed"
 msgstr "啟用失敗"
 msgstr "啟用失敗"
 
 
-#: src/language/constants.ts:53
+#: src/components/Notification/notifications.ts:53 src/language/constants.ts:53
 msgid "Enable Remote Site Error"
 msgid "Enable Remote Site Error"
 msgstr "啟用遠端站點錯誤"
 msgstr "啟用遠端站點錯誤"
 
 
-#: src/language/constants.ts:52
+#: src/components/Notification/notifications.ts:57 src/language/constants.ts:52
 msgid "Enable Remote Site Success"
 msgid "Enable Remote Site Success"
 msgstr "啟用遠端站點成功"
 msgstr "啟用遠端站點成功"
 
 
-#: src/components/Notification/config.ts:69
-msgid "Enable site %{site} on %{node} error, response: %{resp}"
-msgstr "啟用站點 %{site} 在 %{node} 時發生錯誤,回應:%{resp}"
+#: src/components/Notification/notifications.ts:95
+#, fuzzy
+msgid "Enable Remote Stream Error"
+msgstr "啟用遠端站點錯誤"
+
+#: src/components/Notification/notifications.ts:99
+#, fuzzy
+msgid "Enable Remote Stream Success"
+msgstr "啟用遠端站點成功"
+
+#: src/components/Notification/notifications.ts:54
+#, fuzzy
+msgid "Enable site %{name} on %{node} failed"
+msgstr "在 %{node_name} 啟用 %{conf_name} 失敗"
 
 
-#: src/components/Notification/config.ts:61
-msgid "Enable Site %{site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:58
+#, fuzzy
+msgid "Enable site %{name} on %{node} successfully"
 msgstr "成功啟用站點 %{site} 在 %{node}"
 msgstr "成功啟用站點 %{site} 在 %{node}"
 
 
-#: src/views/stream/components/Deploy.vue:41
-msgid "Enable successfully"
-msgstr "啟用成功"
+#: src/components/Notification/notifications.ts:96
+#, fuzzy
+msgid "Enable stream %{name} on %{node} failed"
+msgstr "在 %{node_name} 啟用 %{conf_name} 失敗"
+
+#: src/components/Notification/notifications.ts:100
+#, fuzzy
+msgid "Enable stream %{name} on %{node} successfully"
+msgstr "成功啟用站點 %{site} 在 %{node}"
 
 
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 #: src/views/site/ngx_conf/NgxConfigEditor.vue:183
 msgid "Enable TLS"
 msgid "Enable TLS"
@@ -953,7 +983,7 @@ msgstr "啟用 TOTP"
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:49
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/site/site_list/columns.tsx:61
 #: src/views/stream/components/RightSettings.vue:76
 #: src/views/stream/components/RightSettings.vue:76
-#: src/views/stream/StreamEdit.vue:169 src/views/stream/StreamList.vue:30
+#: src/views/stream/StreamEdit.vue:170 src/views/stream/StreamList.vue:29
 #: src/views/user/userColumns.tsx:38
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgid "Enabled"
 msgstr "已啟用"
 msgstr "已啟用"
@@ -961,7 +991,6 @@ msgstr "已啟用"
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_edit/RightSettings.vue:33
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/site/site_list/SiteList.vue:46 src/views/site/SiteAdd.vue:40
 #: src/views/stream/components/RightSettings.vue:29
 #: src/views/stream/components/RightSettings.vue:29
-#: src/views/stream/components/StreamDuplicate.vue:93
 #: src/views/stream/StreamList.vue:61
 #: src/views/stream/StreamList.vue:61
 msgid "Enabled successfully"
 msgid "Enabled successfully"
 msgstr "成功啟用"
 msgstr "成功啟用"
@@ -1317,6 +1346,10 @@ msgstr "留空表示不需要此項目。"
 msgid "Leave blank will not change anything"
 msgid "Leave blank will not change anything"
 msgstr "留空將不會改變任何內容"
 msgstr "留空將不會改變任何內容"
 
 
+#: src/constants/errors/user.ts:6
+msgid "Legacy recovery code not allowed since totp is not enabled"
+msgstr ""
+
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 #: src/views/site/cert/components/AutoCertStepOne.vue:105
 msgid "Lego disable CNAME Support"
 msgid "Lego disable CNAME Support"
 msgstr "Lego 停用 CNAME 支援"
 msgstr "Lego 停用 CNAME 支援"
@@ -1347,7 +1380,7 @@ msgid "Load successfully"
 msgstr "加載成功"
 msgstr "加載成功"
 
 
 #: src/components/EnvIndicator/EnvIndicator.vue:39
 #: src/components/EnvIndicator/EnvIndicator.vue:39
-#: src/components/NodeSelector/NodeSelector.vue:80
+#: src/components/NodeSelector/NodeSelector.vue:86
 msgid "Local"
 msgid "Local"
 msgstr "本機"
 msgstr "本機"
 
 
@@ -1479,7 +1512,7 @@ msgstr "多行指令"
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/columns.tsx:15
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:82
 #: src/views/stream/components/RightSettings.vue:82
-#: src/views/stream/components/StreamDuplicate.vue:128
+#: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 #: src/views/stream/StreamList.vue:13 src/views/stream/StreamList.vue:186
 msgid "Name"
 msgid "Name"
 msgstr "名稱"
 msgstr "名稱"
@@ -1551,7 +1584,7 @@ msgid "Nginx conf not include stream-enabled"
 msgstr "Nginx 配置檔未包含 stream-enabled"
 msgstr "Nginx 配置檔未包含 stream-enabled"
 
 
 #: src/views/site/site_edit/SiteEdit.vue:223
 #: src/views/site/site_edit/SiteEdit.vue:223
-#: src/views/stream/StreamEdit.vue:207
+#: src/views/stream/StreamEdit.vue:208
 msgid "Nginx Configuration Parse Error"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 設定解析錯誤"
 msgstr "Nginx 設定解析錯誤"
 
 
@@ -1600,7 +1633,7 @@ msgid "Nginx restarted successfully"
 msgstr "Nginx 重啟成功"
 msgstr "Nginx 重啟成功"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:374
 #: src/components/ChatGPT/ChatGPT.vue:374
-#: src/components/Notification/Notification.vue:128
+#: src/components/Notification/Notification.vue:133
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:63
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:94
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:510
@@ -1651,7 +1684,7 @@ msgstr "請注意,如果配置檔包含其他配置或憑證,請提前將它
 msgid "Notification"
 msgid "Notification"
 msgstr "通知"
 msgstr "通知"
 
 
-#: src/components/Notification/Notification.vue:126 src/routes/index.ts:248
+#: src/components/Notification/Notification.vue:131 src/routes/index.ts:248
 msgid "Notifications"
 msgid "Notifications"
 msgstr "通知"
 msgstr "通知"
 
 
@@ -1673,7 +1706,7 @@ msgid ""
 "Firefox."
 "Firefox."
 msgstr "OCSP 必須裝訂可能會導致某些用戶在首次使用 Firefox 訪問時出現錯誤。"
 msgstr "OCSP 必須裝訂可能會導致某些用戶在首次使用 Firefox 訪問時出現錯誤。"
 
 
-#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:109
 #: src/views/dashboard/Environments.vue:107
 #: src/views/dashboard/Environments.vue:107
 #: src/views/environment/envColumns.tsx:56
 #: src/views/environment/envColumns.tsx:56
 msgid "Offline"
 msgid "Offline"
@@ -1688,7 +1721,7 @@ msgid "Ok"
 msgstr "確定"
 msgstr "確定"
 
 
 #: src/components/ChatGPT/ChatGPT.vue:375
 #: src/components/ChatGPT/ChatGPT.vue:375
-#: src/components/Notification/Notification.vue:129
+#: src/components/Notification/Notification.vue:134
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/components/StdDesign/StdDataDisplay/StdBulkActions.vue:95
 #: src/views/notification/Notification.vue:38
 #: src/views/notification/Notification.vue:38
 #: src/views/site/cert/components/ObtainCert.vue:139
 #: src/views/site/cert/components/ObtainCert.vue:139
@@ -1697,7 +1730,6 @@ msgstr "確定"
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_edit/RightSettings.vue:54
 #: src/views/site/site_list/SiteList.vue:144
 #: src/views/site/site_list/SiteList.vue:144
-#: src/views/stream/components/Deploy.vue:19
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/components/RightSettings.vue:50
 #: src/views/stream/StreamList.vue:164
 #: src/views/stream/StreamList.vue:164
 msgid "OK"
 msgid "OK"
@@ -1707,8 +1739,8 @@ msgstr "確定"
 msgid "Once the verification is complete, the records will be removed."
 msgid "Once the verification is complete, the records will be removed."
 msgstr "驗證完成後,記錄將被刪除。"
 msgstr "驗證完成後,記錄將被刪除。"
 
 
-#: src/components/NodeSelector/NodeSelector.vue:83
-#: src/components/NodeSelector/NodeSelector.vue:97
+#: src/components/NodeSelector/NodeSelector.vue:103
+#: src/components/NodeSelector/NodeSelector.vue:89
 #: src/views/dashboard/Environments.vue:100
 #: src/views/dashboard/Environments.vue:100
 #: src/views/environment/envColumns.tsx:52
 #: src/views/environment/envColumns.tsx:52
 msgid "Online"
 msgid "Online"
@@ -1738,17 +1770,15 @@ msgstr "作業系統"
 msgid "OS:"
 msgid "OS:"
 msgstr "作業系統:"
 msgstr "作業系統:"
 
 
-#: src/constants/errors/user.ts:8
+#: src/constants/errors/user.ts:9
 msgid "Otp or recovery code empty"
 msgid "Otp or recovery code empty"
 msgstr "OTP 或復原代碼為空"
 msgstr "OTP 或復原代碼為空"
 
 
 #: src/views/config/ConfigEditor.vue:294
 #: src/views/config/ConfigEditor.vue:294
-#: src/views/stream/components/Deploy.vue:84
 msgid "Overwrite"
 msgid "Overwrite"
 msgstr "覆蓋"
 msgstr "覆蓋"
 
 
 #: src/views/config/ConfigEditor.vue:298
 #: src/views/config/ConfigEditor.vue:298
-#: src/views/stream/components/Deploy.vue:88
 msgid "Overwrite exist file"
 msgid "Overwrite exist file"
 msgstr "覆蓋現有檔案"
 msgstr "覆蓋現有檔案"
 
 
@@ -1843,6 +1873,7 @@ msgstr ""
 "請先在「憑證」 > 「DNS 認證」中新增認證,然後選擇以下認證之一以請求 DNS 供應"
 "請先在「憑證」 > 「DNS 認證」中新增認證,然後選擇以下認證之一以請求 DNS 供應"
 "商的 API。"
 "商的 API。"
 
 
+#: src/components/Notification/notifications.ts:122
 #: src/language/constants.ts:58
 #: src/language/constants.ts:58
 msgid ""
 msgid ""
 "Please generate new recovery codes in the preferences immediately to prevent "
 "Please generate new recovery codes in the preferences immediately to prevent "
@@ -1858,7 +1889,7 @@ msgstr "請輸入檔案名稱"
 msgid "Please input a folder name"
 msgid "Please input a folder name"
 msgstr "請輸入資料夾名稱"
 msgstr "請輸入資料夾名稱"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:38
+#: src/views/stream/components/StreamDuplicate.vue:25
 msgid ""
 msgid ""
 "Please input name, this will be used as the filename of the new "
 "Please input name, this will be used as the filename of the new "
 "configuration!"
 "configuration!"
@@ -1891,20 +1922,6 @@ msgstr "請注意,以下時間配置單位均為秒。"
 msgid "Please select at least one node to upgrade"
 msgid "Please select at least one node to upgrade"
 msgstr "請至少選擇一個節點進行升級"
 msgstr "請至少選擇一個節點進行升級"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:45
-msgid "Please select at least one node!"
-msgstr "請至少選擇一個節點!"
-
-#: src/components/Notification/config.ts:11
-#: src/components/Notification/config.ts:27
-#: src/components/Notification/config.ts:41
-#: src/components/Notification/config.ts:54
-#: src/components/Notification/config.ts:67
-#: src/components/Notification/config.ts:80
-#: src/components/Notification/config.ts:93
-msgid "Please upgrade the remote Nginx UI to the latest version"
-msgstr "請將遠端 Nginx UI 升級至最新版本"
-
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:167
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/environment/BatchUpgrader.vue:220 src/views/system/Upgrade.vue:194
 #: src/views/system/Upgrade.vue:245
 #: src/views/system/Upgrade.vue:245
@@ -2048,20 +2065,12 @@ msgstr "正在重新載入 Nginx"
 msgid "Remove"
 msgid "Remove"
 msgstr "移除"
 msgstr "移除"
 
 
-#: src/components/Notification/config.ts:56
-msgid "Remove site %{site} from %{node} error, response: %{resp}"
-msgstr "從 %{node} 移除站點 %{site} 時發生錯誤,回應:%{resp}"
-
-#: src/components/Notification/config.ts:48
-msgid "Remove Site %{site} from %{node} successfully"
-msgstr "成功從 %{node} 移除站點 %{site}"
-
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/AuthSettings.vue:51
 #: src/views/preference/components/Passkey.vue:46
 #: src/views/preference/components/Passkey.vue:46
 msgid "Remove successfully"
 msgid "Remove successfully"
 msgstr "移除成功"
 msgstr "移除成功"
 
 
-#: src/components/Notification/Notification.vue:97
+#: src/components/Notification/Notification.vue:102
 msgid "Removed successfully"
 msgid "Removed successfully"
 msgstr "移除成功"
 msgstr "移除成功"
 
 
@@ -2070,42 +2079,63 @@ msgstr "移除成功"
 #: src/views/config/ConfigList.vue:166
 #: src/views/config/ConfigList.vue:166
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/ngx_conf/NgxUpstream.vue:125
 #: src/views/site/site_edit/components/ConfigName.vue:44
 #: src/views/site/site_edit/components/ConfigName.vue:44
+#: src/views/stream/components/ConfigName.vue:44
 msgid "Rename"
 msgid "Rename"
 msgstr "重命名"
 msgstr "重命名"
 
 
-#: src/components/Notification/config.ts:30
-msgid ""
-"Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
-msgstr ""
-"在 %{env_name} 上將 %{orig_path} 重命名為 %{new_path} 失敗,回應:%{resp}"
+#: src/components/Notification/notifications.ts:28
+#, fuzzy
+msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed"
+msgstr "成功將 %{env_name} 上的 %{orig_path} 重命名為 %{new_path}"
 
 
-#: src/components/Notification/config.ts:20
+#: src/components/Notification/notifications.ts:32
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgid "Rename %{orig_path} to %{new_path} on %{env_name} successfully"
 msgstr "成功將 %{env_name} 上的 %{orig_path} 重命名為 %{new_path}"
 msgstr "成功將 %{env_name} 上的 %{orig_path} 重命名為 %{new_path}"
 
 
-#: src/language/constants.ts:41
+#: src/components/Notification/notifications.ts:27 src/language/constants.ts:41
 msgid "Rename Remote Config Error"
 msgid "Rename Remote Config Error"
 msgstr "重命名遠端配置錯誤"
 msgstr "重命名遠端配置錯誤"
 
 
-#: src/language/constants.ts:40
+#: src/components/Notification/notifications.ts:31 src/language/constants.ts:40
 msgid "Rename Remote Config Success"
 msgid "Rename Remote Config Success"
 msgstr "重新命名遠端配置成功"
 msgstr "重新命名遠端配置成功"
 
 
-#: src/language/constants.ts:55
+#: src/components/Notification/notifications.ts:61 src/language/constants.ts:55
 msgid "Rename Remote Site Error"
 msgid "Rename Remote Site Error"
 msgstr "重命名遠端遠端站點時發生錯誤"
 msgstr "重命名遠端遠端站點時發生錯誤"
 
 
-#: src/language/constants.ts:54
+#: src/components/Notification/notifications.ts:65 src/language/constants.ts:54
 msgid "Rename Remote Site Success"
 msgid "Rename Remote Site Success"
 msgstr "重新命名遠端站點成功"
 msgstr "重新命名遠端站點成功"
 
 
-#: src/components/Notification/config.ts:95
-msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
-msgstr ""
-"將站點 %{site} 重新命名為 %{new_site} 於 %{node} 時發生錯誤,回應:%{resp}"
+#: src/components/Notification/notifications.ts:103
+#, fuzzy
+msgid "Rename Remote Stream Error"
+msgstr "重命名遠端遠端站點時發生錯誤"
+
+#: src/components/Notification/notifications.ts:107
+#, fuzzy
+msgid "Rename Remote Stream Success"
+msgstr "重新命名遠端站點成功"
+
+#: src/components/Notification/notifications.ts:62
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} failed"
+msgstr "成功將站點 %{site} 重新命名為 %{new_site} 於 %{node}"
 
 
-#: src/components/Notification/config.ts:87
-msgid "Rename Site %{site} to %{new_site} on %{node} successfully"
+#: src/components/Notification/notifications.ts:66
+#, fuzzy
+msgid "Rename site %{name} to %{new_name} on %{node} successfully"
+msgstr "成功將站點 %{site} 重新命名為 %{new_site} 於 %{node}"
+
+#: src/components/Notification/notifications.ts:104
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} failed"
+msgstr "成功將站點 %{site} 重新命名為 %{new_site} 於 %{node}"
+
+#: src/components/Notification/notifications.ts:108
+#, fuzzy
+msgid "Rename stream %{name} to %{new_name} on %{node} successfully"
 msgstr "成功將站點 %{site} 重新命名為 %{new_site} 於 %{node}"
 msgstr "成功將站點 %{site} 重新命名為 %{new_site} 於 %{node}"
 
 
 #: src/views/config/components/Rename.vue:42
 #: src/views/config/components/Rename.vue:42
@@ -2114,6 +2144,7 @@ msgstr "重命名成功"
 
 
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/config/components/ConfigName.vue:30
 #: src/views/site/site_edit/components/ConfigName.vue:27
 #: src/views/site/site_edit/components/ConfigName.vue:27
+#: src/views/stream/components/ConfigName.vue:27
 msgid "Renamed successfully"
 msgid "Renamed successfully"
 msgstr "重新命名成功"
 msgstr "重新命名成功"
 
 
@@ -2190,7 +2221,8 @@ msgstr "執行中"
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/components/ConfigName.vue:52
 #: src/views/site/site_edit/SiteEdit.vue:271
 #: src/views/site/site_edit/SiteEdit.vue:271
-#: src/views/stream/StreamEdit.vue:252
+#: src/views/stream/components/ConfigName.vue:52
+#: src/views/stream/StreamEdit.vue:253
 msgid "Save"
 msgid "Save"
 msgstr "儲存"
 msgstr "儲存"
 
 
@@ -2204,20 +2236,42 @@ msgstr "儲存指令"
 msgid "Save error %{msg}"
 msgid "Save error %{msg}"
 msgstr "儲存錯誤 %{msg}"
 msgstr "儲存錯誤 %{msg}"
 
 
-#: src/language/constants.ts:47
+#: src/components/Notification/notifications.ts:69 src/language/constants.ts:47
 msgid "Save Remote Site Error"
 msgid "Save Remote Site Error"
 msgstr "儲存遠端站點時發生錯誤"
 msgstr "儲存遠端站點時發生錯誤"
 
 
-#: src/language/constants.ts:46
+#: src/components/Notification/notifications.ts:73 src/language/constants.ts:46
 msgid "Save Remote Site Success"
 msgid "Save Remote Site Success"
 msgstr "儲存遠端站點成功"
 msgstr "儲存遠端站點成功"
 
 
-#: src/components/Notification/config.ts:43
-msgid "Save site %{site} to %{node} error, response: %{resp}"
-msgstr "儲存站點 %{site} 至 %{node} 時發生錯誤,回應:%{resp}"
+#: src/components/Notification/notifications.ts:111
+#, fuzzy
+msgid "Save Remote Stream Error"
+msgstr "儲存遠端站點時發生錯誤"
+
+#: src/components/Notification/notifications.ts:115
+#, fuzzy
+msgid "Save Remote Stream Success"
+msgstr "儲存遠端站點成功"
+
+#: src/components/Notification/notifications.ts:70
+#, fuzzy
+msgid "Save site %{name} to %{node} failed"
+msgstr "成功將站點 %{site} 儲存至 %{node}"
+
+#: src/components/Notification/notifications.ts:74
+#, fuzzy
+msgid "Save site %{name} to %{node} successfully"
+msgstr "成功將站點 %{site} 儲存至 %{node}"
+
+#: src/components/Notification/notifications.ts:112
+#, fuzzy
+msgid "Save stream %{name} to %{node} failed"
+msgstr "部署 %{conf_name} 至 %{node_name} 失敗"
 
 
-#: src/components/Notification/config.ts:35
-msgid "Save Site %{site} to %{node} successfully"
+#: src/components/Notification/notifications.ts:116
+#, fuzzy
+msgid "Save stream %{name} to %{node} successfully"
 msgstr "成功將站點 %{site} 儲存至 %{node}"
 msgstr "成功將站點 %{site} 儲存至 %{node}"
 
 
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:47
@@ -2230,7 +2284,7 @@ msgstr "儲存成功"
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/config/ConfigEditor.vue:167
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
 #: src/views/site/site_edit/SiteEdit.vue:152 src/views/site/SiteAdd.vue:37
-#: src/views/stream/StreamEdit.vue:138
+#: src/views/stream/StreamEdit.vue:139
 msgid "Saved successfully"
 msgid "Saved successfully"
 msgstr "儲存成功"
 msgstr "儲存成功"
 
 
@@ -2275,7 +2329,7 @@ msgstr "必須提供 server_name 參數"
 msgid "ServerIdx out of range"
 msgid "ServerIdx out of range"
 msgstr "伺服器索引超出範圍"
 msgstr "伺服器索引超出範圍"
 
 
-#: src/constants/errors/user.ts:11
+#: src/constants/errors/user.ts:12
 msgid "Session not found"
 msgid "Session not found"
 msgstr "找不到工作階段"
 msgstr "找不到工作階段"
 
 
@@ -2386,7 +2440,7 @@ msgstr "穩定"
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/ACMEUser.vue:65
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/certificate/CertificateList/certColumns.tsx:68
 #: src/views/environment/envColumns.tsx:44
 #: src/views/environment/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:23
+#: src/views/site/site_list/columns.tsx:42 src/views/stream/StreamList.vue:22
 msgid "Status"
 msgid "Status"
 msgstr "狀態"
 msgstr "狀態"
 
 
@@ -2399,6 +2453,16 @@ msgstr "已停止"
 msgid "Storage"
 msgid "Storage"
 msgstr "儲存空間"
 msgstr "儲存空間"
 
 
+#: src/constants/errors/stream.ts:4
+#, fuzzy
+msgid "Stream is enabled"
+msgstr "站點已啓用"
+
+#: src/constants/errors/stream.ts:2
+#, fuzzy
+msgid "Stream not found"
+msgstr "站點未找到"
+
 #: src/views/system/SelfCheck/tasks.ts:7
 #: src/views/system/SelfCheck/tasks.ts:7
 msgid "Streams Directory"
 msgid "Streams Directory"
 msgstr "Streams 資料夾"
 msgstr "Streams 資料夾"
@@ -2440,6 +2504,7 @@ msgid "Switch to light theme"
 msgstr "切換到淺色主題"
 msgstr "切換到淺色主題"
 
 
 #: src/views/config/components/Rename.vue:79
 #: src/views/config/components/Rename.vue:79
+#: src/views/stream/components/RightSettings.vue:92
 msgid "Sync"
 msgid "Sync"
 msgstr "同步"
 msgstr "同步"
 
 
@@ -2447,42 +2512,38 @@ msgstr "同步"
 msgid "Sync Certificate"
 msgid "Sync Certificate"
 msgstr "同步憑證"
 msgstr "同步憑證"
 
 
-#: src/components/Notification/cert.ts:11
-msgid ""
-"Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
-"remote Nginx UI to the latest version"
-msgstr ""
-"同步憑證 %{cert_name} 到 %{env_name} 失敗,請將遠端 Nginx UI 升級到最新版本"
-
-#: src/components/Notification/cert.ts:14
-msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
-msgstr "同步憑證 %{cert_name} 到 %{env_name} 失敗,回應:%{resp}"
+#: src/components/Notification/notifications.ts:10
+#, fuzzy
+msgid "Sync Certificate %{cert_name} to %{env_name} failed"
+msgstr "同步憑證 %{cert_name} 到 %{env_name} 成功"
 
 
-#: src/components/Notification/cert.ts:4
+#: src/components/Notification/notifications.ts:14
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgid "Sync Certificate %{cert_name} to %{env_name} successfully"
 msgstr "同步憑證 %{cert_name} 到 %{env_name} 成功"
 msgstr "同步憑證 %{cert_name} 到 %{env_name} 成功"
 
 
-#: src/language/constants.ts:38
+#: src/components/Notification/notifications.ts:9 src/language/constants.ts:38
 msgid "Sync Certificate Error"
 msgid "Sync Certificate Error"
 msgstr "同步憑證錯誤"
 msgstr "同步憑證錯誤"
 
 
-#: src/language/constants.ts:37
+#: src/components/Notification/notifications.ts:13 src/language/constants.ts:37
 msgid "Sync Certificate Success"
 msgid "Sync Certificate Success"
 msgstr "同步憑證成功"
 msgstr "同步憑證成功"
 
 
-#: src/components/Notification/config.ts:14
-msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-msgstr "同步配置 %{config_name} 到 %{env_name} 失敗,回應:%{resp}"
+#: src/components/Notification/notifications.ts:20
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} failed"
+msgstr "同步配置 %{config_name} 到 %{env_name} 成功"
 
 
-#: src/components/Notification/config.ts:4
-msgid "Sync Config %{config_name} to %{env_name} successfully"
+#: src/components/Notification/notifications.ts:24
+#, fuzzy
+msgid "Sync config %{config_name} to %{env_name} successfully"
 msgstr "同步配置 %{config_name} 到 %{env_name} 成功"
 msgstr "同步配置 %{config_name} 到 %{env_name} 成功"
 
 
-#: src/language/constants.ts:44
+#: src/components/Notification/notifications.ts:19 src/language/constants.ts:44
 msgid "Sync Config Error"
 msgid "Sync Config Error"
 msgstr "同步配置錯誤"
 msgstr "同步配置錯誤"
 
 
-#: src/language/constants.ts:43
+#: src/components/Notification/notifications.ts:23 src/language/constants.ts:43
 msgid "Sync Config Success"
 msgid "Sync Config Success"
 msgstr "同步配置成功"
 msgstr "同步配置成功"
 
 
@@ -2511,10 +2572,6 @@ msgstr "系統"
 msgid "System Initial User"
 msgid "System Initial User"
 msgstr "系統初始使用者"
 msgstr "系統初始使用者"
 
 
-#: src/views/stream/components/StreamDuplicate.vue:135
-msgid "Target"
-msgstr "目標"
-
 #: src/constants/errors/self_check.ts:2
 #: src/constants/errors/self_check.ts:2
 msgid "Task not found"
 msgid "Task not found"
 msgstr "找不到任務"
 msgstr "找不到任務"
@@ -2645,7 +2702,7 @@ msgstr "此欄位應為有效的電子郵件地址"
 msgid "This field should be a valid hostname"
 msgid "This field should be a valid hostname"
 msgstr "此欄位應為有效的主機名稱"
 msgstr "此欄位應為有效的主機名稱"
 
 
-#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:45
+#: src/components/StdDesign/StdDataEntry/StdFormItem.vue:39
 #: src/constants/form_errors.ts:2
 #: src/constants/form_errors.ts:2
 msgid "This field should not be empty"
 msgid "This field should not be empty"
 msgstr "此欄位不應為空"
 msgstr "此欄位不應為空"
@@ -2757,7 +2814,7 @@ msgstr "更新成功"
 #: 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
 #: src/views/stream/components/RightSettings.vue:85
 #: src/views/stream/components/RightSettings.vue:85
-#: src/views/stream/StreamList.vue:43 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:42 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgid "Updated at"
 msgstr "更新時間"
 msgstr "更新時間"
 
 
@@ -2810,7 +2867,7 @@ msgstr "使用者名稱"
 msgid "User banned"
 msgid "User banned"
 msgstr "用戶被禁止"
 msgstr "用戶被禁止"
 
 
-#: src/constants/errors/user.ts:7
+#: src/constants/errors/user.ts:8
 msgid "User not enabled otp as 2fa"
 msgid "User not enabled otp as 2fa"
 msgstr "使用者未啟用 OTP 作為雙重身份驗證 (2FA)"
 msgstr "使用者未啟用 OTP 作為雙重身份驗證 (2FA)"
 
 
@@ -2837,7 +2894,7 @@ msgstr "版本"
 msgid "View"
 msgid "View"
 msgstr "檢視"
 msgstr "檢視"
 
 
-#: src/components/Notification/Notification.vue:187
+#: src/components/Notification/Notification.vue:202
 msgid "View all notifications"
 msgid "View all notifications"
 msgstr "查看所有通知"
 msgstr "查看所有通知"
 
 
@@ -2882,7 +2939,7 @@ msgstr ""
 msgid "Webauthn"
 msgid "Webauthn"
 msgstr "Webauthn"
 msgstr "Webauthn"
 
 
-#: src/constants/errors/user.ts:6
+#: src/constants/errors/user.ts:7
 msgid "WebAuthn settings are not configured"
 msgid "WebAuthn settings are not configured"
 msgstr "WebAuthn 設定尚未配置"
 msgstr "WebAuthn 設定尚未配置"
 
 
@@ -2967,6 +3024,77 @@ msgstr "您的舊代碼將不再有效。"
 msgid "Your passkeys"
 msgid "Your passkeys"
 msgstr "您的通行密鑰"
 msgstr "您的通行密鑰"
 
 
+#~ msgid "Deploy %{conf_name} to %{node_name} successfully"
+#~ msgstr "成功部署 %{conf_name} 至 %{node_name}"
+
+#~ msgid "Deploy successfully"
+#~ msgstr "部署成功"
+
+#~ msgid "Disable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "禁用網站 %{site} 在 %{node} 時發生錯誤,回應:%{resp}"
+
+#~ msgid "Do you want to deploy this file to remote server?"
+#~ msgid_plural "Do you want to deploy this file to remote servers?"
+#~ msgstr[0] "您要將此檔案部署至遠端伺服器嗎?"
+
+#~ msgid "Duplicate %{conf_name} to %{node_name} successfully"
+#~ msgstr "成功複製 %{conf_name} 到 %{node_name}"
+
+#~ msgid "Duplicate failed"
+#~ msgstr "複製失敗"
+
+#~ msgid "Duplicate successfully"
+#~ msgstr "複製成功"
+
+#~ msgid "Enable %{conf_name} in %{node_name} successfully"
+#~ msgstr "成功在 %{node_name} 啟用 %{conf_name}"
+
+#~ msgid "Enable site %{site} on %{node} error, response: %{resp}"
+#~ msgstr "啟用站點 %{site} 在 %{node} 時發生錯誤,回應:%{resp}"
+
+#~ msgid "Enable successfully"
+#~ msgstr "啟用成功"
+
+#~ msgid "Please select at least one node!"
+#~ msgstr "請至少選擇一個節點!"
+
+#~ msgid "Please upgrade the remote Nginx UI to the latest version"
+#~ msgstr "請將遠端 Nginx UI 升級至最新版本"
+
+#~ msgid "Remove site %{site} from %{node} error, response: %{resp}"
+#~ msgstr "從 %{node} 移除站點 %{site} 時發生錯誤,回應:%{resp}"
+
+#~ msgid ""
+#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
+#~ "%{resp}"
+#~ msgstr ""
+#~ "在 %{env_name} 上將 %{orig_path} 重命名為 %{new_path} 失敗,回應:%{resp}"
+
+#~ msgid ""
+#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgstr ""
+#~ "將站點 %{site} 重新命名為 %{new_site} 於 %{node} 時發生錯誤,回應:%{resp}"
+
+#~ msgid "Save site %{site} to %{node} error, response: %{resp}"
+#~ msgstr "儲存站點 %{site} 至 %{node} 時發生錯誤,回應:%{resp}"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, please upgrade the "
+#~ "remote Nginx UI to the latest version"
+#~ msgstr ""
+#~ "同步憑證 %{cert_name} 到 %{env_name} 失敗,請將遠端 Nginx UI 升級到最新版"
+#~ "本"
+
+#~ msgid ""
+#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "同步憑證 %{cert_name} 到 %{env_name} 失敗,回應:%{resp}"
+
+#~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
+#~ msgstr "同步配置 %{config_name} 到 %{env_name} 失敗,回應:%{resp}"
+
+#~ msgid "Target"
+#~ msgstr "目標"
+
 #~ msgid ""
 #~ msgid ""
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "If you lose your mobile phone, you can use the recovery code to reset "
 #~ "your 2FA."
 #~ "your 2FA."

+ 245 - 0
cmd/notification/generate.go

@@ -0,0 +1,245 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// Structure for notification function calls
+type NotificationCall struct {
+	Type    string
+	Title   string
+	Content string
+	Path    string
+}
+
+// Directories to exclude
+var excludeDirs = []string{
+	".devcontainer", ".github", ".idea", ".pnpm-store",
+	".vscode", "app", "query", "tmp",
+}
+
+// Main function
+func main() {
+	// Start scanning from the current directory
+	root := "."
+	calls := []NotificationCall{}
+
+	// Scan all Go files
+	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+
+		// Skip excluded directories
+		for _, dir := range excludeDirs {
+			if strings.HasPrefix(path, "./"+dir) || strings.HasPrefix(path, dir+"/") {
+				if info.IsDir() {
+					return filepath.SkipDir
+				}
+				return nil
+			}
+		}
+
+		// Only process Go files
+		if !info.IsDir() && strings.HasSuffix(path, ".go") {
+			findNotificationCalls(path, &calls)
+		}
+
+		return nil
+	})
+
+	if err != nil {
+		fmt.Printf("Error walking the path: %v\n", err)
+		return
+	}
+
+	// Generate a single TS file
+	generateSingleTSFile(calls)
+
+	fmt.Printf("Found %d notification calls\n", len(calls))
+}
+
+// Find notification function calls in Go files
+func findNotificationCalls(filePath string, calls *[]NotificationCall) {
+	// Parse Go code
+	fset := token.NewFileSet()
+	node, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
+	if err != nil {
+		fmt.Printf("Error parsing %s: %v\n", filePath, err)
+		return
+	}
+
+	// Traverse the AST to find function calls
+	ast.Inspect(node, func(n ast.Node) bool {
+		callExpr, ok := n.(*ast.CallExpr)
+		if !ok {
+			return true
+		}
+
+		// Check if it's a call to the notification package
+		selExpr, ok := callExpr.Fun.(*ast.SelectorExpr)
+		if !ok {
+			return true
+		}
+
+		xident, ok := selExpr.X.(*ast.Ident)
+		if !ok {
+			return true
+		}
+
+		// Check if it's one of the functions we're interested in: notification.Info/Error/Warning/Success
+		if xident.Name == "notification" {
+			funcName := selExpr.Sel.Name
+			if funcName == "Info" || funcName == "Error" || funcName == "Warning" || funcName == "Success" {
+				// Function must have at least two parameters (title, content)
+				if len(callExpr.Args) >= 2 {
+					titleArg := callExpr.Args[0]
+					contentArg := callExpr.Args[1]
+
+					// Get parameter values
+					title := getStringValue(titleArg)
+					content := getStringValue(contentArg)
+
+					// Ignore cases where content is a variable name or function call
+					if content != "" && !isVariableOrFunctionCall(content) {
+						*calls = append(*calls, NotificationCall{
+							Type:    funcName,
+							Title:   title,
+							Content: content,
+							Path:    filePath,
+						})
+					}
+				}
+			}
+		}
+
+		return true
+	})
+}
+
+// Check if the string is a variable name or function call
+func isVariableOrFunctionCall(s string) bool {
+	// Simple check: if the string doesn't contain spaces or quotes, it might be a variable name
+	if !strings.Contains(s, " ") && !strings.Contains(s, "\"") && !strings.Contains(s, "'") {
+		return true
+	}
+
+	// If it looks like a function call, e.g., err.Error()
+	if strings.Contains(s, "(") && strings.Contains(s, ")") {
+		return true
+	}
+
+	return false
+}
+
+// Get string value from AST node
+func getStringValue(expr ast.Expr) string {
+	// Direct string
+	if lit, ok := expr.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+		// Return string without quotes
+		return strings.Trim(lit.Value, "\"")
+	}
+
+	// Recover string value from source code expression
+	var str strings.Builder
+	if bin, ok := expr.(*ast.BinaryExpr); ok {
+		// Handle string concatenation expression
+		leftStr := getStringValue(bin.X)
+		rightStr := getStringValue(bin.Y)
+		str.WriteString(leftStr)
+		str.WriteString(rightStr)
+	}
+
+	if str.Len() > 0 {
+		return str.String()
+	}
+
+	// Return empty string if unable to parse as string
+	return ""
+}
+
+// Generate a single TypeScript file
+func generateSingleTSFile(calls []NotificationCall) {
+	// Create target directory
+	targetDir := "app/src/components/Notification"
+	err := os.MkdirAll(targetDir, 0755)
+	if err != nil {
+		fmt.Printf("Error creating directory %s: %v\n", targetDir, err)
+		return
+	}
+
+	// Create file name
+	tsFilePath := filepath.Join(targetDir, "notifications.ts")
+
+	// Prepare file content
+	var content strings.Builder
+	content.WriteString("// Auto-generated notification texts\n")
+	content.WriteString("// Extracted from Go source code notification function calls\n")
+	content.WriteString("/* eslint-disable ts/no-explicit-any */\n\n")
+	content.WriteString("const notifications: Record<string, { title: () => string, content: (args: any) => string }> = {\n")
+
+	// Track used keys to avoid duplicates
+	usedKeys := make(map[string]bool)
+
+	// Organize notifications by directory
+	messagesByDir := make(map[string][]NotificationCall)
+	for _, call := range calls {
+		dir := filepath.Dir(call.Path)
+		// Extract module name from directory path
+		dirParts := strings.Split(dir, "/")
+		moduleName := dirParts[len(dirParts)-1]
+		if strings.HasPrefix(dir, "internal/") || strings.HasPrefix(dir, "api/") {
+			messagesByDir[moduleName] = append(messagesByDir[moduleName], call)
+		} else {
+			messagesByDir["general"] = append(messagesByDir["general"], call)
+		}
+	}
+
+	// Add comments for each module and write notifications
+	for module, moduleCalls := range messagesByDir {
+		content.WriteString(fmt.Sprintf("\n  // %s module notifications\n", module))
+
+		for _, call := range moduleCalls {
+			// Escape quotes in title and content
+			escapedTitle := strings.ReplaceAll(call.Title, "'", "\\'")
+			escapedContent := strings.ReplaceAll(call.Content, "'", "\\'")
+
+			// Use just the title as the key
+			key := call.Title
+
+			// Check if key is already used, generate unique key if necessary
+			uniqueKey := key
+			counter := 1
+			for usedKeys[uniqueKey] {
+				uniqueKey = fmt.Sprintf("%s_%d", key, counter)
+				counter++
+			}
+
+			usedKeys[uniqueKey] = true
+
+			// Write record with both title and content as functions
+			content.WriteString(fmt.Sprintf("  '%s': {\n", uniqueKey))
+			content.WriteString(fmt.Sprintf("    title: () => $gettext('%s'),\n", escapedTitle))
+			content.WriteString(fmt.Sprintf("    content: (args: any) => $gettext('%s', args),\n", escapedContent))
+			content.WriteString("  },\n")
+		}
+	}
+
+	content.WriteString("}\n\n")
+	content.WriteString("export default notifications\n")
+
+	// Write file
+	err = os.WriteFile(tsFilePath, []byte(content.String()), 0644)
+	if err != nil {
+		fmt.Printf("Error writing TS file %s: %v\n", tsFilePath, err)
+		return
+	}
+
+	fmt.Printf("Generated single TS file: %s with %d notifications\n", tsFilePath, len(calls))
+}

+ 3 - 0
gen.sh

@@ -6,3 +6,6 @@ go run cmd/errdef/generate.go -project . -type ts -output ./app/src/constants/er
 
 
 # parse nginx directive indexs
 # parse nginx directive indexs
 go run cmd/ngx_dir_index/ngx_dir_index.go ./internal/nginx/nginx_directives.json
 go run cmd/ngx_dir_index/ngx_dir_index.go ./internal/nginx/nginx_directives.json
+
+# generate notification texts
+go run cmd/notification/generate.go

+ 6 - 6
internal/cert/auto_cert.go

@@ -42,14 +42,14 @@ func autoCert(certModel *model.Cert) {
 	if len(certModel.Domains) == 0 {
 	if len(certModel.Domains) == 0 {
 		log.Error(errors.New("domains list is empty, " +
 		log.Error(errors.New("domains list is empty, " +
 			"try to reopen auto-cert for this config:" + confName))
 			"try to reopen auto-cert for this config:" + confName))
-		notification.Error("Renew Certificate Error", confName)
+		notification.Error("Renew Certificate Error", confName, nil)
 		return
 		return
 	}
 	}
 
 
 	if certModel.SSLCertificatePath == "" {
 	if certModel.SSLCertificatePath == "" {
 		log.Error(errors.New("ssl certificate path is empty, " +
 		log.Error(errors.New("ssl certificate path is empty, " +
 			"try to reopen auto-cert for this config:" + confName))
 			"try to reopen auto-cert for this config:" + confName))
-		notification.Error("Renew Certificate Error", confName)
+		notification.Error("Renew Certificate Error", confName, nil)
 		return
 		return
 	}
 	}
 
 
@@ -57,7 +57,7 @@ func autoCert(certModel *model.Cert) {
 	if err != nil {
 	if err != nil {
 		// Get certificate info error, ignore this certificate
 		// Get certificate info error, ignore this certificate
 		log.Error(errors.Wrap(err, "get certificate info error"))
 		log.Error(errors.Wrap(err, "get certificate info error"))
-		notification.Error("Renew Certificate Error", strings.Join(certModel.Domains, ", "))
+		notification.Error("Renew Certificate Error", strings.Join(certModel.Domains, ", "), nil)
 		return
 		return
 	}
 	}
 	if int(time.Now().Sub(certInfo.NotBefore).Hours()/24) < settings.CertSettings.GetCertRenewalInterval() {
 	if int(time.Now().Sub(certInfo.NotBefore).Hours()/24) < settings.CertSettings.GetCertRenewalInterval() {
@@ -103,14 +103,14 @@ func autoCert(certModel *model.Cert) {
 	// block, unless errChan closed
 	// block, unless errChan closed
 	for err := range errChan {
 	for err := range errChan {
 		log.Error(err)
 		log.Error(err)
-		notification.Error("Renew Certificate Error", strings.Join(payload.ServerName, ", "))
+		notification.Error("Renew Certificate Error", strings.Join(payload.ServerName, ", "), nil)
 		return
 		return
 	}
 	}
 
 
-	notification.Success("Renew Certificate Success", strings.Join(payload.ServerName, ", "))
+	notification.Success("Renew Certificate Success", strings.Join(payload.ServerName, ", "), nil)
 	err = SyncToRemoteServer(certModel)
 	err = SyncToRemoteServer(certModel)
 	if err != nil {
 	if err != nil {
-		notification.Error("Sync Certificate Error", err.Error())
+		notification.Error("Sync Certificate Error", err.Error(), nil)
 		return
 		return
 	}
 	}
 
 

+ 10 - 12
internal/cert/sync.go

@@ -3,6 +3,10 @@ package cert
 import (
 import (
 	"bytes"
 	"bytes"
 	"encoding/json"
 	"encoding/json"
+	"io"
+	"net/http"
+	"os"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
@@ -11,9 +15,6 @@ import (
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
-	"io"
-	"net/http"
-	"os"
 )
 )
 
 
 type SyncCertificatePayload struct {
 type SyncCertificatePayload struct {
@@ -80,7 +81,7 @@ type SyncNotificationPayload struct {
 	StatusCode int    `json:"status_code"`
 	StatusCode int    `json:"status_code"`
 	CertName   string `json:"cert_name"`
 	CertName   string `json:"cert_name"`
 	EnvName    string `json:"env_name"`
 	EnvName    string `json:"env_name"`
-	RespBody   string `json:"resp_body"`
+	Response   string `json:"response"`
 }
 }
 
 
 func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err error) {
 func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err error) {
@@ -115,20 +116,17 @@ func deploy(env *model.Environment, c *model.Cert, payloadBytes []byte) (err err
 		StatusCode: resp.StatusCode,
 		StatusCode: resp.StatusCode,
 		CertName:   c.Name,
 		CertName:   c.Name,
 		EnvName:    env.Name,
 		EnvName:    env.Name,
-		RespBody:   string(respBody),
-	}
-
-	notificationPayloadBytes, err := json.Marshal(notificationPayload)
-	if err != nil {
-		return
+		Response:   string(respBody),
 	}
 	}
 
 
 	if resp.StatusCode != http.StatusOK {
 	if resp.StatusCode != http.StatusOK {
-		notification.Error("Sync Certificate Error", string(notificationPayloadBytes))
+		notification.Error("Sync Certificate Error",
+			"Sync Certificate %{cert_name} to %{env_name} failed", notificationPayload)
 		return
 		return
 	}
 	}
 
 
-	notification.Success("Sync Certificate Success", string(notificationPayloadBytes))
+	notification.Success("Sync Certificate Success",
+		"Sync Certificate %{cert_name} to %{env_name} successfully", notificationPayload)
 
 
 	return
 	return
 }
 }

+ 14 - 23
internal/config/sync.go

@@ -4,6 +4,12 @@ import (
 	"bytes"
 	"bytes"
 	"crypto/tls"
 	"crypto/tls"
 	"encoding/json"
 	"encoding/json"
+	"io"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
@@ -13,11 +19,6 @@ import (
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
-	"io"
-	"net/http"
-	"os"
-	"path/filepath"
-	"strings"
 )
 )
 
 
 type SyncConfigPayload struct {
 type SyncConfigPayload struct {
@@ -104,7 +105,7 @@ type SyncNotificationPayload struct {
 	StatusCode int    `json:"status_code"`
 	StatusCode int    `json:"status_code"`
 	ConfigName string `json:"config_name"`
 	ConfigName string `json:"config_name"`
 	EnvName    string `json:"env_name"`
 	EnvName    string `json:"env_name"`
-	RespBody   string `json:"resp_body"`
+	Response   string `json:"response"`
 }
 }
 
 
 func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payloadBytes []byte) (err error) {
 func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payloadBytes []byte) (err error) {
@@ -139,20 +140,15 @@ func (p *SyncConfigPayload) deploy(env *model.Environment, c *model.Config, payl
 		StatusCode: resp.StatusCode,
 		StatusCode: resp.StatusCode,
 		ConfigName: c.Name,
 		ConfigName: c.Name,
 		EnvName:    env.Name,
 		EnvName:    env.Name,
-		RespBody:   string(respBody),
-	}
-
-	notificationPayloadBytes, err := json.Marshal(notificationPayload)
-	if err != nil {
-		return
+		Response:   string(respBody),
 	}
 	}
 
 
 	if resp.StatusCode != http.StatusOK {
 	if resp.StatusCode != http.StatusOK {
-		notification.Error("Sync Config Error", string(notificationPayloadBytes))
+		notification.Error("Sync Config Error", "Sync config %{config_name} to %{env_name} failed", notificationPayload)
 		return
 		return
 	}
 	}
 
 
-	notification.Success("Sync Config Success", string(notificationPayloadBytes))
+	notification.Success("Sync Config Success", "Sync config %{config_name} to %{env_name} successfully", notificationPayload)
 
 
 	return
 	return
 }
 }
@@ -167,7 +163,7 @@ type SyncRenameNotificationPayload struct {
 	OrigPath   string `json:"orig_path"`
 	OrigPath   string `json:"orig_path"`
 	NewPath    string `json:"new_path"`
 	NewPath    string `json:"new_path"`
 	EnvName    string `json:"env_name"`
 	EnvName    string `json:"env_name"`
-	RespBody   string `json:"resp_body"`
+	Response   string `json:"response"`
 }
 }
 
 
 func (p *RenameConfigPayload) rename(env *model.Environment) (err error) {
 func (p *RenameConfigPayload) rename(env *model.Environment) (err error) {
@@ -215,20 +211,15 @@ func (p *RenameConfigPayload) rename(env *model.Environment) (err error) {
 		OrigPath:   p.Filepath,
 		OrigPath:   p.Filepath,
 		NewPath:    p.NewFilepath,
 		NewPath:    p.NewFilepath,
 		EnvName:    env.Name,
 		EnvName:    env.Name,
-		RespBody:   string(respBody),
-	}
-
-	notificationPayloadBytes, err := json.Marshal(notificationPayload)
-	if err != nil {
-		return
+		Response:   string(respBody),
 	}
 	}
 
 
 	if resp.StatusCode != http.StatusOK {
 	if resp.StatusCode != http.StatusOK {
-		notification.Error("Rename Remote Config Error", string(notificationPayloadBytes))
+		notification.Error("Rename Remote Config Error", "Rename %{orig_path} to %{new_path} on %{env_name} failed", notificationPayload)
 		return
 		return
 	}
 	}
 
 
-	notification.Success("Rename Remote Config Success", string(notificationPayloadBytes))
+	notification.Success("Rename Remote Config Success", "Rename %{orig_path} to %{new_path} on %{env_name} successfully", notificationPayload)
 
 
 	return
 	return
 }
 }

+ 8 - 55
internal/notification/notification.go

@@ -2,67 +2,20 @@ package notification
 
 
 import (
 import (
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/model"
-	"github.com/0xJacky/Nginx-UI/query"
-	"github.com/gin-gonic/gin"
-	"github.com/uozi-tech/cosy/logger"
-	"sync"
 )
 )
 
 
-var (
-	clientMap = make(map[*gin.Context]chan *model.Notification)
-	mutex     = &sync.RWMutex{}
-)
-
-func SetClient(c *gin.Context, evtChan chan *model.Notification) {
-	mutex.Lock()
-	defer mutex.Unlock()
-	clientMap[c] = evtChan
-}
-
-func RemoveClient(c *gin.Context) {
-	mutex.Lock()
-	defer mutex.Unlock()
-	close(clientMap[c])
-	delete(clientMap, c)
-}
-
-func Info(title string, details string) {
-	push(model.NotificationInfo, title, details)
+func Info(title string, content string, details any) {
+	push(model.NotificationInfo, title, content, details)
 }
 }
 
 
-func Error(title string, details string) {
-	push(model.NotificationError, title, details)
+func Error(title string, content string, details any) {
+	push(model.NotificationError, title, content, details)
 }
 }
 
 
-func Warning(title string, details string) {
-	push(model.NotificationWarning, title, details)
-}
-
-func Success(title string, details string) {
-	push(model.NotificationSuccess, title, details)
-}
-
-func push(nType model.NotificationType, title string, details string) {
-	n := query.Notification
-
-	data := &model.Notification{
-		Type:    nType,
-		Title:   title,
-		Details: details,
-	}
-
-	err := n.Create(data)
-	if err != nil {
-		logger.Error(err)
-		return
-	}
-	broadcast(data)
+func Warning(title string, content string, details any) {
+	push(model.NotificationWarning, title, content, details)
 }
 }
 
 
-func broadcast(data *model.Notification) {
-	mutex.RLock()
-	defer mutex.RUnlock()
-	for _, evtChan := range clientMap {
-		evtChan <- data
-	}
+func Success(title string, content string, details any) {
+	push(model.NotificationSuccess, title, content, details)
 }
 }

+ 54 - 0
internal/notification/subscribe.go

@@ -0,0 +1,54 @@
+package notification
+
+import (
+	"sync"
+
+	"github.com/0xJacky/Nginx-UI/model"
+	"github.com/0xJacky/Nginx-UI/query"
+	"github.com/gin-gonic/gin"
+	"github.com/uozi-tech/cosy/logger"
+)
+
+var (
+	clientMap = make(map[*gin.Context]chan *model.Notification)
+	mutex     = &sync.RWMutex{}
+)
+
+func SetClient(c *gin.Context, evtChan chan *model.Notification) {
+	mutex.Lock()
+	defer mutex.Unlock()
+	clientMap[c] = evtChan
+}
+
+func RemoveClient(c *gin.Context) {
+	mutex.Lock()
+	defer mutex.Unlock()
+	close(clientMap[c])
+	delete(clientMap, c)
+}
+
+func broadcast(data *model.Notification) {
+	mutex.RLock()
+	defer mutex.RUnlock()
+	for _, evtChan := range clientMap {
+		evtChan <- data
+	}
+}
+
+func push(nType model.NotificationType, title string, content string, details any) {
+	n := query.Notification
+
+	data := &model.Notification{
+		Type:    nType,
+		Title:   title,
+		Content: content,
+		Details: details,
+	}
+
+	err := n.Create(data)
+	if err != nil {
+		logger.Error(err)
+		return
+	}
+	broadcast(data)
+}

+ 7 - 6
internal/site/delete.go

@@ -2,6 +2,10 @@ package site
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"net/http"
+	"os"
+	"runtime"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
@@ -9,9 +13,6 @@ import (
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/go-resty/resty/v2"
 	"github.com/go-resty/resty/v2"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
-	"net/http"
-	"os"
-	"runtime"
 )
 )
 
 
 // Delete deletes a site by removing the file in sites-available
 // Delete deletes a site by removing the file in sites-available
@@ -65,14 +66,14 @@ func syncDelete(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Delete(fmt.Sprintf("/api/sites/%s", name))
 				Delete(fmt.Sprintf("/api/sites/%s", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Delete Remote Site Error", err.Error())
+				notification.Error("Delete Remote Site Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Delete Remote Site Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Delete Remote Site Error", "Delete site %{name} from %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Delete Remote Site Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Delete Remote Site Success", "Delete site %{name} from %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 }
 }

+ 3 - 3
internal/site/disable.go

@@ -66,14 +66,14 @@ func syncDisable(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Post(fmt.Sprintf("/api/sites/%s/disable", name))
 				Post(fmt.Sprintf("/api/sites/%s/disable", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Disable Remote Site Error", err.Error())
+				notification.Error("Disable Remote Site Error", "", err.Error())
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Disable Remote Site Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Disable Remote Site Error", "Disable site %{name} from %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Disable Remote Site Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Disable Remote Site Success", "Disable site %{name} from %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 
 

+ 8 - 7
internal/site/enable.go

@@ -2,15 +2,16 @@ package site
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"net/http"
+	"os"
+	"runtime"
+	"sync"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/go-resty/resty/v2"
 	"github.com/go-resty/resty/v2"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
-	"net/http"
-	"os"
-	"runtime"
-	"sync"
 )
 )
 
 
 // Enable enables a site by creating a symlink in sites-enabled
 // Enable enables a site by creating a symlink in sites-enabled
@@ -72,14 +73,14 @@ func syncEnable(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Post(fmt.Sprintf("/api/sites/%s/enable", name))
 				Post(fmt.Sprintf("/api/sites/%s/enable", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Enable Remote Site Error", err.Error())
+				notification.Error("Enable Remote Site Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Enable Remote Site Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Enable Remote Site Error", "Enable site %{name} on %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Enable Remote Site Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Enable Remote Site Success", "Enable site %{name} on %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 
 

+ 5 - 5
internal/site/rename.go

@@ -89,18 +89,18 @@ func syncRename(oldName, newName string) {
 				}).
 				}).
 				Post(fmt.Sprintf("/api/sites/%s/rename", oldName))
 				Post(fmt.Sprintf("/api/sites/%s/rename", oldName))
 			if err != nil {
 			if err != nil {
-				notification.Error("Rename Remote Site Error", err.Error())
+				notification.Error("Rename Remote Site Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Rename Remote Site Error",
+				notification.Error("Rename Remote Site Error", "Rename site %{name} to %{new_name} on %{node} failed",
 					NewSyncResult(node.Name, oldName, resp).
 					NewSyncResult(node.Name, oldName, resp).
-						SetNewName(newName).String())
+						SetNewName(newName))
 				return
 				return
 			}
 			}
-			notification.Success("Rename Remote Site Success",
+			notification.Success("Rename Remote Site Success", "Rename site %{name} to %{new_name} on %{node} successfully",
 				NewSyncResult(node.Name, oldName, resp).
 				NewSyncResult(node.Name, oldName, resp).
-					SetNewName(newName).String())
+					SetNewName(newName))
 		}()
 		}()
 	}
 	}
 
 

+ 10 - 9
internal/site/save.go

@@ -2,6 +2,11 @@ package site
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"net/http"
+	"os"
+	"runtime"
+	"sync"
+
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
@@ -9,10 +14,6 @@ import (
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/go-resty/resty/v2"
 	"github.com/go-resty/resty/v2"
 	"github.com/uozi-tech/cosy/logger"
 	"github.com/uozi-tech/cosy/logger"
-	"net/http"
-	"os"
-	"runtime"
-	"sync"
 )
 )
 
 
 // Save saves a site configuration file
 // Save saves a site configuration file
@@ -33,13 +34,13 @@ func Save(name string, content string, overwrite bool, siteCategoryId uint64, sy
 		output := nginx.TestConf()
 		output := nginx.TestConf()
 
 
 		if nginx.GetLogLevel(output) > nginx.Warn {
 		if nginx.GetLogLevel(output) > nginx.Warn {
-			return fmt.Errorf(output)
+			return fmt.Errorf("%s", output)
 		}
 		}
 
 
 		output = nginx.Reload()
 		output = nginx.Reload()
 
 
 		if nginx.GetLogLevel(output) > nginx.Warn {
 		if nginx.GetLogLevel(output) > nginx.Warn {
-			return fmt.Errorf(output)
+			return fmt.Errorf("%s", output)
 		}
 		}
 	}
 	}
 
 
@@ -86,14 +87,14 @@ func syncSave(name string, content string) {
 				}).
 				}).
 				Post(fmt.Sprintf("/api/sites/%s", name))
 				Post(fmt.Sprintf("/api/sites/%s", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Save Remote Site Error", err.Error())
+				notification.Error("Save Remote Site Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Save Remote Site Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Save Remote Site Error", "Save site %{name} to %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Save Remote Site Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Save Remote Site Success", "Save site %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 
 
 			// 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)

+ 0 - 8
internal/site/sync.go

@@ -64,11 +64,3 @@ func (s *SyncResult) SetNewName(name string) *SyncResult {
 	s.NewName = name
 	s.NewName = name
 	return s
 	return s
 }
 }
-
-func (s *SyncResult) String() string {
-	b, err := json.Marshal(s)
-	if err != nil {
-		logger.Error(err)
-	}
-	return string(b)
-}

+ 3 - 3
internal/stream/delete.go

@@ -66,14 +66,14 @@ func syncDelete(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Delete(fmt.Sprintf("/api/streams/%s", name))
 				Delete(fmt.Sprintf("/api/streams/%s", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Delete Remote Stream Error", err.Error())
+				notification.Error("Delete Remote Stream Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Delete Remote Stream Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Delete Remote Stream Error", "Delete stream %{name} from %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Delete Remote Stream Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Delete Remote Stream Success", "Delete stream %{name} from %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 }
 }

+ 3 - 3
internal/stream/disable.go

@@ -66,14 +66,14 @@ func syncDisable(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Post(fmt.Sprintf("/api/streams/%s/disable", name))
 				Post(fmt.Sprintf("/api/streams/%s/disable", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Disable Remote Stream Error", err.Error())
+				notification.Error("Disable Remote Stream Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Disable Remote Stream Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Disable Remote Stream Error", "Disable stream %{name} from %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Disable Remote Stream Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Disable Remote Stream Success", "Disable stream %{name} from %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 
 

+ 3 - 3
internal/stream/enable.go

@@ -72,14 +72,14 @@ func syncEnable(name string) {
 				SetHeader("X-Node-Secret", node.Token).
 				SetHeader("X-Node-Secret", node.Token).
 				Post(fmt.Sprintf("/api/streams/%s/enable", name))
 				Post(fmt.Sprintf("/api/streams/%s/enable", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Enable Remote Stream Error", err.Error())
+				notification.Error("Enable Remote Stream Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Enable Remote Stream Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Enable Remote Stream Error", "Enable stream %{name} on %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Enable Remote Stream Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Enable Remote Stream Success", "Enable stream %{name} on %{node} successfully", NewSyncResult(node.Name, name, resp))
 		}()
 		}()
 	}
 	}
 
 

+ 5 - 5
internal/stream/rename.go

@@ -89,18 +89,18 @@ func syncRename(oldName, newName string) {
 				}).
 				}).
 				Post(fmt.Sprintf("/api/streams/%s/rename", oldName))
 				Post(fmt.Sprintf("/api/streams/%s/rename", oldName))
 			if err != nil {
 			if err != nil {
-				notification.Error("Rename Remote Stream Error", err.Error())
+				notification.Error("Rename Remote Stream Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Rename Remote Stream Error",
+				notification.Error("Rename Remote Stream Error", "Rename stream %{name} to %{new_name} on %{node} failed",
 					NewSyncResult(node.Name, oldName, resp).
 					NewSyncResult(node.Name, oldName, resp).
-						SetNewName(newName).String())
+						SetNewName(newName))
 				return
 				return
 			}
 			}
-			notification.Success("Rename Remote Stream Success",
+			notification.Success("Rename Remote Stream Success", "Rename stream %{name} to %{new_name} on %{node} successfully",
 				NewSyncResult(node.Name, oldName, resp).
 				NewSyncResult(node.Name, oldName, resp).
-					SetNewName(newName).String())
+					SetNewName(newName))
 		}()
 		}()
 	}
 	}
 
 

+ 3 - 3
internal/stream/save.go

@@ -86,14 +86,14 @@ func syncSave(name string, content string) {
 				}).
 				}).
 				Post(fmt.Sprintf("/api/streams/%s", name))
 				Post(fmt.Sprintf("/api/streams/%s", name))
 			if err != nil {
 			if err != nil {
-				notification.Error("Save Remote Stream Error", err.Error())
+				notification.Error("Save Remote Stream Error", err.Error(), nil)
 				return
 				return
 			}
 			}
 			if resp.StatusCode() != http.StatusOK {
 			if resp.StatusCode() != http.StatusOK {
-				notification.Error("Save Remote Stream Error", NewSyncResult(node.Name, name, resp).String())
+				notification.Error("Save Remote Stream Error", "Save stream %{name} to %{node} failed", NewSyncResult(node.Name, name, resp))
 				return
 				return
 			}
 			}
-			notification.Success("Save Remote Stream Success", NewSyncResult(node.Name, name, resp).String())
+			notification.Success("Save Remote Stream Success", "Save stream %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
 
 
 			// 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)

+ 0 - 8
internal/stream/sync.go

@@ -64,11 +64,3 @@ func (s *SyncResult) SetNewName(name string) *SyncResult {
 	s.NewName = name
 	s.NewName = name
 	return s
 	return s
 }
 }
-
-func (s *SyncResult) String() string {
-	b, err := json.Marshal(s)
-	if err != nil {
-		logger.Error(err)
-	}
-	return string(b)
-}

+ 1 - 1
internal/user/otp.go

@@ -68,7 +68,7 @@ func VerifyOTP(user *model.User, otp, recoveryCode string) (err error) {
 			}
 			}
 		}
 		}
 		if verified && usedCount == len(user.RecoveryCodes.Codes) {
 		if verified && usedCount == len(user.RecoveryCodes.Codes) {
-			notification.Warning("All Recovery Codes Have Been Used", "Please generate new recovery codes in the preferences immediately to prevent lockout.")
+			notification.Warning("All Recovery Codes Have Been Used", "Please generate new recovery codes in the preferences immediately to prevent lockout.", nil)
 		}
 		}
 		return ErrRecoveryCode
 		return ErrRecoveryCode
 	}
 	}

+ 2 - 1
model/notification.go

@@ -13,5 +13,6 @@ type Notification struct {
 	Model
 	Model
 	Type    NotificationType `json:"type"`
 	Type    NotificationType `json:"type"`
 	Title   string           `json:"title"`
 	Title   string           `json:"title"`
-	Details string           `json:"details"`
+	Content string           `json:"content"`
+	Details any              `json:"details" gorm:"serializer:json"`
 }
 }