2023-12-13 14:32:57 +03:00
|
|
|
'use client';
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2024-04-03 21:05:53 +03:00
|
|
|
import { BiDiamond, BiMenu } from 'react-icons/bi';
|
2023-12-16 19:20:26 +03:00
|
|
|
import { FiEdit } from 'react-icons/fi';
|
2024-04-03 21:05:53 +03:00
|
|
|
import { LuAlertTriangle, LuArchive, LuBookCopy, LuNetwork, LuWand2 } from 'react-icons/lu';
|
2024-03-01 18:19:33 +03:00
|
|
|
import { VscLibrary } from 'react-icons/vsc';
|
2023-12-16 19:20:26 +03:00
|
|
|
|
2024-04-01 21:45:10 +03:00
|
|
|
import { urls } from '@/app/urls';
|
2024-04-03 21:05:53 +03:00
|
|
|
import {
|
|
|
|
IconAdmin,
|
|
|
|
IconClone,
|
|
|
|
IconDestroy,
|
|
|
|
IconDownload,
|
|
|
|
IconNewItem,
|
|
|
|
IconOwner,
|
|
|
|
IconReader,
|
|
|
|
IconReplace,
|
|
|
|
IconShare,
|
|
|
|
IconUpload
|
|
|
|
} from '@/components/Icons';
|
2024-01-04 19:38:12 +03:00
|
|
|
import Button from '@/components/ui/Button';
|
|
|
|
import Dropdown from '@/components/ui/Dropdown';
|
|
|
|
import DropdownButton from '@/components/ui/DropdownButton';
|
2023-12-16 19:20:26 +03:00
|
|
|
import { useAccessMode } from '@/context/AccessModeContext';
|
2023-12-13 14:32:57 +03:00
|
|
|
import { useAuth } from '@/context/AuthContext';
|
2023-12-26 14:23:51 +03:00
|
|
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
2023-12-13 14:32:57 +03:00
|
|
|
import { useRSForm } from '@/context/RSFormContext';
|
|
|
|
import useDropdown from '@/hooks/useDropdown';
|
2023-12-26 14:23:51 +03:00
|
|
|
import { UserAccessMode } from '@/models/miscellaneous';
|
2023-12-16 19:20:26 +03:00
|
|
|
import { describeAccessMode, labelAccessMode } from '@/utils/labels';
|
2023-07-20 17:11:03 +03:00
|
|
|
|
2024-02-04 23:45:49 +03:00
|
|
|
import { useRSEdit } from './RSEditContext';
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2024-02-04 23:45:49 +03:00
|
|
|
interface RSTabsMenuProps {
|
2023-12-28 14:04:44 +03:00
|
|
|
onDestroy: () => void;
|
2023-07-28 18:23:37 +03:00
|
|
|
}
|
|
|
|
|
2024-02-04 23:45:49 +03:00
|
|
|
function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
|
|
|
|
const controller = useRSEdit();
|
2023-12-13 14:32:57 +03:00
|
|
|
const router = useConceptNavigation();
|
2023-07-25 20:27:29 +03:00
|
|
|
const { user } = useAuth();
|
2024-03-04 19:58:10 +03:00
|
|
|
const model = useRSForm();
|
2023-12-16 19:20:26 +03:00
|
|
|
|
|
|
|
const { mode, setMode } = useAccessMode();
|
|
|
|
|
2023-07-20 17:11:03 +03:00
|
|
|
const schemaMenu = useDropdown();
|
|
|
|
const editMenu = useDropdown();
|
2023-12-16 19:20:26 +03:00
|
|
|
const accessMenu = useDropdown();
|
2023-07-21 00:09:05 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
function handleClaimOwner() {
|
2023-07-21 18:44:14 +03:00
|
|
|
editMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.claim();
|
2023-08-25 22:51:20 +03:00
|
|
|
}
|
2023-07-21 00:09:05 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
function handleDelete() {
|
2023-07-21 18:44:14 +03:00
|
|
|
schemaMenu.hide();
|
2023-08-11 19:28:12 +03:00
|
|
|
onDestroy();
|
2023-08-25 22:51:20 +03:00
|
|
|
}
|
2023-07-21 18:44:14 +03:00
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
function handleDownload() {
|
2023-07-21 18:44:14 +03:00
|
|
|
schemaMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.download();
|
2023-08-25 22:51:20 +03:00
|
|
|
}
|
2023-07-21 18:44:14 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
function handleUpload() {
|
2023-07-21 18:44:14 +03:00
|
|
|
schemaMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.promptUpload();
|
2023-08-25 22:51:20 +03:00
|
|
|
}
|
2023-07-21 18:44:14 +03:00
|
|
|
|
2023-08-25 22:51:20 +03:00
|
|
|
function handleClone() {
|
2023-07-21 18:44:14 +03:00
|
|
|
schemaMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.promptClone();
|
2023-08-25 22:51:20 +03:00
|
|
|
}
|
2023-07-21 18:44:14 +03:00
|
|
|
|
2023-08-24 11:10:04 +03:00
|
|
|
function handleShare() {
|
2023-07-21 18:44:14 +03:00
|
|
|
schemaMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.share();
|
2023-08-24 11:10:04 +03:00
|
|
|
}
|
|
|
|
|
2023-12-16 19:20:26 +03:00
|
|
|
function handleReindex() {
|
|
|
|
editMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.reindex();
|
2023-12-16 19:20:26 +03:00
|
|
|
}
|
|
|
|
|
2024-03-01 18:19:33 +03:00
|
|
|
function handleSubstituteCst() {
|
|
|
|
editMenu.hide();
|
|
|
|
controller.substitute();
|
|
|
|
}
|
|
|
|
|
2023-12-16 19:20:26 +03:00
|
|
|
function handleTemplates() {
|
|
|
|
editMenu.hide();
|
2024-02-04 23:45:49 +03:00
|
|
|
controller.promptTemplate();
|
2023-12-16 19:20:26 +03:00
|
|
|
}
|
|
|
|
|
2024-03-15 12:34:41 +03:00
|
|
|
function handleProduceStructure() {
|
|
|
|
editMenu.hide();
|
|
|
|
controller.produceStructure();
|
|
|
|
}
|
|
|
|
|
2024-03-18 16:22:27 +03:00
|
|
|
function handleInlineSynthesis() {
|
|
|
|
editMenu.hide();
|
|
|
|
controller.inlineSynthesis();
|
|
|
|
}
|
|
|
|
|
2023-12-16 19:20:26 +03:00
|
|
|
function handleChangeMode(newMode: UserAccessMode) {
|
|
|
|
accessMenu.hide();
|
|
|
|
setMode(newMode);
|
|
|
|
}
|
|
|
|
|
2023-08-24 11:10:04 +03:00
|
|
|
function handleCreateNew() {
|
2024-04-01 21:45:10 +03:00
|
|
|
router.push(urls.create_schema);
|
2023-08-24 11:10:04 +03:00
|
|
|
}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
2024-03-04 19:58:10 +03:00
|
|
|
function handleLogin() {
|
2024-04-01 21:45:10 +03:00
|
|
|
router.push(urls.login);
|
2024-03-04 19:58:10 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
return (
|
|
|
|
<div className='flex'>
|
|
|
|
<div ref={schemaMenu.ref}>
|
|
|
|
<Button
|
|
|
|
dense
|
2024-03-04 19:58:10 +03:00
|
|
|
noBorder
|
|
|
|
noOutline
|
2023-12-28 14:04:44 +03:00
|
|
|
tabIndex={-1}
|
|
|
|
title='Меню'
|
2024-02-03 15:33:28 +03:00
|
|
|
hideTitle={schemaMenu.isOpen}
|
2023-12-28 14:04:44 +03:00
|
|
|
icon={<BiMenu size='1.25rem' className='clr-text-controls' />}
|
|
|
|
className='h-full pl-2'
|
|
|
|
onClick={schemaMenu.toggle}
|
2023-07-20 17:11:03 +03:00
|
|
|
/>
|
2023-12-28 14:04:44 +03:00
|
|
|
<Dropdown isOpen={schemaMenu.isOpen}>
|
2024-03-08 18:39:08 +03:00
|
|
|
{user ? (
|
|
|
|
<DropdownButton
|
|
|
|
text={model.isOwned ? 'Вы — владелец' : 'Стать владельцем'}
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconOwner size='1rem' className='icon-green' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!model.isClaimable && !model.isOwned}
|
2024-03-08 18:39:08 +03:00
|
|
|
onClick={!model.isOwned && model.isClaimable ? handleClaimOwner : undefined}
|
|
|
|
/>
|
|
|
|
) : null}
|
2023-12-28 14:04:44 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Поделиться'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconShare size='1rem' className='icon-primary' />}
|
2023-12-28 14:04:44 +03:00
|
|
|
onClick={handleShare}
|
|
|
|
/>
|
2024-03-08 18:39:08 +03:00
|
|
|
{user ? (
|
|
|
|
<DropdownButton
|
|
|
|
text='Клонировать'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconClone size='1rem' className='icon-primary' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={model.isArchive}
|
2024-03-08 18:39:08 +03:00
|
|
|
onClick={handleClone}
|
|
|
|
/>
|
|
|
|
) : null}
|
2023-12-28 14:04:44 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Выгрузить в Экстеор'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconDownload size='1rem' className='icon-primary' />}
|
2023-12-28 14:04:44 +03:00
|
|
|
onClick={handleDownload}
|
|
|
|
/>
|
2024-03-28 18:44:34 +03:00
|
|
|
{controller.isContentEditable ? (
|
2024-03-08 18:39:08 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Загрузить из Экстеора'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconUpload size='1rem' className='icon-red' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={controller.isProcessing}
|
2024-03-08 18:39:08 +03:00
|
|
|
onClick={handleUpload}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
{controller.isMutable ? (
|
|
|
|
<DropdownButton
|
|
|
|
text='Удалить схему'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconDestroy size='1rem' className='icon-red' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={controller.isProcessing}
|
2024-03-08 18:39:08 +03:00
|
|
|
onClick={handleDelete}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
{user ? (
|
|
|
|
<DropdownButton
|
|
|
|
className='border-t-2'
|
|
|
|
text='Создать новую схему'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconNewItem size='1rem' className='icon-primary' />}
|
2024-03-08 18:39:08 +03:00
|
|
|
onClick={handleCreateNew}
|
|
|
|
/>
|
|
|
|
) : null}
|
2024-03-01 18:19:33 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Библиотека'
|
2024-03-08 18:39:08 +03:00
|
|
|
icon={<VscLibrary size='1rem' className='icon-primary' />}
|
2024-04-01 21:45:10 +03:00
|
|
|
onClick={() => router.push(urls.library)}
|
2024-03-01 18:19:33 +03:00
|
|
|
/>
|
2023-12-28 14:04:44 +03:00
|
|
|
</Dropdown>
|
|
|
|
</div>
|
|
|
|
|
2024-03-08 18:39:08 +03:00
|
|
|
{!model.isArchive && user ? (
|
2024-03-04 19:58:10 +03:00
|
|
|
<div ref={editMenu.ref}>
|
|
|
|
<Button
|
|
|
|
dense
|
|
|
|
noBorder
|
|
|
|
noOutline
|
|
|
|
tabIndex={-1}
|
|
|
|
title={'Редактирование'}
|
|
|
|
hideTitle={editMenu.isOpen}
|
2024-04-03 18:48:56 +03:00
|
|
|
className='h-full px-2'
|
2024-03-08 18:39:08 +03:00
|
|
|
icon={<FiEdit size='1.25rem' className={controller.isContentEditable ? 'icon-green' : 'icon-red'} />}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={editMenu.toggle}
|
|
|
|
/>
|
|
|
|
<Dropdown isOpen={editMenu.isOpen}>
|
|
|
|
<DropdownButton
|
2024-03-27 22:54:24 +03:00
|
|
|
text='Шаблоны'
|
2024-03-04 19:58:10 +03:00
|
|
|
title='Создать конституенту из шаблона'
|
2024-03-08 18:39:08 +03:00
|
|
|
icon={<BiDiamond size='1rem' className='icon-green' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={handleTemplates}
|
|
|
|
/>
|
2024-03-18 16:22:27 +03:00
|
|
|
<DropdownButton
|
2024-03-25 13:13:54 +03:00
|
|
|
text='Встраивание'
|
2024-03-18 16:22:27 +03:00
|
|
|
title='Импортировать совокупность конституент из другой схемы'
|
|
|
|
icon={<LuBookCopy size='1rem' className='icon-green' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
2024-03-18 16:22:27 +03:00
|
|
|
onClick={handleInlineSynthesis}
|
|
|
|
/>
|
2024-03-15 14:35:06 +03:00
|
|
|
<DropdownButton
|
|
|
|
className='border-t-2'
|
2024-03-25 13:13:54 +03:00
|
|
|
text='Порядковые имена'
|
2024-03-15 14:35:06 +03:00
|
|
|
title='Присвоить порядковые имена и обновить выражения'
|
2024-03-18 16:22:27 +03:00
|
|
|
icon={<LuWand2 size='1rem' className='icon-primary' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
2024-03-15 14:35:06 +03:00
|
|
|
onClick={handleReindex}
|
|
|
|
/>
|
2024-03-15 12:34:41 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Порождение структуры'
|
|
|
|
title='Раскрыть структуру типизации выделенной конституенты'
|
|
|
|
icon={<LuNetwork size='1rem' className='icon-primary' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!controller.isContentEditable || !controller.canProduceStructure}
|
2024-03-15 12:34:41 +03:00
|
|
|
onClick={handleProduceStructure}
|
|
|
|
/>
|
2024-03-04 19:58:10 +03:00
|
|
|
<DropdownButton
|
|
|
|
text='Отождествление'
|
|
|
|
title='Заменить вхождения одной конституенты на другую'
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconReplace size='1rem' className='icon-red' />}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={handleSubstituteCst}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
2024-03-04 19:58:10 +03:00
|
|
|
/>
|
|
|
|
</Dropdown>
|
|
|
|
</div>
|
|
|
|
) : null}
|
2024-03-08 18:39:08 +03:00
|
|
|
{model.isArchive && user ? (
|
2023-12-28 14:04:44 +03:00
|
|
|
<Button
|
|
|
|
dense
|
|
|
|
noBorder
|
2024-03-04 19:58:10 +03:00
|
|
|
noOutline
|
2023-12-28 14:04:44 +03:00
|
|
|
tabIndex={-1}
|
2024-03-08 18:39:08 +03:00
|
|
|
titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии'
|
2024-03-04 19:58:10 +03:00
|
|
|
hideTitle={accessMenu.isOpen}
|
2024-04-06 22:36:37 +03:00
|
|
|
className='h-full px-2'
|
2024-03-08 18:39:08 +03:00
|
|
|
icon={<LuArchive size='1.25rem' className='icon-primary' />}
|
2024-04-07 21:09:13 +03:00
|
|
|
onClick={event => controller.viewVersion(undefined, event.ctrlKey)}
|
2023-12-16 19:20:26 +03:00
|
|
|
/>
|
2024-03-04 19:58:10 +03:00
|
|
|
) : null}
|
2023-12-28 14:04:44 +03:00
|
|
|
|
2024-03-04 19:58:10 +03:00
|
|
|
{user ? (
|
|
|
|
<div ref={accessMenu.ref}>
|
|
|
|
<Button
|
|
|
|
dense
|
|
|
|
noBorder
|
|
|
|
noOutline
|
|
|
|
tabIndex={-1}
|
|
|
|
title={`Режим ${labelAccessMode(mode)}`}
|
|
|
|
hideTitle={accessMenu.isOpen}
|
|
|
|
className='h-full pr-2'
|
|
|
|
icon={
|
|
|
|
mode === UserAccessMode.ADMIN ? (
|
2024-04-03 21:05:53 +03:00
|
|
|
<IconAdmin size='1.25rem' className='icon-primary' />
|
2024-03-04 19:58:10 +03:00
|
|
|
) : mode === UserAccessMode.OWNER ? (
|
2024-04-03 21:05:53 +03:00
|
|
|
<IconOwner size='1.25rem' className='icon-primary' />
|
2024-03-04 19:58:10 +03:00
|
|
|
) : (
|
2024-04-03 21:05:53 +03:00
|
|
|
<IconReader size='1.25rem' className='icon-primary' />
|
2024-03-04 19:58:10 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
onClick={accessMenu.toggle}
|
|
|
|
/>
|
|
|
|
<Dropdown isOpen={accessMenu.isOpen}>
|
|
|
|
<DropdownButton
|
|
|
|
text={labelAccessMode(UserAccessMode.READER)}
|
|
|
|
title={describeAccessMode(UserAccessMode.READER)}
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconReader size='1rem' className='icon-primary' />}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={() => handleChangeMode(UserAccessMode.READER)}
|
|
|
|
/>
|
|
|
|
<DropdownButton
|
|
|
|
text={labelAccessMode(UserAccessMode.OWNER)}
|
|
|
|
title={describeAccessMode(UserAccessMode.OWNER)}
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconOwner size='1rem' className='icon-primary' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!model.isOwned}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={() => handleChangeMode(UserAccessMode.OWNER)}
|
|
|
|
/>
|
|
|
|
<DropdownButton
|
|
|
|
text={labelAccessMode(UserAccessMode.ADMIN)}
|
|
|
|
title={describeAccessMode(UserAccessMode.ADMIN)}
|
2024-04-03 21:05:53 +03:00
|
|
|
icon={<IconAdmin size='1rem' className='icon-primary' />}
|
2024-03-28 18:44:34 +03:00
|
|
|
disabled={!user?.is_staff}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={() => handleChangeMode(UserAccessMode.ADMIN)}
|
|
|
|
/>
|
|
|
|
</Dropdown>
|
|
|
|
</div>
|
|
|
|
) : null}
|
|
|
|
{!user ? (
|
2023-12-28 14:04:44 +03:00
|
|
|
<Button
|
|
|
|
dense
|
|
|
|
noBorder
|
2024-03-04 19:58:10 +03:00
|
|
|
noOutline
|
2023-12-28 14:04:44 +03:00
|
|
|
tabIndex={-1}
|
2024-03-08 18:39:08 +03:00
|
|
|
titleHtml='<b>Анонимный режим</b><br />Войти в Портал'
|
2024-02-03 15:33:28 +03:00
|
|
|
hideTitle={accessMenu.isOpen}
|
2023-12-28 14:04:44 +03:00
|
|
|
className='h-full pr-2'
|
2024-03-08 18:39:08 +03:00
|
|
|
icon={<LuAlertTriangle size='1.25rem' className='icon-red' />}
|
2024-03-04 19:58:10 +03:00
|
|
|
onClick={handleLogin}
|
2023-12-16 19:20:26 +03:00
|
|
|
/>
|
2024-03-04 19:58:10 +03:00
|
|
|
) : null}
|
2023-07-20 17:11:03 +03:00
|
|
|
</div>
|
2023-12-28 14:04:44 +03:00
|
|
|
);
|
2023-07-20 17:11:03 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
export default RSTabsMenu;
|