feat: bulk delete in find page and find page clean up

Signed-off-by: Varun Raj <varun@skcript.com>
This commit is contained in:
Varun Raj committed 2025-01-19 09:31:35 +05:30
1 parent b60660fe2e
commit 2150aca154
12 files changed
+156 -49

No files matched your search

+49 -4
View File
@@ -1,7 +1,7 @@
import "yet-another-react-lightbox/styles.css";
import { IAsset } from '@/types/asset';
import React, { useMemo, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import Lightbox from 'yet-another-react-lightbox';
import { Gallery } from "react-grid-gallery";
import LazyGridImage from "../ui/lazy-grid-image";
@@ -12,10 +12,40 @@ interface AssetGridProps {
assets: IAsset[];
isInternal?: boolean;
selectable?: boolean;
onSelectionChange?: (ids: string[]) => void;
}
export default function AssetGrid({ assets, isInternal = true, selectable = false }: AssetGridProps) {
export default function AssetGrid({ assets, isInternal = true, selectable = false, onSelectionChange }: AssetGridProps) {
const [index, setIndex] = useState(-1);
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [lastSelectedIndex, setLastSelectedIndex] = useState(-1);
const handleSelect = (_idx: number, asset: IAsset, event: React.MouseEvent<HTMLElement>) => {
event.stopPropagation();
const isPresent = selectedIds.includes(asset.id);
if (isPresent) {
setSelectedIds(selectedIds.filter((id) => id !== asset.id));
onSelectionChange?.(selectedIds.filter((id) => id !== asset.id));
} else {
const clickedIndex = images.findIndex((image) => {
return image.id === asset.id;
});
if (event.shiftKey) {
const startIndex = Math.min(clickedIndex, lastSelectedIndex);
const endIndex = Math.max(clickedIndex, lastSelectedIndex);
const newSelectedIds = images.slice(startIndex, endIndex + 1).map((image) => image.id);
const allSelectedIds = [...selectedIds, ...newSelectedIds];
const uniqueSelectedIds = [...new Set(allSelectedIds)];
setSelectedIds(uniqueSelectedIds);
onSelectionChange?.(uniqueSelectedIds);
} else {
setSelectedIds([...selectedIds, asset.id]);
onSelectionChange?.([...selectedIds, asset.id]);
}
setLastSelectedIndex(clickedIndex);
}
};
const slides = useMemo(() => {
return assets.map((asset) => ({
@@ -45,9 +75,23 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals
original: p.previewUrl as string,
width: p.exifImageWidth / 10 as number,
height: p.exifImageHeight / 10 as number,
orientation: 1
orientation: 1,
isSelected: selectedIds.includes(p.id),
}));
}, [assets]);
}, [assets, selectedIds]);
const handleEsc = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setSelectedIds([]);
onSelectionChange?.([]);
}
};
useEffect(() => {
// Listen for esc key press and unselect all images
window.addEventListener("keydown", handleEsc);
return () => window.removeEventListener("keydown", handleEsc);
}, [images]);
return (
<div>
@@ -63,6 +107,7 @@ export default function AssetGrid({ assets, isInternal = true, selectable = fals
onClick={setIndex}
enableImageSelection={selectable}
thumbnailImageComponent={LazyGridImage}
onSelect={handleSelect}
/>
</div>
);
@@ -0,0 +1,36 @@
import React, { useMemo } from 'react'
import { Button } from '../ui/button';
import { AlertDialog } from '../ui/alert-dialog';
import { deleteAssets } from '@/handlers/api/asset.handler';
interface AssetsBulkDeleteButtonProps {
selectedIds: string[];
onDelete: (ids: string[]) => void;
}
export default function AssetsBulkDeleteButton({ selectedIds, onDelete }: AssetsBulkDeleteButtonProps) {
const ids = useMemo(() => {
return selectedIds
}, [selectedIds]);
const handleDelete = () => {
return deleteAssets(ids).then(() => {
onDelete(ids);
})
}
return (
<AlertDialog
title="Delete the selected assets?"
description="This action will delete the selected assets and cannot be undone."
onConfirm={handleDelete}
disabled={ids.length === 0}
>
<Button variant={"destructive"} size={"sm"} disabled={ids.length === 0}>
Delete
</Button>
</AlertDialog>
)
}