"use client"; import { Box, Checkbox, Divider, FormControl, InputLabel, ListItemIcon, ListItemText, ListSubheader, MenuItem, Select, SelectChangeEvent, Stack, Typography, } from "@mui/material"; import React, { useCallback } from "react"; import { LabelGroup, LabelWithId, TransferListProps } from "./TransferList"; import { useTranslation } from "react-i18next"; import uniqBy from "lodash/uniqBy"; import groupBy from "lodash/groupBy"; import intersectionBy from "lodash/intersectionBy"; import union from "lodash/union"; import differenceBy from "lodash/differenceBy"; export const MultiSelectList: React.FC = ({ allItems, selectedItems, selectedItemsLabel, allItemsLabel, onChange, }) => { // Keep a map for the original order of items const sortMap = React.useMemo(() => { return allItems.reduce<{ [id: string]: LabelWithId & { index: number } }>( (acc, item, index) => ({ ...acc, [item.id]: { ...item, index } }), {}, ); }, [allItems]); const compareFn = React.useCallback( (a: number, b: number) => sortMap[a].index - sortMap[b].index, [sortMap], ); const handleChange = useCallback( (event: SelectChangeEvent) => { const { target: { value }, } = event; const selectedValues = typeof value === "string" ? [Number(value)] : value; onChange(allItems.filter((item) => selectedValues.includes(item.id))); }, [allItems, onChange], ); const handleToggleAll = useCallback(() => { if (selectedItems.length === allItems.length) { onChange([]); } else { onChange(allItems); } }, [allItems, onChange, selectedItems.length]); const handleToggleAllInGroup = useCallback( (groupItems: LabelWithId[]) => () => { const selectedGroupItems = intersectionBy( selectedItems, groupItems, "id", ); if (selectedGroupItems.length !== groupItems.length) { onChange(union(selectedItems, groupItems)); } else { onChange(differenceBy(selectedItems, groupItems, "id")); } }, [onChange, selectedItems], ); const { t } = useTranslation(); const groups: LabelGroup[] = uniqBy( [ ...allItems.reduce((acc, item) => { return item.group ? [...acc, item.group] : acc; }, []), // Items with no group { id: 0, name: t("Ungrouped") }, ], "id", ); const groupedItems = groupBy(allItems, (item) => item.group?.id ?? 0); return ( {selectedItemsLabel} ); }; export default MultiSelectList;