Browse Source

chore: update translations

Jacky 2 months ago
parent
commit
530ef8e12f

+ 158 - 94
app/src/language/ar/app.po

@@ -40,7 +40,7 @@ msgid "ACME User"
 msgstr "مستخدم ACME"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -48,7 +48,7 @@ msgstr "مستخدم ACME"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "إجراء"
@@ -59,7 +59,7 @@ msgstr "إجراء"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "إضافة"
 
@@ -68,8 +68,8 @@ msgstr "إضافة"
 msgid "Add a passkey"
 msgstr "أضف مفتاح مرور"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "إضافة تكوين"
 
@@ -86,11 +86,11 @@ msgstr "أضف مكان"
 msgid "Add Site"
 msgstr "أضف موقع"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "أضف Stream"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "تمت الإضافة بنجاح"
 
@@ -98,8 +98,8 @@ msgstr "تمت الإضافة بنجاح"
 msgid "Additional"
 msgstr "إضافي"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "الوضع المتقدم"
 
@@ -194,8 +194,8 @@ msgstr "هل أنت متأكد أنك تريد حذف هذا العنصر نها
 msgid "Are you sure you want to delete this item?"
 msgstr "هل أنت متأكد أنك تريد حذف هذا العنصر؟"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "هل أنت متأكد أنك تريد الحذف؟"
 
@@ -280,10 +280,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "رجوع"
 
@@ -330,14 +330,14 @@ msgstr "محظور حتى"
 msgid "Base information"
 msgstr "المعلومات الأساسية"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "أساسي"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "الوضع الأساسي"
 
@@ -394,6 +394,11 @@ msgstr "إلغاء"
 msgid "Cannot change initial user password in demo mode"
 msgstr "حظر تغيير كلمة مرور root في العرض التوضيحي"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 #, fuzzy
 msgid "Cannot remove initial user"
@@ -465,7 +470,7 @@ msgstr[3] "الشهادات المعدلة"
 msgstr[4] "الشهادات المعدلة"
 msgstr[5] "الشهادات المعدلة"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "المسار المتغير"
 
@@ -532,6 +537,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "أمر"
@@ -543,6 +552,23 @@ msgstr "أمر"
 msgid "Comments"
 msgstr "تعليقات"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "التكوينات"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -556,6 +582,11 @@ msgstr "نماذج التكوين"
 msgid "Configuration file is test successful"
 msgstr "تم اختبار ملف التكوين بنجاح"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "التكوينات"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "اسم التكوين"
@@ -649,6 +680,11 @@ msgstr ""
 msgid "Created at"
 msgstr "تم الإنشاء في"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "تم الإنشاء في"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "تم الإنشاء بنجاح"
@@ -673,6 +709,11 @@ msgstr "TOTP مفعل للحساب الحالي."
 msgid "Current account is not enabled TOTP."
 msgstr "TOTP معطل للحساب الحالي."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "الإصدار الحالي"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "الإصدار الحالي"
@@ -688,8 +729,8 @@ msgid ""
 "indicator."
 msgstr "قم بتخصيص اسم العقدة المحلية ليتم عرضها في مؤشر البيئة."
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "لوحة المعلومات"
 
@@ -710,8 +751,8 @@ msgstr "وصف"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "حذف"
 
@@ -748,7 +789,7 @@ msgstr "فشل نشر {conf_name}% إلى {node_name}%"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "تمت إزالة الموقع %{site} من %{node} بنجاح"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "حذف الموقع: ‎%{site_name}"
 
@@ -762,7 +803,7 @@ msgstr "فشل نشر {conf_name}% إلى {node_name}%"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "تمت إزالة الموقع %{site} من %{node} بنجاح"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "حذف البث: ‎%{stream_name}"
 
@@ -774,7 +815,7 @@ msgstr "تم الحذف بنجاح"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "نشر"
 
@@ -815,8 +856,8 @@ msgstr ""
 msgid "Directives"
 msgstr "توجيهات"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "تعطيل"
 
@@ -867,17 +908,17 @@ msgstr "تم تعطيل الموقع %{site} على %{node} بنجاح"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "معطل"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "تم التعطيل بنجاح"
 
@@ -977,9 +1018,9 @@ msgstr ""
 "الويب غير HTTPS، إلا عند التشغيل على localhost."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "مكرر"
 
@@ -993,12 +1034,12 @@ msgstr "تم النسخ إلى المحلي بنجاح"
 msgid "Edit"
 msgstr "تعديل %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "تعديل %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "تعديل التكوين"
 
@@ -1019,8 +1060,8 @@ msgstr "بريد إلكتروني"
 msgid "Email (*)"
 msgstr "البريد الإلكتروني (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "تفعيل"
 
@@ -1094,20 +1135,20 @@ msgstr "تفعيل TOTP"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "مفعل"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "تم التفعيل بنجاح"
 
@@ -1130,6 +1171,10 @@ msgstr "البيئات"
 msgid "Error"
 msgstr "خطأ"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1139,11 +1184,15 @@ msgstr "سجلات الأخطاء"
 msgid "Error Logs"
 msgstr "سجلات الأخطاء"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "مسار الملف التنفيذي"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "منتهي الصلاحية"
@@ -1296,16 +1345,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "فشل في تعطيل %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "فشل في التفعيل %{msg}"
 
@@ -1351,6 +1400,11 @@ msgstr "فشل في الحصول على معلومات الشهادة"
 msgid "Failed to get certificate information"
 msgstr "فشل في الحصول على معلومات الشهادة"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "فشل في التفعيل %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1404,8 +1458,8 @@ msgstr "فشل في التفعيل %{msg}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "فشل في الحفظ، تم اكتشاف خطأ(أخطاء) في بناء الجملة في التكوين."
 
@@ -1470,15 +1524,15 @@ msgstr "للمستخدمين الصين: /https://mirror.ghproxy.com"
 msgid "Form parse failed"
 msgstr "فشل التكرار"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "تنسيق الكود"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "خطأ في التنسيق %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "تم التنسيق بنجاح"
 
@@ -1531,6 +1585,13 @@ msgstr ""
 msgid "Hide"
 msgstr "إخفاء"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "مجلد"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "الصفحة الرئيسية"
@@ -1601,10 +1662,12 @@ msgid "Import Certificate"
 msgstr "استيراد شهادة"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1680,7 +1743,7 @@ msgid "Invalid file path: {0}"
 msgstr "رمز 2FA أو الاسترداد غير صالح"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "اسم ملف غير صالح"
 
@@ -1746,7 +1809,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "نوع المفتاح"
@@ -1875,16 +1938,16 @@ msgstr ""
 "تأكد من تكوين وكيل عكسي لدليل .well-known إلى HTTPChallengePort قبل الحصول "
 "على الشهادة."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "إدارة التكوينات"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "إدارة المواقع"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr "إدارة التدفقات"
 
@@ -1946,7 +2009,7 @@ msgstr "توجيه متعدد الأسطر"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1957,7 +2020,7 @@ msgstr "توجيه متعدد الأسطر"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "اسم"
 
@@ -1986,7 +2049,7 @@ msgstr "تثبيت"
 msgid "New name"
 msgstr "اسم جديد"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr "مسار جديد"
 
@@ -2042,8 +2105,8 @@ msgstr "قائمة السماح لمجلد سجلات Nginx"
 msgid "Nginx configuration has been restored"
 msgstr "خطأ في تحليل تكوين Nginx"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "خطأ في تحليل تكوين Nginx"
 
@@ -2140,8 +2203,8 @@ msgstr "خطأ في تحليل تكوين Nginx"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "لا"
 
@@ -2151,15 +2214,19 @@ msgstr "لا"
 msgid "No Action"
 msgstr "إجراء"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "اسم العقدة"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "بيئة"
@@ -2183,7 +2250,7 @@ msgstr "سر العقدة"
 msgid "Nodes"
 msgstr "اسم العقدة"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "ليس بعد"
 
@@ -2262,9 +2329,9 @@ msgstr "حسنًا"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "حسنًا"
@@ -2314,11 +2381,11 @@ msgstr "نظام التشغيل:"
 msgid "Otp or recovery code empty"
 msgstr "استخدم رمز الاسترداد"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "الكتابة فوق"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "الكتابة فوق الملف الموجود"
 
@@ -2362,7 +2429,7 @@ msgstr "اسم المستخدم أو كلمة المرور غير صحيحة"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2439,7 +2506,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "يرجى إدخال اسم الملف"
 
@@ -2895,14 +2962,14 @@ msgstr "يعمل"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "حفظ"
 
@@ -2910,7 +2977,7 @@ msgstr "حفظ"
 msgid "Save Directive"
 msgstr "حفظ التوجيه"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2961,11 +3028,11 @@ msgstr "تم حفظ الموقع %{site} إلى %{node} بنجاح"
 msgid "Save successfully"
 msgstr "تم الحفظ بنجاح"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "تم الحفظ بنجاح"
 
@@ -3181,9 +3248,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "الحالة"
 
@@ -3627,13 +3694,13 @@ msgstr "تم التحديث بنجاح"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "محدث في"
 
@@ -3707,7 +3774,7 @@ msgid "Username (*)"
 msgstr "اسم المستخدم (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "صالح"
@@ -3989,9 +4056,6 @@ msgstr "مفاتيح المرور الخاصة بك"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "لا يمكن المسح؟ استخدم ربط مفتاح النص"
 
-#~ msgid "Directory"
-#~ msgstr "مجلد"
-
 #~ msgid "File"
 #~ msgstr "ملف"
 

+ 157 - 91
app/src/language/de_DE/app.po

@@ -37,7 +37,7 @@ msgid "ACME User"
 msgstr "Benutzername"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -45,7 +45,7 @@ msgstr "Benutzername"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Aktion"
@@ -56,7 +56,7 @@ msgstr "Aktion"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Hinzufügen"
 
@@ -65,8 +65,8 @@ msgstr "Hinzufügen"
 msgid "Add a passkey"
 msgstr "Passkey hinzufügen"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 #, fuzzy
 msgid "Add Configuration"
 msgstr "Konfiguration bearbeiten"
@@ -84,12 +84,12 @@ msgstr "Ort hinzufügen"
 msgid "Add Site"
 msgstr "Seite hinzufügen"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 #, fuzzy
 msgid "Add Stream"
 msgstr "Seite hinzufügen"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 #, fuzzy
 msgid "Added successfully"
 msgstr "Speichern erfolgreich"
@@ -99,8 +99,8 @@ msgstr "Speichern erfolgreich"
 msgid "Additional"
 msgstr "Ort hinzufügen"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Erweiterter Modus"
 
@@ -203,8 +203,8 @@ msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 msgid "Are you sure you want to delete this item?"
 msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 #, fuzzy
 msgid "Are you sure you want to delete?"
 msgstr "Bist du sicher, dass du diese Richtlinie löschen möchtest?"
@@ -294,10 +294,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Zurück"
 
@@ -345,15 +345,15 @@ msgstr "Gesperrt bis"
 msgid "Base information"
 msgstr "Basisinformationen"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 #, fuzzy
 msgid "Basic"
 msgstr "Basic-Modus"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Basic-Modus"
 
@@ -412,6 +412,11 @@ msgstr "Abbrechen"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Verhindere das Ändern des Root-Passworts in der Demo"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 #, fuzzy
 msgid "Cannot remove initial user"
@@ -481,7 +486,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Zertifikat ist gültig"
 msgstr[1] "Zertifikat ist gültig"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "Changed Path"
 msgstr "Zertifikat ist gültig"
@@ -550,6 +555,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 #, fuzzy
 msgid "Command"
@@ -562,6 +571,23 @@ msgstr "Kommando"
 msgid "Comments"
 msgstr "Kom"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Konfigurationen"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -576,6 +602,11 @@ msgstr "Konfigurationen"
 msgid "Configuration file is test successful"
 msgstr "Konfigurationsdatei erfolgreich getestet"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Konfigurationen"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Konf"
@@ -672,6 +703,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Erstellt"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Erstellt"
+
 #: src/views/config/components/Mkdir.vue:35
 #, fuzzy
 msgid "Created successfully"
@@ -697,6 +733,11 @@ msgstr "Aktuelles Konto ist TOTP aktiviert."
 msgid "Current account is not enabled TOTP."
 msgstr "Aktuelles Konto ist nicht TOTP aktiviert."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Aktuelle Version"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Aktuelle Version"
@@ -713,8 +754,8 @@ msgid ""
 msgstr ""
 "Name des lokalen Knotens anpassen, der im Umgebungsindikator angezeigt wird."
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Übersicht"
 
@@ -735,8 +776,8 @@ msgstr "Beschreibung"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Löschen"
 
@@ -775,7 +816,7 @@ msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "Speichern erfolgreich"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Seite löschen: %{site_name}"
 
@@ -789,7 +830,7 @@ msgstr "Ausführen von %{conf_name} auf %{node_name} fehlgeschlagen"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "Speichern erfolgreich"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "Stream löschen: %{stream_name}"
 
@@ -802,7 +843,7 @@ msgstr "Erfolgreich deaktiviert"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Ausführen"
 
@@ -843,8 +884,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Anweisung"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 #, fuzzy
 msgid "Disable"
 msgstr "Deaktiviert"
@@ -898,17 +939,17 @@ msgstr "Speichern erfolgreich"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Deaktiviert"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Erfolgreich deaktiviert"
 
@@ -1016,9 +1057,9 @@ msgstr ""
 "werden."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Duplizieren"
 
@@ -1033,12 +1074,12 @@ msgstr "Erfolgreich dupliziert"
 msgid "Edit"
 msgstr "Bearbeiten %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Bearbeiten %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Konfiguration bearbeiten"
 
@@ -1061,8 +1102,8 @@ msgstr "Email (*)"
 msgid "Email (*)"
 msgstr "Email (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 #, fuzzy
 msgid "Enable"
 msgstr "Aktivieren"
@@ -1141,20 +1182,20 @@ msgstr "Aktiviere TLS"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Aktiviert"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Erfolgreich aktiviert"
 
@@ -1178,6 +1219,10 @@ msgstr "Kommentare"
 msgid "Error"
 msgstr "Fehler"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1187,11 +1232,15 @@ msgstr "Feherlogs"
 msgid "Error Logs"
 msgstr "Feherlogs"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Ausführbarer Pfad"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Abgelaufen"
@@ -1345,16 +1394,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Deaktivierung von %{msg} fehlgeschlagen"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Aktiviern von %{msg} fehlgeschlagen"
 
@@ -1400,6 +1449,11 @@ msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 msgid "Failed to get certificate information"
 msgstr "Fehler beim Abrufen von Zertifikatsinformationen"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Aktiviern von %{msg} fehlgeschlagen"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1449,8 +1503,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 "Fehler beim Speichern, Syntaxfehler wurden in der Konfiguration erkannt."
@@ -1518,16 +1572,16 @@ msgstr "Für chinesische Benutzer: https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "Anlegen fehlgeschlagen"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Formatcode"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 #, fuzzy
 msgid "Format error %{msg}"
 msgstr "Fehler beim Speichern %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 #, fuzzy
 msgid "Format successfully"
 msgstr "Speichern erfolgreich"
@@ -1583,6 +1637,12 @@ msgstr ""
 msgid "Hide"
 msgstr "Verstecken"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+msgid "History"
+msgstr ""
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Startseite"
@@ -1655,10 +1715,12 @@ msgid "Import Certificate"
 msgstr "Zertifikatsstatus"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1734,7 +1796,7 @@ msgid "Invalid file path: {0}"
 msgstr "Ungültige E-Mail!"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 #, fuzzy
 msgid "Invalid filename"
 msgstr "Ungültige E-Mail!"
