Files
windmill/frontend/src/lib/components/moveRenameManager.ts
T
9c28bbfd69 feat(frontend): new path component (#9017)
* stash

* ui nits

* Fix contenteditable feedback look (duplicate typing)

* fix right icon wrong position with placeholder

* user editor in Path editor takes correct width

* nits

* nit

* chore: remove assets-operator changes (moved to separate PR)

These files were mistakenly included in this PR and belong in a dedicated PR
("Allow assets page to operators").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: remove sidebar assets-operator change (moved to separate PR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix disabled

* border nit

* Fix disabled styling

* Apply suggestion from @cubic-dev-ai[bot]

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* nit

* Update frontend/src/lib/components/text_input/TextInput.svelte

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* Fix disabled tabindex and aria-disabled on contenteditable Select

The useContentEditable branch had an unconditional tabindex="0", keeping
a disabled Select in the tab order, and was missing aria-disabled.
Mirror the TextInput div branch.

Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>

* fix: drop obsolete hideFullPath prop from EditorHeader Path usage

* invalidate autocomplete paths on deploy

* nit pixel

* use Badge in auto complete

* nit prevent default

* fix(autocomplete): don't let stale fetch clobber forced refresh

A non-forced fetchWorkspacePaths() that started before invalidateWorkspacePaths()
could still resolve afterward, overwrite the cache, and clear forceNextFetch —
making the post-deploy refresh a no-op. Only write back from the promise that
is still the current pending one, and only clear the force flag when the
completing fetch was itself forced.

* refactor(path): drop unreachable 'group' branch in owner-kind setter

The Select only offers user/folder, so the 'group' branch was dead. Leave a
short note pointing at validateName which still accepts 'group' for
forward-compat.

* fix(path): respect disableEditing on owner-kind selector

Other path-editor controls disable on (disabled || disableEditing); the
owner-kind Select only checked `disabled`, so read-only users (trigger
editors with !can_write) could still toggle User/Folder and mutate the
bound path. Reuse the existing nameDisabled flag.

* Revert "fix(autocomplete): don't let stale fetch clobber forced refresh"

This reverts commit 6649975714.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com>
2026-05-20 13:26:34 +00:00

83 lines
2.3 KiB
TypeScript

import { AppService, FlowService, ScriptService } from '$lib/gen'
import { invalidateWorkspacePaths } from './PathNameAutocomplete.svelte'
type ItemKind = 'flow' | 'script' | 'app'
/**
* Check whether a flow uses on_behalf_of_email.
* Callers use this to show a warning before saving.
*/
export async function checkFlowOnBehalfOf(
workspace: string,
path: string
): Promise<string | undefined> {
const flow = await FlowService.getFlowByPath({ workspace, path })
return flow.on_behalf_of_email
}
/**
* Shared utility that performs the API call to update an item's path and summary.
* No toast, no navigation — callers handle those.
*
* Note: on_behalf_of_email is intentionally omitted from flow updates for security
* reasons — the backend will redeploy the flow on behalf of the current user.
*/
export async function updateItemPathAndSummary(opts: {
workspace: string
kind: ItemKind
initialPath: string
newPath: string
newSummary: string
labels?: string[]
}): Promise<void> {
const { workspace, kind, initialPath, newPath, newSummary, labels } = opts
if (kind === 'flow') {
const flow = await FlowService.getFlowByPath({ workspace, path: initialPath })
await FlowService.updateFlow({
workspace,
path: initialPath,
requestBody: {
path: newPath,
summary: newSummary,
description: flow.description,
value: flow.value,
schema: flow.schema,
tag: flow.tag,
dedicated_worker: flow.dedicated_worker,
ws_error_handler_muted: flow.ws_error_handler_muted,
visible_to_runner_only: flow.visible_to_runner_only,
labels
}
})
} else if (kind === 'script') {
const script = await ScriptService.getScriptByPath({ workspace, path: initialPath })
script.summary = newSummary
await ScriptService.createScript({
workspace,
requestBody: {
...script,
description: script.description ?? '',
lock: script.lock,
parent_hash: script.hash,
path: newPath,
labels
}
})
} else if (kind === 'app') {
await AppService.updateApp({
workspace,
path: initialPath,
requestBody: {
path: newPath !== initialPath ? newPath : undefined,
summary: newSummary,
labels
}
})
}
// The path changed (rename/move) — drop the autocomplete cache so the new
// path shows up immediately instead of after the 60s TTL.
invalidateWorkspacePaths(workspace)
}