diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts
new file mode 100644
index 0000000000..c82d9f9659
--- /dev/null
+++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts
@@ -0,0 +1,41 @@
+import { resetSavedUser, user as userStore } from '$lib/stores/user.store';
+import { assetFactory } from '@test-data/factories/asset-factory';
+import { userAdminFactory } from '@test-data/factories/user-factory';
+import '@testing-library/jest-dom';
+import { render } from '@testing-library/svelte';
+import AssetViewerNavBar from './asset-viewer-nav-bar.svelte';
+
+describe('AssetViewerNavBar component', () => {
+ const additionalProps = {
+ showCopyButton: false,
+ showZoomButton: false,
+ showDetailButton: false,
+ showDownloadButton: false,
+ showMotionPlayButton: false,
+ showShareButton: false,
+ onZoomImage: () => {},
+ onCopyImage: () => {},
+ };
+
+ afterEach(() => {
+ vi.resetAllMocks();
+ resetSavedUser();
+ });
+
+ it('shows back button', () => {
+ const asset = assetFactory.build({ isTrashed: false });
+ const { getByTitle } = render(AssetViewerNavBar, { asset, ...additionalProps });
+ expect(getByTitle('go_back')).toBeInTheDocument();
+ });
+
+ describe('if the current user owns the asset', () => {
+ it('shows delete button', () => {
+ const ownerId = 'id-of-the-user';
+ const user = userAdminFactory.build({ id: ownerId });
+ const asset = assetFactory.build({ ownerId, isTrashed: false });
+ userStore.set(user);
+ const { getByTitle } = render(AssetViewerNavBar, { asset, ...additionalProps });
+ expect(getByTitle('delete')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
index 2dfb841e93..746871516f 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
@@ -1,5 +1,6 @@
+
+{#if asset.isTrashed}
+ dispatch('permanentlyDelete')}
+ title={$t('permanently_delete')}
+ />
+{:else}
+ dispatch('delete')} title={$t('delete')} />
+{/if}
diff --git a/web/src/test-data/factories/user-factory.ts b/web/src/test-data/factories/user-factory.ts
index 24d75254d2..67ac638ea0 100644
--- a/web/src/test-data/factories/user-factory.ts
+++ b/web/src/test-data/factories/user-factory.ts
@@ -1,5 +1,5 @@
import { faker } from '@faker-js/faker';
-import { UserAvatarColor, type UserResponseDto } from '@immich/sdk';
+import { UserAvatarColor, UserStatus, type UserAdminResponseDto, type UserResponseDto } from '@immich/sdk';
import { Sync } from 'factory.ts';
export const userFactory = Sync.makeFactory({
@@ -9,3 +9,21 @@ export const userFactory = Sync.makeFactory({
profileImagePath: '',
avatarColor: UserAvatarColor.Primary,
});
+
+export const userAdminFactory = Sync.makeFactory({
+ id: Sync.each(() => faker.string.uuid()),
+ email: Sync.each(() => faker.internet.email()),
+ name: Sync.each(() => faker.person.fullName()),
+ profileImagePath: '',
+ avatarColor: UserAvatarColor.Primary,
+ isAdmin: true,
+ createdAt: Sync.each(() => faker.date.recent().toISOString()),
+ updatedAt: Sync.each(() => faker.date.recent().toISOString()),
+ deletedAt: null,
+ oauthId: '',
+ quotaUsageInBytes: 0,
+ quotaSizeInBytes: 1000,
+ shouldChangePassword: false,
+ status: UserStatus.Active,
+ storageLabel: null,
+});