From 99f94a363d29a45eaac9c837433c6d21ad4fe717 Mon Sep 17 00:00:00 2001 From: Ben Beckford Date: Tue, 23 Jun 2026 06:03:33 -0700 Subject: [PATCH] chore(web): workflow property ordering (#29261) * chore(web): workflow property ordering * chore(web): extract schema property sorting to method --- packages/plugin-core/manifest.json | 14 +++++++++++--- server/src/dtos/json-schema.dto.ts | 7 ++++++- web/src/lib/components/SchemaConfiguration.svelte | 6 ++++-- web/src/lib/types.ts | 5 ++++- .../workflows/[workflowId]/WorkflowStepCard.svelte | 2 +- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/plugin-core/manifest.json b/packages/plugin-core/manifest.json index 54642476b2..0f1b88827c 100644 --- a/packages/plugin-core/manifest.json +++ b/packages/plugin-core/manifest.json @@ -278,7 +278,9 @@ "title": "Album IDs", "array": true, "description": "Target album IDs", - "uiHint": "AlbumId" + "uiHint": { + "type": "AlbumId" + } }, "albumName": { "type": "string", @@ -368,14 +370,20 @@ "type": "string", "title": "Album ID", "description": "Target album ID", - "uiHint": "AlbumId" + "uiHint": { + "type": "AlbumId", + "order": 1 + } }, "albumIds": { "type": "string", "title": "Album IDs", "description": "Target album IDs", "array": true, - "uiHint": "AlbumId" + "uiHint": { + "type": "AlbumId", + "order": 2 + } } } } diff --git a/server/src/dtos/json-schema.dto.ts b/server/src/dtos/json-schema.dto.ts index 65b92277d5..81b14ad62a 100644 --- a/server/src/dtos/json-schema.dto.ts +++ b/server/src/dtos/json-schema.dto.ts @@ -14,7 +14,12 @@ const JsonSchemaPropertySchema = z enum: z.array(z.string()).optional().describe('Valid choices for enum types'), array: z.boolean().optional().describe('Type is an array type'), required: z.array(z.string()).optional().describe('A list of required properties'), - uiHint: z.string().optional(), + uiHint: z + .object({ + type: z.string().optional(), + order: z.int().optional(), + }) + .optional(), get properties() { return z.record(z.string(), JsonSchemaPropertySchema).optional(); }, diff --git a/web/src/lib/components/SchemaConfiguration.svelte b/web/src/lib/components/SchemaConfiguration.svelte index 37e799984f..1e85e6d945 100644 --- a/web/src/lib/components/SchemaConfiguration.svelte +++ b/web/src/lib/components/SchemaConfiguration.svelte @@ -51,6 +51,8 @@ }; const setUiHintValue = (values: string[]) => setValue(schema.array ? values : values[0]); + const getSchemaProperties = (schema: JSONSchemaProperty) => + Object.entries(schema.properties ?? {}).sort((a, b) => (a[1].uiHint?.order ?? 0) - (b[1].uiHint?.order ?? 0)); const getBoolean = (defaultValue = false) => getValue(defaultValue); const getString = () => getValue(); @@ -72,11 +74,11 @@ {/if}
- {#each Object.entries(schema.properties ?? {}) as [childKey, childSchema] (childKey)} + {#each getSchemaProperties(schema) as [childKey, childSchema] (childKey)} {/each}
-{:else if schema.uiHint === 'AlbumId'} +{:else if schema.uiHint?.type === 'AlbumId'} {:else if schema.enum && schema.array} diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index 41d98df097..ee5a03bb1b 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -96,7 +96,10 @@ export type JSONSchemaProperty = { array?: boolean; properties?: Record; required?: string[]; - uiHint?: 'AlbumId' | 'AssetId' | 'PersonId'; + uiHint?: { + type?: 'AlbumId' | 'AssetId' | 'PersonId'; + order?: number; + }; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/web/src/routes/(user)/workflows/[workflowId]/WorkflowStepCard.svelte b/web/src/routes/(user)/workflows/[workflowId]/WorkflowStepCard.svelte index 5dcf431b39..d3dec41f48 100644 --- a/web/src/routes/(user)/workflows/[workflowId]/WorkflowStepCard.svelte +++ b/web/src/routes/(user)/workflows/[workflowId]/WorkflowStepCard.svelte @@ -55,7 +55,7 @@ ); const isGhost = $derived(step.id === 'ghost'); - const getUiHint = (key: string) => schema?.properties?.[key]?.uiHint; + const getUiHint = (key: string) => schema?.properties?.[key]?.uiHint?.type; const toIds = (value: unknown): string[] => (Array.isArray(value) ? value.map(String) : [String(value)]); let dragImage = $state(); let isDropTarget = $state(false);