Small screen optimizations and help fix

This commit is contained in:
IRBorisov 2024-05-30 01:04:25 +03:00
parent 26991f460c
commit 64e1b028bc
12 changed files with 146 additions and 71 deletions

View File

@ -11,7 +11,7 @@ function ApplicationLayout() {
const { viewportHeight, mainHeight, showScroll } = useConceptOptions();
return (
<NavigationState>
<div className='min-w-[20rem] clr-app antialiased'>
<div className='min-w-[20rem] overflow-x-auto max-w-[100vw] clr-app antialiased'>
<ConceptToaster
className='mt-[4rem] text-sm' // prettier: split lines
autoClose={3000}
@ -23,7 +23,7 @@ function ApplicationLayout() {
<div
id={globals.main_scroll}
className='overflow-x-auto cc-scroll-y min-w-fit'
className='cc-scroll-y min-w-fit'
style={{
maxHeight: viewportHeight,
overflowY: showScroll ? 'scroll' : 'auto'

View File

@ -1,16 +1,21 @@
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/OptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import {
IconClone,
IconControls,
IconDestroy,
IconEdit,
IconList,
IconMoveDown,
IconMoveUp,
IconNewItem,
IconReset,
IconSave,
IconStatusOK,
IconText,
IconTree
} from '../../../components/Icons';
} from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/OptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
function HelpCstEditor() {
const { colors } = useConceptOptions();
@ -21,11 +26,23 @@ function HelpCstEditor() {
<IconSave className='inline-icon' /> сохранить изменения: Ctrl + S
</li>
<li>
<IconEdit className='inline-icon' /> кнопка переименования справа от{' '}
<LinkTopic text='Имени' topic={HelpTopic.CC_CONSTITUENTA} />
<IconReset className='inline-icon' /> сбросить несохраненные изменения
</li>
<li>
<IconClone className='inline-icon icon-green' /> клонировать текущую: Alt + V
</li>
<li>
<IconNewItem className='inline-icon icon-green' /> новая конституента
</li>
<li>
<IconDestroy className='inline-icon icon-red' /> удаление текущей
</li>
<h2>Термин и Текстовое определение</h2>
<li>
<IconEdit className='inline-icon' /> кнопка переименования справа от{' '}
<LinkTopic text='Имени' topic={HelpTopic.CC_CONSTITUENTA} />
</li>
<li>
<IconEdit className='inline-icon' /> кнопка редактирования словоформ справа от{' '}
<LinkTopic text='Термина' topic={HelpTopic.CC_CONSTITUENTA} />
@ -42,9 +59,6 @@ function HelpCstEditor() {
<li>
<IconControls className='inline-icon' /> специальная клавиатура и горячие клавиши
</li>
<li>
<IconList className='inline-icon' /> отображение списка конституент
</li>
<li>
<IconTree className='inline-icon' /> отображение{' '}
<LinkTopic text='дерева разбора' topic={HelpTopic.UI_FORMULA_TREE} />
@ -52,6 +66,13 @@ function HelpCstEditor() {
<li>Ctrl + Пробел дополняет до незанятого имени</li>
<h2>Список конституент</h2>
<li>
<IconList className='inline-icon' /> отображение списка конституент
</li>
<li>
<IconMoveDown className='inline-icon' />
<IconMoveUp className='inline-icon' /> Alt + вверх/вниз перемещение
</li>
<li>фильтрация в верхней части</li>
<li>при наведении на имя конституенты отображаются атрибуты</li>
<li>

View File

@ -2,7 +2,16 @@ import InfoCstStatus from '@/components/info/InfoCstStatus';
import Divider from '@/components/ui/Divider';
import { HelpTopic } from '@/models/miscellaneous';
import { IconAlias, IconDestroy, IconMoveDown, IconMoveUp, IconOpenList, IconReset } from '../../../components/Icons';
import {
IconAlias,
IconClone,
IconDestroy,
IconMoveDown,
IconMoveUp,
IconNewItem,
IconOpenList,
IconReset
} from '../../../components/Icons';
import LinkTopic from '../../../components/ui/LinkTopic';
function HelpRSFormItems() {
@ -26,11 +35,18 @@ function HelpRSFormItems() {
<IconMoveUp className='inline-icon' />
<IconMoveDown className='inline-icon' /> Alt + вверх/вниз перемещение
</li>
<li>
<IconDestroy className='inline-icon icon-red' /> удаление: Delete
<IconClone className='inline-icon icon-green' /> клонировать выделенную: Alt + V
</li>
<li>
<IconOpenList className='inline-icon icon-green' /> добавление: Alt + 1-6,Q,W {' '}
<IconNewItem className='inline-icon icon-green' /> новая конституента: Alt + `
</li>
<li>
<IconOpenList className='inline-icon icon-green' /> быстрое добавление: Alt + 1-6,Q,W
</li>
<li>
<IconDestroy className='inline-icon icon-red' /> удаление выделенных: Delete
</li>
<Divider margins='my-2' />

View File

@ -1,4 +1,14 @@
import { IconClone, IconDestroy, IconMoveDown, IconMoveUp, IconNewItem, IconReset, IconSave } from '@/components/Icons';
import {
IconClone,
IconDestroy,
IconList,
IconListOff,
IconMoveDown,
IconMoveUp,
IconNewItem,
IconReset,
IconSave
} from '@/components/Icons';
import BadgeHelp from '@/components/info/BadgeHelp';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
@ -8,6 +18,7 @@ import { messages, prepareTooltip } from '@/utils/labels';
interface ConstituentaToolbarProps {
disabled: boolean;
modified: boolean;
showList: boolean;
onSubmit: () => void;
onReset: () => void;
@ -17,18 +28,22 @@ interface ConstituentaToolbarProps {
onDelete: () => void;
onClone: () => void;
onCreate: () => void;
onToggleList: () => void;
}
function ConstituentaToolbar({
disabled,
modified,
showList,
onSubmit,
onReset,
onMoveUp,
onMoveDown,
onDelete,
onClone,
onCreate
onCreate,
onToggleList
}: ConstituentaToolbarProps) {
return (
<Overlay position='top-1 right-4' className='cc-icons sm:right-1/2 sm:translate-x-1/2'>
@ -62,6 +77,11 @@ function ConstituentaToolbar({
onClick={onDelete}
icon={<IconDestroy size='1.25rem' className='icon-red' />}
/>
<MiniButton
title='Отображение списка конституент'
icon={showList ? <IconList size='1.25rem' className='icon-primary' /> : <IconListOff size='1.25rem' />}
onClick={onToggleList}
/>
<MiniButton
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
icon={<IconMoveUp size='1.25rem' className='icon-primary' />}

View File

@ -18,7 +18,7 @@ interface ControlsOverlayProps {
function ControlsOverlay({ constituenta, disabled, modified, processing, onRename, onEditTerm }: ControlsOverlayProps) {
return (
<Overlay position='top-1 left-[4.3rem]' className='flex select-none'>
<Overlay position='top-1 left-[4.7rem]' className='flex select-none'>
{!disabled || processing ? (
<MiniButton
title={modified ? messages.unsaved : `Редактировать словоформы термина`}

View File

@ -81,6 +81,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
<ConstituentaToolbar
disabled={disabled}
modified={isModified}
showList={showList}
onMoveUp={controller.moveUp}
onMoveDown={controller.moveDown}
onSubmit={initiateSubmit}
@ -88,6 +89,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
onDelete={controller.deleteCst}
onClone={controller.cloneCst}
onCreate={() => controller.createCst(activeCst?.cst_type, false)}
onToggleList={() => setShowList(prev => !prev)}
/>
) : null}
<div
@ -101,12 +103,10 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
>
<FormConstituenta
disabled={disabled}
showList={showList}
id={globals.constituenta_editor}
state={activeCst}
isModified={isModified}
toggleReset={toggleReset}
onToggleList={() => setShowList(prev => !prev)}
setIsModified={setIsModified}
onEditTerm={controller.editTermForms}
onRename={controller.renameCst}

View File

@ -25,7 +25,6 @@ export const ROW_SIZE_IN_CHARACTERS = 70;
interface FormConstituentaProps {
disabled: boolean;
showList: boolean;
id?: string;
state?: IConstituenta;
@ -34,14 +33,12 @@ interface FormConstituentaProps {
toggleReset: boolean;
setIsModified: React.Dispatch<React.SetStateAction<boolean>>;
onToggleList: () => void;
onRename: () => void;
onEditTerm: () => void;
}
function FormConstituenta({
disabled,
showList,
id,
state,
@ -50,8 +47,7 @@ function FormConstituenta({
toggleReset,
onRename,
onEditTerm,
onToggleList
onEditTerm
}: FormConstituentaProps) {
const { schema, cstUpdate, processing } = useRSForm();
@ -138,7 +134,7 @@ function FormConstituenta({
/>
<form
id={id}
className={clsx('cc-column', 'mt-1 w-full md:w-[47.8rem] shrink-0', 'px-4 py-1')}
className={clsx('cc-column', 'mt-1 w-full md:w-[48.8rem] shrink-0', 'px-6 py-1')}
onSubmit={handleSubmit}
>
<RefsInput
@ -183,10 +179,8 @@ function FormConstituenta({
}
value={expression}
activeCst={state}
showList={showList}
disabled={disabled}
toggleReset={toggleReset}
onToggleList={onToggleList}
onChange={newValue => setExpression(newValue)}
setTypification={setTypification}
/>

View File

@ -5,13 +5,10 @@ import { AnimatePresence } from 'framer-motion';
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { toast } from 'react-toastify';
import { IconControls, IconList, IconListOff, IconText, IconTextOff, IconTree } from '@/components/Icons';
import BadgeHelp from '@/components/info/BadgeHelp';
import RSInput from '@/components/RSInput';
import { RSTextWrapper } from '@/components/RSInput/textEditing';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
import { useConceptOptions } from '@/context/OptionsContext';
import { useRSForm } from '@/context/RSFormContext';
import DlgShowAST from '@/dialogs/DlgShowAST';
import useCheckExpression from '@/hooks/useCheckExpression';
@ -24,6 +21,7 @@ import { TokenID } from '@/models/rslang';
import { storage } from '@/utils/constants';
import { labelTypification } from '@/utils/labels';
import ExpressionToolbar from './ExpressionToolbar';
import ParsingResult from './ParsingResult';
import RSEditorControls from './RSEditControls';
import StatusBar from './StatusBar';
@ -37,11 +35,9 @@ interface EditorRSExpressionProps {
disabled?: boolean;
toggleReset?: boolean;
showList: boolean;
setTypification: (typification: string) => void;
onChange: (newValue: string) => void;
onToggleList: () => void;
}
function EditorRSExpression({
@ -49,14 +45,11 @@ function EditorRSExpression({
disabled,
value,
toggleReset,
showList,
setTypification,
onChange,
onToggleList,
...restProps
}: EditorRSExpressionProps) {
const model = useRSForm();
const { mathFont, setMathFont } = useConceptOptions();
const [isModified, setIsModified] = useState(false);
const parser = useCheckExpression({ schema: model.schema });
@ -147,10 +140,6 @@ function EditorRSExpression({
});
}
function toggleFont() {
setMathFont(mathFont === 'math' ? 'math2' : 'math');
}
const controls = useMemo(
() => (
<RSEditorControls
@ -170,32 +159,12 @@ function EditorRSExpression({
) : null}
</AnimatePresence>
<Overlay position='top-[-0.5rem] right-0 cc-icons'>
<MiniButton
title='Изменить шрифт'
onClick={toggleFont}
icon={
mathFont === 'math' ? <IconText size='1.25rem' className='icon-primary' /> : <IconTextOff size='1.25rem' />
}
<ExpressionToolbar
disabled={disabled}
showControls={showControls}
showAST={handleShowAST}
toggleControls={() => setShowControls(prev => !prev)}
/>
{!disabled || model.processing ? (
<MiniButton
title='Отображение специальной клавиатуры'
icon={<IconControls size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
onClick={() => setShowControls(prev => !prev)}
/>
) : null}
<MiniButton
title='Отображение списка конституент'
icon={showList ? <IconList size='1.25rem' className='icon-primary' /> : <IconListOff size='1.25rem' />}
onClick={onToggleList}
/>
<MiniButton
title='Дерево разбора выражения'
onClick={handleShowAST}
icon={<IconTree size='1.25rem' className='icon-primary' />}
/>
</Overlay>
<Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'>
<StatusBar

View File

@ -0,0 +1,48 @@
import { IconControls, IconText, IconTextOff, IconTree } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
import { useConceptOptions } from '@/context/OptionsContext';
import { useRSForm } from '@/context/RSFormContext';
interface ExpressionToolbarProps {
disabled?: boolean;
showControls: boolean;
toggleControls: () => void;
showAST: () => void;
}
function ExpressionToolbar({ disabled, showControls, toggleControls, showAST }: ExpressionToolbarProps) {
const model = useRSForm();
const { mathFont, setMathFont } = useConceptOptions();
function toggleFont() {
setMathFont(mathFont === 'math' ? 'math2' : 'math');
}
return (
<Overlay position='top-[-0.5rem] right-0 cc-icons'>
<MiniButton
title='Изменить шрифт'
onClick={toggleFont}
icon={
mathFont === 'math' ? <IconText size='1.25rem' className='icon-primary' /> : <IconTextOff size='1.25rem' />
}
/>
{!disabled || model.processing ? (
<MiniButton
title='Отображение специальной клавиатуры'
icon={<IconControls size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
onClick={toggleControls}
/>
) : null}
<MiniButton
title='Дерево разбора выражения'
onClick={showAST}
icon={<IconTree size='1.25rem' className='icon-primary' />}
/>
</Overlay>
);
}
export default ExpressionToolbar;

View File

@ -1,3 +1,4 @@
import clsx from 'clsx';
import { motion } from 'framer-motion';
import { TokenID } from '@/models/rslang';
@ -90,7 +91,13 @@ interface RSEditorControlsProps {
function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
return (
<motion.div
className='flex-wrap text-xs select-none sm:text-sm divide-solid'
className={clsx(
'max-w-[38.5rem] sm:max-w-[40rem] sm:min-w-[40rem] md:max-w-fit mx-1 sm:mx-0',
'flex-wrap',
'divide-solid',
'text-xs md:text-sm',
'select-none'
)}
initial={false}
animate={isOpen ? 'open' : 'closed'}
variants={animateRSControl}

View File

@ -26,8 +26,8 @@ function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps) {
'font-math',
'cursor-pointer disabled:cursor-default',
{
'w-[3.4rem] sm:w-[4.5rem]': label.length > 3,
'w-[1.7rem] sm:w-[2.25rem]': label.length <= 3
'w-[3.7rem] md:w-[4.5rem]': label.length > 3,
'w-[1.85rem] md:w-[2.25rem]': label.length <= 3
}
)}
data-tooltip-id={globals.tooltip}

View File

@ -30,7 +30,7 @@ function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit
const table = useMemo(
() => (
<ConstituentsTable
maxHeight={isBottom ? '12rem' : calculateHeight('8.2rem')}
maxHeight={isBottom ? calculateHeight('42rem') : calculateHeight('8.2rem')}
items={filteredData}
activeCst={activeCst}
onOpenEdit={onOpenEdit}
@ -46,7 +46,7 @@ function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit
'border overflow-hidden', // prettier: split-lines
{
'mt-[2.2rem] rounded-l-md rounded-r-none': !isBottom, // prettier: split-lines
'mt-3 mx-6 rounded-md': isBottom
'mt-3 mx-6 rounded-md md:w-[45.8rem]': isBottom
}
)}
initial={{ ...animateSideView.initial }}