@@ -1803,7 +1865,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "Schlüsseltyp"
@@ -1943,16 +2005,16 @@ msgstr ""
 "zum HTTPChallengePort (Standard: 9180) konfiguriert hast, bevor du das "
 "Zertifikat erhältst."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Verwalte Konfigurationen"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Verwalte Seiten"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "Verwalte Seiten"
@@ -2021,7 +2083,7 @@ msgstr "Einzelne Anweisung"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -2032,7 +2094,7 @@ msgstr "Einzelne Anweisung"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Name"
 
@@ -2062,7 +2124,7 @@ msgstr "Installieren"
 msgid "New name"
 msgstr "Benutzername"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "Pfad"
@@ -2119,8 +2181,8 @@ msgstr "Nginx-Log-Verzeichnis-Whitelist"
 msgid "Nginx configuration has been restored"
 msgstr "Name der Konfiguration"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Name der Konfiguration"
@@ -2221,8 +2283,8 @@ msgstr "Name der Konfiguration"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "Nein"
 
@@ -2232,15 +2294,19 @@ msgstr "Nein"
 msgid "No Action"
 msgstr "Aktion"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Benuztername"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Umgebung"
@@ -2265,7 +2331,7 @@ msgstr "Node-Secret"
 msgid "Nodes"
 msgstr "Benuztername"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "Nicht nach"
 
@@ -2348,9 +2414,9 @@ msgstr "OK"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "OK"
@@ -2402,11 +2468,11 @@ msgstr "OS:"
 msgid "Otp or recovery code empty"
 msgstr "Benuzte Wiederherstellungscode"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "Überschreiben"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "Zu überschreibende Datei existiert"
 
@@ -2450,7 +2516,7 @@ msgstr "Benuztername oder Passwort ist falsch"
 msgid "Password length cannot exceed 20 characters"
 msgstr "Passwort darf nicht länger als 20 Zeichen sein"
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2531,7 +2597,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 #, fuzzy
 msgid "Please input a filename"
 msgstr "Bitte Benutzernamen eingeben!"
@@ -3017,14 +3083,14 @@ msgstr "Arbeite"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Speichern"
 
@@ -3032,7 +3098,7 @@ msgstr "Speichern"
 msgid "Save Directive"
 msgstr "Anweisung speichern"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -3086,11 +3152,11 @@ msgstr "Speichern erfolgreich"
 msgid "Save successfully"
 msgstr "Speichern erfolgreich"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Speichern erfolgreich"
 
@@ -3312,9 +3378,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Status"
 
@@ -3766,13 +3832,13 @@ msgstr "Speichern erfolgreich"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Aktualisiert am"
 
@@ -3850,7 +3916,7 @@ msgid "Username (*)"
 msgstr "Benutzername (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "Gültig"

+ 158 - 95
app/src/language/en/app.po

@@ -38,7 +38,7 @@ msgid "ACME User"
 msgstr "Username"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -46,7 +46,7 @@ msgstr "Username"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
@@ -57,7 +57,7 @@ msgstr "Action"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr ""
 
@@ -66,8 +66,8 @@ msgstr ""
 msgid "Add a passkey"
 msgstr ""
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 #, fuzzy
 msgid "Add Configuration"
 msgstr "Edit Configuration"
@@ -85,12 +85,12 @@ msgstr "Add Location"
 msgid "Add Site"
 msgstr "Add Site"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 #, fuzzy
 msgid "Add Stream"
 msgstr "Add Site"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 #, fuzzy
 msgid "Added successfully"
 msgstr "Saved successfully"
@@ -100,8 +100,8 @@ msgstr "Saved successfully"
 msgid "Additional"
 msgstr "Add Location"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Advance Mode"
 
@@ -202,8 +202,8 @@ msgstr "Are you sure you want to remove this directive?"
 msgid "Are you sure you want to delete this item?"
 msgstr "Are you sure you want to remove this directive?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 #, fuzzy
 msgid "Are you sure you want to delete?"
 msgstr "Are you sure you want to remove this directive?"
@@ -291,10 +291,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Back"
 
@@ -342,15 +342,15 @@ msgstr ""
 msgid "Base information"
 msgstr "Base information"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 #, fuzzy
 msgid "Basic"
 msgstr "Basic Mode"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Basic Mode"
 
@@ -407,6 +407,11 @@ msgstr "Cancel"
 msgid "Cannot change initial user password in demo mode"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr ""
@@ -475,7 +480,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Certificate is valid"
 msgstr[1] "Certificate is valid"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "Changed Path"
 msgstr "Certificate is valid"
@@ -544,6 +549,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 #, fuzzy
 msgid "Command"
@@ -556,6 +565,23 @@ msgstr "Comments"
 msgid "Comments"
 msgstr "Comments"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Configurations"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -570,6 +596,11 @@ msgstr "Configurations"
 msgid "Configuration file is test successful"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Configurations"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Configuration Name"
@@ -664,6 +695,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Created at"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Created at"
+
 #: src/views/config/components/Mkdir.vue:35
 #, fuzzy
 msgid "Created successfully"
@@ -689,6 +725,11 @@ msgstr ""
 msgid "Current account is not enabled TOTP."
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Content"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr ""
@@ -704,8 +745,8 @@ msgid ""
 "indicator."
 msgstr ""
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Dashboard"
 
@@ -726,8 +767,8 @@ msgstr "Enable failed"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr ""
 
@@ -766,7 +807,7 @@ msgstr "Saved successfully"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "Saved successfully"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr ""
 
@@ -780,7 +821,7 @@ msgstr "Saved successfully"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "Saved successfully"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr ""
 
@@ -793,7 +834,7 @@ msgstr "Disabled successfully"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr ""
 
@@ -834,8 +875,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Directives"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 #, fuzzy
 msgid "Disable"
 msgstr "Disabled"
@@ -889,17 +930,17 @@ msgstr "Saved successfully"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Disabled"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Disabled successfully"
 
@@ -1001,9 +1042,9 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 #, fuzzy
 msgid "Duplicate"
 msgstr "Enable failed"
@@ -1019,12 +1060,12 @@ msgstr "Saved successfully"
 msgid "Edit"
 msgstr "Edit %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Edit %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Edit Configuration"
 
@@ -1047,8 +1088,8 @@ msgstr "Email (*)"
 msgid "Email (*)"
 msgstr "Email (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 #, fuzzy
 msgid "Enable"
 msgstr "Enabled"
@@ -1127,20 +1168,20 @@ msgstr "Enable TLS"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Enabled"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Enabled successfully"
 
@@ -1164,6 +1205,10 @@ msgstr "Comments"
 msgid "Error"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 msgid "Error Log"
 msgstr ""
@@ -1172,11 +1217,15 @@ msgstr ""
 msgid "Error Logs"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr ""
@@ -1331,16 +1380,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Failed to disable %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Failed to enable %{msg}"
 
@@ -1387,6 +1436,11 @@ msgstr "Certificate is valid"
 msgid "Failed to get certificate information"
 msgstr "Certificate is valid"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Failed to enable %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1440,8 +1494,8 @@ msgstr "Failed to enable %{msg}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 
@@ -1506,16 +1560,16 @@ msgstr ""
 msgid "Form parse failed"
 msgstr "Enable failed"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 #, fuzzy
 msgid "Format error %{msg}"
 msgstr "Save error %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 #, fuzzy
 msgid "Format successfully"
 msgstr "Saved successfully"
@@ -1570,6 +1624,13 @@ msgstr ""
 msgid "Hide"
 msgstr ""
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Directive"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Home"
@@ -1635,10 +1696,12 @@ msgid "Import Certificate"
 msgstr "Certificate Status"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1716,7 +1779,7 @@ msgid "Invalid file path: {0}"
 msgstr "Invalid E-mail!"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 #, fuzzy
 msgid "Invalid filename"
 msgstr "Invalid E-mail!"
@@ -1787,7 +1850,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr ""
@@ -1920,16 +1983,16 @@ msgstr ""
 "Make sure you have configured a reverse proxy for .well-known directory to "
 "HTTPChallengePort (default: 9180) before getting the certificate."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Manage Configs"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Manage Sites"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "Manage Sites"
@@ -1998,7 +2061,7 @@ msgstr "Single Directive"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -2009,7 +2072,7 @@ msgstr "Single Directive"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Name"
 
@@ -2039,7 +2102,7 @@ msgstr "Install"
 msgid "New name"
 msgstr "Username"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "Path"
@@ -2096,8 +2159,8 @@ msgstr "Configuration Name"
 msgid "Nginx configuration has been restored"
 msgstr "Configuration Name"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Configuration Name"
@@ -2197,8 +2260,8 @@ msgstr "Configuration Name"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "No"
 
@@ -2208,15 +2271,19 @@ msgstr "No"
 msgid "No Action"
 msgstr "Action"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Username"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Comments"
@@ -2242,7 +2309,7 @@ msgstr "Username"
 msgid "Nodes"
 msgstr "Username"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr ""
 
@@ -2321,9 +2388,9 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr ""
@@ -2373,11 +2440,11 @@ msgstr "OS:"
 msgid "Otp or recovery code empty"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr ""
 
@@ -2418,7 +2485,7 @@ msgstr "Password"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2492,7 +2559,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 #, fuzzy
 msgid "Please input a filename"
 msgstr "Please input your username!"
@@ -2968,14 +3035,14 @@ msgstr ""
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Save"
 
@@ -2983,7 +3050,7 @@ msgstr "Save"
 msgid "Save Directive"
 msgstr "Save Directive"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -3037,11 +3104,11 @@ msgstr "Saved successfully"
 msgid "Save successfully"
 msgstr "Saved successfully"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Saved successfully"
 
@@ -3263,9 +3330,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Status"
 
@@ -3695,13 +3762,13 @@ msgstr "Saved successfully"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Updated at"
 
@@ -3779,7 +3846,7 @@ msgid "Username (*)"
 msgstr "Username (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 #, fuzzy
 msgid "Valid"
@@ -4029,10 +4096,6 @@ msgstr ""
 #~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
 #~ msgstr "Saved successfully"
 
-#, fuzzy
-#~ msgid "Directory"
-#~ msgstr "Directive"
-
 #~ msgid "Server error"
 #~ msgstr "Server error"
 

+ 158 - 94
app/src/language/es/app.po

@@ -43,7 +43,7 @@ msgid "ACME User"
 msgstr "Usuario ACME"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -51,7 +51,7 @@ msgstr "Usuario ACME"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Acción"
@@ -62,7 +62,7 @@ msgstr "Acción"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Agregar"
 
@@ -71,8 +71,8 @@ msgstr "Agregar"
 msgid "Add a passkey"
 msgstr "Agregar una llave de acceso"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "Agregar configuración"
 
@@ -89,11 +89,11 @@ msgstr "Agregar Ubicación"
 msgid "Add Site"
 msgstr "Agregar Sitio"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "Agregar Stream"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "Agregado exitoso"
 
@@ -101,8 +101,8 @@ msgstr "Agregado exitoso"
 msgid "Additional"
 msgstr "Adicional"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Modo avanzado"
 
@@ -199,8 +199,8 @@ msgstr "¿Está seguro de que desea eliminar este elemento de forma permanente?"
 msgid "Are you sure you want to delete this item?"
 msgstr "¿Está seguro de que quiere borrar este elemento?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "¿Está seguro de que quiere borrar?"
 
@@ -285,10 +285,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Volver"
 
@@ -335,14 +335,14 @@ msgstr "Bloqueado hasta"
 msgid "Base information"
 msgstr "Información general"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "Básico"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Modo Básico"
 
@@ -401,6 +401,11 @@ msgstr "Cancelar"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Prohibir cambiar la contraseña de root en la demostración"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 #, fuzzy
 msgid "Cannot remove initial user"
@@ -464,7 +469,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Cambiar Certificado"
 msgstr[1] "Cambiar Certificados"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "Ruta cambiada"
 
@@ -531,6 +536,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "Comando"
@@ -542,6 +551,23 @@ msgstr "Comando"
 msgid "Comments"
 msgstr "Comentarios"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Configuraciones"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -555,6 +581,11 @@ msgstr "Plantillas de configuración"
 msgid "Configuration file is test successful"
 msgstr "El archivo de configuración se probó exitosamente"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Configuraciones"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Nombre de la configuración"
@@ -648,6 +679,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Creado el"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Creado el"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "Creado con éxito"
@@ -672,6 +708,11 @@ msgstr "La cuenta actual tiene habilitada TOTP."
 msgid "Current account is not enabled TOTP."
 msgstr "La cuenta actual no tiene habilitada TOTP."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Versión actual"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Versión actual"
@@ -689,8 +730,8 @@ msgstr ""
 "Personalice el nombre del servidor local para mostrarlo en el indicador de "
 "entorno."
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Panel"
 
@@ -711,8 +752,8 @@ msgstr "Descripción"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Eliminar"
 
@@ -749,7 +790,7 @@ msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Eliminar sitio: %{site_name}"
 
@@ -763,7 +804,7 @@ msgstr "Falló el desplegado de %{conf_name} a %{node_name}"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "Eliminar stream: %{site_name}"
 
@@ -775,7 +816,7 @@ msgstr "Borrado exitoso"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Desplegar"
 
@@ -816,8 +857,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Directivas"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "Desactivar"
 
@@ -868,17 +909,17 @@ msgstr "Habilitado exitoso de %{conf_name} en %{node_name}"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Desactivado"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Desactivado con éxito"
 
@@ -977,9 +1018,9 @@ msgstr ""
 "ejecutan en el host local."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Duplicar"
 
@@ -993,12 +1034,12 @@ msgstr "Duplicado con éxito a local"
 msgid "Edit"
 msgstr "Editar %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Editar %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Editar Configuración"
 
@@ -1019,8 +1060,8 @@ msgstr "Correo"
 msgid "Email (*)"
 msgstr "Correo (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "Habilitar"
 
@@ -1097,20 +1138,20 @@ msgstr "Habilitar TLS"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Habilitado"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Habilitado con éxito"
 
@@ -1133,6 +1174,10 @@ msgstr "Entornos"
 msgid "Error"
 msgstr "Error"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1142,11 +1187,15 @@ msgstr "Logs de error"
 msgid "Error Logs"
 msgstr "Logs de error"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Ruta ejecutable"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Vencido"
@@ -1298,16 +1347,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Error al deshabilitar %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Error al habilitar %{msg}"
 
@@ -1353,6 +1402,11 @@ msgstr "No se pudo obtener la información del certificado"
 msgid "Failed to get certificate information"
 msgstr "No se pudo obtener la información del certificado"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Error al habilitar %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1402,8 +1456,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 "No se pudo guardar, se detectó un error(es) de sintaxis en la configuración."
@@ -1471,15 +1525,15 @@ msgstr "Para usuario chino: https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "Duplicado fallido"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Código de formato"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "Error de formato %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "Formateado correctamente"
 
@@ -1532,6 +1586,13 @@ msgstr ""
 msgid "Hide"
 msgstr "Ocultar"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Directorio"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Inicio"
@@ -1604,10 +1665,12 @@ msgid "Import Certificate"
 msgstr "Importar Certificado"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1681,7 +1744,7 @@ msgid "Invalid file path: {0}"
 msgstr "Nombre de archivo inválido"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "Nombre de archivo inválido"
 
