2024-07-31 18:09:31 +03:00
|
|
|
'use client';
|
|
|
|
|
2024-07-21 15:19:57 +03:00
|
|
|
import clsx from 'clsx';
|
2024-07-31 18:09:31 +03:00
|
|
|
import { useMemo } from 'react';
|
2024-07-21 15:19:57 +03:00
|
|
|
|
2024-07-26 21:09:16 +03:00
|
|
|
import {
|
|
|
|
IconAnimation,
|
|
|
|
IconAnimationOff,
|
|
|
|
IconDestroy,
|
2024-07-29 23:15:03 +03:00
|
|
|
IconEdit2,
|
|
|
|
IconExecute,
|
2024-07-26 21:09:16 +03:00
|
|
|
IconFitImage,
|
|
|
|
IconGrid,
|
|
|
|
IconImage,
|
|
|
|
IconLineStraight,
|
|
|
|
IconLineWave,
|
|
|
|
IconNewItem,
|
|
|
|
IconReset,
|
|
|
|
IconSave
|
|
|
|
} from '@/components/Icons';
|
2024-07-21 15:19:57 +03:00
|
|
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
|
|
|
import MiniButton from '@/components/ui/MiniButton';
|
|
|
|
import { HelpTopic } from '@/models/miscellaneous';
|
2024-07-31 18:09:31 +03:00
|
|
|
import { OperationType } from '@/models/oss';
|
2024-07-21 15:19:57 +03:00
|
|
|
import { PARAMETER } from '@/utils/constants';
|
2024-07-23 23:04:21 +03:00
|
|
|
import { prepareTooltip } from '@/utils/labels';
|
2024-07-21 15:19:57 +03:00
|
|
|
|
|
|
|
import { useOssEdit } from '../OssEditContext';
|
|
|
|
|
|
|
|
interface ToolbarOssGraphProps {
|
2024-07-23 23:04:21 +03:00
|
|
|
isModified: boolean;
|
2024-07-24 18:11:39 +03:00
|
|
|
showGrid: boolean;
|
2024-07-26 21:09:16 +03:00
|
|
|
edgeAnimate: boolean;
|
|
|
|
edgeStraight: boolean;
|
2024-07-21 15:19:57 +03:00
|
|
|
onCreate: () => void;
|
2024-07-23 23:04:21 +03:00
|
|
|
onDelete: () => void;
|
2024-07-29 23:15:03 +03:00
|
|
|
onEdit: () => void;
|
|
|
|
onExecute: () => void;
|
2024-07-23 23:04:21 +03:00
|
|
|
onFitView: () => void;
|
2024-07-24 18:11:39 +03:00
|
|
|
onSaveImage: () => void;
|
2024-07-23 23:04:21 +03:00
|
|
|
onSavePositions: () => void;
|
|
|
|
onResetPositions: () => void;
|
2024-07-24 18:11:39 +03:00
|
|
|
toggleShowGrid: () => void;
|
2024-07-26 21:09:16 +03:00
|
|
|
toggleEdgeAnimate: () => void;
|
|
|
|
toggleEdgeStraight: () => void;
|
2024-07-21 15:19:57 +03:00
|
|
|
}
|
|
|
|
|
2024-07-23 23:04:21 +03:00
|
|
|
function ToolbarOssGraph({
|
|
|
|
isModified,
|
2024-07-24 18:11:39 +03:00
|
|
|
showGrid,
|
2024-07-26 21:09:16 +03:00
|
|
|
edgeAnimate,
|
|
|
|
edgeStraight,
|
2024-07-23 23:04:21 +03:00
|
|
|
onCreate,
|
|
|
|
onDelete,
|
2024-07-29 23:15:03 +03:00
|
|
|
onEdit,
|
|
|
|
onExecute,
|
2024-07-23 23:04:21 +03:00
|
|
|
onFitView,
|
2024-07-24 18:11:39 +03:00
|
|
|
onSaveImage,
|
2024-07-23 23:04:21 +03:00
|
|
|
onSavePositions,
|
2024-07-24 18:11:39 +03:00
|
|
|
onResetPositions,
|
2024-07-26 21:09:16 +03:00
|
|
|
toggleShowGrid,
|
|
|
|
toggleEdgeAnimate,
|
|
|
|
toggleEdgeStraight
|
2024-07-23 23:04:21 +03:00
|
|
|
}: ToolbarOssGraphProps) {
|
2024-07-21 15:19:57 +03:00
|
|
|
const controller = useOssEdit();
|
2024-07-31 18:09:31 +03:00
|
|
|
const selectedOperation = useMemo(
|
|
|
|
() => controller.schema?.operationByID.get(controller.selected[0]),
|
|
|
|
[controller.selected, controller.schema]
|
|
|
|
);
|
|
|
|
const readyForSynthesis = useMemo(() => {
|
|
|
|
if (!selectedOperation || selectedOperation.operation_type !== OperationType.SYNTHESIS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!controller.schema || selectedOperation.result) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const argumentIDs = controller.schema.graph.expandInputs([selectedOperation.id]);
|
2024-09-16 19:38:51 +03:00
|
|
|
if (!argumentIDs || argumentIDs.length < 1) {
|
2024-07-31 18:09:31 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const argumentOperations = argumentIDs.map(id => controller.schema!.operationByID.get(id)!);
|
|
|
|
if (argumentOperations.some(item => item.result === null)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}, [selectedOperation, controller.schema]);
|
2024-07-21 15:19:57 +03:00
|
|
|
|
|
|
|
return (
|
2024-07-26 21:09:16 +03:00
|
|
|
<div className='flex flex-col items-center'>
|
|
|
|
<div className='cc-icons'>
|
2024-07-29 23:15:03 +03:00
|
|
|
<MiniButton
|
|
|
|
title='Сбросить изменения'
|
|
|
|
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
|
|
|
disabled={!isModified}
|
|
|
|
onClick={onResetPositions}
|
|
|
|
/>
|
2024-07-23 23:04:21 +03:00
|
|
|
<MiniButton
|
2024-07-26 21:09:16 +03:00
|
|
|
icon={<IconFitImage size='1.25rem' className='icon-primary' />}
|
|
|
|
title='Сбросить вид'
|
|
|
|
onClick={onFitView}
|
2024-07-23 23:04:21 +03:00
|
|
|
/>
|
|
|
|
<MiniButton
|
2024-07-26 21:09:16 +03:00
|
|
|
title={showGrid ? 'Скрыть сетку' : 'Отобразить сетку'}
|
|
|
|
icon={
|
|
|
|
showGrid ? (
|
|
|
|
<IconGrid size='1.25rem' className='icon-green' />
|
|
|
|
) : (
|
|
|
|
<IconGrid size='1.25rem' className='icon-primary' />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
onClick={toggleShowGrid}
|
2024-07-23 23:04:21 +03:00
|
|
|
/>
|
2024-07-21 15:19:57 +03:00
|
|
|
<MiniButton
|
2024-07-26 21:09:16 +03:00
|
|
|
title={edgeStraight ? 'Связи: прямые' : 'Связи: безье'}
|
|
|
|
icon={
|
|
|
|
edgeStraight ? (
|
|
|
|
<IconLineStraight size='1.25rem' className='icon-primary' />
|
|
|
|
) : (
|
|
|
|
<IconLineWave size='1.25rem' className='icon-primary' />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
onClick={toggleEdgeStraight}
|
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
title={edgeAnimate ? 'Анимация: вкл' : 'Анимация: выкл'}
|
|
|
|
icon={
|
|
|
|
edgeAnimate ? (
|
|
|
|
<IconAnimation size='1.25rem' className='icon-primary' />
|
|
|
|
) : (
|
|
|
|
<IconAnimationOff size='1.25rem' className='icon-primary' />
|
|
|
|
)
|
|
|
|
}
|
|
|
|
onClick={toggleEdgeAnimate}
|
2024-07-21 15:19:57 +03:00
|
|
|
/>
|
2024-07-23 23:04:21 +03:00
|
|
|
<MiniButton
|
2024-07-26 21:09:16 +03:00
|
|
|
icon={<IconImage size='1.25rem' className='icon-primary' />}
|
|
|
|
title='Сохранить изображение'
|
|
|
|
onClick={onSaveImage}
|
2024-07-23 23:04:21 +03:00
|
|
|
/>
|
2024-07-26 21:09:16 +03:00
|
|
|
<BadgeHelp
|
|
|
|
topic={HelpTopic.UI_OSS_GRAPH}
|
|
|
|
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
|
|
|
|
offset={4}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
{controller.isMutable ? (
|
|
|
|
<div className='cc-icons'>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
|
|
|
|
icon={<IconSave size='1.25rem' className='icon-primary' />}
|
|
|
|
disabled={controller.isProcessing || !isModified}
|
|
|
|
onClick={onSavePositions}
|
|
|
|
/>
|
|
|
|
<MiniButton
|
2024-07-30 16:00:09 +03:00
|
|
|
titleHtml={prepareTooltip('Новая операция', 'Ctrl + Q')}
|
2024-07-26 21:09:16 +03:00
|
|
|
icon={<IconNewItem size='1.25rem' className='icon-green' />}
|
|
|
|
disabled={controller.isProcessing}
|
|
|
|
onClick={onCreate}
|
|
|
|
/>
|
|
|
|
<MiniButton
|
2024-08-27 11:34:36 +03:00
|
|
|
title='Активировать операцию'
|
2024-07-31 18:09:31 +03:00
|
|
|
icon={<IconExecute size='1.25rem' className='icon-green' />}
|
|
|
|
disabled={controller.isProcessing || controller.selected.length !== 1 || !readyForSynthesis}
|
2024-07-29 23:15:03 +03:00
|
|
|
onClick={onExecute}
|
|
|
|
/>
|
|
|
|
<MiniButton
|
2024-08-01 20:11:32 +03:00
|
|
|
titleHtml={prepareTooltip('Редактировать выбранную', 'Двойной клик')}
|
2024-07-29 23:15:03 +03:00
|
|
|
icon={<IconEdit2 size='1.25rem' className='icon-primary' />}
|
|
|
|
disabled={controller.selected.length !== 1 || controller.isProcessing}
|
|
|
|
onClick={onEdit}
|
|
|
|
/>
|
|
|
|
<MiniButton
|
|
|
|
titleHtml={prepareTooltip('Удалить выбранную', 'Delete')}
|
2024-07-26 21:09:16 +03:00
|
|
|
icon={<IconDestroy size='1.25rem' className='icon-red' />}
|
2024-08-15 23:23:45 +03:00
|
|
|
disabled={
|
|
|
|
controller.selected.length !== 1 ||
|
|
|
|
controller.isProcessing ||
|
|
|
|
!controller.canDelete(controller.selected[0])
|
|
|
|
}
|
2024-07-26 21:09:16 +03:00
|
|
|
onClick={onDelete}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-07-23 23:04:21 +03:00
|
|
|
) : null}
|
2024-07-21 15:19:57 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2024-07-29 23:15:03 +03:00
|
|
|
//IconExecute
|
2024-07-21 15:19:57 +03:00
|
|
|
export default ToolbarOssGraph;
|