ConceptPortal-public/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx

327 lines
10 KiB
TypeScript
Raw Normal View History

'use client';
2023-07-25 20:27:29 +03:00
2023-12-28 14:04:44 +03:00
import {
BiDiamond,
BiDownload,
BiDuplicate,
BiMenu,
BiMeteor,
BiPlusCircle,
BiShareAlt,
BiTrash,
BiUpload
} from 'react-icons/bi';
2023-12-16 19:20:26 +03:00
import { FiEdit } from 'react-icons/fi';
import {
LuAlertTriangle,
LuArchive,
LuBookCopy,
LuCrown,
LuGlasses,
LuNetwork,
LuReplace,
LuWand2
} from 'react-icons/lu';
import { VscLibrary } from 'react-icons/vsc';
2023-12-16 19:20:26 +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';
import { useAuth } from '@/context/AuthContext';
2023-12-26 14:23:51 +03:00
import { useConceptNavigation } from '@/context/NavigationContext';
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
import { useRSEdit } from './RSEditContext';
2023-12-28 14:04:44 +03:00
interface RSTabsMenuProps {
2023-12-28 14:04:44 +03:00
onDestroy: () => void;
2023-07-28 18:23:37 +03:00
}
function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
const controller = useRSEdit();
const router = useConceptNavigation();
2023-07-25 20:27:29 +03:00
const { user } = useAuth();
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() {
editMenu.hide();
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() {
schemaMenu.hide();
onDestroy();
2023-08-25 22:51:20 +03:00
}
2023-12-28 14:04:44 +03:00
function handleDownload() {
schemaMenu.hide();
controller.download();
2023-08-25 22:51:20 +03:00
}
2023-08-25 22:51:20 +03:00
function handleUpload() {
schemaMenu.hide();
controller.promptUpload();
2023-08-25 22:51:20 +03:00
}
2023-08-25 22:51:20 +03:00
function handleClone() {
schemaMenu.hide();
controller.promptClone();
2023-08-25 22:51:20 +03:00
}
2023-08-24 11:10:04 +03:00
function handleShare() {
schemaMenu.hide();
controller.share();
2023-08-24 11:10:04 +03:00
}
2023-12-16 19:20:26 +03:00
function handleReindex() {
editMenu.hide();
controller.reindex();
2023-12-16 19:20:26 +03:00
}
function handleSubstituteCst() {
editMenu.hide();
controller.substitute();
}
2023-12-16 19:20:26 +03:00
function handleTemplates() {
editMenu.hide();
controller.promptTemplate();
2023-12-16 19:20:26 +03:00
}
2024-03-15 12:34:41 +03:00
function handleProduceStructure() {
editMenu.hide();
controller.produceStructure();
}
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() {
2023-12-19 19:40:42 +03:00
router.push('/library/create');
2023-08-24 11:10:04 +03:00
}
2023-07-25 20:27:29 +03:00
function handleLogin() {
router.push('/login');
}
2023-12-28 14:04:44 +03:00
return (
<div className='flex'>
<div ref={schemaMenu.ref}>
<Button
dense
noBorder
noOutline
2023-12-28 14:04:44 +03:00
tabIndex={-1}
title='Меню'
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}>
{user ? (
<DropdownButton
text={model.isOwned ? 'Вы — владелец' : 'Стать владельцем'}
2024-03-08 19:37:36 +03:00
icon={<LuCrown size='1rem' className='icon-green' />}
2024-03-28 18:44:34 +03:00
disabled={!model.isClaimable && !model.isOwned}
onClick={!model.isOwned && model.isClaimable ? handleClaimOwner : undefined}
/>
) : null}
2023-12-28 14:04:44 +03:00
<DropdownButton
text='Поделиться'
icon={<BiShareAlt size='1rem' className='icon-primary' />}
2023-12-28 14:04:44 +03:00
onClick={handleShare}
/>
{user ? (
<DropdownButton
text='Клонировать'
icon={<BiDuplicate size='1rem' className='icon-primary' />}
2024-03-28 18:44:34 +03:00
disabled={model.isArchive}
onClick={handleClone}
/>
) : null}
2023-12-28 14:04:44 +03:00
<DropdownButton
text='Выгрузить в Экстеор'
icon={<BiDownload 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 ? (
<DropdownButton
text='Загрузить из Экстеора'
icon={<BiUpload size='1rem' className='icon-red' />}
2024-03-28 18:44:34 +03:00
disabled={controller.isProcessing}
onClick={handleUpload}
/>
) : null}
{controller.isMutable ? (
<DropdownButton
text='Удалить схему'
icon={<BiTrash size='1rem' className='icon-red' />}
2024-03-28 18:44:34 +03:00
disabled={controller.isProcessing}
onClick={handleDelete}
/>
) : null}
{user ? (
<DropdownButton
className='border-t-2'
text='Создать новую схему'
icon={<BiPlusCircle size='1rem' className='icon-primary' />}
onClick={handleCreateNew}
/>
) : null}
<DropdownButton
text='Библиотека'
icon={<VscLibrary size='1rem' className='icon-primary' />}
onClick={() => router.push('/library')}
/>
2023-12-28 14:04:44 +03:00
</Dropdown>
</div>
{!model.isArchive && user ? (
<div ref={editMenu.ref}>
<Button
dense
noBorder
noOutline
tabIndex={-1}
title={'Редактирование'}
hideTitle={editMenu.isOpen}
className='h-full'
icon={<FiEdit size='1.25rem' className={controller.isContentEditable ? 'icon-green' : 'icon-red'} />}
onClick={editMenu.toggle}
/>
<Dropdown isOpen={editMenu.isOpen}>
<DropdownButton
text='Шаблоны'
title='Создать конституенту из шаблона'
icon={<BiDiamond size='1rem' className='icon-green' />}
2024-03-28 18:44:34 +03:00
disabled={!controller.isContentEditable || controller.isProcessing}
onClick={handleTemplates}
/>
<DropdownButton
2024-03-25 13:13:54 +03:00
text='Встраивание'
title='Импортировать совокупность конституент из другой схемы'
icon={<LuBookCopy size='1rem' className='icon-green' />}
2024-03-28 18:44:34 +03:00
disabled={!controller.isContentEditable || controller.isProcessing}
onClick={handleInlineSynthesis}
/>
<DropdownButton
className='border-t-2'
2024-03-25 13:13:54 +03:00
text='Порядковые имена'
title='Присвоить порядковые имена и обновить выражения'
icon={<LuWand2 size='1rem' className='icon-primary' />}
2024-03-28 18:44:34 +03:00
disabled={!controller.isContentEditable || controller.isProcessing}
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}
/>
<DropdownButton
text='Отождествление'
title='Заменить вхождения одной конституенты на другую'
icon={<LuReplace size='1rem' className='icon-red' />}
onClick={handleSubstituteCst}
2024-03-28 18:44:34 +03:00
disabled={!controller.isContentEditable || controller.isProcessing}
/>
</Dropdown>
</div>
) : null}
{model.isArchive && user ? (
2023-12-28 14:04:44 +03:00
<Button
dense
noBorder
noOutline
2023-12-28 14:04:44 +03:00
tabIndex={-1}
titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии'
hideTitle={accessMenu.isOpen}
2023-12-28 14:04:44 +03:00
className='h-full'
icon={<LuArchive size='1.25rem' className='icon-primary' />}
onClick={() => controller.viewVersion(undefined)}
2023-12-16 19:20:26 +03:00
/>
) : null}
2023-12-28 14:04:44 +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 ? (
<BiMeteor size='1.25rem' className='icon-primary' />
) : mode === UserAccessMode.OWNER ? (
<LuCrown size='1.25rem' className='icon-primary' />
) : (
<LuGlasses size='1.25rem' className='icon-primary' />
)
}
onClick={accessMenu.toggle}
/>
<Dropdown isOpen={accessMenu.isOpen}>
<DropdownButton
text={labelAccessMode(UserAccessMode.READER)}
title={describeAccessMode(UserAccessMode.READER)}
icon={<LuGlasses size='1rem' className='icon-primary' />}
onClick={() => handleChangeMode(UserAccessMode.READER)}
/>
<DropdownButton
text={labelAccessMode(UserAccessMode.OWNER)}
title={describeAccessMode(UserAccessMode.OWNER)}
icon={<LuCrown size='1rem' className='icon-primary' />}
2024-03-28 18:44:34 +03:00
disabled={!model.isOwned}
onClick={() => handleChangeMode(UserAccessMode.OWNER)}
/>
<DropdownButton
text={labelAccessMode(UserAccessMode.ADMIN)}
title={describeAccessMode(UserAccessMode.ADMIN)}
icon={<BiMeteor size='1rem' className='icon-primary' />}
2024-03-28 18:44:34 +03:00
disabled={!user?.is_staff}
onClick={() => handleChangeMode(UserAccessMode.ADMIN)}
/>
</Dropdown>
</div>
) : null}
{!user ? (
2023-12-28 14:04:44 +03:00
<Button
dense
noBorder
noOutline
2023-12-28 14:04:44 +03:00
tabIndex={-1}
titleHtml='<b>Анонимный режим</b><br />Войти в Портал'
hideTitle={accessMenu.isOpen}
2023-12-28 14:04:44 +03:00
className='h-full pr-2'
icon={<LuAlertTriangle size='1.25rem' className='icon-red' />}
onClick={handleLogin}
2023-12-16 19:20:26 +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;