buster/web/src/components/features/dropdowns/SaveToCollectionsDropdown.tsx

115 lines
3.7 KiB
TypeScript
Raw Normal View History

2025-02-20 10:53:49 +08:00
import { AppDropdownSelect } from '@/components/ui/dropdown';
2025-02-20 11:05:30 +08:00
import { AppMaterialIcons } from '@/components/ui';
2025-02-20 10:53:49 +08:00
import { AppTooltip } from '@/components/ui/tooltip';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
2025-02-13 12:57:05 +08:00
import { useBusterCollectionListContextSelector } from '@/context/Collections';
2025-01-24 04:15:10 +08:00
import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes';
import { useMemoizedFn } from 'ahooks';
import { Button } from 'antd';
import React, { useMemo } from 'react';
2025-02-01 02:04:49 +08:00
import type { BusterCollectionListItem } from '@/api/asset_interfaces';
2025-03-01 02:30:39 +08:00
import { NewCollectionModal } from '../modals/NewCollectionModal';
export const SaveToCollectionsDropdown: React.FC<{
children: React.ReactNode;
selectedCollections: string[];
onSaveToCollection: (collectionId: string[]) => Promise<void>;
onRemoveFromCollection: (collectionId: string) => Promise<void>;
}> = React.memo(({ children, onRemoveFromCollection, onSaveToCollection, selectedCollections }) => {
2025-02-13 12:57:05 +08:00
const collectionsList = useBusterCollectionListContextSelector((x) => x.collectionsList);
const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage);
const [openCollectionModal, setOpenCollectionModal] = React.useState(false);
const [showDropdown, setShowDropdown] = React.useState(false);
const items = useMemo(
() =>
2025-02-13 12:57:05 +08:00
(collectionsList || []).map((collection) => {
return {
key: collection.id,
label: collection.name,
onClick: () => onClickItem(collection),
link: createBusterRoute({
route: BusterRoutes.APP_COLLECTIONS_ID,
collectionId: collection.id
})
};
}),
[collectionsList]
);
const onClickItem = useMemoizedFn((collection: BusterCollectionListItem) => {
const isSelected = selectedCollections.some((id) => id === collection.id);
if (isSelected) {
onRemoveFromCollection(collection.id);
} else {
const allCollectionsAndSelected = selectedCollections.map((id) => id).concat(collection.id);
onSaveToCollection(allCollectionsAndSelected);
}
});
const onCollectionCreated = useMemoizedFn(async (collectionId: string) => {
await onSaveToCollection([collectionId]);
onChangePage({
route: BusterRoutes.APP_COLLECTIONS_ID,
collectionId
});
});
const onCloseCollectionModal = useMemoizedFn(() => {
setOpenCollectionModal(false);
setShowDropdown(false);
});
const onOpenChange = useMemoizedFn((open: boolean) => {
setShowDropdown(open);
});
const onClick = useMemoizedFn(() => {
setOpenCollectionModal(true);
setShowDropdown(false);
});
2025-02-05 11:57:02 +08:00
const memoizedButton = useMemo(() => {
return (
<Button
type="text"
block
2025-02-19 04:23:44 +08:00
className="justify-start!"
2025-02-05 11:57:02 +08:00
icon={<AppMaterialIcons icon="add" />}
onClick={onClick}>
New collection
</Button>
);
}, [onClick]);
return (
<>
<AppDropdownSelect
trigger={['click']}
placement="bottomRight"
2025-02-19 04:23:44 +08:00
className="flex! h-fit! items-center"
headerContent={'Save to a collection'}
open={showDropdown}
onOpenChange={onOpenChange}
2025-02-05 11:57:02 +08:00
footerContent={memoizedButton}
items={items}
selectedItems={selectedCollections}>
{showDropdown ? (
<>{children}</>
) : (
<AppTooltip title={showDropdown ? '' : 'Save to collection'}>{children} </AppTooltip>
)}
</AppDropdownSelect>
<NewCollectionModal
open={openCollectionModal}
onClose={onCloseCollectionModal}
useChangePage={false}
onCollectionCreated={onCollectionCreated}
/>
</>
);
});
SaveToCollectionsDropdown.displayName = 'SaveToCollectionsDropdown';