mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
R: Refactor constituents search
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
This commit is contained in:
parent
d0b430eb17
commit
cad521f46d
|
@ -1,27 +1,20 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { MiniButton } from '@/components/Control';
|
import { MiniButton } from '@/components/Control';
|
||||||
import { IconChild } from '@/components/Icons';
|
import { IconChild } from '@/components/Icons';
|
||||||
import { SearchBar } from '@/components/Input';
|
import { SearchBar } from '@/components/Input';
|
||||||
|
|
||||||
import { type IConstituenta, type IRSForm } from '../../../models/rsform';
|
|
||||||
import { matchConstituenta } from '../../../models/rsformAPI';
|
|
||||||
import { SelectMatchMode } from '../../../pages/RSFormPage/ViewConstituents/SelectMatchMode';
|
import { SelectMatchMode } from '../../../pages/RSFormPage/ViewConstituents/SelectMatchMode';
|
||||||
import { DependencyMode, useCstSearchStore } from '../../../stores/cstSearch';
|
import { useCstSearchStore } from '../../../stores/cstSearch';
|
||||||
|
import { useRSEdit } from '../RSEditContext';
|
||||||
|
|
||||||
import { SelectGraphFilter } from './SelectGraphFilter';
|
import { SelectGraphFilter } from './SelectGraphFilter';
|
||||||
|
|
||||||
interface ConstituentsSearchProps {
|
interface ConstituentsSearchProps {
|
||||||
schema: IRSForm;
|
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
activeID?: number;
|
|
||||||
|
|
||||||
onChange: (newValue: IConstituenta[]) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ConstituentsSearch({ schema, activeID, dense, onChange }: ConstituentsSearchProps) {
|
export function ConstituentsSearch({ dense }: ConstituentsSearchProps) {
|
||||||
const query = useCstSearchStore(state => state.query);
|
const query = useCstSearchStore(state => state.query);
|
||||||
const filterMatch = useCstSearchStore(state => state.match);
|
const filterMatch = useCstSearchStore(state => state.match);
|
||||||
const filterSource = useCstSearchStore(state => state.source);
|
const filterSource = useCstSearchStore(state => state.source);
|
||||||
|
@ -31,13 +24,7 @@ export function ConstituentsSearch({ schema, activeID, dense, onChange }: Consti
|
||||||
const setSource = useCstSearchStore(state => state.setSource);
|
const setSource = useCstSearchStore(state => state.setSource);
|
||||||
const toggleInherited = useCstSearchStore(state => state.toggleInherited);
|
const toggleInherited = useCstSearchStore(state => state.toggleInherited);
|
||||||
|
|
||||||
const graphFiltered = activeID ? applyGraphQuery(schema, activeID, filterSource) : schema.items;
|
const { schema } = useRSEdit();
|
||||||
const queryFiltered = query ? graphFiltered.filter(cst => matchConstituenta(cst, query, filterMatch)) : graphFiltered;
|
|
||||||
const inheritanceFiltered = !includeInherited ? queryFiltered.filter(cst => !cst.is_inherited) : queryFiltered;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
onChange(inheritanceFiltered);
|
|
||||||
}, [inheritanceFiltered, onChange]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex border-b clr-input rounded-t-md'>
|
<div className='flex border-b clr-input rounded-t-md'>
|
||||||
|
@ -62,34 +49,3 @@ export function ConstituentsSearch({ schema, activeID, dense, onChange }: Consti
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== Internals =========
|
|
||||||
/**
|
|
||||||
* Filter list of {@link ILibraryItem} to a given graph query.
|
|
||||||
*/
|
|
||||||
function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): IConstituenta[] {
|
|
||||||
if (mode === DependencyMode.ALL) {
|
|
||||||
return target.items;
|
|
||||||
}
|
|
||||||
const ids = (() => {
|
|
||||||
switch (mode) {
|
|
||||||
case DependencyMode.OUTPUTS: {
|
|
||||||
return target.graph.nodes.get(pivot)?.outputs;
|
|
||||||
}
|
|
||||||
case DependencyMode.INPUTS: {
|
|
||||||
return target.graph.nodes.get(pivot)?.inputs;
|
|
||||||
}
|
|
||||||
case DependencyMode.EXPAND_OUTPUTS: {
|
|
||||||
return target.graph.expandAllOutputs([pivot]);
|
|
||||||
}
|
|
||||||
case DependencyMode.EXPAND_INPUTS: {
|
|
||||||
return target.graph.expandAllInputs([pivot]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
if (ids) {
|
|
||||||
return target.items.filter(cst => ids.find(id => id === cst.id));
|
|
||||||
} else {
|
|
||||||
return target.items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,27 +9,32 @@ import { PARAMETER, prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
import { BadgeConstituenta } from '../../../components/BadgeConstituenta';
|
import { BadgeConstituenta } from '../../../components/BadgeConstituenta';
|
||||||
import { describeConstituenta } from '../../../labels';
|
import { describeConstituenta } from '../../../labels';
|
||||||
import { type IConstituenta } from '../../../models/rsform';
|
import { type IConstituenta, type IRSForm } from '../../../models/rsform';
|
||||||
|
import { matchConstituenta } from '../../../models/rsformAPI';
|
||||||
|
import { DependencyMode, useCstSearchStore } from '../../../stores/cstSearch';
|
||||||
|
import { useRSEdit } from '../RSEditContext';
|
||||||
|
|
||||||
const DESCRIPTION_MAX_SYMBOLS = 280;
|
const DESCRIPTION_MAX_SYMBOLS = 280;
|
||||||
|
|
||||||
interface TableSideConstituentsProps {
|
interface TableSideConstituentsProps {
|
||||||
items: IConstituenta[];
|
|
||||||
activeCst: IConstituenta | null;
|
|
||||||
onOpenEdit: (cstID: number) => void;
|
|
||||||
autoScroll?: boolean;
|
autoScroll?: boolean;
|
||||||
maxHeight: string;
|
maxHeight: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<IConstituenta>();
|
const columnHelper = createColumnHelper<IConstituenta>();
|
||||||
|
|
||||||
export function TableSideConstituents({
|
export function TableSideConstituents({ autoScroll = true, maxHeight }: TableSideConstituentsProps) {
|
||||||
items,
|
const { schema, activeCst, navigateCst } = useRSEdit();
|
||||||
activeCst,
|
|
||||||
autoScroll = true,
|
const query = useCstSearchStore(state => state.query);
|
||||||
onOpenEdit,
|
const filterMatch = useCstSearchStore(state => state.match);
|
||||||
maxHeight
|
const filterSource = useCstSearchStore(state => state.source);
|
||||||
}: TableSideConstituentsProps) {
|
const includeInherited = useCstSearchStore(state => state.includeInherited);
|
||||||
|
|
||||||
|
const graphFiltered = activeCst ? applyGraphQuery(schema, activeCst.id, filterSource) : schema.items;
|
||||||
|
const queryFiltered = query ? graphFiltered.filter(cst => matchConstituenta(cst, query, filterMatch)) : graphFiltered;
|
||||||
|
const items = !includeInherited ? queryFiltered.filter(cst => !cst.is_inherited) : queryFiltered;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!activeCst) {
|
if (!activeCst) {
|
||||||
return;
|
return;
|
||||||
|
@ -116,7 +121,38 @@ export function TableSideConstituents({
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Измените параметры фильтра</p>
|
||||||
</NoData>
|
</NoData>
|
||||||
}
|
}
|
||||||
onRowClicked={cst => onOpenEdit(cst.id)}
|
onRowClicked={cst => navigateCst(cst.id)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== Internals =========
|
||||||
|
/**
|
||||||
|
* Filter list of {@link ILibraryItem} to a given graph query.
|
||||||
|
*/
|
||||||
|
function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): IConstituenta[] {
|
||||||
|
if (mode === DependencyMode.ALL) {
|
||||||
|
return target.items;
|
||||||
|
}
|
||||||
|
const ids = (() => {
|
||||||
|
switch (mode) {
|
||||||
|
case DependencyMode.OUTPUTS: {
|
||||||
|
return target.graph.nodes.get(pivot)?.outputs;
|
||||||
|
}
|
||||||
|
case DependencyMode.INPUTS: {
|
||||||
|
return target.graph.nodes.get(pivot)?.inputs;
|
||||||
|
}
|
||||||
|
case DependencyMode.EXPAND_OUTPUTS: {
|
||||||
|
return target.graph.expandAllOutputs([pivot]);
|
||||||
|
}
|
||||||
|
case DependencyMode.EXPAND_INPUTS: {
|
||||||
|
return target.graph.expandAllInputs([pivot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
if (ids) {
|
||||||
|
return target.items.filter(cst => ids.find(id => id === cst.id));
|
||||||
|
} else {
|
||||||
|
return target.items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { useRoleStore, UserRole } from '@/features/users';
|
import { useRoleStore, UserRole } from '@/features/users';
|
||||||
|
@ -9,9 +8,6 @@ import { useWindowSize } from '@/hooks/useWindowSize';
|
||||||
import { useFitHeight } from '@/stores/appLayout';
|
import { useFitHeight } from '@/stores/appLayout';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
import { type IConstituenta } from '../../../models/rsform';
|
|
||||||
import { useRSEdit } from '../RSEditContext';
|
|
||||||
|
|
||||||
import { ConstituentsSearch } from './ConstituentsSearch';
|
import { ConstituentsSearch } from './ConstituentsSearch';
|
||||||
import { TableSideConstituents } from './TableSideConstituents';
|
import { TableSideConstituents } from './TableSideConstituents';
|
||||||
|
|
||||||
|
@ -27,9 +23,6 @@ export function ViewConstituents({ isBottom, isMounted }: ViewConstituentsProps)
|
||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const listHeight = useFitHeight(!isBottom ? '8.2rem' : role !== UserRole.READER ? '42rem' : '35rem', '10rem');
|
const listHeight = useFitHeight(!isBottom ? '8.2rem' : role !== UserRole.READER ? '42rem' : '35rem', '10rem');
|
||||||
const { schema, activeCst, navigateCst } = useRSEdit();
|
|
||||||
|
|
||||||
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema.items);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
|
@ -49,19 +42,8 @@ export function ViewConstituents({ isBottom, isMounted }: ViewConstituentsProps)
|
||||||
maxWidth: isMounted ? '100%' : '0'
|
maxWidth: isMounted ? '100%' : '0'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ConstituentsSearch
|
<ConstituentsSearch dense={!!windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD} />
|
||||||
dense={!!windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD}
|
<TableSideConstituents maxHeight={listHeight} autoScroll={!isBottom} />
|
||||||
schema={schema}
|
|
||||||
activeID={activeCst?.id}
|
|
||||||
onChange={setFilteredData}
|
|
||||||
/>
|
|
||||||
<TableSideConstituents
|
|
||||||
maxHeight={listHeight}
|
|
||||||
items={filteredData}
|
|
||||||
activeCst={activeCst}
|
|
||||||
onOpenEdit={navigateCst}
|
|
||||||
autoScroll={!isBottom}
|
|
||||||
/>
|
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user