F: Improve OSS UI and Manuals
Some checks are pending
Backend CI / build (3.12) (push) Waiting to run
Frontend CI / build (22.x) (push) Waiting to run

This commit is contained in:
Ivan 2024-08-19 22:03:39 +03:00
parent 3869b453c8
commit 3f8fab80aa
12 changed files with 178 additions and 133 deletions

View File

@ -31,7 +31,7 @@ function Tooltip({
<TooltipImpl
delayShow={1000}
delayHide={100}
opacity={0.97}
opacity={1}
className={clsx(
'max-h-[calc(100svh-6rem)]',
'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain',

View File

@ -3,10 +3,14 @@
import clsx from 'clsx';
import { useState } from 'react';
import BadgeHelp from '@/components/info/BadgeHelp';
import Checkbox from '@/components/ui/Checkbox';
import Modal, { ModalProps } from '@/components/ui/Modal';
import Overlay from '@/components/ui/Overlay';
import TextInput from '@/components/ui/TextInput';
import { HelpTopic } from '@/models/miscellaneous';
import { IOperation } from '@/models/oss';
import { PARAMETER } from '@/utils/constants';
interface DlgDeleteOperationProps extends Pick<ModalProps, 'hideWindow'> {
target: IOperation;
@ -31,6 +35,14 @@ function DlgDeleteOperation({ hideWindow, target, onSubmit }: DlgDeleteOperation
onSubmit={handleSubmit}
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column', 'select-none')}
>
<Overlay position='top-[-2rem] right-[4rem]'>
<BadgeHelp
topic={HelpTopic.CC_PROPAGATION}
className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')}
offset={14}
/>
</Overlay>
<TextInput
disabled
dense

View File

@ -84,6 +84,7 @@ export enum HelpTopic {
CC_RELATIONS = 'concept-relations',
CC_SYNTHESIS = 'concept-synthesis',
CC_OSS = 'concept-operations-schema',
CC_PROPAGATION = 'concept-change-propagation',
RSLANG = 'rslang',
RSL_TYPES = 'rslang-types',
@ -129,6 +130,7 @@ export const topicParent = new Map<HelpTopic, HelpTopic>([
[HelpTopic.CC_RELATIONS, HelpTopic.CONCEPTUAL],
[HelpTopic.CC_SYNTHESIS, HelpTopic.CONCEPTUAL],
[HelpTopic.CC_OSS, HelpTopic.CONCEPTUAL],
[HelpTopic.CC_PROPAGATION, HelpTopic.CONCEPTUAL],
[HelpTopic.RSLANG, HelpTopic.RSLANG],
[HelpTopic.RSL_TYPES, HelpTopic.RSLANG],

View File

@ -2,6 +2,7 @@ import useWindowSize from '@/hooks/useWindowSize';
import { HelpTopic } from '@/models/miscellaneous';
import HelpConceptOSS from './items/cc/HelpConceptOSS';
import HelpConceptPropagation from './items/cc/HelpConceptPropagation';
import HelpConceptRelations from './items/cc/HelpConceptRelations';
import HelpConceptSynthesis from './items/cc/HelpConceptSynthesis';
import HelpConceptSystem from './items/cc/HelpConceptSystem';
@ -69,6 +70,7 @@ function TopicPage({ topic }: TopicPageProps) {
if (topic === HelpTopic.CC_RELATIONS) return <HelpConceptRelations />;
if (topic === HelpTopic.CC_SYNTHESIS) return <HelpConceptSynthesis />;
if (topic === HelpTopic.CC_OSS) return <HelpConceptOSS />;
if (topic === HelpTopic.CC_PROPAGATION) return <HelpConceptPropagation />;
if (topic === HelpTopic.RSLANG) return <HelpRSLang />;
if (topic === HelpTopic.RSL_TYPES) return <HelpRSLangTypes />;

View File

@ -1,4 +1,4 @@
import { IconOSS, IconPredecessor } from '@/components/Icons';
import { IconConsolidation, IconExecute, IconOSS } from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic';
import { HelpTopic } from '@/models/miscellaneous';
@ -16,22 +16,30 @@ function HelpConceptOSS() {
и отображается в форме <LinkTopic text='Графа синтеза' topic={HelpTopic.UI_OSS_GRAPH} />.
</p>
<p>
Отдельные операции в рамках ОСС задаются <b>таблицами отождествлений</b> понятий из синтезируемых схем. Таким
образом <LinkTopic text='конституенты' topic={HelpTopic.CC_CONSTITUENTA} /> в каждой КС разделяются на исходные
Базовыми операциями ОСС являются загрузка и синтез. Схема может быть загружена из другой локации (
<b>внешняя КС</b>) или создана в ОСС (<b>собственная КС</b>). Загрузка схем, полученных синтезом в других ОСС не
допускается. Также запрещена повторная загрузка той же КС в рамках одной ОСС.
</p>
<p>
Операция синтеза в рамках ОСС задаются набором операций-аргументов и <b>таблицей отождествлений</b> понятий из
КС, привязанных к выбранным аргументам. Таким образом{' '}
<LinkTopic text='конституенты' topic={HelpTopic.CC_CONSTITUENTA} /> в каждой КС разделяются на исходные
(дописанные), наследованные, отождествленные (удаляемые).
</p>
<p>
Портал поддерживает <b>сквозные изменения</b> в рамках ОСС. Изменения, внесенные в исходные концептуальные схемы
автоматически проносятся через граф синтеза (путем обновления наследованных конституент). Формальные определения
наследованных конституент можно редактировать только путем изменения{' '}
После задания аргументов и таблицы отождествления необходимо единожды{' '}
<span className='text-nowrap'>
<IconPredecessor className='inline-icon' /> исходных конституент.
<IconExecute className='inline-icon icon-green' /> выполнить Синтез
</span>
, чтобы активировать <LinkTopic text='сквозные изменения' topic={HelpTopic.CC_PROPAGATION} />.
</p>
<p>
<b>Ромбовидным синтезом</b> называется операция, где используются КС, имеющие общих предков. При таком синтезе
могут возникать дубликаты и неоднозначности в результате. Необходимо внимательно формировать таблицу
отождествлений, добавляя дублирующиеся понятия из синтезируемых схем.
<span className='text-nowrap'>
<IconConsolidation className='inline-icon' /> <b>Ромбовидным синтезом</b>
</span>{' '}
называется операция, где используются КС, имеющие общих предков. При таком синтезе могут возникать дубликаты и
неоднозначности в результате. Необходимо внимательно формировать таблицу отождествлений, добавляя дублирующиеся
понятия из синтезируемых схем.
</p>
</div>
);

View File

@ -0,0 +1,43 @@
import { IconPredecessor } from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic';
import { HelpTopic } from '@/models/miscellaneous';
function HelpConceptPropagation() {
return (
<div className='text-justify'>
<h1>Сквозные изменения</h1>
<p>
Портал поддерживает <b>сквозные изменения</b> в рамках <LinkTopic text='ОСС' topic={HelpTopic.CC_OSS} />.
Изменения, внесенные в исходные концептуальные схемы автоматически проносятся через граф синтеза (путем
обновления наследованных конституент). Формальные определения и конвенции наследованных конституент можно
редактировать только путем изменения{' '}
<span className='text-nowrap'>
<IconPredecessor className='inline-icon' /> <b>исходных конституент</b>.
</span>
</p>
<p>
Изменения на уровне концептуальной схемы (добавление/удаление/изменение) конституенты приводят к автоматическому
созданию / удаление / обновлению наследованных конституент. Если удаляемые конституенты находятся в таблице
отождествлений одной из операций, то такие отождествления <u>будут автоматические отменены</u>.
</p>
<p>
Удаление концептуальной схемы, привязанной к операции приводит к автоматическому удалению всех наследованных
конституент. В дальнейшем можно повторно выполнить как операцию загрузки, так и синтез. Однако дописанные
конституенты и отмененные отождествления <u>восстановлены не будут</u>.
</p>
<p>
При изменении аргументов операции синтеза в случае наличия привязанной схемы соответствующие конституенты
аргументов будут автоматически добавлены / удалены. Таблицы отождествлений будут соответствующим образом
скорректированы так, чтобы не использовать удаленные конституенты.
</p>
<p>
Удаление операции возможно для операций Загрузка без ограничений и для Синтеза в случае, когда операция не
является аргументом другой операции. При удалении операции можно выбрать опцию "удалить схему", чтобы удалить
концептуальную схему из базы портала. Также можно выбрать опцию "сохранить конституенты", в результате которой
наследованные конституенты в операциях ниже по графу станут исходными.
</p>
</div>
);
}
export default HelpConceptPropagation;

View File

@ -42,6 +42,10 @@ function HelpOssGraph() {
<IconAnimation className='inline-icon' />
<IconAnimationOff className='inline-icon' /> Анимация
</li>
<li>черта сверху - Загрузка</li>
<li>
черта слева - КС <LinkTopic text='внешняя' topic={HelpTopic.CC_OSS} />
</li>
</div>
<Divider vertical margins='mx-3 mt-3' className='hidden sm:block' />

View File

@ -59,10 +59,10 @@ function HelpRSGraphTerm() {
<IconEdit className='inline-icon' /> Двойной клик редактирование
</li>
<li>
<IconDestroy className='inline-icon' /> Delete удалить выбранные
<IconDestroy className='inline-icon icon-red' /> Delete удалить выбранные
</li>
<li>
<IconNewItem className='inline-icon' /> Новая со ссылками на выделенные
<IconNewItem className='inline-icon icon-green' /> Новая со ссылками на выделенные
</li>
</div>
</div>
@ -85,7 +85,7 @@ function HelpRSGraphTerm() {
<IconImage className='inline-icon' /> Сохранить в формат PNG
</li>
<li>
* <LinkTopic text='наследованные' topic={HelpTopic.CC_OSS} /> в ОСС
* <LinkTopic text='наследованные' topic={HelpTopic.CC_PROPAGATION} /> в ОСС
</li>
</div>

View File

@ -1,66 +1,14 @@
import { Handle, Position } from 'reactflow';
import { IconRSForm } from '@/components/Icons';
import TooltipOperation from '@/components/info/TooltipOperation';
import MiniButton from '@/components/ui/MiniButton.tsx';
import Overlay from '@/components/ui/Overlay';
import { OssNodeInternal } from '@/models/miscellaneous';
import { PARAMETER, prefixes } from '@/utils/constants';
import { truncateToLastWord } from '@/utils/utils';
import { useOssEdit } from '../OssEditContext';
import NodeCore from './NodeCore';
function InputNode(node: OssNodeInternal) {
const controller = useOssEdit();
const hasFile = !!node.data.operation.result;
const longLabel = node.data.label.length > PARAMETER.ossLongLabel;
const labelText = truncateToLastWord(node.data.label, PARAMETER.ossTruncateLabel);
const handleOpenSchema = () => {
controller.openOperationSchema(Number(node.id));
};
return (
<>
<NodeCore node={node} />
<Handle type='source' position={Position.Bottom} />
<Overlay position='top-0 right-0' className='flex p-[0.1rem]'>
<MiniButton
icon={<IconRSForm className={hasFile ? 'clr-text-green' : 'clr-text-red'} size='0.75rem' />}
noHover
noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'}
hideTitle={!controller.showTooltip}
onClick={() => {
handleOpenSchema();
}}
disabled={!hasFile}
/>
</Overlay>
{!node.data.operation.is_owned ? (
<Overlay position='left-[0.2rem] top-[0.1rem]'>
<div className='border rounded-none clr-input h-[1.3rem]'></div>
</Overlay>
) : null}
<div id={`${prefixes.operation_list}${node.id}`} className='h-[34px] w-[144px] flex items-center justify-center'>
<div
className='text-center'
style={{
fontSize: longLabel ? '12px' : '14px',
lineHeight: longLabel ? '16px' : '20px',
paddingLeft: '4px',
paddingRight: longLabel ? '10px' : '4px'
}}
>
{labelText}
</div>
{controller.showTooltip && !node.dragging ? (
<TooltipOperation anchor={`#${prefixes.operation_list}${node.id}`} node={node} />
) : null}
</div>
</>
);
}

View File

@ -0,0 +1,85 @@
'use client';
import { IconConsolidation, IconRSForm } from '@/components/Icons';
import TooltipOperation from '@/components/info/TooltipOperation';
import MiniButton from '@/components/ui/MiniButton.tsx';
import Overlay from '@/components/ui/Overlay';
import { OssNodeInternal } from '@/models/miscellaneous';
import { OperationType } from '@/models/oss';
import { PARAMETER, prefixes } from '@/utils/constants';
import { truncateToLastWord } from '@/utils/utils';
import { useOssEdit } from '../OssEditContext';
interface NodeCoreProps {
node: OssNodeInternal;
}
function NodeCore({ node }: NodeCoreProps) {
const controller = useOssEdit();
const hasFile = !!node.data.operation.result;
const longLabel = node.data.label.length > PARAMETER.ossLongLabel;
const labelText = truncateToLastWord(node.data.label, PARAMETER.ossTruncateLabel);
const handleOpenSchema = () => {
controller.openOperationSchema(Number(node.id));
};
return (
<>
<Overlay position='top-0 right-0' className='flex flex-col gap-1 p-[2px]'>
<MiniButton
icon={<IconRSForm className={hasFile ? 'clr-text-green' : 'clr-text-red'} size='12px' />}
noHover
noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'}
hideTitle={!controller.showTooltip}
onClick={handleOpenSchema}
disabled={!hasFile}
/>
{node.data.operation.is_consolidation ? (
<MiniButton
icon={<IconConsolidation className='clr-text-primary' size='12px' />}
disabled
noPadding
noHover
titleHtml='<b>Внимание!</b><br />Ромбовидный синтез</br/>Возможны дубликаты конституент'
hideTitle={!controller.showTooltip}
/>
) : null}
</Overlay>
{node.data.operation.operation_type === OperationType.INPUT ? (
<Overlay position='top-[1px] right-1/2 translate-x-1/2' className='flex'>
<div className='border-t w-[30px]'></div>
</Overlay>
) : null}
{!node.data.operation.is_owned ? (
<Overlay position='left-[2px] top-[6px]'>
<div className='border-r rounded-none clr-input h-[22px]'></div>
</Overlay>
) : null}
<div id={`${prefixes.operation_list}${node.id}`} className='h-[34px] w-[144px] flex items-center justify-center'>
<div
className='text-center'
style={{
fontSize: longLabel ? '12px' : '14px',
lineHeight: longLabel ? '16px' : '20px',
paddingLeft: '4px',
paddingRight: longLabel ? '10px' : '4px'
}}
>
{labelText}
</div>
{controller.showTooltip && !node.dragging ? (
<TooltipOperation anchor={`#${prefixes.operation_list}${node.id}`} node={node} />
) : null}
</div>
</>
);
}
export default NodeCore;

View File

@ -2,78 +2,17 @@
import { Handle, Position } from 'reactflow';
import { IconConsolidation, IconRSForm } from '@/components/Icons';
import TooltipOperation from '@/components/info/TooltipOperation';
import MiniButton from '@/components/ui/MiniButton.tsx';
import Overlay from '@/components/ui/Overlay';
import { OssNodeInternal } from '@/models/miscellaneous';
import { PARAMETER, prefixes } from '@/utils/constants';
import { truncateToLastWord } from '@/utils/utils';
import { useOssEdit } from '../OssEditContext';
import NodeCore from './NodeCore';
function OperationNode(node: OssNodeInternal) {
const controller = useOssEdit();
const hasFile = !!node.data.operation.result;
const longLabel = node.data.label.length > PARAMETER.ossLongLabel;
const labelText = truncateToLastWord(node.data.label, PARAMETER.ossTruncateLabel);
const handleOpenSchema = () => {
controller.openOperationSchema(Number(node.id));
};
return (
<>
<Handle type='source' position={Position.Bottom} />
<Overlay position='top-0 right-0' className='flex flex-col gap-1 p-[0.1rem]'>
<MiniButton
icon={<IconRSForm className={hasFile ? 'clr-text-green' : 'clr-text-red'} size='0.75rem' />}
noHover
noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'}
hideTitle={!controller.showTooltip}
onClick={handleOpenSchema}
disabled={!hasFile}
/>
{node.data.operation.is_consolidation ? (
<MiniButton
icon={<IconConsolidation className='clr-text-primary' size='0.75rem' />}
disabled
noPadding
noHover
titleHtml='<b>Внимание!</b><br />Ромбовидный синтез</br/>Возможны дубликаты конституент'
hideTitle={!controller.showTooltip}
/>
) : null}
</Overlay>
{!node.data.operation.is_owned ? (
<Overlay position='left-[0.2rem] top-[0.1rem]'>
<div className='border rounded-none clr-input h-[1.3rem]'></div>
</Overlay>
) : null}
<div id={`${prefixes.operation_list}${node.id}`} className='h-[34px] w-[144px] flex items-center justify-center'>
<div
className='px-1 text-center'
style={{
fontSize: longLabel ? '12px' : '14px',
lineHeight: longLabel ? '16px' : '20px',
paddingLeft: '4px',
paddingRight: longLabel ? '10px' : '4px'
}}
>
{labelText}
</div>
{controller.showTooltip && !node.dragging ? (
<TooltipOperation anchor={`#${prefixes.operation_list}${node.id}`} node={node} />
) : null}
</div>
<Handle type='target' position={Position.Top} id='left' style={{ left: 40 }} />
<Handle type='target' position={Position.Top} id='right' style={{ right: 40, left: 'auto' }} />
<NodeCore node={node} />
<Handle type='source' position={Position.Bottom} />
</>
);
}

View File

@ -383,6 +383,7 @@ export function labelHelpTopic(topic: HelpTopic): string {
case HelpTopic.CC_RELATIONS: return 'Связи понятий';
case HelpTopic.CC_SYNTHESIS: return 'Синтез схем';
case HelpTopic.CC_OSS: return 'Операционная схема';
case HelpTopic.CC_PROPAGATION: return 'Сквозные изменения';
case HelpTopic.RSLANG: return 'Экспликация';
case HelpTopic.RSL_TYPES: return 'Типизация';
@ -430,7 +431,8 @@ export function describeHelpTopic(topic: HelpTopic): string {
case HelpTopic.CC_CONSTITUENTA: return 'понятия конституенты и ее атрибутов';
case HelpTopic.CC_RELATIONS: return 'отношения между конституентами';
case HelpTopic.CC_SYNTHESIS: return 'операция синтеза концептуальных схем';
case HelpTopic.CC_OSS: return 'операционная схема синтеза <br/>и протаскивание изменений';
case HelpTopic.CC_OSS: return 'операционная схема синтеза';
case HelpTopic.CC_PROPAGATION: return 'протаскивание изменений в ОСС';
case HelpTopic.RSLANG: return 'экспликация и язык родов структур';
case HelpTopic.RSL_TYPES: return 'система типов в <br/>родоструктурной экспликации';