1 import { type FC, type PropsWithChildren, createContext, useContext, useMemo, useState } from 'react';
2 import { useSelector } from 'react-redux';
4 import { selectBulkSelectionAliasCount } from '@proton/pass/store/selectors';
5 import type { BulkSelectionDTO, SelectedItem } from '@proton/pass/types';
6 import { pipe } from '@proton/pass/utils/fp/pipe';
7 import noop from '@proton/utils/noop';
9 export type BulkSelection = Map<string, Set<string>>;
11 type BulkSelectContextType = {
15 selection: BulkSelection;
19 isSelected: (item: { shareId: string; itemId: string }) => boolean;
20 select: (item: SelectedItem) => void;
21 unselect: (item: SelectedItem) => void;
24 const BulkSelectContext = createContext<BulkSelectContextType>({
32 isSelected: () => false,
37 export const bulkSelectionDTO = (selection: BulkSelection): BulkSelectionDTO =>
38 Array.from(selection.keys()).reduce<BulkSelectionDTO>((dto, shareId) => {
40 selection.get(shareId)?.forEach((itemId) => {
41 dto[shareId][itemId] = true;
47 export const BulkSelectProvider: FC<PropsWithChildren> = ({ children }) => {
48 const [selection, setSelection] = useState<BulkSelection>(new Map());
49 const [enabled, setEnabled] = useState(false);
50 const aliasCount = useSelector(selectBulkSelectionAliasCount(bulkSelectionDTO(selection)));
52 const context = useMemo<BulkSelectContextType>(() => {
53 const clear = () => setSelection(new Map());
57 count: Array.from(selection.values()).reduce((count, { size }) => count + size, 0),
62 enable: () => setEnabled(true),
63 disable: pipe(() => setEnabled(false), clear),
65 isSelected: ({ shareId, itemId }) => selection.get(shareId)?.has(itemId) ?? false,
67 select: ({ shareId, itemId }) =>
68 setSelection((curr) => {
69 const shareSet = curr.get(shareId) ?? new Set();
71 return new Map(curr.set(shareId, shareSet));
74 unselect: ({ shareId, itemId }) =>
75 setSelection((curr) => {
76 curr.get(shareId)?.delete(itemId);
80 }, [selection, enabled, aliasCount]);
82 return <BulkSelectContext.Provider value={context}>{children}</BulkSelectContext.Provider>;
85 export const useBulkSelect = (): BulkSelectContextType => useContext(BulkSelectContext);