@@ -1746,7 +1809,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "Tipo llave"
@@ -1878,16 +1941,16 @@ msgstr ""
 "Asegúrese de haber configurado un proxy reverso para el directorio .well-"
 "known en HTTPChallengePort antes de obtener el certificado."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Administrar configuraciones"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Administrar sitios"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr "Administrar Transmisiones"
 
@@ -1949,7 +2012,7 @@ msgstr "Directiva multilínea"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1960,7 +2023,7 @@ msgstr "Directiva multilínea"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Nombre"
 
@@ -1989,7 +2052,7 @@ msgstr "Instalar"
 msgid "New name"
 msgstr "Nuevo nombre"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr "Nueva ruta"
 
@@ -2045,8 +2108,8 @@ msgstr "Lista blanca de directorios de registro de Nginx"
 msgid "Nginx configuration has been restored"
 msgstr "Error de análisis de configuración de Nginx"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "Error de análisis de configuración de Nginx"
 
@@ -2146,8 +2209,8 @@ msgstr "Error de análisis de configuración de Nginx"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "No"
 
@@ -2157,15 +2220,19 @@ msgstr "No"
 msgid "No Action"
 msgstr "Acción"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Nuevo nombre"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Entorno"
@@ -2190,7 +2257,7 @@ msgstr "Secreto del nodo"
 msgid "Nodes"
 msgstr "Nuevo nombre"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "No después de"
 
@@ -2270,9 +2337,9 @@ msgstr "Ok"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "OK"
@@ -2322,11 +2389,11 @@ msgstr "SO:"
 msgid "Otp or recovery code empty"
 msgstr "Usar código de recuperación"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "Sobrescribir"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "Sobrescribir archivo existente"
 
@@ -2371,7 +2438,7 @@ msgstr "El nombre de usuario o contraseña son incorrectos"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2453,7 +2520,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "Por favor, ingrese un nombre de archivo"
 
@@ -2923,14 +2990,14 @@ msgstr "Corriendo"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Guardar"
 
@@ -2938,7 +3005,7 @@ msgstr "Guardar"
 msgid "Save Directive"
 msgstr "Guardar Directiva"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2991,11 +3058,11 @@ msgstr "Duplicado con éxito de %{conf_name} a %{node_name}"
 msgid "Save successfully"
 msgstr "Guardado con éxito"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Guardado con éxito"
 
@@ -3211,9 +3278,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Estado"
 
@@ -3669,13 +3736,13 @@ msgstr "Actualización exitosa"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Actualizado a"
 
@@ -3749,7 +3816,7 @@ msgid "Username (*)"
 msgstr "Nombre de usuario (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "Válido"
@@ -4029,9 +4096,6 @@ msgstr "Sus llaves de acceso"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "¿No puede escanear? Utilice la vinculación con una llave de texto"
 
-#~ msgid "Directory"
-#~ msgstr "Directorio"
-
 #~ msgid "File"
 #~ msgstr "Archivo"
 

+ 158 - 95
app/src/language/fr_FR/app.po

@@ -42,7 +42,7 @@ msgid "ACME User"
 msgstr "Nom d'utilisateur"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -50,7 +50,7 @@ msgstr "Nom d'utilisateur"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
@@ -61,7 +61,7 @@ msgstr "Action"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Ajouter"
 
@@ -70,8 +70,8 @@ msgstr "Ajouter"
 msgid "Add a passkey"
 msgstr "Ajouter une clé d'accès"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 #, fuzzy
 msgid "Add Configuration"
 msgstr "Modifier la configuration"
@@ -89,12 +89,12 @@ msgstr "Ajouter une localisation"
 msgid "Add Site"
 msgstr "Ajouter un site"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 #, fuzzy
 msgid "Add Stream"
 msgstr "Ajouter un site"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 #, fuzzy
 msgid "Added successfully"
 msgstr "Mis à jour avec succés"
@@ -104,8 +104,8 @@ msgstr "Mis à jour avec succés"
 msgid "Additional"
 msgstr "Supplémentaire"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Mode avancé"
 
@@ -209,8 +209,8 @@ msgstr "Etes-vous sûr que vous voulez supprimer ?"
 msgid "Are you sure you want to delete this item?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
 
@@ -298,10 +298,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Retour"
 
@@ -348,14 +348,14 @@ msgstr "Banni durant"
 msgid "Base information"
 msgstr "Information générale"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "Basique"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Mode simple"
 
@@ -415,6 +415,11 @@ msgstr "Annuler"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Interdire la modification du mot de passe root dans la démo"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr "Impossible de retirer l'utilisateur initial"
@@ -483,7 +488,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Changer de certificat"
 msgstr[1] "Changer de certificat"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "Changed Path"
 msgstr "Changer de certificat"
@@ -556,6 +561,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr "Clique pour copier"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 #, fuzzy
 msgid "Command"
@@ -568,6 +577,23 @@ msgstr "Commentaires"
 msgid "Comments"
 msgstr "Commentaires"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Configurations"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -581,6 +607,11 @@ msgstr "Modèles de configuration"
 msgid "Configuration file is test successful"
 msgstr "Le fichier de configuration est testé avec succès"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Configurations"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Nom de la configuration"
@@ -676,6 +707,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Créé le"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Créé le"
+
 #: src/views/config/components/Mkdir.vue:35
 #, fuzzy
 msgid "Created successfully"
@@ -701,6 +737,11 @@ msgstr "Le compte actuel a le TOTP d'activé."
 msgid "Current account is not enabled TOTP."
 msgstr "Le compte actuel n'a pas le TOTP d'activé."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Version actuelle"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Version actuelle"
@@ -718,8 +759,8 @@ msgid ""
 msgstr ""
 "Personnaliser le nom du nœud local affiché dans l'indicateur d'environnement"
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Dashboard"
 
@@ -740,8 +781,8 @@ msgstr "Description"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Supprimer"
 
@@ -780,7 +821,7 @@ msgstr "Dupliqué avec succès"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "Dupliqué avec succès"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Supprimer le site : %{site_name}"
 
@@ -794,7 +835,7 @@ msgstr "Dupliqué avec succès"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "Dupliqué avec succès"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 #, fuzzy
 msgid "Delete stream: %{stream_name}"
 msgstr "Supprimer le site : %{site_name}"
@@ -808,7 +849,7 @@ msgstr "Désactivé avec succès"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Déployer"
 
@@ -850,8 +891,8 @@ msgstr "DirectiveIdx hors limite"
 msgid "Directives"
 msgstr "Directives"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 #, fuzzy
 msgid "Disable"
 msgstr "Désactivé"
@@ -905,17 +946,17 @@ msgstr "Dupliqué avec succès"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Désactivé"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Désactivé avec succès"
 
@@ -1020,9 +1061,9 @@ msgstr ""
 "exécuté sur localhost."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Dupliquer"
 
@@ -1037,12 +1078,12 @@ msgstr "Dupliqué avec succès"
 msgid "Edit"
 msgstr "Modifier %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Modifier %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Modifier la configuration"
 
@@ -1065,8 +1106,8 @@ msgstr "Email (*)"
 msgid "Email (*)"
 msgstr "Email (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 #, fuzzy
 msgid "Enable"
 msgstr "Activé"
@@ -1145,20 +1186,20 @@ msgstr "Activer TLS"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Activé"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Activé avec succès"
 
@@ -1183,6 +1224,10 @@ msgstr "Commentaires"
 msgid "Error"
 msgstr "Erreur"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1192,11 +1237,15 @@ msgstr "Journaux d'erreurs"
 msgid "Error Logs"
 msgstr "Journaux d'erreurs"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Chemin exécutable"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Expiré"
@@ -1351,16 +1400,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Impossible de désactiver %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Impossible d'activer %{msg}"
 
@@ -1406,6 +1455,11 @@ msgstr "Échec de l'obtention des informations sur le certificat"
 msgid "Failed to get certificate information"
 msgstr "Échec de l'obtention des informations sur le certificat"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Impossible d'activer %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1461,8 +1515,8 @@ msgstr "Erreur lecture nginx.conf"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "Erreur lecture nginx.conf"
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 "Échec de l'enregistrement, une ou plusieurs erreurs de syntaxe ont été "
@@ -1533,15 +1587,15 @@ msgstr "Utilisateur chinois : https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "Dupliquer"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Code de formatage"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "Erreur de format %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "Formaté avec succès"
 
@@ -1593,6 +1647,13 @@ msgstr ""
 msgid "Hide"
 msgstr "Cacher"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Directive"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Menu principal"
@@ -1670,10 +1731,12 @@ msgid "Import Certificate"
 msgstr "État du certificat"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1749,7 +1812,7 @@ msgid "Invalid file path: {0}"
 msgstr "Format de la requête invalide"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "Nom de fichier invalide"
 
@@ -1817,7 +1880,7 @@ msgstr ""
 "Garder vos codes de récupération sécurisés autant que votre mot de passe. "
 "Nous recommandons de les enregistrer avec un gestionnaire de mots de passe."
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 #, fuzzy
 msgid "Key Type"
@@ -1953,16 +2016,16 @@ msgstr ""
 "Assurez vous d'avoir configuré un reverse proxy pour le répertoire .well-"
 "known vers HTTPChallengePort avant d'obtenir le certificat."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Gérer les configurations"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Gérer les sites"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "Gérer les sites"
@@ -2029,7 +2092,7 @@ msgstr "Directive multiligne"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -2040,7 +2103,7 @@ msgstr "Directive multiligne"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Nom"
 
@@ -2070,7 +2133,7 @@ msgstr "Installer"
 msgid "New name"
 msgstr "Nom d'utilisateur"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "Chemin"
@@ -2128,8 +2191,8 @@ msgstr "Erreur d'analyse de configuration Nginx"
 msgid "Nginx configuration has been restored"
 msgstr "Erreur d'analyse de configuration Nginx"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "Erreur d'analyse de configuration Nginx"
 
@@ -2230,8 +2293,8 @@ msgstr "Erreur d'analyse de configuration Nginx"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "Non"
 
@@ -2241,15 +2304,19 @@ msgstr "Non"
 msgid "No Action"
 msgstr "Action"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Nom d'utilisateur"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Commentaires"
@@ -2275,7 +2342,7 @@ msgstr "Secret Jwt"
 msgid "Nodes"
 msgstr "Nom d'utilisateur"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr ""
 
@@ -2352,9 +2419,9 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "OK"
@@ -2403,11 +2470,11 @@ msgstr "OS :"
 msgid "Otp or recovery code empty"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr ""
 
@@ -2448,7 +2515,7 @@ msgstr "Le pseudo ou mot de passe est incorect"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2526,7 +2593,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "Veuillez renseigner un nom de fichier"
 
@@ -3009,14 +3076,14 @@ msgstr "En cours d'éxécution"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Enregistrer"
 
@@ -3024,7 +3091,7 @@ msgstr "Enregistrer"
 msgid "Save Directive"
 msgstr "Enregistrer la directive"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -3077,11 +3144,11 @@ msgstr "Dupliqué avec succès"
 msgid "Save successfully"
 msgstr "Sauvegarde réussie"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Enregistré avec succès"
 
@@ -3301,9 +3368,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Statut"
 
@@ -3743,13 +3810,13 @@ msgstr "Mis à jour avec succés"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Mis à jour le"
 
@@ -3825,7 +3892,7 @@ msgid "Username (*)"
 msgstr "Nom d'utilisateur (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr ""
@@ -4081,10 +4148,6 @@ msgstr ""
 #~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
 #~ msgstr "Dupliqué avec succès"
 
-#, fuzzy
-#~ msgid "Directory"
-#~ msgstr "Directive"
-
 #~ msgid "File"
 #~ msgstr "Fichier"
 

+ 158 - 94
app/src/language/ko_KR/app.po

@@ -41,7 +41,7 @@ msgid "ACME User"
 msgstr "ACME 사용자"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -49,7 +49,7 @@ msgstr "ACME 사용자"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "작업"
@@ -60,7 +60,7 @@ msgstr "작업"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "추가"
 
@@ -69,8 +69,8 @@ msgstr "추가"
 msgid "Add a passkey"
 msgstr ""
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "구성 추가"
 
@@ -87,11 +87,11 @@ msgstr "위치 추가"
 msgid "Add Site"
 msgstr "사이트 추가"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "스트림 추가"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "성공적으로 추가됨"
 
@@ -99,8 +99,8 @@ msgstr "성공적으로 추가됨"
 msgid "Additional"
 msgstr "추가적인"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "고급 모드"
 
@@ -196,8 +196,8 @@ msgstr "이 항목을 영구적으로 삭제하시겠습니까?"
 msgid "Are you sure you want to delete this item?"
 msgstr "이 항목을 삭제하시겠습니까?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "정말 삭제하시겠습니까?"
 
@@ -282,10 +282,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "뒤로"
 
@@ -332,14 +332,14 @@ msgstr "차단될 시간"
 msgid "Base information"
 msgstr "기본 정보"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "기본"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "기본 모드"
 
@@ -396,6 +396,11 @@ msgstr "취소"
 msgid "Cannot change initial user password in demo mode"
 msgstr "데모에서 루트 비밀번호 변경 금지"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr ""
@@ -460,7 +465,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "인증서 변경"
 msgstr[1] "인증서 변경"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "Changed Path"
 msgstr "인증서 변경"
@@ -528,6 +533,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "명령어"
@@ -539,6 +548,23 @@ msgstr "명령어"
 msgid "Comments"
 msgstr "댓글"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "구성들"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -552,6 +578,11 @@ msgstr "구성 템플릿"
 msgid "Configuration file is test successful"
 msgstr "구성 파일 테스트 성공"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "구성들"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "구성 이름"
@@ -645,6 +676,11 @@ msgstr ""
 msgid "Created at"
 msgstr "생성 시간"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "생성 시간"
+
 #: src/views/config/components/Mkdir.vue:35
 #, fuzzy
 msgid "Created successfully"
@@ -670,6 +706,11 @@ msgstr ""
 msgid "Current account is not enabled TOTP."
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "현재 버전"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "현재 버전"
@@ -685,8 +726,8 @@ msgid ""
 "indicator."
 msgstr ""
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "대시보드"
 
@@ -707,8 +748,8 @@ msgstr "설명"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "삭제"
 
@@ -747,7 +788,7 @@ msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "사이트 삭제: %{site_name}"
 
@@ -761,7 +802,7 @@ msgstr "%{conf_name}을(를) %{node_name}(으)로 배포 실패"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "스트림 삭제: %{stream_name}"
 
@@ -773,7 +814,7 @@ msgstr "성공적으로 삭제됨"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "배포"
 
@@ -814,8 +855,8 @@ msgstr ""
 msgid "Directives"
 msgstr "지시문들"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "비활성화"
 
@@ -868,17 +909,17 @@ msgstr "%{node_name}에서 %{conf_name} 성공적으로 활성화됨"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "비활성화됨"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "성공적으로 비활성화됨"
 
@@ -973,9 +1014,9 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "복제"
 
@@ -989,12 +1030,12 @@ msgstr "로컬로 성공적으로 복제됨"
 msgid "Edit"
 msgstr "%{n} 편집"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "%{n} 편집"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "구성 편집"
 
@@ -1016,8 +1057,8 @@ msgstr "이메일 (*)"
 msgid "Email (*)"
 msgstr "이메일 (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "활성화"
 
@@ -1095,20 +1136,20 @@ msgstr "TLS 활성화"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "활성화됨"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "성공적으로 활성화됨"
 
@@ -1132,6 +1173,10 @@ msgstr "환경"
 msgid "Error"
 msgstr "오류"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1141,11 +1186,15 @@ msgstr "오류 로그"
 msgid "Error Logs"
 msgstr "오류 로그"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "실행 가능 경로"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "만료됨"
@@ -1299,16 +1348,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "%{msg} 비활성화 실패"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "%{msg} 활성화 실패"
 
@@ -1354,6 +1403,11 @@ msgstr "인증서 정보 가져오기 실패"
 msgid "Failed to get certificate information"
 msgstr "인증서 정보 가져오기 실패"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "%{msg} 활성화 실패"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1403,8 +1457,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "저장 실패, 구성에서 구문 오류가 감지되었습니다."
 
@@ -1469,16 +1523,16 @@ msgstr "중국 사용자를 위해: https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "복제 실패"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "코드 형식"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 #, fuzzy
 msgid "Format error %{msg}"
 msgstr "형식 오류 %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 #, fuzzy
 msgid "Format successfully"
 msgstr "성공적으로 형식 지정됨"
@@ -1532,6 +1586,13 @@ msgstr ""
 msgid "Hide"
 msgstr ""
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "디렉토리"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "홈"
@@ -1599,10 +1660,12 @@ msgid "Import Certificate"
 msgstr "인증서 상태"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1678,7 +1741,7 @@ msgid "Invalid file path: {0}"
 msgstr "Invalid E-mail!"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 #, fuzzy
 msgid "Invalid filename"
 msgstr "Invalid E-mail!"
@@ -1745,7 +1808,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "키 유형"
@@ -1882,16 +1945,16 @@ msgstr ""
 "인증서를 획득하기 전에 .well-known 디렉토리에 대한역방향 프록시를 "
 "HTTPChallengePort(기본값: 9180)로 구성했는지 확인하세요."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "구성 관리"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "사이트 관리"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "스트림 관리"
@@ -1960,7 +2023,7 @@ msgstr "단일 지시문"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1971,7 +2034,7 @@ msgstr "단일 지시문"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "이름"
 
@@ -2001,7 +2064,7 @@ msgstr "설치"
 msgid "New name"
 msgstr "이름 변경"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "경로"
@@ -2058,8 +2121,8 @@ msgstr "Nginx 구성 오류름"
 msgid "Nginx configuration has been restored"
 msgstr "Nginx 구성 오류름"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 구성 오류름"
@@ -2161,8 +2224,8 @@ msgstr "Nginx 구성 오류름"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "아니요"
 
@@ -2172,15 +2235,19 @@ msgstr "아니요"
 msgid "No Action"
 msgstr "작업"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "이름 변경"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "환경"
@@ -2205,7 +2272,7 @@ msgstr "노드 시크릿"
 msgid "Nodes"
 msgstr "이름 변경"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "만료일"
 
@@ -2283,9 +2350,9 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "확인"
@@ -2335,11 +2402,11 @@ msgstr "OS:"
 msgid "Otp or recovery code empty"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "덮어쓰기"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "기존 파일 덮어쓰기"
 
@@ -2380,7 +2447,7 @@ msgstr "사용자 이름 또는 비밀번호가 올바르지 않습니다"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2455,7 +2522,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 #, fuzzy
 msgid "Please input a filename"
 msgstr "사용자 이름을 입력해주세요!"
@@ -2940,14 +3007,14 @@ msgstr "실행 중"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "저장"
 
@@ -2955,7 +3022,7 @@ msgstr "저장"
 msgid "Save Directive"
 msgstr "지시문 저장"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -3009,11 +3076,11 @@ msgstr "%{conf_name}을(를) %{node_name}(으)로 성공적으로 복제함"
 msgid "Save successfully"
 msgstr "성공적으로 저장됨"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "성공적으로 저장됨"
 
@@ -3230,9 +3297,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "상태"
 
@@ -3665,13 +3732,13 @@ msgstr "성공적으로 저장되었습니다"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "업데이트됨"
 
@@ -3749,7 +3816,7 @@ msgid "Username (*)"
 msgstr "사용자 이름 (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "유효함"
@@ -4002,9 +4069,6 @@ msgstr ""
 #~ msgid "Target"
 #~ msgstr "대상"
 
-#~ msgid "Directory"
-#~ msgstr "디렉토리"
-
 #~ msgid "File"
 #~ msgstr "파일"
 

+ 156 - 95
app/src/language/messages.pot

@@ -30,7 +30,7 @@ msgid "ACME User"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -38,8 +38,8 @@ msgstr ""
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93
-#: src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100
+#: src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr ""
@@ -50,7 +50,7 @@ msgstr ""
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr ""
 
@@ -60,8 +60,8 @@ msgid "Add a passkey"
 msgstr ""
 
 #: src/routes/modules/config.ts:20
-#: src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr ""
 
@@ -79,11 +79,11 @@ msgstr ""
 msgid "Add Site"
 msgstr ""
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr ""
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr ""
 
@@ -91,8 +91,8 @@ msgstr ""
 msgid "Additional"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr ""
 
@@ -183,8 +183,8 @@ msgstr ""
 msgid "Are you sure you want to delete this item?"
 msgstr ""
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr ""
 
@@ -266,12 +266,12 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213
+#: src/views/config/ConfigEditor.vue:232
 #: src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180
 #: src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr ""
 
@@ -315,14 +315,14 @@ msgstr ""
 msgid "Base information"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr ""
 
@@ -377,6 +377,11 @@ msgstr ""
 msgid "Cannot change initial user password in demo mode"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr ""
@@ -436,7 +441,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr ""
 
@@ -497,6 +502,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr ""
@@ -508,6 +517,22 @@ msgstr ""
 msgid "Comments"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+msgid "Compare Configurations"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 msgid "Config path is empty"
 msgstr ""
@@ -520,6 +545,10 @@ msgstr ""
 msgid "Configuration file is test successful"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+msgid "Configuration History"
+msgstr ""
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr ""
@@ -609,6 +638,10 @@ msgstr ""
 msgid "Created at"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+msgid "Created At"
+msgstr ""
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr ""
@@ -633,6 +666,10 @@ msgstr ""
 msgid "Current account is not enabled TOTP."
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+msgid "Current Content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr ""
@@ -647,8 +684,8 @@ msgid "Customize the name of local node to be displayed in the environment indic
 msgstr ""
 
 #: src/routes/modules/dashboard.ts:10
-#: src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97
+#: src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99
 #: src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr ""
@@ -669,8 +706,8 @@ msgstr ""
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr ""
 
@@ -705,7 +742,7 @@ msgstr ""
 msgid "Delete site %{name} from %{node} successfully"
 msgstr ""
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr ""
 
@@ -717,7 +754,7 @@ msgstr ""
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr ""
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr ""
 
@@ -729,7 +766,7 @@ msgstr ""
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr ""
 
@@ -771,8 +808,8 @@ msgstr ""
 msgid "Directives"
 msgstr ""
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr ""
 
@@ -819,19 +856,19 @@ msgstr ""
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79
-#: src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86
+#: src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57
 #: src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr ""
 
@@ -922,9 +959,9 @@ msgid "Due to the security policies of some browsers, you cannot use passkeys on
 msgstr ""
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr ""
 
@@ -937,13 +974,13 @@ msgstr ""
 msgid "Edit"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr ""
 
 #: src/routes/modules/config.ts:30
-#: src/views/config/ConfigEditor.vue:204
+#: src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr ""
 
@@ -964,8 +1001,8 @@ msgstr ""
 msgid "Email (*)"
 msgstr ""
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr ""
 
@@ -1034,21 +1071,21 @@ msgstr ""
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172
-#: src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180
+#: src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr ""
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr ""
 
@@ -1072,6 +1109,10 @@ msgstr ""
 msgid "Error"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 msgid "Error Log"
 msgstr ""
@@ -1081,11 +1122,15 @@ msgstr ""
 msgid "Error Logs"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr ""
@@ -1219,16 +1264,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr ""
 
@@ -1268,6 +1313,10 @@ msgstr ""
 msgid "Failed to get certificate information"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+msgid "Failed to load history records"
+msgstr ""
+
 #: src/constants/errors/backup.ts:30
 msgid "Failed to open source file: {0}"
 msgstr ""
@@ -1312,8 +1361,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr ""
 
@@ -1375,15 +1424,15 @@ msgstr ""
 msgid "Form parse failed"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr ""
 
@@ -1433,6 +1482,12 @@ msgstr ""
 msgid "Hide"
 msgstr ""
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+msgid "History"
+msgstr ""
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr ""
@@ -1491,10 +1546,12 @@ msgid "Import Certificate"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1566,7 +1623,7 @@ msgid "Invalid file path: {0}"
 msgstr ""
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr ""
 
@@ -1626,7 +1683,7 @@ msgstr ""
 msgid "Keep your recovery codes as safe as your password. We recommend saving them with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr ""
@@ -1742,19 +1799,19 @@ msgid "Make sure you have configured a reverse proxy for .well-known directory t
 msgstr ""
 
 #: src/routes/modules/config.ts:10
-#: src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139
+#: src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141
 #: src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr ""
 
 #: src/routes/modules/sites.ts:10
-#: src/views/site/site_list/SiteList.vue:95
+#: src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr ""
 
 #: src/routes/modules/streams.ts:10
-#: src/views/stream/StreamList.vue:173
+#: src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr ""
 
@@ -1818,7 +1875,7 @@ msgstr ""
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
 #: src/views/config/configColumns.tsx:7
-#: src/views/config/ConfigEditor.vue:256
+#: src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1830,7 +1887,7 @@ msgstr ""
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
 #: src/views/stream/StreamList.vue:19
-#: src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr ""
 
@@ -1858,7 +1915,7 @@ msgstr ""
 msgid "New name"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr ""
 
@@ -1912,8 +1969,8 @@ msgstr ""
 msgid "Nginx configuration has been restored"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr ""
 
@@ -2004,8 +2061,8 @@ msgstr ""
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr ""
 
@@ -2014,14 +2071,18 @@ msgstr ""
 msgid "No Action"
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 msgid "Node"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 msgid "Node Group"
 msgstr ""
 
@@ -2042,7 +2103,7 @@ msgstr ""
 msgid "Nodes"
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr ""
 
@@ -2113,9 +2174,9 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr ""
@@ -2165,11 +2226,11 @@ msgstr ""
 msgid "Otp or recovery code empty"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr ""
 
@@ -2206,7 +2267,7 @@ msgstr ""
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2273,7 +2334,7 @@ msgid "Please generate new recovery codes in the preferences immediately to prev
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr ""
 
@@ -2702,14 +2763,14 @@ msgstr ""
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr ""
 
@@ -2717,7 +2778,7 @@ msgstr ""
 msgid "Save Directive"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2764,11 +2825,11 @@ msgstr ""
 msgid "Save successfully"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr ""
 
@@ -2965,10 +3026,10 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59
-#: src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66
+#: src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr ""
 
@@ -3328,13 +3389,13 @@ msgstr ""
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
 #: src/views/config/configColumns.tsx:34
-#: src/views/config/ConfigEditor.vue:276
+#: src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65
+#: src/views/stream/StreamList.vue:66
 #: src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr ""
@@ -3410,7 +3471,7 @@ msgid "Username (*)"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr ""

+ 158 - 94
app/src/language/ru_RU/app.po

@@ -43,7 +43,7 @@ msgid "ACME User"
 msgstr "Пользователь ACME"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -51,7 +51,7 @@ msgstr "Пользователь ACME"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Действие"
@@ -62,7 +62,7 @@ msgstr "Действие"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Добавить"
 
@@ -71,8 +71,8 @@ msgstr "Добавить"
 msgid "Add a passkey"
 msgstr "Добавить ключ доступа"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "Добавить конфигурацию"
 
@@ -89,11 +89,11 @@ msgstr "Добавить Location"
 msgid "Add Site"
 msgstr "Добавить Сайт"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "Добавить поток"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "Добавлено успешно"
 
@@ -101,8 +101,8 @@ msgstr "Добавлено успешно"
 msgid "Additional"
 msgstr "Дополнительно"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Расширенный режим"
 
@@ -194,8 +194,8 @@ msgstr "Вы уверены, что хотите удалить этот эле
 msgid "Are you sure you want to delete this item?"
 msgstr "Вы уверены, что хотите удалить этот элемент?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "Вы уверены, что хотите удалить?"
 
@@ -279,10 +279,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Назад"
 
@@ -329,14 +329,14 @@ msgstr "Заблокирован до"
 msgid "Base information"
 msgstr "Основная информация"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "Основные"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Простой режим"
 
@@ -392,6 +392,11 @@ msgstr "Отмена"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Невозможно изменить пароль начального пользователя в демо-режиме"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr "Невозможно удалить начального пользователя"
@@ -452,7 +457,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Сертификат изменен"
 msgstr[1] "Сертификаты изменены"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "Путь изменён"
 
@@ -519,6 +524,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "Команда"
@@ -530,6 +539,23 @@ msgstr "Команда"
 msgid "Comments"
 msgstr "Комментарии"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Конфигурации"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -543,6 +569,11 @@ msgstr "Шаблоны конфигурации"
 msgid "Configuration file is test successful"
 msgstr "Проверка конфигурации успешна"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Конфигурации"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Название конфигурации"
@@ -635,6 +666,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Создан в"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Создан в"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "Создано успешно"
@@ -659,6 +695,11 @@ msgstr "Текущая учетная запись имеет включенну
 msgid "Current account is not enabled TOTP."
 msgstr "Для текущей учетной записи TOTP не включен."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Текущяя версия"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Текущяя версия"
@@ -675,8 +716,8 @@ msgid ""
 "indicator."
 msgstr "Настройте имя локального сервера для отображения в индикаторе среды."
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Доска"
 
@@ -696,8 +737,8 @@ msgstr "Ошибка расшифровки"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Удалить"
 
@@ -735,7 +776,7 @@ msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "Сайт %{name} успешно удалён с %{node}"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Удалить сайт: %{site_name}"
 
@@ -748,7 +789,7 @@ msgstr "Не удалось развернуть %{conf_name} на %{node_name}"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "Поток %{name} успешно удалён с %{node}"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "Удалить поток: %{stream_name}"
 
@@ -760,7 +801,7 @@ msgstr "Удалено успешно"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Развернуть"
 
@@ -801,8 +842,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Директивы"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "Отключить"
 
@@ -855,17 +896,17 @@ msgstr "Включение %{conf_name} in %{node_name} успешно"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Отключено"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Отключено успешно"
 
@@ -964,9 +1005,9 @@ msgstr ""
 "запускаются на localhost."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Дублировать"
 
@@ -980,12 +1021,12 @@ msgstr "Успешно дублировано на локальный"
 msgid "Edit"
 msgstr "Редактировать %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Редактировать %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Редактировать Конфигурацию"
 
@@ -1006,8 +1047,8 @@ msgstr "Электронная почта"
 msgid "Email (*)"
 msgstr "Email (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "Включить"
 
@@ -1081,20 +1122,20 @@ msgstr "Включить TOTP"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Включено"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Активировано успешно"
 
@@ -1117,6 +1158,10 @@ msgstr "Окружения"
 msgid "Error"
 msgstr "Ошибка"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1126,11 +1171,15 @@ msgstr "Ошибка логирования"
 msgid "Error Logs"
 msgstr "Ошибка логирования"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Исполняемый путь"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Истекший"
@@ -1282,16 +1331,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Не удалось отключить %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Не удалось включить %{msg}"
 
@@ -1337,6 +1386,11 @@ msgstr "Не удалось получить информацию о серти
 msgid "Failed to get certificate information"
 msgstr "Не удалось получить информацию о сертификате"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Не удалось включить %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1386,8 +1440,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "Не удалось сохранить, обнаружены синтаксические ошибки в конфигурации."
 
@@ -1454,15 +1508,15 @@ msgstr "Для китайских пользователей: https://mirror.ghp
 msgid "Form parse failed"
 msgstr "Дублирование не удалось"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Форматировать код"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "Ошибка формата %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "Форматирование успешно"
 
@@ -1515,6 +1569,13 @@ msgstr ""
 msgid "Hide"
 msgstr "Скрыть"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Каталог"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Главная"
@@ -1587,10 +1648,12 @@ msgid "Import Certificate"
 msgstr "Импортировать сертификат"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1664,7 +1727,7 @@ msgid "Invalid file path: {0}"
 msgstr "Неверное имя файла"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "Неверное имя файла"
 
@@ -1727,7 +1790,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "Тип ключа"
@@ -1858,16 +1921,16 @@ msgstr ""
 "Убедитесь, что вы настроили обратный прокси для каталога .well-known на "
 "HTTPChallengePort перед получением сертификата."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Конфигурации"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Сайты"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr "Управление потоками"
 
@@ -1929,7 +1992,7 @@ msgstr "Многострочная директива"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1940,7 +2003,7 @@ msgstr "Многострочная директива"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Имя"
 
@@ -1969,7 +2032,7 @@ msgstr "Установить"
 msgid "New name"
 msgstr "Новое имя"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr "Новый путь"
 
@@ -2025,8 +2088,8 @@ msgstr "Белый список директорий для логов Nginx"
 msgid "Nginx configuration has been restored"
 msgstr "Ошибка разбора конфигурации Nginx"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "Ошибка разбора конфигурации Nginx"
 
@@ -2125,8 +2188,8 @@ msgstr "Ошибка разбора конфигурации Nginx"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "Нет"
 
@@ -2136,15 +2199,19 @@ msgstr "Нет"
 msgid "No Action"
 msgstr "Действие"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Имя узла"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Окружение"
@@ -2168,7 +2235,7 @@ msgstr "Секрет узла"
 msgid "Nodes"
 msgstr "Имя узла"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "Не позднее"
 
@@ -2247,9 +2314,9 @@ msgstr "Ок"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "ОК"
@@ -2298,11 +2365,11 @@ msgstr "OS:"
 msgid "Otp or recovery code empty"
 msgstr "Код OTP или восстановления пуст"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "Перезаписать"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "Перезаписать существующий файл"
 
@@ -2343,7 +2410,7 @@ msgstr "Имя пользователя или пароль неверны"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2423,7 +2490,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "Пожалуйста, введите имя файла"
 
@@ -2890,14 +2957,14 @@ msgstr "Выполняется"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Сохранить"
 
@@ -2905,7 +2972,7 @@ msgstr "Сохранить"
 msgid "Save Directive"
 msgstr "Сохранить директиву"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2956,11 +3023,11 @@ msgstr "Поток %{name} успешно сохранён на %{node}"
 msgid "Save successfully"
 msgstr "Сохранено успешно"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Успешно сохранено"
 
@@ -3175,9 +3242,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Статус"
 
@@ -3625,13 +3692,13 @@ msgstr "Успешно обновлено"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Обновлено в"
 
@@ -3705,7 +3772,7 @@ msgid "Username (*)"
 msgstr "Имя пользователя (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "Действительный"
@@ -3968,9 +4035,6 @@ msgstr ""
 #~ msgid "Target"
 #~ msgstr "Цель"
 
-#~ msgid "Directory"
-#~ msgstr "Каталог"
-
 #~ msgid "File"
 #~ msgstr "Файл"
 

+ 158 - 94
app/src/language/tr_TR/app.po

@@ -39,7 +39,7 @@ msgid "ACME User"
 msgstr "ACME Kullanıcısı"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -47,7 +47,7 @@ msgstr "ACME Kullanıcısı"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Eylem"
@@ -58,7 +58,7 @@ msgstr "Eylem"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Ekle"
 
@@ -67,8 +67,8 @@ msgstr "Ekle"
 msgid "Add a passkey"
 msgstr "Geçiş anahtarı ekleme"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "Yapılandırma Ekle"
 
@@ -85,11 +85,11 @@ msgstr "Konum ekle"
 msgid "Add Site"
 msgstr "Site Ekle"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "Akış Ekle"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "Başarıyla eklendi"
 
@@ -97,8 +97,8 @@ msgstr "Başarıyla eklendi"
 msgid "Additional"
 msgstr "İlave bilgi"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Gelişmiş Mod"
 
@@ -194,8 +194,8 @@ msgstr "Bu öğeyi kalıcı olarak silmek istediğinizden emin misiniz?"
 msgid "Are you sure you want to delete this item?"
 msgstr "Bu öğeyi silmek istediğinizden emin misiniz?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "Silmek istediğine emin misin?"
 
@@ -280,10 +280,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Geri"
 
@@ -330,14 +330,14 @@ msgstr "Şu Zamana Kadar Yasaklı"
 msgid "Base information"
 msgstr "Temel bilgiler"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "Temel"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Temel Mod"
 
@@ -394,6 +394,11 @@ msgstr "İptal"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Demoda kök parolasını değiştirmeyi yasakla"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 #, fuzzy
 msgid "Cannot remove initial user"
@@ -457,7 +462,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Değişen Sertifika"
 msgstr[1] "Değişen Sertifikalar"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "Değişen Dosya Yolu"
 
@@ -524,6 +529,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "Komut"
@@ -535,6 +544,23 @@ msgstr "Komut"
 msgid "Comments"
 msgstr "Yorumlar"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Yapılandırmalar"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -548,6 +574,11 @@ msgstr "Yapılandırma Şablonları"
 msgid "Configuration file is test successful"
 msgstr "Yapılandırma dosyası başarıyla test edildi"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Yapılandırmalar"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Yapılandırma Adı"
@@ -641,6 +672,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Oluşturulma Tarihi"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Oluşturulma Tarihi"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "Başarıyla oluşturuldu"
@@ -665,6 +701,11 @@ msgstr "Mevcut hesap için TOTP etkinleştirildi."
 msgid "Current account is not enabled TOTP."
 msgstr "Mevcut hesap için TOTP etkin değil."
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Mevcut sürüm"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Mevcut sürüm"
@@ -681,8 +722,8 @@ msgid ""
 "indicator."
 msgstr "Ortam göstergesinde görüntülenecek yerel sunucu adını özelleştirin."
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Kontrol Paneli"
 
@@ -703,8 +744,8 @@ msgstr "Açıklama"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Sil"
 
@@ -744,7 +785,7 @@ msgstr ""
 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:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Siteyi sil: %{site_name}"
 
@@ -759,7 +800,7 @@ msgstr ""
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "Akışı sil: %{stream_name}"
 
@@ -771,7 +812,7 @@ msgstr "Başarıyla silindi"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Yayınla"
 
@@ -812,8 +853,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Yönergeler"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "Devre Dışı"
 
@@ -874,17 +915,17 @@ msgstr ""
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Devre dışı"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Başarıyla devre dışı bırakıldı"
 
@@ -983,9 +1024,9 @@ msgstr ""
 "kullanamazsınız."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Kopyala"
 
@@ -999,12 +1040,12 @@ msgstr "Başarıyla yerel kopya oluşturuldu"
 msgid "Edit"
 msgstr "Düzenle %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Düzenle %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Yapılandırmayı Düzenle"
 
@@ -1025,8 +1066,8 @@ msgstr "E-posta"
 msgid "Email (*)"
 msgstr "E-posta(*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "Etkinleştir"
 
@@ -1110,20 +1151,20 @@ msgstr "TOTP'yi Etkinleştir"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Etkin"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Başarıyla etkinleştirildi"
 
@@ -1146,6 +1187,10 @@ msgstr "Ortamlar"
 msgid "Error"
 msgstr "Hata"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1155,11 +1200,15 @@ msgstr "Hata Günlükleri"
 msgid "Error Logs"
 msgstr "Hata Günlükleri"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Yürütülebilir Dosya Yolu"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Süresi Doldu"
@@ -1311,16 +1360,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Devre dışı bırakılamadı %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Etkinleştirilemedi %{msg}"
 
@@ -1366,6 +1415,11 @@ msgstr "Sertifika bilgileri alınamadı"
 msgid "Failed to get certificate information"
 msgstr "Sertifika bilgileri alınamadı"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Etkinleştirilemedi %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1415,8 +1469,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "Kaydedilemedi, yapılandırmada sözdizimi hatası(ları) tespit edildi."
 
@@ -1483,15 +1537,15 @@ msgstr "Çinli kullanıcılar için: https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "Kopyalama başarısız oldu"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Kodu Biçimlendir"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "Biçimlendirme hatası %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "Başarıyla biçimlendirildi"
 
@@ -1544,6 +1598,13 @@ msgstr ""
 msgid "Hide"
 msgstr "Gizle"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Dizin"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Anasayfa"
@@ -1617,10 +1678,12 @@ msgid "Import Certificate"
 msgstr "Sertifika İçe Aktar"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1694,7 +1757,7 @@ msgid "Invalid file path: {0}"
 msgstr "Geçersiz dosya adı"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "Geçersiz dosya adı"
 
@@ -1759,7 +1822,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "Anahtar Türü"
@@ -1890,18 +1953,18 @@ msgstr ""
 "Sertifikayı almadan önce .well-known dizini için HTTPChallengePort'a bir "
 "ters proxy yapılandırdığınızdan emin olun."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 #, fuzzy
 msgid "Manage Configs"
 msgstr "Yapılandırmaları Yönet"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 #, fuzzy
 msgid "Manage Sites"
 msgstr "Siteleri Yönet"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "Akışları Yönet"
@@ -1976,7 +2039,7 @@ msgstr "Çok Hatlı Direktif"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1987,7 +2050,7 @@ msgstr "Çok Hatlı Direktif"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 #, fuzzy
 msgid "Name"
 msgstr "İsim"
@@ -2022,7 +2085,7 @@ msgstr "Yükle"
 msgid "New name"
 msgstr "Yeni Ad"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "Yeni Yol"
@@ -2083,8 +2146,8 @@ msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 msgid "Nginx configuration has been restored"
 msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
@@ -2190,8 +2253,8 @@ msgstr "Nginx Yapılandırma Ayrıştırma Hatası"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 #, fuzzy
 msgid "No"
 msgstr "Hayır"
@@ -2202,15 +2265,19 @@ msgstr "Hayır"
 msgid "No Action"
 msgstr "Eylem"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Yeni Ad"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Ortam"
@@ -2236,7 +2303,7 @@ msgstr "Düğüm Sırrı"
 msgid "Nodes"
 msgstr "Yeni Ad"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 #, fuzzy
 msgid "Not After"
 msgstr "Sonra değil"
@@ -2325,9 +2392,9 @@ msgstr "Tamam"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 #, fuzzy
 msgid "OK"
@@ -2385,12 +2452,12 @@ msgstr "İŞLETIM SISTEMI:"
 msgid "Otp or recovery code empty"
 msgstr "Kurtarma kodunu kullanın"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 #, fuzzy
 msgid "Overwrite"
 msgstr "Üzerine yaz"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 #, fuzzy
 msgid "Overwrite exist file"
 msgstr "Mevcut dosyanın üzerine yaz"
@@ -2440,7 +2507,7 @@ msgstr "Kullanıcı adı veya şifre yanlış"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2530,7 +2597,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 #, fuzzy
 msgid "Please input a filename"
 msgstr "Lütfen bir dosya adı girin"
@@ -3059,14 +3126,14 @@ msgstr "Çalışıyor"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 #, fuzzy
 msgid "Save"
 msgstr "Kaydet"
@@ -3076,7 +3143,7 @@ msgstr "Kaydet"
 msgid "Save Directive"
 msgstr "Direktifi Kaydet"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 #, fuzzy
@@ -3132,11 +3199,11 @@ msgstr "%{conf_name} başarıyla %{node_name} düğümüne kopyalandı"
 msgid "Save successfully"
 msgstr "Başarıyla kaydedin"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 #, fuzzy
 msgid "Saved successfully"
 msgstr "Başarıyla Kaydedildi"
@@ -3373,9 +3440,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 #, fuzzy
 msgid "Status"
 msgstr "Durum"
@@ -3872,13 +3939,13 @@ msgstr "Güncellendi"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 #, fuzzy
 msgid "Updated at"
 msgstr "Güncelleme"
@@ -3966,7 +4033,7 @@ msgid "Username (*)"
 msgstr "Kullanıcı adı (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 #, fuzzy
 msgid "Valid"
@@ -4260,9 +4327,6 @@ msgstr "Geçiş anahtarlarınız"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "Tarayamıyor musunuz? Metin anahtar bağlamasını kullanın"
 
-#~ msgid "Directory"
-#~ msgstr "Dizin"
-
 #~ msgid "File"
 #~ msgstr "Dosya"
 

+ 158 - 95
app/src/language/vi_VN/app.po

@@ -37,7 +37,7 @@ msgid "ACME User"
 msgstr "Người dùng"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -45,7 +45,7 @@ msgstr "Người dùng"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Hành động"
@@ -56,7 +56,7 @@ msgstr "Hành động"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "Thêm"
 
@@ -65,8 +65,8 @@ msgstr "Thêm"
 msgid "Add a passkey"
 msgstr ""
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 #, fuzzy
 msgid "Add Configuration"
 msgstr "Sửa cấu hình"
@@ -84,12 +84,12 @@ msgstr "Thêm Location"
 msgid "Add Site"
 msgstr "Thêm Website"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 #, fuzzy
 msgid "Add Stream"
 msgstr "Thêm Website"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 #, fuzzy
 msgid "Added successfully"
 msgstr "Cập nhật thành công"
@@ -99,8 +99,8 @@ msgstr "Cập nhật thành công"
 msgid "Additional"
 msgstr "Tùy chọn bổ sung"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "Nâng cao"
 
@@ -201,8 +201,8 @@ msgstr "Bạn chắc chắn muốn xóa nó "
 msgid "Are you sure you want to delete this item?"
 msgstr "Bạn chắc chắn muốn xóa nó "
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 #, fuzzy
 msgid "Are you sure you want to delete?"
 msgstr "Bạn chắc chắn muốn xóa nó "
@@ -291,10 +291,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "Quay lại"
 
@@ -342,15 +342,15 @@ msgstr ""
 msgid "Base information"
 msgstr "Thông tin"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 #, fuzzy
 msgid "Basic"
 msgstr "Cơ bản"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "Cơ bản"
 
@@ -409,6 +409,11 @@ msgstr "Huỷ"
 msgid "Cannot change initial user password in demo mode"
 msgstr "Cấm thay đổi mật khẩu root trong demo"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr ""
@@ -478,7 +483,7 @@ msgid_plural "Changed Certificates"
 msgstr[0] "Thay đổi chứng chỉ"
 msgstr[1] "Thay đổi chứng chỉ"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "Changed Path"
 msgstr "Thay đổi chứng chỉ"
@@ -547,6 +552,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr ""
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 #, fuzzy
 msgid "Command"
@@ -559,6 +568,23 @@ msgstr "Bình luận"
 msgid "Comments"
 msgstr "Bình luận"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "Cấu hình"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -573,6 +599,11 @@ msgstr "Mẫu Cấu hình"
 msgid "Configuration file is test successful"
 msgstr "Tệp cấu hình được kiểm tra thành công"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "Cấu hình"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "Tên cấu hình"
@@ -667,6 +698,11 @@ msgstr ""
 msgid "Created at"
 msgstr "Ngày tạo"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "Ngày tạo"
