improve app editor behavior when hiding right panel

This commit is contained in:
Ruben Fiszel
2024-12-21 00:37:08 +01:00
parent cfdd7d13f9
commit c1d11ce044
6 changed files with 104 additions and 113 deletions
@@ -30,10 +30,10 @@
import ItemPicker from '$lib/components/ItemPicker.svelte'
import VariableEditor from '$lib/components/VariableEditor.svelte'
import { VariableService, type Job, type Policy } from '$lib/gen'
import { VariableService, type Policy } from '$lib/gen'
import { initHistory } from '$lib/history'
import { Component, Minus, Paintbrush, Plus, Smartphone, Scan, Hand, Grab } from 'lucide-svelte'
import { findGridItem, findGridItemParentGrid } from './appUtils'
import { animateTo, findGridItem, findGridItemParentGrid } from './appUtils'
import ComponentNavigation from './component/ComponentNavigation.svelte'
import CssSettings from './componentsPanel/CssSettings.svelte'
import SettingsPanel from './SettingsPanel.svelte'
@@ -49,7 +49,6 @@
import { getTheme } from './componentsPanel/themeUtils'
import StylePanel from './settingsPanel/StylePanel.svelte'
import type DiffDrawer from '$lib/components/DiffDrawer.svelte'
import RunnableJobPanel from './RunnableJobPanel.svelte'
import HideButton from './settingsPanel/HideButton.svelte'
import AppEditorBottomPanel from './AppEditorBottomPanel.svelte'
import panzoom from 'panzoom'
@@ -386,27 +385,6 @@
}
}
function animateTo(start: number, end: number, onUpdate: (newValue: number) => void) {
const duration = 400
const startTime = performance.now()
function animate(time: number) {
const elapsed = time - startTime
const progress = Math.min(elapsed / duration, 1)
const currentValue = start + (end - start) * easeInOut(progress)
onUpdate(currentValue)
if (progress < 1) {
requestAnimationFrame(animate)
}
}
requestAnimationFrame(animate)
}
function easeInOut(t: number) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
}
$: $cssEditorOpen && selectCss()
function selectCss() {
@@ -583,13 +561,11 @@
} else {
leftPanelSize = storedLeftPanelSize
}
storedLeftPanelSize = 0
}
function showRightPanel() {
rightPanelSize = storedRightPanelSize
centerPanelSize = centerPanelSize - storedRightPanelSize
storedRightPanelSize = 0
}
function showBottomPanel(animate: boolean = false) {
@@ -611,7 +587,6 @@
runnablePanelSize = storedBottomPanelSize
gridPanelSize = gridPanelSize - storedBottomPanelSize
}
storedBottomPanelSize = 0
}
function keydown(event: KeyboardEvent) {
@@ -705,9 +680,6 @@
$: $connectingInput.opened, updatePannelInConnecting()
let testJob: Job | undefined = undefined
let jobToWatch: { componentId: string; job: string } | undefined = undefined
$: updateCursorStyle(!!$connectingInput.opened && !$panzoomActive)
function updateCursorStyle(disabled: boolean) {
@@ -1125,14 +1097,7 @@
{rightPanelSize}
{centerPanelWidth}
{runnablePanelSize}
>
<RunnableJobPanel
float={rightPanelSize !== 0}
hidden={runnablePanelSize === 0}
bind:testJob
bind:jobToWatch
/>
</AppEditorBottomPanel>
/>
</Pane>
{/if}
</Splitpanes>
@@ -1,5 +1,4 @@
<script lang="ts">
import { twMerge } from 'tailwind-merge'
import InlineScriptsPanel from './inlineScriptsPanel/InlineScriptsPanel.svelte'
import RunnableJobPanel from './RunnableJobPanel.svelte'
@@ -10,15 +9,13 @@
{#if rightPanelSize !== 0}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div class={twMerge('relative h-full w-full overflow-x-visible')} on:mouseenter on:mouseleave>
<div class="relative h-full w-full overflow-x-visible" on:mouseenter on:mouseleave>
<InlineScriptsPanel on:hidePanel />
<RunnableJobPanel hidden={runnablePanelSize === 0} />
<slot />
</div>
{:else}
<div class="flex flex-row relative w-full h-full">
<InlineScriptsPanel width={centerPanelWidth - 400} on:hidePanel />
<slot />
<InlineScriptsPanel width={centerPanelWidth * 0.66} on:hidePanel />
<RunnableJobPanel float={false} hidden={runnablePanelSize === 0} />
</div>
{/if}
@@ -9,6 +9,7 @@
export let hidden: boolean = false
export let testJob: Job | undefined = undefined
export let jobToWatch: { componentId: string; job: string } | undefined = undefined
export let width: number | undefined = undefined
const { runnableJobEditorPanel, selectedComponentInEditor } =
getContext<AppEditorContext>('AppEditorContext')
@@ -16,7 +17,7 @@
let testJobLoader: TestJobLoader
$: $runnableJobEditorPanel.focused &&
$: ($runnableJobEditorPanel.focused || !float) &&
$selectedComponentInEditor &&
$runnableJobEditorPanel.jobs &&
updateSelectedJob()
@@ -59,7 +60,10 @@
<RunnableJobPanelInner {testIsLoading} {frontendJob} {testJob} />
</div>
{:else}
<div class="flex flex-col w-full">
<div
class="flex flex-col min-w-0 grow h-full"
style={width !== undefined ? `width:${width}px;` : ''}
>
{#if $selectedComponentInEditor}
<RunnableJobPanelInner {testIsLoading} {frontendJob} {testJob} />
{:else if !hidden}
@@ -1281,3 +1281,24 @@ export function areShadowsTheSame(
shadow1.h === shadow2.h
)
}
export function animateTo(start: number, end: number, onUpdate: (newValue: number) => void) {
const duration = 400
const startTime = performance.now()
function animate(time: number) {
const elapsed = time - startTime
const progress = Math.min(elapsed / duration, 1)
const currentValue = start + (end - start) * easeInOut(progress)
onUpdate(currentValue)
if (progress < 1) {
requestAnimationFrame(animate)
}
}
requestAnimationFrame(animate)
}
function easeInOut(t: number) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
}
@@ -1,7 +1,6 @@
<script lang="ts">
import { getContext } from 'svelte'
import type { AppEditorContext, AppViewerContext, HiddenRunnable } from '../../types'
import SplitPanesWrapper from '$lib/components/splitPanes/SplitPanesWrapper.svelte'
import { Pane, Splitpanes } from 'svelte-splitpanes'
import InlineScriptsPanelList from './InlineScriptsPanelList.svelte'
import InlineScriptEditor from './InlineScriptEditor.svelte'
@@ -105,60 +104,58 @@
export let width: number | undefined = undefined
</script>
<SplitPanesWrapper>
<Splitpanes
class={twMerge('!overflow-visible')}
style={width !== undefined ? `width:${width}px;` : ''}
>
<Pane size={25}>
<InlineScriptsPanelList on:hidePanel />
</Pane>
<Pane size={75}>
{#if !$selectedComponentInEditor}
<div class="text-sm text-secondary text-center py-8 px-2">
Select a script on the left panel
</div>
{:else if gridItem}
{#key gridItem?.id}
<InlineScriptsPanelWithTable
<Splitpanes
class={twMerge('!overflow-visible')}
style={width !== undefined ? `width:${width}px;` : 'width: 100%;'}
>
<Pane size={25}>
<InlineScriptsPanelList on:hidePanel />
</Pane>
<Pane size={75}>
{#if !$selectedComponentInEditor}
<div class="text-sm text-secondary text-center py-8 px-2">
Select a script on the left panel
</div>
{:else if gridItem}
{#key gridItem?.id}
<InlineScriptsPanelWithTable
on:createScriptFromInlineScript={(e) => {
createScriptFromInlineScript(gridItem?.id ?? 'unknown', e.detail)
}}
bind:gridItem
/>
{/key}
{:else if unusedInlineScript > -1 && $app.unusedInlineScripts?.[unusedInlineScript]}
{#key unusedInlineScript}
<InlineScriptEditor
on:createScriptFromInlineScript={() =>
sendUserToast('Cannot save to workspace unused scripts', true)}
id={`unused-${unusedInlineScript}`}
bind:name={$app.unusedInlineScripts[unusedInlineScript].name}
bind:inlineScript={$app.unusedInlineScripts[unusedInlineScript].inlineScript}
on:delete={() => {
// remove the script from the array at the index
$app.unusedInlineScripts.splice(unusedInlineScript, 1)
$app.unusedInlineScripts = [...$app.unusedInlineScripts]
}}
/>
{/key}
{:else if hiddenInlineScript > -1}
{#key hiddenInlineScript}
{#if $app.hiddenInlineScripts?.[hiddenInlineScript]}
<InlineScriptHiddenRunnable
on:createScriptFromInlineScript={(e) => {
createScriptFromInlineScript(gridItem?.id ?? 'unknown', e.detail)
createScriptFromInlineScript(BG_PREFIX + hiddenInlineScript, e.detail)
}}
bind:gridItem
/>
{/key}
{:else if unusedInlineScript > -1 && $app.unusedInlineScripts?.[unusedInlineScript]}
{#key unusedInlineScript}
<InlineScriptEditor
on:createScriptFromInlineScript={() =>
sendUserToast('Cannot save to workspace unused scripts', true)}
id={`unused-${unusedInlineScript}`}
bind:name={$app.unusedInlineScripts[unusedInlineScript].name}
bind:inlineScript={$app.unusedInlineScripts[unusedInlineScript].inlineScript}
on:delete={() => {
// remove the script from the array at the index
$app.unusedInlineScripts.splice(unusedInlineScript, 1)
$app.unusedInlineScripts = [...$app.unusedInlineScripts]
}}
/>
{/key}
{:else if hiddenInlineScript > -1}
{#key hiddenInlineScript}
{#if $app.hiddenInlineScripts?.[hiddenInlineScript]}
<InlineScriptHiddenRunnable
on:createScriptFromInlineScript={(e) => {
createScriptFromInlineScript(BG_PREFIX + hiddenInlineScript, e.detail)
}}
transformer={$selectedComponentInEditor?.endsWith('_transformer')}
on:delete={() => deleteBackgroundScript(hiddenInlineScript)}
id={BG_PREFIX + hiddenInlineScript}
bind:runnable={$app.hiddenInlineScripts[hiddenInlineScript]}
/>{/if}{/key}
{:else}
<div class="text-sm text-tertiary text-center py-8 px-2">
No script found at id {$selectedComponentInEditor}
</div>
{/if}
</Pane>
</Splitpanes>
</SplitPanesWrapper>
transformer={$selectedComponentInEditor?.endsWith('_transformer')}
on:delete={() => deleteBackgroundScript(hiddenInlineScript)}
id={BG_PREFIX + hiddenInlineScript}
bind:runnable={$app.hiddenInlineScripts[hiddenInlineScript]}
/>{/if}{/key}
{:else}
<div class="text-sm text-tertiary text-center py-8 px-2">
No script found at id {$selectedComponentInEditor}
</div>
{/if}
</Pane>
</Splitpanes>
@@ -18,13 +18,18 @@
export let defaultUserInput = false
export let hideCreateScript = false
export let onlyFlow = false
let tab: Tab = onlyFlow ? 'workspaceflows' : 'inlinescripts'
let filter: string = ''
let picker: Drawer
export let rawApps = false
const { app, workspace } = getContext<AppViewerContext>('AppViewerContext')
let tab: Tab = onlyFlow
? 'workspaceflows'
: $app?.unusedInlineScripts?.length > 0
? 'inlinescripts'
: 'workspacescripts'
let filter: string = ''
let picker: Drawer
const dispatch = createEventDispatcher<{
pick: {
runnable: Runnable
@@ -138,15 +143,17 @@
<div class="max-w-6xl">
<Tabs bind:selected={tab}>
{#if !onlyFlow}
<Tab size="sm" value="inlinescripts">
<div class="flex gap-2 items-center my-1">
<Building size={18} strokeWidth={1.5} />
Detached Inline Scripts
</div>
</Tab>
{#if !rawApps}
<Tab size="sm" value="inlinescripts">
<div class="flex gap-2 items-center my-1">
<Building size={18} strokeWidth={1.5} />
Detached Inline Scripts
</div>
</Tab>
{/if}
<Tab size="sm" value="workspacescripts">
<div class="flex gap-2 items-center my-1">
<Building size={18} strokeWidth={1.5}/>
<Building size={18} strokeWidth={1.5} />
Workspace Scripts
</div>
</Tab>