Portal/rsconcept/frontend/src/components/select/PickSchema.tsx

125 lines
3.5 KiB
TypeScript
Raw Normal View History

2024-06-07 20:17:03 +03:00
import { useLayoutEffect, useMemo, useState } from 'react';
import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
2024-06-27 11:34:52 +03:00
import { useLibrary } from '@/context/LibraryContext';
2024-06-19 22:09:31 +03:00
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
2024-06-07 20:17:03 +03:00
import { ILibraryFilter } from '@/models/miscellaneous';
import FlexColumn from '../ui/FlexColumn';
interface PickSchemaProps {
id?: string;
initialFilter?: string;
rows?: number;
value?: LibraryItemID;
2024-07-26 00:33:22 +03:00
baseFilter?: (target: ILibraryItem) => boolean;
2024-06-07 20:17:03 +03:00
onSelectValue: (newValue: LibraryItemID) => void;
}
const columnHelper = createColumnHelper<ILibraryItem>();
2024-07-26 00:33:22 +03:00
function PickSchema({ id, initialFilter = '', rows = 4, value, onSelectValue, baseFilter }: PickSchemaProps) {
2024-06-07 20:17:03 +03:00
const intl = useIntl();
const { colors } = useConceptOptions();
const library = useLibrary();
const [filterText, setFilterText] = useState(initialFilter);
const [filter, setFilter] = useState<ILibraryFilter>({});
const [items, setItems] = useState<ILibraryItem[]>([]);
useLayoutEffect(() => {
setFilter({
2024-06-19 22:09:31 +03:00
query: filterText,
type: LibraryItemType.RSFORM
2024-06-07 20:17:03 +03:00
});
}, [filterText]);
useLayoutEffect(() => {
2024-07-26 00:33:22 +03:00
const filtered = library.applyFilter(filter);
if (baseFilter) {
setItems(filtered.filter(baseFilter));
} else {
setItems(filtered);
}
}, [library, filter, filter.query, baseFilter]);
2024-06-07 20:17:03 +03:00
const columns = useMemo(
() => [
columnHelper.accessor('alias', {
id: 'alias',
header: 'Шифр',
size: 150,
minSize: 80,
maxSize: 150
}),
columnHelper.accessor('title', {
id: 'title',
header: 'Название',
size: 1200,
minSize: 200,
maxSize: 1200,
cell: props => <div className='text-ellipsis'>{props.getValue()}</div>
}),
columnHelper.accessor('time_update', {
id: 'time_update',
header: 'Дата',
cell: props => (
<div className='whitespace-nowrap'>
{new Date(props.getValue()).toLocaleString(intl.locale, {
year: '2-digit',
month: '2-digit',
day: '2-digit'
})}
</div>
)
})
],
[intl]
);
const conditionalRowStyles = useMemo(
(): IConditionalStyle<ILibraryItem>[] => [
{
when: (item: ILibraryItem) => item.id === value,
style: { backgroundColor: colors.bgSelected }
}
],
[value, colors]
);
return (
<div className='border divide-y'>
<SearchBar
id={id ? `${id}__search` : undefined}
noBorder
value={filterText}
onChange={newValue => setFilterText(newValue)}
/>
<DataTable
id={id}
rows={rows}
dense
noHeader
noFooter
className='text-sm select-none cc-scroll-y'
data={items}
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={
2024-06-21 19:16:41 +03:00
<FlexColumn className='dense p-3 items-center min-h-[6rem]'>
2024-06-07 20:17:03 +03:00
<p>Список схем пуст</p>
<p>Измените параметры фильтра</p>
</FlexColumn>
}
onRowClicked={rowData => onSelectValue(rowData.id)}
/>
</div>
);
}
export default PickSchema;