diff options
Diffstat (limited to 'web/source/settings/lib/form')
-rw-r--r-- | web/source/settings/lib/form/bool.jsx | 10 | ||||
-rw-r--r-- | web/source/settings/lib/form/check-list.jsx | 12 | ||||
-rw-r--r-- | web/source/settings/lib/form/combo-box.jsx | 13 | ||||
-rw-r--r-- | web/source/settings/lib/form/index.js | 49 | ||||
-rw-r--r-- | web/source/settings/lib/form/radio.jsx | 10 | ||||
-rw-r--r-- | web/source/settings/lib/form/submit.js | 17 | ||||
-rw-r--r-- | web/source/settings/lib/form/text.jsx | 10 |
7 files changed, 79 insertions, 42 deletions
diff --git a/web/source/settings/lib/form/bool.jsx b/web/source/settings/lib/form/bool.jsx index b124abd50..38364be5c 100644 --- a/web/source/settings/lib/form/bool.jsx +++ b/web/source/settings/lib/form/bool.jsx @@ -20,15 +20,16 @@ const React = require("react"); -module.exports = function useBoolInput({ name, Name }, { defaultValue = false } = {}) { - const [value, setValue] = React.useState(defaultValue); +const _default = false; +module.exports = function useBoolInput({ name, Name }, { initialValue = _default }) { + const [value, setValue] = React.useState(initialValue); function onChange(e) { setValue(e.target.checked); } function reset() { - setValue(defaultValue); + setValue(initialValue); } // Array / Object hybrid, for easier access in different contexts @@ -45,6 +46,7 @@ module.exports = function useBoolInput({ name, Name }, { defaultValue = false } reset, value, setter: setValue, - hasChanged: () => value != defaultValue + hasChanged: () => value != initialValue, + _default }); };
\ No newline at end of file diff --git a/web/source/settings/lib/form/check-list.jsx b/web/source/settings/lib/form/check-list.jsx index b19e17a29..7827671be 100644 --- a/web/source/settings/lib/form/check-list.jsx +++ b/web/source/settings/lib/form/check-list.jsx @@ -81,13 +81,13 @@ const { reducer, actions } = createSlice({ } }); -function initialState({ entries, uniqueKey, defaultValue }) { +function initialState({ entries, uniqueKey, initialValue }) { const selectedEntries = new Set(); return { entries: syncpipe(entries, [ (_) => _.map((entry) => { let key = entry[uniqueKey]; - let checked = entry.checked ?? defaultValue; + let checked = entry.checked ?? initialValue; if (checked) { selectedEntries.add(key); @@ -110,9 +110,9 @@ function initialState({ entries, uniqueKey, defaultValue }) { }; } -module.exports = function useCheckListInput({ name }, { entries, uniqueKey = "key", defaultValue = false }) { +module.exports = function useCheckListInput({ name }, { entries, uniqueKey = "key", initialValue = false }) { const [state, dispatch] = React.useReducer(reducer, null, - () => initialState({ entries, uniqueKey, defaultValue }) // initial state + () => initialState({ entries, uniqueKey, initialValue }) // initial state ); const toggleAllRef = React.useRef(null); @@ -132,8 +132,8 @@ module.exports = function useCheckListInput({ name }, { entries, uniqueKey = "ke }, [state.selectedEntries]); const reset = React.useCallback( - () => dispatch(actions.updateAll(defaultValue)), - [defaultValue] + () => dispatch(actions.updateAll(initialValue)), + [initialValue] ); const onChange = React.useCallback( diff --git a/web/source/settings/lib/form/combo-box.jsx b/web/source/settings/lib/form/combo-box.jsx index 3e8cea44a..ce799f430 100644 --- a/web/source/settings/lib/form/combo-box.jsx +++ b/web/source/settings/lib/form/combo-box.jsx @@ -22,17 +22,18 @@ const React = require("react"); const { useComboboxState } = require("ariakit/combobox"); -module.exports = function useComboBoxInput({ name, Name }, { defaultValue } = {}) { +const _default = ""; +module.exports = function useComboBoxInput({ name, Name }, { initialValue = _default }) { const [isNew, setIsNew] = React.useState(false); const state = useComboboxState({ - defaultValue, + defaultValue: initialValue, gutter: 0, sameWidth: true }); function reset() { - state.setValue(""); + state.setValue(initialValue); } return Object.assign([ @@ -48,9 +49,11 @@ module.exports = function useComboBoxInput({ name, Name }, { defaultValue } = {} name, state, value: state.value, - hasChanged: () => state.value != defaultValue, + setter: (val) => state.setValue(val), + hasChanged: () => state.value != initialValue, isNew, setIsNew, - reset + reset, + _default }); };
\ No newline at end of file diff --git a/web/source/settings/lib/form/index.js b/web/source/settings/lib/form/index.js index aef3bf0d2..38e426baa 100644 --- a/web/source/settings/lib/form/index.js +++ b/web/source/settings/lib/form/index.js @@ -18,15 +18,52 @@ "use strict"; +const React = require("react"); +const getByDot = require("get-by-dot").default; + function capitalizeFirst(str) { - return str.slice(0, 1).toUpperCase() + str.slice(1); + return str.slice(0, 1).toUpperCase + str.slice(1); +} + +function selectorByKey(key) { + if (key.includes("[")) { + // get-by-dot does not support 'nested[deeper][key]' notation, convert to 'nested.deeper.key' + key = key + .replace(/\[/g, ".") // nested.deeper].key] + .replace(/\]/g, ""); // nested.deeper.key + } + + return function selector(obj) { + if (obj == undefined) { + return undefined; + } else { + return getByDot(obj, key); + } + }; } -function makeHook(func) { - return (name, ...args) => func({ - name, - Name: capitalizeFirst(name) - }, ...args); +function makeHook(hookFunction) { + return function (name, opts = {}) { + // for dynamically generating attributes like 'setName' + const Name = React.useMemo(() => capitalizeFirst(name), [name]); + + const selector = React.useMemo(() => selectorByKey(name), [name]); + const valueSelector = opts.valueSelector ?? selector; + + opts.initialValue = React.useMemo(() => { + if (opts.source == undefined) { + return opts.defaultValue; + } else { + return valueSelector(opts.source) ?? opts.defaultValue; + } + }, [opts.source, opts.defaultValue, valueSelector]); + + const hook = hookFunction({ name, Name }, opts); + + return Object.assign(hook, { + name, Name, + }); + }; } module.exports = { diff --git a/web/source/settings/lib/form/radio.jsx b/web/source/settings/lib/form/radio.jsx index 47ab6c726..e95997474 100644 --- a/web/source/settings/lib/form/radio.jsx +++ b/web/source/settings/lib/form/radio.jsx @@ -20,15 +20,16 @@ const React = require("react"); -module.exports = function useRadioInput({ name, Name }, { defaultValue, options } = {}) { - const [value, setValue] = React.useState(defaultValue); +const _default = ""; +module.exports = function useRadioInput({ name, Name }, { initialValue = _default, options }) { + const [value, setValue] = React.useState(initialValue); function onChange(e) { setValue(e.target.value); } function reset() { - setValue(defaultValue); + setValue(initialValue); } // Array / Object hybrid, for easier access in different contexts @@ -46,6 +47,7 @@ module.exports = function useRadioInput({ name, Name }, { defaultValue, options value, setter: setValue, options, - hasChanged: () => value != defaultValue + hasChanged: () => value != initialValue, + _default }); };
\ No newline at end of file diff --git a/web/source/settings/lib/form/submit.js b/web/source/settings/lib/form/submit.js index 6f20165a5..2a81307c5 100644 --- a/web/source/settings/lib/form/submit.js +++ b/web/source/settings/lib/form/submit.js @@ -18,7 +18,6 @@ "use strict"; -const Promise = require("bluebird"); const React = require("react"); const syncpipe = require("syncpipe"); @@ -27,7 +26,7 @@ module.exports = function useFormSubmit(form, mutationQuery, { changedOnly = tru throw new ("useFormSubmit: mutationQuery was not an Array. Is a valid useMutation RTK Query provided?"); } const [runMutation, result] = mutationQuery; - const [usedAction, setUsedAction] = React.useState(); + const usedAction = React.useRef(null); return [ function submitForm(e) { let action; @@ -41,7 +40,7 @@ module.exports = function useFormSubmit(form, mutationQuery, { changedOnly = tru if (action == "") { action = undefined; } - setUsedAction(action); + usedAction.current = action; // transform the field definitions into an object with just their values let updatedFields = []; const mutationData = syncpipe(form, [ @@ -65,19 +64,11 @@ module.exports = function useFormSubmit(form, mutationQuery, { changedOnly = tru mutationData.action = action; - return Promise.try(() => { - return runMutation(mutationData); - }).then((res) => { - if (res.error == undefined) { - updatedFields.forEach((field) => { - field.reset(); - }); - } - }); + return runMutation(mutationData); }, { ...result, - action: usedAction + action: usedAction.current } ]; };
\ No newline at end of file diff --git a/web/source/settings/lib/form/text.jsx b/web/source/settings/lib/form/text.jsx index d9a9ab28c..ce116f9ab 100644 --- a/web/source/settings/lib/form/text.jsx +++ b/web/source/settings/lib/form/text.jsx @@ -20,15 +20,16 @@ const React = require("react"); +const _default = ""; module.exports = function useTextInput({ name, Name }, { - defaultValue = "", + initialValue = _default, dontReset = false, validator, showValidation = true, initValidation } = {}) { - const [text, setText] = React.useState(defaultValue); + const [text, setText] = React.useState(initialValue); const textRef = React.useRef(null); const [validation, setValidation] = React.useState(initValidation ?? ""); @@ -48,7 +49,7 @@ module.exports = function useTextInput({ name, Name }, { function reset() { if (!dontReset) { - setText(defaultValue); + setText(initialValue); } } @@ -81,6 +82,7 @@ module.exports = function useTextInput({ name, Name }, { setter: setText, valid, validate: () => setValidation(validator(text)), - hasChanged: () => text != defaultValue + hasChanged: () => text != initialValue, + _default }); };
\ No newline at end of file |