Skip to content

Commit

Permalink
refactor(web) open api client (#7103)
Browse files Browse the repository at this point in the history
* refactor: person api

* refactor: shared link and others
  • Loading branch information
jrasm91 authored Feb 14, 2024
1 parent 5fc1d43 commit d8631a0
Show file tree
Hide file tree
Showing 81 changed files with 621 additions and 639 deletions.
122 changes: 1 addition & 121 deletions web/src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,15 @@
import {
AssetApi,
AssetApiFp,
AssetJobName,
DownloadApi,
JobName,
PersonApi,
SearchApi,
SharedLinkApi,
UserApiFp,
base,
common,
configuration,
} from '@immich/sdk/axios';
import type { ApiParams as ApiParameters } from './types';
import { AssetApi, DownloadApi, configuration } from '@immich/sdk/axios';

class ImmichApi {
public downloadApi: DownloadApi;
public assetApi: AssetApi;
public searchApi: SearchApi;
public sharedLinkApi: SharedLinkApi;
public personApi: PersonApi;

private config: configuration.Configuration;
private key?: string;

get isSharedLink() {
return !!this.key;
}

constructor(parameters: configuration.ConfigurationParameters) {
this.config = new configuration.Configuration(parameters);

this.downloadApi = new DownloadApi(this.config);
this.assetApi = new AssetApi(this.config);
this.searchApi = new SearchApi(this.config);
this.sharedLinkApi = new SharedLinkApi(this.config);
this.personApi = new PersonApi(this.config);
}

private createUrl(path: string, parameters?: Record<string, unknown>) {
const searchParameters = new URLSearchParams();
for (const key in parameters) {
const value = parameters[key];
if (value !== undefined && value !== null) {
searchParameters.set(key, value.toString());
}
}

const url = new URL(path, common.DUMMY_BASE_URL);
url.search = searchParameters.toString();

return (this.config.basePath || base.BASE_PATH) + common.toPathString(url);
}

public setKey(key: string) {
this.key = key;
}

public getKey(): string | undefined {
return this.key;
}

public setAccessToken(accessToken: string) {
this.config.accessToken = accessToken;
}

public removeAccessToken() {
this.config.accessToken = undefined;
}

public setBaseUrl(baseUrl: string) {
this.config.basePath = baseUrl;
}

public getAssetFileUrl(...[assetId, isThumb, isWeb]: ApiParameters<typeof AssetApiFp, 'serveFile'>) {
const path = `/asset/file/${assetId}`;
return this.createUrl(path, { isThumb, isWeb, key: this.getKey() });
}

public getAssetThumbnailUrl(...[assetId, format]: ApiParameters<typeof AssetApiFp, 'getAssetThumbnail'>) {
const path = `/asset/thumbnail/${assetId}`;
return this.createUrl(path, { format, key: this.getKey() });
}

public getProfileImageUrl(...[userId]: ApiParameters<typeof UserApiFp, 'getProfileImage'>) {
const path = `/user/profile-image/${userId}`;
return this.createUrl(path);
}

public getPeopleThumbnailUrl(personId: string) {
const path = `/person/${personId}/thumbnail`;
return this.createUrl(path);
}

public getJobName(jobName: JobName) {
const names: Record<JobName, string> = {
[JobName.ThumbnailGeneration]: 'Generate Thumbnails',
[JobName.MetadataExtraction]: 'Extract Metadata',
[JobName.Sidecar]: 'Sidecar Metadata',
[JobName.SmartSearch]: 'Smart Search',
[JobName.FaceDetection]: 'Face Detection',
[JobName.FacialRecognition]: 'Facial Recognition',
[JobName.VideoConversion]: 'Transcode Videos',
[JobName.StorageTemplateMigration]: 'Storage Template Migration',
[JobName.Migration]: 'Migration',
[JobName.BackgroundTask]: 'Background Tasks',
[JobName.Search]: 'Search',
[JobName.Library]: 'Library',
};

return names[jobName];
}

public getAssetJobName(job: AssetJobName) {
const names: Record<AssetJobName, string> = {
[AssetJobName.RefreshMetadata]: 'Refresh metadata',
[AssetJobName.RegenerateThumbnail]: 'Refresh thumbnails',
[AssetJobName.TranscodeVideo]: 'Refresh encoded videos',
};

return names[job];
}

public getAssetJobMessage(job: AssetJobName) {
const messages: Record<AssetJobName, string> = {
[AssetJobName.RefreshMetadata]: 'Refreshing metadata',
[AssetJobName.RegenerateThumbnail]: `Regenerating thumbnails`,
[AssetJobName.TranscodeVideo]: `Refreshing encoded video`,
};

return messages[job];
}
}

Expand Down
2 changes: 1 addition & 1 deletion web/src/api/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { finishOAuth, linkOAuthAccount, startOAuth, unlinkOAuthAccount } from '@immich/sdk';
import type { UserResponseDto } from '@immich/sdk/axios';
import { type UserResponseDto } from '@immich/sdk/axios';
import type { AxiosError } from 'axios';
import {
NotificationType,
Expand Down
11 changes: 6 additions & 5 deletions web/src/lib/components/admin-page/jobs/job-tile.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<script lang="ts">
import { locale } from '$lib/stores/preferences.store';
import { createEventDispatcher } from 'svelte';
import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@api';
import Badge from '$lib/components/elements/badge.svelte';
import JobTileButton from './job-tile-button.svelte';
import JobTileStatus from './job-tile-status.svelte';
import Button from '$lib/components/elements/buttons/button.svelte';
import Icon from '$lib/components/elements/icon.svelte';
import { locale } from '$lib/stores/preferences.store';
import { type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk';
import { JobCommand } from '@immich/sdk/axios';
import {
mdiAlertCircle,
mdiAllInclusive,
Expand All @@ -16,6 +14,9 @@
mdiPlay,
mdiSelectionSearch,
} from '@mdi/js';
import { createEventDispatcher } from 'svelte';
import JobTileButton from './job-tile-button.svelte';
import JobTileStatus from './job-tile-status.svelte';
export let title: string;
export let subtitle: string | undefined;
Expand Down
27 changes: 14 additions & 13 deletions web/src/lib/components/admin-page/jobs/jobs-panel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import { featureFlags } from '$lib/stores/server-config.store';
import { getJobName } from '$lib/utils';
import { handleError } from '$lib/utils/handle-error';
import { type AllJobStatusResponseDto, api, JobCommand, type JobCommandDto, JobName } from '@api';
import type { ComponentType } from 'svelte';
import { sendJobCommand, type AllJobStatusResponseDto, type JobCommandDto } from '@immich/sdk';
import { JobCommand, JobName } from '@immich/sdk/axios';
import {
mdiFaceRecognition,
mdiFileJpgBox,
Expand All @@ -18,10 +19,10 @@
mdiTagFaces,
mdiVideo,
} from '@mdi/js';
import type { ComponentType } from 'svelte';
import ConfirmDialogue from '../../shared-components/confirm-dialogue.svelte';
import JobTile from './job-tile.svelte';
import StorageMigrationDescription from './storage-migration-description.svelte';
import { sendJobCommand } from '@immich/sdk';
export let jobs: AllJobStatusResponseDto;
Expand Down Expand Up @@ -59,23 +60,23 @@
$: jobDetails = <Partial<Record<JobName, JobDetails>>>{
[JobName.ThumbnailGeneration]: {
icon: mdiFileJpgBox,
title: api.getJobName(JobName.ThumbnailGeneration),
title: getJobName(JobName.ThumbnailGeneration),
subtitle: 'Generate large, small and blurred thumbnails for each asset, as well as thumbnails for each person',
},
[JobName.MetadataExtraction]: {
icon: mdiTable,
title: api.getJobName(JobName.MetadataExtraction),
title: getJobName(JobName.MetadataExtraction),
subtitle: 'Extract metadata information from each asset, such as GPS and resolution',
},
[JobName.Library]: {
icon: mdiLibraryShelves,
title: api.getJobName(JobName.Library),
title: getJobName(JobName.Library),
subtitle: 'Perform library tasks',
allText: 'ALL',
missingText: 'REFRESH',
},
[JobName.Sidecar]: {
title: api.getJobName(JobName.Sidecar),
title: getJobName(JobName.Sidecar),
icon: mdiFileXmlBox,
subtitle: 'Discover or synchronize sidecar metadata from the filesystem',
allText: 'SYNC',
Expand All @@ -84,40 +85,40 @@
},
[JobName.SmartSearch]: {
icon: mdiImageSearch,
title: api.getJobName(JobName.SmartSearch),
title: getJobName(JobName.SmartSearch),
subtitle: 'Run machine learning on assets to support smart search',
disabled: !$featureFlags.smartSearch,
},
[JobName.FaceDetection]: {
icon: mdiFaceRecognition,
title: api.getJobName(JobName.FaceDetection),
title: getJobName(JobName.FaceDetection),
subtitle:
'Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. "All" (re-)processes all assets. "Missing" queues assets that haven\'t been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.',
handleCommand: handleConfirmCommand,
disabled: !$featureFlags.facialRecognition,
},
[JobName.FacialRecognition]: {
icon: mdiTagFaces,
title: api.getJobName(JobName.FacialRecognition),
title: getJobName(JobName.FacialRecognition),
subtitle:
'Group detected faces into people. This step runs after Face Detection is complete. "All" (re-)clusters all faces. "Missing" queues faces that don\'t have a person assigned.',
handleCommand: handleConfirmCommand,
disabled: !$featureFlags.facialRecognition,
},
[JobName.VideoConversion]: {
icon: mdiVideo,
title: api.getJobName(JobName.VideoConversion),
title: getJobName(JobName.VideoConversion),
subtitle: 'Transcode videos for wider compatibility with browsers and devices',
},
[JobName.StorageTemplateMigration]: {
icon: mdiFolderMove,
title: api.getJobName(JobName.StorageTemplateMigration),
title: getJobName(JobName.StorageTemplateMigration),
allowForceCommand: false,
component: StorageMigrationDescription,
},
[JobName.Migration]: {
icon: mdiFolderMove,
title: api.getJobName(JobName.Migration),
title: getJobName(JobName.Migration),
subtitle: 'Migrate thumbnails for assets and faces to the latest folder structure',
allowForceCommand: false,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import Icon from '$lib/components/elements/icon.svelte';
import { locale } from '$lib/stores/preferences.store';
import type { ServerStatsResponseDto } from '@api';
import { asByteUnitString, getBytesWithUnit } from '$lib/utils/byte-units';
import StatsCard from './stats-card.svelte';
import type { ServerStatsResponseDto } from '@immich/sdk';
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
import Icon from '$lib/components/elements/icon.svelte';
import StatsCard from './stats-card.svelte';
export let stats: ServerStatsResponseDto = {
photos: 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ResetOptions } from '$lib/utils/dipatch';
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';

export type SettingsEventType = {
reset: ResetOptions & { configKeys: Array<keyof SystemConfigDto> };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
<script lang="ts">
import {
AudioCodec,
CQMode,
type SystemConfigDto,
ToneMapping,
TranscodeHWAccel,
TranscodePolicy,
VideoCodec,
} from '@api';
import Icon from '$lib/components/elements/icon.svelte';
import { type SystemConfigDto } from '@immich/sdk';
import { AudioCodec, CQMode, ToneMapping, TranscodeHWAccel, TranscodePolicy, VideoCodec } from '@immich/sdk/axios';
import { mdiHelpCircleOutline } from '@mdi/js';
import { isEqual, sortBy } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings';
import SettingAccordion from '../setting-accordion.svelte';
import SettingButtonsRow from '../setting-buttons-row.svelte';
import SettingCheckboxes from '../setting-checkboxes.svelte';
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
import SettingSelect from '../setting-select.svelte';
import SettingSwitch from '../setting-switch.svelte';
import SettingCheckboxes from '../setting-checkboxes.svelte';
import { isEqual, sortBy } from 'lodash-es';
import { fade } from 'svelte/transition';
import SettingAccordion from '../setting-accordion.svelte';
import { mdiHelpCircleOutline } from '@mdi/js';
import Icon from '$lib/components/elements/icon.svelte';
import { createEventDispatcher } from 'svelte';
import type { SettingsEventType } from '../admin-settings';
export let savedConfig: SystemConfigDto;
export let defaultConfig: SystemConfigDto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
import { api, JobName, type SystemConfigDto, type SystemConfigJobDto } from '@api';
import { getJobName } from '$lib/utils';
import { type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk';
import { JobName } from '@immich/sdk/axios';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down Expand Up @@ -41,7 +43,7 @@
<SettingInputField
inputType={SettingInputFieldType.NUMBER}
{disabled}
label="{api.getJobName(jobName)} Concurrency"
label="{getJobName(jobName)} Concurrency"
desc=""
bind:value={config.job[jobName].concurrency}
required={true}
Expand All @@ -50,7 +52,7 @@
{:else}
<SettingInputField
inputType={SettingInputFieldType.NUMBER}
label="{api.getJobName(jobName)} Concurrency"
label="{getJobName(jobName)} Concurrency"
desc=""
value="1"
disabled={true}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { LogLevel, type SystemConfigDto } from '@api';
import { type SystemConfigDto } from '@immich/sdk';
import { LogLevel } from '@immich/sdk/axios';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { SystemConfigDto } from '@api';
import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
Expand Down
Loading

0 comments on commit d8631a0

Please sign in to comment.