+
 #: src/views/config/components/Mkdir.vue:35
 #, fuzzy
 msgid "Created successfully"
@@ -692,6 +728,11 @@ msgstr ""
 msgid "Current account is not enabled TOTP."
 msgstr ""
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "Phiên bản hiện tại"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "Phiên bản hiện tại"
@@ -707,8 +748,8 @@ msgid ""
 "indicator."
 msgstr ""
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "Bảng điều khiển"
 
@@ -729,8 +770,8 @@ msgstr "Mô tả"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "Xoá"
 
@@ -769,7 +810,7 @@ msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
 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:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "Xoá trang web: %{site_name}"
 
@@ -783,7 +824,7 @@ msgstr "Triển khai %{conf_name} tới %{node_name} thất bại"
 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:105
+#: src/views/stream/StreamList.vue:106
 #, fuzzy
 msgid "Delete stream: %{stream_name}"
 msgstr "Xoá trang web: %{site_name}"
@@ -797,7 +838,7 @@ msgstr "Đã xoá thành công"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "Triển khai"
 
@@ -838,8 +879,8 @@ msgstr ""
 msgid "Directives"
 msgstr "Directives"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 #, fuzzy
 msgid "Disable"
 msgstr "Tắt"
@@ -893,17 +934,17 @@ msgstr "Đã bật %{conf_name} trên %{node_name}"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "Đã tắt"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "Đã tắt thành công"
 
@@ -1006,9 +1047,9 @@ msgid ""
 msgstr ""
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "Nhân bản"
 
@@ -1023,12 +1064,12 @@ msgstr "Đã sao chép thành công vào máy cục bộ"
 msgid "Edit"
 msgstr "Sửa %{n}"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "Sửa %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "Sửa cấu hình"
 
@@ -1051,8 +1092,8 @@ msgstr "Email (*)"
 msgid "Email (*)"
 msgstr "Email (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 #, fuzzy
 msgid "Enable"
 msgstr "Đã bật"
@@ -1131,20 +1172,20 @@ msgstr "Bật TLS"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "Đã bật"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "Đã bật"
 
@@ -1169,6 +1210,10 @@ msgstr "Environments"
 msgid "Error"
 msgstr "Lỗi"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1178,11 +1223,15 @@ msgstr "Log lỗi"
 msgid "Error Logs"
 msgstr "Log lỗi"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "Đường dẫn thực thi"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "Đã hết hạn"
@@ -1336,16 +1385,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "Không thể tắt %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "Không thể bật %{msg}"
 
@@ -1391,6 +1440,11 @@ msgstr "Không thể truy xuất thông tin chứng chỉ"
 msgid "Failed to get certificate information"
 msgstr "Không thể truy xuất thông tin chứng chỉ"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "Không thể bật %{msg}"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1440,8 +1494,8 @@ msgstr ""
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr ""
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "Không lưu được, đã phát hiện thấy (các) lỗi cú pháp trong cấu hình."
 
@@ -1507,16 +1561,16 @@ msgstr "Người dùng Trung Quốc: https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "Nhân bản thất bại"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "Định dạng code"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 #, fuzzy
 msgid "Format error %{msg}"
 msgstr "Lưu lỗi %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 #, fuzzy
 msgid "Format successfully"
 msgstr "Định dạng thành công"
@@ -1570,6 +1624,13 @@ msgstr ""
 msgid "Hide"
 msgstr ""
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "Thư mục"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "Trang chủ"
@@ -1636,10 +1697,12 @@ msgid "Import Certificate"
 msgstr "Chứng chỉ"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr ""
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1715,7 +1778,7 @@ msgid "Invalid file path: {0}"
 msgstr "E-mail không chính xác!"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 #, fuzzy
 msgid "Invalid filename"
 msgstr "E-mail không chính xác!"
@@ -1782,7 +1845,7 @@ msgid ""
 "with a password manager."
 msgstr ""
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 #, fuzzy
 msgid "Key Type"
@@ -1915,16 +1978,16 @@ msgstr ""
 "Đảm bảo rằng bạn đã định cấu hình proxy ngược (reverse proxy) thư mục .well-"
 "known tới HTTPChallengePort (default: 9180) trước khi ký chứng chỉ SSL."
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "Quản lý cấu hình"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "Quản lý Website"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 #, fuzzy
 msgid "Manage Streams"
 msgstr "Quản lý Website"
@@ -1992,7 +2055,7 @@ msgstr "Single Directive"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -2003,7 +2066,7 @@ msgstr "Single Directive"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "Tên"
 
@@ -2033,7 +2096,7 @@ msgstr "Cài đặt"
 msgid "New name"
 msgstr "Username"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 #, fuzzy
 msgid "New Path"
 msgstr "Đường dẫn"
@@ -2090,8 +2153,8 @@ msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 msgid "Nginx configuration has been restored"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 #, fuzzy
 msgid "Nginx Configuration Parse Error"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
@@ -2191,8 +2254,8 @@ msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "Không"
 
@@ -2202,15 +2265,19 @@ msgstr "Không"
 msgid "No Action"
 msgstr "Hành động"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "Username"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "Environment"
@@ -2235,7 +2302,7 @@ msgstr ""
 msgid "Nodes"
 msgstr "Username"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "Không phải sau khi"
 
@@ -2313,9 +2380,9 @@ msgstr ""
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr ""
@@ -2365,11 +2432,11 @@ msgstr "Hệ điều hành:"
 msgid "Otp or recovery code empty"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "Ghi đè"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "Ghi đè tập tin đã tồn tại"
 
@@ -2410,7 +2477,7 @@ msgstr "Tên người dùng hoặc mật khẩu không chính xác"
 msgid "Password length cannot exceed 20 characters"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2486,7 +2553,7 @@ msgid ""
 msgstr ""
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 #, fuzzy
 msgid "Please input a filename"
 msgstr "Vui lòng nhập username!"
@@ -2968,14 +3035,14 @@ msgstr "Running"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "Lưu"
 
@@ -2983,7 +3050,7 @@ msgstr "Lưu"
 msgid "Save Directive"
 msgstr "Lưu Directive"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -3037,11 +3104,11 @@ msgstr "Nhân bản %{conf_name} thành %{node_name} thành công"
 msgid "Save successfully"
 msgstr "Lưu thành công"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "Lưu thành công"
 
@@ -3255,9 +3322,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "Trạng thái"
 
@@ -3686,13 +3753,13 @@ msgstr "Cập nhật thành công"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "Ngày cập nhật"
 
@@ -3770,7 +3837,7 @@ msgid "Username (*)"
 msgstr "Username (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "Hợp lệ"
@@ -4027,10 +4094,6 @@ msgstr ""
 #~ msgid "Target"
 #~ msgstr "Mục tiêu"
 
-#, fuzzy
-#~ msgid "Directory"
-#~ msgstr "Thư mục"
-
 #~ msgid "File"
 #~ msgstr "Tệp tin"
 

+ 153 - 95
app/src/language/zh_CN/app.po

@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "POT-Creation-Date: \n"
-"PO-Revision-Date: 2025-04-05 20:52+0800\n"
+"PO-Revision-Date: 2025-04-06 10:43+0800\n"
 "Last-Translator: 0xJacky <me@jackyu.cn>\n"
 "Language-Team: Chinese (Simplified Han script) <https://weblate.nginxui.com/"
 "projects/nginx-ui/frontend/zh_Hans/>\n"
@@ -41,7 +41,7 @@ msgid "ACME User"
 msgstr "ACME 用户"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -49,7 +49,7 @@ msgstr "ACME 用户"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
@@ -60,7 +60,7 @@ msgstr "操作"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "添加"
 
@@ -69,8 +69,8 @@ msgstr "添加"
 msgid "Add a passkey"
 msgstr "添加 Passkey"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "添加配置"
 
@@ -87,11 +87,11 @@ msgstr "添加 Location"
 msgid "Add Site"
 msgstr "添加站点"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "添加 Stream"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "添加成功"
 
@@ -99,8 +99,8 @@ msgstr "添加成功"
 msgid "Additional"
 msgstr "额外选项"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "高级模式"
 
@@ -190,8 +190,8 @@ msgstr "您确定要永久删除此项目吗?"
 msgid "Are you sure you want to delete this item?"
 msgstr "你确定要删除这个项目吗?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "您确定要删除吗?"
 
@@ -273,10 +273,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr "自动索引站点和 Stream 的配置文件。"
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "返回"
 
@@ -320,14 +320,14 @@ msgstr "禁用至"
 msgid "Base information"
 msgstr "基本信息"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "基本"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "基本模式"
 
@@ -382,6 +382,11 @@ msgstr "取消"
 msgid "Cannot change initial user password in demo mode"
 msgstr "不可在 Demo 中修改初始用户的密码"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr "无法比较:内容缺失"
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr "不可删除初始用户"
@@ -439,7 +444,7 @@ msgid "Changed Certificate"
 msgid_plural "Changed Certificates"
 msgstr[0] "变更证书"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "变更后的路径"
 
@@ -509,6 +514,10 @@ msgstr "单击或拖动备份文件到此区域上传"
 msgid "Click to copy"
 msgstr "点击复制"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr "关闭"
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "命令"
@@ -520,6 +529,22 @@ msgstr "命令"
 msgid "Comments"
 msgstr "注释"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr "比较"
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+msgid "Compare Configurations"
+msgstr "配置比较"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr "比较选定"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr "与当前的比较"
+
 #: src/constants/errors/backup.ts:14
 msgid "Config path is empty"
 msgstr "配置路径为空"
@@ -532,6 +557,10 @@ msgstr "配置"
 msgid "Configuration file is test successful"
 msgstr "配置文件测试成功"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+msgid "Configuration History"
+msgstr "配置历史记录"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "配置名称"
@@ -623,6 +652,10 @@ msgstr ""
 msgid "Created at"
 msgstr "创建时间"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+msgid "Created At"
+msgstr "创建时间"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "创建成功"
@@ -647,6 +680,10 @@ msgstr "当前账户已启用 TOTP 验证。"
 msgid "Current account is not enabled TOTP."
 msgstr "当前用户未启用 TOTP 验证。"
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+msgid "Current Content"
+msgstr "当前内容"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "当前版本"
@@ -662,8 +699,8 @@ msgid ""
 "indicator."
 msgstr "自定义显示在环境指示器中的本地服务器名称。"
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "仪表盘"
 
@@ -683,8 +720,8 @@ msgstr "解密失败"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "删除"
 
@@ -717,7 +754,7 @@ msgstr "部署 %{name} 到 %{node} 失败"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "成功从 %{node} 中删除站点 %{name}"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "删除站点: %{site_name}"
 
@@ -729,7 +766,7 @@ msgstr "部署 %{name} 到 %{node} 失败"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "成功从 %{node} 中删除站点 %{name}"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "删除 Stream: %{stream_name}"
 
@@ -741,7 +778,7 @@ msgstr "删除成功"
 msgid "Demo"
 msgstr "Demo"
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "部署"
 
@@ -782,8 +819,8 @@ msgstr "指令 index 超出范围"
 msgid "Directives"
 msgstr "指令"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "禁用"
 
@@ -828,17 +865,17 @@ msgstr "在 %{node} 上禁用 %{name} 成功"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "禁用"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "禁用成功"
 
@@ -932,9 +969,9 @@ msgstr ""
 "使用 Passkey。"
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "复制"
 
@@ -947,12 +984,12 @@ msgstr "成功复制到本地"
 msgid "Edit"
 msgstr "编辑"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "编辑 %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "编辑配置"
 
@@ -973,8 +1010,8 @@ msgstr "邮箱"
 msgid "Email (*)"
 msgstr "邮箱 (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "启用"
 
@@ -1041,20 +1078,20 @@ msgstr "启用 TOTP"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "启用"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "启用成功"
 
@@ -1077,6 +1114,10 @@ msgstr "环境"
 msgid "Error"
 msgstr "错误"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr "差异查看器初始化出错"
+
 #: src/views/nginx_log/NginxLogList.vue:31
 msgid "Error Log"
 msgstr "错误日志"
@@ -1085,11 +1126,15 @@ msgstr "错误日志"
 msgid "Error Logs"
 msgstr "错误日志"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr "内容处理错误"
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "可执行文件路径"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "已过期"
@@ -1223,16 +1268,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr "解密 Nginx UI 目录失败:{0}"
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "禁用失败 %{msg}"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "启用失败 %{msg}"
 
@@ -1272,6 +1317,10 @@ msgstr "生成初始化向量失败:{0}"
 msgid "Failed to get certificate information"
 msgstr "获取证书信息失败"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+msgid "Failed to load history records"
+msgstr "加载历史记录失败"
+
 #: src/constants/errors/backup.ts:30
 msgid "Failed to open source file: {0}"
 msgstr "打开源文件失败:{0}"
@@ -1316,8 +1365,8 @@ msgstr "恢复 Nginx 配置失败:{0}"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "恢复 Nginx UI 文件失败:{0}"
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "保存失败,在配置中检测到语法错误。"
 
@@ -1380,15 +1429,15 @@ msgstr "中国用户:https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "表单解析失败"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "代码格式化"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "保存错误 %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "格式化成功"
 
@@ -1438,6 +1487,12 @@ msgstr "哈希验证失败:文件完整性受损"
 msgid "Hide"
 msgstr "隐藏"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+msgid "History"
+msgstr "历史"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "首页"
@@ -1505,10 +1560,12 @@ msgid "Import Certificate"
 msgstr "导入证书"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 msgid "Indexed"
 msgstr "已索引"
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr "索引中..."
 
@@ -1580,7 +1637,7 @@ msgid "Invalid file path: {0}"
 msgstr "文件路径无效:{0}"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "文件名无效"
 
@@ -1643,7 +1700,7 @@ msgid ""
 msgstr ""
 "请像保护密码一样安全地保管您的恢复代码。我们建议使用密码管理器保存它们。"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "密钥类型"
@@ -1769,16 +1826,16 @@ msgstr ""
 "在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 "
 "HTTPChallengePort。"
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "配置管理"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "网站管理"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr "管理 Stream"
 
@@ -1840,7 +1897,7 @@ msgstr "多行指令"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1851,7 +1908,7 @@ msgstr "多行指令"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "名称"
 
@@ -1879,7 +1936,7 @@ msgstr "新安装"
 msgid "New name"
 msgstr "新名称"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr "新路径"
 
@@ -1933,8 +1990,8 @@ msgstr "未设置 Nginx 配置目录"
 msgid "Nginx configuration has been restored"
 msgstr "Nginx 配置已恢复"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 配置解析错误"
 
@@ -2026,8 +2083,8 @@ msgstr "Nginx UI 配置已恢复,几秒钟后将自动重启。"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "取消"
 
@@ -2036,14 +2093,18 @@ msgstr "取消"
 msgid "No Action"
 msgstr "无操作"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr "未选择记录"
+
 #: src/views/preference/Preference.vue:168
 msgid "Node"
 msgstr "节点"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 msgid "Node Group"
 msgstr "节点组"
 
@@ -2064,7 +2125,7 @@ msgstr "节点密钥"
 msgid "Nodes"
 msgstr "节点"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "有效期"
 
@@ -2139,9 +2200,9 @@ msgstr "确定"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "确定"
@@ -2190,11 +2251,11 @@ msgstr "OS:"
 msgid "Otp or recovery code empty"
 msgstr "OTP 或恢复代码为空"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "覆盖"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "覆盖现有文件"
 
