diff --git a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte index 8e5b739001..73a63a4a8a 100644 --- a/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte +++ b/web/src/lib/components/assets/thumbnail/image-thumbnail.svelte @@ -19,7 +19,7 @@ export let hidden = false; export let border = false; export let preload = true; - export let eyeColor: 'black' | 'white' = 'white'; + export let hiddenIconClass = 'text-white'; let complete = false; let img: HTMLImageElement; @@ -54,7 +54,7 @@ {#if hidden}
- +
{/if} diff --git a/web/src/lib/components/faces-page/manage-people-visibility.spec.ts b/web/src/lib/components/faces-page/manage-people-visibility.spec.ts new file mode 100644 index 0000000000..e9120553ae --- /dev/null +++ b/web/src/lib/components/faces-page/manage-people-visibility.spec.ts @@ -0,0 +1,108 @@ +import { sdkMock } from '$lib/__mocks__/sdk.mock'; +import ManagePeopleVisibility from '$lib/components/faces-page/manage-people-visibility.svelte'; +import type { PersonResponseDto } from '@immich/sdk'; +import { personFactory } from '@test-data/factories/person-factory'; +import { render } from '@testing-library/svelte'; + +describe('ManagePeopleVisibility Component', () => { + let personVisible: PersonResponseDto; + let personHidden: PersonResponseDto; + let personWithoutName: PersonResponseDto; + + beforeAll(() => { + // Prevents errors from `img.decode()` in ImageThumbnail + Object.defineProperty(HTMLImageElement.prototype, 'decode', { + value: vi.fn(), + }); + }); + + beforeEach(() => { + personVisible = personFactory.build({ isHidden: false }); + personHidden = personFactory.build({ isHidden: true }); + personWithoutName = personFactory.build({ isHidden: false, name: undefined }); + sdkMock.updatePeople.mockResolvedValue([]); + }); + + afterEach(() => { + vi.resetAllMocks(); + }); + + it('does not update people when no changes are made', () => { + const { getByText } = render(ManagePeopleVisibility, { + props: { + people: [personVisible, personHidden, personWithoutName], + onClose: vi.fn(), + }, + }); + + const saveButton = getByText('done'); + saveButton.click(); + expect(sdkMock.updatePeople).not.toHaveBeenCalled(); + }); + + it('hides unnamed people on first button press', () => { + const { getByText, getByTitle } = render(ManagePeopleVisibility, { + props: { + people: [personVisible, personHidden, personWithoutName], + onClose: vi.fn(), + }, + }); + + const toggleButton = getByTitle('toggle_visibility'); + toggleButton.click(); + const saveButton = getByText('done'); + saveButton.click(); + + expect(sdkMock.updatePeople).toHaveBeenCalledWith({ + peopleUpdateDto: { + people: [{ id: personWithoutName.id, isHidden: true }], + }, + }); + }); + + it('hides all people on second button press', () => { + const { getByText, getByTitle } = render(ManagePeopleVisibility, { + props: { + people: [personVisible, personHidden, personWithoutName], + onClose: vi.fn(), + }, + }); + + const toggleButton = getByTitle('toggle_visibility'); + toggleButton.click(); + toggleButton.click(); + const saveButton = getByText('done'); + saveButton.click(); + + expect(sdkMock.updatePeople).toHaveBeenCalledWith({ + peopleUpdateDto: { + people: expect.arrayContaining([ + { id: personVisible.id, isHidden: true }, + { id: personWithoutName.id, isHidden: true }, + ]), + }, + }); + }); + + it('shows all people on third button press', () => { + const { getByText, getByTitle } = render(ManagePeopleVisibility, { + props: { + people: [personVisible, personHidden, personWithoutName], + onClose: vi.fn(), + }, + }); + + const toggleButton = getByTitle('toggle_visibility'); + toggleButton.click(); + toggleButton.click(); + toggleButton.click(); + const saveButton = getByText('done'); + saveButton.click(); + + expect(sdkMock.updatePeople).toHaveBeenCalledWith({ + peopleUpdateDto: { + people: [{ id: personHidden.id, isHidden: false }], + }, + }); + }); +}); diff --git a/web/src/lib/components/faces-page/manage-people-visibility.svelte b/web/src/lib/components/faces-page/manage-people-visibility.svelte new file mode 100644 index 0000000000..8744950111 --- /dev/null +++ b/web/src/lib/components/faces-page/manage-people-visibility.svelte @@ -0,0 +1,162 @@ + + + + + + +
+
+ +
+

{$t('show_and_hide_people')}

+

({people.length.toLocaleString($locale)})

+
+
+
+
+ + +
+ {#if !showLoadingSpinner} + + {:else} + + {/if} +
+
+ +
+
+ {#each people as person, index (person.id)} + + {/each} +
+
diff --git a/web/src/lib/components/faces-page/show-hide.svelte b/web/src/lib/components/faces-page/show-hide.svelte deleted file mode 100644 index 5c476d396b..0000000000 --- a/web/src/lib/components/faces-page/show-hide.svelte +++ /dev/null @@ -1,81 +0,0 @@ - - - - -
-
-
- -
-

{$t('show_and_hide_people')}

-

({countTotalPeople.toLocaleString($locale)})

-
-
-
-
- - onChange(getNextVisibility(toggleVisibility))} - /> -
- {#if !showLoadingSpinner} - - {:else} - - {/if} -
-
- -
- -
-
diff --git a/web/src/routes/(user)/people/+page.svelte b/web/src/routes/(user)/people/+page.svelte index 5a70ecde86..1b646d7d08 100644 --- a/web/src/routes/(user)/people/+page.svelte +++ b/web/src/routes/(user)/people/+page.svelte @@ -1,13 +1,14 @@ - + {#if showMergeModal} - {#if countTotalPeople > 0} + {#if people.length > 0}