mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 15:12:26 -05:00 
			
		
		
		
	[chore/frogend] Restructure form data default values / update from Query data (#1422)
* eslint: set console use to error to catch debug littering in CI * remove debug logging * some form field restructuring, fixes submitted updates not being reflected * more form field restructuring * remove debug logger * simplify field updates * fix react state set during render when submitting import file * className instead of class * show Select hints again
This commit is contained in:
		
					parent
					
						
							
								0a9874329d
							
						
					
				
			
			
				commit
				
					
						47daddc10c
					
				
			
		
					 19 changed files with 153 additions and 86 deletions
				
			
		|  | @ -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 | ||||
| 	}); | ||||
| }; | ||||
|  | @ -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( | ||||
|  |  | |||
|  | @ -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 | ||||
| 	}); | ||||
| }; | ||||
|  | @ -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 makeHook(func) { | ||||
| 	return (name, ...args) => func({ | ||||
| 		name, | ||||
| 		Name: capitalizeFirst(name) | ||||
| 	}, ...args); | ||||
| 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(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 = { | ||||
|  |  | |||
|  | @ -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 | ||||
| 	}); | ||||
| }; | ||||
|  | @ -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 | ||||
| 		} | ||||
| 	]; | ||||
| }; | ||||
|  | @ -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 | ||||
| 	}); | ||||
| }; | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue