ConceptPortal-public/rsconcept/frontend/src/pages/LibraryPage/LibraryTable.tsx

192 lines
6.0 KiB
TypeScript
Raw Normal View History

'use client';
2024-06-19 22:10:15 +03:00
import clsx from 'clsx';
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
2023-07-15 17:46:19 +03:00
import { useIntl } from 'react-intl';
2023-07-25 23:08:10 +03:00
import { urls } from '@/app/urls';
2024-06-20 11:50:37 +03:00
import { IconFolderTree } from '@/components/Icons';
2024-06-04 11:19:21 +03:00
import BadgeLocation from '@/components/info/BadgeLocation';
import { CProps } from '@/components/props';
2024-06-05 14:43:52 +03:00
import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/ui/DataTable';
import FlexColumn from '@/components/ui/FlexColumn';
2024-06-19 22:10:15 +03:00
import MiniButton from '@/components/ui/MiniButton';
import TextURL from '@/components/ui/TextURL';
2023-12-26 14:23:51 +03:00
import { useConceptNavigation } from '@/context/NavigationContext';
2024-05-02 21:19:23 +03:00
import { useConceptOptions } from '@/context/OptionsContext';
import { useUsers } from '@/context/UsersContext';
import useLocalStorage from '@/hooks/useLocalStorage';
2024-01-16 13:47:29 +03:00
import useWindowSize from '@/hooks/useWindowSize';
2024-06-04 23:00:22 +03:00
import { ILibraryItem, LibraryItemType } from '@/models/library';
import { storage } from '@/utils/constants';
2024-06-05 14:43:52 +03:00
interface LibraryTableProps {
2023-12-28 14:04:44 +03:00
items: ILibraryItem[];
resetQuery: () => void;
2024-06-19 22:10:15 +03:00
folderMode: boolean;
toggleFolderMode: () => void;
2023-07-15 17:46:19 +03:00
}
const columnHelper = createColumnHelper<ILibraryItem>();
2024-06-19 22:10:15 +03:00
function LibraryTable({ items, resetQuery, folderMode, toggleFolderMode }: LibraryTableProps) {
const router = useConceptNavigation();
2023-07-15 17:46:19 +03:00
const intl = useIntl();
const { getUserLabel } = useUsers();
2024-06-05 14:43:52 +03:00
const { calculateHeight, colors } = useConceptOptions();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50);
2023-07-15 17:46:19 +03:00
function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) {
2024-06-04 23:00:22 +03:00
if (item.item_type === LibraryItemType.RSFORM) {
router.push(urls.schema(item.id), event.ctrlKey || event.metaKey);
} else if (item.item_type === LibraryItemType.OSS) {
router.push(urls.oss(item.id), event.ctrlKey || event.metaKey);
}
}
2023-07-15 17:46:19 +03:00
2024-01-16 13:47:29 +03:00
const windowSize = useWindowSize();
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
useLayoutEffect(() => {
setColumnVisibility({
owner: !windowSize.isSmall
});
}, [windowSize]);
2024-06-19 22:10:15 +03:00
const handleToggleFolder = useCallback(
(event: CProps.EventMouse) => {
2024-06-20 11:50:37 +03:00
event.preventDefault();
event.stopPropagation();
toggleFolderMode();
2024-06-19 22:10:15 +03:00
},
[toggleFolderMode]
);
2023-08-26 17:26:49 +03:00
const columns = useMemo(
2023-12-28 14:04:44 +03:00
() => [
2024-06-19 22:10:15 +03:00
...(folderMode
? []
: [
columnHelper.accessor('location', {
id: 'location',
header: () => (
<MiniButton
noPadding
2024-06-20 11:50:37 +03:00
noHover
2024-06-19 22:10:15 +03:00
className='pl-2 max-h-[1rem] translate-y-[-0.125rem]'
onClick={handleToggleFolder}
2024-06-20 11:50:37 +03:00
titleHtml='Переключение в режим Проводник'
icon={<IconFolderTree size='1.25rem' className='clr-text-controls' />}
2024-06-19 22:10:15 +03:00
/>
),
size: 50,
minSize: 50,
maxSize: 50,
enableSorting: true,
cell: props => <BadgeLocation location={props.getValue()} />,
sortingFn: 'text'
})
]),
2023-12-28 14:04:44 +03:00
columnHelper.accessor('alias', {
id: 'alias',
header: 'Шифр',
2024-01-16 13:47:29 +03:00
size: 150,
minSize: 80,
maxSize: 150,
2023-12-28 14:04:44 +03:00
enableSorting: true,
2024-06-04 11:19:21 +03:00
cell: props => <div className='min-w-[5rem]'>{props.getValue()}</div>,
2023-12-28 14:04:44 +03:00
sortingFn: 'text'
}),
columnHelper.accessor('title', {
id: 'title',
header: 'Название',
2024-01-16 13:47:29 +03:00
size: 1200,
minSize: 200,
maxSize: 1200,
2023-12-28 14:04:44 +03:00
enableSorting: true,
sortingFn: 'text'
}),
columnHelper.accessor(item => item.owner ?? 0, {
id: 'owner',
header: 'Владелец',
2024-01-16 13:47:29 +03:00
size: 400,
minSize: 100,
maxSize: 400,
cell: props => getUserLabel(props.getValue()),
2023-12-28 14:04:44 +03:00
enableSorting: true,
sortingFn: 'text'
}),
columnHelper.accessor('time_update', {
id: 'time_update',
2024-01-16 13:47:29 +03:00
header: windowSize.isSmall ? 'Дата' : 'Обновлена',
2023-12-28 14:04:44 +03:00
cell: props => (
2024-01-16 13:47:29 +03:00
<div className='whitespace-nowrap'>
{new Date(props.getValue()).toLocaleString(intl.locale, {
2024-01-16 13:47:29 +03:00
year: '2-digit',
month: '2-digit',
day: '2-digit',
...(!windowSize.isSmall && {
hour: '2-digit',
minute: '2-digit'
})
})}
</div>
2023-12-28 14:04:44 +03:00
),
enableSorting: true,
sortingFn: 'datetime',
sortDescFirst: true
})
],
2024-06-19 22:10:15 +03:00
[intl, getUserLabel, windowSize, handleToggleFolder, folderMode]
2023-12-28 14:04:44 +03:00
);
2023-09-10 20:17:18 +03:00
2024-05-02 21:19:23 +03:00
const tableHeight = useMemo(() => calculateHeight('2.2rem'), [calculateHeight]);
2024-06-05 14:43:52 +03:00
const conditionalRowStyles = useMemo(
(): IConditionalStyle<ILibraryItem>[] => [
{
when: (item: ILibraryItem) => item.item_type === LibraryItemType.OSS,
style: {
backgroundColor: colors.bgGreen50
}
}
],
[colors]
);
2023-12-28 14:04:44 +03:00
return (
<DataTable
id='library_data'
columns={columns}
data={items}
headPosition='0'
2024-06-19 22:10:15 +03:00
className={clsx('text-xs sm:text-sm cc-scroll-y', { 'border-l border-b': folderMode })}
style={{ maxHeight: tableHeight }}
noDataComponent={
<FlexColumn className='p-3 items-center min-h-[6rem]'>
<p>Список схем пуст</p>
<p className='flex gap-6'>
<TextURL text='Создать схему' href='/library/create' />
<TextURL text='Очистить фильтр' onClick={resetQuery} />
</p>
</FlexColumn>
}
columnVisibility={columnVisibility}
onRowClicked={handleOpenItem}
enableSorting
initialSorting={{
id: 'time_update',
desc: true
}}
enablePagination
paginationPerPage={itemsPerPage}
onChangePaginationOption={setItemsPerPage}
paginationOptions={[10, 20, 30, 50, 100]}
2024-06-05 14:43:52 +03:00
conditionalRowStyles={conditionalRowStyles}
/>
2023-12-28 14:04:44 +03:00
);
2023-07-15 17:46:19 +03:00
}
2024-06-05 14:43:52 +03:00
export default LibraryTable;