frontend apps rename improvements

This commit is contained in:
Ruben Fiszel
2023-04-12 14:38:13 +02:00
parent 6aa1008933
commit 0cd1e65e46
9 changed files with 127 additions and 86 deletions
@@ -190,7 +190,7 @@
$state = $state
} catch (e) {
sendUserToast('Error running frontend script: ' + e.message, true)
sendUserToast(`Error running frontend script ${id}: ` + e.message, true)
// Manually add a fake job to the job list to show the error
@@ -206,8 +206,7 @@
}
loading = false
return
}
if (noBackend) {
} else if (noBackend) {
if (!noToast) {
sendUserToast('This app is not connected to a windmill backend, it is a static preview')
}
@@ -25,7 +25,6 @@
faClipboard,
faExternalLink,
faFileExport,
faGlobe,
faSave
} from '@fortawesome/free-solid-svg-icons'
import {
@@ -42,7 +41,7 @@
import { getContext } from 'svelte'
import { Icon } from 'svelte-awesome'
import { Pane, Splitpanes } from 'svelte-splitpanes'
import { appToHubUrl, classNames, copyToClipboard, sendUserToast } from '../../../utils'
import { classNames, copyToClipboard, sendUserToast } from '../../../utils'
import type {
AppInput,
ConnectedAppInput,
@@ -607,14 +606,14 @@
appExport.open($app)
}
},
{
displayName: 'Publish to Hub',
icon: faGlobe,
action: () => {
const url = appToHubUrl(toStatic($app, $staticExporter, $summary))
window.open(url.toString(), '_blank')
}
},
// {
// displayName: 'Publish to Hub',
// icon: faGlobe,
// action: () => {
// const url = appToHubUrl(toStatic($app, $staticExporter, $summary))
// window.open(url.toString(), '_blank')
// }
// },
{
displayName: 'Hub compatible JSON',
icon: faFileExport,
@@ -32,7 +32,10 @@ export function dfs(
for (const item of grid) {
if (item.id === id) {
return [id]
} else if (item.data.type == 'tablecomponent' && item.data.actionButtons.find((x) => x.id)) {
} else if (
item.data.type == 'tablecomponent' &&
item.data.actionButtons.find((x) => id == x.id)
) {
return [item.id, id]
} else {
for (let i = 0; i < (item.data.numberOfSubgrids ?? 0); i++) {
@@ -133,11 +136,14 @@ export function findGridItem(app: App, id: string): GridItem | undefined {
}
export function getNextGridItemId(app: App): string {
const subgridsKeys = allItems(app.grid, app.subgrids).map((x) => x.id)
const withoutDash = subgridsKeys.map((element) => element.split('-')[0])
const id = getNextId([...new Set(withoutDash)])
return id
const allIds = allItems(app.grid, app.subgrids).flatMap((x) => {
if (x.data.type === 'tablecomponent') {
return [x.id, ...x.data.actionButtons.map((x) => x.id)]
} else {
return [x.id]
}
})
return getNextId(allIds)
}
export function getAllRecomputeIdsForComponent(app: App, id: string | undefined) {
@@ -12,7 +12,7 @@
export let first: boolean = false
</script>
<OutputHeader selectable={false} {id} {name} color="blue" {first}>
<OutputHeader renamable={false} selectable={true} {id} {name} color="blue" {first}>
<ComponentOutputViewer
componentId={id}
on:select={({ detail }) => {
@@ -6,6 +6,8 @@
import { getContext } from 'svelte'
import { allsubIds, findGridItem } from '../../appUtils'
import IdEditor from './IdEditor.svelte'
import type { AppComponent } from '../../component'
import type { Runnable } from '$lib/components/apps/inputType'
export let id: string
export let name: string
@@ -13,6 +15,7 @@
export let nested: boolean = false
export let color: 'blue' | 'indigo' = 'indigo'
export let selectable: boolean = true
export let renamable: boolean = true
const { manuallyOpened, search, hasResult } = getContext<ContextPanelContext>('ContextPanel')
@@ -47,66 +50,102 @@
}
function renameId(newId: string): void {
{
const item = findGridItem($app, id)
if (item) {
item.data.id = newId
item.id = newId
}
const oldSubgrids = Object.keys($app.subgrids ?? {}).filter((subgrid) =>
subgrid.startsWith(id + '-')
)
oldSubgrids.forEach((subgrid) => {
if ($app.subgrids) {
$app.subgrids[subgrid.replace(id, newId)] = $app.subgrids[subgrid]
delete $app.subgrids[subgrid]
}
})
allItems($app.grid, $app.subgrids).forEach((item) => {
if (item.data.componentInput?.type == 'connected') {
if (item.data.componentInput.connection?.componentId === id) {
item.data.componentInput.connection.componentId = newId
}
} else if (item.data.componentInput?.type == 'runnable') {
if (
item.data.componentInput?.runnable?.type === 'runnableByName' &&
item.data.componentInput?.runnable?.inlineScript?.refreshOn
?.map((x) => x.id)
?.includes(id)
) {
item.data.componentInput.runnable.inlineScript.refreshOn =
item.data.componentInput.runnable.inlineScript.refreshOn.map((x) => {
if (x.id === id) {
return {
id: newId,
key: x.key
}
}
return x
})
}
}
const item = findGridItem($app, id)
Object.values(item.data.configuration ?? {}).forEach((config) => {
if (config.type === 'connected') {
if (config.connection?.componentId === id) {
config.connection.componentId = newId
}
} else if (config.type == 'oneOf') {
Object.values(config.configuration ?? {}).forEach((choices) => {
Object.values(choices).forEach((c) => {
if (c.type === 'connected') {
if (c.connection?.componentId === id) {
c.connection.componentId = newId
}
}
})
})
}
if (!item) {
return
}
item.data.id = newId
item.id = newId
const oldSubgrids = Object.keys($app.subgrids ?? {}).filter((subgrid) =>
subgrid.startsWith(id + '-')
)
oldSubgrids.forEach((subgrid) => {
if ($app.subgrids) {
$app.subgrids[subgrid.replace(id, newId)] = $app.subgrids[subgrid]
delete $app.subgrids[subgrid]
}
})
function propagateRename(from: string, to: string) {
allItems($app.grid, $app.subgrids).forEach((item) => {
renameComponent(from, to, item.data)
})
$app.hiddenInlineScripts.forEach((x) => {
console.log('process', x.name, id)
processRunnable(from, to, {
name: x.name,
inlineScript: x.inlineScript,
type: 'runnableByName'
})
})
$app = $app
$selectedComponent = [newId]
}
propagateRename(id, newId)
if (item?.data.type == 'tablecomponent') {
for (let c of item.data.actionButtons) {
let old = c.id
c.id = c.id.replace(id + '_', newId + '_')
propagateRename(old, c.id)
}
}
$app = $app
$selectedComponent = [newId]
}
function renameComponent(from: string, to: string, data: AppComponent) {
if (data.type == 'tablecomponent') {
for (let c of data.actionButtons) {
renameComponent(from, to, c)
}
}
let componentInput = data.componentInput
if (componentInput?.type == 'connected') {
if (componentInput.connection?.componentId === from) {
componentInput.connection.componentId = to
}
} else if (componentInput?.type == 'runnable') {
processRunnable(from, to, componentInput.runnable)
}
Object.values(data.configuration ?? {}).forEach((config) => {
if (config.type === 'connected') {
if (config.connection?.componentId === from) {
config.connection.componentId = to
}
} else if (config.type == 'oneOf') {
Object.values(config.configuration ?? {}).forEach((choices) => {
Object.values(choices).forEach((c) => {
if (c.type === 'connected') {
if (c.connection?.componentId === id) {
c.connection.componentId = to
}
}
})
})
}
})
}
function processRunnable(from: string, to: string, runnable: Runnable) {
if (
runnable?.type === 'runnableByName' &&
runnable?.inlineScript?.refreshOn?.find((x) => x.id === from)
) {
console.log('processss')
runnable.inlineScript.refreshOn = runnable.inlineScript.refreshOn.map((x) => {
console.log('renaming', x)
if (x.id === from) {
return {
id: to,
key: x.key
}
}
return x
})
}
}
</script>
@@ -161,7 +200,7 @@
</div>
{/if}
</button>
{#if selectable && ($selectedComponent?.includes(id) || $hoverStore === id)}
{#if selectable && renamable && ($selectedComponent?.includes(id) || $hoverStore === id)}
<IdEditor
{id}
on:selected={() => ($selectedComponent = [id])}
@@ -11,7 +11,7 @@
export let first: boolean = false
</script>
<OutputHeader {id} name={'Table action'} {first}>
<OutputHeader renamable={false} {id} name={'Table action'} {first}>
<ComponentOutputViewer
componentId={id}
on:select={({ detail }) => {
@@ -236,7 +236,6 @@
<TableActions id={component.id} bind:components={componentSettings.item.data.actionButtons} />
{/if}
<AlignmentEditor bind:component={componentSettings.item.data} />
{#if componentSettings.item.data.type === 'buttoncomponent' || componentSettings.item.data.type === 'formcomponent' || componentSettings.item.data.type === 'formbuttoncomponent'}
<Recompute
bind:recomputeIds={componentSettings.item.data.recomputeIds}
@@ -245,6 +244,7 @@
{/if}
<div class="grow shrink" />
<AlignmentEditor bind:component={componentSettings.item.data} />
{#if Object.keys(ccomponents[component.type].customCss ?? {}).length > 0}
<PanelSection title="Styling">
@@ -156,13 +156,13 @@
</Button>
{/if}
</div>
<div class="flex flex-row gap-2 flex-wrap">
<div class="flex flex-row gap-2 flex-wrap mt-2">
{#each frontendDependencies as label, index}
<span class={classNames(badgeClass, colors['blue'])}>
{label}
<button
on:click={() => deleteDep(index)}
class="bg-red-300 cursor-pointer hover:bg-red-400 ml-1 rounded-md"
class="bg-blue-300 cursor-pointer hover:bg-blue-400 ml-1 rounded-md"
>
<X size={18} class="p-0.5" />
</button>
@@ -8,7 +8,6 @@
displayDaysAgo,
emptyString,
encodeState,
flowToHubUrl,
sendUserToast
} from '$lib/utils'
import {
@@ -19,7 +18,6 @@
faClipboard,
faCodeFork,
faEdit,
faGlobe,
faList,
faPlay,
faShare,
@@ -249,7 +247,7 @@
{/if}
<div class="flex gap-2 flex-wrap mt-2">
<Button
<!-- <Button
target="_blank"
href={flowToHubUrl(flow).toString()}
variant="border"
@@ -258,7 +256,7 @@
startIcon={{ icon: faGlobe }}
>
Publish to Hub
</Button>
</Button> -->
<Button
on:click={() => shareModal.openDrawer(flow?.path ?? '', 'flow')}
variant="border"