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

155 lines
4.5 KiB
TypeScript
Raw Normal View History

'use client';
import clsx from 'clsx';
2024-01-16 13:47:29 +03:00
import { 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
2024-01-16 13:47:29 +03:00
import DataTable, { createColumnHelper, VisibilityState } from '@/components/DataTable';
import HelpButton from '@/components/Help/HelpButton';
import FlexColumn from '@/components/ui/FlexColumn';
import TextURL from '@/components/ui/TextURL';
import { useAuth } from '@/context/AuthContext';
2023-12-26 14:23:51 +03:00
import { useConceptNavigation } from '@/context/NavigationContext';
import { useUsers } from '@/context/UsersContext';
import useLocalStorage from '@/hooks/useLocalStorage';
2024-01-16 13:47:29 +03:00
import useWindowSize from '@/hooks/useWindowSize';
import { ILibraryItem } from '@/models/library';
2023-12-26 14:23:51 +03:00
import { HelpTopic } from '@/models/miscellaneous';
import ItemIcons from './ItemIcons';
2023-07-15 17:46:19 +03:00
2023-07-28 00:03:37 +03:00
interface ViewLibraryProps {
2023-12-28 14:04:44 +03:00
items: ILibraryItem[];
resetQuery: () => void;
2023-07-15 17:46:19 +03:00
}
const columnHelper = createColumnHelper<ILibraryItem>();
function ViewLibrary({ items, resetQuery }: ViewLibraryProps) {
const router = useConceptNavigation();
2023-07-15 17:46:19 +03:00
const intl = useIntl();
2023-09-05 00:23:53 +03:00
const { user } = useAuth();
2023-07-15 17:46:19 +03:00
const { getUserLabel } = useUsers();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>('library_per_page', 50);
2023-07-15 17:46:19 +03:00
const handleOpenItem = (item: ILibraryItem) => router.push(`/rsforms/${item.id}`);
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]);
2023-08-26 17:26:49 +03:00
const columns = useMemo(
2023-12-28 14:04:44 +03:00
() => [
columnHelper.display({
id: 'status',
header: '',
size: 60,
minSize: 60,
maxSize: 60,
cell: props => <ItemIcons item={props.row.original} user={user} />
}),
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,
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-01-16 13:47:29 +03:00
[intl, getUserLabel, user, windowSize]
2023-12-28 14:04:44 +03:00
);
2023-09-10 20:17:18 +03:00
2023-12-28 14:04:44 +03:00
return (
<>
2024-02-22 11:35:27 +03:00
<div className='sticky top-[2.3rem]'>
2024-01-04 15:04:14 +03:00
<div
className={clsx(
'z-pop', // prettier: split lines
'absolute top-[0.125rem] left-[0.25rem]',
'ml-3',
'flex gap-1'
)}
>
2024-02-22 11:35:27 +03:00
<HelpButton topic={HelpTopic.LIBRARY} className='max-w-[30rem] text-sm' offset={5} place='right-start' />
2023-12-28 14:04:44 +03:00
</div>
</div>
<DataTable
id='library_data'
2023-12-28 14:04:44 +03:00
columns={columns}
data={items}
2024-01-16 13:47:29 +03:00
headPosition='2.2rem'
className='text-xs sm:text-sm'
2023-12-28 14:04:44 +03:00
noDataComponent={
<FlexColumn className='p-3 items-center min-h-[6rem]'>
2023-12-28 14:04:44 +03:00
<p>Список схем пуст</p>
<p className='flex gap-6'>
2023-12-28 14:04:44 +03:00
<TextURL text='Создать схему' href='/library/create' />
<TextURL text='Очистить фильтр' onClick={resetQuery} />
2023-12-28 14:04:44 +03:00
</p>
</FlexColumn>
2023-12-28 14:04:44 +03:00
}
2024-01-16 13:47:29 +03:00
columnVisibility={columnVisibility}
2023-12-28 14:04:44 +03:00
onRowClicked={handleOpenItem}
enableSorting
initialSorting={{
id: 'time_update',
desc: true
}}
enablePagination
paginationPerPage={itemsPerPage}
onChangePaginationOption={setItemsPerPage}
paginationOptions={[10, 20, 30, 50, 100]}
/>
</>
);
2023-07-15 17:46:19 +03:00
}
2023-12-28 14:04:44 +03:00
export default ViewLibrary;