mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-13 22:56:28 +00:00
109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import React, { useState, useCallback, useMemo } from 'react';
|
|
import type { FlexProps } from '@chakra-ui/react';
|
|
import { Box, Checkbox, Flex } from '@chakra-ui/react';
|
|
import { useTranslation } from 'next-i18next';
|
|
|
|
export type TableMultipleSelectHookProps<T = any> = {
|
|
list: T[];
|
|
getItemId: (item: T) => string | number;
|
|
};
|
|
|
|
export const useTableMultipleSelect = <T = any,>({
|
|
list,
|
|
getItemId
|
|
}: TableMultipleSelectHookProps<T>) => {
|
|
const { t } = useTranslation();
|
|
const [selectedItems, setSelectedItems] = useState<T[]>([]);
|
|
|
|
// Toggle single item selection
|
|
const toggleSelect = useCallback(
|
|
(item: T) => {
|
|
const itemId = getItemId(item);
|
|
setSelectedItems((prev) => {
|
|
const isSelected = prev.some((selected) => getItemId(selected) === itemId);
|
|
if (isSelected) {
|
|
return prev.filter((selected) => getItemId(selected) !== itemId);
|
|
} else {
|
|
return [...prev, item];
|
|
}
|
|
});
|
|
},
|
|
[getItemId]
|
|
);
|
|
|
|
// Check if item is selected
|
|
const isSelected = useCallback(
|
|
(item: T) => {
|
|
const itemId = getItemId(item);
|
|
return selectedItems.some((selected) => getItemId(selected) === itemId);
|
|
},
|
|
[selectedItems, getItemId]
|
|
);
|
|
|
|
const isSelecteAll = useMemo(() => {
|
|
return list.length > 0 && list.every((item) => isSelected(item));
|
|
}, [list, isSelected]);
|
|
|
|
// Select all items
|
|
const selectAllTrigger = useCallback(() => {
|
|
if (isSelecteAll) {
|
|
setSelectedItems([]);
|
|
} else {
|
|
setSelectedItems((pre) => [...pre, ...list.filter((item) => !isSelected(item))]);
|
|
}
|
|
}, [isSelecteAll, list, isSelected]);
|
|
|
|
const selectedCount = selectedItems.length;
|
|
// Check if has selections
|
|
const hasSelections = selectedCount > 0;
|
|
|
|
// Floating Action Bar component
|
|
const FloatingActionBar = useCallback(
|
|
({
|
|
children,
|
|
Controler,
|
|
activedStyles,
|
|
...props
|
|
}: { children?: ReactNode; activedStyles?: FlexProps; Controler: ReactNode } & FlexProps) => {
|
|
return hasSelections || !!children ? (
|
|
<Flex
|
|
w={'100%'}
|
|
bg="white"
|
|
px={6}
|
|
pt={4}
|
|
pb={2}
|
|
alignItems="center"
|
|
{...props}
|
|
{...activedStyles}
|
|
>
|
|
{hasSelections && (
|
|
<>
|
|
<Checkbox size="sm" isChecked={isSelecteAll} onChange={selectAllTrigger} />
|
|
<Box ml={2} fontSize="sm" color="gray.600">
|
|
{t('common:select_count_num', { num: selectedCount })}
|
|
</Box>
|
|
<Box flex={'1 0 0'} ml={4}>
|
|
{Controler}
|
|
</Box>
|
|
</>
|
|
)}
|
|
<Box flex={hasSelections ? '' : '1 0 0'}>{children}</Box>
|
|
</Flex>
|
|
) : null;
|
|
},
|
|
[hasSelections, isSelecteAll, selectAllTrigger, selectedCount, t]
|
|
);
|
|
|
|
return {
|
|
selectedItems,
|
|
isSelecteAll,
|
|
selectAllTrigger,
|
|
hasSelections,
|
|
toggleSelect,
|
|
isSelected,
|
|
FloatingActionBar,
|
|
setSelectedItems
|
|
};
|
|
};
|