seeder-st2110-components 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +1 -1
- package/dist/index.esm.js +741 -74
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +740 -72
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/styles/index.less +10 -0
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo, useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
2
|
-
import { Tooltip, App, Modal, Form, Input, Alert, message, Dropdown, Spin, Divider, Typography, InputNumber, ConfigProvider, Badge, Switch,
|
|
2
|
+
import { Tooltip, App, Modal, Form, Input, Alert, message, Dropdown, Spin, Select, Divider, Typography, InputNumber, ConfigProvider, Badge, Switch, List, Empty, Button, Space, Flex, Checkbox, Row, Col } from 'antd';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useWebSocket, useInterval } from 'ahooks';
|
|
5
5
|
import { LoadingOutlined, ExclamationCircleFilled, PlusOutlined } from '@ant-design/icons';
|
|
@@ -790,6 +790,601 @@ const useSystemOperations = function () {
|
|
|
790
790
|
};
|
|
791
791
|
var useSystemOperations$1 = useSystemOperations;
|
|
792
792
|
|
|
793
|
+
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
|
794
|
+
|
|
795
|
+
var isDateObject = (value) => value instanceof Date;
|
|
796
|
+
|
|
797
|
+
var isNullOrUndefined = (value) => value == null;
|
|
798
|
+
|
|
799
|
+
const isObjectType = (value) => typeof value === 'object';
|
|
800
|
+
var isObject = (value) => !isNullOrUndefined(value) &&
|
|
801
|
+
!Array.isArray(value) &&
|
|
802
|
+
isObjectType(value) &&
|
|
803
|
+
!isDateObject(value);
|
|
804
|
+
|
|
805
|
+
var getEventValue = (event) => isObject(event) && event.target
|
|
806
|
+
? isCheckBoxInput(event.target)
|
|
807
|
+
? event.target.checked
|
|
808
|
+
: event.target.value
|
|
809
|
+
: event;
|
|
810
|
+
|
|
811
|
+
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
|
812
|
+
|
|
813
|
+
var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name));
|
|
814
|
+
|
|
815
|
+
var isPlainObject = (tempObject) => {
|
|
816
|
+
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
817
|
+
return (isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf'));
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
var isWeb = typeof window !== 'undefined' &&
|
|
821
|
+
typeof window.HTMLElement !== 'undefined' &&
|
|
822
|
+
typeof document !== 'undefined';
|
|
823
|
+
|
|
824
|
+
function cloneObject(data) {
|
|
825
|
+
let copy;
|
|
826
|
+
const isArray = Array.isArray(data);
|
|
827
|
+
const isFileListInstance = typeof FileList !== 'undefined' ? data instanceof FileList : false;
|
|
828
|
+
if (data instanceof Date) {
|
|
829
|
+
copy = new Date(data);
|
|
830
|
+
}
|
|
831
|
+
else if (!(isWeb && (data instanceof Blob || isFileListInstance)) &&
|
|
832
|
+
(isArray || isObject(data))) {
|
|
833
|
+
copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
|
|
834
|
+
if (!isArray && !isPlainObject(data)) {
|
|
835
|
+
copy = data;
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
for (const key in data) {
|
|
839
|
+
if (data.hasOwnProperty(key)) {
|
|
840
|
+
copy[key] = cloneObject(data[key]);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
return data;
|
|
847
|
+
}
|
|
848
|
+
return copy;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
var isKey = (value) => /^\w*$/.test(value);
|
|
852
|
+
|
|
853
|
+
var isUndefined = (val) => val === undefined;
|
|
854
|
+
|
|
855
|
+
var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : [];
|
|
856
|
+
|
|
857
|
+
var stringToPath = (input) => compact(input.replace(/["|']|\]/g, '').split(/\.|\[/));
|
|
858
|
+
|
|
859
|
+
var get = (object, path, defaultValue) => {
|
|
860
|
+
if (!path || !isObject(object)) {
|
|
861
|
+
return defaultValue;
|
|
862
|
+
}
|
|
863
|
+
const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], object);
|
|
864
|
+
return isUndefined(result) || result === object
|
|
865
|
+
? isUndefined(object[path])
|
|
866
|
+
? defaultValue
|
|
867
|
+
: object[path]
|
|
868
|
+
: result;
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
var isBoolean = (value) => typeof value === 'boolean';
|
|
872
|
+
|
|
873
|
+
var set = (object, path, value) => {
|
|
874
|
+
let index = -1;
|
|
875
|
+
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
876
|
+
const length = tempPath.length;
|
|
877
|
+
const lastIndex = length - 1;
|
|
878
|
+
while (++index < length) {
|
|
879
|
+
const key = tempPath[index];
|
|
880
|
+
let newValue = value;
|
|
881
|
+
if (index !== lastIndex) {
|
|
882
|
+
const objValue = object[key];
|
|
883
|
+
newValue =
|
|
884
|
+
isObject(objValue) || Array.isArray(objValue)
|
|
885
|
+
? objValue
|
|
886
|
+
: !isNaN(+tempPath[index + 1])
|
|
887
|
+
? []
|
|
888
|
+
: {};
|
|
889
|
+
}
|
|
890
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
object[key] = newValue;
|
|
894
|
+
object = object[key];
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
const EVENTS = {
|
|
899
|
+
BLUR: 'blur',
|
|
900
|
+
FOCUS_OUT: 'focusout',
|
|
901
|
+
CHANGE: 'change',
|
|
902
|
+
};
|
|
903
|
+
const VALIDATION_MODE = {
|
|
904
|
+
onBlur: 'onBlur',
|
|
905
|
+
onChange: 'onChange',
|
|
906
|
+
onSubmit: 'onSubmit',
|
|
907
|
+
onTouched: 'onTouched',
|
|
908
|
+
all: 'all',
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
const HookFormContext = React.createContext(null);
|
|
912
|
+
HookFormContext.displayName = 'HookFormContext';
|
|
913
|
+
/**
|
|
914
|
+
* This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
|
|
915
|
+
*
|
|
916
|
+
* @remarks
|
|
917
|
+
* [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
|
|
918
|
+
*
|
|
919
|
+
* @returns return all useForm methods
|
|
920
|
+
*
|
|
921
|
+
* @example
|
|
922
|
+
* ```tsx
|
|
923
|
+
* function App() {
|
|
924
|
+
* const methods = useForm();
|
|
925
|
+
* const onSubmit = data => console.log(data);
|
|
926
|
+
*
|
|
927
|
+
* return (
|
|
928
|
+
* <FormProvider {...methods} >
|
|
929
|
+
* <form onSubmit={methods.handleSubmit(onSubmit)}>
|
|
930
|
+
* <NestedInput />
|
|
931
|
+
* <input type="submit" />
|
|
932
|
+
* </form>
|
|
933
|
+
* </FormProvider>
|
|
934
|
+
* );
|
|
935
|
+
* }
|
|
936
|
+
*
|
|
937
|
+
* function NestedInput() {
|
|
938
|
+
* const { register } = useFormContext(); // retrieve all hook methods
|
|
939
|
+
* return <input {...register("test")} />;
|
|
940
|
+
* }
|
|
941
|
+
* ```
|
|
942
|
+
*/
|
|
943
|
+
const useFormContext = () => React.useContext(HookFormContext);
|
|
944
|
+
|
|
945
|
+
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
946
|
+
const result = {
|
|
947
|
+
defaultValues: control._defaultValues,
|
|
948
|
+
};
|
|
949
|
+
for (const key in formState) {
|
|
950
|
+
Object.defineProperty(result, key, {
|
|
951
|
+
get: () => {
|
|
952
|
+
const _key = key;
|
|
953
|
+
if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
|
|
954
|
+
control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
|
|
955
|
+
}
|
|
956
|
+
localProxyFormState && (localProxyFormState[_key] = true);
|
|
957
|
+
return formState[_key];
|
|
958
|
+
},
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
return result;
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
|
968
|
+
*
|
|
969
|
+
* @remarks
|
|
970
|
+
* [API](https://react-hook-form.com/docs/useformstate) • [Demo](https://codesandbox.io/s/useformstate-75xly)
|
|
971
|
+
*
|
|
972
|
+
* @param props - include options on specify fields to subscribe. {@link UseFormStateReturn}
|
|
973
|
+
*
|
|
974
|
+
* @example
|
|
975
|
+
* ```tsx
|
|
976
|
+
* function App() {
|
|
977
|
+
* const { register, handleSubmit, control } = useForm({
|
|
978
|
+
* defaultValues: {
|
|
979
|
+
* firstName: "firstName"
|
|
980
|
+
* }});
|
|
981
|
+
* const { dirtyFields } = useFormState({
|
|
982
|
+
* control
|
|
983
|
+
* });
|
|
984
|
+
* const onSubmit = (data) => console.log(data);
|
|
985
|
+
*
|
|
986
|
+
* return (
|
|
987
|
+
* <form onSubmit={handleSubmit(onSubmit)}>
|
|
988
|
+
* <input {...register("firstName")} placeholder="First Name" />
|
|
989
|
+
* {dirtyFields.firstName && <p>Field is dirty.</p>}
|
|
990
|
+
* <input type="submit" />
|
|
991
|
+
* </form>
|
|
992
|
+
* );
|
|
993
|
+
* }
|
|
994
|
+
* ```
|
|
995
|
+
*/
|
|
996
|
+
function useFormState(props) {
|
|
997
|
+
const methods = useFormContext();
|
|
998
|
+
const { control = methods.control, disabled, name, exact } = props || {};
|
|
999
|
+
const [formState, updateFormState] = React.useState(control._formState);
|
|
1000
|
+
const _localProxyFormState = React.useRef({
|
|
1001
|
+
isDirty: false,
|
|
1002
|
+
isLoading: false,
|
|
1003
|
+
dirtyFields: false,
|
|
1004
|
+
touchedFields: false,
|
|
1005
|
+
validatingFields: false,
|
|
1006
|
+
isValidating: false,
|
|
1007
|
+
isValid: false,
|
|
1008
|
+
errors: false,
|
|
1009
|
+
});
|
|
1010
|
+
useIsomorphicLayoutEffect(() => control._subscribe({
|
|
1011
|
+
name,
|
|
1012
|
+
formState: _localProxyFormState.current,
|
|
1013
|
+
exact,
|
|
1014
|
+
callback: (formState) => {
|
|
1015
|
+
!disabled &&
|
|
1016
|
+
updateFormState({
|
|
1017
|
+
...control._formState,
|
|
1018
|
+
...formState,
|
|
1019
|
+
});
|
|
1020
|
+
},
|
|
1021
|
+
}), [name, disabled, exact]);
|
|
1022
|
+
React.useEffect(() => {
|
|
1023
|
+
_localProxyFormState.current.isValid && control._setValid(true);
|
|
1024
|
+
}, [control]);
|
|
1025
|
+
return React.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
var isString = (value) => typeof value === 'string';
|
|
1029
|
+
|
|
1030
|
+
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
1031
|
+
if (isString(names)) {
|
|
1032
|
+
isGlobal && _names.watch.add(names);
|
|
1033
|
+
return get(formValues, names, defaultValue);
|
|
1034
|
+
}
|
|
1035
|
+
if (Array.isArray(names)) {
|
|
1036
|
+
return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName),
|
|
1037
|
+
get(formValues, fieldName)));
|
|
1038
|
+
}
|
|
1039
|
+
isGlobal && (_names.watchAll = true);
|
|
1040
|
+
return formValues;
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
1044
|
+
|
|
1045
|
+
function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
|
1046
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
1047
|
+
return object1 === object2;
|
|
1048
|
+
}
|
|
1049
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
|
1050
|
+
return object1.getTime() === object2.getTime();
|
|
1051
|
+
}
|
|
1052
|
+
const keys1 = Object.keys(object1);
|
|
1053
|
+
const keys2 = Object.keys(object2);
|
|
1054
|
+
if (keys1.length !== keys2.length) {
|
|
1055
|
+
return false;
|
|
1056
|
+
}
|
|
1057
|
+
if (_internal_visited.has(object1) || _internal_visited.has(object2)) {
|
|
1058
|
+
return true;
|
|
1059
|
+
}
|
|
1060
|
+
_internal_visited.add(object1);
|
|
1061
|
+
_internal_visited.add(object2);
|
|
1062
|
+
for (const key of keys1) {
|
|
1063
|
+
const val1 = object1[key];
|
|
1064
|
+
if (!keys2.includes(key)) {
|
|
1065
|
+
return false;
|
|
1066
|
+
}
|
|
1067
|
+
if (key !== 'ref') {
|
|
1068
|
+
const val2 = object2[key];
|
|
1069
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
1070
|
+
(isObject(val1) && isObject(val2)) ||
|
|
1071
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
|
1072
|
+
? !deepEqual(val1, val2, _internal_visited)
|
|
1073
|
+
: val1 !== val2) {
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
return true;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Custom hook to subscribe to field change and isolate re-rendering at the component level.
|
|
1083
|
+
*
|
|
1084
|
+
* @remarks
|
|
1085
|
+
*
|
|
1086
|
+
* [API](https://react-hook-form.com/docs/usewatch) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-usewatch-h9i5e)
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* ```tsx
|
|
1090
|
+
* const { control } = useForm();
|
|
1091
|
+
* const values = useWatch({
|
|
1092
|
+
* name: "fieldName"
|
|
1093
|
+
* control,
|
|
1094
|
+
* })
|
|
1095
|
+
* ```
|
|
1096
|
+
*/
|
|
1097
|
+
function useWatch(props) {
|
|
1098
|
+
const methods = useFormContext();
|
|
1099
|
+
const { control = methods.control, name, defaultValue, disabled, exact, compute, } = props || {};
|
|
1100
|
+
const _defaultValue = React.useRef(defaultValue);
|
|
1101
|
+
const _compute = React.useRef(compute);
|
|
1102
|
+
const _computeFormValues = React.useRef(undefined);
|
|
1103
|
+
_compute.current = compute;
|
|
1104
|
+
const defaultValueMemo = React.useMemo(() => control._getWatch(name, _defaultValue.current), [control, name]);
|
|
1105
|
+
const [value, updateValue] = React.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
|
1106
|
+
useIsomorphicLayoutEffect(() => control._subscribe({
|
|
1107
|
+
name,
|
|
1108
|
+
formState: {
|
|
1109
|
+
values: true,
|
|
1110
|
+
},
|
|
1111
|
+
exact,
|
|
1112
|
+
callback: (formState) => {
|
|
1113
|
+
if (!disabled) {
|
|
1114
|
+
const formValues = generateWatchOutput(name, control._names, formState.values || control._formValues, false, _defaultValue.current);
|
|
1115
|
+
if (_compute.current) {
|
|
1116
|
+
const computedFormValues = _compute.current(formValues);
|
|
1117
|
+
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
|
1118
|
+
updateValue(computedFormValues);
|
|
1119
|
+
_computeFormValues.current = computedFormValues;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
updateValue(formValues);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
}), [control, disabled, name, exact]);
|
|
1128
|
+
React.useEffect(() => control._removeUnmounted());
|
|
1129
|
+
return value;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* Custom hook to work with controlled component, this function provide you with both form and field level state. Re-render is isolated at the hook level.
|
|
1134
|
+
*
|
|
1135
|
+
* @remarks
|
|
1136
|
+
* [API](https://react-hook-form.com/docs/usecontroller) • [Demo](https://codesandbox.io/s/usecontroller-0o8px)
|
|
1137
|
+
*
|
|
1138
|
+
* @param props - the path name to the form field value, and validation rules.
|
|
1139
|
+
*
|
|
1140
|
+
* @returns field properties, field and form state. {@link UseControllerReturn}
|
|
1141
|
+
*
|
|
1142
|
+
* @example
|
|
1143
|
+
* ```tsx
|
|
1144
|
+
* function Input(props) {
|
|
1145
|
+
* const { field, fieldState, formState } = useController(props);
|
|
1146
|
+
* return (
|
|
1147
|
+
* <div>
|
|
1148
|
+
* <input {...field} placeholder={props.name} />
|
|
1149
|
+
* <p>{fieldState.isTouched && "Touched"}</p>
|
|
1150
|
+
* <p>{formState.isSubmitted ? "submitted" : ""}</p>
|
|
1151
|
+
* </div>
|
|
1152
|
+
* );
|
|
1153
|
+
* }
|
|
1154
|
+
* ```
|
|
1155
|
+
*/
|
|
1156
|
+
function useController(props) {
|
|
1157
|
+
const methods = useFormContext();
|
|
1158
|
+
const { name, disabled, control = methods.control, shouldUnregister, defaultValue, } = props;
|
|
1159
|
+
const isArrayField = isNameInFieldArray(control._names.array, name);
|
|
1160
|
+
const defaultValueMemo = React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
|
1161
|
+
const value = useWatch({
|
|
1162
|
+
control,
|
|
1163
|
+
name,
|
|
1164
|
+
defaultValue: defaultValueMemo,
|
|
1165
|
+
exact: true,
|
|
1166
|
+
});
|
|
1167
|
+
const formState = useFormState({
|
|
1168
|
+
control,
|
|
1169
|
+
name,
|
|
1170
|
+
exact: true,
|
|
1171
|
+
});
|
|
1172
|
+
const _props = React.useRef(props);
|
|
1173
|
+
const _registerProps = React.useRef(control.register(name, {
|
|
1174
|
+
...props.rules,
|
|
1175
|
+
value,
|
|
1176
|
+
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
|
1177
|
+
}));
|
|
1178
|
+
_props.current = props;
|
|
1179
|
+
const fieldState = React.useMemo(() => Object.defineProperties({}, {
|
|
1180
|
+
invalid: {
|
|
1181
|
+
enumerable: true,
|
|
1182
|
+
get: () => !!get(formState.errors, name),
|
|
1183
|
+
},
|
|
1184
|
+
isDirty: {
|
|
1185
|
+
enumerable: true,
|
|
1186
|
+
get: () => !!get(formState.dirtyFields, name),
|
|
1187
|
+
},
|
|
1188
|
+
isTouched: {
|
|
1189
|
+
enumerable: true,
|
|
1190
|
+
get: () => !!get(formState.touchedFields, name),
|
|
1191
|
+
},
|
|
1192
|
+
isValidating: {
|
|
1193
|
+
enumerable: true,
|
|
1194
|
+
get: () => !!get(formState.validatingFields, name),
|
|
1195
|
+
},
|
|
1196
|
+
error: {
|
|
1197
|
+
enumerable: true,
|
|
1198
|
+
get: () => get(formState.errors, name),
|
|
1199
|
+
},
|
|
1200
|
+
}), [formState, name]);
|
|
1201
|
+
const onChange = React.useCallback((event) => _registerProps.current.onChange({
|
|
1202
|
+
target: {
|
|
1203
|
+
value: getEventValue(event),
|
|
1204
|
+
name: name,
|
|
1205
|
+
},
|
|
1206
|
+
type: EVENTS.CHANGE,
|
|
1207
|
+
}), [name]);
|
|
1208
|
+
const onBlur = React.useCallback(() => _registerProps.current.onBlur({
|
|
1209
|
+
target: {
|
|
1210
|
+
value: get(control._formValues, name),
|
|
1211
|
+
name: name,
|
|
1212
|
+
},
|
|
1213
|
+
type: EVENTS.BLUR,
|
|
1214
|
+
}), [name, control._formValues]);
|
|
1215
|
+
const ref = React.useCallback((elm) => {
|
|
1216
|
+
const field = get(control._fields, name);
|
|
1217
|
+
if (field && elm) {
|
|
1218
|
+
field._f.ref = {
|
|
1219
|
+
focus: () => elm.focus && elm.focus(),
|
|
1220
|
+
select: () => elm.select && elm.select(),
|
|
1221
|
+
setCustomValidity: (message) => elm.setCustomValidity(message),
|
|
1222
|
+
reportValidity: () => elm.reportValidity(),
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
}, [control._fields, name]);
|
|
1226
|
+
const field = React.useMemo(() => ({
|
|
1227
|
+
name,
|
|
1228
|
+
value,
|
|
1229
|
+
...(isBoolean(disabled) || formState.disabled
|
|
1230
|
+
? { disabled: formState.disabled || disabled }
|
|
1231
|
+
: {}),
|
|
1232
|
+
onChange,
|
|
1233
|
+
onBlur,
|
|
1234
|
+
ref,
|
|
1235
|
+
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
|
1236
|
+
React.useEffect(() => {
|
|
1237
|
+
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
|
1238
|
+
control.register(name, {
|
|
1239
|
+
..._props.current.rules,
|
|
1240
|
+
...(isBoolean(_props.current.disabled)
|
|
1241
|
+
? { disabled: _props.current.disabled }
|
|
1242
|
+
: {}),
|
|
1243
|
+
});
|
|
1244
|
+
const updateMounted = (name, value) => {
|
|
1245
|
+
const field = get(control._fields, name);
|
|
1246
|
+
if (field && field._f) {
|
|
1247
|
+
field._f.mount = value;
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1250
|
+
updateMounted(name, true);
|
|
1251
|
+
if (_shouldUnregisterField) {
|
|
1252
|
+
const value = cloneObject(get(control._options.defaultValues, name));
|
|
1253
|
+
set(control._defaultValues, name, value);
|
|
1254
|
+
if (isUndefined(get(control._formValues, name))) {
|
|
1255
|
+
set(control._formValues, name, value);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
!isArrayField && control.register(name);
|
|
1259
|
+
return () => {
|
|
1260
|
+
(isArrayField
|
|
1261
|
+
? _shouldUnregisterField && !control._state.action
|
|
1262
|
+
: _shouldUnregisterField)
|
|
1263
|
+
? control.unregister(name)
|
|
1264
|
+
: updateMounted(name, false);
|
|
1265
|
+
};
|
|
1266
|
+
}, [name, control, isArrayField, shouldUnregister]);
|
|
1267
|
+
React.useEffect(() => {
|
|
1268
|
+
control._setDisabledField({
|
|
1269
|
+
disabled,
|
|
1270
|
+
name,
|
|
1271
|
+
});
|
|
1272
|
+
}, [disabled, name, control]);
|
|
1273
|
+
return React.useMemo(() => ({
|
|
1274
|
+
field,
|
|
1275
|
+
formState,
|
|
1276
|
+
fieldState,
|
|
1277
|
+
}), [field, formState, fieldState]);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Component based on `useController` hook to work with controlled component.
|
|
1282
|
+
*
|
|
1283
|
+
* @remarks
|
|
1284
|
+
* [API](https://react-hook-form.com/docs/usecontroller/controller) • [Demo](https://codesandbox.io/s/react-hook-form-v6-controller-ts-jwyzw) • [Video](https://www.youtube.com/watch?v=N2UNk_UCVyA)
|
|
1285
|
+
*
|
|
1286
|
+
* @param props - the path name to the form field value, and validation rules.
|
|
1287
|
+
*
|
|
1288
|
+
* @returns provide field handler functions, field and form state.
|
|
1289
|
+
*
|
|
1290
|
+
* @example
|
|
1291
|
+
* ```tsx
|
|
1292
|
+
* function App() {
|
|
1293
|
+
* const { control } = useForm<FormValues>({
|
|
1294
|
+
* defaultValues: {
|
|
1295
|
+
* test: ""
|
|
1296
|
+
* }
|
|
1297
|
+
* });
|
|
1298
|
+
*
|
|
1299
|
+
* return (
|
|
1300
|
+
* <form>
|
|
1301
|
+
* <Controller
|
|
1302
|
+
* control={control}
|
|
1303
|
+
* name="test"
|
|
1304
|
+
* render={({ field: { onChange, onBlur, value, ref }, formState, fieldState }) => (
|
|
1305
|
+
* <>
|
|
1306
|
+
* <input
|
|
1307
|
+
* onChange={onChange} // send value to hook form
|
|
1308
|
+
* onBlur={onBlur} // notify when input is touched
|
|
1309
|
+
* value={value} // return updated value
|
|
1310
|
+
* ref={ref} // set ref for focus management
|
|
1311
|
+
* />
|
|
1312
|
+
* <p>{formState.isSubmitted ? "submitted" : ""}</p>
|
|
1313
|
+
* <p>{fieldState.isTouched ? "touched" : ""}</p>
|
|
1314
|
+
* </>
|
|
1315
|
+
* )}
|
|
1316
|
+
* />
|
|
1317
|
+
* </form>
|
|
1318
|
+
* );
|
|
1319
|
+
* }
|
|
1320
|
+
* ```
|
|
1321
|
+
*/
|
|
1322
|
+
const Controller = (props) => props.render(useController(props));
|
|
1323
|
+
|
|
1324
|
+
// 获取 LSM 中的IP映射列表
|
|
1325
|
+
async function get_lsm_data() {
|
|
1326
|
+
return request('/api/get_lsm_data', {
|
|
1327
|
+
method: 'GET'
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
const useLSMLabel = function () {
|
|
1332
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1333
|
+
const [lsmList, setLsmList] = useState([]);
|
|
1334
|
+
const {
|
|
1335
|
+
name,
|
|
1336
|
+
label = "Label",
|
|
1337
|
+
control,
|
|
1338
|
+
onLsmSelect,
|
|
1339
|
+
fetchLsmData = get_lsm_data,
|
|
1340
|
+
formItemProps = {},
|
|
1341
|
+
selectProps = {},
|
|
1342
|
+
fieldNames = {
|
|
1343
|
+
label: 'label',
|
|
1344
|
+
value: 'label'
|
|
1345
|
+
}
|
|
1346
|
+
} = props;
|
|
1347
|
+
useEffect(() => {
|
|
1348
|
+
const loadLsmData = async () => {
|
|
1349
|
+
try {
|
|
1350
|
+
const res = await fetchLsmData();
|
|
1351
|
+
if (res !== null && res !== void 0 && res.length) {
|
|
1352
|
+
setLsmList(res);
|
|
1353
|
+
}
|
|
1354
|
+
} catch (error) {
|
|
1355
|
+
console.error('Failed to fetch LSM data:', error);
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
loadLsmData();
|
|
1359
|
+
}, [fetchLsmData]);
|
|
1360
|
+
const renderLSMField = () => /*#__PURE__*/jsx(Controller, {
|
|
1361
|
+
name: name,
|
|
1362
|
+
control: control,
|
|
1363
|
+
render: _ref => {
|
|
1364
|
+
let {
|
|
1365
|
+
field
|
|
1366
|
+
} = _ref;
|
|
1367
|
+
return /*#__PURE__*/jsx(Form.Item, _objectSpread2(_objectSpread2({
|
|
1368
|
+
label: label
|
|
1369
|
+
}, formItemProps), {}, {
|
|
1370
|
+
children: /*#__PURE__*/jsx(Select, _objectSpread2(_objectSpread2(_objectSpread2({}, field), selectProps), {}, {
|
|
1371
|
+
options: lsmList,
|
|
1372
|
+
fieldNames: fieldNames,
|
|
1373
|
+
allowClear: true,
|
|
1374
|
+
showSearch: true,
|
|
1375
|
+
optionFilterProp: "label",
|
|
1376
|
+
onChange: (value, option) => {
|
|
1377
|
+
field.onChange(value);
|
|
1378
|
+
onLsmSelect === null || onLsmSelect === void 0 || onLsmSelect(value === undefined ? undefined : option);
|
|
1379
|
+
},
|
|
1380
|
+
placeholder: selectProps.placeholder || 'Please select label'
|
|
1381
|
+
}))
|
|
1382
|
+
}));
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
return renderLSMField;
|
|
1386
|
+
};
|
|
1387
|
+
|
|
793
1388
|
const NetworkFieldGroup = _ref => {
|
|
794
1389
|
var _fieldConfig$netmask$, _fieldConfig$netmask;
|
|
795
1390
|
let {
|
|
@@ -1041,8 +1636,6 @@ const NetworkSettingsModal = _ref2 => {
|
|
|
1041
1636
|
setSubmitLoading(true);
|
|
1042
1637
|
try {
|
|
1043
1638
|
const values = await form.validateFields();
|
|
1044
|
-
// console.log("Direct form values:", values);
|
|
1045
|
-
|
|
1046
1639
|
const updatePromises = [];
|
|
1047
1640
|
|
|
1048
1641
|
// 更新LAN配置
|
|
@@ -1086,16 +1679,13 @@ const NetworkSettingsModal = _ref2 => {
|
|
|
1086
1679
|
const allSucceeded = results.every(result => result.status === 'fulfilled');
|
|
1087
1680
|
if (allSucceeded) {
|
|
1088
1681
|
handleSuccess();
|
|
1089
|
-
} else {
|
|
1090
|
-
message.error('Some configurations failed to update');
|
|
1091
1682
|
}
|
|
1092
1683
|
} catch (error) {
|
|
1093
1684
|
console.error('Failed to update configurations: ', error);
|
|
1094
|
-
message.error('Failed to update configurations');
|
|
1095
1685
|
} finally {
|
|
1096
1686
|
setSubmitLoading(false);
|
|
1097
1687
|
}
|
|
1098
|
-
}, [form, sections, lanConfigs, st2110Interfaces, updateLanConfig, updateSysConfig, handleSuccess
|
|
1688
|
+
}, [form, sections, lanConfigs, st2110Interfaces, updateLanConfig, updateSysConfig, handleSuccess]);
|
|
1099
1689
|
|
|
1100
1690
|
// 合并默认模态框属性和传入的属性
|
|
1101
1691
|
const mergedModalProps = _objectSpread2({
|
|
@@ -1407,7 +1997,7 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
1407
1997
|
showDescription = false,
|
|
1408
1998
|
texts = {
|
|
1409
1999
|
newButton: "New Preset",
|
|
1410
|
-
removeButton: "
|
|
2000
|
+
removeButton: "Delete"
|
|
1411
2001
|
}
|
|
1412
2002
|
} = _ref;
|
|
1413
2003
|
// 动态计算列布局
|
|
@@ -1418,7 +2008,7 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
1418
2008
|
className: "list-container",
|
|
1419
2009
|
children: /*#__PURE__*/jsx(List, {
|
|
1420
2010
|
header: /*#__PURE__*/jsxs("div", {
|
|
1421
|
-
className: "grid ".concat(gridColumns, " w-full list-header"),
|
|
2011
|
+
className: "grid ".concat(gridColumns, " gap-2 w-full list-header"),
|
|
1422
2012
|
children: [/*#__PURE__*/jsx("div", {
|
|
1423
2013
|
children: "Name"
|
|
1424
2014
|
}), /*#__PURE__*/jsx("div", {
|
|
@@ -1436,14 +2026,27 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
1436
2026
|
},
|
|
1437
2027
|
onClick: () => onSelectPreset(item),
|
|
1438
2028
|
children: /*#__PURE__*/jsxs("div", {
|
|
1439
|
-
className: "grid ".concat(gridColumns, " w-full text-text-normal"),
|
|
2029
|
+
className: "grid ".concat(gridColumns, " gap-2 w-full text-text-normal"),
|
|
1440
2030
|
children: [/*#__PURE__*/jsx("div", {
|
|
1441
|
-
|
|
1442
|
-
children:
|
|
2031
|
+
className: "min-w-0",
|
|
2032
|
+
children: /*#__PURE__*/jsx(Typography.Text, {
|
|
2033
|
+
ellipsis: true,
|
|
2034
|
+
title: item.name,
|
|
2035
|
+
children: item.name || "Untitled Preset"
|
|
2036
|
+
})
|
|
1443
2037
|
}), /*#__PURE__*/jsx("div", {
|
|
1444
|
-
|
|
2038
|
+
className: "min-w-0",
|
|
2039
|
+
children: /*#__PURE__*/jsx(Typography.Text, {
|
|
2040
|
+
ellipsis: true,
|
|
2041
|
+
children: item.create_time
|
|
2042
|
+
})
|
|
1445
2043
|
}), showDescription && /*#__PURE__*/jsx("div", {
|
|
1446
|
-
|
|
2044
|
+
className: "min-w-0",
|
|
2045
|
+
children: /*#__PURE__*/jsx(Typography.Text, {
|
|
2046
|
+
ellipsis: true,
|
|
2047
|
+
title: item.description,
|
|
2048
|
+
children: item.description
|
|
2049
|
+
})
|
|
1447
2050
|
})]
|
|
1448
2051
|
})
|
|
1449
2052
|
}),
|
|
@@ -1459,7 +2062,7 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
1459
2062
|
onClick: onAddNew,
|
|
1460
2063
|
className: "p-0 h-auto",
|
|
1461
2064
|
icon: /*#__PURE__*/jsx(PlusOutlined, {}),
|
|
1462
|
-
children: "Create
|
|
2065
|
+
children: "Create New Preset"
|
|
1463
2066
|
})
|
|
1464
2067
|
})
|
|
1465
2068
|
})
|
|
@@ -1475,18 +2078,16 @@ const LeftList = /*#__PURE__*/memo(_ref => {
|
|
|
1475
2078
|
size: "middle",
|
|
1476
2079
|
children: [/*#__PURE__*/jsx(Button, {
|
|
1477
2080
|
type: "default",
|
|
1478
|
-
icon: /*#__PURE__*/jsx(PlusOutlined, {})
|
|
1479
|
-
style:
|
|
1480
|
-
|
|
1481
|
-
},
|
|
2081
|
+
icon: /*#__PURE__*/jsx(PlusOutlined, {})
|
|
2082
|
+
// style={{ padding: "20px 12px" }}
|
|
2083
|
+
,
|
|
1482
2084
|
className: "btn-gray",
|
|
1483
2085
|
onClick: onAddNew,
|
|
1484
2086
|
children: texts.newButton
|
|
1485
2087
|
}), /*#__PURE__*/jsx(Button, {
|
|
1486
|
-
type: "default"
|
|
1487
|
-
style:
|
|
1488
|
-
|
|
1489
|
-
},
|
|
2088
|
+
type: "default"
|
|
2089
|
+
// style={{ padding: "20px 12px" }}
|
|
2090
|
+
,
|
|
1490
2091
|
className: "btn-gray",
|
|
1491
2092
|
onClick: onRemove,
|
|
1492
2093
|
children: texts.removeButton
|
|
@@ -1523,8 +2124,8 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
1523
2124
|
originalPresetData,
|
|
1524
2125
|
fields = {
|
|
1525
2126
|
name: {
|
|
1526
|
-
label: "
|
|
1527
|
-
placeholder: "
|
|
2127
|
+
label: "Name",
|
|
2128
|
+
placeholder: "Please enter name",
|
|
1528
2129
|
required: true
|
|
1529
2130
|
}
|
|
1530
2131
|
},
|
|
@@ -1532,7 +2133,7 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
1532
2133
|
loadButton: "Load",
|
|
1533
2134
|
saveButton: "Save"
|
|
1534
2135
|
},
|
|
1535
|
-
presetChanged
|
|
2136
|
+
presetChanged // 作用:在切换选中预设时强制触发 Checkbox 的重新初始化
|
|
1536
2137
|
} = _ref3;
|
|
1537
2138
|
const [initialSelected, setInitialSelected] = useState([]);
|
|
1538
2139
|
const currentSelected = Form.useWatch('category_list', form) || [];
|
|
@@ -1592,32 +2193,40 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
1592
2193
|
},
|
|
1593
2194
|
children: [/*#__PURE__*/jsx(Form.Item, {
|
|
1594
2195
|
name: "name",
|
|
1595
|
-
label: fields.name.label
|
|
1596
|
-
rules
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
}
|
|
2196
|
+
label: fields.name.label
|
|
2197
|
+
// rules={[
|
|
2198
|
+
// {
|
|
2199
|
+
// required: fields.name.required,
|
|
2200
|
+
// validator: async (_, value) => {
|
|
2201
|
+
// if (!value || value.trim() === '') {
|
|
2202
|
+
// return Promise.reject(new Error('Preset name cannot be empty or spaces only'));
|
|
2203
|
+
// }
|
|
2204
|
+
// }
|
|
2205
|
+
// }
|
|
2206
|
+
// ]}
|
|
2207
|
+
,
|
|
2208
|
+
required: true,
|
|
1604
2209
|
children: /*#__PURE__*/jsx(Input, {
|
|
1605
2210
|
placeholder: fields.name.placeholder,
|
|
1606
2211
|
disabled: isEditing
|
|
1607
2212
|
})
|
|
1608
2213
|
}), hasCategoryList && /*#__PURE__*/jsx(Form.Item, {
|
|
1609
2214
|
name: "category_list",
|
|
1610
|
-
label: fields.category_list.label
|
|
1611
|
-
rules
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
}
|
|
2215
|
+
label: fields.category_list.label
|
|
2216
|
+
// rules={[
|
|
2217
|
+
// {
|
|
2218
|
+
// required: fields.category_list.required,
|
|
2219
|
+
// message: 'Please select at least one category',
|
|
2220
|
+
// validator: (_, value) => {
|
|
2221
|
+
// if (value && value.length > 0) {
|
|
2222
|
+
// return Promise.resolve();
|
|
2223
|
+
// }
|
|
2224
|
+
// return Promise.reject(new Error('Please select at least one category'));
|
|
2225
|
+
// }
|
|
2226
|
+
// }
|
|
2227
|
+
// ]}
|
|
2228
|
+
,
|
|
2229
|
+
required: true,
|
|
1621
2230
|
children: /*#__PURE__*/jsx(Checkbox.Group, {
|
|
1622
2231
|
className: "grid grid-cols-2 gap-2",
|
|
1623
2232
|
onChange: handleCheckboxChange,
|
|
@@ -1633,7 +2242,10 @@ const RightDetailForm = /*#__PURE__*/memo(_ref3 => {
|
|
|
1633
2242
|
children: /*#__PURE__*/jsx(Input.TextArea, {
|
|
1634
2243
|
rows: 4,
|
|
1635
2244
|
placeholder: fields.description.placeholder,
|
|
1636
|
-
disabled: isEditing
|
|
2245
|
+
disabled: isEditing,
|
|
2246
|
+
style: {
|
|
2247
|
+
resize: 'none'
|
|
2248
|
+
}
|
|
1637
2249
|
})
|
|
1638
2250
|
})]
|
|
1639
2251
|
}), isEditing ? /*#__PURE__*/jsx(SubmitButton, _objectSpread2(_objectSpread2({
|
|
@@ -1666,20 +2278,20 @@ const Preset = _ref => {
|
|
|
1666
2278
|
// 字段配置
|
|
1667
2279
|
fields = {
|
|
1668
2280
|
name: {
|
|
1669
|
-
label: "
|
|
1670
|
-
placeholder: "
|
|
2281
|
+
label: "Name",
|
|
2282
|
+
placeholder: "Please enter name",
|
|
1671
2283
|
required: true
|
|
1672
2284
|
}
|
|
1673
2285
|
},
|
|
1674
2286
|
texts = {
|
|
1675
2287
|
title: "Preset Management",
|
|
1676
2288
|
emptyText: "Select a preset from the list to view details",
|
|
1677
|
-
deleteConfirm: "Are you sure to delete preset",
|
|
2289
|
+
deleteConfirm: "Are you sure you want to delete preset",
|
|
1678
2290
|
loadConfirm: "Are you sure you want to load preset",
|
|
1679
2291
|
loadText: "Loading...",
|
|
1680
2292
|
successText: "Success",
|
|
1681
2293
|
newButton: "New Preset",
|
|
1682
|
-
removeButton: "
|
|
2294
|
+
removeButton: "Delete",
|
|
1683
2295
|
loadButton: "Load",
|
|
1684
2296
|
saveButton: "Save"
|
|
1685
2297
|
},
|
|
@@ -1697,16 +2309,19 @@ const Preset = _ref => {
|
|
|
1697
2309
|
const [loading, setLoading] = useState(false);
|
|
1698
2310
|
const [presetChanged, setPresetChanged] = useState(0);
|
|
1699
2311
|
const [form] = Form.useForm();
|
|
1700
|
-
|
|
1701
|
-
// 获取预设列表
|
|
1702
|
-
useEffect(() => {
|
|
1703
|
-
fetchPresetList();
|
|
1704
|
-
}, []);
|
|
1705
2312
|
const fetchPresetList = useCallback(async () => {
|
|
1706
2313
|
try {
|
|
1707
2314
|
const data = await getPresetList();
|
|
1708
2315
|
const presets = (data === null || data === void 0 ? void 0 : data.preset_list) || data || [];
|
|
1709
2316
|
setPresetList(presets);
|
|
2317
|
+
|
|
2318
|
+
// 自动选中第一个预设
|
|
2319
|
+
if (presets.length > 0) {
|
|
2320
|
+
const firstPreset = presets[0];
|
|
2321
|
+
setSelectedPreset(firstPreset);
|
|
2322
|
+
form.setFieldsValue(firstPreset);
|
|
2323
|
+
setPresetChanged(prev => prev + 1);
|
|
2324
|
+
}
|
|
1710
2325
|
} catch (error) {
|
|
1711
2326
|
console.error('Failed to fetch preset list:', error);
|
|
1712
2327
|
}
|
|
@@ -1714,7 +2329,7 @@ const Preset = _ref => {
|
|
|
1714
2329
|
const handleSelectPreset = useCallback(preset => {
|
|
1715
2330
|
setSelectedPreset(preset);
|
|
1716
2331
|
form.setFieldsValue(preset);
|
|
1717
|
-
setPresetChanged(prev => prev + 1);
|
|
2332
|
+
setPresetChanged(prev => prev + 1);
|
|
1718
2333
|
}, [form]);
|
|
1719
2334
|
const handleAddNew = useCallback(() => {
|
|
1720
2335
|
var _fields$category_list;
|
|
@@ -1752,18 +2367,44 @@ const Preset = _ref => {
|
|
|
1752
2367
|
cancelText: 'No',
|
|
1753
2368
|
okText: 'Yes',
|
|
1754
2369
|
onOk: async () => {
|
|
2370
|
+
// 在删除前记录当前选中项的位置
|
|
2371
|
+
const currentIndex = presetList.findIndex(item => isUnsavedPreset ? !item.id : item.id === selectedPreset.id);
|
|
1755
2372
|
if (!isUnsavedPreset) {
|
|
1756
2373
|
await removePreset({
|
|
1757
2374
|
id: selectedPreset.id
|
|
1758
2375
|
});
|
|
1759
2376
|
AntdMessage.success(texts.successText);
|
|
1760
|
-
// 刷新列表
|
|
1761
|
-
await fetchPresetList();
|
|
1762
2377
|
} else {
|
|
2378
|
+
// 移除未保存的预设
|
|
1763
2379
|
setPresetList(prev => prev.filter(item => !!item.id));
|
|
1764
2380
|
}
|
|
1765
2381
|
|
|
1766
|
-
//
|
|
2382
|
+
// 获取删除后的列表
|
|
2383
|
+
const updatedList = isUnsavedPreset ? presetList.filter(item => !!item.id) : await getPresetList().then(data => (data === null || data === void 0 ? void 0 : data.preset_list) || data || []);
|
|
2384
|
+
|
|
2385
|
+
// 更新列表
|
|
2386
|
+
setPresetList(updatedList);
|
|
2387
|
+
if (updatedList.length > 0) {
|
|
2388
|
+
// 计算下一个索引
|
|
2389
|
+
let nextIndex = 0;
|
|
2390
|
+
if (currentIndex > 0) {
|
|
2391
|
+
// 如果删除的不是最后一项
|
|
2392
|
+
if (currentIndex < updatedList.length) {
|
|
2393
|
+
nextIndex = currentIndex; // 保持相同位置
|
|
2394
|
+
} else {
|
|
2395
|
+
nextIndex = updatedList.length - 1; // 选最后一个
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
const nextPreset = updatedList[nextIndex];
|
|
2399
|
+
if (nextPreset) {
|
|
2400
|
+
setSelectedPreset(nextPreset);
|
|
2401
|
+
form.setFieldsValue(nextPreset);
|
|
2402
|
+
setPresetChanged(prev => prev + 1);
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
// 列表为空
|
|
1767
2408
|
setSelectedPreset(null);
|
|
1768
2409
|
form.resetFields();
|
|
1769
2410
|
}
|
|
@@ -1771,7 +2412,7 @@ const Preset = _ref => {
|
|
|
1771
2412
|
} catch (error) {
|
|
1772
2413
|
console.error('Failed to delete preset:', error);
|
|
1773
2414
|
}
|
|
1774
|
-
}, [selectedPreset, form, AntdModal, AntdMessage,
|
|
2415
|
+
}, [selectedPreset, form, AntdModal, AntdMessage, texts, removePreset, getPresetList]);
|
|
1775
2416
|
const handleLoadPreset = useCallback(async loadData => {
|
|
1776
2417
|
if (!loadData) return;
|
|
1777
2418
|
|
|
@@ -1827,27 +2468,53 @@ const Preset = _ref => {
|
|
|
1827
2468
|
const handleSave = useCallback(async () => {
|
|
1828
2469
|
setLoading(true);
|
|
1829
2470
|
try {
|
|
1830
|
-
|
|
1831
|
-
|
|
2471
|
+
var _fields$name, _fields$category_list2;
|
|
2472
|
+
const values = await form.getFieldsValue();
|
|
2473
|
+
|
|
2474
|
+
// 验证预设名称
|
|
2475
|
+
if ((_fields$name = fields.name) !== null && _fields$name !== void 0 && _fields$name.required) {
|
|
2476
|
+
if (!values.name || values.name.trim() === '') {
|
|
2477
|
+
AntdMessage.error('Name is required.');
|
|
2478
|
+
return; // 直接返回 不执行
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
// 验证分类列表
|
|
2483
|
+
if ((_fields$category_list2 = fields.category_list) !== null && _fields$category_list2 !== void 0 && _fields$category_list2.required) {
|
|
2484
|
+
if (!values.category_list || values.category_list.length === 0) {
|
|
2485
|
+
AntdMessage.error('No category selected.');
|
|
2486
|
+
return;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
1832
2489
|
await savePreset(values);
|
|
1833
2490
|
AntdMessage.success(texts.successText);
|
|
2491
|
+
const savedPresetName = values.name;
|
|
2492
|
+
|
|
1834
2493
|
// 刷新列表
|
|
1835
|
-
await
|
|
2494
|
+
const data = await getPresetList();
|
|
2495
|
+
const presets = (data === null || data === void 0 ? void 0 : data.preset_list) || data || [];
|
|
2496
|
+
setPresetList(presets);
|
|
1836
2497
|
|
|
1837
|
-
//
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
console.error('Form validation failed:', error.errorFields);
|
|
2498
|
+
// 在刷新后的列表中查找同名的预设
|
|
2499
|
+
const newlySavedPreset = presets.find(item => item.name === savedPresetName);
|
|
2500
|
+
if (newlySavedPreset) {
|
|
2501
|
+
setSelectedPreset(newlySavedPreset);
|
|
2502
|
+
form.setFieldsValue(newlySavedPreset);
|
|
2503
|
+
setPresetChanged(prev => prev + 1);
|
|
1844
2504
|
} else {
|
|
1845
|
-
|
|
2505
|
+
setSelectedPreset(values);
|
|
1846
2506
|
}
|
|
2507
|
+
} catch (error) {
|
|
2508
|
+
console.error('Failed to save preset:', error);
|
|
1847
2509
|
} finally {
|
|
1848
2510
|
setLoading(false);
|
|
1849
2511
|
}
|
|
1850
|
-
}, [form, AntdMessage,
|
|
2512
|
+
}, [form, AntdMessage, texts, savePreset, getPresetList]);
|
|
2513
|
+
|
|
2514
|
+
// 初始化数据
|
|
2515
|
+
useEffect(() => {
|
|
2516
|
+
fetchPresetList();
|
|
2517
|
+
}, [fetchPresetList]);
|
|
1851
2518
|
return /*#__PURE__*/jsx(Modal, {
|
|
1852
2519
|
title: texts.title,
|
|
1853
2520
|
width: width,
|
|
@@ -3712,5 +4379,5 @@ function DraggableNumberInput(_ref2) {
|
|
|
3712
4379
|
}));
|
|
3713
4380
|
}
|
|
3714
4381
|
|
|
3715
|
-
export { AuthorizationModal$1 as AuthorizationModal, CommonHeader$1 as CommonHeader, DraggableNumberInput, NetworkSettingsModal$1 as NetworkSettingsModal, PresetModal, PtpModal$1 as PtpModal, SystemOperations$1 as SystemOperations, UpgradeManager$1 as UpgradeManager, useAuth, useHardwareUsage$1 as useHardwareUsage, useSystemOperations$1 as useSystemOperations, useUpgrade$1 as useUpgrade };
|
|
4382
|
+
export { AuthorizationModal$1 as AuthorizationModal, CommonHeader$1 as CommonHeader, DraggableNumberInput, NetworkSettingsModal$1 as NetworkSettingsModal, PresetModal, PtpModal$1 as PtpModal, SystemOperations$1 as SystemOperations, UpgradeManager$1 as UpgradeManager, useAuth, useHardwareUsage$1 as useHardwareUsage, useLSMLabel, useSystemOperations$1 as useSystemOperations, useUpgrade$1 as useUpgrade };
|
|
3716
4383
|
//# sourceMappingURL=index.esm.js.map
|