ConceptPortal-public/rsconcept/frontend/src/components/select/PickConstituenta.tsx

121 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-03-20 15:03:53 +03:00
'use client';
import { useEffect, useMemo, useState } from 'react';
2024-03-20 15:27:32 +03:00
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
2024-04-01 19:07:20 +03:00
import { useConceptOptions } from '@/context/OptionsContext';
2023-12-26 14:23:51 +03:00
import { CstMatchMode } from '@/models/miscellaneous';
import { IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI';
import { prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels';
2024-05-16 22:39:28 +03:00
import BadgeConstituenta from '../info/BadgeConstituenta';
2024-03-20 15:27:32 +03:00
import FlexColumn from '../ui/FlexColumn';
2024-05-16 22:39:28 +03:00
interface PickConstituentaProps {
id?: string;
2024-03-20 15:03:53 +03:00
prefixID: string;
2023-12-28 14:04:44 +03:00
data?: IConstituenta[];
rows?: number;
2024-01-29 14:44:51 +03:00
initialFilter?: string;
2023-12-28 14:04:44 +03:00
onBeginFilter?: (cst: IConstituenta) => boolean;
describeFunc?: (cst: IConstituenta) => string;
matchFunc?: (cst: IConstituenta, filter: string) => boolean;
value?: IConstituenta;
onSelectValue: (newValue: IConstituenta) => void;
}
const columnHelper = createColumnHelper<IConstituenta>();
2024-05-16 22:39:28 +03:00
function PickConstituenta({
id,
2023-12-28 14:04:44 +03:00
data,
value,
2024-01-29 14:44:51 +03:00
initialFilter = '',
rows = 4,
prefixID = prefixes.cst_list,
describeFunc = describeConstituenta,
matchFunc = (cst, filter) => matchConstituenta(cst, filter, CstMatchMode.ALL),
2023-12-27 19:34:39 +03:00
onBeginFilter,
onSelectValue
2024-05-16 22:39:28 +03:00
}: PickConstituentaProps) {
2024-04-01 19:07:20 +03:00
const { colors } = useConceptOptions();
const [filteredData, setFilteredData] = useState<IConstituenta[]>([]);
2024-01-29 14:44:51 +03:00
const [filterText, setFilterText] = useState(initialFilter);
2023-12-28 14:04:44 +03:00
useEffect(() => {
if (!data) {
setFilteredData([]);
} else {
2023-12-27 19:34:39 +03:00
const newData = onBeginFilter ? data.filter(onBeginFilter) : data;
if (filterText) {
setFilteredData(newData.filter(cst => matchFunc(cst, filterText)));
} else {
setFilteredData(newData);
}
}
2023-12-27 19:34:39 +03:00
}, [data, filterText, matchFunc, onBeginFilter]);
const columns = useMemo(
2023-12-28 14:04:44 +03:00
() => [
columnHelper.accessor('alias', {
id: 'alias',
size: 65,
minSize: 65,
maxSize: 65,
2024-05-16 22:39:28 +03:00
cell: props => <BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixID} />
2023-12-28 14:04:44 +03:00
}),
columnHelper.accessor(cst => describeFunc(cst), {
id: 'description'
})
],
[colors, prefixID, describeFunc]
);
const conditionalRowStyles = useMemo(
2023-12-28 14:04:44 +03:00
(): IConditionalStyle<IConstituenta>[] => [
{
when: (cst: IConstituenta) => cst.id === value?.id,
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)}
/>
2023-12-28 14:04:44 +03:00
<DataTable
id={id}
2024-03-20 15:03:53 +03:00
rows={rows}
contentHeight='1.3rem'
2023-12-28 14:04:44 +03:00
dense
noHeader
noFooter
2024-05-02 21:19:23 +03:00
className='text-sm select-none cc-scroll-y'
2023-12-28 14:04:44 +03:00
data={filteredData}
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={
<FlexColumn className='p-3 items-center min-h-[6rem]'>
2023-12-28 14:04:44 +03:00
<p>Список конституент пуст</p>
<p>Измените параметры фильтра</p>
</FlexColumn>
2023-12-28 14:04:44 +03:00
}
onRowClicked={onSelectValue}
/>
</div>
);
}
2024-05-16 22:39:28 +03:00
export default PickConstituenta;