Refactor and optimize dialogs

This commit is contained in:
IRBorisov 2023-12-07 01:21:27 +03:00
parent 38b661f290
commit eab63814d5
20 changed files with 196 additions and 164 deletions

View File

@ -9,7 +9,7 @@ extends Omit<React.DetailedHTMLProps<LabelHTMLAttributes<HTMLLabelElement>, HTML
function Label({ text, tooltip, className, ...restProps }: LabelProps) { function Label({ text, tooltip, className, ...restProps }: LabelProps) {
return ( return (
<label <label
className={`text-sm font-semibold ${className} whitespace-nowrap`} className={`text-sm font-semibold whitespace-nowrap ${className}`}
title={tooltip} title={tooltip}
{...restProps} {...restProps}
> >

View File

@ -16,12 +16,13 @@ export interface ModalProps {
onSubmit?: () => void onSubmit?: () => void
onCancel?: () => void onCancel?: () => void
children: React.ReactNode children: React.ReactNode
className?: string
} }
function Modal({ function Modal({
title, hideWindow, onSubmit, title, hideWindow, onSubmit,
readonly, onCancel, canSubmit, readonly, onCancel, canSubmit,
submitInvalidTooltip, submitInvalidTooltip, className,
children, children,
submitText = 'Продолжить' submitText = 'Продолжить'
}: ModalProps) { }: ModalProps) {
@ -42,9 +43,9 @@ function Modal({
<> <>
<div className='fixed top-0 left-0 w-full h-full z-navigation clr-modal-backdrop' /> <div className='fixed top-0 left-0 w-full h-full z-navigation clr-modal-backdrop' />
<div ref={ref} <div ref={ref}
className='fixed bottom-1/2 left-1/2 translate-y-1/2 -translate-x-1/2 px-6 w-fit max-w-[calc(100vw-2rem)] h-fit z-modal clr-app border shadow-md' className='fixed -translate-x-1/2 translate-y-1/2 border shadow-md bottom-1/2 left-1/2 z-modal clr-app'
> >
<Overlay position='right-[-1rem] top-2' className='text-disabled'> <Overlay position='right-[0.3rem] top-2' className='text-disabled'>
<MiniButton <MiniButton
tooltip='Закрыть диалоговое окно [ESC]' tooltip='Закрыть диалоговое окно [ESC]'
icon={<CrossIcon size={5}/>} icon={<CrossIcon size={5}/>}
@ -52,25 +53,32 @@ function Modal({
/> />
</Overlay> </Overlay>
{title ? <h1 className='my-2 text-lg select-none'>{title}</h1> : null} {title ? <h1 className='px-12 py-2 text-lg select-none'>{title}</h1> : null}
<div className='max-h-[calc(100vh-8rem)] overflow-auto flex flex-col justify-start '> <div
className={`w-full h-fit ${className}`}
style={{
maxHeight: 'calc(100vh - 8rem)',
maxWidth: 'calc(100vw - 2rem)',
overflow: 'auto'
}}
>
{children} {children}
</div> </div>
<div className='flex justify-center w-full gap-6 my-3 z-modal-controls'> <div className='flex justify-center w-full gap-12 px-6 py-3 z-modal-controls min-w-fit'>
{!readonly ? {!readonly ?
<Button autoFocus <Button autoFocus
text={submitText} text={submitText}
tooltip={!canSubmit ? submitInvalidTooltip: ''} tooltip={!canSubmit ? submitInvalidTooltip: ''}
dimensions='min-w-[8rem] min-h-[2.6rem] w-fit h-fit' dimensions='min-w-[8rem] min-h-[2.6rem]'
colors='clr-btn-primary' colors='clr-btn-primary'
disabled={!canSubmit} disabled={!canSubmit}
onClick={handleSubmit} onClick={handleSubmit}
/> : null} /> : null}
<Button <Button
text={readonly ? 'Закрыть' : 'Отмена'} text={readonly ? 'Закрыть' : 'Отмена'}
dimensions='min-w-[8rem] min-h-[2.6rem] w-fit h-fit' dimensions='min-w-[8rem] min-h-[2.6rem]'
onClick={handleCancel} onClick={handleCancel}
/> />
</div> </div>

View File

@ -25,7 +25,8 @@ function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>
control: (styles, { isDisabled }) => ({ control: (styles, { isDisabled }) => ({
...styles, ...styles,
borderRadius: '0.25rem', borderRadius: '0.25rem',
cursor: isDisabled ? 'not-allowed' : 'pointer' cursor: isDisabled ? 'not-allowed' : 'pointer',
boxShadow: 'none'
}), }),
option: (styles, { isSelected }) => ({ option: (styles, { isSelected }) => ({
...styles, ...styles,

View File

@ -25,7 +25,8 @@ function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option
control: (styles, { isDisabled }) => ({ control: (styles, { isDisabled }) => ({
...styles, ...styles,
borderRadius: '0.25rem', borderRadius: '0.25rem',
cursor: isDisabled ? 'not-allowed' : 'pointer' cursor: isDisabled ? 'not-allowed' : 'pointer',
boxShadow: 'none'
}), }),
menuPortal: (styles) => ({ menuPortal: (styles) => ({
...styles, ...styles,

View File

@ -87,7 +87,7 @@ function RSInput({
{ tag: tags.literal, color: colors.fgBlue }, // literals { tag: tags.literal, color: colors.fgBlue }, // literals
{ tag: tags.controlKeyword, fontWeight: '500'}, // R | I | D { tag: tags.controlKeyword, fontWeight: '500'}, // R | I | D
{ tag: tags.unit, fontSize: '0.75rem' }, // indicies { tag: tags.unit, fontSize: '0.75rem' }, // indicies
{ tag: tags.brace, color:colors.fgPurple, fontWeight: '500' }, // braces (curly brackets) { tag: tags.brace, color:colors.fgPurple, fontWeight: '700' }, // braces (curly brackets)
] ]
}), [disabled, colors, darkMode]); }), [disabled, colors, darkMode]);
@ -108,12 +108,14 @@ function RSInput({
if (event.altKey) { if (event.altKey) {
if (text.processAltKey(event.code, event.shiftKey)) { if (text.processAltKey(event.code, event.shiftKey)) {
event.preventDefault(); event.preventDefault();
event.stopPropagation();
} }
} else if (!event.ctrlKey) { } else if (!event.ctrlKey) {
const newSymbol = getSymbolSubstitute(event.code, event.shiftKey); const newSymbol = getSymbolSubstitute(event.code, event.shiftKey);
if (newSymbol) { if (newSymbol) {
text.replaceWith(newSymbol); text.replaceWith(newSymbol);
event.preventDefault(); event.preventDefault();
event.stopPropagation();
} }
} }
}, [thisRef]); }, [thisRef]);

View File

@ -60,8 +60,8 @@ function DlgCloneLibraryItem({ hideWindow, base }: DlgCloneLibraryItemProps) {
canSubmit={canSubmit} canSubmit={canSubmit}
submitText='Создать' submitText='Создать'
onSubmit={handleSubmit} onSubmit={handleSubmit}
className='flex flex-col gap-3 px-6 py-2'
> >
<div className='flex flex-col gap-3'>
<TextInput <TextInput
label='Полное название' label='Полное название'
value={title} value={title}
@ -83,7 +83,6 @@ function DlgCloneLibraryItem({ hideWindow, base }: DlgCloneLibraryItemProps) {
value={common} value={common}
setValue={value => setCommon(value)} setValue={value => setCommon(value)}
/> />
</div>
</Modal>); </Modal>);
} }

View File

@ -114,33 +114,35 @@ function DlgConstituentaTemplate({ hideWindow, schema, onCreate, insertAfter }:
canSubmit={validated} canSubmit={validated}
onSubmit={handleSubmit} onSubmit={handleSubmit}
submitText='Создать' submitText='Создать'
className='max-w-[43rem] min-w-[43rem] min-h-[35rem] px-6'
> >
<Tabs defaultFocus forceRenderTabPanel <Tabs defaultFocus forceRenderTabPanel
className='flex flex-col items-center max-w-[40rem] min-w-[40rem] min-h-[35rem] mb-1'
selectedTabClassName='clr-selected' selectedTabClassName='clr-selected'
selectedIndex={activeTab} selectedIndex={activeTab}
onSelect={setActiveTab} onSelect={setActiveTab}
> >
<Overlay position='top-0 left-[12.3rem]'> <Overlay position='top-0 right-[6rem]'>
<HelpButton topic={HelpTopic.RSTEMPLATES} dimensions='max-w-[35rem]' /> <HelpButton topic={HelpTopic.RSTEMPLATES} dimensions='max-w-[35rem]' />
</Overlay> </Overlay>
<TabList className='flex mb-3 border'> <TabList className='flex justify-center mb-3'>
<ConceptTab <div className='flex border w-fit'>
label='Шаблон' <ConceptTab
tooltip='Выбор шаблона выражения' label='Шаблон'
className='border-r w-[8rem]' tooltip='Выбор шаблона выражения'
/> className='border-r w-[8rem]'
<ConceptTab />
label='Аргументы' <ConceptTab
tooltip='Подстановка аргументов шаблона' label='Аргументы'
className='border-r w-[8rem]' tooltip='Подстановка аргументов шаблона'
/> className='border-r w-[8rem]'
<ConceptTab />
label='Конституента' <ConceptTab
tooltip='Редактирование атрибутов конституенты' label='Конституента'
className='w-[8rem]' tooltip='Редактирование атрибутов конституенты'
/> className='w-[8rem]'
/>
</div>
</TabList> </TabList>
<div className='w-full'> <div className='w-full'>

View File

@ -20,7 +20,6 @@ extends Pick<ModalProps, 'hideWindow'> {
function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) { function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstProps) {
const [validated, setValidated] = useState(false); const [validated, setValidated] = useState(false);
const [cstData, updateCstData] = usePartialUpdate( const [cstData, updateCstData] = usePartialUpdate(
initial || { initial || {
cst_type: CstType.BASE, cst_type: CstType.BASE,
@ -53,51 +52,51 @@ function DlgCreateCst({ hideWindow, initial, schema, onCreate }: DlgCreateCstPro
canSubmit={validated} canSubmit={validated}
onSubmit={handleSubmit} onSubmit={handleSubmit}
submitText='Создать' submitText='Создать'
className='h-fit min-w-[35rem] py-2 flex flex-col justify-stretch gap-3 px-6'
> >
<div className='h-fit w-[35rem] px-2 my-2 flex flex-col justify-stretch gap-3'>
<div className='flex justify-center w-full gap-6'> <div className='flex justify-center w-full gap-6'>
<SelectSingle <SelectSingle
className='min-w-[15rem] self-center'
placeholder='Выберите тип' placeholder='Выберите тип'
className='min-w-[15rem] self-center'
options={SelectorCstType} options={SelectorCstType}
value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }} value={{ value: cstData.cst_type, label: labelCstType(cstData.cst_type) }}
onChange={data => updateCstData({ cst_type: data?.value ?? CstType.BASE})} onChange={data => updateCstData({ cst_type: data?.value ?? CstType.BASE})}
/> />
<TextInput id='alias' label='Имя' <TextInput dense
dense label='Имя'
dimensions='w-[7rem]' dimensions='w-[7rem]'
value={cstData.alias} value={cstData.alias}
onChange={event => updateCstData({ alias: event.target.value})} onChange={event => updateCstData({ alias: event.target.value})}
/> />
</div> </div>
<TextArea id='term' label='Термин' <TextArea spellCheck
label='Термин'
placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение' placeholder='Схемный или предметный термин, обозначающий данное понятие или утверждение'
rows={2} rows={2}
value={cstData.term_raw} value={cstData.term_raw}
spellCheck
onChange={event => updateCstData({ term_raw: event.target.value })} onChange={event => updateCstData({ term_raw: event.target.value })}
/> />
<RSInput id='expression' label='Формальное определение' <RSInput
label='Формальное определение'
placeholder='Родоструктурное выражение, задающее формальное определение' placeholder='Родоструктурное выражение, задающее формальное определение'
height='5.1rem' height='5.1rem'
value={cstData.definition_formal} value={cstData.definition_formal}
onChange={value => updateCstData({definition_formal: value})} onChange={value => updateCstData({definition_formal: value})}
/> />
<TextArea id='definition' label='Текстовое определение' <TextArea spellCheck
label='Текстовое определение'
placeholder='Лингвистическая интерпретация формального выражения' placeholder='Лингвистическая интерпретация формального выражения'
rows={2} rows={2}
value={cstData.definition_raw} value={cstData.definition_raw}
spellCheck
onChange={event => updateCstData({ definition_raw: event.target.value })} onChange={event => updateCstData({ definition_raw: event.target.value })}
/> />
<TextArea id='convention' label='Конвенция / Комментарий' <TextArea spellCheck
label='Конвенция / Комментарий'
placeholder='Договоренность об интерпретации или пояснение' placeholder='Договоренность об интерпретации или пояснение'
rows={2} rows={2}
value={cstData.convention} value={cstData.convention}
spellCheck
onChange={event => updateCstData({ convention: event.target.value })} onChange={event => updateCstData({ convention: event.target.value })}
/> />
</div>
</Modal>); </Modal>);
} }

View File

@ -1,69 +0,0 @@
import { useMemo, useState } from 'react';
import Checkbox from '../components/Common/Checkbox';
import Modal, { ModalProps } from '../components/Common/Modal';
import { useRSForm } from '../context/RSFormContext';
import { prefixes } from '../utils/constants';
import { labelConstituenta } from '../utils/labels';
interface DlgDeleteCstProps
extends Pick<ModalProps, 'hideWindow'> {
selected: number[]
onDelete: (items: number[]) => void
}
function DlgDeleteCst({ hideWindow, selected, onDelete }: DlgDeleteCstProps) {
const { schema } = useRSForm();
const [expandOut, setExpandOut] = useState(false);
const expansion: number[] = useMemo(() => schema?.graph.expandOutputs(selected) ?? [], [selected, schema?.graph]);
function handleSubmit() {
hideWindow();
if (expandOut) {
onDelete(selected.concat(expansion));
} else {
onDelete(selected);
}
}
return (
<Modal canSubmit
title='Удаление конституент'
submitText={expandOut ? 'Удалить с зависимыми' : 'Удалить'}
hideWindow={hideWindow}
onSubmit={handleSubmit}
>
<div className='max-w-[60vw] min-w-[30rem]'>
<p>Выбраны к удалению: <b>{selected.length}</b></p>
<div className='px-3 border h-[9rem] mt-1 overflow-y-auto whitespace-nowrap'>
{selected.map(
(id) => {
const cst = schema!.items.find(cst => cst.id === id);
return (cst ?
<p key={`${prefixes.cst_delete_list}${cst.id}`}>
{labelConstituenta(cst)}
</p> : null);
})}
</div>
<p className='mt-4'>Зависимые конституенты: <b>{expansion.length}</b></p>
<div className='mt-1 mb-3 px-3 border h-[9rem] overflow-y-auto whitespace-nowrap'>
{expansion.map(
(id) => {
const cst = schema!.items.find(cst => cst.id === id);
return (cst ?
<p key={`${prefixes.cst_dependant_list}${cst.id}`}>
{labelConstituenta(cst)}
</p> : null);
})}
</div>
<Checkbox
label='Удалить зависимые конституенты'
value={expandOut}
setValue={value => setExpandOut(value)}
/>
</div>
</Modal>);
}
export default DlgDeleteCst;

View File

@ -0,0 +1,31 @@
import { IConstituenta } from '../../models/rsform';
import { labelConstituenta } from '../../utils/labels';
interface ConstituentsListProps {
list: number[]
items: IConstituenta[]
prefix: string
title?: string
}
function ConstituentsList({ list, items, title, prefix }: ConstituentsListProps) {
return (
<div>
{title ?
<p className='pb-1'>
{title}: <b>{list.length}</b>
</p> : null}
<div className='px-3 border h-[9rem] overflow-y-auto whitespace-nowrap'>
{list.map(
(id) => {
const cst = items.find(cst => cst.id === id);
return (cst ?
<p key={`${prefix}${cst.id}`}>
{labelConstituenta(cst)}
</p> : null);
})}
</div>
</div>);
}
export default ConstituentsList;

View File

@ -0,0 +1,57 @@
import { useMemo, useState } from 'react';
import Checkbox from '../../components/Common/Checkbox';
import Modal, { ModalProps } from '../../components/Common/Modal';
import { IRSForm } from '../../models/rsform';
import { prefixes } from '../../utils/constants';
import ConstituentsList from './ConstituentsList';
interface DlgDeleteCstProps
extends Pick<ModalProps, 'hideWindow'> {
selected: number[]
onDelete: (items: number[]) => void
schema: IRSForm
}
function DlgDeleteCst({ hideWindow, selected, schema, onDelete }: DlgDeleteCstProps) {
const [expandOut, setExpandOut] = useState(false);
const expansion: number[] = useMemo(() => schema.graph.expandOutputs(selected), [selected, schema.graph]);
function handleSubmit() {
hideWindow();
if (expandOut) {
onDelete(selected.concat(expansion));
} else {
onDelete(selected);
}
}
return (
<Modal canSubmit
title='Удаление конституент'
submitText={expandOut ? 'Удалить с зависимыми' : 'Удалить'}
hideWindow={hideWindow}
onSubmit={handleSubmit}
className='max-w-[60vw] min-w-[30rem] px-6 flex flex-col gap-3'
>
<ConstituentsList
title='Выбраны к удалению'
list={selected}
items={schema.items}
prefix={prefixes.cst_delete_list}
/>
<ConstituentsList
title='Зависимые конституенты'
list={expansion}
items={schema.items}
prefix={prefixes.cst_dependant_list}
/>
<Checkbox
label='Удалить зависимые конституенты'
value={expandOut}
setValue={value => setExpandOut(value)}
/>
</Modal>);
}
export default DlgDeleteCst;

View File

@ -0,0 +1 @@
export { default } from './DlgDeleteCst';

View File

@ -47,28 +47,30 @@ function DlgEditReference({ hideWindow, items, initial, onSave }: DlgEditReferen
hideWindow={hideWindow} hideWindow={hideWindow}
canSubmit={isValid} canSubmit={isValid}
onSubmit={handleSubmit} onSubmit={handleSubmit}
className='items-center min-w-[40rem] max-w-[40rem] px-6 min-h-[34rem]'
> >
<Tabs defaultFocus <Tabs defaultFocus
className='flex flex-col items-center min-w-[40rem] max-w-[40rem] mb-2 min-h-[34rem]'
selectedTabClassName='clr-selected' selectedTabClassName='clr-selected'
selectedIndex={activeTab} selectedIndex={activeTab}
onSelect={setActiveTab} onSelect={setActiveTab}
> >
<Overlay position='top-0 left-[12.2rem]'> <Overlay position='top-0 right-[4rem]'>
<HelpButton topic={HelpTopic.TERM_CONTROL} dimensions='max-w-[38rem]' offset={14} /> <HelpButton topic={HelpTopic.TERM_CONTROL} dimensions='max-w-[35rem]' offset={14} />
</Overlay> </Overlay>
<TabList className='flex mb-3 border'> <TabList className='flex justify-center mb-3'>
<ConceptTab <div className='flex border w-fit'>
label={labelReferenceType(ReferenceType.ENTITY)} <ConceptTab
tooltip='Отсылка на термин в заданной словоформе' label={labelReferenceType(ReferenceType.ENTITY)}
className='w-[12rem] border-r-2' tooltip='Отсылка на термин в заданной словоформе'
/> className='w-[12rem] border-r-2'
<ConceptTab />
label={labelReferenceType(ReferenceType.SYNTACTIC)} <ConceptTab
tooltip='Установление синтаксической связи с отсылкой на термин' label={labelReferenceType(ReferenceType.SYNTACTIC)}
className='w-[12rem]' tooltip='Установление синтаксической связи с отсылкой на термин'
/> className='w-[12rem]'
/>
</div>
</TabList> </TabList>
<div className='w-full'> <div className='w-full'>

View File

@ -10,15 +10,14 @@ interface WordformButtonProps {
function WordformButton({ text, example, grams, onSelectGrams, isSelected, ...restProps }: WordformButtonProps) { function WordformButton({ text, example, grams, onSelectGrams, isSelected, ...restProps }: WordformButtonProps) {
return ( return (
<button type='button' tabIndex={-1} <button type='button' tabIndex={-1}
onClick={() => onSelectGrams(grams)} onClick={() => onSelectGrams(grams)}
className={`min-w-[6rem] p-1 border rounded-none cursor-pointer clr-btn-clear clr-hover ${isSelected ? 'clr-selected': ''}`} className={`min-w-[6rem] p-1 border rounded-none cursor-pointer clr-btn-clear clr-hover ${isSelected ? 'clr-selected': ''}`}
{...restProps} {...restProps}
> >
<p className='font-semibold'>{text}</p> <p className='font-semibold'>{text}</p>
<p>{example}</p> <p>{example}</p>
</button> </button>);
);
} }
export default WordformButton; export default WordformButton;

View File

@ -1,5 +1,6 @@
import { useEffect, useLayoutEffect, useMemo, useState } from 'react'; import { useEffect, useLayoutEffect, useMemo, useState } from 'react';
import Label from '../components/Common/Label';
import MiniButton from '../components/Common/MiniButton'; import MiniButton from '../components/Common/MiniButton';
import Modal from '../components/Common/Modal'; import Modal from '../components/Common/Modal';
import Overlay from '../components/Common/Overlay'; import Overlay from '../components/Common/Overlay';
@ -210,28 +211,28 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
hideWindow={hideWindow} hideWindow={hideWindow}
submitText='Сохранить' submitText='Сохранить'
onSubmit={handleSubmit} onSubmit={handleSubmit}
className='min-w-[40rem] max-w-[40rem] px-6'
> >
<div className='min-w-[40rem] max-w-[40rem]'>
<Overlay position='top-[-0.2rem] left-[7.5rem]'> <Overlay position='top-[-0.2rem] left-[7.5rem]'>
<HelpButton topic={HelpTopic.TERM_CONTROL} dimensions='max-w-[38rem]' offset={3} /> <HelpButton topic={HelpTopic.TERM_CONTROL} dimensions='max-w-[38rem]' offset={3} />
</Overlay> </Overlay>
<TextArea disabled spellCheck <TextArea disabled spellCheck
label='Начальная форма' label='Начальная форма'
placeholder='Начальная форма' placeholder='Термин в начальной форме'
rows={1} rows={1}
value={term} value={term}
/> />
<div className='mt-3 mb-2 text-sm font-semibold'> <div className='mt-3 mb-2'>
Параметры словоформы <Label text='Параметры словоформы' />
</div> </div>
<div className='flex items-start justify-between w-full'> <div className='flex items-start justify-between w-full'>
<div className='flex items-center'> <div className='flex items-center'>
<TextArea <TextArea
placeholder='Введите текст' placeholder='Введите текст'
dimensions='min-w-[18rem] w-full min-h-[4.2rem]' dimensions='min-w-[18rem] w-full min-h-[5rem]'
rows={2} rows={2}
value={inputText} value={inputText}
onChange={event => setInputText(event.target.value)} onChange={event => setInputText(event.target.value)}
@ -309,7 +310,6 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
onRowClicked={handleRowClicked} onRowClicked={handleRowClicked}
/> />
</div> </div>
</div>
</Modal>); </Modal>);
} }

View File

@ -25,10 +25,10 @@ function DlgGraphParams({ hideWindow, initial, onConfirm } : DlgGraphParamsProps
title='Настройки графа термов' title='Настройки графа термов'
onSubmit={handleSubmit} onSubmit={handleSubmit}
submitText='Применить' submitText='Применить'
className='flex gap-12 px-6 py-2'
> >
<div className='flex gap-6 my-2'>
<div className='flex flex-col gap-1'> <div className='flex flex-col gap-1'>
<h1>Преобразования</h1> <h1 className='mb-2'>Преобразования</h1>
<Checkbox <Checkbox
label='Скрыть текст' label='Скрыть текст'
tooltip='Не отображать термины' tooltip='Не отображать термины'
@ -55,7 +55,7 @@ function DlgGraphParams({ hideWindow, initial, onConfirm } : DlgGraphParamsProps
/> />
</div> </div>
<div className='flex flex-col gap-1'> <div className='flex flex-col gap-1'>
<h1>Типы конституент</h1> <h1 className='mb-2'>Типы конституент</h1>
<Checkbox <Checkbox
label={labelCstType(CstType.BASE)} label={labelCstType(CstType.BASE)}
value={params.allowBase} value={params.allowBase}
@ -97,7 +97,6 @@ function DlgGraphParams({ hideWindow, initial, onConfirm } : DlgGraphParamsProps
setValue={value => updateParams({ allowTheorem: value})} setValue={value => updateParams({ allowTheorem: value})}
/> />
</div> </div>
</div>
</Modal>); </Modal>);
} }

View File

@ -47,8 +47,8 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
hideWindow={hideWindow} hideWindow={hideWindow}
canSubmit={validated} canSubmit={validated}
onSubmit={handleSubmit} onSubmit={handleSubmit}
className='flex justify-center items-center gap-6 w-full min-w-[24rem] py-6 px-6'
> >
<div className='flex justify-center items-center gap-6 w-full min-w-[22rem] my-3'>
<SelectSingle <SelectSingle
placeholder='Выберите тип' placeholder='Выберите тип'
className='min-w-[14rem] self-center' className='min-w-[14rem] self-center'
@ -67,7 +67,6 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
onChange={event => updateData({alias: event.target.value})} onChange={event => updateData({alias: event.target.value})}
/> />
</div> </div>
</div>
</Modal>); </Modal>);
} }

View File

@ -53,9 +53,9 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
, []); , []);
return ( return (
<Modal <Modal readonly
hideWindow={hideWindow} hideWindow={hideWindow}
readonly className='px-6'
> >
<div className='w-full my-2 text-lg text-center'> <div className='w-full my-2 text-lg text-center'>
{!hoverNode ? expression : null} {!hoverNode ? expression : null}

View File

@ -44,20 +44,20 @@ function DlgUploadRSForm({ hideWindow }: DlgUploadRSFormProps) {
canSubmit={!!file} canSubmit={!!file}
onSubmit={handleSubmit} onSubmit={handleSubmit}
submitText='Загрузить' submitText='Загрузить'
className='w-[20rem] px-6'
> >
<div className='flex flex-col items-start min-w-[20rem] max-w-[20rem]'> <FileInput
<FileInput label='Выбрать файл'
label='Выбрать файл' dimensions='w-full flex items-center'
acceptType={EXTEOR_TRS_FILE} acceptType={EXTEOR_TRS_FILE}
onChange={handleFile} onChange={handleFile}
/> />
<Checkbox <Checkbox
label='Загружать название и комментарий' label='Загружать название и комментарий'
dimensions='w-fit pb-2' dimensions='w-fit py-2'
value={loadMetadata} value={loadMetadata}
setValue={value => setLoadMetadata(value)} setValue={value => setLoadMetadata(value)}
/> />
</div>
</Modal>); </Modal>);
} }

View File

@ -362,6 +362,7 @@ function RSTabs() {
/> : null} /> : null}
{showDeleteCst ? {showDeleteCst ?
<DlgDeleteCst <DlgDeleteCst
schema={schema!}
hideWindow={() => setShowDeleteCst(false)} hideWindow={() => setShowDeleteCst(false)}
onDelete={handleDeleteCst} onDelete={handleDeleteCst}
selected={toBeDeleted} selected={toBeDeleted}