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