2024-04-04 20:03:41 +03:00
|
|
|
import clsx from 'clsx';
|
2024-08-21 20:21:23 +03:00
|
|
|
import { useCallback } from 'react';
|
2024-04-04 20:03:41 +03:00
|
|
|
|
|
|
|
import { Graph } from '@/models/Graph';
|
|
|
|
|
|
|
|
import {
|
|
|
|
IconGraphCollapse,
|
2024-04-06 23:09:25 +03:00
|
|
|
IconGraphCore,
|
2024-04-04 20:03:41 +03:00
|
|
|
IconGraphExpand,
|
|
|
|
IconGraphInputs,
|
2024-08-21 20:21:23 +03:00
|
|
|
IconGraphInverse,
|
2024-04-04 20:03:41 +03:00
|
|
|
IconGraphMaximize,
|
|
|
|
IconGraphOutputs,
|
2024-08-21 20:21:23 +03:00
|
|
|
IconPredecessor,
|
2024-04-04 20:03:41 +03:00
|
|
|
IconReset
|
|
|
|
} from '../Icons';
|
|
|
|
import { CProps } from '../props';
|
|
|
|
import MiniButton from '../ui/MiniButton';
|
|
|
|
|
2024-06-26 19:47:31 +03:00
|
|
|
interface ToolbarGraphSelectionProps extends CProps.Styling {
|
2024-04-04 20:03:41 +03:00
|
|
|
graph: Graph;
|
2024-12-02 15:59:03 +03:00
|
|
|
selected: number[];
|
2024-08-21 20:21:23 +03:00
|
|
|
isCore: (item: number) => boolean;
|
2024-12-02 15:59:03 +03:00
|
|
|
isOwned?: (item: number) => boolean;
|
|
|
|
setSelected: (newSelection: number[]) => void;
|
2024-05-23 13:36:16 +03:00
|
|
|
emptySelection?: boolean;
|
2024-04-04 20:03:41 +03:00
|
|
|
}
|
|
|
|
|
2024-06-26 19:47:31 +03:00
|
|
|
function ToolbarGraphSelection({
|
2024-05-23 13:36:16 +03:00
|
|
|
className,
|
|
|
|
graph,
|
2024-12-02 15:59:03 +03:00
|
|
|
selected,
|
2024-08-21 20:21:23 +03:00
|
|
|
isCore,
|
|
|
|
isOwned,
|
2024-05-23 13:36:16 +03:00
|
|
|
setSelected,
|
|
|
|
emptySelection,
|
|
|
|
...restProps
|
2024-06-26 19:47:31 +03:00
|
|
|
}: ToolbarGraphSelectionProps) {
|
2024-08-21 20:21:23 +03:00
|
|
|
const handleSelectCore = useCallback(() => {
|
|
|
|
const core = [...graph.nodes.keys()].filter(isCore);
|
|
|
|
setSelected([...core, ...graph.expandInputs(core)]);
|
|
|
|
}, [setSelected, graph, isCore]);
|
|
|
|
|
|
|
|
const handleSelectOwned = useCallback(
|
2024-12-02 15:59:03 +03:00
|
|
|
() => (isOwned ? setSelected([...graph.nodes.keys()].filter(isOwned)) : undefined),
|
2024-08-21 20:21:23 +03:00
|
|
|
[setSelected, graph, isOwned]
|
|
|
|
);
|
|
|
|
|
|
|
|
const handleInvertSelection = useCallback(
|
2024-12-02 15:59:03 +03:00
|
|
|
() => setSelected([...graph.nodes.keys()].filter(item => !selected.includes(item))),
|
|
|
|
[setSelected, selected, graph]
|
2024-08-21 20:21:23 +03:00
|
|
|
);
|
|
|
|
|
2024-04-04 20:03:41 +03:00
|
|
|
return (
|
|
|
|
<div className={clsx('cc-icons', className)} {...restProps}>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Сбросить выделение'
|
|
|
|
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
|
|
|
onClick={() => setSelected([])}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить все влияющие'
|
|
|
|
icon={<IconGraphCollapse size='1.25rem' className='icon-primary' />}
|
2024-12-02 15:59:03 +03:00
|
|
|
onClick={() => setSelected([...selected, ...graph.expandAllInputs(selected)])}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить все зависимые'
|
|
|
|
icon={<IconGraphExpand size='1.25rem' className='icon-primary' />}
|
2024-12-02 15:59:03 +03:00
|
|
|
onClick={() => setSelected([...selected, ...graph.expandAllOutputs(selected)])}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
2024-06-18 15:19:19 +03:00
|
|
|
titleHtml='<b>Максимизация</b> <br/>дополнение выделения конституентами, <br/>зависимыми только от выделенных'
|
2024-04-04 20:03:41 +03:00
|
|
|
icon={<IconGraphMaximize size='1.25rem' className='icon-primary' />}
|
2024-12-02 15:59:03 +03:00
|
|
|
onClick={() => setSelected(graph.maximizePart(selected))}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить поставщиков'
|
|
|
|
icon={<IconGraphInputs size='1.25rem' className='icon-primary' />}
|
2024-12-02 15:59:03 +03:00
|
|
|
onClick={() => setSelected([...selected, ...graph.expandInputs(selected)])}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить потребителей'
|
|
|
|
icon={<IconGraphOutputs size='1.25rem' className='icon-primary' />}
|
2024-12-02 15:59:03 +03:00
|
|
|
onClick={() => setSelected([...selected, ...graph.expandOutputs(selected)])}
|
2024-05-23 13:36:16 +03:00
|
|
|
disabled={emptySelection}
|
2024-04-04 20:03:41 +03:00
|
|
|
/>
|
2024-08-21 20:21:23 +03:00
|
|
|
<MiniButton
|
|
|
|
titleHtml='Инвертировать'
|
|
|
|
icon={<IconGraphInverse size='1.25rem' className='icon-primary' />}
|
|
|
|
onClick={handleInvertSelection}
|
|
|
|
/>
|
2024-04-06 23:09:25 +03:00
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить ядро'
|
|
|
|
icon={<IconGraphCore size='1.25rem' className='icon-primary' />}
|
2024-08-21 20:21:23 +03:00
|
|
|
onClick={handleSelectCore}
|
|
|
|
/>
|
2024-12-02 15:59:03 +03:00
|
|
|
{isOwned ? (
|
|
|
|
<MiniButton
|
|
|
|
titleHtml='Выделить собственные'
|
|
|
|
icon={<IconPredecessor size='1.25rem' className='icon-primary' />}
|
|
|
|
onClick={handleSelectOwned}
|
|
|
|
/>
|
|
|
|
) : null}
|
2024-04-04 20:03:41 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-06-26 19:47:31 +03:00
|
|
|
export default ToolbarGraphSelection;
|