2022-11-20 16:23:55 +00:00
|
|
|
import { LOG } from "@/utilities/console";
|
2022-06-30 15:35:23 +00:00
|
|
|
import { get, isNull, isUndefined, uniqBy } from "lodash";
|
2022-10-25 15:39:57 +00:00
|
|
|
import { useCallback, useMemo, useRef } from "react";
|
2022-11-20 16:23:55 +00:00
|
|
|
import { useFormActions, useStagedValues } from "../utilities/FormValues";
|
2022-06-30 15:35:23 +00:00
|
|
|
import { useSettings } from "../utilities/SettingsProvider";
|
2022-10-25 15:39:57 +00:00
|
|
|
import { useSubmitHookWith } from "./HooksProvider";
|
2022-06-30 15:35:23 +00:00
|
|
|
|
|
|
|
export interface BaseInput<T> {
|
|
|
|
disabled?: boolean;
|
|
|
|
settingKey: string;
|
|
|
|
settingOptions?: SettingValueOptions<T>;
|
|
|
|
}
|
|
|
|
|
|
|
|
export type SettingValueOptions<T> = {
|
|
|
|
original?: boolean;
|
|
|
|
defaultValue?: T;
|
2022-11-20 16:23:55 +00:00
|
|
|
onLoaded?: (settings: Settings) => T;
|
2022-06-30 15:35:23 +00:00
|
|
|
onSaved?: (value: T) => unknown;
|
|
|
|
onSubmit?: (value: T) => unknown;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function useBaseInput<T, V>(props: T & BaseInput<V>) {
|
2022-11-20 16:23:55 +00:00
|
|
|
const { settingKey, settingOptions, ...rest } = props;
|
2022-06-30 15:35:23 +00:00
|
|
|
// TODO: Opti options
|
|
|
|
const value = useSettingValue<V>(settingKey, settingOptions);
|
|
|
|
|
|
|
|
const { setValue } = useFormActions();
|
|
|
|
|
|
|
|
const update = useCallback(
|
|
|
|
(newValue: V | null) => {
|
|
|
|
const moddedValue =
|
|
|
|
(newValue && settingOptions?.onSaved?.(newValue)) ?? newValue;
|
|
|
|
|
2022-11-20 16:23:55 +00:00
|
|
|
setValue(moddedValue, settingKey);
|
2022-06-30 15:35:23 +00:00
|
|
|
},
|
2022-11-20 16:23:55 +00:00
|
|
|
[settingOptions, setValue, settingKey]
|
2022-06-30 15:35:23 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
return { value, update, rest };
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useSettingValue<T>(
|
|
|
|
key: string,
|
|
|
|
options?: SettingValueOptions<T>
|
|
|
|
): Readonly<Nullable<T>> {
|
|
|
|
const settings = useSettings();
|
|
|
|
|
|
|
|
const optionsRef = useRef(options);
|
2022-10-25 15:39:57 +00:00
|
|
|
optionsRef.current = options;
|
2022-06-30 15:35:23 +00:00
|
|
|
|
2022-10-25 15:39:57 +00:00
|
|
|
useSubmitHookWith(key, options?.onSubmit);
|
2022-06-30 15:35:23 +00:00
|
|
|
|
|
|
|
const originalValue = useMemo(() => {
|
|
|
|
const onLoaded = optionsRef.current?.onLoaded;
|
|
|
|
const defaultValue = optionsRef.current?.defaultValue;
|
|
|
|
if (onLoaded) {
|
|
|
|
LOG("info", `${key} is using custom loader`);
|
|
|
|
|
2022-11-20 16:23:55 +00:00
|
|
|
return onLoaded(settings);
|
2022-06-30 15:35:23 +00:00
|
|
|
}
|
|
|
|
|
2022-11-20 16:23:55 +00:00
|
|
|
const path = key.replaceAll("-", ".");
|
2022-06-30 15:35:23 +00:00
|
|
|
|
2022-11-20 16:23:55 +00:00
|
|
|
const value = get({ settings }, path, null) as Nullable<T>;
|
2022-06-30 15:35:23 +00:00
|
|
|
|
|
|
|
if (defaultValue && (isNull(value) || isUndefined(value))) {
|
|
|
|
LOG("info", `${key} is falling back to`, defaultValue);
|
|
|
|
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
2022-11-20 16:23:55 +00:00
|
|
|
}, [key, settings]);
|
2022-06-30 15:35:23 +00:00
|
|
|
|
|
|
|
const stagedValue = useStagedValues();
|
|
|
|
|
|
|
|
if (key in stagedValue && optionsRef.current?.original !== true) {
|
|
|
|
return stagedValue[key] as T;
|
|
|
|
} else {
|
|
|
|
return originalValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useUpdateArray<T>(key: string, compare: keyof T) {
|
|
|
|
const { setValue } = useFormActions();
|
|
|
|
const stagedValue = useStagedValues();
|
|
|
|
|
|
|
|
const compareRef = useRef(compare);
|
|
|
|
compareRef.current = compare;
|
|
|
|
|
|
|
|
const staged: T[] = useMemo(() => {
|
|
|
|
if (key in stagedValue) {
|
|
|
|
return stagedValue[key];
|
|
|
|
} else {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}, [key, stagedValue]);
|
|
|
|
|
|
|
|
return useCallback(
|
|
|
|
(v: T) => {
|
|
|
|
const newArray = uniqBy([v, ...staged], compareRef.current);
|
|
|
|
setValue(newArray, key);
|
|
|
|
},
|
|
|
|
[staged, setValue, key]
|
|
|
|
);
|
|
|
|
}
|