mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] Allow import/export/creation of domain allows via admin panel (#2264)
* it's happening! * aaa * fix silly whoopsie * it's working pa! it's working ma! * model report parameters * shuffle some more stuff around * getting there * oo hoo * finish tidying up for now * aaa * fix use form submit errors * peepee poo poo * aaaaa * ffff * they see me typin', they hatin' * boop * aaa * oooo * typing typing tappa tappa * almost done typing * weee * alright * push it push it real good doo doo doo doo doo doo * thingy no worky * almost done * mutation modifers not quite right * hmm * it works * view blocks + allows nicely * it works! * typia install * the old linterino * linter plz
This commit is contained in:
114
web/source/settings/lib/form/index.ts
Normal file
114
web/source/settings/lib/form/index.ts
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useMemo } from "react";
|
||||
import getByDot from "get-by-dot";
|
||||
|
||||
import text from "./text";
|
||||
import file from "./file";
|
||||
import bool from "./bool";
|
||||
import radio from "./radio";
|
||||
import combobox from "./combo-box";
|
||||
import checklist from "./check-list";
|
||||
import fieldarray from "./field-array";
|
||||
|
||||
import type {
|
||||
CreateHook,
|
||||
FormInputHook,
|
||||
HookOpts,
|
||||
TextFormInputHook,
|
||||
RadioFormInputHook,
|
||||
FileFormInputHook,
|
||||
BoolFormInputHook,
|
||||
ComboboxFormInputHook,
|
||||
FieldArrayInputHook,
|
||||
ChecklistInputHook,
|
||||
} from "./types";
|
||||
|
||||
function capitalizeFirst(str: string) {
|
||||
return str.slice(0, 1).toUpperCase + str.slice(1);
|
||||
}
|
||||
|
||||
function selectorByKey(key: string) {
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Memoized hook generator function. Take a createHook
|
||||
* function and use it to return a new FormInputHook function.
|
||||
*
|
||||
* @param createHook
|
||||
* @returns
|
||||
*/
|
||||
function inputHook(createHook: CreateHook): (_name: string, _opts: HookOpts) => FormInputHook {
|
||||
return (name: string, opts?: HookOpts): FormInputHook => {
|
||||
// for dynamically generating attributes like 'setName'
|
||||
const Name = useMemo(() => capitalizeFirst(name), [name]);
|
||||
const selector = useMemo(() => selectorByKey(name), [name]);
|
||||
const valueSelector = opts?.valueSelector?? selector;
|
||||
|
||||
if (opts) {
|
||||
opts.initialValue = useMemo(() => {
|
||||
if (opts.source == undefined) {
|
||||
return opts.defaultValue;
|
||||
} else {
|
||||
return valueSelector(opts.source) ?? opts.defaultValue;
|
||||
}
|
||||
}, [opts.source, opts.defaultValue, valueSelector]);
|
||||
}
|
||||
|
||||
const hook = createHook({ name, Name }, opts ?? {});
|
||||
return Object.assign(hook, { name, Name });
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplest form hook type in town.
|
||||
*/
|
||||
function value<T>(name: string, initialValue: T) {
|
||||
return {
|
||||
_default: initialValue,
|
||||
name,
|
||||
Name: "",
|
||||
value: initialValue,
|
||||
hasChanged: () => true, // always included
|
||||
};
|
||||
}
|
||||
|
||||
export const useTextInput = inputHook(text) as (_name: string, _opts?: HookOpts<string>) => TextFormInputHook;
|
||||
export const useFileInput = inputHook(file) as (_name: string, _opts?: HookOpts<File>) => FileFormInputHook;
|
||||
export const useBoolInput = inputHook(bool) as (_name: string, _opts?: HookOpts<boolean>) => BoolFormInputHook;
|
||||
export const useRadioInput = inputHook(radio) as (_name: string, _opts?: HookOpts<string>) => RadioFormInputHook;
|
||||
export const useComboBoxInput = inputHook(combobox) as (_name: string, _opts?: HookOpts<string>) => ComboboxFormInputHook;
|
||||
export const useCheckListInput = inputHook(checklist) as (_name: string, _opts?: HookOpts<boolean>) => ChecklistInputHook;
|
||||
export const useFieldArrayInput = inputHook(fieldarray) as (_name: string, _opts?: HookOpts<string>) => FieldArrayInputHook;
|
||||
export const useValue = value as <T>(_name: string, _initialValue: T) => FormInputHook<T>;
|
Reference in New Issue
Block a user