summaryrefslogtreecommitdiff
path: root/packages/frontend/src/widgets/widget.ts
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-12-27 14:36:33 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-12-27 14:36:33 +0900
commit9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch)
treece5959571a981b9c4047da3c7b3fd080aa44222c /packages/frontend/src/widgets/widget.ts
parentwip: retention for dashboard (diff)
downloadsharkey-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.ts73
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,
+ };
+};