From 150dad6d2b5a88f5ab029bb12e9f6b4e00dcdcbf Mon Sep 17 00:00:00 2001 From: Faton Ramadani Date: Fri, 14 Jul 2023 15:08:27 +0200 Subject: [PATCH] feat(frontend): add modal component controls (#1877) * feat(frontend): add modal component controls * feat(frontend): add modal component controls --- .../components/helpers/RunnableWrapper.svelte | 111 ++++++++++++------ .../apps/components/helpers/eval.ts | 14 ++- .../apps/components/layout/AppModal.svelte | 20 +++- .../apps/editor/component/components.ts | 40 ++++++- frontend/src/lib/components/apps/types.ts | 2 + frontend/src/lib/components/apps/utils.ts | 2 + 6 files changed, 147 insertions(+), 42 deletions(-) diff --git a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte index 5121cb7d6f..21419639ed 100644 --- a/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte +++ b/frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte @@ -13,7 +13,15 @@ type SideEffectAction = | { - selected: 'gotoUrl' | 'none' | 'setTab' | 'sendToast' | 'sendErrorToast' | 'errorOverlay' + selected: + | 'gotoUrl' + | 'none' + | 'setTab' + | 'sendToast' + | 'sendErrorToast' + | 'errorOverlay' + | 'openModal' + | 'closeModal' configuration: { gotoUrl: { url: string | undefined; newTab: boolean | undefined } setTab: { @@ -26,6 +34,12 @@ message: string | undefined appendError: boolean | undefined } + openModal?: { + modalId: string | undefined + } + closeModal?: { + modalId: string | undefined + } } } | undefined @@ -90,44 +104,67 @@ if (sideEffect.selected == 'none') return - if (sideEffect.selected == 'setTab') { - if (Array.isArray(sideEffect.configuration.setTab.setTab)) { - sideEffect.configuration.setTab?.setTab?.forEach((tab) => { - if (tab) { - const { id, index } = tab - $componentControl[id].setTab?.(index) - } - }) + switch (sideEffect.selected) { + case 'setTab': + const setTab = sideEffect?.configuration.setTab?.setTab + + if (Array.isArray(setTab)) { + setTab.forEach((tab) => { + if (tab) { + const { id, index } = tab + $componentControl[id].setTab?.(index) + } + }) + } + break + case 'gotoUrl': + const url = sideEffect?.configuration?.gotoUrl?.url + + if (!url) return + + const newTab = sideEffect?.configuration?.gotoUrl?.newTab + + if (newTab) { + window.open(url, '_blank') + } else { + window.location.href = url + } + + break + case 'sendToast': { + const message = sideEffect?.configuration?.sendToast?.message + + if (!message) return + + sendUserToast(message, !success) + break } - } else if ( - sideEffect.selected == 'gotoUrl' && - sideEffect.configuration.gotoUrl.url && - sideEffect.configuration.gotoUrl.url != '' - ) { - if (sideEffect.configuration.gotoUrl.newTab) { - window.open(sideEffect.configuration.gotoUrl.url, '_blank') - } else { - window.location.href = sideEffect.configuration.gotoUrl.url + case 'sendErrorToast': { + const message = sideEffect?.configuration?.sendErrorToast?.message + const appendError = sideEffect?.configuration?.sendErrorToast?.appendError + + if (!message) return + + sendUserToast(message, true, [], appendError ? errorMessage : undefined) + break } - } else if ( - sideEffect.selected == 'sendToast' && - sideEffect.configuration.sendToast && - sideEffect.configuration.sendToast.message && - sideEffect.configuration.sendToast.message != '' - ) { - sendUserToast(sideEffect.configuration.sendToast.message, !success) - } else if ( - sideEffect.selected == 'sendErrorToast' && - sideEffect.configuration.sendErrorToast && - sideEffect.configuration.sendErrorToast.message && - sideEffect.configuration.sendErrorToast.message != '' - ) { - sendUserToast( - sideEffect.configuration.sendErrorToast.message, - true, - [], - sideEffect.configuration.sendErrorToast.appendError ? errorMessage : undefined - ) + case 'openModal': { + const modalId = sideEffect?.configuration?.openModal?.modalId + if (modalId) { + $componentControl[modalId].openModal?.() + } + break + } + case 'closeModal': { + const modalId = sideEffect?.configuration?.closeModal?.modalId + + if (!modalId) return + + $componentControl[modalId].closeModal?.() + break + } + default: + break } } diff --git a/frontend/src/lib/components/apps/components/helpers/eval.ts b/frontend/src/lib/components/apps/components/helpers/eval.ts index 54c3f40573..36c36845c6 100644 --- a/frontend/src/lib/components/apps/components/helpers/eval.ts +++ b/frontend/src/lib/components/apps/components/helpers/eval.ts @@ -20,7 +20,7 @@ export function computeGlobalContext(world: World | undefined, extraContext: any function create_context_function_template(eval_string, context, noReturn: boolean) { return ` -return async function (context, state, goto, setTab, recompute, getAgGrid, setValue, setSelectedIndex) { +return async function (context, state, goto, setTab, recompute, getAgGrid, setValue, setSelectedIndex, openModal, closeModal) { "use strict"; ${ Object.keys(context).length > 0 @@ -44,7 +44,9 @@ function make_context_evaluator( recompute, getAgGrid, setValue, - setSelectedIndex + setSelectedIndex, + openModal, + closeModal ) => Promise { let template = create_context_function_template(eval_string, context, noReturn) let functor = Function(template) @@ -96,6 +98,8 @@ export async function eval_like( agGrid?: { api: any; columnApi: any } setValue?: (value: any) => void setSelectedIndex?: (index: number) => void + openModal?: () => void + closeModal?: () => void } >, worldStore: World | undefined, @@ -146,6 +150,12 @@ export async function eval_like( }, (id, index) => { controlComponents[id]?.setSelectedIndex?.(index) + }, + (id) => { + controlComponents[id]?.openModal?.() + }, + (id) => { + controlComponents[id]?.closeModal?.() } ) } diff --git a/frontend/src/lib/components/apps/components/layout/AppModal.svelte b/frontend/src/lib/components/apps/components/layout/AppModal.svelte index b5b9259d64..f7d4b09a78 100644 --- a/frontend/src/lib/components/apps/components/layout/AppModal.svelte +++ b/frontend/src/lib/components/apps/components/layout/AppModal.svelte @@ -22,8 +22,15 @@ export let noWFull = false export let render: boolean - const { app, focusedGrid, selectedComponent, worldStore, connectingInput, mode } = - getContext('AppViewerContext') + const { + app, + focusedGrid, + selectedComponent, + worldStore, + connectingInput, + mode, + componentControl + } = getContext('AppViewerContext') //used so that we can count number of outputs setup for first refresh initOutput($worldStore, id, {}) @@ -49,6 +56,15 @@ components['modalcomponent'].initialData.configuration, configuration ) + + $componentControl[id] = { + openModal: () => { + open = true + }, + closeModal: () => { + open = false + } + } diff --git a/frontend/src/lib/components/apps/editor/component/components.ts b/frontend/src/lib/components/apps/editor/component/components.ts index 574baa05af..debefa1686 100644 --- a/frontend/src/lib/components/apps/editor/component/components.ts +++ b/frontend/src/lib/components/apps/editor/component/components.ts @@ -281,7 +281,9 @@ const labels = { gotoUrl: 'Go to an url', setTab: 'Set the tab of a tabs component', sendToast: 'Display a toast notification', - sendErrorToast: 'Display an error toast notification' + sendErrorToast: 'Display an error toast notification', + openModal: 'Open a modal', + closeModal: 'Close a modal' } const onSuccessClick = { @@ -324,6 +326,24 @@ const onSuccessClick = { placeholder: 'Hello there', noVariablePicker: true } + }, + openModal: { + modalId: { + tooltip: 'The id of the modal to open', + fieldType: 'text', + type: 'static', + value: '', + noVariablePicker: true + } + }, + closeModal: { + modalId: { + tooltip: 'The id of the modal to close', + fieldType: 'text', + type: 'static', + value: '', + noVariablePicker: true + } } } } as const @@ -373,6 +393,24 @@ const onErrorClick = { type: 'static', value: true } + }, + openModal: { + modalId: { + tooltip: 'The id of the modal to open', + fieldType: 'text', + type: 'static', + value: '', + noVariablePicker: true + } + }, + closeModal: { + modalId: { + tooltip: 'The id of the modal to close', + fieldType: 'text', + type: 'static', + value: '', + noVariablePicker: true + } } } } as const diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 22a4101118..7c6521ad3a 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -206,6 +206,8 @@ export type AppViewerContext = { onDelete?: () => void setValue?: (value: any) => void setSelectedIndex?: (index: number) => void + openModal?: () => void + closeModal?: () => void } > > diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts index b7e27a5982..8509ef76cf 100644 --- a/frontend/src/lib/components/apps/utils.ts +++ b/frontend/src/lib/components/apps/utils.ts @@ -218,6 +218,8 @@ declare function recompute(id: string): void; declare function getAgGrid(id: string): {api: any, columnApi: any} | undefined; declare function setValue(id: string, value: any): void; declare function setSelectedIndex(id: string, index: number): void; +declare function openModal(id: string): void; +declare function closeModal(id: string): void; ` : '' }