2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
|
|
|
|
2024-12-12 13:19:12 +03:00
|
|
|
import { animated, useSpring } from '@react-spring/web';
|
2024-03-15 14:35:06 +03:00
|
|
|
import clsx from 'clsx';
|
2024-12-12 13:19:12 +03:00
|
|
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
2023-12-08 19:24:08 +03:00
|
|
|
|
2024-06-09 15:19:39 +03:00
|
|
|
import { useAccessMode } from '@/context/AccessModeContext';
|
2024-06-26 19:47:31 +03:00
|
|
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
2024-06-04 14:20:43 +03:00
|
|
|
import useWindowSize from '@/hooks/useWindowSize';
|
2024-03-17 19:24:12 +03:00
|
|
|
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
2024-06-09 15:19:39 +03:00
|
|
|
import { UserLevel } from '@/models/user';
|
2024-12-12 13:19:12 +03:00
|
|
|
import { PARAMETER } from '@/utils/constants';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
2023-12-08 19:24:08 +03:00
|
|
|
import ConstituentsSearch from './ConstituentsSearch';
|
2024-06-26 19:47:31 +03:00
|
|
|
import TableSideConstituents from './TableSideConstituents';
|
2023-12-08 19:24:08 +03:00
|
|
|
|
2024-06-04 14:20:43 +03:00
|
|
|
// Window width cutoff for dense search bar
|
|
|
|
const COLUMN_DENSE_SEARCH_THRESHOLD = 1100;
|
|
|
|
|
2023-12-08 19:24:08 +03:00
|
|
|
interface ViewConstituentsProps {
|
2023-12-28 14:04:44 +03:00
|
|
|
expression: string;
|
2024-03-15 14:35:06 +03:00
|
|
|
isBottom?: boolean;
|
2024-05-23 13:36:16 +03:00
|
|
|
activeCst?: IConstituenta;
|
2023-12-28 14:04:44 +03:00
|
|
|
schema?: IRSForm;
|
2024-03-17 19:24:12 +03:00
|
|
|
onOpenEdit: (cstID: ConstituentaID) => void;
|
2024-12-12 13:19:12 +03:00
|
|
|
isMounted: boolean;
|
2023-12-08 19:24:08 +03:00
|
|
|
}
|
|
|
|
|
2024-12-12 13:19:12 +03:00
|
|
|
function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit, isMounted }: ViewConstituentsProps) {
|
2024-04-06 14:39:49 +03:00
|
|
|
const { calculateHeight } = useConceptOptions();
|
2024-06-04 14:20:43 +03:00
|
|
|
const windowSize = useWindowSize();
|
2024-06-09 15:19:39 +03:00
|
|
|
const { accessLevel } = useAccessMode();
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2023-12-08 19:24:08 +03:00
|
|
|
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
|
|
|
|
2024-12-12 13:19:12 +03:00
|
|
|
const [isVisible, setIsVisible] = useState(true);
|
|
|
|
const isFirstRender = useRef(true);
|
|
|
|
const springs = useSpring({
|
|
|
|
from: { opacity: 0, width: '0' },
|
|
|
|
to: async next => {
|
|
|
|
if (isFirstRender.current) {
|
|
|
|
await next({ opacity: isMounted ? 1 : 0, width: isMounted ? '100%' : '0', config: { duration: 0 } });
|
|
|
|
isFirstRender.current = false;
|
|
|
|
} else {
|
|
|
|
if (isMounted) {
|
|
|
|
await next({ width: '100%', config: { duration: PARAMETER.moveDuration } });
|
|
|
|
await next({ opacity: 1, config: { duration: PARAMETER.fadeDuration } });
|
|
|
|
} else {
|
|
|
|
await next({ opacity: 0, config: { duration: PARAMETER.fadeDuration } });
|
|
|
|
await next({ width: '0', config: { duration: PARAMETER.moveDuration } });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onRest: props => {
|
|
|
|
if (props.finished && !isMounted) {
|
|
|
|
setIsVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isMounted) {
|
|
|
|
setIsVisible(true);
|
|
|
|
}
|
|
|
|
}, [isMounted]);
|
|
|
|
|
2024-04-30 16:06:25 +03:00
|
|
|
const table = useMemo(
|
|
|
|
() => (
|
2024-06-26 19:47:31 +03:00
|
|
|
<TableSideConstituents
|
2024-06-09 15:19:39 +03:00
|
|
|
maxHeight={
|
|
|
|
isBottom
|
|
|
|
? calculateHeight(accessLevel !== UserLevel.READER ? '42rem' : '35rem', '10rem')
|
|
|
|
: calculateHeight('8.2rem')
|
|
|
|
}
|
2024-04-30 16:06:25 +03:00
|
|
|
items={filteredData}
|
2024-05-23 13:36:16 +03:00
|
|
|
activeCst={activeCst}
|
2024-04-30 16:06:25 +03:00
|
|
|
onOpenEdit={onOpenEdit}
|
2024-08-24 08:24:32 +03:00
|
|
|
autoScroll={!isBottom}
|
2024-04-30 16:06:25 +03:00
|
|
|
/>
|
|
|
|
),
|
2024-06-09 15:19:39 +03:00
|
|
|
[isBottom, filteredData, activeCst, onOpenEdit, calculateHeight, accessLevel]
|
2024-04-30 16:06:25 +03:00
|
|
|
);
|
|
|
|
|
2024-12-12 13:19:12 +03:00
|
|
|
if (!isVisible) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-12-17 20:19:28 +03:00
|
|
|
return (
|
2024-12-12 13:19:12 +03:00
|
|
|
<animated.div
|
2024-03-15 14:35:06 +03:00
|
|
|
className={clsx(
|
2024-08-24 08:24:32 +03:00
|
|
|
'border', // prettier: split-lines
|
2024-03-15 14:35:06 +03:00
|
|
|
{
|
2024-08-24 08:24:32 +03:00
|
|
|
'mt-[2.2rem] rounded-l-md rounded-r-none h-fit overflow-visible': !isBottom,
|
|
|
|
'mt-3 mx-6 rounded-md md:max-w-[45.8rem] overflow-hidden': isBottom
|
2024-03-15 14:35:06 +03:00
|
|
|
}
|
|
|
|
)}
|
2024-12-12 13:19:12 +03:00
|
|
|
style={springs}
|
2023-12-28 14:04:44 +03:00
|
|
|
>
|
|
|
|
<ConstituentsSearch
|
2024-06-04 14:20:43 +03:00
|
|
|
dense={windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD ? true : undefined}
|
2023-12-28 14:04:44 +03:00
|
|
|
schema={schema}
|
2024-05-23 13:36:16 +03:00
|
|
|
activeID={activeCst?.id}
|
2023-12-28 14:04:44 +03:00
|
|
|
activeExpression={expression}
|
|
|
|
setFiltered={setFilteredData}
|
|
|
|
/>
|
2024-04-30 16:06:25 +03:00
|
|
|
{table}
|
2024-12-12 13:19:12 +03:00
|
|
|
</animated.div>
|
2023-12-28 14:04:44 +03:00
|
|
|
);
|
2023-12-08 19:24:08 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
export default ViewConstituents;
|