context panel refactor
This commit is contained in:
@@ -171,6 +171,7 @@
|
||||
updateRegionOutput()
|
||||
|
||||
if (z) {
|
||||
//@ts-ignore
|
||||
gridItem.data.configuration.zoom.value = z
|
||||
}
|
||||
|
||||
@@ -180,7 +181,9 @@
|
||||
}
|
||||
|
||||
if (gridItem) {
|
||||
//@ts-ignore
|
||||
gridItem.data.configuration.longitude.value = center[0]
|
||||
//@ts-ignore
|
||||
gridItem.data.configuration.latitude.value = center[1]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,9 @@
|
||||
function syncZoomValue() {
|
||||
const gridItem = findGridItem($app, id)
|
||||
|
||||
//@ts-ignore
|
||||
if (gridItem && gridItem.data.configuration.zoom.value !== zoom) {
|
||||
//@ts-ignore
|
||||
gridItem.data.configuration.zoom.value = zoom
|
||||
}
|
||||
|
||||
|
||||
@@ -351,6 +351,4 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-full h-full" />
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, setContext } from 'svelte'
|
||||
import { setContext } from 'svelte'
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
import { buildWorld, type World } from '../rx'
|
||||
import { buildWorld } from '../rx'
|
||||
import type {
|
||||
App,
|
||||
AppEditorContext,
|
||||
@@ -10,11 +10,16 @@
|
||||
EditorBreakpoint,
|
||||
EditorMode
|
||||
} from '../types'
|
||||
import GridEditor from './GridEditor.svelte'
|
||||
import { classNames } from '$lib/utils'
|
||||
import type { Policy } from '$lib/gen'
|
||||
import Button from '../../common/button/Button.svelte'
|
||||
import { Unlock } from 'lucide-svelte'
|
||||
import RecomputeAllComponents from './RecomputeAllComponents.svelte'
|
||||
import GridViewer from './GridViewer.svelte'
|
||||
import { Component } from './component'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { columnConfiguration } from '../gridUtils'
|
||||
import { HiddenComponent } from '../components'
|
||||
|
||||
export let app: App
|
||||
export let appPath: string
|
||||
@@ -28,7 +33,6 @@
|
||||
export let isLocked = false
|
||||
|
||||
const appStore = writable<App>(app)
|
||||
const worldStore = writable<World | undefined>(undefined)
|
||||
const selectedComponent = writable<string | undefined>(undefined)
|
||||
const mode = writable<EditorMode>('preview')
|
||||
|
||||
@@ -40,6 +44,7 @@
|
||||
|
||||
const runnableComponents = writable<Record<string, () => Promise<void>>>({})
|
||||
|
||||
const parentWidth = writable(0)
|
||||
setContext<AppViewerContext>('AppViewerContext', {
|
||||
worldStore: buildWorld(context),
|
||||
app: appStore,
|
||||
@@ -60,7 +65,7 @@
|
||||
openDebugRun: writable(undefined),
|
||||
focusedGrid: writable(undefined),
|
||||
stateId: writable(0),
|
||||
parentWidth: writable(0),
|
||||
parentWidth,
|
||||
state: writable({}),
|
||||
componentControl: writable({})
|
||||
})
|
||||
@@ -70,12 +75,6 @@
|
||||
pickVariableCallback: writable(undefined)
|
||||
})
|
||||
|
||||
let mounted = false
|
||||
|
||||
onMount(() => {
|
||||
mounted = true
|
||||
})
|
||||
|
||||
let ncontext = context
|
||||
|
||||
function hashchange(e: HashChangeEvent) {
|
||||
@@ -98,9 +97,48 @@
|
||||
>
|
||||
{#if $appStore.grid}
|
||||
<div class={classNames('mx-auto', width)}>
|
||||
<GridEditor {policy} />
|
||||
<div
|
||||
class="w-full sticky top-0 flex justify-between border-b bg-gray-50 px-4 py-1 items-center gap-4"
|
||||
style="z-index: 1000;"
|
||||
>
|
||||
<h2 class="truncate">{summary}</h2>
|
||||
<RecomputeAllComponents />
|
||||
<div class="text-2xs text-gray-600">
|
||||
{policy.on_behalf_of ? `on behalf of ${policy.on_behalf_of_email}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div
|
||||
style={app.css?.['app']?.['grid']?.style}
|
||||
class={twMerge('px-4 pt-4 pb-2 overflow-visible', app.css?.['app']?.['grid']?.class ?? '')}
|
||||
bind:clientWidth={$parentWidth}
|
||||
>
|
||||
<div>
|
||||
<GridViewer
|
||||
onTopId={$selectedComponent}
|
||||
items={app.grid}
|
||||
let:dataItem
|
||||
rowHeight={36}
|
||||
cols={columnConfiguration}
|
||||
gap={[4, 2]}
|
||||
>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class={'h-full w-full center-center'}
|
||||
on:pointerdown={() => ($selectedComponent = dataItem.data.id)}
|
||||
>
|
||||
<Component
|
||||
render={true}
|
||||
pointerdown={false}
|
||||
component={dataItem.data}
|
||||
selected={false}
|
||||
locked={true}
|
||||
/>
|
||||
</div>
|
||||
</GridViewer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if isLocked}
|
||||
@@ -116,3 +154,17 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if app.hiddenInlineScripts}
|
||||
{#each app.hiddenInlineScripts as script, index}
|
||||
{#if script}
|
||||
<HiddenComponent
|
||||
id={`bg_${index}`}
|
||||
inlineScript={script.inlineScript}
|
||||
name={script.name}
|
||||
fields={script.fields}
|
||||
autoRefresh={script.autoRefresh ?? false}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { getContext, afterUpdate } from 'svelte'
|
||||
import type { App, AppEditorContext, AppViewerContext, GridItem } from '../types'
|
||||
import type { App, AppEditorContext, AppViewerContext } from '../types'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { columnConfiguration, disableDrag, enableDrag, isFixed, toggleFixed } from '../gridUtils'
|
||||
import { columnConfiguration, isFixed, toggleFixed } from '../gridUtils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
import RecomputeAllComponents from './RecomputeAllComponents.svelte'
|
||||
@@ -11,7 +11,7 @@
|
||||
import Component from './component/Component.svelte'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import { push } from '$lib/history'
|
||||
import { expandGriditem, findGridItem, sortGridItemsPosition } from './appUtils'
|
||||
import { expandGriditem, findGridItem } from './appUtils'
|
||||
import Grid from '../svelte-grid/Grid.svelte'
|
||||
|
||||
export let policy: Policy
|
||||
@@ -30,31 +30,6 @@
|
||||
|
||||
const { history } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
// The drag is disabled when the user is connecting an input
|
||||
// or when the user is previewing the app
|
||||
// or when the focused grid is a subgrid
|
||||
$: setAllDrags($mode === 'preview' || $connectingInput.opened)
|
||||
|
||||
function setAllDrags(enable: boolean) {
|
||||
const fct = enable ? disableDrag : enableDrag
|
||||
|
||||
$app.grid.map((gridItem) => {
|
||||
const disabledGridItem = fct(gridItem)
|
||||
|
||||
if (disabledGridItem?.data?.subGrids) {
|
||||
disabledGridItem.data.subGrids = disabledGridItem.data.subGrids.map(
|
||||
(subgrid: GridItem[]) => subgrid?.map((subgridItem: GridItem) => fct(subgridItem)) ?? []
|
||||
)
|
||||
}
|
||||
|
||||
return disabledGridItem
|
||||
})
|
||||
|
||||
Object.values($app.subgrids ?? {}).map(
|
||||
(subgrid: GridItem[]) => subgrid?.map((subgridItem: GridItem) => fct(subgridItem)) ?? []
|
||||
)
|
||||
}
|
||||
|
||||
function removeGridElement(component) {
|
||||
if (component) {
|
||||
$app.grid = $app.grid.filter((gridComponent) => {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
bind:component={actionButton}
|
||||
duplicateMoveAllowed={false}
|
||||
onDelete={() => {
|
||||
//@ts-ignore
|
||||
gridItem.data.actionButtons = gridItem.data.actionButtons.filter(
|
||||
(c) => c.id !== actionButton.id
|
||||
)
|
||||
|
||||
104
frontend/src/lib/components/apps/editor/GridViewer.svelte
Normal file
104
frontend/src/lib/components/apps/editor/GridViewer.svelte
Normal file
@@ -0,0 +1,104 @@
|
||||
<script lang="ts">
|
||||
import { onMount, createEventDispatcher } from 'svelte'
|
||||
|
||||
import type { FilledItem } from '../svelte-grid/types'
|
||||
import GridViewerComponent from './GridViewerComponent.svelte'
|
||||
import { getColumn, throttle } from '../svelte-grid/utils/other'
|
||||
import { getContainerHeight } from '../svelte-grid/utils/container'
|
||||
import { specifyUndefinedColumns } from '../svelte-grid/utils/item'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
type T = $$Generic
|
||||
|
||||
export let items: FilledItem<T>[]
|
||||
export let rowHeight: number
|
||||
export let cols: [number, number][]
|
||||
export let gap = [10, 10]
|
||||
export let throttleUpdate = 100
|
||||
|
||||
export let onTopId: string | undefined = undefined
|
||||
export let containerWidth: number | undefined = undefined
|
||||
|
||||
export let parentWidth: number | undefined = undefined
|
||||
|
||||
let getComputedCols
|
||||
|
||||
let container
|
||||
|
||||
$: [gapX, gapY] = gap
|
||||
|
||||
let xPerPx = 0
|
||||
let yPerPx = rowHeight
|
||||
|
||||
$: containerHeight = getContainerHeight(items, yPerPx, getComputedCols)
|
||||
|
||||
const onResize = throttle(() => {
|
||||
items = specifyUndefinedColumns(items, getComputedCols, cols)
|
||||
dispatch('resize', {
|
||||
cols: getComputedCols,
|
||||
xPerPx,
|
||||
yPerPx,
|
||||
width: containerWidth
|
||||
})
|
||||
}, throttleUpdate)
|
||||
|
||||
onMount(() => {
|
||||
const sizeObserver = new ResizeObserver((entries) => {
|
||||
requestAnimationFrame(() => {
|
||||
let width = entries[0].contentRect.width
|
||||
|
||||
if (width === containerWidth) return
|
||||
|
||||
getComputedCols = getColumn(parentWidth ?? width, cols)
|
||||
|
||||
xPerPx = width / getComputedCols
|
||||
|
||||
if (!containerWidth) {
|
||||
items = specifyUndefinedColumns(items, getComputedCols, cols)
|
||||
|
||||
dispatch('mount', {
|
||||
cols: getComputedCols,
|
||||
xPerPx,
|
||||
yPerPx // same as rowHeight
|
||||
})
|
||||
} else {
|
||||
onResize()
|
||||
}
|
||||
|
||||
containerWidth = width
|
||||
})
|
||||
})
|
||||
|
||||
sizeObserver.observe(container)
|
||||
|
||||
return () => sizeObserver.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="svlt-grid-container" style="height: {containerHeight}px" bind:this={container}>
|
||||
{#if xPerPx}
|
||||
{#each items as item (item.id)}
|
||||
<GridViewerComponent
|
||||
onTop={item.id == onTopId}
|
||||
width={Math.min(getComputedCols, item[getComputedCols] && item[getComputedCols].w) *
|
||||
xPerPx -
|
||||
gapX * 2}
|
||||
height={(item[getComputedCols] && item[getComputedCols].h) * yPerPx - gapY * 2}
|
||||
top={(item[getComputedCols] && item[getComputedCols].y) * yPerPx + gapY}
|
||||
left={(item[getComputedCols] && item[getComputedCols].x) * xPerPx + gapX}
|
||||
>
|
||||
{#if item[getComputedCols]}
|
||||
<slot dataItem={item} item={item[getComputedCols]} />
|
||||
{/if}
|
||||
</GridViewerComponent>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svlt-grid-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
export let width: number
|
||||
export let height: number
|
||||
export let left: number
|
||||
export let top: number
|
||||
|
||||
export let onTop: boolean
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="svlt-grid-item"
|
||||
style="width: {width}px; height:{height}px; {onTop ? 'z-index: 100;' : ''}
|
||||
{`transition: transform 0.1s, opacity 0.1s; transform: translate(${left}px, ${top}px); `}"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.svlt-grid-item {
|
||||
touch-action: none;
|
||||
position: absolute;
|
||||
will-change: auto;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,7 @@
|
||||
import { expandGriditem, findGridItem, sortGridItemsPosition } from './appUtils'
|
||||
import { push } from '$lib/history'
|
||||
import Grid from '../svelte-grid/Grid.svelte'
|
||||
import GridViewer from './GridViewer.svelte'
|
||||
|
||||
export let containerHeight: number
|
||||
export let containerWidth: number | undefined = undefined
|
||||
@@ -89,46 +90,85 @@
|
||||
on:pointerup={onpointerup}
|
||||
style="height: {containerHeight}px; {style ?? ''}"
|
||||
>
|
||||
<div class={highlight && $mode !== 'preview' ? 'border-gray-400 border border-dashed' : ''}>
|
||||
<Grid
|
||||
{#if $mode !== 'preview'}
|
||||
<div class={highlight ? 'border-gray-400 border border-dashed' : ''}>
|
||||
<Grid
|
||||
items={subGrid}
|
||||
on:redraw={(e) => {
|
||||
push(history, $app)
|
||||
subGrid = e.detail
|
||||
}}
|
||||
let:dataItem
|
||||
rowHeight={36}
|
||||
cols={columnConfiguration}
|
||||
fastStart={true}
|
||||
gap={[4, 2]}
|
||||
scroller={container}
|
||||
parentWidth={$parentWidth - 17}
|
||||
{containerWidth}
|
||||
>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
{#if $connectingInput.opened}
|
||||
<div
|
||||
on:pointerenter={() => ($connectingInput.hoveredComponent = dataItem.data.id)}
|
||||
on:pointerleave={() => ($connectingInput.hoveredComponent = undefined)}
|
||||
class="absolute w-full h-full bg-black border-2 bg-opacity-25 z-20 flex justify-center items-center"
|
||||
/>
|
||||
<div
|
||||
style="transform: translate(-50%, -50%);"
|
||||
class="absolute w-fit justify-center bg-indigo-500/90 left-[50%] top-[50%] z-50 px-6 rounded border text-white py-2 text-5xl center-center"
|
||||
>
|
||||
{dataItem.data.id}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
on:pointerdown={() => selectComponent(dataItem.data.id)}
|
||||
class={classNames(
|
||||
'h-full w-full center-center',
|
||||
$selectedComponent === dataItem.data.id ? 'active-grid-item' : '',
|
||||
dataItem.data.card ? 'border border-gray-100' : '',
|
||||
'top-0'
|
||||
)}
|
||||
>
|
||||
<Component
|
||||
render={visible}
|
||||
{pointerdown}
|
||||
component={dataItem.data}
|
||||
selected={$selectedComponent === dataItem.data.id}
|
||||
locked={isFixed(dataItem)}
|
||||
on:lock={() => lock(dataItem)}
|
||||
on:expand={() => {
|
||||
const parentGridItem = findGridItem($app, id)
|
||||
|
||||
if (!parentGridItem) {
|
||||
return
|
||||
}
|
||||
$selectedComponent = dataItem.data.id
|
||||
push(history, $app)
|
||||
|
||||
expandGriditem(subGrid, dataItem, $breakpoint, parentGridItem)
|
||||
$app = $app
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
</div>
|
||||
{:else}
|
||||
<GridViewer
|
||||
items={subGrid}
|
||||
on:redraw={(e) => {
|
||||
push(history, $app)
|
||||
subGrid = e.detail
|
||||
}}
|
||||
let:dataItem
|
||||
rowHeight={36}
|
||||
cols={columnConfiguration}
|
||||
fastStart={true}
|
||||
gap={[4, 2]}
|
||||
scroller={container}
|
||||
parentWidth={$parentWidth - 17}
|
||||
{containerWidth}
|
||||
>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
{#if $connectingInput.opened}
|
||||
<div
|
||||
on:pointerenter={() => ($connectingInput.hoveredComponent = dataItem.data.id)}
|
||||
on:pointerleave={() => ($connectingInput.hoveredComponent = undefined)}
|
||||
class="absolute w-full h-full bg-black border-2 bg-opacity-25 z-20 flex justify-center items-center"
|
||||
/>
|
||||
<div
|
||||
style="transform: translate(-50%, -50%);"
|
||||
class="absolute w-fit justify-center bg-indigo-500/90 left-[50%] top-[50%] z-50 px-6 rounded border text-white py-2 text-5xl center-center"
|
||||
>
|
||||
{dataItem.data.id}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
on:pointerdown={() => selectComponent(dataItem.data.id)}
|
||||
class={classNames(
|
||||
'h-full w-full center-center',
|
||||
$selectedComponent === dataItem.data.id ? 'active-grid-item' : '',
|
||||
dataItem.data.card ? 'border border-gray-100' : '',
|
||||
'top-0'
|
||||
)}
|
||||
class={classNames('h-full w-full center-center', 'top-0')}
|
||||
>
|
||||
<Component
|
||||
render={visible}
|
||||
@@ -136,22 +176,9 @@
|
||||
component={dataItem.data}
|
||||
selected={$selectedComponent === dataItem.data.id}
|
||||
locked={isFixed(dataItem)}
|
||||
on:lock={() => lock(dataItem)}
|
||||
on:expand={() => {
|
||||
const parentGridItem = findGridItem($app, id)
|
||||
|
||||
if (!parentGridItem) {
|
||||
return
|
||||
}
|
||||
$selectedComponent = dataItem.data.id
|
||||
push(history, $app)
|
||||
|
||||
expandGriditem(subGrid, dataItem, $breakpoint, parentGridItem)
|
||||
$app = $app
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
</div>
|
||||
</GridViewer>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,15 +35,12 @@ export function findGridItemParentGrid(app: App, id: string): string | undefined
|
||||
}
|
||||
}
|
||||
|
||||
export function isIdInsideGriditem(app: App, gridItem: GridItem, id: string | undefined): boolean {
|
||||
const path: string[] = []
|
||||
let currentId = id
|
||||
while (currentId) {
|
||||
path.push(currentId)
|
||||
currentId = findGridItemParentGrid(app, currentId)?.split('-')[0]
|
||||
export function allsubIds(app: App, parentId: string): string[] {
|
||||
let item = findGridItem(app, parentId)
|
||||
if (!item?.data.numberOfSubgrids) {
|
||||
return [parentId]
|
||||
}
|
||||
|
||||
return path.includes(gridItem.id)
|
||||
return getAllSubgridsAndComponentIds(app, item?.data)[1]
|
||||
}
|
||||
|
||||
export function findGridItem(app: App, id: string): GridItem | undefined {
|
||||
@@ -336,7 +333,7 @@ export function sortGridItemsPosition<T>(
|
||||
gridItems: FilledItem<T>[],
|
||||
width: number
|
||||
): FilledItem<T>[] {
|
||||
return gridItems.sort((a: GridItem, b: GridItem) => {
|
||||
return gridItems.sort((a: FilledItem<T>, b: FilledItem<T>) => {
|
||||
const aX = a[width].x
|
||||
const aY = a[width].y
|
||||
const bX = b[width].x
|
||||
@@ -392,7 +389,10 @@ export function recursivelyFilterKeyInJSON(
|
||||
Object.keys(json).forEach((key) => {
|
||||
if (
|
||||
key.toLowerCase().includes(search.toLowerCase()) ||
|
||||
extraSearch?.toLowerCase().includes(search.toLowerCase())
|
||||
extraSearch?.toLowerCase().includes(search.toLowerCase()) ||
|
||||
(typeof json[key] === 'string' && json[key].toLowerCase().includes(search.toLowerCase())) ||
|
||||
(typeof json[key] === 'number' &&
|
||||
json[key].toString().toLowerCase().includes(search.toLowerCase()))
|
||||
) {
|
||||
filteredJSON[key] = json[key]
|
||||
} else if (typeof json[key] === 'object') {
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
FileText,
|
||||
AtSignIcon
|
||||
} from 'lucide-svelte'
|
||||
import type { BaseAppComponent } from '../../types'
|
||||
import type { BaseAppComponent, GridItem } from '../../types'
|
||||
import type { Size } from '../../svelte-grid/types'
|
||||
|
||||
type BaseComponent<T extends string> = {
|
||||
@@ -68,7 +68,7 @@ export type BarChartComponent = BaseComponent<'barchartcomponent'>
|
||||
export type PieChartComponent = BaseComponent<'piechartcomponent'>
|
||||
export type ScatterChartComponent = BaseComponent<'scatterchartcomponent'>
|
||||
export type TableComponent = BaseComponent<'tablecomponent'> & {
|
||||
actionButtons: (BaseAppComponent & ButtonComponent)[]
|
||||
actionButtons: (BaseAppComponent & ButtonComponent & GridItem)[]
|
||||
}
|
||||
export type AggridComponent = BaseComponent<'aggridcomponent'>
|
||||
export type DisplayComponent = BaseComponent<'displaycomponent'>
|
||||
@@ -769,7 +769,7 @@ Hello \${ctx.username}
|
||||
fieldType: 'boolean',
|
||||
value: false,
|
||||
onlyStatic: true,
|
||||
tooltip: "Configure all columns as Editable by users"
|
||||
tooltip: 'Configure all columns as Editable by users'
|
||||
},
|
||||
pagination: {
|
||||
type: 'static',
|
||||
@@ -782,7 +782,7 @@ Hello \${ctx.username}
|
||||
fieldType: 'number',
|
||||
value: 10,
|
||||
onlyStatic: true,
|
||||
tooltip: "Number of rows per page"
|
||||
tooltip: 'Number of rows per page'
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
@@ -887,7 +887,7 @@ Hello \${ctx.username}
|
||||
fieldType: 'boolean',
|
||||
value: false,
|
||||
onlyStatic: true,
|
||||
tooltip: "Allows user to manually add new value"
|
||||
tooltip: 'Allows user to manually add new value'
|
||||
},
|
||||
placeholder: {
|
||||
type: 'static',
|
||||
@@ -1004,7 +1004,7 @@ Hello \${ctx.username}
|
||||
type: 'static',
|
||||
value: 1,
|
||||
fieldType: 'number',
|
||||
tooltip: "Spread between each number suggestion"
|
||||
tooltip: 'Spread between each number suggestion'
|
||||
}
|
||||
},
|
||||
customCss: {
|
||||
@@ -1048,7 +1048,7 @@ Hello \${ctx.username}
|
||||
fieldType: 'select',
|
||||
onlyStatic: true,
|
||||
optionValuesKey: 'localeOptions',
|
||||
tooltip: "Currency format"
|
||||
tooltip: 'Currency format'
|
||||
}
|
||||
},
|
||||
customCss: {
|
||||
@@ -1088,7 +1088,7 @@ Hello \${ctx.username}
|
||||
type: 'static',
|
||||
value: 1,
|
||||
fieldType: 'number',
|
||||
tooltip: "Spread between each number suggestion"
|
||||
tooltip: 'Spread between each number suggestion'
|
||||
}
|
||||
},
|
||||
customCss: {
|
||||
@@ -1135,7 +1135,7 @@ Hello \${ctx.username}
|
||||
type: 'static',
|
||||
value: 1,
|
||||
fieldType: 'number',
|
||||
tooltip: "Spread between each number suggestion"
|
||||
tooltip: 'Spread between each number suggestion'
|
||||
}
|
||||
},
|
||||
customCss: {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { getContext } from 'svelte'
|
||||
import type { AppViewerContext, GridItem } from '../../types'
|
||||
import ComponentOutputViewer from './ComponentOutputViewer.svelte'
|
||||
import { connectInput, isIdInsideGriditem } from '../appUtils'
|
||||
import { connectInput } from '../appUtils'
|
||||
import SubGridOutput from './SubGridOutput.svelte'
|
||||
import OutputHeader from './components/OutputHeader.svelte'
|
||||
import TableActionsOutput from './components/TableActionsOutput.svelte'
|
||||
@@ -14,8 +14,7 @@
|
||||
export let parentId: string | undefined = undefined
|
||||
export let expanded: boolean = false
|
||||
|
||||
const { app, selectedComponent, connectingInput } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const { selectedComponent, connectingInput } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const name = getComponentNameById(gridItem.id)
|
||||
|
||||
function getComponentNameById(componentId: string) {
|
||||
@@ -30,14 +29,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: subGrids = Array.from({ length: gridItem.data.numberOfSubgrids }).map(
|
||||
$: subGrids = Array.from({ length: gridItem.data.numberOfSubgrids ?? 0 }).map(
|
||||
(_, i) => `${gridItem.id}-${i}`
|
||||
)
|
||||
|
||||
$: insideGrid = isIdInsideGriditem($app, gridItem, $selectedComponent)
|
||||
$: isSelected = $selectedComponent === gridItem.id
|
||||
$: shouldOpen = insideGrid || isSelected
|
||||
|
||||
function onHeaderClick(manuallyOpen: boolean) {
|
||||
if (manuallyOpen) {
|
||||
if (parentId) {
|
||||
@@ -52,7 +47,6 @@
|
||||
</script>
|
||||
|
||||
<OutputHeader
|
||||
{shouldOpen}
|
||||
on:handleClick={(e) => {
|
||||
if (!$connectingInput.opened) {
|
||||
onHeaderClick(e.detail.manuallyOpen)
|
||||
@@ -62,19 +56,16 @@
|
||||
name={getComponentNameById(gridItem.id)}
|
||||
{first}
|
||||
{nested}
|
||||
{expanded}
|
||||
>
|
||||
<div class="py-1">
|
||||
<ComponentOutputViewer
|
||||
componentId={gridItem.id}
|
||||
on:select={({ detail }) => {
|
||||
if ($connectingInput.opened) {
|
||||
$connectingInput = connectInput($connectingInput, gridItem.id, detail)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ComponentOutputViewer
|
||||
componentId={gridItem.id}
|
||||
on:select={({ detail }) => {
|
||||
if ($connectingInput.opened) {
|
||||
$connectingInput = connectInput($connectingInput, gridItem.id, detail)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<SubGridOutput {name} {expanded} {subGrids} parentId={gridItem.id} />
|
||||
<TableActionsOutput {gridItem} {expanded} />
|
||||
<TableActionsOutput {gridItem} />
|
||||
</OutputHeader>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
import { getContext } from 'svelte'
|
||||
import type { Writable } from 'svelte/store'
|
||||
import type { Output } from '../../rx'
|
||||
import type { AppViewerContext } from '../../types'
|
||||
import { recursivelyFilterKeyInJSON } from '../appUtils'
|
||||
import type { AppViewerContext, ContextPanelContext } from '../../types'
|
||||
import { recursivelyFilterKeyInJSON as recursivelyFilterInJSON } from '../appUtils'
|
||||
|
||||
export let componentId: string
|
||||
|
||||
const { worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const { search } = getContext<{ search: Writable<string> }>('searchCtx')
|
||||
const { search, hasResult } = getContext<ContextPanelContext>('ContextPanel')
|
||||
|
||||
let object = {}
|
||||
|
||||
@@ -29,11 +29,15 @@
|
||||
|
||||
$: subscribeToAllOutputs($worldStore?.outputsById?.[componentId])
|
||||
|
||||
$: filtered = recursivelyFilterKeyInJSON(object, $search, componentId)
|
||||
$: filtered = recursivelyFilterInJSON(object, $search, componentId)
|
||||
|
||||
$: $hasResult[componentId] = Object.keys(filtered).length > 0
|
||||
</script>
|
||||
|
||||
{#if Object.keys(filtered).length > 0}
|
||||
{#if $hasResult[componentId] || $search == ''}
|
||||
<ObjectViewer json={filtered} on:select topBrackets={false} />
|
||||
{:else if $search.length > 0}
|
||||
<div class="text-xs pl-2">No results</div>
|
||||
<div class="text-xs pl-2 text-gray-600">No results</div>
|
||||
{:else}
|
||||
<div class="text-xs pl-2 text-gray-600">No outputs</div>
|
||||
{/if}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { getContext, setContext } from 'svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
import type { AppViewerContext } from '../../types'
|
||||
import type { AppViewerContext, ContextPanelContext } from '../../types'
|
||||
import { connectInput } from '../appUtils'
|
||||
import PanelSection from '../settingsPanel/common/PanelSection.svelte'
|
||||
import ComponentOutput from './ComponentOutput.svelte'
|
||||
@@ -13,19 +13,17 @@
|
||||
import MinMaxButton from './components/MinMaxButton.svelte'
|
||||
import OutputHeader from './components/OutputHeader.svelte'
|
||||
|
||||
const { connectingInput, app, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
const { connectingInput, app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let search = writable<string>('')
|
||||
let expanded = false
|
||||
let ctxOpened = true
|
||||
let stateOpened = true
|
||||
let expanded = writable(false)
|
||||
|
||||
setContext('searchCtx', {
|
||||
search
|
||||
setContext<ContextPanelContext>('ContextPanel', {
|
||||
search,
|
||||
manuallyOpened: writable<Record<string, boolean>>({}),
|
||||
hasResult: writable<Record<string, boolean>>({}),
|
||||
expanded
|
||||
})
|
||||
|
||||
$: expanded && !ctxOpened && (ctxOpened = true)
|
||||
$: expanded && !stateOpened && (stateOpened = true)
|
||||
</script>
|
||||
|
||||
<PanelSection noPadding titlePadding="px-4 pt-2 pb-0.5" title="Outputs">
|
||||
@@ -50,46 +48,44 @@
|
||||
</div>
|
||||
|
||||
<div class="p-1 ">
|
||||
<MinMaxButton bind:expanded />
|
||||
<MinMaxButton bind:expanded={$expanded} />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
{#key $worldStore?.outputsById}
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">State & Context</span>
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">State & Context</span>
|
||||
|
||||
<OutputHeader id={'ctx'} name={'App Context'} first color="blue" {expanded}>
|
||||
<ComponentOutputViewer
|
||||
componentId={'ctx'}
|
||||
on:select={({ detail }) => {
|
||||
$connectingInput = connectInput($connectingInput, 'ctx', detail)
|
||||
}}
|
||||
/>
|
||||
</OutputHeader>
|
||||
<OutputHeader id={'ctx'} name={'App Context'} first color="blue">
|
||||
<ComponentOutputViewer
|
||||
componentId={'ctx'}
|
||||
on:select={({ detail }) => {
|
||||
$connectingInput = connectInput($connectingInput, 'ctx', detail)
|
||||
}}
|
||||
/>
|
||||
</OutputHeader>
|
||||
|
||||
<OutputHeader id={'state'} name={'State'} color="blue" {expanded}>
|
||||
<ComponentOutputViewer
|
||||
componentId={'state'}
|
||||
on:select={({ detail }) => {
|
||||
$connectingInput = connectInput($connectingInput, 'state', detail)
|
||||
}}
|
||||
/>
|
||||
</OutputHeader>
|
||||
</div>
|
||||
<OutputHeader id={'state'} name={'State'} color="blue">
|
||||
<ComponentOutputViewer
|
||||
componentId={'state'}
|
||||
on:select={({ detail }) => {
|
||||
$connectingInput = connectInput($connectingInput, 'state', detail)
|
||||
}}
|
||||
/>
|
||||
</OutputHeader>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">Components</span>
|
||||
{#each $app.grid as gridItem, index (gridItem.id)}
|
||||
<ComponentOutput {gridItem} first={index === 0} {expanded} />
|
||||
{/each}
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">Components</span>
|
||||
{#each $app.grid as gridItem, index (gridItem.id)}
|
||||
<ComponentOutput {gridItem} first={index === 0} />
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">Background scripts</span>
|
||||
<div class="border-t">
|
||||
<BackgroundScriptsOutput />
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-sm font-bold p-2">Background scripts</span>
|
||||
<div class="border-t">
|
||||
<BackgroundScriptsOutput {expanded} />
|
||||
</div>
|
||||
</div>
|
||||
{/key}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
export let expanded: boolean = false
|
||||
export let subGrids: string[]
|
||||
|
||||
const { app, connectingInput, breakpoint, worldStore } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
const { app, connectingInput, worldStore } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let selected = 0
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
export let id: string
|
||||
export let name: string
|
||||
export let expanded: boolean = false
|
||||
export let first: boolean = false
|
||||
|
||||
function onHeaderClick(manuallyOpen: boolean) {
|
||||
@@ -30,13 +29,11 @@
|
||||
{name}
|
||||
color="blue"
|
||||
{first}
|
||||
{expanded}
|
||||
on:handleClick={(e) => {
|
||||
if (!$connectingInput.opened) {
|
||||
onHeaderClick(e.detail.manuallyOpen)
|
||||
}
|
||||
}}
|
||||
shouldOpen={$selectedComponent === id}
|
||||
>
|
||||
<ComponentOutputViewer
|
||||
componentId={id}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { AppViewerContext } from '$lib/components/apps/types'
|
||||
import { getContext } from 'svelte'
|
||||
import OutputHeader from './OutputHeader.svelte'
|
||||
import BackgroundScriptOutput from './BackgroundScriptOutput.svelte'
|
||||
|
||||
const { app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
@@ -10,5 +9,5 @@
|
||||
</script>
|
||||
|
||||
{#each $app.hiddenInlineScripts as action, index}
|
||||
<BackgroundScriptOutput id={`bg_${index}`} name={action.name} {expanded} />
|
||||
<BackgroundScriptOutput id={`bg_${index}`} name={action.name} />
|
||||
{/each}
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type { AppViewerContext, ContextPanelContext } from '$lib/components/apps/types'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { ChevronDown, ChevronUp } from 'lucide-svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import { slide } from 'svelte/transition'
|
||||
import { allsubIds } from '../../appUtils'
|
||||
|
||||
export let id: string
|
||||
export let name: string
|
||||
export let first: boolean = false
|
||||
export let nested: boolean = false
|
||||
export let color: 'blue' | 'indigo' = 'indigo'
|
||||
export let expanded: boolean = false
|
||||
export let shouldOpen: boolean = false
|
||||
|
||||
$: open = shouldOpen
|
||||
let manuallyOpen = false
|
||||
const { expanded, manuallyOpened, search, hasResult } =
|
||||
getContext<ContextPanelContext>('ContextPanel')
|
||||
|
||||
const { selectedComponent, app } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
$: subids = allsubIds($app, id)
|
||||
$: inSearch =
|
||||
$search != '' &&
|
||||
($hasResult[id] ||
|
||||
Object.entries($hasResult).some(([key, value]) => value && subids.includes(key)))
|
||||
$: open =
|
||||
$expanded || subids.includes($selectedComponent ?? '') || $manuallyOpened[id] || inSearch
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: if (expanded) {
|
||||
manuallyOpen = true
|
||||
} else {
|
||||
manuallyOpen = false
|
||||
}
|
||||
|
||||
const hoverColor = {
|
||||
blue: 'hover:bg-blue-300 hover:text-blue-600',
|
||||
indigo: 'hover:bg-indigo-300 hover:text-indigo-600'
|
||||
@@ -45,42 +49,47 @@
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class={classNames(
|
||||
'flex items-center justify-between p-1 cursor-pointer border-b gap-1 truncate',
|
||||
hoverColor[color],
|
||||
open && !manuallyOpen ? openBackground[color] : 'bg-white',
|
||||
first ? 'border-t' : '',
|
||||
nested ? 'border-l' : ''
|
||||
)}
|
||||
on:click={() => {
|
||||
dispatch('handleClick', { manuallyOpen })
|
||||
manuallyOpen = !manuallyOpen
|
||||
}}
|
||||
>
|
||||
<div class={$search == '' || inSearch ? '' : 'invisible h-0 overflow-hidden'}>
|
||||
<div
|
||||
class={classNames(
|
||||
'text-2xs ml-0.5 font-bold px-2 py-0.5 rounded-sm',
|
||||
open ? idClass[color] : ' bg-gray-100'
|
||||
'flex items-center justify-between p-1 cursor-pointer border-b gap-1 truncate',
|
||||
hoverColor[color],
|
||||
$selectedComponent == id ? openBackground[color] : 'bg-white',
|
||||
first ? 'border-t' : '',
|
||||
nested ? 'border-l' : ''
|
||||
)}
|
||||
on:click={() => {
|
||||
dispatch('handleClick', { manuallyOpen: $manuallyOpened[id] })
|
||||
$manuallyOpened[id] = $manuallyOpened[id] != undefined ? !$manuallyOpened[id] : true
|
||||
}}
|
||||
>
|
||||
{id}
|
||||
<div
|
||||
class={classNames(
|
||||
'text-2xs ml-0.5 font-bold px-2 py-0.5 rounded-sm',
|
||||
$selectedComponent == id ? idClass[color] : ' bg-gray-100'
|
||||
)}
|
||||
>
|
||||
{id}
|
||||
</div>
|
||||
<div
|
||||
on:click|stopPropagation={() => {
|
||||
$manuallyOpened[id] = $manuallyOpened[id] != undefined ? !$manuallyOpened[id] : false
|
||||
}}
|
||||
class="text-2xs font-bold flex flex-row gap-2 items-center truncate"
|
||||
>
|
||||
{name}
|
||||
{#if !open}
|
||||
<ChevronDown size={14} />
|
||||
{:else if $manuallyOpened[id]}
|
||||
<ChevronUp size={14} class={manuallyOpenColor[color]} strokeWidth={4} />
|
||||
{:else}
|
||||
<ChevronUp size={14} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-2xs font-bold flex flex-row gap-2 items-center truncate">
|
||||
{name}
|
||||
{#if !open && !manuallyOpen}
|
||||
<ChevronDown size={14} />
|
||||
{:else if manuallyOpen}
|
||||
<ChevronUp size={14} class={manuallyOpenColor[color]} strokeWidth={4} />
|
||||
{:else}
|
||||
<ChevronUp size={14} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if open || manuallyOpen}
|
||||
<div class="py-1 border-b" transition:slide|local>
|
||||
<div class="py-1 border-b {open ? '' : 'invisible h-0 overflow-hidden'} ">
|
||||
<div class={classNames(nested ? 'border-l ml-2' : '')}>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
const { connectingInput } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
export let id: string
|
||||
export let expanded: boolean = false
|
||||
export let first: boolean = false
|
||||
</script>
|
||||
|
||||
<OutputHeader {id} name={'Table action'} {first} {expanded}>
|
||||
<OutputHeader {id} name={'Table action'} {first}>
|
||||
<ComponentOutputViewer
|
||||
componentId={id}
|
||||
on:select={({ detail }) => {
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
import TableActionOutput from './TableActionOutput.svelte'
|
||||
|
||||
export let gridItem: GridItem
|
||||
export let expanded: boolean = false
|
||||
</script>
|
||||
|
||||
<div class="my-1">
|
||||
{#if gridItem.data.type === 'tablecomponent' && gridItem.data.actionButtons.length > 0}
|
||||
<div class="ml-2 border-l">
|
||||
{#each gridItem.data.actionButtons as action, index}
|
||||
<TableActionOutput id={action.id} {expanded} first={index === 0} />
|
||||
<TableActionOutput id={action.id} first={index === 0} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
const componentType = $app.grid.find((c) => c.data.id === id)?.data?.type
|
||||
|
||||
const content =
|
||||
defaultCode(componentType, language) ??
|
||||
defaultCode(componentType ?? '', language) ??
|
||||
initialCode(language, Script.kind.SCRIPT, subkind ?? 'flow')
|
||||
|
||||
return newInlineScript(content, language, path)
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
{#each $app.grid as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id && gridItem.data.id === selectedScriptComponentId}
|
||||
<InlineScriptEditorPanel
|
||||
defaultUserInput={gridItem?.data?.type == 'formcomponent' ||
|
||||
gridItem?.data?.type == 'buttonformcomponent'}
|
||||
defaultUserInput={gridItem?.data?.type == 'formcomponent'}
|
||||
id={gridItem.data.id}
|
||||
bind:componentInput={gridItem.data.componentInput}
|
||||
/>
|
||||
@@ -60,8 +59,7 @@
|
||||
{#each $app.subgrids[key] as gridItem (gridItem?.data?.id)}
|
||||
{#if gridItem?.data?.id && gridItem.data.id === selectedScriptComponentId}
|
||||
<InlineScriptEditorPanel
|
||||
defaultUserInput={gridItem.data?.type == 'formcomponent' ||
|
||||
gridItem.data?.type == 'buttonformcomponent'}
|
||||
defaultUserInput={gridItem.data?.type == 'formcomponent'}
|
||||
id={gridItem.data.id}
|
||||
bind:componentInput={gridItem.data.componentInput}
|
||||
/>
|
||||
|
||||
@@ -7,8 +7,8 @@ const Breakpoints = {
|
||||
lg: 1024
|
||||
}
|
||||
|
||||
const WIDE_GRID_COLUMNS = 12 as const;
|
||||
const NARROW_GRID_COLUMNS = 3 as const;
|
||||
const WIDE_GRID_COLUMNS = 12 as const
|
||||
const NARROW_GRID_COLUMNS = 3 as const
|
||||
|
||||
const columnConfiguration: ColumnConfiguration = [
|
||||
[Breakpoints.lg, WIDE_GRID_COLUMNS],
|
||||
@@ -17,14 +17,6 @@ const columnConfiguration: ColumnConfiguration = [
|
||||
|
||||
const gridColumns = columnConfiguration.map((value) => value[1])
|
||||
|
||||
function disableDrag(component: GridItem): GridItem {
|
||||
gridColumns.forEach((column: number) => {
|
||||
component[column].customDragger = true
|
||||
component[column].customResizer = true
|
||||
})
|
||||
return component
|
||||
}
|
||||
|
||||
function toggleFixed(component: GridItem): GridItem {
|
||||
const nValue = !component[gridColumns[0]].fixed
|
||||
gridColumns.forEach((column: number) => {
|
||||
@@ -44,21 +36,11 @@ function isFixed(component: GridItem): boolean {
|
||||
return fixed
|
||||
}
|
||||
|
||||
function enableDrag(component: GridItem): GridItem {
|
||||
gridColumns.forEach((column: number) => {
|
||||
component[column].customDragger = false
|
||||
component[column].customResizer = false
|
||||
})
|
||||
return component
|
||||
}
|
||||
|
||||
export {
|
||||
gridColumns,
|
||||
WIDE_GRID_COLUMNS,
|
||||
NARROW_GRID_COLUMNS,
|
||||
columnConfiguration,
|
||||
disableDrag,
|
||||
enableDrag,
|
||||
Breakpoints,
|
||||
toggleFixed,
|
||||
isFixed
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
|
||||
export interface Size {
|
||||
w: number
|
||||
h: number
|
||||
w: number
|
||||
h: number
|
||||
}
|
||||
|
||||
export interface Positon {
|
||||
x: number
|
||||
y: number
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
|
||||
interface ItemLayout extends Size, Positon {
|
||||
fixed?: boolean
|
||||
resizable?: boolean
|
||||
draggable?: boolean
|
||||
customDragger?: boolean
|
||||
customResizer?: boolean
|
||||
min?: Size
|
||||
max?: Size
|
||||
fixed?: boolean
|
||||
resizable?: boolean
|
||||
draggable?: boolean
|
||||
customDragger?: boolean
|
||||
customResizer?: boolean
|
||||
min?: Size
|
||||
max?: Size
|
||||
}
|
||||
|
||||
export type FilledItem<T> = T & { [width: number]: Required<ItemLayout>; data: any, id: string }
|
||||
|
||||
|
||||
|
||||
export type FilledItem<T> = { [width: number]: Required<ItemLayout>; data: T; id: string }
|
||||
|
||||
@@ -77,10 +77,7 @@ export type AppSection = {
|
||||
id: SectionID
|
||||
}
|
||||
|
||||
export type GridItem = FilledItem<{
|
||||
data: AppComponent
|
||||
id: string
|
||||
}>
|
||||
export type GridItem = FilledItem<AppComponent>
|
||||
|
||||
export type InlineScript = {
|
||||
content: string
|
||||
@@ -155,3 +152,10 @@ export type EditorBreakpoint = 'sm' | 'lg'
|
||||
export const IS_APP_PUBLIC_CONTEXT_KEY = 'isAppPublicContext' as const
|
||||
|
||||
type ComponentID = string
|
||||
|
||||
export type ContextPanelContext = {
|
||||
search: Writable<string>
|
||||
manuallyOpened: Writable<Record<string, boolean>>
|
||||
expanded: Writable<boolean>
|
||||
hasResult: Writable<Record<string, boolean>>
|
||||
}
|
||||
|
||||
@@ -199,8 +199,8 @@ export function getAllScriptNames(app: App): string[] {
|
||||
acc.push(componentInput.runnable.name)
|
||||
}
|
||||
|
||||
if (componentInput?.type === 'tablecomponent') {
|
||||
componentInput.actionButtons.forEach((actionButton) => {
|
||||
if (gridItem.data.type === 'tablecomponent') {
|
||||
gridItem.data.actionButtons.forEach((actionButton) => {
|
||||
if (actionButton.componentInput?.type === 'runnable') {
|
||||
if (actionButton.componentInput.runnable?.type === 'runnableByName') {
|
||||
acc.push(actionButton.componentInput.runnable.name)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
{:else if topBrackets}
|
||||
<span class="text-black">{openBracket}{closeBracket}</span>
|
||||
{:else}
|
||||
<span class="text-gray-600 text-xs">No items</span>
|
||||
<span class="text-gray-600 text-xs ml-2">No items</span>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user