1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import { LOG } from "@/utilities/console";
import type { UseFormReturnType } from "@mantine/form";
import { createContext, useCallback, useContext, useRef } from "react";
export const FormContext = createContext<UseFormReturnType<FormValues> | null>(
null,
);
export function useFormValues() {
const context = useContext(FormContext);
if (context === null) {
throw new Error("useFormValues must be used within a FormContext");
}
return context;
}
export function useStagedValues() {
const form = useFormValues();
return { ...form.values.settings };
}
export function useFormActions() {
const form = useFormValues();
const formRef = useRef(form);
formRef.current = form;
const update = useCallback((object: LooseObject) => {
LOG("info", `Updating values`, object);
formRef.current.setValues((values) => {
const changes = { ...values.settings, ...object };
return { ...values, settings: changes };
});
}, []);
const setValue = useCallback((v: unknown, key: string, hook?: HookType) => {
LOG("info", `Updating value of ${key}`, v);
formRef.current.setValues((values) => {
const changes = { ...values.settings, [key]: v };
const hooks = { ...values.hooks };
if (hook) {
LOG(
"info",
`Adding submit hook ${key}, will be executed before submitting`,
);
hooks[key] = hook;
}
return { ...values, settings: changes, hooks };
});
}, []);
return { update, setValue };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type HookType = (value: any) => unknown;
export type FormKey = keyof FormValues;
export type FormValues = {
// Settings that saved to the backend
settings: LooseObject;
// Settings that saved to the frontend
// storages: LooseObject;
// submit hooks
hooks: StrictObject<HookType>;
};
export function runHooks(
hooks: FormValues["hooks"],
settings: FormValues["settings"],
) {
for (const key in settings) {
if (key in hooks) {
LOG("info", "Running submit hook for", key, settings[key]);
const value = settings[key];
const fn = hooks[key];
settings[key] = fn(value);
LOG("info", "Finish submit hook", key, settings[key]);
}
}
}
|