Minor UI fixes

This commit is contained in:
IRBorisov 2024-03-26 22:55:53 +03:00
parent 6a41ecd88c
commit 8a134557b6
9 changed files with 44 additions and 42 deletions

View File

@ -23,7 +23,7 @@ interface TemplateTabProps {
function TemplateTab({ state, partialUpdate }: TemplateTabProps) { function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
const { templates, retrieveTemplate } = useLibrary(); const { templates, retrieveTemplate } = useLibrary();
const [selectedSchema, setSelectedSchema] = useState<IRSForm | undefined>(undefined); const [category, setCategory] = useState<IRSForm | undefined>(undefined);
const [filteredData, setFilteredData] = useState<IConstituenta[]>([]); const [filteredData, setFilteredData] = useState<IConstituenta[]>([]);
@ -47,16 +47,16 @@ function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
); );
const categorySelector = useMemo((): { value: number; label: string }[] => { const categorySelector = useMemo((): { value: number; label: string }[] => {
if (!selectedSchema) { if (!category) {
return []; return [];
} }
return selectedSchema.items return category.items
.filter(cst => cst.cst_type === CATEGORY_CST_TYPE) .filter(cst => cst.cst_type === CATEGORY_CST_TYPE)
.map(cst => ({ .map(cst => ({
value: cst.id, value: cst.id,
label: cst.term_raw label: cst.term_raw
})); }));
}, [selectedSchema]); }, [category]);
useEffect(() => { useEffect(() => {
if (templates.length > 0 && !state.templateID) { if (templates.length > 0 && !state.templateID) {
@ -66,23 +66,22 @@ function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
useEffect(() => { useEffect(() => {
if (!state.templateID) { if (!state.templateID) {
setSelectedSchema(undefined); setCategory(undefined);
} else { } else {
retrieveTemplate(state.templateID, setSelectedSchema); retrieveTemplate(state.templateID, setCategory);
} }
}, [state.templateID, retrieveTemplate]); }, [state.templateID, retrieveTemplate]);
// Filter constituents
useEffect(() => { useEffect(() => {
if (!selectedSchema) { if (!category) {
return; return;
} }
let data = selectedSchema.items; let data = category.items;
if (state.filterCategory) { if (state.filterCategory) {
data = applyFilterCategory(state.filterCategory, selectedSchema); data = applyFilterCategory(state.filterCategory, category);
} }
setFilteredData(data); setFilteredData(data);
}, [state.filterCategory, selectedSchema]); }, [state.filterCategory, category]);
return ( return (
<> <>
@ -92,16 +91,14 @@ function TemplateTab({ state, partialUpdate }: TemplateTabProps) {
className='flex-grow border-none' className='flex-grow border-none'
options={categorySelector} options={categorySelector}
value={ value={
state.filterCategory && selectedSchema state.filterCategory && category
? { ? {
value: state.filterCategory.id, value: state.filterCategory.id,
label: state.filterCategory.term_raw label: state.filterCategory.term_raw
} }
: null : null
} }
onChange={data => onChange={data => partialUpdate({ filterCategory: category?.items.find(cst => cst.id === data?.value) })}
partialUpdate({ filterCategory: selectedSchema?.items.find(cst => cst.id === data?.value) })
}
isClearable isClearable
/> />
<SelectSingle <SelectSingle

View File

@ -8,7 +8,6 @@ import { IConstituenta, IRSForm } from './rsform';
* Create style name from {@link FontStyle}. * Create style name from {@link FontStyle}.
*/ */
export function getFontClassName(style: FontStyle): string { export function getFontClassName(style: FontStyle): string {
console.log(style);
return `font-${style}`; return `font-${style}`;
} }

View File

@ -233,7 +233,7 @@ export function isMockCst(cst: IConstituenta) {
*/ */
export function applyFilterCategory(start: IConstituenta, schema: IRSFormData): IConstituenta[] { export function applyFilterCategory(start: IConstituenta, schema: IRSFormData): IConstituenta[] {
const nextCategory = schema.items.find(cst => cst.order > start.order && cst.cst_type === CATEGORY_CST_TYPE); const nextCategory = schema.items.find(cst => cst.order > start.order && cst.cst_type === CATEGORY_CST_TYPE);
return schema.items.filter(cst => cst.order > start.order && (!nextCategory || cst.order <= nextCategory.order)); return schema.items.filter(cst => cst.order >= start.order && (!nextCategory || cst.order < nextCategory.order));
} }
/** /**

View File

@ -56,11 +56,12 @@ function EditorRSExpression({
onToggleList, onToggleList,
...restProps ...restProps
}: EditorRSExpressionProps) { }: EditorRSExpressionProps) {
const { schema } = useRSForm(); const model = useRSForm();
const { mathFont, setMathFont } = useConceptTheme(); const { mathFont, setMathFont } = useConceptTheme();
const [isModified, setIsModified] = useState(false); const [isModified, setIsModified] = useState(false);
const { parseData, checkExpression, resetParse, loading } = useCheckExpression({ schema }); const parser = useCheckExpression({ schema: model.schema });
const { resetParse } = parser;
const rsInput = useRef<ReactCodeMirrorRef>(null); const rsInput = useRef<ReactCodeMirrorRef>(null);
const [syntaxTree, setSyntaxTree] = useState<SyntaxTree>([]); const [syntaxTree, setSyntaxTree] = useState<SyntaxTree>([]);
@ -84,7 +85,7 @@ function EditorRSExpression({
} }
const prefix = getDefinitionPrefix(activeCst); const prefix = getDefinitionPrefix(activeCst);
const expression = prefix + value; const expression = prefix + value;
checkExpression(expression, activeCst, parse => { parser.checkExpression(expression, activeCst, parse => {
if (parse.errors.length > 0) { if (parse.errors.length > 0) {
onShowError(parse.errors[0]); onShowError(parse.errors[0]);
} else { } else {
@ -163,15 +164,17 @@ function EditorRSExpression({
<Overlay position='top-[-0.5rem] right-0 flex'> <Overlay position='top-[-0.5rem] right-0 flex'>
<MiniButton <MiniButton
title='Изменить шрифт' title='Изменить шрифт'
icon={<BiFontFamily size='1.25rem' className={mathFont === 'math' ? 'icon-primary' : ''} />}
onClick={toggleFont} onClick={toggleFont}
icon={<BiFontFamily size='1.25rem' className={mathFont === 'math' ? 'icon-primary' : ''} />}
/> />
<MiniButton {!disabled || model.processing ? (
noHover <MiniButton
title='Отображение специальной клавиатуры' noHover
onClick={() => setShowControls(prev => !prev)} title='Отображение специальной клавиатуры'
icon={<FaRegKeyboard size='1.25rem' className={showControls ? 'icon-primary' : ''} />} onClick={() => setShowControls(prev => !prev)}
/> icon={<FaRegKeyboard size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
/>
) : null}
<MiniButton <MiniButton
noHover noHover
title='Отображение списка конституент' title='Отображение списка конституент'
@ -188,10 +191,10 @@ function EditorRSExpression({
<Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'> <Overlay position='top-[-0.5rem] pl-[8rem] sm:pl-[4rem] right-1/2 translate-x-1/2 flex'>
<StatusBar <StatusBar
processing={loading} processing={parser.loading}
isModified={isModified} isModified={isModified}
constituenta={activeCst} constituenta={activeCst}
parseData={parseData} parseData={parser.parseData}
onAnalyze={() => handleCheckExpression()} onAnalyze={() => handleCheckExpression()}
/> />
<HelpButton topic={HelpTopic.CONSTITUENTA} offset={4} /> <HelpButton topic={HelpTopic.CONSTITUENTA} offset={4} />
@ -207,11 +210,15 @@ function EditorRSExpression({
{...restProps} {...restProps}
/> />
<RSEditorControls isOpen={showControls} disabled={disabled} onEdit={handleEdit} /> <RSEditorControls
isOpen={showControls && (!disabled || model.processing)}
disabled={disabled}
onEdit={handleEdit}
/>
<ParsingResult <ParsingResult
isOpen={!!parseData && parseData.errors.length > 0} isOpen={!!parser.parseData && parser.parseData.errors.length > 0}
data={parseData} data={parser.parseData}
disabled={disabled} disabled={disabled}
onShowError={onShowError} onShowError={onShowError}
/> />

View File

@ -1,4 +1,3 @@
import clsx from 'clsx';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { IExpressionParse, IRSErrorDescription } from '@/models/rslang'; import { IExpressionParse, IRSErrorDescription } from '@/models/rslang';
@ -19,7 +18,7 @@ function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultPro
return ( return (
<motion.div <motion.div
className={clsx('border', 'text-sm', 'overflow-y-auto')} className='dense border text-sm overflow-y-auto'
initial={false} initial={false}
animate={isOpen ? 'open' : 'closed'} animate={isOpen ? 'open' : 'closed'}
variants={animateParseResults} variants={animateParseResults}

View File

@ -118,7 +118,7 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
/> />
<div className='flex flex-col'> <div className='flex flex-col'>
<Overlay position='top-[-0.25rem] right-[-0.25rem] flex'> <Overlay position='top-[-0.25rem] right-[-0.25rem] flex'>
{controller.isMutable || controller.isProcessing ? ( {controller.isMutable || (controller.isMutable && controller.isProcessing) ? (
<> <>
<MiniButton <MiniButton
noHover noHover
@ -173,7 +173,7 @@ function FormRSForm({ id, isModified, setIsModified }: FormRSFormProps) {
setValue={value => setCanonical(value)} setValue={value => setCanonical(value)}
/> />
</div> </div>
{controller.isContentEditable || controller.isProcessing ? ( {controller.isContentEditable || (controller.isMutable && controller.isProcessing) ? (
<SubmitButton <SubmitButton
text='Сохранить изменения' text='Сохранить изменения'
className='self-center' className='self-center'

View File

@ -27,7 +27,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
const canSave = useMemo(() => modified && controller.isMutable, [modified, controller.isMutable]); const canSave = useMemo(() => modified && controller.isMutable, [modified, controller.isMutable]);
return ( return (
<Overlay position='top-1 right-1/2 translate-x-1/2' className='flex'> <Overlay position='top-1 right-1/2 translate-x-1/2' className='flex'>
{controller.isContentEditable || controller.isProcessing ? ( {controller.isContentEditable || (controller.isMutable && controller.isProcessing) ? (
<MiniButton <MiniButton
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')} titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
disabled={!canSave} disabled={!canSave}
@ -67,7 +67,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
onClick={controller.claim} onClick={controller.claim}
/> />
) : null} ) : null}
{controller.isContentEditable || controller.isProcessing ? ( {controller.isContentEditable || (controller.isMutable && controller.isProcessing) ? (
<MiniButton <MiniButton
title='Удалить схему' title='Удалить схему'
disabled={!controller.isMutable} disabled={!controller.isMutable}

View File

@ -97,7 +97,7 @@ function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps)
return ( return (
<div tabIndex={-1} className='outline-none' onKeyDown={handleTableKey}> <div tabIndex={-1} className='outline-none' onKeyDown={handleTableKey}>
{controller.isContentEditable || controller.isProcessing ? ( {controller.isContentEditable || (controller.isMutable && controller.isProcessing) ? (
<SelectedCounter <SelectedCounter
totalCount={controller.schema?.stats?.count_all ?? 0} totalCount={controller.schema?.stats?.count_all ?? 0}
selectedCount={selected.length} selectedCount={selected.length}
@ -105,7 +105,7 @@ function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps)
/> />
) : null} ) : null}
{controller.isContentEditable || controller.isProcessing ? ( {controller.isContentEditable || (controller.isMutable && controller.isProcessing) ? (
<RSListToolbar selectedCount={selected.length} /> <RSListToolbar selectedCount={selected.length} />
) : null} ) : null}
<div <div
@ -118,7 +118,7 @@ function EditorRSList({ selected, setSelected, onOpenEdit }: EditorRSListProps)
<RSTable <RSTable
items={controller.schema?.items} items={controller.schema?.items}
maxHeight={tableHeight} maxHeight={tableHeight}
enableSelection={controller.isContentEditable || controller.isProcessing} enableSelection={controller.isContentEditable || (controller.isMutable && controller.isProcessing)}
selected={rowSelection} selected={rowSelection}
setSelected={handleRowSelection} setSelected={handleRowSelection}
onEdit={onOpenEdit} onEdit={onOpenEdit}

View File

@ -106,7 +106,7 @@ li {
text-wrap: pretty; text-wrap: pretty;
} }
div > p { div:not(.dense) > p {
@apply [&:not(:last-child)]:mb-2; @apply [&:not(:last-child)]:mb-2;
} }