@@ -2235,7 +2296,7 @@ msgstr "用户名和密码错误"
 msgid "Password length cannot exceed 20 characters"
 msgstr "密码长度不能超过 20 个字符"
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2310,7 +2371,7 @@ msgid ""
 msgstr "请立即在偏好设置中生成新的恢复码,以防止无法访问您的账户。"
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "请输入文件名"
 
@@ -2741,14 +2802,14 @@ msgstr "运行中"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "保存"
 
@@ -2756,7 +2817,7 @@ msgstr "保存"
 msgid "Save Directive"
 msgstr "保存指令"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2801,11 +2862,11 @@ msgstr "成功将站点 %{name} 保存到 %{node} 中"
 msgid "Save successfully"
 msgstr "保存成功"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "保存成功"
 
@@ -3010,9 +3071,9 @@ msgid "Start Restore"
 msgstr "开始还原"
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "状态"
 
@@ -3424,13 +3485,13 @@ msgstr "更新成功"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "修改时间"
 
@@ -3503,7 +3564,7 @@ msgid "Username (*)"
 msgstr "用户名 (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "有效的"
@@ -3780,9 +3841,6 @@ msgstr "你的 Passkeys"
 #~ msgid "Can't scan? Use text key binding"
 #~ msgstr "无法扫描?使用文本密钥绑定"
 
-#~ msgid "Directory"
-#~ msgstr "目录"
-
 #~ msgid "File"
 #~ msgstr "文件"
 

+ 158 - 94
app/src/language/zh_TW/app.po

@@ -46,7 +46,7 @@ msgid "ACME User"
 msgstr "ACME 用戶"
 
 #: src/views/certificate/ACMEUser.vue:95
-#: src/views/certificate/CertificateList/certColumns.tsx:97
+#: src/views/certificate/CertificateList/certColumns.tsx:94
 #: src/views/certificate/DNSCredential.vue:33
 #: src/views/config/configColumns.tsx:42
 #: src/views/environments/group/columns.ts:43
@@ -54,7 +54,7 @@ msgstr "ACME 用戶"
 #: src/views/nginx_log/NginxLogList.vue:53
 #: src/views/notification/notificationColumns.tsx:66
 #: src/views/preference/AuthSettings.vue:30
-#: src/views/site/site_list/columns.tsx:93 src/views/stream/StreamList.vue:72
+#: src/views/site/site_list/columns.tsx:100 src/views/stream/StreamList.vue:73
 #: src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
@@ -65,7 +65,7 @@ msgstr "操作"
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:163
 #: src/views/site/ngx_conf/NgxUpstream.vue:154
-#: src/views/stream/StreamList.vue:175
+#: src/views/stream/StreamList.vue:176
 msgid "Add"
 msgstr "新增"
 
@@ -74,8 +74,8 @@ msgstr "新增"
 msgid "Add a passkey"
 msgstr "新增通行密鑰"
 
-#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:144
-#: src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:20 src/views/config/ConfigEditor.vue:146
+#: src/views/config/ConfigEditor.vue:210
 msgid "Add Configuration"
 msgstr "添加配置"
 
@@ -92,11 +92,11 @@ msgstr "新增 Location"
 msgid "Add Site"
 msgstr "新增網站"
 
-#: src/views/stream/StreamList.vue:241
+#: src/views/stream/StreamList.vue:242
 msgid "Add Stream"
 msgstr "新增 Stream"
 
-#: src/views/stream/StreamList.vue:156
+#: src/views/stream/StreamList.vue:157
 msgid "Added successfully"
 msgstr "添加成功"
 
@@ -104,8 +104,8 @@ msgstr "添加成功"
 msgid "Additional"
 msgstr "其他設定"
 
-#: src/views/site/site_edit/SiteEdit.vue:206
-#: src/views/stream/StreamEdit.vue:192
+#: src/views/site/site_edit/SiteEdit.vue:225
+#: src/views/stream/StreamEdit.vue:211
 msgid "Advance Mode"
 msgstr "進階模式"
 
@@ -196,8 +196,8 @@ msgstr "您確定要永久刪除此項目嗎?"
 msgid "Are you sure you want to delete this item?"
 msgstr "您確定要刪除此項目嗎?"
 
-#: src/views/site/site_list/SiteList.vue:143
-#: src/views/stream/StreamList.vue:225
+#: src/views/site/site_list/SiteList.vue:200
+#: src/views/stream/StreamList.vue:226
 msgid "Are you sure you want to delete?"
 msgstr "您確定要刪除嗎?"
 
@@ -281,10 +281,10 @@ msgid "Automatically indexed from site and stream configurations."
 msgstr ""
 
 #: src/views/certificate/CertificateEditor.vue:255
-#: src/views/config/ConfigEditor.vue:213 src/views/config/ConfigList.vue:106
+#: src/views/config/ConfigEditor.vue:232 src/views/config/ConfigList.vue:106
 #: src/views/config/ConfigList.vue:180 src/views/nginx_log/NginxLog.vue:173
-#: src/views/site/site_edit/SiteEdit.vue:265
-#: src/views/stream/StreamEdit.vue:248
+#: src/views/site/site_edit/SiteEdit.vue:285
+#: src/views/stream/StreamEdit.vue:268
 msgid "Back"
 msgstr "返回"
 
@@ -331,14 +331,14 @@ msgstr "禁止至"
 msgid "Base information"
 msgstr "基本資訊"
 
-#: src/views/config/ConfigEditor.vue:241
+#: src/views/config/ConfigEditor.vue:260
 #: src/views/site/site_edit/RightSettings.vue:79
 #: src/views/stream/components/RightSettings.vue:79
 msgid "Basic"
 msgstr "基本"
 
-#: src/views/site/site_edit/SiteEdit.vue:209
-#: src/views/stream/StreamEdit.vue:195
+#: src/views/site/site_edit/SiteEdit.vue:228
+#: src/views/stream/StreamEdit.vue:214
 msgid "Basic Mode"
 msgstr "基本模式"
 
@@ -393,6 +393,11 @@ msgstr "取消"
 msgid "Cannot change initial user password in demo mode"
 msgstr "無法在示範模式下更改初始使用者密碼"
 
+#: src/components/ConfigHistory/DiffViewer.vue:49
+#: src/components/ConfigHistory/DiffViewer.vue:66
+msgid "Cannot compare: Missing content"
+msgstr ""
+
 #: src/constants/errors/user.ts:10
 msgid "Cannot remove initial user"
 msgstr "無法移除初始使用者"
@@ -450,7 +455,7 @@ msgid "Changed Certificate"
 msgid_plural "Changed Certificates"
 msgstr[0] "變更後憑證"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "Changed Path"
 msgstr "變更後路徑"
 
@@ -520,6 +525,10 @@ msgstr ""
 msgid "Click to copy"
 msgstr "點擊複製"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:156
+msgid "Close"
+msgstr ""
+
 #: src/views/preference/LogrotateSettings.vue:22
 msgid "Command"
 msgstr "命令"
@@ -531,6 +540,23 @@ msgstr "命令"
 msgid "Comments"
 msgstr "備註"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:114
+msgid "Compare"
+msgstr ""
+
+#: src/components/ConfigHistory/DiffViewer.vue:349
+#, fuzzy
+msgid "Compare Configurations"
+msgstr "設定"
+
+#: src/components/ConfigHistory/ConfigHistory.vue:117
+msgid "Compare Selected"
+msgstr ""
+
+#: src/components/ConfigHistory/ConfigHistory.vue:116
+msgid "Compare with Current"
+msgstr ""
+
 #: src/constants/errors/backup.ts:14
 #, fuzzy
 msgid "Config path is empty"
@@ -544,6 +570,11 @@ msgstr "設定模板"
 msgid "Configuration file is test successful"
 msgstr "設定檔案測試成功"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:125
+#, fuzzy
+msgid "Configuration History"
+msgstr "設定"
+
 #: src/views/site/site_add/SiteAdd.vue:101
 msgid "Configuration Name"
 msgstr "設定名稱"
@@ -636,6 +667,11 @@ msgstr ""
 msgid "Created at"
 msgstr "建立時間"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:42
+#, fuzzy
+msgid "Created At"
+msgstr "建立時間"
+
 #: src/views/config/components/Mkdir.vue:35
 msgid "Created successfully"
 msgstr "創建成功"
@@ -660,6 +696,11 @@ msgstr "當前帳戶已啟用 TOTP。"
 msgid "Current account is not enabled TOTP."
 msgstr "當前帳戶未啟用 TOTP。"
 
+#: src/components/ConfigHistory/DiffViewer.vue:54
+#, fuzzy
+msgid "Current Content"
+msgstr "目前版本"
+
 #: src/views/system/Upgrade.vue:165
 msgid "Current Version"
 msgstr "目前版本"
@@ -675,8 +716,8 @@ msgid ""
 "indicator."
 msgstr "自訂顯示在環境指示器中的本地節點名稱。"
 
-#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:134
-#: src/views/config/ConfigEditor.vue:97 src/views/config/ConfigList.vue:64
+#: src/routes/modules/dashboard.ts:10 src/views/config/ConfigEditor.vue:136
+#: src/views/config/ConfigEditor.vue:99 src/views/config/ConfigList.vue:64
 msgid "Dashboard"
 msgstr "儀表板"
 
@@ -696,8 +737,8 @@ msgstr "解密失敗"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:519
 #: src/views/site/ngx_conf/NgxServer.vue:110
 #: src/views/site/ngx_conf/NgxUpstream.vue:128
-#: src/views/site/site_list/SiteList.vue:152
-#: src/views/stream/StreamList.vue:234
+#: src/views/site/site_list/SiteList.vue:209
+#: src/views/stream/StreamList.vue:235
 msgid "Delete"
 msgstr "刪除"
 
@@ -730,7 +771,7 @@ msgstr "從 %{node} 刪除網站 %{name} 失敗"
 msgid "Delete site %{name} from %{node} successfully"
 msgstr "成功從 %{node} 移除站點 %{name}"
 
-#: src/views/site/site_list/SiteList.vue:68
+#: src/views/site/site_list/SiteList.vue:115
 msgid "Delete site: %{site_name}"
 msgstr "刪除網站:%{site_name}"
 
@@ -742,7 +783,7 @@ msgstr "部署 %{conf_name} 至 %{node} 失敗"
 msgid "Delete stream %{name} from %{node} successfully"
 msgstr "成功從 %{node} 移除站點 %{name}"
 
-#: src/views/stream/StreamList.vue:105
+#: src/views/stream/StreamList.vue:106
 msgid "Delete stream: %{stream_name}"
 msgstr "刪除 Stream:%{stream_name}"
 
@@ -754,7 +795,7 @@ msgstr "刪除成功"
 msgid "Demo"
 msgstr ""
 
-#: src/views/config/ConfigEditor.vue:285
+#: src/views/config/ConfigEditor.vue:304
 msgid "Deploy"
 msgstr "部署"
 
@@ -795,8 +836,8 @@ msgstr "指令索引超出範圍"
 msgid "Directives"
 msgstr "指令"
 
-#: src/views/site/site_list/SiteList.vue:123
-#: src/views/stream/StreamList.vue:205
+#: src/views/site/site_list/SiteList.vue:180
+#: src/views/stream/StreamList.vue:206
 msgid "Disable"
 msgstr "停用"
 
@@ -845,17 +886,17 @@ msgstr "成功禁用 %{node} 中的站点 %{site}"
 #: src/views/preference/HTTPSettings.vue:24
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
-#: src/views/site/site_edit/SiteEdit.vue:191
-#: src/views/site/site_list/columns.tsx:70
-#: src/views/site/site_list/columns.tsx:79 src/views/stream/StreamEdit.vue:178
-#: src/views/stream/StreamList.vue:56 src/views/user/userColumns.tsx:41
+#: src/views/site/site_edit/SiteEdit.vue:199
+#: src/views/site/site_list/columns.tsx:77
+#: src/views/site/site_list/columns.tsx:86 src/views/stream/StreamEdit.vue:186
+#: src/views/stream/StreamList.vue:57 src/views/user/userColumns.tsx:41
 msgid "Disabled"
 msgstr "停用"
 
 #: src/views/site/site_edit/RightSettings.vue:42
-#: src/views/site/site_list/SiteList.vue:57
+#: src/views/site/site_list/SiteList.vue:104
 #: src/views/stream/components/RightSettings.vue:42
-#: src/views/stream/StreamList.vue:94
+#: src/views/stream/StreamList.vue:95
 msgid "Disabled successfully"
 msgstr "成功停用"
 
@@ -949,9 +990,9 @@ msgstr ""
 "通行密鑰。"
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
-#: src/views/site/site_list/SiteList.vue:138
+#: src/views/site/site_list/SiteList.vue:195
 #: src/views/stream/components/StreamDuplicate.vue:64
-#: src/views/stream/StreamList.vue:220
+#: src/views/stream/StreamList.vue:221
 msgid "Duplicate"
 msgstr "複製"
 
@@ -964,12 +1005,12 @@ msgstr "成功複製至本機"
 msgid "Edit"
 msgstr "編輯"
 
-#: src/views/site/site_edit/SiteEdit.vue:180
-#: src/views/stream/StreamEdit.vue:167
+#: src/views/site/site_edit/SiteEdit.vue:188
+#: src/views/stream/StreamEdit.vue:175
 msgid "Edit %{n}"
 msgstr "編輯 %{n}"
 
-#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:204
+#: src/routes/modules/config.ts:30 src/views/config/ConfigEditor.vue:210
 msgid "Edit Configuration"
 msgstr "編輯設定"
 
@@ -990,8 +1031,8 @@ msgstr "電子郵件"
 msgid "Email (*)"
 msgstr "電子郵件 (*)"
 
-#: src/views/site/site_list/SiteList.vue:131
-#: src/views/stream/StreamList.vue:213
+#: src/views/site/site_list/SiteList.vue:188
+#: src/views/stream/StreamList.vue:214
 msgid "Enable"
 msgstr "啟用"
 
@@ -1065,20 +1106,20 @@ msgstr "啟用 TOTP"
 #: src/views/preference/NodeSettings.vue:25
 #: src/views/preference/NodeSettings.vue:30
 #: src/views/site/site_edit/RightSettings.vue:82
-#: src/views/site/site_edit/SiteEdit.vue:185
-#: src/views/site/site_list/columns.tsx:66
-#: src/views/site/site_list/columns.tsx:78
+#: src/views/site/site_edit/SiteEdit.vue:193
+#: src/views/site/site_list/columns.tsx:73
+#: src/views/site/site_list/columns.tsx:85
 #: src/views/stream/components/RightSettings.vue:81
-#: src/views/stream/StreamEdit.vue:172 src/views/stream/StreamList.vue:52
+#: src/views/stream/StreamEdit.vue:180 src/views/stream/StreamList.vue:53
 #: src/views/user/userColumns.tsx:38
 msgid "Enabled"
 msgstr "已啟用"
 
 #: src/views/site/site_add/SiteAdd.vue:40
 #: src/views/site/site_edit/RightSettings.vue:33
-#: src/views/site/site_list/SiteList.vue:47
+#: src/views/site/site_list/SiteList.vue:94
 #: src/views/stream/components/RightSettings.vue:33
-#: src/views/stream/StreamList.vue:84
+#: src/views/stream/StreamList.vue:85
 msgid "Enabled successfully"
 msgstr "成功啟用"
 
@@ -1101,6 +1142,10 @@ msgstr "環境"
 msgid "Error"
 msgstr "錯誤"
 
+#: src/components/ConfigHistory/DiffViewer.vue:127
+msgid "Error initializing diff viewer"
+msgstr ""
+
 #: src/views/nginx_log/NginxLogList.vue:31
 #, fuzzy
 msgid "Error Log"
