fix: schema configuration (#29000)

This commit is contained in:
Jason Rasmussen
2026-06-11 19:05:07 -04:00
committed by GitHub
parent 13a7b4a276
commit c3e23a6b3a
5 changed files with 187 additions and 8 deletions
@@ -2,7 +2,19 @@
import SchemaAlbumPicker from '$lib/components/SchemaAlbumPicker.svelte';
import Self from '$lib/components/SchemaConfiguration.svelte';
import type { JSONSchemaProperty, SchemaConfig } from '$lib/types';
import { CodeBlock, Field, Input, Label, MultiSelect, NumberInput, Select, Switch, Text } from '@immich/ui';
import {
CodeBlock,
Field,
HelperText,
Input,
Label,
MultiSelect,
NumberInput,
Select,
Switch,
Text,
} from '@immich/ui';
import { t } from 'svelte-i18n';
type Props = {
schema: JSONSchemaProperty;
@@ -75,12 +87,11 @@
<Select options={schema.enum} bind:value={getString, setValue} />
</Field>
{:else if schema.array}
<!-- {@const values = getValue<string[]>([])}
{@const values = getValue<string[]>([])}
<Field {label} {description}>
{#each values as value, i (i)}
<Input bind:value={() => getValue<string>(), setValue} />
{/each}
</Field> -->
<Input value={values.join(',')} disabled />
<HelperText>{$t('unsupported_field_type')}</HelperText>
</Field>
{:else if schema.type === 'boolean'}
<Field {label} {description}>
<Switch bind:checked={() => getBoolean(schema.default ?? false), setValue} />
@@ -2,6 +2,7 @@
import SchemaConfiguration from '$lib/components/SchemaConfiguration.svelte';
import PluginMethodPicker from '$lib/modals/PluginMethodPicker.svelte';
import { type JSONSchemaProperty, type SchemaConfig } from '$lib/types';
import { getWorkflowDefaultConfig } from '$lib/utils/workflow';
import { WorkflowTrigger, type PluginMethodResponseDto, type WorkflowStepDto } from '@immich/sdk';
import { FormModal, IconButton, modalManager, Stack, Text, Textarea } from '@immich/ui';
import { mdiPencilOutline } from '@mdi/js';
@@ -31,7 +32,7 @@
}
method = selected;
config = selected.schema ? {} : null;
config = selected.schema ? getWorkflowDefaultConfig(selected.schema as JSONSchemaProperty) : null;
};
void onPickMethod();
@@ -3,6 +3,7 @@
import { pluginManager } from '$lib/managers/plugin-manager.svelte';
import PluginMethodPicker from '$lib/modals/PluginMethodPicker.svelte';
import { type JSONSchemaProperty, type SchemaConfig } from '$lib/types';
import { getWorkflowDefaultConfig } from '$lib/utils/workflow';
import { WorkflowTrigger, type WorkflowStepDto } from '@immich/sdk';
import { Button, FormModal, modalManager, Stack, Text, Textarea } from '@immich/ui';
import { mdiPencilOutline } from '@mdi/js';
@@ -30,7 +31,7 @@
}
method = selected;
config = selected.schema ? {} : null;
config = selected.schema ? getWorkflowDefaultConfig(selected.schema as JSONSchemaProperty) : null;
};
</script>
+112
View File
@@ -0,0 +1,112 @@
import { getWorkflowDefaultConfig } from '$lib/utils/workflow';
describe(getWorkflowDefaultConfig.name, () => {
describe('required properties', () => {
it('should use a default value', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'boolean',
default: true,
},
},
required: ['test'],
}),
).toEqual({ test: true });
});
it('should default to an empty array', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'string',
array: true,
},
},
required: ['test'],
}),
).toEqual({ test: [] });
});
it('should default to false', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'boolean',
},
},
required: ['test'],
}),
).toEqual({ test: false });
});
it('should default to 0 (integer)', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'integer',
},
},
required: ['test'],
}),
).toEqual({ test: 0 });
});
it('should default to 0 (number)', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'number',
},
},
required: ['test'],
}),
).toEqual({ test: 0 });
});
it('should default to an empty string', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
test: {
type: 'string',
},
},
required: ['test'],
}),
).toEqual({ test: '' });
});
it('should default recursively', () => {
expect(
getWorkflowDefaultConfig({
type: 'object',
properties: {
parent: {
type: 'object',
properties: {
test: {
type: 'string',
array: true,
},
},
required: ['test'],
},
},
required: ['parent'],
}),
).toEqual({ parent: { test: [] } });
});
});
});
+54
View File
@@ -1,5 +1,6 @@
import { WorkflowTrigger } from '@immich/sdk';
import type { MessageFormatter } from 'svelte-i18n';
import type { JSONSchemaProperty } from '$lib/types';
export const getTriggerName = ($t: MessageFormatter, type: WorkflowTrigger) => {
switch (type) {
@@ -34,3 +35,56 @@ export const getTriggerDescription = ($t: MessageFormatter, type: WorkflowTrigge
}
}
};
export const getWorkflowDefaultConfig = (schema: JSONSchemaProperty) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const config: any = {};
const requiredProperties = schema.required ?? [];
for (const [key, property] of Object.entries(schema.properties ?? {})) {
// default values
if (property.default) {
config[key] = property.default;
break;
}
if (!requiredProperties.includes(key)) {
continue;
}
if (property.array) {
config[key] = [];
continue;
}
switch (property.type) {
case 'string': {
config[key] = '';
break;
}
case 'integer':
case 'number': {
config[key] = 0;
break;
}
case 'boolean': {
config[key] = false;
break;
}
case 'object': {
config[key] = property.properties ? getWorkflowDefaultConfig(property) : {};
break;
}
default: {
console.log(`Unknown configuration type: ${property.type}`);
}
}
}
return config;
};