From aa8b8b35fd745a591a3f2ae23b7217d49ab28afa Mon Sep 17 00:00:00 2001 From: Faton Ramadani Date: Thu, 8 Dec 2022 13:26:01 +0100 Subject: [PATCH] App editor v2 (#1001) * fix(frontend): Fix app InputValue sync * feat(frontend): WIP * feat(frontend): WIP * feat(frontend): Type aligned * feat(frontend): working * feat(frontend): working * feat(frontend): Fix text binding * feat(frontend): Connect + script working * feat(frontend): Fix reactity issues --- .../src/lib/components/TestJobLoader.svelte | 2 + .../apps/components/DisplayComponent.svelte | 27 +-- .../apps/components/buttons/AppButton.svelte | 36 ++- .../components/dataDisplay/AppBarChart.svelte | 48 +++- .../components/dataDisplay/AppPieChart.svelte | 69 +++--- .../components/dataDisplay/AppTable.svelte | 37 ++- .../components/dataDisplay/AppText.svelte | 27 ++- .../apps/components/dataDisplay/app.md | 49 ++++ .../apps/components/helpers/InputValue.svelte | 28 ++- .../helpers/NonRunnableComponent.svelte | 31 +++ .../helpers/RunnableComponent.svelte | 58 ++--- .../components/helpers/RunnableWrapper.svelte | 34 +++ .../lib/components/apps/components/index.ts | 54 ----- .../selectInputs/AppCheckbox.svelte | 10 +- .../components/apps/editor/AppEditor.svelte | 109 +++++---- .../components/apps/editor/AppPreview.svelte | 15 +- .../apps/editor/ComponentEditor.svelte | 49 ++-- .../apps/editor/ComponentHeader.svelte | 17 ++ .../components/apps/editor/GridEditor.svelte | 44 +++- .../componentsPanel/componentDefaultProps.ts | 9 +- .../componentsPanel/componentStaticValues.ts | 4 +- .../apps/editor/componentsPanel/data.ts | 145 ++++++++---- .../editor/contextPanel/ContextPanel.svelte | 13 +- .../settingsPanel/ComponentPanel.svelte | 214 ++++++++++-------- .../settingsPanel/ConnectedInputEditor.svelte | 78 +++++++ .../settingsPanel/DynamicInputEditor.svelte | 73 ------ .../settingsPanel/InputsSpecEditor.svelte | 14 +- .../settingsPanel/InputsSpecsEditor.svelte | 161 ++++++------- .../settingsPanel/PickInlineScript.svelte | 2 +- .../settingsPanel/StaticInputEditor.svelte | 56 +++-- .../settingsPanel/TableActionLabel.svelte | 13 ++ .../editor/settingsPanel/TableActions.svelte | 20 +- .../settingsPanel/common/PanelSection.svelte | 2 +- frontend/src/lib/components/apps/inputType.ts | 85 +++++++ frontend/src/lib/components/apps/rx.ts | 38 +++- frontend/src/lib/components/apps/types.ts | 106 ++------- frontend/src/lib/components/apps/utils.ts | 67 +++++- frontend/src/routes/apps/get/[...path].svelte | 2 +- 38 files changed, 1097 insertions(+), 749 deletions(-) create mode 100644 frontend/src/lib/components/apps/components/dataDisplay/app.md create mode 100644 frontend/src/lib/components/apps/components/helpers/NonRunnableComponent.svelte create mode 100644 frontend/src/lib/components/apps/components/helpers/RunnableWrapper.svelte delete mode 100644 frontend/src/lib/components/apps/components/index.ts create mode 100644 frontend/src/lib/components/apps/editor/ComponentHeader.svelte create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/ConnectedInputEditor.svelte delete mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/DynamicInputEditor.svelte create mode 100644 frontend/src/lib/components/apps/editor/settingsPanel/TableActionLabel.svelte create mode 100644 frontend/src/lib/components/apps/inputType.ts diff --git a/frontend/src/lib/components/TestJobLoader.svelte b/frontend/src/lib/components/TestJobLoader.svelte index 513a4e301e..84e90366cc 100644 --- a/frontend/src/lib/components/TestJobLoader.svelte +++ b/frontend/src/lib/components/TestJobLoader.svelte @@ -26,6 +26,7 @@ export async function abstractRun(fn: () => Promise) { try { intervalId && clearIntervalAsync(intervalId) + if (isLoading && job) { JobService.cancelQueuedJob({ workspace: workspace!, @@ -36,6 +37,7 @@ isLoading = true const testId = await fn() + await watchJob(testId) } catch (err) { isLoading = false diff --git a/frontend/src/lib/components/apps/components/DisplayComponent.svelte b/frontend/src/lib/components/apps/components/DisplayComponent.svelte index 9331c3e2a8..15f3a5b585 100644 --- a/frontend/src/lib/components/apps/components/DisplayComponent.svelte +++ b/frontend/src/lib/components/apps/components/DisplayComponent.svelte @@ -1,29 +1,20 @@ - - -{#if $worldStore} +
Results
- {#if resultValue === undefined && componentInputs.result.type === 'output'} - Waiting for result - {:else} - - {/if} +
-{/if} +
diff --git a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte index 2c9a705c8a..35569b7c14 100644 --- a/frontend/src/lib/components/apps/components/buttons/AppButton.svelte +++ b/frontend/src/lib/components/apps/components/buttons/AppButton.svelte @@ -1,16 +1,15 @@ - - - + + + - - + + + diff --git a/frontend/src/lib/components/apps/components/dataDisplay/AppBarChart.svelte b/frontend/src/lib/components/apps/components/dataDisplay/AppBarChart.svelte index 87a666afcb..80ff1088a2 100644 --- a/frontend/src/lib/components/apps/components/dataDisplay/AppBarChart.svelte +++ b/frontend/src/lib/components/apps/components/dataDisplay/AppBarChart.svelte @@ -14,15 +14,13 @@ } from 'chart.js' import type { ChartData } from 'chart.js' - - import type { InputsSpec } from '../../types' - import RunnableComponent from '../helpers/RunnableComponent.svelte' + import RunnableWrapper from '../helpers/RunnableWrapper.svelte' + import type { AppInput } from '../../inputType' + import InputValue from '../helpers/InputValue.svelte' export let id: string - export let inputs: InputsSpec - export let path: string | undefined = undefined - export let runType: 'script' | 'flow' | undefined = undefined - export let inlineScriptName: string | undefined = undefined + export let componentInput: AppInput | undefined + export let configuration: Record export const staticOutputs: string[] = ['loading', 'result'] @@ -38,10 +36,38 @@ ) let result: ChartData<'bar', number[], unknown> | undefined = undefined + let labels: string[] = [] + let theme: string = 'theme1' + + $: backgroundColor = { + theme1: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], + // blue theme + theme2: ['#4e73df', '#1cc88a', '#36b9cc', '#f6c23e', '#e74a3b'], + // red theme + theme3: ['#e74a3b', '#4e73df', '#1cc88a', '#36b9cc', '#f6c23e'] + }[theme] + + const options = { + responsive: true, + animation: false + } + + $: data = { + labels, + datasets: [ + { + data: result, + backgroundColor + } + ] + } - - {#if result} - + + + + + {#if data} + {/if} - + diff --git a/frontend/src/lib/components/apps/components/dataDisplay/AppPieChart.svelte b/frontend/src/lib/components/apps/components/dataDisplay/AppPieChart.svelte index e208ad1287..18fd2191ac 100644 --- a/frontend/src/lib/components/apps/components/dataDisplay/AppPieChart.svelte +++ b/frontend/src/lib/components/apps/components/dataDisplay/AppPieChart.svelte @@ -13,14 +13,13 @@ ArcElement } from 'chart.js' import type { ChartData } from 'chart.js' - import type { InputsSpec } from '../../types' - import RunnableComponent from '../helpers/RunnableComponent.svelte' + import RunnableWrapper from '../helpers/RunnableWrapper.svelte' + import type { AppInput } from '../../inputType' + import InputValue from '../helpers/InputValue.svelte' export let id: string - export let inputs: InputsSpec - export let path: string | undefined = undefined - export let runType: 'script' | 'flow' | undefined = undefined - export let inlineScriptName: string | undefined = undefined + export let componentInput: AppInput | undefined + export let configuration: Record export const staticOutputs: string[] = ['loading', 'result'] @@ -35,43 +34,39 @@ ArcElement ) - let options = { + let result: ChartData<'bar', number[], unknown> | undefined = undefined + let labels: string[] = [] + let theme: string = 'theme1' + + $: backgroundColor = { + theme1: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], + // blue theme + theme2: ['#4e73df', '#1cc88a', '#36b9cc', '#f6c23e', '#e74a3b'], + // red theme + theme3: ['#e74a3b', '#4e73df', '#1cc88a', '#36b9cc', '#f6c23e'] + }[theme] + + const options = { responsive: true, animation: false } - let nextColor = 0 - - // TODO: Replace with nicer windmill branded color pallet. - const colors = ['#3b82f6', '#ff6384', '#4bc0c0', '#ff9f40', '#9966ff', '#ffcd56', '#c9cbcf'] - - function generateColor() { - const col = colors[nextColor] - nextColor = (nextColor + 1) % colors.length - return col - } - - let result: { name: string; value: number; color: string | undefined }[] | undefined = undefined - let data: ChartData<'pie', number[], string> | undefined = undefined - - $: if (Array.isArray(result)) { - nextColor = 0 - data = { - datasets: [ - { - data: result.map((x) => x.value), - backgroundColor: result.map((x) => x.color ?? generateColor()) - } - ], - labels: result.map((x) => x.name) - } - } else { - data = undefined + $: data = { + labels, + datasets: [ + { + data: result, + backgroundColor: backgroundColor + } + ] } - - {#if result} + + + + + {#if data} {/if} - + diff --git a/frontend/src/lib/components/apps/components/dataDisplay/AppTable.svelte b/frontend/src/lib/components/apps/components/dataDisplay/AppTable.svelte index 562c63b53f..e4f410ee58 100644 --- a/frontend/src/lib/components/apps/components/dataDisplay/AppTable.svelte +++ b/frontend/src/lib/components/apps/components/dataDisplay/AppTable.svelte @@ -3,18 +3,16 @@ import { classNames } from '$lib/utils' import { getContext } from 'svelte' import type { Output } from '../../rx' - import type { AppEditorContext, BaseAppComponent, ButtonComponent, InputsSpec } from '../../types' + import type { AppEditorContext, BaseAppComponent, ButtonComponent } from '../../types' import InputValue from '../helpers/InputValue.svelte' import DebouncedInput from '../helpers/DebouncedInput.svelte' - import RunnableComponent from '../helpers/RunnableComponent.svelte' import AppButton from '../buttons/AppButton.svelte' + import type { AppInput } from '../../inputType' + import RunnableWrapper from '../helpers/RunnableWrapper.svelte' export let id: string - export let inputs: InputsSpec - export let path: string | undefined = undefined - export let runType: 'script' | 'flow' | undefined = undefined - export let inlineScriptName: string | undefined = undefined - export let componentInputs: InputsSpec + export let componentInput: AppInput | undefined + export let configuration: Record export let actionButtons: (BaseAppComponent & ButtonComponent)[] const { worldStore, staticOutputs: staticOutputsStore } = @@ -38,7 +36,7 @@ } } - let searchEnabledValue: boolean | undefined = undefined + let searchConfiguration: 'Frontend' | 'Backend' | 'Disabled' = 'Disabled' let paginationEnabled: boolean | undefined = undefined let page = 1 @@ -50,22 +48,17 @@ const extraQueryParams = { search, page } export const reservedKeys: string[] = Object.keys(extraQueryParams) + + $: (searchConfiguration === 'Frontend' || searchConfiguration === 'Backend') && + (extraQueryParams.search = search) - - + + - +
- {#if searchEnabledValue} + {#if searchConfiguration !== 'Disabled'}
@@ -111,7 +104,7 @@ {/each} @@ -148,4 +141,4 @@
{/if}
- + diff --git a/frontend/src/lib/components/apps/components/dataDisplay/AppText.svelte b/frontend/src/lib/components/apps/components/dataDisplay/AppText.svelte index f055062b0e..9043a2473f 100644 --- a/frontend/src/lib/components/apps/components/dataDisplay/AppText.svelte +++ b/frontend/src/lib/components/apps/components/dataDisplay/AppText.svelte @@ -1,20 +1,27 @@ - - - - - + + + {#if result === ''} +
+ No text +
+ {:else} + + {/if} +
+
diff --git a/frontend/src/lib/components/apps/components/dataDisplay/app.md b/frontend/src/lib/components/apps/components/dataDisplay/app.md new file mode 100644 index 0000000000..d9e61f4d10 --- /dev/null +++ b/frontend/src/lib/components/apps/components/dataDisplay/app.md @@ -0,0 +1,49 @@ +- Input () => any + + - text field + - Checkbox + - select + +- Display: (data: Static | Connect | Result, configuration: List) => Outputs + + - Table : + actions: List +
+ + + + {/if}