mirror of
https://github.com/immich-app/immich.git
synced 2025-12-21 17:25:35 +03:00
use showDialog directly
This commit is contained in:
@@ -2144,7 +2144,11 @@
|
|||||||
"trash_page_title": "Trash ({count})",
|
"trash_page_title": "Trash ({count})",
|
||||||
"trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.",
|
"trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.",
|
||||||
"trigger": "Trigger",
|
"trigger": "Trigger",
|
||||||
|
"trigger_asset_uploaded": "Asset Uploaded",
|
||||||
|
"trigger_asset_uploaded_description": "Triggered when a new asset is uploaded",
|
||||||
"trigger_description": "An event that kick off the workflow",
|
"trigger_description": "An event that kick off the workflow",
|
||||||
|
"trigger_person_recognized": "Person Recognized",
|
||||||
|
"trigger_person_recognized_description": "Triggered when a person is detected",
|
||||||
"trigger_type": "Trigger type",
|
"trigger_type": "Trigger type",
|
||||||
"troubleshoot": "Troubleshoot",
|
"troubleshoot": "Troubleshoot",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
|
|||||||
@@ -14,42 +14,30 @@ class PluginTriggerResponseDto {
|
|||||||
/// Returns a new [PluginTriggerResponseDto] instance.
|
/// Returns a new [PluginTriggerResponseDto] instance.
|
||||||
PluginTriggerResponseDto({
|
PluginTriggerResponseDto({
|
||||||
required this.contextType,
|
required this.contextType,
|
||||||
required this.description,
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
required this.type,
|
||||||
});
|
});
|
||||||
|
|
||||||
PluginContextType contextType;
|
PluginContextType contextType;
|
||||||
|
|
||||||
String description;
|
|
||||||
|
|
||||||
String name;
|
|
||||||
|
|
||||||
PluginTriggerType type;
|
PluginTriggerType type;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PluginTriggerResponseDto &&
|
bool operator ==(Object other) => identical(this, other) || other is PluginTriggerResponseDto &&
|
||||||
other.contextType == contextType &&
|
other.contextType == contextType &&
|
||||||
other.description == description &&
|
|
||||||
other.name == name &&
|
|
||||||
other.type == type;
|
other.type == type;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(contextType.hashCode) +
|
(contextType.hashCode) +
|
||||||
(description.hashCode) +
|
|
||||||
(name.hashCode) +
|
|
||||||
(type.hashCode);
|
(type.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PluginTriggerResponseDto[contextType=$contextType, description=$description, name=$name, type=$type]';
|
String toString() => 'PluginTriggerResponseDto[contextType=$contextType, type=$type]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
json[r'contextType'] = this.contextType;
|
json[r'contextType'] = this.contextType;
|
||||||
json[r'description'] = this.description;
|
|
||||||
json[r'name'] = this.name;
|
|
||||||
json[r'type'] = this.type;
|
json[r'type'] = this.type;
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
@@ -64,8 +52,6 @@ class PluginTriggerResponseDto {
|
|||||||
|
|
||||||
return PluginTriggerResponseDto(
|
return PluginTriggerResponseDto(
|
||||||
contextType: PluginContextType.fromJson(json[r'contextType'])!,
|
contextType: PluginContextType.fromJson(json[r'contextType'])!,
|
||||||
description: mapValueOfType<String>(json, r'description')!,
|
|
||||||
name: mapValueOfType<String>(json, r'name')!,
|
|
||||||
type: PluginTriggerType.fromJson(json[r'type'])!,
|
type: PluginTriggerType.fromJson(json[r'type'])!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -115,8 +101,6 @@ class PluginTriggerResponseDto {
|
|||||||
/// The list of required keys that must be present in a JSON.
|
/// The list of required keys that must be present in a JSON.
|
||||||
static const requiredKeys = <String>{
|
static const requiredKeys = <String>{
|
||||||
'contextType',
|
'contextType',
|
||||||
'description',
|
|
||||||
'name',
|
|
||||||
'type',
|
'type',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18459,12 +18459,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"description": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
"type": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
@@ -18475,8 +18469,6 @@
|
|||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"contextType",
|
"contextType",
|
||||||
"description",
|
|
||||||
"name",
|
|
||||||
"type"
|
"type"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
|
|||||||
@@ -968,8 +968,6 @@ export type PluginResponseDto = {
|
|||||||
};
|
};
|
||||||
export type PluginTriggerResponseDto = {
|
export type PluginTriggerResponseDto = {
|
||||||
contextType: PluginContextType;
|
contextType: PluginContextType;
|
||||||
description: string;
|
|
||||||
name: string;
|
|
||||||
"type": PluginTriggerType;
|
"type": PluginTriggerType;
|
||||||
};
|
};
|
||||||
export type QueueResponseDto = {
|
export type QueueResponseDto = {
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import type { JSONSchema } from 'src/types/plugin-schema.types';
|
|||||||
import { ValidateEnum } from 'src/validation';
|
import { ValidateEnum } from 'src/validation';
|
||||||
|
|
||||||
export class PluginTriggerResponseDto {
|
export class PluginTriggerResponseDto {
|
||||||
name!: string;
|
|
||||||
@ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType' })
|
@ValidateEnum({ enum: PluginTriggerType, name: 'PluginTriggerType' })
|
||||||
type!: PluginTriggerType;
|
type!: PluginTriggerType;
|
||||||
description!: string;
|
|
||||||
@ValidateEnum({ enum: PluginContextType, name: 'PluginContextType' })
|
@ValidateEnum({ enum: PluginContextType, name: 'PluginContextType' })
|
||||||
contextType!: PluginContextType;
|
contextType!: PluginContextType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,17 @@
|
|||||||
import { PluginContext, PluginTriggerType } from 'src/enum';
|
import { PluginContext, PluginTriggerType } from 'src/enum';
|
||||||
|
|
||||||
export type PluginTrigger = {
|
export type PluginTrigger = {
|
||||||
name: string;
|
|
||||||
type: PluginTriggerType;
|
type: PluginTriggerType;
|
||||||
description: string;
|
|
||||||
contextType: PluginContext;
|
contextType: PluginContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pluginTriggers: PluginTrigger[] = [
|
export const pluginTriggers: PluginTrigger[] = [
|
||||||
{
|
{
|
||||||
name: 'Asset Uploaded',
|
|
||||||
type: PluginTriggerType.AssetCreate,
|
type: PluginTriggerType.AssetCreate,
|
||||||
description: 'Triggered when a new asset is uploaded',
|
|
||||||
contextType: PluginContext.Asset,
|
contextType: PluginContext.Asset,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Person Recognized',
|
|
||||||
type: PluginTriggerType.PersonRecognized,
|
type: PluginTriggerType.PersonRecognized,
|
||||||
description: 'Triggered when a person is detected',
|
|
||||||
contextType: PluginContext.Person,
|
contextType: PluginContext.Person,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PluginActionResponseDto, PluginFilterResponseDto, PluginTriggerResponseDto } from '@immich/sdk';
|
import {
|
||||||
|
PluginTriggerType,
|
||||||
|
type PluginActionResponseDto,
|
||||||
|
type PluginFilterResponseDto,
|
||||||
|
type PluginTriggerResponseDto,
|
||||||
|
} from '@immich/sdk';
|
||||||
import { Icon, IconButton, Text } from '@immich/ui';
|
import { Icon, IconButton, Text } from '@immich/ui';
|
||||||
import { mdiClose, mdiFilterOutline, mdiFlashOutline, mdiPlayCircleOutline, mdiViewDashboardOutline } from '@mdi/js';
|
import { mdiClose, mdiFilterOutline, mdiFlashOutline, mdiPlayCircleOutline, mdiViewDashboardOutline } from '@mdi/js';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
@@ -12,6 +17,20 @@
|
|||||||
|
|
||||||
let { trigger, filters, actions }: Props = $props();
|
let { trigger, filters, actions }: Props = $props();
|
||||||
|
|
||||||
|
const getTriggerName = (triggerType: PluginTriggerType) => {
|
||||||
|
switch (triggerType) {
|
||||||
|
case PluginTriggerType.AssetCreate: {
|
||||||
|
return $t('trigger_asset_uploaded');
|
||||||
|
}
|
||||||
|
case PluginTriggerType.PersonRecognized: {
|
||||||
|
return $t('trigger_person_recognized');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return triggerType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let isOpen = $state(false);
|
let isOpen = $state(false);
|
||||||
let position = $state({ x: 0, y: 0 });
|
let position = $state({ x: 0, y: 0 });
|
||||||
let isDragging = $state(false);
|
let isDragging = $state(false);
|
||||||
@@ -96,7 +115,7 @@
|
|||||||
<Icon icon={mdiFlashOutline} size="18" class="text-primary" />
|
<Icon icon={mdiFlashOutline} size="18" class="text-primary" />
|
||||||
<span class="text-[10px] font-semibold uppercase tracking-wide">{$t('trigger')}</span>
|
<span class="text-[10px] font-semibold uppercase tracking-wide">{$t('trigger')}</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm truncate pl-5">{trigger.name}</p>
|
<p class="text-sm truncate pl-5">{getTriggerName(trigger.type)}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Connector -->
|
<!-- Connector -->
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { PluginTriggerType, type PluginTriggerResponseDto } from '@immich/sdk';
|
import { PluginTriggerType, type PluginTriggerResponseDto } from '@immich/sdk';
|
||||||
import { Icon, Text } from '@immich/ui';
|
import { Icon, Text } from '@immich/ui';
|
||||||
import { mdiFaceRecognition, mdiFileUploadOutline, mdiLightningBolt } from '@mdi/js';
|
import { mdiFaceRecognition, mdiFileUploadOutline, mdiLightningBolt } from '@mdi/js';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
trigger: PluginTriggerResponseDto;
|
trigger: PluginTriggerResponseDto;
|
||||||
@@ -24,6 +25,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTriggerName = (triggerType: PluginTriggerType) => {
|
||||||
|
switch (triggerType) {
|
||||||
|
case PluginTriggerType.AssetCreate: {
|
||||||
|
return $t('trigger_asset_uploaded');
|
||||||
|
}
|
||||||
|
case PluginTriggerType.PersonRecognized: {
|
||||||
|
return $t('trigger_person_recognized');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return triggerType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTriggerDescription = (triggerType: PluginTriggerType) => {
|
||||||
|
switch (triggerType) {
|
||||||
|
case PluginTriggerType.AssetCreate: {
|
||||||
|
return $t('trigger_asset_uploaded_description');
|
||||||
|
}
|
||||||
|
case PluginTriggerType.PersonRecognized: {
|
||||||
|
return $t('trigger_person_recognized_description');
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@@ -42,9 +71,9 @@
|
|||||||
<Icon icon={getTriggerIcon(trigger.type)} size="24" />
|
<Icon icon={getTriggerIcon(trigger.type)} size="24" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<Text class="font-semibold mb-1">{trigger.name}</Text>
|
<Text class="font-semibold mb-1">{getTriggerName(trigger.type)}</Text>
|
||||||
{#if trigger.description}
|
{#if getTriggerDescription(trigger.type)}
|
||||||
<Text size="small">{trigger.description}</Text>
|
<Text size="small">{getTriggerDescription(trigger.type)}</Text>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { ConfirmModal } from '@immich/ui';
|
|
||||||
import { t } from 'svelte-i18n';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onClose: (confirmed: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
let { onClose }: Props = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
confirmColor="danger"
|
|
||||||
prompt={$t('workflow_delete_prompt')}
|
|
||||||
onClose={(confirmed) => (confirmed ? onClose(true) : onClose(false))}
|
|
||||||
/>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { ConfirmModal } from '@immich/ui';
|
|
||||||
import { t } from 'svelte-i18n';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onClose: (confirmed: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
let { onClose }: Props = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
confirmColor="primary"
|
|
||||||
prompt={$t('workflow_navigation_prompt')}
|
|
||||||
onClose={(confirmed) => (confirmed ? onClose(true) : onClose(false))}
|
|
||||||
/>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { ConfirmModal } from '@immich/ui';
|
|
||||||
import { mdiLightningBolt } from '@mdi/js';
|
|
||||||
import { t } from 'svelte-i18n';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onClose: (confirmed: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
let { onClose }: Props = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
confirmColor="primary"
|
|
||||||
title={$t('change_trigger')}
|
|
||||||
icon={mdiLightningBolt}
|
|
||||||
prompt={$t('change_trigger_prompt')}
|
|
||||||
onClose={(confirmed) => (confirmed ? onClose(true) : onClose(false))}
|
|
||||||
/>
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
|
||||||
import { AppRoute } from '$lib/constants';
|
import { AppRoute } from '$lib/constants';
|
||||||
import WorkflowDeleteConfirmModal from '$lib/modals/WorkflowDeleteConfirmModal.svelte';
|
|
||||||
import type { WorkflowPayload } from '$lib/services/workflow.service';
|
import type { WorkflowPayload } from '$lib/services/workflow.service';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
import {
|
import {
|
||||||
@@ -109,7 +108,11 @@
|
|||||||
|
|
||||||
const handleDeleteWorkflow = async (workflow: WorkflowResponseDto) => {
|
const handleDeleteWorkflow = async (workflow: WorkflowResponseDto) => {
|
||||||
try {
|
try {
|
||||||
const confirmed = await modalManager.show(WorkflowDeleteConfirmModal);
|
const confirmed = await modalManager.showDialog({
|
||||||
|
prompt: $t('workflow_delete_prompt'),
|
||||||
|
confirmColor: 'danger',
|
||||||
|
});
|
||||||
|
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
import WorkflowTriggerCard from '$lib/components/workflows/WorkflowTriggerCard.svelte';
|
import WorkflowTriggerCard from '$lib/components/workflows/WorkflowTriggerCard.svelte';
|
||||||
import { AppRoute } from '$lib/constants';
|
import { AppRoute } from '$lib/constants';
|
||||||
import AddWorkflowStepModal from '$lib/modals/AddWorkflowStepModal.svelte';
|
import AddWorkflowStepModal from '$lib/modals/AddWorkflowStepModal.svelte';
|
||||||
import WorkflowNavigationConfirmModal from '$lib/modals/WorkflowNavigationConfirmModal.svelte';
|
|
||||||
import WorkflowTriggerUpdateConfirmModal from '$lib/modals/WorkflowTriggerUpdateConfirmModal.svelte';
|
|
||||||
import {
|
import {
|
||||||
buildWorkflowPayload,
|
buildWorkflowPayload,
|
||||||
getActionsByContext,
|
getActionsByContext,
|
||||||
@@ -287,7 +285,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleTriggerChange = async (newTrigger: PluginTriggerResponseDto) => {
|
const handleTriggerChange = async (newTrigger: PluginTriggerResponseDto) => {
|
||||||
const confirmed = await modalManager.show(WorkflowTriggerUpdateConfirmModal);
|
const confirmed = await modalManager.showDialog({
|
||||||
|
prompt: $t('change_trigger_prompt'),
|
||||||
|
title: $t('change_trigger'),
|
||||||
|
confirmColor: 'primary',
|
||||||
|
});
|
||||||
|
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
@@ -303,7 +305,10 @@
|
|||||||
cancel();
|
cancel();
|
||||||
|
|
||||||
modalManager
|
modalManager
|
||||||
.show(WorkflowNavigationConfirmModal)
|
.showDialog({
|
||||||
|
prompt: $t('workflow_navigation_prompt'),
|
||||||
|
confirmColor: 'primary',
|
||||||
|
})
|
||||||
.then((isConfirmed) => {
|
.then((isConfirmed) => {
|
||||||
if (isConfirmed && to) {
|
if (isConfirmed && to) {
|
||||||
allowNavigation = true;
|
allowNavigation = true;
|
||||||
@@ -398,7 +403,7 @@
|
|||||||
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
{#each triggers as trigger (trigger.name)}
|
{#each triggers as trigger (trigger.type)}
|
||||||
<WorkflowTriggerCard
|
<WorkflowTriggerCard
|
||||||
{trigger}
|
{trigger}
|
||||||
selected={selectedTrigger.type === trigger.type}
|
selected={selectedTrigger.type === trigger.type}
|
||||||
|
|||||||
Reference in New Issue
Block a user