From 16b31b98f391197c745dcc4328c49fc32905d0ff Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:52:52 -0700 Subject: [PATCH] feat: config page ux improvements (#315) * feat: convert config inputs to textarea * fix: save config works * feat: add descriptions to config page inputs * chore: package-lock.json update * refactor(configuration): css tweaks * fix: localStorage stores stringified json --------- Co-authored-by: Marcin Rataj --- package-lock.json | 9 --- src/components/local-storage-input.tsx | 53 ++++++++++----- src/components/local-storage-toggle.css | 2 +- src/lib/config-db.ts | 8 +-- src/lib/local-storage.ts | 19 ++++++ src/pages/config.tsx | 88 ++++++++++++++++++++++--- 6 files changed, 139 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4bcaf656..d3d051f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6478,15 +6478,6 @@ "ajv": "^6.9.1" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "extraneous": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", diff --git a/src/components/local-storage-input.tsx b/src/components/local-storage-input.tsx index 582e5d42..7e4632a4 100644 --- a/src/components/local-storage-input.tsx +++ b/src/components/local-storage-input.tsx @@ -7,22 +7,38 @@ export interface LocalStorageInputProps extends React.DetailedHTMLProps { try { - JSON.parse(value) + value.split('\n') return null } catch (err) { return err as Error } } -export default ({ resetKey, localStorageKey, label, placeholder, validationFn, defaultValue, ...props }: LocalStorageInputProps): JSX.Element => { - const [value, setValue] = useState(localStorage.getItem(localStorageKey) ?? defaultValue) + +const getFromLocalStorage = (postLoadFormat?: (arg0: string) => string) => (key: string, fallback: string) => { + let localStorageValue = localStorage.getItem(key) + if (localStorageValue != null && postLoadFormat != null) { + localStorageValue = postLoadFormat(localStorageValue) + } + return localStorageValue ?? fallback +} + +/** + * A Local storage input (text area) component that saves the input to local storage. + */ +export default ({ resetKey, localStorageKey, label, placeholder, validationFn, defaultValue, description, preSaveFormat, postLoadFormat, ...props }: LocalStorageInputProps): JSX.Element => { + const localStorageLoadFn = getFromLocalStorage(postLoadFormat) + const [value, setValue] = useState(localStorageLoadFn(localStorageKey, defaultValue)) const [error, setError] = useState(null) useEffect(() => { - setValue(localStorage.getItem(localStorageKey) ?? defaultValue) + setValue(localStorageLoadFn(localStorageKey, defaultValue)) }, [resetKey]) if (validationFn == null) { @@ -35,26 +51,31 @@ export default ({ resetKey, localStorageKey, label, placeholder, validationFn, d if (err != null) { throw err } - localStorage.setItem(localStorageKey, value) + localStorage.setItem(localStorageKey, preSaveFormat?.(value) ?? value) setError(null) } catch (err) { setError(err as Error) } }, [value]) + props = { + ...props, + className: `${props.className ?? ''} flex-column items-start mb3` + } + return (
- - { setValue(e.target.value) }} - /> - {error != null && {error.message}} + + {description} +