mirror of
https://github.com/immich-app/immich.git
synced 2026-05-21 23:26:31 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54d7b0feb9 |
@@ -2417,6 +2417,7 @@
|
||||
"use_browser_locale_description": "Format dates, times, and numbers based on your browser locale",
|
||||
"use_current_connection": "Use current connection",
|
||||
"use_custom_date_range": "Use custom date range instead",
|
||||
"use_template": "Use template",
|
||||
"user": "User",
|
||||
"user_has_been_deleted": "This user has been deleted.",
|
||||
"user_id": "User ID",
|
||||
@@ -2491,6 +2492,7 @@
|
||||
"workflow_name": "Workflow name",
|
||||
"workflow_navigation_prompt": "Are you sure you want to leave without saving your changes?",
|
||||
"workflow_summary": "Workflow summary",
|
||||
"workflow_templates": "Workflow templates",
|
||||
"workflow_update_success": "Workflow updated successfully",
|
||||
"workflow_updated": "Workflow updated",
|
||||
"workflows": "Workflows",
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { workflowTemplates, type WorkflowTemplate } from '$lib/templates/workflow-templates';
|
||||
import { FormModal, Icon, ListButton, Text } from '@immich/ui';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
type Props = {
|
||||
onClose: (template?: WorkflowTemplate) => void;
|
||||
};
|
||||
|
||||
const { onClose }: Props = $props();
|
||||
|
||||
let selected = $state<WorkflowTemplate>();
|
||||
|
||||
const onSubmit = () => onClose(selected);
|
||||
</script>
|
||||
|
||||
<FormModal title={$t('workflow_templates')} {onClose} {onSubmit} disabled={!selected} size="medium">
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each workflowTemplates as template (template.id)}
|
||||
<ListButton selected={selected?.id === template.id} onclick={() => (selected = template)}>
|
||||
<div class="flex w-full items-center gap-3 text-start">
|
||||
<div
|
||||
class="flex size-9 shrink-0 items-center justify-center rounded-lg bg-immich-primary/10 text-immich-primary dark:bg-immich-dark-primary/15 dark:text-immich-dark-primary"
|
||||
>
|
||||
<Icon icon={template.icon} size="18" />
|
||||
</div>
|
||||
<div class="min-w-0 grow">
|
||||
<Text fontWeight="medium">{template.name}</Text>
|
||||
<Text size="tiny" color="muted">{template.description}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</ListButton>
|
||||
{/each}
|
||||
</div>
|
||||
</FormModal>
|
||||
@@ -10,10 +10,11 @@ import {
|
||||
type WorkflowUpdateDto,
|
||||
} from '@immich/sdk';
|
||||
import { modalManager, toastManager, type ActionItem } from '@immich/ui';
|
||||
import { mdiCodeJson, mdiDelete, mdiPause, mdiPencil, mdiPlay, mdiPlus } from '@mdi/js';
|
||||
import { mdiCodeJson, mdiDelete, mdiFileDocumentMultipleOutline, mdiPause, mdiPencil, mdiPlay, mdiPlus } from '@mdi/js';
|
||||
import type { MessageFormatter } from 'svelte-i18n';
|
||||
import { goto } from '$app/navigation';
|
||||
import { eventManager } from '$lib/managers/event-manager.svelte';
|
||||
import WorkflowTemplatePicker from '$lib/modals/WorkflowTemplatePicker.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getFormatter } from '$lib/utils/i18n';
|
||||
@@ -33,7 +34,25 @@ export const getWorkflowsActions = ($t: MessageFormatter) => {
|
||||
}),
|
||||
};
|
||||
|
||||
return { Create };
|
||||
const UseTemplate: ActionItem = {
|
||||
title: $t('use_template'),
|
||||
icon: mdiFileDocumentMultipleOutline,
|
||||
onAction: async () => {
|
||||
const template = await modalManager.show(WorkflowTemplatePicker, {});
|
||||
if (!template) {
|
||||
return;
|
||||
}
|
||||
await handleCreateWorkflow({
|
||||
trigger: template.trigger,
|
||||
steps: template.steps,
|
||||
name: template.name,
|
||||
description: template.description,
|
||||
enabled: false,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
return { Create, UseTemplate };
|
||||
};
|
||||
|
||||
export const getWorkflowActions = ($t: MessageFormatter, workflow: WorkflowResponseDto) => {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { WorkflowTrigger, type WorkflowStepDto } from '@immich/sdk';
|
||||
import { mdiAccountGroupOutline, mdiMonitorScreenshot } from '@mdi/js';
|
||||
|
||||
export type WorkflowTemplate = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
trigger: WorkflowTrigger;
|
||||
steps: WorkflowStepDto[];
|
||||
};
|
||||
|
||||
export const workflowTemplates: WorkflowTemplate[] = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Archive screenshots to album',
|
||||
description: 'Add uploads with "screenshot" in the filename to an album and archive them',
|
||||
icon: mdiMonitorScreenshot,
|
||||
trigger: WorkflowTrigger.AssetCreate,
|
||||
steps: [
|
||||
{
|
||||
method: 'immich-plugin-core#assetFileFilter',
|
||||
config: {
|
||||
pattern: 'screenshot',
|
||||
matchType: 'contains',
|
||||
caseSensitive: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
method: 'immich-plugin-core#assetAddToAlbums',
|
||||
config: { albumIds: [] },
|
||||
},
|
||||
{
|
||||
method: 'immich-plugin-core#assetArchive',
|
||||
config: { inverse: false },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Add person to album',
|
||||
description: 'Add assets to an album when a specific person is recognized',
|
||||
icon: mdiAccountGroupOutline,
|
||||
trigger: WorkflowTrigger.PersonRecognized,
|
||||
steps: [
|
||||
{
|
||||
method: 'immich-plugin-core#filterPerson',
|
||||
config: { personIds: [], matchAny: true },
|
||||
},
|
||||
{
|
||||
method: 'immich-plugin-core#assetAddToAlbums',
|
||||
config: { albumIds: [] },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -59,7 +59,7 @@
|
||||
});
|
||||
};
|
||||
|
||||
const { Create } = $derived(getWorkflowsActions($t));
|
||||
const { Create, UseTemplate } = $derived(getWorkflowsActions($t));
|
||||
|
||||
const onWorkflowCreate = async (response: WorkflowResponseDto) => {
|
||||
await goto(Route.viewWorkflow(response));
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<OnEvents {onWorkflowCreate} {onWorkflowUpdate} {onWorkflowDelete} />
|
||||
|
||||
<UserPageLayout title={data.meta.title} actions={[Create]} scrollbar={false}>
|
||||
<UserPageLayout title={data.meta.title} actions={[UseTemplate, Create]} scrollbar={false}>
|
||||
<section class="flex place-content-center sm:mx-4">
|
||||
<Container center size="large" class="pb-28">
|
||||
{#if workflows.length === 0}
|
||||
|
||||
Reference in New Issue
Block a user