diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
| commit | 9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch) | |
| tree | ce5959571a981b9c4047da3c7b3fd080aa44222c /packages/frontend/src/widgets/widget.ts | |
| parent | wip: retention for dashboard (diff) | |
| download | sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.gz sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.bz2 sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.zip | |
rename: client -> frontend
Diffstat (limited to 'packages/frontend/src/widgets/widget.ts')
| -rw-r--r-- | packages/frontend/src/widgets/widget.ts | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/packages/frontend/src/widgets/widget.ts b/packages/frontend/src/widgets/widget.ts new file mode 100644 index 0000000000..8bd56a5966 --- /dev/null +++ b/packages/frontend/src/widgets/widget.ts @@ -0,0 +1,73 @@ +import { reactive, watch } from 'vue'; +import { throttle } from 'throttle-debounce'; +import { Form, GetFormResultType } from '@/scripts/form'; +import * as os from '@/os'; +import { deepClone } from '@/scripts/clone'; + +export type Widget<P extends Record<string, unknown>> = { + id: string; + data: Partial<P>; +}; + +export type WidgetComponentProps<P extends Record<string, unknown>> = { + widget?: Widget<P>; +}; + +export type WidgetComponentEmits<P extends Record<string, unknown>> = { + (ev: 'updateProps', props: P); +}; + +export type WidgetComponentExpose = { + name: string; + id: string | null; + configure: () => void; +}; + +export const useWidgetPropsManager = <F extends Form & Record<string, { default: any; }>>( + name: string, + propsDef: F, + props: Readonly<WidgetComponentProps<GetFormResultType<F>>>, + emit: WidgetComponentEmits<GetFormResultType<F>>, +): { + widgetProps: GetFormResultType<F>; + save: () => void; + configure: () => void; +} => { + const widgetProps = reactive(props.widget ? deepClone(props.widget.data) : {}); + + const mergeProps = () => { + for (const prop of Object.keys(propsDef)) { + if (typeof widgetProps[prop] === 'undefined') { + widgetProps[prop] = propsDef[prop].default; + } + } + }; + watch(widgetProps, () => { + mergeProps(); + }, { deep: true, immediate: true }); + + const save = throttle(3000, () => { + emit('updateProps', widgetProps); + }); + + const configure = async () => { + const form = deepClone(propsDef); + for (const item of Object.keys(form)) { + form[item].default = widgetProps[item]; + } + const { canceled, result } = await os.form(name, form); + if (canceled) return; + + for (const key of Object.keys(result)) { + widgetProps[key] = result[key]; + } + + save(); + }; + + return { + widgetProps, + save, + configure, + }; +}; |