diff --git a/backend/.sqlx/query-6f857451605a0453c82b4faada248689c02edde28433eb388092d30c94922e76.json b/backend/.sqlx/query-6f857451605a0453c82b4faada248689c02edde28433eb388092d30c94922e76.json deleted file mode 100644 index 2ebaaabdfd..0000000000 --- a/backend/.sqlx/query-6f857451605a0453c82b4faada248689c02edde28433eb388092d30c94922e76.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT path,\n typ as \"typ!: UserDraftItemKind\",\n created_at as \"saved_at!\"\n FROM draft\n WHERE workspace_id = $1 AND email = $2\n ORDER BY created_at DESC", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "typ!: UserDraftItemKind", - "type_info": { - "Custom": { - "name": "draft_kind", - "kind": { - "Enum": [ - "script", - "flow", - "app", - "raw_app", - "resource", - "variable", - "trigger_schedule", - "trigger_webhook", - "trigger_default_email", - "trigger_email", - "trigger_http", - "trigger_websocket", - "trigger_postgres", - "trigger_kafka", - "trigger_nats", - "trigger_mqtt", - "trigger_sqs", - "trigger_gcp", - "trigger_azure", - "trigger_poll", - "trigger_cli", - "trigger_nextcloud", - "trigger_google", - "trigger_github" - ] - } - } - } - }, - { - "ordinal": 2, - "name": "saved_at!", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "6f857451605a0453c82b4faada248689c02edde28433eb388092d30c94922e76" -} diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index f6822ef8be..d35163333a 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -7910,33 +7910,6 @@ paths: format: date-time required: [status, current_timestamp] - /w/{workspace}/drafts/list_drafts: - get: - summary: list the current user's drafts in a workspace (metadata only) - operationId: listDrafts - tags: - - draft - parameters: - - $ref: "#/components/parameters/WorkspaceId" - responses: - "200": - description: list of (path, kind, saved_at) tuples - content: - application/json: - schema: - type: array - items: - type: object - properties: - path: - type: string - typ: - $ref: "#/components/schemas/UserDraftItemKind" - saved_at: - type: string - format: date-time - required: [path, typ, saved_at] - /w/{workspace}/drafts/get_draft/{kind}/{path}: get: summary: fetch the current user's draft at a path diff --git a/backend/windmill-api/src/drafts.rs b/backend/windmill-api/src/drafts.rs index d9858393a2..85c6073f99 100644 --- a/backend/windmill-api/src/drafts.rs +++ b/backend/windmill-api/src/drafts.rs @@ -24,7 +24,6 @@ pub fn workspaced_service() -> Router { Router::new() .route("/get/{kind}/{*path}", get(get_draft_for_user)) .route("/save_draft/{kind}/{*path}", post(save_draft)) - .route("/list_drafts", get(list_drafts)) .route("/get_draft/{kind}/{*path}", get(get_draft)) } @@ -165,36 +164,6 @@ async fn save_draft( } } -#[derive(Serialize, Debug)] -pub struct DraftListItem { - pub path: String, - pub typ: UserDraftItemKind, - pub saved_at: chrono::DateTime, -} - -/// Metadata-only listing of the current user's drafts in a workspace. -/// Excludes the legacy NULL-email rows. Ordered most-recently-saved first. -async fn list_drafts( - authed: ApiAuthed, - Extension(db): Extension, - Path(w_id): Path, -) -> Result>> { - let rows = sqlx::query_as!( - DraftListItem, - r#"SELECT path, - typ as "typ!: UserDraftItemKind", - created_at as "saved_at!" - FROM draft - WHERE workspace_id = $1 AND email = $2 - ORDER BY created_at DESC"#, - &w_id, - &authed.email, - ) - .fetch_all(&db) - .await?; - Ok(Json(rows)) -} - #[derive(Serialize, Debug)] pub struct OwnDraft { pub value: sqlx::types::Json>, diff --git a/frontend/src/lib/components/copilot/chat/global/core.test.ts b/frontend/src/lib/components/copilot/chat/global/core.test.ts index 0b96cbfd9b..ac28f6216e 100644 --- a/frontend/src/lib/components/copilot/chat/global/core.test.ts +++ b/frontend/src/lib/components/copilot/chat/global/core.test.ts @@ -151,13 +151,7 @@ vi.mock('$lib/gen', async () => { ) } return { value: entry.value, saved_at: entry.saved_at } - }), - listDrafts: vi.fn(async () => - [...draftDb.store.entries()].map(([k, v]) => { - const slash = k.indexOf('/') - return { typ: k.slice(0, slash), path: k.slice(slash + 1), saved_at: v.saved_at } - }) - ) + }) }) } }) @@ -179,7 +173,7 @@ import { setOpenPreviewHandler } from './core' import { UserDraft, __resetUserDraftForTesting } from '$lib/userDraft.svelte' -import { clearGlobalDrafts } from './userDraftAdapter' +import { clearEphemeralSecretVariableDraftValues } from './userDraftAdapter' import { bundleRawAppDraft } from './rawAppBundlerBridge' import { AppService, @@ -273,7 +267,7 @@ describe('global AI tools', () => { __resetUserDraftForTesting() localStorage.clear() draftDb.reset() - await clearGlobalDrafts(WORKSPACE) + clearEphemeralSecretVariableDraftValues(WORKSPACE) vi.clearAllMocks() }) diff --git a/frontend/src/lib/components/copilot/chat/global/gate.ts b/frontend/src/lib/components/copilot/chat/global/gate.ts index 664f06ff39..807e71c09d 100644 --- a/frontend/src/lib/components/copilot/chat/global/gate.ts +++ b/frontend/src/lib/components/copilot/chat/global/gate.ts @@ -10,9 +10,8 @@ * * When the mode is ready to ship to everyone, replace every call to * `isGlobalAiEnabled()` with `true` and delete this file. The references are - * intentionally narrow (chat mode visibility, custom prompt settings, the - * `change_mode` tool enum, and the `/global_drafts` dev route) so the rip-out - * is a small grep. + * intentionally narrow (chat mode visibility, custom prompt settings, and the + * `change_mode` tool enum) so the rip-out is a small grep. */ const STORAGE_KEY = 'wm_dev_global_ai' diff --git a/frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts b/frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts index e2c38a4d9e..e48ff9397f 100644 --- a/frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts +++ b/frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts @@ -37,24 +37,6 @@ const TRIGGER_KIND_BY_DRAFT_KIND = Object.fromEntries( ]) ) as Partial> -const GLOBAL_DRAFT_KINDS = [ - 'script', - 'flow', - 'raw_app', - 'trigger_schedule', - 'trigger_http', - 'trigger_websocket', - 'trigger_kafka', - 'trigger_nats', - 'trigger_postgres', - 'trigger_mqtt', - 'trigger_sqs', - 'trigger_gcp', - 'trigger_azure', - 'resource', - 'variable' -] as const satisfies UserDraftItemKind[] - const secretVariableDraftValues = new Map>() function clone(value: T): T { @@ -103,7 +85,7 @@ export function clearEphemeralSecretVariableDraftValue(workspace: string, path: if (workspaceValues.size === 0) secretVariableDraftValues.delete(workspace) } -function clearEphemeralSecretVariableDraftValues(workspace: string): void { +export function clearEphemeralSecretVariableDraftValues(workspace: string): void { secretVariableDraftValues.delete(workspace) } @@ -569,24 +551,3 @@ export async function deleteGlobalDraft( }) if (type === 'variable') clearEphemeralSecretVariableDraftValue(workspace, storagePath) } - -export async function clearGlobalDrafts(workspace: string): Promise { - // `UserDraft.list` only sees in-tab mounted entries post #9351, so - // enumerate the user's persisted drafts from the DB instead and delete - // each global-mode kind. - const kinds = new Set(GLOBAL_DRAFT_KINDS) - const drafts = await DraftService.listDrafts({ workspace }) - for (const draft of drafts) { - if (!kinds.has(draft.typ)) continue - await UserDraftDbSyncer.save({ - workspace, - itemKind: draft.typ, - path: draft.path, - value: null, - immediate: true, - force: true, - throwOnError: true - }) - } - clearEphemeralSecretVariableDraftValues(workspace) -} diff --git a/frontend/src/lib/userDraft.svelte.ts b/frontend/src/lib/userDraft.svelte.ts index 9a106bff39..0ebca0004b 100644 --- a/frontend/src/lib/userDraft.svelte.ts +++ b/frontend/src/lib/userDraft.svelte.ts @@ -480,8 +480,8 @@ export const UserDraft = { /** * List currently-mounted live entries for `workspace`. Without the * localStorage layer, "list" is meaningful only for in-tab entries — - * for a workspace-wide view across sessions, call - * `DraftService.listDrafts` instead. + * for a workspace-wide view across sessions, use the deployed list + * endpoints with `includeDraftOnly` (which flag the caller's drafts). */ list(opts?: UserDraftListOptions): UserDraftEntry[] { const ws = resolveWorkspace(opts) diff --git a/frontend/src/routes/(root)/(logged)/global_drafts/+page.js b/frontend/src/routes/(root)/(logged)/global_drafts/+page.js deleted file mode 100644 index d62178ddb3..0000000000 --- a/frontend/src/routes/(root)/(logged)/global_drafts/+page.js +++ /dev/null @@ -1,5 +0,0 @@ -export function load() { - return { - stuff: { title: 'Global AI drafts' } - } -} diff --git a/frontend/src/routes/(root)/(logged)/global_drafts/+page.svelte b/frontend/src/routes/(root)/(logged)/global_drafts/+page.svelte deleted file mode 100644 index fed900526c..0000000000 --- a/frontend/src/routes/(root)/(logged)/global_drafts/+page.svelte +++ /dev/null @@ -1,105 +0,0 @@ - - -{#if enabled} -
-
-
-

Global drafts

-

- Dev-only inspector for the current user's DB-backed drafts. -

-
- -
- - {#if drafts.length === 0} -

No drafts.

- {:else} -
    - {#each drafts as draft (draftKey(draft))} -
  • -
    - {draft.typ} - · - {draft.path} - {draft.saved_at} -
    -
  • - {/each} -
- {/if} -
-{/if}