@@ -1110,11 +1155,15 @@ msgstr "錯誤日誌"
 msgid "Error Logs"
 msgstr "錯誤日誌"
 
+#: src/components/ConfigHistory/DiffViewer.vue:79
+msgid "Error processing content"
+msgstr ""
+
 #: src/views/system/Upgrade.vue:177
 msgid "Executable Path"
 msgstr "可執行檔路徑"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:85
+#: src/views/certificate/CertificateList/certColumns.tsx:82
 #: src/views/site/cert/CertInfo.vue:31
 msgid "Expired"
 msgstr "已過期"
@@ -1266,16 +1315,16 @@ msgid "Failed to decrypt Nginx UI directory: {0}"
 msgstr ""
 
 #: src/views/site/site_edit/RightSettings.vue:45
-#: src/views/site/site_list/SiteList.vue:61
+#: src/views/site/site_list/SiteList.vue:108
 #: src/views/stream/components/RightSettings.vue:45
-#: src/views/stream/StreamList.vue:98
+#: src/views/stream/StreamList.vue:99
 msgid "Failed to disable %{msg}"
 msgstr "停用 %{msg} 失敗"
 
 #: src/views/site/site_edit/RightSettings.vue:36
-#: src/views/site/site_list/SiteList.vue:51
+#: src/views/site/site_list/SiteList.vue:98
 #: src/views/stream/components/RightSettings.vue:36
-#: src/views/stream/StreamList.vue:88
+#: src/views/stream/StreamList.vue:89
 msgid "Failed to enable %{msg}"
 msgstr "啟用 %{msg} 失敗"
 
@@ -1321,6 +1370,11 @@ msgstr "取得憑證資訊失敗"
 msgid "Failed to get certificate information"
 msgstr "取得憑證資訊失敗"
 
+#: src/components/ConfigHistory/ConfigHistory.vue:65
+#, fuzzy
+msgid "Failed to load history records"
+msgstr "創建備份失敗"
+
 #: src/constants/errors/backup.ts:30
 #, fuzzy
 msgid "Failed to open source file: {0}"
@@ -1374,8 +1428,8 @@ msgstr "解析 nginx.conf 失敗"
 msgid "Failed to restore Nginx UI files: {0}"
 msgstr "解析 nginx.conf 失敗"
 
-#: src/views/site/site_edit/SiteEdit.vue:135
-#: src/views/stream/StreamEdit.vue:122
+#: src/views/site/site_edit/SiteEdit.vue:139
+#: src/views/stream/StreamEdit.vue:126
 msgid "Failed to save, syntax error(s) was detected in the configuration."
 msgstr "儲存失敗,在設定中檢測到語法錯誤。"
 
@@ -1440,15 +1494,15 @@ msgstr "中國使用者:https://mirror.ghproxy.com/"
 msgid "Form parse failed"
 msgstr "複製失敗"
 
-#: src/views/config/ConfigEditor.vue:216
+#: src/views/config/ConfigEditor.vue:235
 msgid "Format Code"
 msgstr "格式化程式碼"
 
-#: src/views/config/ConfigEditor.vue:183
+#: src/views/config/ConfigEditor.vue:185
 msgid "Format error %{msg}"
 msgstr "格式錯誤 %{msg}"
 
-#: src/views/config/ConfigEditor.vue:181
+#: src/views/config/ConfigEditor.vue:183
 msgid "Format successfully"
 msgstr "成功格式化"
 
@@ -1498,6 +1552,13 @@ msgstr ""
 msgid "Hide"
 msgstr "隱藏"
 
+#: src/views/config/ConfigEditor.vue:220
+#: src/views/site/site_edit/SiteEdit.vue:212
+#: src/views/stream/StreamEdit.vue:199
+#, fuzzy
+msgid "History"
+msgstr "目錄"
+
 #: src/routes/index.ts:47
 msgid "Home"
 msgstr "首頁"
@@ -1566,11 +1627,13 @@ msgid "Import Certificate"
 msgstr "導入憑證"
 
 #: src/views/nginx_log/NginxLogList.vue:137
+#: src/views/site/site_list/SiteList.vue:149
 #, fuzzy
 msgid "Indexed"
 msgstr "網站首頁 (index)"
 
 #: src/views/nginx_log/NginxLogList.vue:134
+#: src/views/site/site_list/SiteList.vue:146
 msgid "Indexing..."
 msgstr ""
 
@@ -1646,7 +1709,7 @@ msgid "Invalid file path: {0}"
 msgstr "無效的請求格式"
 
 #: src/views/config/components/Rename.vue:64
-#: src/views/config/ConfigEditor.vue:250
+#: src/views/config/ConfigEditor.vue:269
 msgid "Invalid filename"
 msgstr "無效的檔案名"
 
@@ -1710,7 +1773,7 @@ msgid ""
 msgstr ""
 "請將您的復原代碼與密碼同樣妥善保管。我們建議使用密碼管理工具來儲存它們。"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:62
+#: src/views/certificate/CertificateList/certColumns.tsx:59
 #: src/views/site/cert/components/AutoCertStepOne.vue:77
 msgid "Key Type"
 msgstr "密鑰類型"
@@ -1836,16 +1899,16 @@ msgid ""
 msgstr ""
 "在取得憑證前,請確保您已將 .well-known 目錄反向代理到 HTTPChallengePort。"
 
-#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:102
-#: src/views/config/ConfigEditor.vue:139 src/views/config/ConfigList.vue:69
+#: src/routes/modules/config.ts:10 src/views/config/ConfigEditor.vue:104
+#: src/views/config/ConfigEditor.vue:141 src/views/config/ConfigList.vue:69
 msgid "Manage Configs"
 msgstr "管理設定"
 
-#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:95
+#: src/routes/modules/sites.ts:10 src/views/site/site_list/SiteList.vue:142
 msgid "Manage Sites"
 msgstr "管理網站"
 
-#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:173
+#: src/routes/modules/streams.ts:10 src/views/stream/StreamList.vue:174
 msgid "Manage Streams"
 msgstr "管理 Stream"
 
@@ -1907,7 +1970,7 @@ msgstr "多行指令"
 #: src/views/certificate/CertificateList/certColumns.tsx:10
 #: src/views/certificate/DNSCredential.vue:11
 #: src/views/config/components/Mkdir.vue:64
-#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:256
+#: src/views/config/configColumns.tsx:7 src/views/config/ConfigEditor.vue:275
 #: src/views/environments/group/columns.ts:8
 #: src/views/environments/list/envColumns.tsx:9
 #: src/views/nginx_log/NginxLogList.vue:37
@@ -1918,7 +1981,7 @@ msgstr "多行指令"
 #: src/views/site/site_list/SiteDuplicate.vue:79
 #: src/views/stream/components/RightSettings.vue:87
 #: src/views/stream/components/StreamDuplicate.vue:71
-#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:246
+#: src/views/stream/StreamList.vue:19 src/views/stream/StreamList.vue:247
 msgid "Name"
 msgstr "名稱"
 
@@ -1947,7 +2010,7 @@ msgstr "安裝"
 msgid "New name"
 msgstr "新名稱"
 
-#: src/views/config/ConfigEditor.vue:269
+#: src/views/config/ConfigEditor.vue:288
 msgid "New Path"
 msgstr "新路徑"
 
@@ -2003,8 +2066,8 @@ msgstr "Nginx 日誌目錄白名單"
 msgid "Nginx configuration has been restored"
 msgstr "Nginx 設定解析錯誤"
 
-#: src/views/site/site_edit/SiteEdit.vue:224
-#: src/views/stream/StreamEdit.vue:210
+#: src/views/site/site_edit/SiteEdit.vue:244
+#: src/views/stream/StreamEdit.vue:230
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 設定解析錯誤"
 
@@ -2101,8 +2164,8 @@ msgstr "Nginx 設定解析錯誤"
 #: src/views/preference/CertSettings.vue:73
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:97
 #: src/views/site/ngx_conf/LocationEditor.vue:88
-#: src/views/site/site_list/SiteList.vue:141
-#: src/views/stream/StreamList.vue:223
+#: src/views/site/site_list/SiteList.vue:198
+#: src/views/stream/StreamList.vue:224
 msgid "No"
 msgstr "取消"
 
@@ -2112,15 +2175,19 @@ msgstr "取消"
 msgid "No Action"
 msgstr "操作"
 
+#: src/components/ConfigHistory/DiffViewer.vue:36
+msgid "No records selected"
+msgstr ""
+
 #: src/views/preference/Preference.vue:168
 #, fuzzy
 msgid "Node"
 msgstr "節點名稱"
 
 #: src/views/site/site_edit/RightSettings.vue:91
-#: src/views/site/site_list/columns.tsx:42
+#: src/views/site/site_list/columns.tsx:49
 #: src/views/stream/components/RightSettings.vue:90
-#: src/views/stream/StreamList.vue:28
+#: src/views/stream/StreamList.vue:29
 #, fuzzy
 msgid "Node Group"
 msgstr "環境"
@@ -2144,7 +2211,7 @@ msgstr "節點密鑰"
 msgid "Nodes"
 msgstr "節點名稱"
 
-#: src/views/certificate/CertificateList/certColumns.tsx:91
+#: src/views/certificate/CertificateList/certColumns.tsx:88
 msgid "Not After"
 msgstr "不晚於"
 
@@ -2219,9 +2286,9 @@ msgstr "確定"
 #: src/views/site/ngx_conf/NgxServer.vue:79
 #: src/views/site/ngx_conf/NgxUpstream.vue:33
 #: src/views/site/site_edit/RightSettings.vue:54
-#: src/views/site/site_list/SiteList.vue:142
+#: src/views/site/site_list/SiteList.vue:199
 #: src/views/stream/components/RightSettings.vue:54
-#: src/views/stream/StreamList.vue:224
+#: src/views/stream/StreamList.vue:225
 #: src/views/system/Backup/BackupCreator.vue:149
 msgid "OK"
 msgstr "確定"
@@ -2270,11 +2337,11 @@ msgstr "作業系統:"
 msgid "Otp or recovery code empty"
 msgstr "OTP 或復原代碼為空"
 
-#: src/views/config/ConfigEditor.vue:294
+#: src/views/config/ConfigEditor.vue:313
 msgid "Overwrite"
 msgstr "覆蓋"
 
-#: src/views/config/ConfigEditor.vue:298
+#: src/views/config/ConfigEditor.vue:317
 msgid "Overwrite exist file"
 msgstr "覆蓋現有檔案"
 
@@ -2316,7 +2383,7 @@ msgstr "密碼錯誤"
 msgid "Password length cannot exceed 20 characters"
 msgstr "密碼長度不能超過 20 個字元"
 
-#: src/views/config/ConfigEditor.vue:263
+#: src/views/config/ConfigEditor.vue:282
 #: src/views/nginx_log/NginxLogList.vue:45
 #: src/views/site/ngx_conf/LocationEditor.vue:109
 #: src/views/site/ngx_conf/LocationEditor.vue:137
@@ -2392,7 +2459,7 @@ msgid ""
 msgstr "請立即在偏好設定中產生新的恢復碼,以免無法訪問您的賬戶。"
 
 #: src/views/config/components/Rename.vue:63
-#: src/views/config/ConfigEditor.vue:249
+#: src/views/config/ConfigEditor.vue:268
 msgid "Please input a filename"
 msgstr "請輸入檔案名稱"
 
@@ -2848,14 +2915,14 @@ msgstr "執行中"
 #: src/components/StdDesign/StdDetail/StdDetail.vue:93
 #: src/views/certificate/CertificateEditor.vue:262
 #: src/views/config/components/ConfigName.vue:56
-#: src/views/config/ConfigEditor.vue:222
+#: src/views/config/ConfigEditor.vue:241
 #: src/views/preference/components/Passkey.vue:130
 #: src/views/preference/Preference.vue:221
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:127
 #: src/views/site/site_edit/components/ConfigName.vue:52
-#: src/views/site/site_edit/SiteEdit.vue:272
+#: src/views/site/site_edit/SiteEdit.vue:292
 #: src/views/stream/components/ConfigName.vue:52
-#: src/views/stream/StreamEdit.vue:255
+#: src/views/stream/StreamEdit.vue:275
 msgid "Save"
 msgstr "儲存"
 
@@ -2863,7 +2930,7 @@ msgstr "儲存"
 msgid "Save Directive"
 msgstr "儲存指令"
 
-#: src/views/config/ConfigEditor.vue:171
+#: src/views/config/ConfigEditor.vue:173
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:41
 #: src/views/site/site_add/SiteAdd.vue:46
 msgid "Save error %{msg}"
@@ -2914,11 +2981,11 @@ msgstr "成功將站點 %{site} 儲存至 %{node}"
 msgid "Save successfully"
 msgstr "儲存成功"
 
-#: src/views/config/ConfigEditor.vue:167
+#: src/views/config/ConfigEditor.vue:169
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:39
 #: src/views/site/site_add/SiteAdd.vue:37
-#: src/views/site/site_edit/SiteEdit.vue:153
-#: src/views/stream/StreamEdit.vue:141
+#: src/views/site/site_edit/SiteEdit.vue:157
+#: src/views/stream/StreamEdit.vue:145
 msgid "Saved successfully"
 msgstr "儲存成功"
 
@@ -3130,9 +3197,9 @@ msgid "Start Restore"
 msgstr ""
 
 #: src/views/certificate/ACMEUser.vue:65
-#: src/views/certificate/CertificateList/certColumns.tsx:68
+#: src/views/certificate/CertificateList/certColumns.tsx:65
 #: src/views/environments/list/envColumns.tsx:44
-#: src/views/site/site_list/columns.tsx:59 src/views/stream/StreamList.vue:45
+#: src/views/site/site_list/columns.tsx:66 src/views/stream/StreamList.vue:46
 msgid "Status"
 msgstr "狀態"
 
@@ -3554,13 +3621,13 @@ msgstr "更新成功"
 
 #: src/views/certificate/ACMEUser.vue:88
 #: src/views/certificate/DNSCredential.vue:27
-#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:276
+#: src/views/config/configColumns.tsx:34 src/views/config/ConfigEditor.vue:295
 #: src/views/environments/group/columns.ts:37
 #: src/views/environments/list/envColumns.tsx:90
 #: src/views/site/site_edit/RightSettings.vue:100
-#: src/views/site/site_list/columns.tsx:86
+#: src/views/site/site_list/columns.tsx:93
 #: src/views/stream/components/RightSettings.vue:99
-#: src/views/stream/StreamList.vue:65 src/views/user/userColumns.tsx:54
+#: src/views/stream/StreamList.vue:66 src/views/user/userColumns.tsx:54
 msgid "Updated at"
 msgstr "更新時間"
 
@@ -3633,7 +3700,7 @@ msgid "Username (*)"
 msgstr "使用者名稱 (*)"
 
 #: src/views/certificate/ACMEUser.vue:124
-#: src/views/certificate/CertificateList/certColumns.tsx:81
+#: src/views/certificate/CertificateList/certColumns.tsx:78
 #: src/views/site/cert/CertInfo.vue:24
 msgid "Valid"
 msgstr "有效"
@@ -3899,9 +3966,6 @@ msgstr "您的通行密鑰"
 #~ "The recovery code is only displayed once, please save it in a safe place."
 #~ msgstr "恢復碼僅顯示一次,請將其保存在安全的地方。"
 
-#~ msgid "Directory"
-#~ msgstr "目錄"
-
 #~ msgid "File"
 #~ msgstr "檔案"