2025-04-21 20:37:11 +03:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
import { FormProvider, useForm, useWatch } from 'react-hook-form';
|
|
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
|
|
|
|
|
import { HelpTopic } from '@/features/help';
|
|
|
|
|
|
|
|
import { ModalForm } from '@/components/modal';
|
|
|
|
import { TabLabel, TabList, TabPanel, Tabs } from '@/components/tabs';
|
|
|
|
import { useDialogsStore } from '@/stores/dialogs';
|
|
|
|
|
2025-04-28 13:59:38 +03:00
|
|
|
import { type ICreateBlockDTO, schemaCreateBlock } from '../../backend/types';
|
2025-04-21 20:37:11 +03:00
|
|
|
import { useCreateBlock } from '../../backend/use-create-block';
|
2025-04-28 13:59:38 +03:00
|
|
|
import { type LayoutManager } from '../../models/oss-layout-api';
|
2025-04-21 20:37:11 +03:00
|
|
|
import { BLOCK_NODE_MIN_HEIGHT, BLOCK_NODE_MIN_WIDTH } from '../../pages/oss-page/editor-oss-graph/graph/block-node';
|
|
|
|
|
|
|
|
import { TabBlockCard } from './tab-block-card';
|
|
|
|
import { TabBlockChildren } from './tab-block-children';
|
|
|
|
|
|
|
|
export interface DlgCreateBlockProps {
|
2025-04-28 13:59:38 +03:00
|
|
|
manager: LayoutManager;
|
2025-04-21 20:37:11 +03:00
|
|
|
initialInputs: number[];
|
|
|
|
defaultX: number;
|
|
|
|
defaultY: number;
|
|
|
|
onCreate?: (newID: number) => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const TabID = {
|
|
|
|
CARD: 0,
|
|
|
|
CHILDREN: 1
|
|
|
|
} as const;
|
|
|
|
export type TabID = (typeof TabID)[keyof typeof TabID];
|
|
|
|
|
|
|
|
export function DlgCreateBlock() {
|
|
|
|
const { createBlock } = useCreateBlock();
|
|
|
|
|
2025-04-28 13:59:38 +03:00
|
|
|
const { manager, initialInputs, onCreate, defaultX, defaultY } = useDialogsStore(
|
2025-04-21 20:37:11 +03:00
|
|
|
state => state.props as DlgCreateBlockProps
|
|
|
|
);
|
|
|
|
|
|
|
|
const methods = useForm<ICreateBlockDTO>({
|
|
|
|
resolver: zodResolver(schemaCreateBlock),
|
|
|
|
defaultValues: {
|
|
|
|
item_data: {
|
|
|
|
title: '',
|
|
|
|
description: '',
|
|
|
|
parent: null
|
|
|
|
},
|
|
|
|
position_x: defaultX,
|
|
|
|
position_y: defaultY,
|
|
|
|
width: BLOCK_NODE_MIN_WIDTH,
|
|
|
|
height: BLOCK_NODE_MIN_HEIGHT,
|
|
|
|
children_blocks: initialInputs.filter(id => id < 0).map(id => -id),
|
|
|
|
children_operations: initialInputs.filter(id => id > 0),
|
2025-04-28 13:59:38 +03:00
|
|
|
layout: manager.layout
|
2025-04-21 20:37:11 +03:00
|
|
|
},
|
|
|
|
mode: 'onChange'
|
|
|
|
});
|
|
|
|
const title = useWatch({ control: methods.control, name: 'item_data.title' });
|
|
|
|
const [activeTab, setActiveTab] = useState<TabID>(TabID.CARD);
|
2025-04-28 13:59:38 +03:00
|
|
|
const isValid = !!title && !manager.oss.blocks.some(block => block.title === title);
|
2025-04-21 20:37:11 +03:00
|
|
|
|
|
|
|
function onSubmit(data: ICreateBlockDTO) {
|
2025-04-28 13:59:38 +03:00
|
|
|
const rectangle = manager.calculateNewBlockPosition(data);
|
2025-04-21 20:37:11 +03:00
|
|
|
data.position_x = rectangle.x;
|
|
|
|
data.position_y = rectangle.y;
|
|
|
|
data.width = rectangle.width;
|
|
|
|
data.height = rectangle.height;
|
2025-04-28 13:59:38 +03:00
|
|
|
void createBlock({ itemID: manager.oss.id, data: data }).then(response => onCreate?.(response.new_block.id));
|
2025-04-21 20:37:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ModalForm
|
|
|
|
header='Создание операции'
|
|
|
|
submitText='Создать'
|
|
|
|
canSubmit={isValid}
|
|
|
|
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
|
2025-04-22 13:59:14 +03:00
|
|
|
className='w-160 px-6 h-110'
|
2025-04-21 20:37:11 +03:00
|
|
|
helpTopic={HelpTopic.CC_OSS}
|
|
|
|
>
|
|
|
|
<Tabs
|
|
|
|
selectedTabClassName='cc-selected'
|
|
|
|
className='grid'
|
|
|
|
selectedIndex={activeTab}
|
|
|
|
onSelect={index => setActiveTab(index as TabID)}
|
|
|
|
>
|
|
|
|
<TabList className='z-pop mx-auto -mb-5 flex border divide-x rounded-none bg-secondary'>
|
|
|
|
<TabLabel title='Основные атрибуты блока' label='Карточка' />
|
|
|
|
<TabLabel title='Выбор вложенных узлов' label='Содержимое' />
|
|
|
|
</TabList>
|
|
|
|
|
|
|
|
<FormProvider {...methods}>
|
|
|
|
<TabPanel>
|
|
|
|
<TabBlockCard />
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
<TabPanel>
|
|
|
|
<TabBlockChildren />
|
|
|
|
</TabPanel>
|
|
|
|
</FormProvider>
|
|
|
|
</Tabs>
|
|
|
|
</ModalForm>
|
|
|
|
);
|
|
|
|
}
|