mirror of
https://github.com/immich-app/immich.git
synced 2026-03-26 11:50:53 +03:00
fix: filter after searching by asset id (#26994)
* fix: filter after searching by asset id * Update web/src/lib/modals/SearchFilterModal.svelte Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
This commit is contained in:
@@ -14,11 +14,11 @@
|
|||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import SearchHistoryBox from './search-history-box.svelte';
|
import SearchHistoryBox from './search-history-box.svelte';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
value?: string;
|
value?: string;
|
||||||
grayTheme: boolean;
|
grayTheme: boolean;
|
||||||
searchQuery?: MetadataSearchDto | SmartSearchDto;
|
searchQuery?: MetadataSearchDto | SmartSearchDto;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { value = $bindable(''), grayTheme, searchQuery = {} }: Props = $props();
|
let { value = $bindable(''), grayTheme, searchQuery = {} }: Props = $props();
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
<script lang="ts" module>
|
|
||||||
export interface SearchCameraFilter {
|
|
||||||
make?: string;
|
|
||||||
model?: string;
|
|
||||||
lensModel?: string;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Combobox, { asComboboxOptions, asSelectedOption } from '$lib/components/shared-components/combobox.svelte';
|
import Combobox, { asComboboxOptions, asSelectedOption } from '$lib/components/shared-components/combobox.svelte';
|
||||||
|
import type { SearchCameraFilter } from '$lib/types';
|
||||||
import { handlePromiseError } from '$lib/utils';
|
import { handlePromiseError } from '$lib/utils';
|
||||||
import { SearchSuggestionType, getSearchSuggestions } from '@immich/sdk';
|
import { SearchSuggestionType, getSearchSuggestions } from '@immich/sdk';
|
||||||
import { Text } from '@immich/ui';
|
import { Text } from '@immich/ui';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
filters: SearchCameraFilter;
|
filters: SearchCameraFilter;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { filters = $bindable() }: Props = $props();
|
let { filters = $bindable() }: Props = $props();
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
<script lang="ts" module>
|
|
||||||
export interface SearchDateFilter {
|
|
||||||
takenBefore?: DateTime;
|
|
||||||
takenAfter?: DateTime;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { SearchDateFilter } from '$lib/types';
|
||||||
import { DatePicker, Text } from '@immich/ui';
|
import { DatePicker, Text } from '@immich/ui';
|
||||||
import type { DateTime } from 'luxon';
|
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
filters: SearchDateFilter;
|
filters: SearchDateFilter;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { filters = $bindable() }: Props = $props();
|
let { filters = $bindable() }: Props = $props();
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,11 @@
|
|||||||
<script lang="ts" module>
|
|
||||||
export interface SearchDisplayFilters {
|
|
||||||
isNotInAlbum: boolean;
|
|
||||||
isArchive: boolean;
|
|
||||||
isFavorite: boolean;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { SearchDisplayFilters } from '$lib/types';
|
||||||
import { Checkbox, Label, Text } from '@immich/ui';
|
import { Checkbox, Label, Text } from '@immich/ui';
|
||||||
|
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
filters: SearchDisplayFilters;
|
filters: SearchDisplayFilters;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { filters = $bindable() }: Props = $props();
|
let { filters = $bindable() }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,22 +1,15 @@
|
|||||||
<script lang="ts" module>
|
|
||||||
export interface SearchLocationFilter {
|
|
||||||
country?: string;
|
|
||||||
state?: string;
|
|
||||||
city?: string;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Combobox, { asComboboxOptions, asSelectedOption } from '$lib/components/shared-components/combobox.svelte';
|
import Combobox, { asComboboxOptions, asSelectedOption } from '$lib/components/shared-components/combobox.svelte';
|
||||||
|
import type { SearchLocationFilter } from '$lib/types';
|
||||||
import { handlePromiseError } from '$lib/utils';
|
import { handlePromiseError } from '$lib/utils';
|
||||||
import { getSearchSuggestions, SearchSuggestionType } from '@immich/sdk';
|
import { getSearchSuggestions, SearchSuggestionType } from '@immich/sdk';
|
||||||
import { Text } from '@immich/ui';
|
import { Text } from '@immich/ui';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
filters: SearchLocationFilter;
|
filters: SearchLocationFilter;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { filters = $bindable() }: Props = $props();
|
let { filters = $bindable() }: Props = $props();
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,5 @@
|
|||||||
<script lang="ts" module>
|
|
||||||
import { MediaType, QueryType, validQueryTypes } from '$lib/constants';
|
|
||||||
import type { SearchDateFilter } from '../components/shared-components/search-bar/search-date-section.svelte';
|
|
||||||
import type { SearchDisplayFilters } from '../components/shared-components/search-bar/search-display-section.svelte';
|
|
||||||
import type { SearchLocationFilter } from '../components/shared-components/search-bar/search-location-section.svelte';
|
|
||||||
|
|
||||||
export type SearchFilter = {
|
|
||||||
query: string;
|
|
||||||
ocr?: string;
|
|
||||||
queryType: 'smart' | 'metadata' | 'description' | 'ocr';
|
|
||||||
personIds: SvelteSet<string>;
|
|
||||||
tagIds: SvelteSet<string> | null;
|
|
||||||
location: SearchLocationFilter;
|
|
||||||
camera: SearchCameraFilter;
|
|
||||||
date: SearchDateFilter;
|
|
||||||
display: SearchDisplayFilters;
|
|
||||||
mediaType: MediaType;
|
|
||||||
rating?: number | null;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SearchCameraSection, {
|
import SearchCameraSection from '$lib/components/shared-components/search-bar/search-camera-section.svelte';
|
||||||
type SearchCameraFilter,
|
|
||||||
} from '$lib/components/shared-components/search-bar/search-camera-section.svelte';
|
|
||||||
import SearchDateSection from '$lib/components/shared-components/search-bar/search-date-section.svelte';
|
import SearchDateSection from '$lib/components/shared-components/search-bar/search-date-section.svelte';
|
||||||
import SearchDisplaySection from '$lib/components/shared-components/search-bar/search-display-section.svelte';
|
import SearchDisplaySection from '$lib/components/shared-components/search-bar/search-display-section.svelte';
|
||||||
import SearchLocationSection from '$lib/components/shared-components/search-bar/search-location-section.svelte';
|
import SearchLocationSection from '$lib/components/shared-components/search-bar/search-location-section.svelte';
|
||||||
@@ -31,7 +8,9 @@
|
|||||||
import SearchRatingsSection from '$lib/components/shared-components/search-bar/search-ratings-section.svelte';
|
import SearchRatingsSection from '$lib/components/shared-components/search-bar/search-ratings-section.svelte';
|
||||||
import SearchTagsSection from '$lib/components/shared-components/search-bar/search-tags-section.svelte';
|
import SearchTagsSection from '$lib/components/shared-components/search-bar/search-tags-section.svelte';
|
||||||
import SearchTextSection from '$lib/components/shared-components/search-bar/search-text-section.svelte';
|
import SearchTextSection from '$lib/components/shared-components/search-bar/search-text-section.svelte';
|
||||||
|
import { MediaType, QueryType, validQueryTypes } from '$lib/constants';
|
||||||
import { preferences } from '$lib/stores/user.store';
|
import { preferences } from '$lib/stores/user.store';
|
||||||
|
import type { SearchFilter } from '$lib/types';
|
||||||
import { parseUtcDate } from '$lib/utils/date-time';
|
import { parseUtcDate } from '$lib/utils/date-time';
|
||||||
import { generateId } from '$lib/utils/generate-id';
|
import { generateId } from '$lib/utils/generate-id';
|
||||||
import { AssetTypeEnum, AssetVisibility, type MetadataSearchDto, type SmartSearchDto } from '@immich/sdk';
|
import { AssetTypeEnum, AssetVisibility, type MetadataSearchDto, type SmartSearchDto } from '@immich/sdk';
|
||||||
@@ -41,10 +20,10 @@
|
|||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { SvelteSet } from 'svelte/reactivity';
|
import { SvelteSet } from 'svelte/reactivity';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
searchQuery: MetadataSearchDto | SmartSearchDto;
|
searchQuery: MetadataSearchDto | SmartSearchDto;
|
||||||
onClose: (search?: SmartSearchDto | MetadataSearchDto) => void;
|
onClose: (search?: SmartSearchDto | MetadataSearchDto) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
let { searchQuery, onClose }: Props = $props();
|
let { searchQuery, onClose }: Props = $props();
|
||||||
|
|
||||||
@@ -66,6 +45,7 @@
|
|||||||
return validQueryTypes.has(storedQueryType) ? storedQueryType : QueryType.SMART;
|
return validQueryTypes.has(storedQueryType) ? storedQueryType : QueryType.SMART;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const asFilter = (searchQuery: SmartSearchDto | MetadataSearchDto): SearchFilter => {
|
||||||
let query = '';
|
let query = '';
|
||||||
if ('query' in searchQuery && searchQuery.query) {
|
if ('query' in searchQuery && searchQuery.query) {
|
||||||
query = searchQuery.query;
|
query = searchQuery.query;
|
||||||
@@ -74,10 +54,11 @@
|
|||||||
query = searchQuery.originalFileName;
|
query = searchQuery.originalFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
let filter: SearchFilter = $state({
|
return {
|
||||||
query,
|
query,
|
||||||
ocr: searchQuery.ocr,
|
ocr: searchQuery.ocr,
|
||||||
queryType: defaultQueryType(),
|
queryType: defaultQueryType(),
|
||||||
|
queryAssetId: 'queryAssetId' in searchQuery ? searchQuery.queryAssetId : undefined,
|
||||||
personIds: new SvelteSet('personIds' in searchQuery ? searchQuery.personIds : []),
|
personIds: new SvelteSet('personIds' in searchQuery ? searchQuery.personIds : []),
|
||||||
tagIds:
|
tagIds:
|
||||||
'tagIds' in searchQuery
|
'tagIds' in searchQuery
|
||||||
@@ -111,7 +92,10 @@
|
|||||||
? MediaType.Video
|
? MediaType.Video
|
||||||
: MediaType.All,
|
: MediaType.All,
|
||||||
rating: searchQuery.rating,
|
rating: searchQuery.rating,
|
||||||
});
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let filter: SearchFilter = $state(asFilter(searchQuery));
|
||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
filter = {
|
filter = {
|
||||||
@@ -145,6 +129,7 @@
|
|||||||
|
|
||||||
let payload: SmartSearchDto | MetadataSearchDto = {
|
let payload: SmartSearchDto | MetadataSearchDto = {
|
||||||
query: filter.queryType === 'smart' ? query : undefined,
|
query: filter.queryType === 'smart' ? query : undefined,
|
||||||
|
queryAssetId: filter.queryAssetId || undefined,
|
||||||
ocr: filter.queryType === 'ocr' ? query : undefined,
|
ocr: filter.queryType === 'ocr' ? query : undefined,
|
||||||
originalFileName: filter.queryType === 'metadata' ? query : undefined,
|
originalFileName: filter.queryType === 'metadata' ? query : undefined,
|
||||||
description: filter.queryType === 'description' ? query : undefined,
|
description: filter.queryType === 'description' ? query : undefined,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
import { MediaType } from '$lib/constants';
|
||||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||||
import type { QueueResponseDto, ServerVersionResponseDto } from '@immich/sdk';
|
import type { QueueResponseDto, ServerVersionResponseDto } from '@immich/sdk';
|
||||||
import type { ActionItem } from '@immich/ui';
|
import type { ActionItem } from '@immich/ui';
|
||||||
|
import type { DateTime } from 'luxon';
|
||||||
|
import type { SvelteSet } from 'svelte/reactivity';
|
||||||
|
|
||||||
export interface ReleaseEvent {
|
export interface ReleaseEvent {
|
||||||
isAvailable: boolean;
|
isAvailable: boolean;
|
||||||
@@ -48,3 +51,41 @@ export type AssetControlContext = {
|
|||||||
getOwnedAssets: () => TimelineAsset[]; // Only assets owned by the user
|
getOwnedAssets: () => TimelineAsset[]; // Only assets owned by the user
|
||||||
clearSelect: () => void;
|
clearSelect: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SearchCameraFilter = {
|
||||||
|
make?: string;
|
||||||
|
model?: string;
|
||||||
|
lensModel?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SearchDateFilter = {
|
||||||
|
takenBefore?: DateTime;
|
||||||
|
takenAfter?: DateTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SearchDisplayFilters = {
|
||||||
|
isNotInAlbum: boolean;
|
||||||
|
isArchive: boolean;
|
||||||
|
isFavorite: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SearchLocationFilter = {
|
||||||
|
country?: string;
|
||||||
|
state?: string;
|
||||||
|
city?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SearchFilter = {
|
||||||
|
query: string;
|
||||||
|
ocr?: string;
|
||||||
|
queryType: 'smart' | 'metadata' | 'description' | 'ocr';
|
||||||
|
personIds: SvelteSet<string>;
|
||||||
|
tagIds: SvelteSet<string> | null;
|
||||||
|
location: SearchLocationFilter;
|
||||||
|
queryAssetId?: string;
|
||||||
|
camera: SearchCameraFilter;
|
||||||
|
date: SearchDateFilter;
|
||||||
|
display: SearchDisplayFilters;
|
||||||
|
mediaType: MediaType;
|
||||||
|
rating?: number | null;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user