diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index 72a83f02e1..716fcbfa91 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -28,12 +28,10 @@ import ComponentList from './componentsPanel/ComponentList.svelte' import ContextPanel from './contextPanel/ContextPanel.svelte' - import InlineScriptsPanel from './inlineScriptsPanel/InlineScriptsPanel.svelte' - import { page } from '$app/stores' import ItemPicker from '$lib/components/ItemPicker.svelte' import VariableEditor from '$lib/components/VariableEditor.svelte' - import { VariableService, type Policy } from '$lib/gen' + import { VariableService, type Job, type Policy } from '$lib/gen' import { initHistory } from '$lib/history' import { Component, Minus, Paintbrush, Plus, Smartphone } from 'lucide-svelte' import { findGridItem, findGridItemParentGrid } from './appUtils' @@ -56,6 +54,8 @@ import type DiffDrawer from '$lib/components/DiffDrawer.svelte' import RunnableJobPanel from './RunnableJobPanel.svelte' import { goto, replaceState } from '$app/navigation' + import HideButton from './settingsPanel/HideButton.svelte' + import AppEditorBottomPanel from './AppEditorBottomPanel.svelte' export let app: App export let path: string @@ -311,7 +311,7 @@ let gridPanelSize = 70 let leftPanelSize = 22 - let centerPanelSize = 63 + let centerPanelSize = 56 let rightPanelSize = 22 let tmpRunnablePanelSize = -1 @@ -540,11 +540,105 @@ let runnableJobEnterTimeout: NodeJS.Timeout | undefined = undefined let stillInJobEnter = false + let storedLeftPanelSize = 0 + let storedRightPanelSize = 0 + let storedBottomPanelSize = 0 + + let centerPanelWidth = 0 + + function hideLeftPanel() { + storedLeftPanelSize = leftPanelSize + leftPanelSize = 0 + centerPanelSize = centerPanelSize + storedLeftPanelSize + } + + function hideRightPanel() { + storedRightPanelSize = rightPanelSize + rightPanelSize = 0 + centerPanelSize = centerPanelSize + storedRightPanelSize + } + + function hideBottomPanel() { + storedBottomPanelSize = runnablePanelSize + gridPanelSize = 99 + runnablePanelSize = 0 + } + + function showLeftPanel() { + leftPanelSize = storedLeftPanelSize + centerPanelSize = centerPanelSize - storedLeftPanelSize + storedLeftPanelSize = 0 + } + + function showRightPanel() { + rightPanelSize = storedRightPanelSize + centerPanelSize = centerPanelSize - storedRightPanelSize + storedRightPanelSize = 0 + } + + function showBottomPanel() { + runnablePanelSize = storedBottomPanelSize + gridPanelSize = gridPanelSize - storedBottomPanelSize + storedBottomPanelSize = 0 + } + + function keydown(event: KeyboardEvent) { + let classes = event.target?.['className'] + if ( + (typeof classes === 'string' && classes.includes('inputarea')) || + ['INPUT', 'TEXTAREA'].includes(document.activeElement?.tagName!) + ) { + return + } + + switch (event.key) { + case 'b': { + if (event.ctrlKey || event.metaKey) { + event.preventDefault() + + if (leftPanelSize !== 0) { + hideLeftPanel() + } else { + showLeftPanel() + } + } + break + } + + case 'u': { + if (event.ctrlKey || event.metaKey) { + event.preventDefault() + + if (rightPanelSize !== 0) { + hideRightPanel() + } else { + showRightPanel() + } + } + break + } + + case 'l': { + if (event.ctrlKey || event.metaKey) { + event.preventDefault() + + if (runnablePanelSize !== 0) { + hideBottomPanel() + } else { + showBottomPanel() + } + } + break + } + } + } + let testJob: Job | undefined = undefined + let jobToWatch: { componentId: string; job: string } | undefined = undefined - + {#if !$userStore?.operator} {#if $appStore} @@ -556,6 +650,15 @@ {diffDrawer} bind:savedApp {version} + leftPanelHidden={leftPanelSize === 0} + rightPanelHidden={rightPanelSize === 0} + bottomPanelHidden={runnablePanelSize === 0} + on:showLeftPanel={() => showLeftPanel()} + on:showRightPanel={() => showRightPanel()} + on:hideLeftPanel={() => hideLeftPanel()} + on:hideRightPanel={() => hideRightPanel()} + on:hideBottomPanel={() => hideBottomPanel()} + on:showBottomPanel={() => showBottomPanel()} /> {#if $mode === 'preview'} @@ -601,7 +704,7 @@ - + hideLeftPanel()} /> @@ -618,7 +721,39 @@ 'wm-app-viewer h-full overflow-visible' )} style={$appStore.css?.['app']?.['viewer']?.style} + bind:clientWidth={centerPanelWidth} > + {#if leftPanelSize === 0} + + showLeftPanel()} + direction="right" + hidden + btnClasses="border bg-surface" + /> + + {/if} + {#if rightPanelSize === 0} + + showRightPanel()} + direction="left" + hidden + btnClasses="border bg-surface" + /> + + {/if} + {#if runnablePanelSize === 0} + + showBottomPanel()} + direction="bottom" + hidden + btnClasses="border bg-surface" + /> + + {/if} + {#if $connectingInput?.opened == false && !$componentActive} - - { runnableJobEnterTimeout && clearTimeout(runnableJobEnterTimeout) stillInJobEnter = true @@ -718,6 +851,7 @@ } }, 200) }} + on:hidePanel={() => hideBottomPanel()} on:mouseleave={() => { stillInJobEnter = false runnableJobEnterTimeout = setTimeout( @@ -725,98 +859,119 @@ 200 ) }} + {rightPanelSize} + {centerPanelWidth} + {runnablePanelSize} > - - - + + {/if} - - - - - Component library - { - if ($cssEditorOpen) { - $cssEditorOpen = false - selectedTab = 'insert' - } - }} - id="app-editor-component-library-tab" - > - - - - - - - Component settings - { - if ($cssEditorOpen) { - $cssEditorOpen = false - selectedTab = 'settings' - } - }} - > - - - - - - - Global styling - { - if (!$cssEditorOpen) { - $cssEditorOpen = true - selectedTab = 'css' - } - }} - > - - - - - - - - {#if $selectedComponent !== undefined} - { - befSelected = undefined + {#if rightPanelSize === 0} + + {:else} + + + + + Component library + { + if ($cssEditorOpen) { + $cssEditorOpen = false selectedTab = 'insert' - }} - /> - - {:else} - - Select a component to see the settings for it + } + }} + id="app-editor-component-library-tab" + > + + - {/if} - - - - - - - - - - - + + + + Component settings + { + if ($cssEditorOpen) { + $cssEditorOpen = false + selectedTab = 'settings' + } + }} + > + + + + + + + Global styling + { + if (!$cssEditorOpen) { + $cssEditorOpen = true + selectedTab = 'css' + } + }} + > + + + + + + + { + storedRightPanelSize = rightPanelSize + rightPanelSize = 0 + centerPanelSize = centerPanelSize + storedRightPanelSize + }} + direction="right" + /> + + + + {#if $selectedComponent !== undefined} + { + befSelected = undefined + selectedTab = 'insert' + }} + /> + + {:else} + + Select a component to see the settings for it + + {/if} + + + + + + + + + + + + {/if} {/if} diff --git a/frontend/src/lib/components/apps/editor/AppEditorBottomPanel.svelte b/frontend/src/lib/components/apps/editor/AppEditorBottomPanel.svelte new file mode 100644 index 0000000000..be46d46c81 --- /dev/null +++ b/frontend/src/lib/components/apps/editor/AppEditorBottomPanel.svelte @@ -0,0 +1,24 @@ + + +{#if rightPanelSize !== 0} + + + + + + +{:else} + + + + + +{/if} diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index dd3467df78..bd08c89810 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -33,7 +33,7 @@ Smartphone, FileClock } from 'lucide-svelte' - import { getContext } from 'svelte' + import { createEventDispatcher, getContext } from 'svelte' import { Pane, Splitpanes } from 'svelte-splitpanes' import { classNames, @@ -84,6 +84,7 @@ import { collectOneOfFields } from './appUtils' import Summary from '$lib/components/Summary.svelte' import ToggleEnable from '$lib/components/common/toggleButton-v2/ToggleEnable.svelte' + import HideButton from './settingsPanel/HideButton.svelte' async function hash(message) { try { @@ -116,6 +117,9 @@ } | undefined = undefined export let version: number | undefined = undefined + export let leftPanelHidden: boolean = false + export let rightPanelHidden: boolean = false + export let bottomPanelHidden: boolean = false const { app, @@ -126,7 +130,8 @@ jobsById, staticExporter, errorByComponent, - openDebugRun + openDebugRun, + mode } = getContext('AppViewerContext') const { history, jobsDrawerOpen, refreshComponents } = @@ -743,6 +748,8 @@ export function openTroubleshootPanel() { debugAppDrawerOpen = true } + + const dispatch = createEventDispatcher() @@ -1322,6 +1329,43 @@ + {#if $mode !== 'preview'} + + { + if (leftPanelHidden) { + dispatch('showLeftPanel') + } else { + dispatch('hideLeftPanel') + } + }} + /> + { + if (bottomPanelHidden) { + dispatch('showBottomPanel') + } else { + dispatch('hideBottomPanel') + } + }} + /> + { + if (rightPanelHidden) { + dispatch('showRightPanel') + } else { + dispatch('hideRightPanel') + } + }} + /> + + {/if} {#if $enterpriseLicense && appPath != ''} {/if} diff --git a/frontend/src/lib/components/apps/editor/RunnableJobPanel.svelte b/frontend/src/lib/components/apps/editor/RunnableJobPanel.svelte index afb545275c..2d8609205e 100644 --- a/frontend/src/lib/components/apps/editor/RunnableJobPanel.svelte +++ b/frontend/src/lib/components/apps/editor/RunnableJobPanel.svelte @@ -1,21 +1,21 @@ + + + + {#if frontendJob} + + Frontend Job + Check your browser console to see the logs + + {:else} + + {/if} + + + {#if frontendJob} + + + + {:else if testJob != undefined && 'result' in testJob && testJob.result != undefined} + + + {:else} + + {#if testIsLoading} + + {:else} + Test to see the result here + {/if} + + {/if} + + diff --git a/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte b/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte index 07539f0a21..f1b7502d9d 100644 --- a/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte +++ b/frontend/src/lib/components/apps/editor/contextPanel/ContextPanel.svelte @@ -1,6 +1,6 @@ + { + dispatch('hidePanel') + }} + direction="left" + /> diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte index 6b903f461e..a56b454c20 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte @@ -14,6 +14,7 @@ import { ScriptService } from '$lib/gen' import { workspaceStore } from '$lib/stores' import { findNextAvailablePath } from '$lib/path' + import { twMerge } from 'tailwind-merge' const { app, runnableComponents } = getContext('AppViewerContext') const { selectedComponentInEditor } = getContext('AppEditorContext') @@ -100,12 +101,17 @@ $app = $app } + + export let width: number | undefined = undefined - + - + {#if !$selectedComponentInEditor} diff --git a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte index 422f0e01e2..c7eddb2ea8 100644 --- a/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +++ b/frontend/src/lib/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte @@ -1,7 +1,7 @@ - + + { + dispatch('hidePanel') + }} + /> + + diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/HideButton.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/HideButton.svelte new file mode 100644 index 0000000000..a4f0c1cfb1 --- /dev/null +++ b/frontend/src/lib/components/apps/editor/settingsPanel/HideButton.svelte @@ -0,0 +1,52 @@ + + + + + + {hidden ? 'Show' : 'Hide '} the {direction} panel. + + + {getModifierKey()}{shortcuts[direction]} + + + + +