mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-08-14 21:00:37 +03:00
Improve graph UI
This commit is contained in:
parent
2f98ae90ff
commit
64ebce3082
28
rsconcept/frontend/package-lock.json
generated
28
rsconcept/frontend/package-lock.json
generated
|
@ -28,7 +28,7 @@
|
||||||
"react-tabs": "^6.0.2",
|
"react-tabs": "^6.0.2",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
"react-tooltip": "^5.26.3",
|
"react-tooltip": "^5.26.3",
|
||||||
"reagraph": "^4.15.26"
|
"reagraph": "^4.15.27"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lezer/generator": "^1.7.0",
|
"@lezer/generator": "^1.7.0",
|
||||||
|
@ -8301,25 +8301,13 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path2d": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path2d/-/path2d-0.1.1.tgz",
|
|
||||||
"integrity": "sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA==",
|
|
||||||
"optional": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path2d-polyfill": {
|
"node_modules/path2d-polyfill": {
|
||||||
"version": "2.1.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz",
|
||||||
"integrity": "sha512-4Rka5lN+rY/p0CdD8+E+BFv51lFaFvJOrlOhyQ+zjzyQrzyh3ozmxd1vVGGDdIbUFSBtIZLSnspxTgPT0iJhvA==",
|
"integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
|
||||||
"path2d": "0.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pdfjs-dist": {
|
"node_modules/pdfjs-dist": {
|
||||||
|
@ -9045,9 +9033,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/reagraph": {
|
"node_modules/reagraph": {
|
||||||
"version": "4.15.26",
|
"version": "4.15.27",
|
||||||
"resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.15.26.tgz",
|
"resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.15.27.tgz",
|
||||||
"integrity": "sha512-s8xYL9frjoQA1BmPS9tOshR8My9qDSRAiU79YfYO+grleBvhsbXMh7Evlj1ACYh8OR6fLNCdsuK1Micz6fZ7zQ==",
|
"integrity": "sha512-BoYWSFdbxeLkEL4lAM9Y/ey0L+liY1is/3+dxZ4pvhlVj4f9RIWZh1IqILY+7t2mRYts5RInsgz0ZAV4t4tIJw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-spring/three": "9.6.1",
|
"@react-spring/three": "9.6.1",
|
||||||
"@react-three/fiber": "8.13.5",
|
"@react-three/fiber": "8.13.5",
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
"react-tabs": "^6.0.2",
|
"react-tabs": "^6.0.2",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
"react-tooltip": "^5.26.3",
|
"react-tooltip": "^5.26.3",
|
||||||
"reagraph": "^4.15.26"
|
"reagraph": "^4.15.27"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lezer/generator": "^1.7.0",
|
"@lezer/generator": "^1.7.0",
|
||||||
|
|
|
@ -27,9 +27,9 @@ export { BiFontFamily as IconText } from 'react-icons/bi';
|
||||||
export { BiFont as IconTextOff } from 'react-icons/bi';
|
export { BiFont as IconTextOff } from 'react-icons/bi';
|
||||||
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
||||||
|
|
||||||
export { LuMinimize as IconGraphClosure } from 'react-icons/lu';
|
export { BiCollapse as IconGraphCollapse } from 'react-icons/bi';
|
||||||
|
export { BiExpand as IconGraphExpand } from 'react-icons/bi';
|
||||||
export { LuMaximize as IconGraphMaximize } from 'react-icons/lu';
|
export { LuMaximize as IconGraphMaximize } from 'react-icons/lu';
|
||||||
export { LuExpand as IconGraphExpand } from 'react-icons/lu';
|
|
||||||
export { BiGitBranch as IconGraphInputs } from 'react-icons/bi';
|
export { BiGitBranch as IconGraphInputs } from 'react-icons/bi';
|
||||||
export { BiGitMerge as IconGraphOutputs } from 'react-icons/bi';
|
export { BiGitMerge as IconGraphOutputs } from 'react-icons/bi';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
import { useLayoutEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
|
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
|
||||||
import { useConceptOptions } from '@/context/OptionsContext';
|
import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
|
@ -9,8 +9,8 @@ import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
||||||
import { describeConstituenta } from '@/utils/labels';
|
import { describeConstituenta } from '@/utils/labels';
|
||||||
|
|
||||||
import ConstituentaBadge from '../info/ConstituentaBadge';
|
import ConstituentaBadge from '../info/ConstituentaBadge';
|
||||||
import Button from '../ui/Button';
|
|
||||||
import FlexColumn from '../ui/FlexColumn';
|
import FlexColumn from '../ui/FlexColumn';
|
||||||
|
import SelectGraphToolbar from './SelectGraphToolbar';
|
||||||
|
|
||||||
interface ConstituentaMultiPickerProps {
|
interface ConstituentaMultiPickerProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
@ -19,7 +19,7 @@ interface ConstituentaMultiPickerProps {
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
setSelected: React.Dispatch<ConstituentaID[]>;
|
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<IConstituenta>();
|
const columnHelper = createColumnHelper<IConstituenta>();
|
||||||
|
@ -55,26 +55,6 @@ function ConstituentaMultiPicker({ id, schema, prefixID, rows, selected, setSele
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectBasis = useCallback(() => {
|
|
||||||
if (!schema || selected.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const addition = schema.graph.expandAllInputs(selected).filter(id => !selected.includes(id));
|
|
||||||
if (addition.length > 0) {
|
|
||||||
setSelected([...selected, ...addition]);
|
|
||||||
}
|
|
||||||
}, [schema, selected, setSelected]);
|
|
||||||
|
|
||||||
const selectDependant = useCallback(() => {
|
|
||||||
if (!schema || selected.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const addition = schema.graph.expandAllOutputs(selected).filter(id => !selected.includes(id));
|
|
||||||
if (addition.length > 0) {
|
|
||||||
setSelected([...selected, ...addition]);
|
|
||||||
}
|
|
||||||
}, [schema, selected, setSelected]);
|
|
||||||
|
|
||||||
const columns = useMemo(
|
const columns = useMemo(
|
||||||
() => [
|
() => [
|
||||||
columnHelper.accessor('alias', {
|
columnHelper.accessor('alias', {
|
||||||
|
@ -98,20 +78,13 @@ function ConstituentaMultiPicker({ id, schema, prefixID, rows, selected, setSele
|
||||||
<span className='w-[24ch] select-none whitespace-nowrap'>
|
<span className='w-[24ch] select-none whitespace-nowrap'>
|
||||||
Выбраны {selected.length} из {schema?.items.length ?? 0}
|
Выбраны {selected.length} из {schema?.items.length ?? 0}
|
||||||
</span>
|
</span>
|
||||||
<div className='flex w-full gap-6 text-sm'>
|
{schema ? (
|
||||||
<Button
|
<SelectGraphToolbar
|
||||||
text='Влияющие'
|
graph={schema.graph} // prettier: split lines
|
||||||
title='Добавить все конституенты, от которых зависят выбранные'
|
setSelected={setSelected}
|
||||||
className='w-[7rem] text-sm'
|
className='w-full ml-8'
|
||||||
onClick={selectBasis}
|
|
||||||
/>
|
/>
|
||||||
<Button
|
) : null}
|
||||||
text='Зависимые'
|
|
||||||
title='Добавить все конституенты, которые зависят от выбранных'
|
|
||||||
className='w-[7rem] text-sm'
|
|
||||||
onClick={selectDependant}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<DataTable
|
<DataTable
|
||||||
id={id}
|
id={id}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
|
import { Graph } from '@/models/Graph';
|
||||||
|
|
||||||
|
import {
|
||||||
|
IconGraphCollapse,
|
||||||
|
IconGraphExpand,
|
||||||
|
IconGraphInputs,
|
||||||
|
IconGraphMaximize,
|
||||||
|
IconGraphOutputs,
|
||||||
|
IconReset
|
||||||
|
} from '../Icons';
|
||||||
|
import { CProps } from '../props';
|
||||||
|
import MiniButton from '../ui/MiniButton';
|
||||||
|
|
||||||
|
interface SelectGraphToolbarProps extends CProps.Styling {
|
||||||
|
graph: Graph;
|
||||||
|
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectGraphToolbar({ className, graph, setSelected, ...restProps }: SelectGraphToolbarProps) {
|
||||||
|
return (
|
||||||
|
<div className={clsx('cc-icons', className)} {...restProps}>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='Сбросить выделение'
|
||||||
|
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected([])}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='Выделить все влияющие'
|
||||||
|
icon={<IconGraphCollapse size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected(prev => [...prev, ...graph.expandAllInputs(prev)])}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='Выделить все зависимые'
|
||||||
|
icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected(prev => [...prev, ...graph.expandAllOutputs(prev)])}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='<b>Максимизация</b> - дополнение выделения конституентами, зависимыми только от выделенных'
|
||||||
|
icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected(prev => graph.maximizePart(prev))}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='Выделить поставщиков'
|
||||||
|
icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected(prev => [...prev, ...graph.expandInputs(prev)])}
|
||||||
|
/>
|
||||||
|
<MiniButton
|
||||||
|
titleHtml='Выделить потребителей'
|
||||||
|
icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
|
||||||
|
onClick={() => setSelected(prev => [...prev, ...graph.expandOutputs(prev)])}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectGraphToolbar;
|
|
@ -11,7 +11,7 @@ interface ConstituentsTabProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
error?: ErrorData;
|
error?: ErrorData;
|
||||||
selected: ConstituentaID[];
|
selected: ConstituentaID[];
|
||||||
setSelected: React.Dispatch<ConstituentaID[]>;
|
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConstituentsTab({ schema, error, loading, selected, setSelected }: ConstituentsTabProps) {
|
function ConstituentsTab({ schema, error, loading, selected, setSelected }: ConstituentsTabProps) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ function EditorRSList({ onOpenEdit }: EditorRSListProps) {
|
||||||
newSelection.push(cst.id);
|
newSelection.push(cst.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
controller.setSelection(newSelection);
|
controller.setSelected(newSelection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,13 @@ import {
|
||||||
IconDestroy,
|
IconDestroy,
|
||||||
IconFilter,
|
IconFilter,
|
||||||
IconFitImage,
|
IconFitImage,
|
||||||
IconGraphClosure,
|
|
||||||
IconGraphExpand,
|
|
||||||
IconGraphInputs,
|
|
||||||
IconGraphMaximize,
|
|
||||||
IconGraphOutputs,
|
|
||||||
IconNewItem,
|
IconNewItem,
|
||||||
IconReset,
|
|
||||||
IconRotate3D,
|
IconRotate3D,
|
||||||
IconText,
|
IconText,
|
||||||
IconTextOff
|
IconTextOff
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import BadgeHelp from '@/components/man/BadgeHelp';
|
import BadgeHelp from '@/components/man/BadgeHelp';
|
||||||
|
import SelectGraphToolbar from '@/components/select/SelectGraphToolbar';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
@ -101,43 +96,7 @@ function GraphToolbar({
|
||||||
) : null}
|
) : null}
|
||||||
<BadgeHelp topic={HelpTopic.GRAPH_TERM} className='max-w-[calc(100vw-4rem)]' offset={4} />
|
<BadgeHelp topic={HelpTopic.GRAPH_TERM} className='max-w-[calc(100vw-4rem)]' offset={4} />
|
||||||
</div>
|
</div>
|
||||||
<div className='cc-icons'>
|
<SelectGraphToolbar graph={controller.schema!.graph} setSelected={controller.setSelected} />
|
||||||
<MiniButton
|
|
||||||
titleHtml='<b>[ESC]</b><br/>Сбросить выделение'
|
|
||||||
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
|
||||||
onClick={controller.deselectAll}
|
|
||||||
/>
|
|
||||||
<MiniButton
|
|
||||||
titleHtml='<b>Замыкание</b> - дополнение выделения влияющими конституентами'
|
|
||||||
icon={<IconGraphClosure size='1.25rem' className='icon-primary' />}
|
|
||||||
disabled={controller.nothingSelected}
|
|
||||||
onClick={controller.selectAllInputs}
|
|
||||||
/>
|
|
||||||
<MiniButton
|
|
||||||
titleHtml='<b>Максимизация</b> - дополнение выделения конституентами, зависимыми только от выделенных'
|
|
||||||
icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
|
|
||||||
disabled={controller.nothingSelected}
|
|
||||||
onClick={controller.selectMax}
|
|
||||||
/>
|
|
||||||
<MiniButton
|
|
||||||
titleHtml='Выделить все зависимые'
|
|
||||||
icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
|
|
||||||
disabled={controller.nothingSelected}
|
|
||||||
onClick={controller.selectAllOutputs}
|
|
||||||
/>
|
|
||||||
<MiniButton
|
|
||||||
titleHtml='Выделить поставщиков'
|
|
||||||
icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
|
|
||||||
disabled={controller.nothingSelected}
|
|
||||||
onClick={controller.selectInputs}
|
|
||||||
/>
|
|
||||||
<MiniButton
|
|
||||||
titleHtml='Выделить потребителей'
|
|
||||||
icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
|
|
||||||
disabled={controller.nothingSelected}
|
|
||||||
onClick={controller.selectOutputs}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Overlay>
|
</Overlay>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ interface IRSEditContext {
|
||||||
canProduceStructure: boolean;
|
canProduceStructure: boolean;
|
||||||
nothingSelected: boolean;
|
nothingSelected: boolean;
|
||||||
|
|
||||||
setSelection: (selected: ConstituentaID[]) => void;
|
setSelected: React.Dispatch<React.SetStateAction<ConstituentaID[]>>;
|
||||||
select: (target: ConstituentaID) => void;
|
select: (target: ConstituentaID) => void;
|
||||||
selectAllInputs: () => void;
|
selectAllInputs: () => void;
|
||||||
selectAllOutputs: () => void;
|
selectAllOutputs: () => void;
|
||||||
|
@ -486,7 +486,7 @@ export const RSEditState = ({
|
||||||
canProduceStructure,
|
canProduceStructure,
|
||||||
nothingSelected,
|
nothingSelected,
|
||||||
|
|
||||||
setSelection: (selected: ConstituentaID[]) => setSelected(selected),
|
setSelected: setSelected,
|
||||||
select: (target: ConstituentaID) => setSelected(prev => [...prev, target]),
|
select: (target: ConstituentaID) => setSelected(prev => [...prev, target]),
|
||||||
deselect: (target: ConstituentaID) => setSelected(prev => prev.filter(id => id !== target)),
|
deselect: (target: ConstituentaID) => setSelected(prev => prev.filter(id => id !== target)),
|
||||||
selectAllInputs: () => setSelected(prev => [...prev, ...(model.schema?.graph.expandAllInputs(prev) ?? [])]),
|
selectAllInputs: () => setSelected(prev => [...prev, ...(model.schema?.graph.expandAllInputs(prev) ?? [])]),
|
||||||
|
|
|
@ -2,7 +2,15 @@
|
||||||
|
|
||||||
import { useCallback, useLayoutEffect, useState } from 'react';
|
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
import { IconFilter, IconSettings } from '@/components/Icons';
|
import {
|
||||||
|
IconFilter,
|
||||||
|
IconGraphCollapse,
|
||||||
|
IconGraphExpand,
|
||||||
|
IconGraphInputs,
|
||||||
|
IconGraphOutputs,
|
||||||
|
IconSettings,
|
||||||
|
IconText
|
||||||
|
} from '@/components/Icons';
|
||||||
import Dropdown from '@/components/ui/Dropdown';
|
import Dropdown from '@/components/ui/Dropdown';
|
||||||
import DropdownButton from '@/components/ui/DropdownButton';
|
import DropdownButton from '@/components/ui/DropdownButton';
|
||||||
import SearchBar from '@/components/ui/SearchBar';
|
import SearchBar from '@/components/ui/SearchBar';
|
||||||
|
@ -24,6 +32,23 @@ interface ConstituentsSearchProps {
|
||||||
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
|
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DependencyIcon(mode: DependencyMode, size: string) {
|
||||||
|
switch (mode) {
|
||||||
|
case DependencyMode.ALL:
|
||||||
|
return <IconSettings size={size} />;
|
||||||
|
case DependencyMode.EXPRESSION:
|
||||||
|
return <IconText size={size} />;
|
||||||
|
case DependencyMode.OUTPUTS:
|
||||||
|
return <IconGraphOutputs size={size} />;
|
||||||
|
case DependencyMode.INPUTS:
|
||||||
|
return <IconGraphInputs size={size} />;
|
||||||
|
case DependencyMode.EXPAND_OUTPUTS:
|
||||||
|
return <IconGraphExpand size={size} />;
|
||||||
|
case DependencyMode.EXPAND_INPUTS:
|
||||||
|
return <IconGraphCollapse size={size} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }: ConstituentsSearchProps) {
|
function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }: ConstituentsSearchProps) {
|
||||||
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL);
|
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL);
|
||||||
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL);
|
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL);
|
||||||
|
@ -121,7 +146,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }:
|
||||||
title='Настройка фильтрации по графу термов'
|
title='Настройка фильтрации по графу термов'
|
||||||
hideTitle={sourceMenu.isOpen}
|
hideTitle={sourceMenu.isOpen}
|
||||||
className='h-full pr-2'
|
className='h-full pr-2'
|
||||||
icon={<IconSettings size='1.25rem' />}
|
icon={DependencyIcon(filterSource, '1.25rem')}
|
||||||
text={labelCstSource(filterSource)}
|
text={labelCstSource(filterSource)}
|
||||||
onClick={sourceMenu.toggle}
|
onClick={sourceMenu.toggle}
|
||||||
/>
|
/>
|
||||||
|
@ -132,13 +157,14 @@ function ConstituentsSearch({ schema, activeID, activeExpression, setFiltered }:
|
||||||
const source = value as DependencyMode;
|
const source = value as DependencyMode;
|
||||||
return (
|
return (
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
className='w-[23rem]'
|
className='w-[18rem]'
|
||||||
key={`${prefixes.cst_source_list}${index}`}
|
key={`${prefixes.cst_source_list}${index}`}
|
||||||
onClick={() => handleSourceChange(source)}
|
onClick={() => handleSourceChange(source)}
|
||||||
>
|
>
|
||||||
<p>
|
<div className='inline-flex items-center gap-1'>
|
||||||
|
{DependencyIcon(source, '1.25rem')}
|
||||||
<b>{labelCstSource(source)}:</b> {describeCstSource(source)}
|
<b>{labelCstSource(source)}:</b> {describeCstSource(source)}
|
||||||
</p>
|
</div>
|
||||||
</DropdownButton>
|
</DropdownButton>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -243,11 +243,11 @@ export function describeCstSource(mode: DependencyMode): string {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DependencyMode.ALL: return 'все конституенты';
|
case DependencyMode.ALL: return 'все конституенты';
|
||||||
case DependencyMode.EXPRESSION: return 'идентификаторы из выражения';
|
case DependencyMode.EXPRESSION: return 'имена из выражения';
|
||||||
case DependencyMode.OUTPUTS: return 'прямые ссылки на текущую';
|
case DependencyMode.OUTPUTS: return 'прямые исходящие';
|
||||||
case DependencyMode.INPUTS: return 'прямые ссылки из текущей';
|
case DependencyMode.INPUTS: return 'прямые входящие';
|
||||||
case DependencyMode.EXPAND_OUTPUTS: return 'опосредованные ссылки на текущую';
|
case DependencyMode.EXPAND_OUTPUTS: return 'цепочка исходящих';
|
||||||
case DependencyMode.EXPAND_INPUTS: return 'опосредованные ссылки из текущей';
|
case DependencyMode.EXPAND_INPUTS: return 'цепочка входящих';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user