Refactor help pages

This commit is contained in:
IRBorisov 2023-08-23 18:11:42 +03:00
parent 375bac2a52
commit 6467ff7b80
28 changed files with 361 additions and 101 deletions

View File

@ -1 +1,2 @@
**/parser.ts
**/node_modules/**

View File

@ -22,9 +22,6 @@
"off",
{ "allowConstantExport": true }
],
"simple-import-sort/imports": "warn",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-argument": "off"
"simple-import-sort/imports": "warn"
}
}

View File

@ -12,6 +12,7 @@ function ConceptTooltip({ className, place='bottom', ...props }: ConceptTooltipP
return (
<Tooltip
opacity={0.95}
className={`overflow-auto border shadow-md z-20 ${className}`}
variant={(darkMode ? 'dark' : 'light')}
place={place}

View File

@ -3,10 +3,11 @@ import { type FallbackProps } from 'react-error-boundary';
import Button from './Common/Button';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
console.log(error);
return (
<div className='flex flex-col items-center antialiased clr-app' role='alert'>
<h1 className='text-lg font-semibold'>Something went wrong!</h1>
<pre className='text-red'>Error message: {error.message}</pre>
{ error }
<Button onClick={resetErrorBoundary} text='Try again' />
</div>
);

View File

@ -0,0 +1,9 @@
function HelpAPI() {
return (
<div className=''>
<b>Справочник по API</b>
</div>
);
}
export default HelpAPI;

View File

@ -0,0 +1,25 @@
import Divider from '../Common/Divider';
import InfoCstStatus from './InfoCstStatus';
function HelpConstituenta() {
return (
<div className=''>
<h1>Подсказки</h1>
<p><b className='text-red'>Изменения сохраняются ПОСЛЕ нажатия на кнопку снизу или слева вверху</b></p>
<p><b>Клик на формальное выражение</b> - обратите внимание на кнопки снизу.<br/>Для каждой есть горячая клавиша в подсказке</p>
<p><b>Список конституент справа</b> - обратите внимание на настройки фильтрации</p>
<p>- слева от ввода текста настраивается набор атрибутов конституенты</p>
<p>- справа от ввода текста настраивается список конституент, которые фильтруются</p>
<p>- текущая конституента выделена цветом строки</p>
<p>- двойной клик / Alt + клик - выбор редактируемой конституенты</p>
<p>- при наведении на ID конституенты отображаются ее атрибуты</p>
<p>- столбец "Описание" содержит один из непустых текстовых атрибутов</p>
<Divider margins='mt-2' />
<InfoCstStatus title='Статусы' />
</div>
);
}
export default HelpConstituenta;

View File

@ -0,0 +1,9 @@
function HelpExteor() {
return (
<div className=''>
<b>Справочник по Экстеору</b>
</div>
);
}
export default HelpExteor;

View File

@ -0,0 +1,9 @@
function HelpLibrary() {
return (
<div className=''>
<b>Справочник по Библиотеке</b>
</div>
);
}
export default HelpLibrary;

View File

@ -0,0 +1,21 @@
import { urls } from '../../utils/constants';
import TextURL from '../Common/TextURL';
function HelpMain() {
return (
<div className='w-full lg:text-justify'>
<h1>Портал</h1>
<p><u>Портал</u> позволяет анализировать предметные области, формально записывать системы определений (<u>концептуальные схемы</u>) и синтезировать их с помощью математического аппарата родов структур.</p>
<p>Навигация по порталу осуществляется верхнюю панель или ссылки в "подвале" страницы. Их можно скрыть с помощью кнопки в правом верхнем углу</p>
<p className='mt-2'><b>Основные разделы Портала</b></p>
<li><TextURL text='Библиотека' href='/library?filter=common' /> содержит обещдоступные схемы и инструменты поиска и навигации по ним</li>
<li><TextURL text='Мои схемы' href='/library?filter=personal' /> содержит отслеживаемые и редактируемые схемы. Основной рабочий раздел</li>
<p className='mt-2'><b>Поддержка Портала</b></p>
<p>Портал разрабатывается <TextURL text='Центром Концепт' href={urls.concept}/> и является проектом с открытым исходным кодом, доступным на <TextURL text='Github' href={urls.gitrepo}/>.</p>
<p>Ждём Ваши пожелания по доработке, найденные ошибки и иные предложения по адресу <TextURL href={urls.mailportal} text='portal@acconcept.ru'/></p>
<p></p>
</div>
);
}
export default HelpMain;

View File

@ -0,0 +1,19 @@
import Divider from '../Common/Divider';
import InfoCstStatus from './InfoCstStatus';
function HelpRSFormItems() {
return (
<div>
<h1>Горячие клавиши</h1>
<p><b>Двойной клик / Alt + клик</b> - редактирование конституенты</p>
<p><b>Клик на квадрат слева</b> - выделение конституенты</p>
<p><b>Alt + вверх/вниз</b> - движение конституент</p>
<p><b>Delete</b> - удаление конституент</p>
<p><b>Alt + 1-6,Q,W</b> - добавление конституент</p>
<Divider margins='mt-2' />
<InfoCstStatus title='Статусы' />
</div>
);
}
export default HelpRSFormItems;

View File

@ -0,0 +1,14 @@
function HelpRSFormMeta() {
return (
<div>
<h1>Концептуальная схема</h1>
<p><b>Владелец</b> - пользователь, обладающий правом редактирования</p>
<p>Для <b>общедоступных</b> схем владельцем может стать любой пользователь</p>
<p>Для <b>библиотечных</b> схем правом редактирования обладают только администраторы</p>
<p><b>Клонировать</b> - создать копию схемы для дальнейшего редактирования</p>
<p><b>Загрузить/Выгрузить схему</b> - взаимодействие с Экстеор через файлы формата TRS</p>
</div>
);
}
export default HelpRSFormMeta;

View File

@ -0,0 +1,16 @@
import { urls } from '../../utils/constants';
function HelpRSLang() {
return (
<div className='flex flex-col w-full'>
<p>Для ознакомления с основами родов структур можно использовать следующие материалы:</p>
<ul>
<li>1. <a className='underline' href={urls.intro_video}>Краткое введение в мат. аппарат</a></li>
<li>2. <a className='underline' href={urls.full_course}>Видео лекций по мат. аппарату для 4 курса (второй семестр 2022-23 год)</a></li>
<li>3. <a className='underline' href={urls.ponomarev}>Учебник И. Н. Пономарева</a></li>
</ul>
</div>
);
}
export default HelpRSLang;

View File

@ -0,0 +1,34 @@
import Divider from '../Common/Divider';
import InfoCstClass from './InfoCstClass';
import InfoCstStatus from './InfoCstStatus';
function HelpTermGraph() {
return (
<div className='flex text-sm'>
<div>
<h1>Настройка графа</h1>
<p><b>Цвет</b> - выбор правила покраски узлов</p>
<p><b>Граф</b> - выбор модели расположения узлов</p>
<p><b>Удалить несвязанные</b> - скрыть одинокие вершины</p>
<p><b>Транзитивная редукция</b> - скрыть транзитивные пути</p>
<Divider margins='mt-2' />
<InfoCstStatus title='Статусы конституент' />
</div>
<Divider vertical margins='mx-3' />
<div>
<h1>Горячие клавиши</h1>
<p><b>Клик на конституенту</b> - выделение, включая скрытые конституенты</p>
<p><b>Довйной клик</b> - редактирование конституенты</p>
<p><b>Delete</b> - удалить выбранные</p>
<Divider margins='mt-2' />
<InfoCstClass title='Классы конституент' />
</div>
</div>
);
}
export default HelpTermGraph;

View File

@ -1,23 +0,0 @@
import { urls } from '../utils/constants';
function ManualsPage() {
return (
<div className='flex flex-col w-full py-2'>
<b>Справочники находятся в разработке</b>
<p>Для ознакомления с основами родов структур можно использовать следующие материалы:</p>
<ul>
<li>
1. <a className='underline' href={urls.intro_video}>Краткое введение в мат. аппарат</a>
</li>
<li>
2. <a className='underline' href={urls.full_course}>Видео лекций по мат. аппарату для 4 курса (второй семестр 2022-23 год)</a>
</li>
<li>
3. <a className='underline' href={urls.ponomarev}>Учебник И. Н. Пономарева</a>
</li>
</ul>
</div>
);
}
export default ManualsPage;

View File

@ -0,0 +1,29 @@
import { prefixes } from '../../utils/constants';
import { HelpTopic } from '../../utils/models';
import { mapTopicInfo } from '../../utils/staticUI';
interface TopicsListProps {
activeTopic: HelpTopic
onChangeTopic: (newTopic: HelpTopic) => void
}
function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
return (
<div className='sticky top-0 left-0 border-r min-w-[13rem] pt-2 select-none flex flex-col clr-bg-pop'>
<div className='mb-2 font-bold text-center'>Справка</div>
{ [... mapTopicInfo.entries()].map(
([topic, info], index) => {
return (
<div key={`${prefixes.topic_list}${index}`}
className={`px-3 py-1 border-y cursor-pointer clr-hover ${activeTopic === topic ? 'font-semibold underline' : ''}`}
title={info.tooltip}
onClick={() => onChangeTopic(topic)}
>
{info.text}
</div>)
})}
</div>
);
}
export default TopicsList;

View File

@ -0,0 +1,32 @@
import HelpAPI from '../../components/Help/HelpAPI';
import HelpConstituenta from '../../components/Help/HelpConstituenta';
import HelpExteor from '../../components/Help/HelpExteor';
import HelpLibrary from '../../components/Help/HelpLibrary';
import HelpMain from '../../components/Help/HelpMain';
import HelpRSFormItems from '../../components/Help/HelpRSFormItems';
import HelpRSFormMeta from '../../components/Help/HelpRSFormMeta';
import HelpRSLang from '../../components/Help/HelpRSLang';
import HelpTermGraph from '../../components/Help/HelpTermGraph';
import { HelpTopic } from '../../utils/models';
interface ViewTopicProps {
topic: HelpTopic
}
function ViewTopic({ topic }: ViewTopicProps) {
return (
<div className='px-2 py-2'>
{topic === HelpTopic.MAIN && <HelpMain />}
{topic === HelpTopic.RSLANG && <HelpRSLang />}
{topic === HelpTopic.LIBRARY && <HelpLibrary />}
{topic === HelpTopic.RSFORM && <HelpRSFormMeta />}
{topic === HelpTopic.CSTLIST && <HelpRSFormItems />}
{topic === HelpTopic.CONSTITUENTA && <HelpConstituenta />}
{topic === HelpTopic.GRAPH_TERM && <HelpTermGraph />}
{topic === HelpTopic.EXTEOR && <HelpExteor />}
{topic === HelpTopic.API && <HelpAPI />}
</div>
);
}
export default ViewTopic;

View File

@ -0,0 +1,44 @@
import { useCallback, useLayoutEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { HelpTopic } from '../../utils/models';
import TopicsList from './TopicsList';
import ViewTopic from './ViewTopic';
function ManualsPage() {
const navigate = useNavigate();
const search = useLocation().search;
const [activeTopic, setActiveTopic] = useState<HelpTopic>(HelpTopic.MAIN);
const navigateTo = useCallback(
(newTopic: HelpTopic) => {
navigate(`/manuals?topic=${newTopic}`);
}, [navigate]);
function onSelectTopic(newTopic: HelpTopic) {
navigateTo(newTopic);
}
useLayoutEffect(() => {
const topic = new URLSearchParams(search).get('topic') as HelpTopic;
if (!Object.values(HelpTopic).includes(topic)) {
navigateTo(HelpTopic.MAIN);
return;
} else {
setActiveTopic(topic);
}
}, [search, setActiveTopic, navigateTo]);
return (
<div className='flex items-start justify-start w-full gap-2'>
<TopicsList
activeTopic={activeTopic}
onChangeTopic={topic => onSelectTopic(topic)}
/>
<ViewTopic topic={activeTopic} />
</div>
);
}
export default ManualsPage;

View File

@ -68,7 +68,7 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
>
<div className='flex items-center gap-4 px-2 mb-2 h-fit min-w-[25rem]'>
<ConceptSelect
className='my-2 min-w-[14rem] self-center'
className='mt-2 min-w-[14rem] self-center'
options={CstTypeSelector}
placeholder='Выберите тип'
values={cstType ? [{ value: cstType, label: getCstTypeLabel(cstType) }] : []}

View File

@ -2,11 +2,10 @@ import { useLayoutEffect, useMemo, useState } from 'react';
import { toast } from 'react-toastify';
import ConceptTooltip from '../../components/Common/ConceptTooltip';
import Divider from '../../components/Common/Divider';
import MiniButton from '../../components/Common/MiniButton';
import SubmitButton from '../../components/Common/SubmitButton';
import TextArea from '../../components/Common/TextArea';
import CstStatusInfo from '../../components/Help/InfoCstStatus';
import HelpConstituenta from '../../components/Help/HelpConstituenta';
import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
import { CstType, EditMode, ICstCreateData, ICstRenameData, ICstUpdateData, SyntaxTree } from '../../utils/models';
@ -155,20 +154,7 @@ function EditorConstituenta({ activeID, onShowAST, onCreateCst, onRenameCst, onO
<HelpIcon color='text-primary' size={5} />
</div>
<ConceptTooltip anchorSelect='#cst-help'>
<div className='max-w-[35rem]'>
<h1>Подсказки</h1>
<p><b className='text-red'>Изменения сохраняются ПОСЛЕ нажатия на кнопку снизу или слева вверху</b></p>
<p><b>Клик на формальное выражение</b> - обратите внимание на кнопки снизу.<br/>Для каждой есть горячая клавиша в подсказке</p>
<p><b>Список конституент справа</b> - обратите внимание на настройки фильтрации</p>
<p>- слева от ввода текста настраивается набор атрибутов конституенты</p>
<p>- справа от ввода текста настраивается список конституент, которые фильтруются</p>
<p>- текущая конституента выделена цветом строки</p>
<p>- двойной клик / Alt + клик - выбор редактируемой конституенты</p>
<p>- при наведении на ID конституенты отображаются ее атрибуты</p>
<p>- столбец "Описание" содержит один из непустых текстовых атрибутов</p>
<Divider margins='mt-2' />
<CstStatusInfo title='Статусы' />
</div>
<HelpConstituenta />
</ConceptTooltip>
</div>
</div>

View File

@ -5,7 +5,7 @@ import Button from '../../components/Common/Button';
import ConceptDataTable from '../../components/Common/ConceptDataTable';
import ConceptTooltip from '../../components/Common/ConceptTooltip';
import Divider from '../../components/Common/Divider';
import CstStatusInfo from '../../components/Help/InfoCstStatus';
import HelpRSFormItems from '../../components/Help/HelpRSFormItems';
import { ArrowDownIcon, ArrowsRotateIcon, ArrowUpIcon, DumpBinIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext';
@ -319,16 +319,7 @@ function EditorItems({ onOpenEdit, onCreateCst, onDeleteCst }: EditorItemsProps)
<HelpIcon color='text-primary' size={6} />
</div>
<ConceptTooltip anchorSelect='#items-table-help'>
<div>
<h1>Горячие клавиши</h1>
<p><b>Двойной клик / Alt + клик</b> - редактирование конституенты</p>
<p><b>Клик на квадрат слева</b> - выделение конституенты</p>
<p><b>Alt + вверх/вниз</b> - движение конституент</p>
<p><b>Delete</b> - удаление конституент</p>
<p><b>Alt + 1-6,Q,W</b> - добавление конституент</p>
<Divider margins='mt-2' />
<CstStatusInfo title='Статусы' />
</div>
<HelpRSFormItems />
</ConceptTooltip>
</div>
</div>

View File

@ -3,11 +3,13 @@ import { useIntl } from 'react-intl';
import { toast } from 'react-toastify';
import Checkbox from '../../components/Common/Checkbox';
import ConceptTooltip from '../../components/Common/ConceptTooltip';
import MiniButton from '../../components/Common/MiniButton';
import SubmitButton from '../../components/Common/SubmitButton';
import TextArea from '../../components/Common/TextArea';
import TextInput from '../../components/Common/TextInput';
import { CrownIcon, DownloadIcon, DumpBinIcon, SaveIcon, ShareIcon } from '../../components/Icons';
import HelpRSFormMeta from '../../components/Help/HelpRSFormMeta';
import { CrownIcon, DownloadIcon, DumpBinIcon, HelpIcon, SaveIcon, ShareIcon } from '../../components/Icons';
import { useAuth } from '../../context/AuthContext';
import { useRSForm } from '../../context/RSFormContext';
import { useUsers } from '../../context/UsersContext';
@ -76,7 +78,7 @@ function EditorRSForm({ onDestroy }: EditorRSFormProps) {
return (
<form onSubmit={handleSubmit} className='flex-grow max-w-xl px-4 py-2 border min-w-fit'>
<div className='relative w-full'>
<div className='absolute top-0 right-0'>
<div className='absolute top-0 right-0 flex'>
<MiniButton
tooltip='Поделиться схемой'
icon={<ShareIcon size={5} color='text-primary'/>}
@ -99,6 +101,12 @@ function EditorRSForm({ onDestroy }: EditorRSFormProps) {
onClick={onDestroy}
icon={<DumpBinIcon size={5} color={isEditable ? 'text-red' : ''} />}
/>
<div id='rsform-help' className='py-1 ml-1'>
<HelpIcon color='text-primary' size={5} />
</div>
<ConceptTooltip anchorSelect='#rsform-help'>
<HelpRSFormMeta />
</ConceptTooltip>
</div>
</div>
<TextInput id='title' label='Полное название' type='text'

View File

@ -9,9 +9,8 @@ import ConceptSelect from '../../components/Common/ConceptSelect';
import ConceptTooltip from '../../components/Common/ConceptTooltip';
import Divider from '../../components/Common/Divider';
import MiniButton from '../../components/Common/MiniButton';
import HelpTermGraph from '../../components/Help/HelpTermGraph';
import InfoConstituenta from '../../components/Help/InfoConstituenta';
import InfoCstClass from '../../components/Help/InfoCstClass';
import CstStatusInfo from '../../components/Help/InfoCstStatus';
import { ArrowsRotateIcon, DumpBinIcon, FilterCogIcon, HelpIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
import { useConceptTheme } from '../../context/ThemeContext';
@ -476,30 +475,7 @@ function EditorTermGraph({ onOpenEdit, onCreateCst, onDeleteCst }: EditorTermGra
/>
</div>
<ConceptTooltip anchorSelect='#items-graph-help'>
<div className='flex'>
<div>
<h1>Настройка графа</h1>
<p><b>Цвет</b> - выбор правила покраски узлов</p>
<p><b>Граф</b> - выбор модели расположения узлов</p>
<p><b>Удалить несвязанные</b> - скрыть одинокие вершины</p>
<p><b>Транзитивная редукция</b> - скрыть транзитивные пути</p>
<Divider margins='mt-2' />
<CstStatusInfo title='Статусы конституент' />
</div>
<Divider vertical margins='mx-3' />
<div>
<h1>Горячие клавиши</h1>
<p><b>Клик на конституенту</b> - выделение, включая скрытые конституенты</p>
<p><b>Довйной клик</b> - редактирование конституенты</p>
<p><b>Delete</b> - удалить выбранные</p>
<Divider margins='mt-2' />
<InfoCstClass title='Классы конституент' />
</div>
</div>
<HelpTermGraph />
</ConceptTooltip>
<GraphCanvas
draggable

View File

@ -74,7 +74,7 @@ function RSTabs() {
const activeTab = Number(new URLSearchParams(search).get('tab')) ?? RSTabsList.CARD;
const cstQuery = new URLSearchParams(search).get('active');
setActiveTab(activeTab);
setActiveID(Number(cstQuery) ?? ((schema && schema?.items.length > 0) ? schema.items[0].id : undefined))
setActiveID(Number(cstQuery) ?? ((schema && schema?.items.length > 0) ? schema.items[0].id : undefined));
}, [search, setActiveTab, setActiveID, schema]);
function onSelectTab(index: number) {
@ -128,7 +128,7 @@ function RSTabs() {
const handleRenameCst = useCallback(
(data: ICstRenameData) => {
cstRename(data, () => toast.success(`Конституента переименована: ${renameInitialData!.alias} -> ${data.alias}`));
cstRename(data, () => toast.success(`Переименование: ${renameInitialData!.alias} -> ${data.alias}`));
}, [cstRename, renameInitialData]);
const promptRenameCst = useCallback(

View File

@ -1,4 +1,4 @@
import axios, { AxiosRequestConfig } from 'axios'
import axios, { AxiosError, AxiosRequestConfig } from 'axios'
import { toast } from 'react-toastify'
import { type ErrorInfo } from '../components/BackendError'
@ -260,11 +260,11 @@ function AxiosGet<ResponseData>({ endpoint, request, title, options }: IAxiosReq
console.log(`REQUEST: [[${title}]]`);
if (request.setLoading) request.setLoading(true);
axios.get<ResponseData>(endpoint, options)
.then((response) => {
.then(response => {
if (request.setLoading) request.setLoading(false);
if (request.onSuccess) request.onSuccess(response.data);
})
.catch((error) => {
.catch((error: Error | AxiosError) => {
if (request.setLoading) request.setLoading(false);
if (request.showError) toast.error(error.message);
if (request.onError) request.onError(error);
@ -277,11 +277,11 @@ function AxiosPost<RequestData, ResponseData>(
console.log(`POST: [[${title}]]`);
if (request.setLoading) request.setLoading(true);
axios.post<ResponseData>(endpoint, request.data, options)
.then((response) => {
.then(response => {
if (request.setLoading) request.setLoading(false);
if (request.onSuccess) request.onSuccess(response.data);
})
.catch((error) => {
.catch((error: Error | AxiosError) => {
if (request.setLoading) request.setLoading(false);
if (request.showError) toast.error(error.message);
if (request.onError) request.onError(error);
@ -294,11 +294,11 @@ function AxiosDelete<RequestData, ResponseData>(
console.log(`DELETE: [[${title}]]`);
if (request.setLoading) request.setLoading(true);
axios.delete<ResponseData>(endpoint, options)
.then((response) => {
.then(response => {
if (request.setLoading) request.setLoading(false);
if (request.onSuccess) request.onSuccess(response.data);
})
.catch((error) => {
.catch((error: Error | AxiosError) => {
if (request.setLoading) request.setLoading(false);
if (request.showError) toast.error(error.message);
if (request.onError) request.onError(error);
@ -311,12 +311,12 @@ function AxiosPatch<RequestData, ResponseData>(
console.log(`PATCH: [[${title}]]`);
if (request.setLoading) request.setLoading(true);
axios.patch<ResponseData>(endpoint, request.data, options)
.then((response) => {
.then(response => {
if (request.setLoading) request.setLoading(false);
if (request.onSuccess) request.onSuccess(response.data);
return response.data;
})
.catch((error) => {
.catch((error: Error | AxiosError) => {
if (request.setLoading) request.setLoading(false);
if (request.showError) toast.error(error.message);
if (request.onError) request.onError(error);

View File

@ -20,7 +20,8 @@ export const urls = {
ponomarev: 'https://inponomarev.ru/textbook',
intro_video: 'https://www.youtube.com/watch?v=0Ty9mu9sOJo',
full_course: 'https://www.youtube.com/playlist?list=PLGe_JiAwpqu1C70ruQmCm_OWTWU3KJwDo',
gitrepo: 'https://github.com/IRBorisov/ConceptPortal'
gitrepo: 'https://github.com/IRBorisov/ConceptPortal',
mailportal: 'mailto:portal@acconcept.ru'
};
export const resources = {
@ -29,5 +30,6 @@ export const resources = {
export const prefixes = {
cst_list: 'cst-list-',
cst_status_list: 'cst-status-list-'
cst_status_list: 'cst-status-list-',
topic_list: 'topic-list-',
}

View File

@ -270,6 +270,19 @@ export enum CstMatchMode {
NAME
}
// Help manual topic compare mode
export enum HelpTopic {
MAIN = 'main',
RSLANG = 'rslang',
LIBRARY = 'library',
RSFORM = 'rsform',
CSTLIST = 'cstlist',
CONSTITUENTA = 'constituenta',
GRAPH_TERM = 'graph-term',
EXTEOR = 'exteor',
API = 'api'
}
// ========== Model functions =================
export function inferStatus(parse?: ParsingStatus, value?: ValueClass): ExpressionStatus {
if (!parse || !value) {

View File

@ -2,7 +2,9 @@ import { LayoutTypes } from 'reagraph';
import { ColoringScheme } from '../pages/RSFormPage/EditorTermGraph';
import { resolveErrorClass,RSErrorClass, RSErrorType, TokenID } from './enums';
import { CstClass, CstMatchMode, CstType, DependencyMode, ExpressionStatus, IConstituenta,
import {
CstClass, CstMatchMode, CstType,
DependencyMode, ExpressionStatus, HelpTopic, IConstituenta,
IFunctionArg,IRSErrorDescription, IRSForm,
ISyntaxTreeNode, ParsingStatus, ValueClass
} from './models';
@ -18,6 +20,11 @@ export interface IFormatInfo {
tooltip: string
}
export interface ITopicInfo {
text: string
tooltip: string
}
export function getCstDescription(cst: IConstituenta): string {
if (cst.cstType === CstType.STRUCTURED) {
return (
@ -246,7 +253,7 @@ export function getCstTypeShortcut(type: CstType) {
}
export const CstTypeSelector = (Object.values(CstType)).map(
(typeStr) => {
(typeStr) => {
const type = typeStr as CstType;
return { value: type, label: getCstTypeLabel(type) };
});
@ -357,6 +364,45 @@ export const mapStatusInfo: Map<ExpressionStatus, IFormatInfo> = new Map([
text: 'N/A',
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
tooltip: 'произошла ошибка при проверке выражения'
}]
]);
export const mapTopicInfo: Map<HelpTopic, ITopicInfo> = new Map([
[ HelpTopic.MAIN, {
text: 'Портал',
tooltip: 'Общая справка по порталу'
}],
[ HelpTopic.RSLANG, {
text: 'Рода структур',
tooltip: 'Справка по языку родов структур и экспликации'
}],
[ HelpTopic.LIBRARY, {
text: 'Библиотека',
tooltip: 'Интерфейс работы с библиотекой схем'
}],
[ HelpTopic.RSFORM, {
text: 'Концептуальная схема',
tooltip: 'Интерфейс работы с описанием схемы'
}],
[ HelpTopic.CSTLIST, {
text: 'Список конституент',
tooltip: 'Интерфейс работы со списком конституент'
}],
[ HelpTopic.CONSTITUENTA, {
text: 'Конституента',
tooltip: 'Интерфейс редактирования конституенты'
}],
[ HelpTopic.GRAPH_TERM, {
text: 'Граф термов',
tooltip: 'Интерфейс работ с графом термов схемы'
}],
[ HelpTopic.EXTEOR, {
text: 'Экстеор',
tooltip: 'Справка по программе Экстеор'
}],
[ HelpTopic.API, {
text: 'REST API',
tooltip: 'Документация интерфейса для разработчиков'
}],
]);