mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(web,server): server features (#3756)
* feat: server features * chore: open api * icon size --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
28d3d3e679
commit
2b839088c7
40 changed files with 805 additions and 187 deletions
|
|
@ -4,17 +4,23 @@
|
|||
|
||||
<script lang="ts">
|
||||
export let color: Colors;
|
||||
export let disabled = false;
|
||||
|
||||
const colorClasses: Record<Colors, string> = {
|
||||
'light-gray': 'bg-gray-300/90 dark:bg-gray-600/90',
|
||||
gray: 'bg-gray-300 dark:bg-gray-600',
|
||||
};
|
||||
|
||||
const hoverClasses = disabled
|
||||
? 'cursor-not-allowed'
|
||||
: 'hover:bg-immich-primary hover:text-white dark:hover:bg-immich-dark-primary dark:hover:text-black';
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="flex h-full w-full flex-col place-content-center place-items-center gap-2 px-8 py-2 text-xs text-gray-600 transition-colors hover:bg-immich-primary hover:text-white dark:text-gray-200 dark:hover:bg-immich-dark-primary dark:hover:text-black {colorClasses[
|
||||
{disabled}
|
||||
class="flex h-full w-full flex-col place-content-center place-items-center gap-2 px-8 py-2 text-xs text-gray-600 transition-colors dark:text-gray-200 {colorClasses[
|
||||
color
|
||||
]}"
|
||||
]} {hoverClasses}"
|
||||
on:click
|
||||
>
|
||||
<slot />
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import FastForward from 'svelte-material-icons/FastForward.svelte';
|
||||
import AllInclusive from 'svelte-material-icons/AllInclusive.svelte';
|
||||
import Close from 'svelte-material-icons/Close.svelte';
|
||||
import AlertCircle from 'svelte-material-icons/AlertCircle.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { JobCommand, JobCommandDto, JobCountsDto, QueueStatusDto } from '@api';
|
||||
|
|
@ -19,6 +20,7 @@
|
|||
export let queueStatus: QueueStatusDto;
|
||||
export let allowForceCommand = true;
|
||||
export let icon: typeof Icon;
|
||||
export let disabled = false;
|
||||
|
||||
export let allText: string;
|
||||
export let missingText: string;
|
||||
|
|
@ -94,7 +96,15 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex w-full flex-row overflow-hidden sm:w-32 sm:flex-col">
|
||||
{#if !isIdle}
|
||||
{#if disabled}
|
||||
<JobTileButton
|
||||
disabled={true}
|
||||
color="light-gray"
|
||||
on:click={() => dispatch('command', { command: JobCommand.Start, force: false })}
|
||||
>
|
||||
<AlertCircle size="36" /> DISABLED
|
||||
</JobTileButton>
|
||||
{:else if !isIdle}
|
||||
{#if waitingCount > 0}
|
||||
<JobTileButton color="gray" on:click={() => dispatch('command', { command: JobCommand.Empty, force: false })}>
|
||||
<Close size="24" /> CLEAR
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { AppRoute } from '$lib/constants';
|
||||
import { featureFlags } from '$lib/stores/feature-flags.store';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { AllJobStatusResponseDto, api, JobCommand, JobCommandDto, JobName } from '@api';
|
||||
import type { ComponentType } from 'svelte';
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
subtitle?: string;
|
||||
allText?: string;
|
||||
missingText?: string;
|
||||
disabled?: boolean;
|
||||
icon: typeof Icon;
|
||||
allowForceCommand?: boolean;
|
||||
component?: ComponentType;
|
||||
|
|
@ -51,7 +53,7 @@
|
|||
handleCommand(JobName.RecognizeFaces, { command: JobCommand.Start, force: true });
|
||||
};
|
||||
|
||||
const jobDetails: Partial<Record<JobName, JobDetails>> = {
|
||||
$: jobDetails = <Partial<Record<JobName, JobDetails>>>{
|
||||
[JobName.ThumbnailGeneration]: {
|
||||
icon: FileJpgBox,
|
||||
title: api.getJobName(JobName.ThumbnailGeneration),
|
||||
|
|
@ -73,17 +75,20 @@
|
|||
icon: TagMultiple,
|
||||
title: api.getJobName(JobName.ObjectTagging),
|
||||
subtitle: 'Run machine learning to tag objects\nNote that some assets may not have any objects detected',
|
||||
disabled: !$featureFlags.machineLearning,
|
||||
},
|
||||
[JobName.ClipEncoding]: {
|
||||
icon: VectorCircle,
|
||||
title: api.getJobName(JobName.ClipEncoding),
|
||||
subtitle: 'Run machine learning to generate clip embeddings',
|
||||
disabled: !$featureFlags.machineLearning,
|
||||
},
|
||||
[JobName.RecognizeFaces]: {
|
||||
icon: FaceRecognition,
|
||||
title: api.getJobName(JobName.RecognizeFaces),
|
||||
subtitle: 'Run machine learning to recognize faces',
|
||||
handleCommand: handleFaceCommand,
|
||||
disabled: !$featureFlags.machineLearning,
|
||||
},
|
||||
[JobName.VideoConversion]: {
|
||||
icon: Video,
|
||||
|
|
@ -97,8 +102,7 @@
|
|||
component: StorageMigrationDescription,
|
||||
},
|
||||
};
|
||||
|
||||
const jobDetailsArray = Object.entries(jobDetails) as [JobName, JobDetails][];
|
||||
$: jobList = Object.entries(jobDetails) as [JobName, JobDetails][];
|
||||
|
||||
async function handleCommand(jobId: JobName, jobCommand: JobCommandDto) {
|
||||
const title = jobDetails[jobId]?.title;
|
||||
|
|
@ -138,11 +142,12 @@
|
|||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
{#each jobDetailsArray as [jobName, { title, subtitle, allText, missingText, allowForceCommand, icon, component, handleCommand: handleCommandOverride }]}
|
||||
{#each jobList as [jobName, { title, subtitle, disabled, allText, missingText, allowForceCommand, icon, component, handleCommand: handleCommandOverride }]}
|
||||
{@const { jobCounts, queueStatus } = jobs[jobName]}
|
||||
<JobTile
|
||||
{icon}
|
||||
{title}
|
||||
{disabled}
|
||||
{subtitle}
|
||||
allText={allText || 'ALL'}
|
||||
missingText={missingText || 'MISSING'}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue