1717 <el-card shadow =" never" class =" history-setting" >
1818 <el-collapse v-model =" activeCollapse" :accordion =" true" class =" !border-0" >
1919 <el-collapse-item :title =" $t('file.historySettingTitle')" name =" history" class =" !border-0" >
20- <el-form label-position =" top" class =" flex items-end gap-6" >
21- <el-form-item :label =" $t('file.historyEnable')" >
20+ <el-form
21+ ref =" historySettingFormRef"
22+ :model =" historySetting"
23+ :rules =" historySettingRules"
24+ label-position =" top"
25+ class =" flex items-end gap-6"
26+ >
27+ <el-form-item :label =" $t('file.historyEnable')" prop =" enable" >
2228 <el-switch
2329 v-model =" historySetting.enable"
2430 active-value =" Enable"
2531 inactive-value =" Disable"
2632 />
2733 </el-form-item >
28- <el-form-item :label =" $t('file.historyMaxPerPath')" >
34+ <el-form-item :label =" $t('file.historyMaxPerPath')" prop = " maxPerPath " >
2935 <el-input-number
3036 v-model =" historySetting.maxPerPath"
3137 :min =" 1"
3238 :max =" 1000"
3339 class =" !w-52"
3440 />
3541 </el-form-item >
36- <el-form-item :label =" $t('file.historyDiskQuota')" >
42+ <el-form-item :label =" $t('file.historyDiskQuota')" prop = " diskQuotaMB " >
3743 <el-input-number
3844 v-model =" historySetting.diskQuotaMB"
3945 :min =" 1"
212218</template >
213219
214220<script setup lang="ts">
215- import { computed , nextTick , onBeforeUnmount , onMounted , onUnmounted , ref } from ' vue' ;
221+ import { computed , nextTick , onBeforeUnmount , onMounted , onUnmounted , reactive , ref } from ' vue' ;
216222import { dateFormatSimpleWithSecond } from ' @/utils/date' ;
217223import { computeSize } from ' @/utils/size' ;
218224import { MsgError , MsgSuccess } from ' @/utils/message' ;
@@ -221,7 +227,7 @@ import { getAgentFileHistoryInfo, updateAgentFileHistoryInfo } from '@/api/modul
221227import { File } from ' @/api/interface/file' ;
222228import { Setting } from ' @/api/interface/setting' ;
223229import { loadMonacoLanguageSupport , setupMonacoEnvironment } from ' @/utils/monaco' ;
224- import { ElMessageBox } from ' element-plus' ;
230+ import { ElMessageBox , type FormInstance , type FormRules } from ' element-plus' ;
225231import { Languages } from ' @/global/mimetype' ;
226232import i18n from ' @/lang' ;
227233
@@ -241,6 +247,7 @@ const historyLoading = ref(false);
241247const deleteLoading = ref (false );
242248const settingSaving = ref (false );
243249const restoreLoading = ref (false );
250+ const historySettingFormRef = ref <FormInstance >();
244251const scope = ref <' current' | ' all' >(' current' );
245252const operationFilter = ref (' ' );
246253const activeCollapse = ref ([]);
@@ -256,6 +263,51 @@ const historySetting = ref<Setting.FileHistoryInfo>({
256263 maxPerPath: 20 ,
257264 diskQuotaMB: 1024 ,
258265});
266+ const historySettingRules = reactive <FormRules <Setting .FileHistoryInfo >>({
267+ enable: [
268+ {
269+ required: true ,
270+ message: i18n .global .t (' commons.rule.requiredInput' ),
271+ trigger: ' change' ,
272+ },
273+ ],
274+ maxPerPath: [
275+ {
276+ required: true ,
277+ message: i18n .global .t (' commons.rule.requiredInput' ),
278+ trigger: ' change' ,
279+ },
280+ {
281+ validator : (_ , value , callback ) => {
282+ const parsedValue = Number (value );
283+ if (! Number .isInteger (parsedValue ) || parsedValue <= 0 ) {
284+ callback (new Error (i18n .global .t (' commons.rule.integer' )));
285+ return ;
286+ }
287+ callback ();
288+ },
289+ trigger: ' change' ,
290+ },
291+ ],
292+ diskQuotaMB: [
293+ {
294+ required: true ,
295+ message: i18n .global .t (' commons.rule.requiredInput' ),
296+ trigger: ' change' ,
297+ },
298+ {
299+ validator : (_ , value , callback ) => {
300+ const parsedValue = Number (value );
301+ if (! Number .isInteger (parsedValue ) || parsedValue <= 0 ) {
302+ callback (new Error (i18n .global .t (' commons.rule.integer' )));
303+ return ;
304+ }
305+ callback ();
306+ },
307+ trigger: ' change' ,
308+ },
309+ ],
310+ });
259311const historyItems = ref <File .FileHistoryInfo []>([]);
260312const selected = ref <File .FileHistoryInfo []>([]);
261313const selectedHistory = ref <File .FileHistoryInfo | null >(null );
@@ -267,6 +319,7 @@ const windowWidth = ref(window.innerWidth);
267319const operationMap = {
268320 ' ' : i18n .global .t (' app.all' ),
269321 save: i18n .global .t (' commons.button.save' ),
322+ restore: i18n .global .t (' commons.button.recover' ),
270323 move: i18n .global .t (' file.move' ),
271324 rename: i18n .global .t (' file.rename' ),
272325} as const ;
@@ -279,7 +332,7 @@ const operationOptions = Object.entries(operationMap).map(([value, label]) => ({
279332const getOperationLabel = (operation : string ) => {
280333 return operationMap [operation as keyof typeof operationMap ] || operation ;
281334};
282- const isVersionRecord = (operation : string ) => operation === ' save' ;
335+ const isVersionRecord = (operation : string ) => operation === ' save' || operation === ' restore ' ;
283336const canRestoreSelected = computed (() => isVersionRecord (selectedHistory .value ?.operation || ' ' ));
284337const isRestoringCurrentFile = computed (() => selectedHistory .value ?.path === currentFile .value .path );
285338const getCurrentTargetPath = (row : File .FileHistoryInfo ) => row .currentPath || row .path ;
@@ -412,10 +465,23 @@ const loadHistorySetting = async () => {
412465 historySetting .value = res .data ;
413466};
414467
468+ const normalizeHistorySettingNumber = (value : number , defaultValue : number ) => {
469+ const parsedValue = Number (value );
470+ return parsedValue > 0 ? parsedValue : defaultValue ;
471+ };
472+
415473const saveHistorySetting = async () => {
416474 settingSaving .value = true ;
417475 try {
418- await updateAgentFileHistoryInfo (historySetting .value );
476+ const valid = await historySettingFormRef .value ?.validate ().catch (() => false );
477+ if (! valid ) {
478+ return ;
479+ }
480+ await updateAgentFileHistoryInfo ({
481+ ... historySetting .value ,
482+ maxPerPath: normalizeHistorySettingNumber (historySetting .value .maxPerPath , 20 ),
483+ diskQuotaMB: normalizeHistorySettingNumber (historySetting .value .diskQuotaMB , 1024 ),
484+ });
419485 MsgSuccess (i18n .global .t (' commons.msg.updateSuccess' ));
420486 } catch (error ) {
421487 MsgError (String (error ));
0 commit comments