Skip to content

Commit af017c0

Browse files
committed
feat(web): move search options into a modal
1 parent 8f73313 commit af017c0

File tree

6 files changed

+25
-32
lines changed

6 files changed

+25
-32
lines changed

Diff for: web/src/lib/components/shared-components/full-screen-modal.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
</div>
7070
{#if isStickyBottom}
7171
<div
72-
class="flex flex-col sm:flex-row justify-end w-full gap-2 sm:gap-4 sticky bottom-0 py-4 px-5 bg-immich-bg dark:bg-immich-dark-gray border-t border-gray-200 dark:border-gray-500 shadow"
72+
class="flex flex-col sm:flex-row justify-end w-full gap-2 sm:gap-4 sticky bottom-0 py-4 px-5 bg-immich-bg dark:bg-immich-dark-gray border-t border-gray-200 dark:border-gray-500 shadow z-[9999]"
7373
>
7474
<slot name="sticky-bottom" />
7575
</div>

Diff for: web/src/lib/components/shared-components/modal-header.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@
3333
</h1>
3434
</div>
3535

36-
<CircleIconButton on:click={onClose} icon={mdiClose} size={'20'} title={$t('close')} />
36+
<CircleIconButton on:click={onClose} icon={mdiClose} size={'20'} title={$t('close')} class="focus:ring-2" />
3737
</div>

Diff for: web/src/lib/components/shared-components/search-bar/search-bar.svelte

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import { isSearchEnabled, preventRaceConditionSearchBar, savedSearchTerms } from '$lib/stores/search.store';
55
import { mdiClose, mdiMagnify, mdiTune } from '@mdi/js';
66
import SearchHistoryBox from './search-history-box.svelte';
7-
import SearchFilterBox from './search-filter-box.svelte';
7+
import SearchFilterModal from './search-filter-modal.svelte';
88
import type { MetadataSearchDto, SmartSearchDto } from '@immich/sdk';
99
import { getMetadataSearchQuery } from '$lib/utils/metadata-search';
1010
import { handlePromiseError } from '$lib/utils';
@@ -160,8 +160,8 @@
160160
id="main-search-bar"
161161
class="w-full transition-all border-2 px-14 py-4 text-immich-fg/75 dark:text-immich-dark-fg
162162
{grayTheme ? 'dark:bg-immich-dark-gray' : 'dark:bg-immich-dark-bg'}
163-
{(showSuggestions && isSearchSuggestions) || showFilter ? 'rounded-t-3xl' : 'rounded-3xl bg-gray-200'}
164-
{$isSearchEnabled ? 'border-gray-200 dark:border-gray-700 bg-white' : 'border-transparent'}"
163+
{showSuggestions && isSearchSuggestions ? 'rounded-t-3xl' : 'rounded-3xl bg-gray-200'}
164+
{$isSearchEnabled && !showFilter ? 'border-gray-200 dark:border-gray-700 bg-white' : 'border-transparent'}"
165165
placeholder={$t('search_your_photos')}
166166
required
167167
pattern="^(?!m:$).*$"
@@ -215,6 +215,6 @@
215215
</form>
216216

217217
{#if showFilter}
218-
<SearchFilterBox {searchQuery} on:search={({ detail }) => onSearch(detail)} />
218+
<SearchFilterModal {searchQuery} onSearch={(payload) => onSearch(payload)} onClose={() => (showFilter = false)} />
219219
{/if}
220220
</div>

Diff for: web/src/lib/components/shared-components/search-bar/search-filter-box.svelte renamed to web/src/lib/components/shared-components/search-bar/search-filter-modal.svelte

+17-25
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
<script lang="ts">
2525
import Button from '$lib/components/elements/buttons/button.svelte';
2626
import { AssetTypeEnum, type SmartSearchDto, type MetadataSearchDto } from '@immich/sdk';
27-
import { createEventDispatcher } from 'svelte';
28-
import { fly } from 'svelte/transition';
2927
import SearchPeopleSection from './search-people-section.svelte';
3028
import SearchLocationSection from './search-location-section.svelte';
3129
import SearchCameraSection, { type SearchCameraFilter } from './search-camera-section.svelte';
@@ -35,12 +33,17 @@
3533
import SearchDisplaySection from './search-display-section.svelte';
3634
import SearchTextSection from './search-text-section.svelte';
3735
import { t } from 'svelte-i18n';
36+
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
37+
import { mdiTune } from '@mdi/js';
38+
import { generateId } from '$lib/utils/generate-id';
3839
3940
export let searchQuery: MetadataSearchDto | SmartSearchDto;
41+
export let onClose: () => void;
42+
export let onSearch: (search: SmartSearchDto | MetadataSearchDto) => void;
4043
4144
const parseOptionalDate = (dateString?: string) => (dateString ? parseUtcDate(dateString) : undefined);
4245
const toStartOfDayDate = (dateString: string) => parseUtcDate(dateString)?.startOf('day').toISODate() || undefined;
43-
const dispatch = createEventDispatcher<{ search: SmartSearchDto | MetadataSearchDto }>();
46+
const formId = generateId();
4447
4548
// combobox and all the search components have terrible support for value | null so we use empty string instead.
4649
function withNullAsUndefined<T>(value: T | null) {
@@ -113,21 +116,13 @@
113116
type,
114117
};
115118
116-
dispatch('search', payload);
119+
onSearch(payload);
117120
};
118121
</script>
119122

120-
<div
121-
transition:fly={{ y: 25, duration: 250 }}
122-
class="absolute w-full rounded-b-3xl border-2 border-t-0 border-gray-200 bg-white shadow-2xl dark:border-gray-700 dark:bg-immich-dark-gray dark:text-gray-300"
123-
>
124-
<form
125-
id="search-filter-form"
126-
autocomplete="off"
127-
on:submit|preventDefault={search}
128-
on:reset|preventDefault={resetForm}
129-
>
130-
<div class="px-4 sm:px-6 py-4 space-y-10 max-h-[calc(100dvh-12rem)] overflow-y-auto immich-scrollbar" tabindex="-1">
123+
<FullScreenModal icon={mdiTune} width="wide" title={$t('search_options')} {onClose}>
124+
<form id={formId} autocomplete="off" on:submit|preventDefault={search} on:reset|preventDefault={resetForm}>
125+
<div class="space-y-10 pb-10" tabindex="-1">
131126
<!-- PEOPLE -->
132127
<SearchPeopleSection bind:selectedPeople={filter.personIds} />
133128

@@ -143,21 +138,18 @@
143138
<!-- DATE RANGE -->
144139
<SearchDateSection bind:filters={filter.date} />
145140

146-
<div class="grid md:grid-cols-2 gap-x-5 gap-y-8">
141+
<div class="grid md:grid-cols-2 gap-x-5 gap-y-10">
147142
<!-- MEDIA TYPE -->
148143
<SearchMediaSection bind:filteredMedia={filter.mediaType} />
149144

150145
<!-- DISPLAY OPTIONS -->
151146
<SearchDisplaySection bind:filters={filter.display} />
152147
</div>
153148
</div>
154-
155-
<div
156-
id="button-row"
157-
class="flex justify-end gap-4 border-t dark:border-gray-800 dark:bg-immich-dark-gray px-4 sm:py-6 py-4 mt-2 rounded-b-3xl"
158-
>
159-
<Button type="reset" color="gray">{$t('clear_all')}</Button>
160-
<Button type="submit">{$t('search')}</Button>
161-
</div>
162149
</form>
163-
</div>
150+
151+
<svelte:fragment slot="sticky-bottom">
152+
<Button type="reset" color="gray" fullwidth form={formId}>{$t('clear_all')}</Button>
153+
<Button type="submit" fullwidth form={formId}>{$t('search')}</Button>
154+
</svelte:fragment>
155+
</FullScreenModal>

Diff for: web/src/lib/components/shared-components/search-bar/search-media-section.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import RadioButton from '$lib/components/elements/radio-button.svelte';
3-
import { MediaType } from './search-filter-box.svelte';
3+
import { MediaType } from './search-filter-modal.svelte';
44
import { t } from 'svelte-i18n';
55
66
export let filteredMedia: MediaType;

Diff for: web/src/lib/i18n/en.json

+1
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@
10671067
"search_for_existing_person": "Search for existing person",
10681068
"search_no_people": "No people",
10691069
"search_no_people_named": "No people named \"{name}\"",
1070+
"search_options": "Search options",
10701071
"search_people": "Search people",
10711072
"search_places": "Search places",
10721073
"search_state": "Search state...",

0 commit comments

Comments
 (0)