mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-21 16:02:28 +00:00
fix: fix id renaming in apps
This commit is contained in:
@@ -1,24 +1,40 @@
|
||||
<script lang="ts">
|
||||
import { stopPropagation, createBubbler } from 'svelte/legacy'
|
||||
|
||||
const bubble = createBubbler()
|
||||
import { ArrowRight } from 'lucide-svelte'
|
||||
import { Button } from './common'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { forbiddenIds } from './flows/idUtils'
|
||||
import { slide } from 'svelte/transition'
|
||||
|
||||
export let initialId: string
|
||||
export let reservedIds: string[] = []
|
||||
export let label: string = 'Component ID'
|
||||
export let value = initialId
|
||||
export let buttonText = ''
|
||||
export let btnClasses = '!p-1 !w-[34px] !ml-1'
|
||||
export let acceptUnderScores = false
|
||||
interface Props {
|
||||
initialId: string
|
||||
reservedIds?: string[]
|
||||
label?: string
|
||||
value?: any
|
||||
buttonText?: string
|
||||
btnClasses?: string
|
||||
acceptUnderScores?: boolean
|
||||
onSave: ({ oldId, newId }: { oldId: string; newId: string }) => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
let error = ''
|
||||
const dispatch = createEventDispatcher()
|
||||
let {
|
||||
initialId,
|
||||
reservedIds = [],
|
||||
label = 'Component ID',
|
||||
value = $bindable(initialId),
|
||||
buttonText = '',
|
||||
btnClasses = '!p-1 !w-[34px] !ml-1',
|
||||
acceptUnderScores = false,
|
||||
onSave,
|
||||
onClose
|
||||
}: Props = $props()
|
||||
|
||||
let error = $state('')
|
||||
const regex = acceptUnderScores ? /^[a-zA-Z][a-zA-Z0-9_]*$/ : /^[a-zA-Z][a-zA-Z0-9]*$/
|
||||
|
||||
$: validateId(value, reservedIds)
|
||||
|
||||
function validateId(id: string, reservedIds: string[]) {
|
||||
if (id == initialId) {
|
||||
error = ''
|
||||
@@ -35,9 +51,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
let inputDiv: HTMLInputElement | undefined = undefined
|
||||
let inputDiv: HTMLInputElement | undefined = $state(undefined)
|
||||
|
||||
$: inputDiv?.focus()
|
||||
$effect(() => {
|
||||
untrack(() => validateId(value, reservedIds))
|
||||
})
|
||||
$effect(() => {
|
||||
inputDiv?.focus()
|
||||
})
|
||||
</script>
|
||||
|
||||
<label class="block text-primary">
|
||||
@@ -50,15 +71,17 @@
|
||||
type="text"
|
||||
bind:value
|
||||
class="!w-auto grow"
|
||||
on:click|stopPropagation={() => {}}
|
||||
on:keydown|stopPropagation={({ key }) => {
|
||||
onclick={stopPropagation(() => {})}
|
||||
onkeydown={(e) => {
|
||||
e.stopPropagation()
|
||||
let key = e.key
|
||||
if (key === 'Enter' && error === '' && value !== initialId) {
|
||||
dispatch('save', value)
|
||||
onSave({ oldId: initialId, newId: value })
|
||||
} else if (key == 'Escape') {
|
||||
dispatch('close')
|
||||
onClose?.()
|
||||
}
|
||||
}}
|
||||
on:keypress|stopPropagation
|
||||
onkeypress={stopPropagation(bubble('keypress'))}
|
||||
/>
|
||||
<Button
|
||||
size="xs"
|
||||
@@ -67,8 +90,8 @@
|
||||
{btnClasses}
|
||||
aria-label="Save ID"
|
||||
disabled={error != '' || value === initialId}
|
||||
on:click={() => {
|
||||
dispatch('save', value)
|
||||
onclick={() => {
|
||||
onSave({ oldId: initialId, newId: value })
|
||||
}}
|
||||
>
|
||||
{buttonText}<ArrowRight size={18} />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { AppViewerContext } from '$lib/components/apps/types'
|
||||
import { allItems } from '$lib/components/apps/utils'
|
||||
import { Pencil } from 'lucide-svelte'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import { getContext } from 'svelte'
|
||||
import IdEditorInput from '$lib/components/IdEditorInput.svelte'
|
||||
import Popover from '$lib/components/meltComponents/Popover.svelte'
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
interface Props {
|
||||
id: string
|
||||
onChange: ({ oldId, newId }: { oldId: string; newId: string }) => void
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
let { id }: Props = $props()
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let { id, onChange, onClose }: Props = $props()
|
||||
|
||||
let reservedIds = $derived(allItems($app.grid, $app.subgrids).map((item) => item.id))
|
||||
</script>
|
||||
@@ -39,10 +39,10 @@
|
||||
{#snippet content({ close })}
|
||||
<IdEditorInput
|
||||
initialId={id}
|
||||
on:close={() => close()}
|
||||
on:save={(e) => {
|
||||
dispatch('save', e.detail)
|
||||
close()
|
||||
{onClose}
|
||||
onSave={(e) => {
|
||||
onChange(e)
|
||||
onClose?.()
|
||||
}}
|
||||
{reservedIds}
|
||||
/>
|
||||
|
||||
+8
-12
@@ -74,7 +74,7 @@
|
||||
indigo: 'bg-indigo-500 text-white'
|
||||
}
|
||||
|
||||
function renameId(newId: string): void {
|
||||
function renameId(oldId: string, newId: string): void {
|
||||
const item = findGridItem($app, id)
|
||||
|
||||
if (!item) {
|
||||
@@ -84,12 +84,12 @@
|
||||
item.id = newId
|
||||
|
||||
const oldSubgrids = Object.keys($app.subgrids ?? {}).filter((subgrid) =>
|
||||
subgrid.startsWith(id + '-')
|
||||
subgrid.startsWith(oldId + '-')
|
||||
)
|
||||
|
||||
oldSubgrids.forEach((subgrid) => {
|
||||
if ($app.subgrids) {
|
||||
$app.subgrids[subgrid.replace(id, newId)] = $app.subgrids[subgrid]
|
||||
$app.subgrids[subgrid.replace(oldId, newId)] = $app.subgrids[subgrid]
|
||||
delete $app.subgrids[subgrid]
|
||||
}
|
||||
})
|
||||
@@ -103,11 +103,11 @@
|
||||
processRunnable(from, to, x)
|
||||
})
|
||||
}
|
||||
propagateRename(id, newId)
|
||||
propagateRename(oldId, newId)
|
||||
if (item?.data.type == 'tablecomponent') {
|
||||
for (let c of item.data.actionButtons) {
|
||||
let old = c.id
|
||||
c.id = c.id.replace(id + '_', newId + '_')
|
||||
c.id = c.id.replace(oldId + '_', newId + '_')
|
||||
propagateRename(old, c.id)
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@
|
||||
) {
|
||||
for (let c of item.data.actions ?? []) {
|
||||
let old = c.id
|
||||
c.id = c.id.replace(id + '_', newId + '_')
|
||||
c.id = c.id.replace(oldId + '_', newId + '_')
|
||||
propagateRename(old, c.id)
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@
|
||||
if (item?.data.type === 'menucomponent') {
|
||||
for (let c of item.data.menuItems) {
|
||||
let old = c.id
|
||||
c.id = c.id.replace(id + '_', newId + '_')
|
||||
c.id = c.id.replace(oldId + '_', newId + '_')
|
||||
propagateRename(old, c.id)
|
||||
}
|
||||
}
|
||||
@@ -277,11 +277,7 @@
|
||||
</button>
|
||||
{#if selectable && renamable && $selectedComponent?.includes(id)}
|
||||
<div class="h-3">
|
||||
<IdEditor
|
||||
{id}
|
||||
on:selected={() => ($selectedComponent = [id])}
|
||||
on:save={({ detail }) => renameId(detail)}
|
||||
/></div
|
||||
<IdEditor {id} onChange={({ oldId, newId }) => renameId(oldId, newId)} /></div
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -225,11 +225,11 @@
|
||||
acceptUnderScores
|
||||
reservedIds={dfs(flowStore?.val?.value.modules ?? [], (x) => x.id)}
|
||||
bind:value={newId}
|
||||
on:save={(e) => {
|
||||
dispatch('changeId', { id, newId: e.detail, deps: getDeps?.dependents ?? {} })
|
||||
onSave={({ oldId, newId }) => {
|
||||
dispatch('changeId', { id: oldId, newId, deps: getDeps?.dependents ?? {} })
|
||||
editId = false
|
||||
}}
|
||||
on:close={() => {
|
||||
onClose={() => {
|
||||
editId = false
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user