mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	feat(web): Add select all button to all views (#2714)
* Add select all to photos * Add selection of favorites * Add select all button to albums * Add select all to archive * Add select all to search * try to fix identation * Revert "try to fix identation" This reverts commit 40c727b74a9300caed892a61b8703be2ef3a6a26. * try to fix identation * try to fix identation * try to fix identation * try to fix identation * fix bucketposition * Run prettier --------- Co-authored-by: Yonggan <yonggan@obco.pro>
This commit is contained in:
		@@ -33,6 +33,7 @@
 | 
			
		||||
	import CreateSharedLinkModal from '../shared-components/create-share-link-modal/create-shared-link-modal.svelte';
 | 
			
		||||
	import GalleryViewer from '../shared-components/gallery-viewer/gallery-viewer.svelte';
 | 
			
		||||
	import ImmichLogo from '../shared-components/immich-logo.svelte';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
	import {
 | 
			
		||||
		NotificationType,
 | 
			
		||||
		notificationController
 | 
			
		||||
@@ -332,6 +333,10 @@
 | 
			
		||||
		isShowShareUserSelection = false;
 | 
			
		||||
		isShowShareLinkModal = true;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const handleSelectAll = () => {
 | 
			
		||||
		multiSelectAsset = new Set(album.assets);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<section class="bg-immich-bg dark:bg-immich-dark-bg" class:hidden={isShowThumbnailSelection}>
 | 
			
		||||
@@ -341,6 +346,7 @@
 | 
			
		||||
			assets={multiSelectAsset}
 | 
			
		||||
			clearSelect={() => (multiSelectAsset = new Set())}
 | 
			
		||||
		>
 | 
			
		||||
			<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
			<DownloadAction filename={album.albumName} sharedLinkKey={sharedLink?.key} />
 | 
			
		||||
			{#if isOwned}
 | 
			
		||||
				<RemoveFromAlbum bind:album />
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
	import TimerSand from 'svelte-material-icons/TimerSand.svelte';
 | 
			
		||||
	import { assetInteractionStore } from '$lib/stores/asset-interaction.store';
 | 
			
		||||
	import { assetGridState, assetStore } from '$lib/stores/assets.store';
 | 
			
		||||
	import { handleError } from '../../../utils/handle-error';
 | 
			
		||||
	import { AssetGridState, BucketPosition } from '$lib/models/asset-grid-state';
 | 
			
		||||
 | 
			
		||||
	let selecting = false;
 | 
			
		||||
 | 
			
		||||
	const handleSelectAll = async () => {
 | 
			
		||||
		try {
 | 
			
		||||
			selecting = true;
 | 
			
		||||
			let _assetGridState = new AssetGridState();
 | 
			
		||||
			assetGridState.subscribe((state) => {
 | 
			
		||||
				_assetGridState = state;
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			for (let i = 0; i < _assetGridState.buckets.length; i++) {
 | 
			
		||||
				await assetStore.getAssetsByBucket(
 | 
			
		||||
					_assetGridState.buckets[i].bucketDate,
 | 
			
		||||
					BucketPosition.Unknown
 | 
			
		||||
				);
 | 
			
		||||
				for (const asset of _assetGridState.buckets[i].assets) {
 | 
			
		||||
					assetInteractionStore.addAssetToMultiselectGroup(asset);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			selecting = false;
 | 
			
		||||
		} catch (e) {
 | 
			
		||||
			handleError(e, 'Error selecting all assets');
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if selecting}
 | 
			
		||||
	<CircleIconButton title="Delete" logo={TimerSand} />
 | 
			
		||||
{/if}
 | 
			
		||||
{#if !selecting}
 | 
			
		||||
	<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
{/if}
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
	import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
 | 
			
		||||
	import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
 | 
			
		||||
	import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
	import { archivedAsset } from '$lib/stores/archived-asset.store';
 | 
			
		||||
	import { handleError } from '$lib/utils/handle-error';
 | 
			
		||||
	import { api, AssetResponseDto } from '@api';
 | 
			
		||||
@@ -17,6 +18,7 @@
 | 
			
		||||
	import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
 | 
			
		||||
	import Plus from 'svelte-material-icons/Plus.svelte';
 | 
			
		||||
	import type { PageData } from './$types';
 | 
			
		||||
	import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
 | 
			
		||||
	export let data: PageData;
 | 
			
		||||
 | 
			
		||||
@@ -39,6 +41,9 @@
 | 
			
		||||
	const onAssetDelete = (assetId: string) => {
 | 
			
		||||
		$archivedAsset = $archivedAsset.filter((a) => a.id !== assetId);
 | 
			
		||||
	};
 | 
			
		||||
	const handleSelectAll = () => {
 | 
			
		||||
		selectedAssets = new Set($archivedAsset);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<UserPageLayout user={data.user} hideNavbar={isMultiSelectionMode} title={data.meta.title}>
 | 
			
		||||
@@ -57,6 +62,7 @@
 | 
			
		||||
				clearSelect={() => (selectedAssets = new Set())}
 | 
			
		||||
			>
 | 
			
		||||
				<ArchiveAction unarchive onAssetArchive={(asset) => onAssetDelete(asset.id)} />
 | 
			
		||||
				<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
				<CreateSharedLink />
 | 
			
		||||
				<AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
					<AddToAlbum />
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,8 @@
 | 
			
		||||
	import Plus from 'svelte-material-icons/Plus.svelte';
 | 
			
		||||
	import Error from '../../+error.svelte';
 | 
			
		||||
	import type { PageData } from './$types';
 | 
			
		||||
	import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
 | 
			
		||||
	let favorites: AssetResponseDto[] = [];
 | 
			
		||||
	let selectedAssets: Set<AssetResponseDto> = new Set();
 | 
			
		||||
@@ -38,6 +40,10 @@
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const handleSelectAll = () => {
 | 
			
		||||
		selectedAssets = new Set(favorites);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const onAssetDelete = (assetId: string) => {
 | 
			
		||||
		favorites = favorites.filter((a) => a.id !== assetId);
 | 
			
		||||
	};
 | 
			
		||||
@@ -48,6 +54,7 @@
 | 
			
		||||
	<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
 | 
			
		||||
		<FavoriteAction removeFavorite onAssetFavorite={(asset) => onAssetDelete(asset.id)} />
 | 
			
		||||
		<CreateSharedLink />
 | 
			
		||||
		<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
		<AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
			<AddToAlbum />
 | 
			
		||||
			<AddToAlbum shared />
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,8 @@
 | 
			
		||||
	import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
 | 
			
		||||
	import Plus from 'svelte-material-icons/Plus.svelte';
 | 
			
		||||
	import type { PageData } from './$types';
 | 
			
		||||
	import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
 | 
			
		||||
	export let data: PageData;
 | 
			
		||||
 | 
			
		||||
@@ -50,11 +52,15 @@
 | 
			
		||||
	const onAssetDelete = (assetId: string) => {
 | 
			
		||||
		data.assets = data.assets.filter((asset: AssetResponseDto) => asset.id !== assetId);
 | 
			
		||||
	};
 | 
			
		||||
	const handleSelectAll = () => {
 | 
			
		||||
		selectedAssets = new Set(data.assets);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if isMultiSelectionMode}
 | 
			
		||||
	<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
 | 
			
		||||
		<CreateSharedLink />
 | 
			
		||||
		<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
		<AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
			<AddToAlbum />
 | 
			
		||||
			<AddToAlbum shared />
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
	import DeleteAssets from '$lib/components/photos-page/actions/delete-assets.svelte';
 | 
			
		||||
	import DownloadAction from '$lib/components/photos-page/actions/download-action.svelte';
 | 
			
		||||
	import FavoriteAction from '$lib/components/photos-page/actions/favorite-action.svelte';
 | 
			
		||||
	import SelectAllAssets from '$lib/components/photos-page/actions/select-all-assets.svelte';
 | 
			
		||||
	import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
 | 
			
		||||
	import AssetSelectContextMenu from '$lib/components/photos-page/asset-select-context-menu.svelte';
 | 
			
		||||
	import AssetSelectControlBar from '$lib/components/photos-page/asset-select-control-bar.svelte';
 | 
			
		||||
@@ -37,6 +38,7 @@
 | 
			
		||||
				clearSelect={assetInteractionStore.clearMultiselect}
 | 
			
		||||
			>
 | 
			
		||||
				<CreateSharedLink />
 | 
			
		||||
				<SelectAllAssets />
 | 
			
		||||
				<AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
					<AddToAlbum />
 | 
			
		||||
					<AddToAlbum shared />
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
	import ImageOffOutline from 'svelte-material-icons/ImageOffOutline.svelte';
 | 
			
		||||
	import Plus from 'svelte-material-icons/Plus.svelte';
 | 
			
		||||
	import type { PageData } from './$types';
 | 
			
		||||
	import SelectAll from 'svelte-material-icons/SelectAll.svelte';
 | 
			
		||||
	import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
 | 
			
		||||
 | 
			
		||||
	export let data: PageData;
 | 
			
		||||
 | 
			
		||||
@@ -44,12 +46,16 @@
 | 
			
		||||
	const onAssetDelete = (assetId: string) => {
 | 
			
		||||
		searchResultAssets = searchResultAssets.filter((a: AssetResponseDto) => a.id !== assetId);
 | 
			
		||||
	};
 | 
			
		||||
	const handleSelectAll = () => {
 | 
			
		||||
		selectedAssets = new Set(searchResultAssets);
 | 
			
		||||
	};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<section>
 | 
			
		||||
	{#if isMultiSelectionMode}
 | 
			
		||||
		<AssetSelectControlBar assets={selectedAssets} clearSelect={() => (selectedAssets = new Set())}>
 | 
			
		||||
			<CreateSharedLink />
 | 
			
		||||
			<CircleIconButton title="Select all" logo={SelectAll} on:click={handleSelectAll} />
 | 
			
		||||
			<AssetSelectContextMenu icon={Plus} title="Add">
 | 
			
		||||
				<AddToAlbum />
 | 
			
		||||
				<AddToAlbum shared />
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user