2024-06-07 20:17:03 +03:00
|
|
|
|
'use client';
|
|
|
|
|
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import fileDownload from 'js-file-download';
|
|
|
|
|
import { toast } from 'react-toastify';
|
|
|
|
|
|
2025-01-23 19:41:31 +03:00
|
|
|
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import { urls } from '@/app/urls';
|
2025-01-21 20:33:05 +03:00
|
|
|
|
import { useAuth } from '@/backend/auth/useAuth';
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { useCstSubstitute } from '@/backend/rsform/useCstSubstitute';
|
|
|
|
|
import { useDownloadRSForm } from '@/backend/rsform/useDownloadRSForm';
|
|
|
|
|
import { useInlineSynthesis } from '@/backend/rsform/useInlineSynthesis';
|
|
|
|
|
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
|
|
|
|
import { useProduceStructure } from '@/backend/rsform/useProduceStructure';
|
|
|
|
|
import { useResetAliases } from '@/backend/rsform/useResetAliases';
|
|
|
|
|
import { useRestoreOrder } from '@/backend/rsform/useRestoreOrder';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import {
|
|
|
|
|
IconAdmin,
|
|
|
|
|
IconAlert,
|
|
|
|
|
IconArchive,
|
|
|
|
|
IconClone,
|
|
|
|
|
IconDestroy,
|
|
|
|
|
IconDownload,
|
|
|
|
|
IconEdit2,
|
|
|
|
|
IconEditor,
|
|
|
|
|
IconGenerateNames,
|
|
|
|
|
IconGenerateStructure,
|
|
|
|
|
IconInlineSynthesis,
|
|
|
|
|
IconLibrary,
|
|
|
|
|
IconMenu,
|
|
|
|
|
IconNewItem,
|
2024-07-28 00:37:33 +03:00
|
|
|
|
IconOSS,
|
2024-06-07 20:17:03 +03:00
|
|
|
|
IconOwner,
|
2024-12-18 12:35:17 +03:00
|
|
|
|
IconQR,
|
2024-06-07 20:17:03 +03:00
|
|
|
|
IconReader,
|
|
|
|
|
IconReplace,
|
|
|
|
|
IconShare,
|
|
|
|
|
IconSortList,
|
|
|
|
|
IconTemplates,
|
|
|
|
|
IconUpload
|
|
|
|
|
} from '@/components/Icons';
|
|
|
|
|
import Button from '@/components/ui/Button';
|
2024-12-12 13:17:24 +03:00
|
|
|
|
import Divider from '@/components/ui/Divider';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import Dropdown from '@/components/ui/Dropdown';
|
|
|
|
|
import DropdownButton from '@/components/ui/DropdownButton';
|
|
|
|
|
import useDropdown from '@/hooks/useDropdown';
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { AccessPolicy, LocationHead } from '@/models/library';
|
|
|
|
|
import { CstType } from '@/models/rsform';
|
2025-01-15 23:03:23 +03:00
|
|
|
|
import { UserRole } from '@/models/user';
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { useDialogsStore } from '@/stores/dialogs';
|
|
|
|
|
import { useModificationStore } from '@/stores/modification';
|
2025-01-15 23:03:23 +03:00
|
|
|
|
import { useRoleStore } from '@/stores/role';
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { EXTEOR_TRS_FILE } from '@/utils/constants';
|
|
|
|
|
import { describeAccessMode, information, labelAccessMode, tooltips } from '@/utils/labels';
|
|
|
|
|
import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { OssTabID } from '../OssPage/OssEditContext';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import { useRSEdit } from './RSEditContext';
|
|
|
|
|
|
2025-01-26 22:24:34 +03:00
|
|
|
|
function MenuRSTabs() {
|
2024-06-07 20:17:03 +03:00
|
|
|
|
const controller = useRSEdit();
|
|
|
|
|
const router = useConceptNavigation();
|
|
|
|
|
const { user } = useAuth();
|
|
|
|
|
|
2025-01-15 23:03:23 +03:00
|
|
|
|
const role = useRoleStore(state => state.role);
|
|
|
|
|
const setRole = useRoleStore(state => state.setRole);
|
2025-01-26 22:24:34 +03:00
|
|
|
|
const { isModified } = useModificationStore();
|
|
|
|
|
const isProcessing = useIsProcessingRSForm();
|
|
|
|
|
|
|
|
|
|
const { resetAliases } = useResetAliases();
|
|
|
|
|
const { restoreOrder } = useRestoreOrder();
|
|
|
|
|
const { produceStructure } = useProduceStructure();
|
|
|
|
|
const { inlineSynthesis } = useInlineSynthesis();
|
|
|
|
|
const { cstSubstitute } = useCstSubstitute();
|
|
|
|
|
const { download } = useDownloadRSForm();
|
|
|
|
|
|
|
|
|
|
const showInlineSynthesis = useDialogsStore(state => state.showInlineSynthesis);
|
|
|
|
|
const showQR = useDialogsStore(state => state.showQR);
|
|
|
|
|
const showSubstituteCst = useDialogsStore(state => state.showSubstituteCst);
|
|
|
|
|
const showClone = useDialogsStore(state => state.showCloneLibraryItem);
|
|
|
|
|
const showUpload = useDialogsStore(state => state.showUploadRSForm);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
|
|
|
|
const schemaMenu = useDropdown();
|
|
|
|
|
const editMenu = useDropdown();
|
|
|
|
|
const accessMenu = useDropdown();
|
|
|
|
|
|
2025-01-26 22:24:34 +03:00
|
|
|
|
// TODO: move into separate function
|
|
|
|
|
const canProduceStructure =
|
|
|
|
|
!!controller.activeCst &&
|
|
|
|
|
!!controller.activeCst.parse.typification &&
|
|
|
|
|
controller.activeCst.cst_type !== CstType.BASE &&
|
|
|
|
|
controller.activeCst.cst_type !== CstType.CONSTANT;
|
|
|
|
|
|
|
|
|
|
function calculateCloneLocation() {
|
|
|
|
|
const location = controller.schema.location;
|
|
|
|
|
const head = location.substring(0, 2) as LocationHead;
|
|
|
|
|
if (head === LocationHead.LIBRARY) {
|
|
|
|
|
return user?.is_staff ? location : LocationHead.USER;
|
|
|
|
|
}
|
|
|
|
|
if (controller.schema.owner === user?.id) {
|
|
|
|
|
return location;
|
|
|
|
|
}
|
|
|
|
|
return head === LocationHead.USER ? LocationHead.USER : location;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
|
function handleDelete() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
controller.deleteSchema();
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleDownload() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
if (isModified && !promptUnsaved()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const fileName = (controller.schema.alias ?? 'Schema') + EXTEOR_TRS_FILE;
|
|
|
|
|
download({ itemID: controller.schema.id, version: controller.schema.version }, (data: Blob) => {
|
|
|
|
|
try {
|
|
|
|
|
fileDownload(data, fileName);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleUpload() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
showUpload({ itemID: controller.schema.id });
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleClone() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
if (isModified && !promptUnsaved()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
showClone({
|
|
|
|
|
base: controller.schema,
|
|
|
|
|
initialLocation: calculateCloneLocation(),
|
|
|
|
|
selected: controller.selected,
|
|
|
|
|
totalCount: controller.schema.items.length
|
|
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleShare() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
sharePage();
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-18 12:35:17 +03:00
|
|
|
|
function handleShowQR() {
|
|
|
|
|
schemaMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
showQR({ target: generatePageQR() });
|
2024-09-16 14:02:27 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
|
function handleReindex() {
|
|
|
|
|
editMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
resetAliases(controller.schema.id, () => toast.success(information.reindexComplete));
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleRestoreOrder() {
|
|
|
|
|
editMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
restoreOrder(controller.schema.id, () => toast.success(information.reorderComplete));
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleSubstituteCst() {
|
|
|
|
|
editMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
if (isModified && !promptUnsaved()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
showSubstituteCst({
|
|
|
|
|
schema: controller.schema,
|
|
|
|
|
onSubstitute: data =>
|
|
|
|
|
cstSubstitute(
|
|
|
|
|
{
|
|
|
|
|
itemID: controller.schema.id, //
|
|
|
|
|
data
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
controller.setSelected(prev => prev.filter(id => !data.substitutions.find(sub => sub.original === id)));
|
|
|
|
|
toast.success(information.substituteSingle);
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleTemplates() {
|
|
|
|
|
editMenu.hide();
|
|
|
|
|
controller.promptTemplate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleProduceStructure() {
|
|
|
|
|
editMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
if (!controller.activeCst) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (isModified && !promptUnsaved()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
produceStructure(
|
|
|
|
|
{
|
|
|
|
|
itemID: controller.schema.id, //
|
|
|
|
|
data: { target: controller.activeCst.id }
|
|
|
|
|
},
|
|
|
|
|
cstList => {
|
|
|
|
|
toast.success(information.addedConstituents(cstList.length));
|
|
|
|
|
if (cstList.length !== 0) {
|
|
|
|
|
controller.setSelected(cstList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleInlineSynthesis() {
|
|
|
|
|
editMenu.hide();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
if (isModified && !promptUnsaved()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
showInlineSynthesis({
|
|
|
|
|
receiver: controller.schema,
|
|
|
|
|
onInlineSynthesis: data => {
|
|
|
|
|
const oldCount = controller.schema.items.length;
|
|
|
|
|
inlineSynthesis({ itemID: controller.schema.id, data }, newSchema => {
|
|
|
|
|
controller.deselectAll();
|
|
|
|
|
toast.success(information.addedConstituents(newSchema.items.length - oldCount));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
2025-01-15 23:03:23 +03:00
|
|
|
|
function handleChangeMode(newMode: UserRole) {
|
2024-06-07 20:17:03 +03:00
|
|
|
|
accessMenu.hide();
|
2025-01-15 23:03:23 +03:00
|
|
|
|
setRole(newMode);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleCreateNew() {
|
|
|
|
|
router.push(urls.create_schema);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleLogin() {
|
|
|
|
|
router.push(urls.login);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className='flex'>
|
|
|
|
|
<div ref={schemaMenu.ref}>
|
|
|
|
|
<Button
|
|
|
|
|
dense
|
|
|
|
|
noBorder
|
|
|
|
|
noOutline
|
|
|
|
|
tabIndex={-1}
|
|
|
|
|
title='Меню'
|
|
|
|
|
hideTitle={schemaMenu.isOpen}
|
|
|
|
|
icon={<IconMenu size='1.25rem' className='clr-text-controls' />}
|
|
|
|
|
className='h-full pl-2'
|
|
|
|
|
onClick={schemaMenu.toggle}
|
|
|
|
|
/>
|
|
|
|
|
<Dropdown isOpen={schemaMenu.isOpen}>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Поделиться'
|
2025-01-26 22:24:34 +03:00
|
|
|
|
titleHtml={tooltips.shareItem(controller.schema.access_policy)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconShare size='1rem' className='icon-primary' />}
|
|
|
|
|
onClick={handleShare}
|
2024-06-18 15:06:52 +03:00
|
|
|
|
disabled={controller.schema?.access_policy !== AccessPolicy.PUBLIC}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
2024-12-18 12:35:17 +03:00
|
|
|
|
<DropdownButton
|
|
|
|
|
text='QR-код'
|
|
|
|
|
title='Показать QR-код схемы'
|
|
|
|
|
icon={<IconQR size='1rem' className='icon-primary' />}
|
|
|
|
|
onClick={handleShowQR}
|
|
|
|
|
/>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
{user ? (
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Клонировать'
|
2024-12-18 12:35:17 +03:00
|
|
|
|
icon={<IconClone size='1rem' className='icon-green' />}
|
2025-01-23 19:41:31 +03:00
|
|
|
|
disabled={controller.isArchive}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleClone}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Выгрузить в Экстеор'
|
|
|
|
|
icon={<IconDownload size='1rem' className='icon-primary' />}
|
|
|
|
|
onClick={handleDownload}
|
|
|
|
|
/>
|
|
|
|
|
{controller.isContentEditable ? (
|
|
|
|
|
<DropdownButton
|
2024-08-01 20:10:58 +03:00
|
|
|
|
text='Загрузить из Экстеор'
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconUpload size='1rem' className='icon-red' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={isProcessing || controller.schema?.oss.length !== 0}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleUpload}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
{controller.isMutable ? (
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Удалить схему'
|
|
|
|
|
icon={<IconDestroy size='1rem' className='icon-red' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={isProcessing || role < UserRole.OWNER}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleDelete}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
2024-09-12 11:16:18 +03:00
|
|
|
|
|
2024-12-12 13:17:24 +03:00
|
|
|
|
<Divider margins='mx-3 my-1' />
|
2024-09-12 11:16:18 +03:00
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
|
{user ? (
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Создать новую схему'
|
|
|
|
|
icon={<IconNewItem size='1rem' className='icon-primary' />}
|
|
|
|
|
onClick={handleCreateNew}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
{controller.schema.oss.length > 0 ? (
|
2024-07-28 00:37:33 +03:00
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Перейти к ОСС'
|
|
|
|
|
icon={<IconOSS size='1rem' className='icon-primary' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
onClick={() => router.push(urls.oss(controller.schema.oss[0].id, OssTabID.GRAPH))}
|
2024-07-28 00:37:33 +03:00
|
|
|
|
/>
|
|
|
|
|
) : null}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Библиотека'
|
|
|
|
|
icon={<IconLibrary size='1rem' className='icon-primary' />}
|
|
|
|
|
onClick={() => router.push(urls.library)}
|
|
|
|
|
/>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
</div>
|
2025-01-23 19:41:31 +03:00
|
|
|
|
{!controller.isArchive && user ? (
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<div ref={editMenu.ref}>
|
|
|
|
|
<Button
|
|
|
|
|
dense
|
|
|
|
|
noBorder
|
|
|
|
|
noOutline
|
|
|
|
|
tabIndex={-1}
|
2024-08-23 22:53:32 +03:00
|
|
|
|
title='Редактирование'
|
2024-06-07 20:17:03 +03:00
|
|
|
|
hideTitle={editMenu.isOpen}
|
|
|
|
|
className='h-full px-2'
|
|
|
|
|
icon={<IconEdit2 size='1.25rem' className={controller.isContentEditable ? 'icon-green' : 'icon-red'} />}
|
|
|
|
|
onClick={editMenu.toggle}
|
|
|
|
|
/>
|
|
|
|
|
<Dropdown isOpen={editMenu.isOpen}>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Шаблоны'
|
|
|
|
|
title='Создать конституенту из шаблона'
|
|
|
|
|
icon={<IconTemplates size='1rem' className='icon-green' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleTemplates}
|
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Встраивание'
|
|
|
|
|
titleHtml='Импортировать совокупность <br/>конституент из другой схемы'
|
|
|
|
|
icon={<IconInlineSynthesis size='1rem' className='icon-green' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleInlineSynthesis}
|
|
|
|
|
/>
|
2024-09-12 11:16:18 +03:00
|
|
|
|
|
2024-12-12 13:17:24 +03:00
|
|
|
|
<Divider margins='mx-3 my-1' />
|
2024-09-12 11:16:18 +03:00
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Упорядочить список'
|
|
|
|
|
titleHtml='Упорядочить список, исходя из <br/>логики типов и связей конституент'
|
|
|
|
|
icon={<IconSortList size='1rem' className='icon-primary' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleRestoreOrder}
|
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Порядковые имена'
|
|
|
|
|
titleHtml='Присвоить порядковые имена <br/>и обновить выражения'
|
|
|
|
|
icon={<IconGenerateNames size='1rem' className='icon-primary' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleReindex}
|
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Порождение структуры'
|
|
|
|
|
titleHtml='Раскрыть структуру типизации <br/>выделенной конституенты'
|
|
|
|
|
icon={<IconGenerateStructure size='1rem' className='icon-primary' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || !canProduceStructure || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
onClick={handleProduceStructure}
|
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
|
|
|
|
text='Отождествление'
|
|
|
|
|
titleHtml='Заменить вхождения <br/>одной конституенты на другую'
|
|
|
|
|
icon={<IconReplace size='1rem' className='icon-red' />}
|
|
|
|
|
onClick={handleSubstituteCst}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
disabled={!controller.isContentEditable || isProcessing}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
router.push(urls.schema(itemID, version), newTab);
|
2025-01-23 19:41:31 +03:00
|
|
|
|
{controller.isArchive && user ? (
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<Button
|
|
|
|
|
dense
|
|
|
|
|
noBorder
|
|
|
|
|
noOutline
|
|
|
|
|
tabIndex={-1}
|
|
|
|
|
titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии'
|
|
|
|
|
hideTitle={accessMenu.isOpen}
|
|
|
|
|
className='h-full px-2'
|
|
|
|
|
icon={<IconArchive size='1.25rem' className='icon-primary' />}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
onClick={event => router.push(urls.schema(controller.schema.id), event.ctrlKey || event.metaKey)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
{user ? (
|
|
|
|
|
<div ref={accessMenu.ref}>
|
|
|
|
|
<Button
|
|
|
|
|
dense
|
|
|
|
|
noBorder
|
|
|
|
|
noOutline
|
|
|
|
|
tabIndex={-1}
|
2025-01-15 23:03:23 +03:00
|
|
|
|
title={`Режим ${labelAccessMode(role)}`}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
hideTitle={accessMenu.isOpen}
|
|
|
|
|
className='h-full pr-2'
|
|
|
|
|
icon={
|
2025-01-15 23:03:23 +03:00
|
|
|
|
role === UserRole.ADMIN ? (
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<IconAdmin size='1.25rem' className='icon-primary' />
|
2025-01-15 23:03:23 +03:00
|
|
|
|
) : role === UserRole.OWNER ? (
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<IconOwner size='1.25rem' className='icon-primary' />
|
2025-01-15 23:03:23 +03:00
|
|
|
|
) : role === UserRole.EDITOR ? (
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<IconEditor size='1.25rem' className='icon-primary' />
|
|
|
|
|
) : (
|
|
|
|
|
<IconReader size='1.25rem' className='icon-primary' />
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
onClick={accessMenu.toggle}
|
|
|
|
|
/>
|
|
|
|
|
<Dropdown isOpen={accessMenu.isOpen}>
|
|
|
|
|
<DropdownButton
|
2025-01-15 23:03:23 +03:00
|
|
|
|
text={labelAccessMode(UserRole.READER)}
|
|
|
|
|
title={describeAccessMode(UserRole.READER)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconReader size='1rem' className='icon-primary' />}
|
2025-01-15 23:03:23 +03:00
|
|
|
|
onClick={() => handleChangeMode(UserRole.READER)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
2025-01-15 23:03:23 +03:00
|
|
|
|
text={labelAccessMode(UserRole.EDITOR)}
|
|
|
|
|
title={describeAccessMode(UserRole.EDITOR)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconEditor size='1rem' className='icon-primary' />}
|
2025-01-23 19:41:31 +03:00
|
|
|
|
disabled={!controller.isOwned && !controller.schema?.editors.includes(user.id)}
|
2025-01-15 23:03:23 +03:00
|
|
|
|
onClick={() => handleChangeMode(UserRole.EDITOR)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
2025-01-15 23:03:23 +03:00
|
|
|
|
text={labelAccessMode(UserRole.OWNER)}
|
|
|
|
|
title={describeAccessMode(UserRole.OWNER)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconOwner size='1rem' className='icon-primary' />}
|
2025-01-23 19:41:31 +03:00
|
|
|
|
disabled={!controller.isOwned}
|
2025-01-15 23:03:23 +03:00
|
|
|
|
onClick={() => handleChangeMode(UserRole.OWNER)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
<DropdownButton
|
2025-01-15 23:03:23 +03:00
|
|
|
|
text={labelAccessMode(UserRole.ADMIN)}
|
|
|
|
|
title={describeAccessMode(UserRole.ADMIN)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
icon={<IconAdmin size='1rem' className='icon-primary' />}
|
|
|
|
|
disabled={!user?.is_staff}
|
2025-01-15 23:03:23 +03:00
|
|
|
|
onClick={() => handleChangeMode(UserRole.ADMIN)}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
/>
|
|
|
|
|
</Dropdown>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
|
|
|
|
{!user ? (
|
|
|
|
|
<Button
|
|
|
|
|
dense
|
|
|
|
|
noBorder
|
|
|
|
|
noOutline
|
|
|
|
|
tabIndex={-1}
|
|
|
|
|
titleHtml='<b>Анонимный режим</b><br />Войти в Портал'
|
|
|
|
|
hideTitle={accessMenu.isOpen}
|
|
|
|
|
className='h-full pr-2'
|
|
|
|
|
icon={<IconAlert size='1.25rem' className='icon-red' />}
|
|
|
|
|
onClick={handleLogin}
|
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-26 19:47:05 +03:00
|
|
|
|
export default MenuRSTabs;
|