mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
This commit is contained in:
parent
3381aaa0db
commit
4eebcaef53
|
@ -69,9 +69,12 @@ export { IoLibrary as IconLibrary2 } from 'react-icons/io5';
|
|||
export { BiDiamond as IconTemplates } from 'react-icons/bi';
|
||||
export { TbHexagons as IconOSS } from 'react-icons/tb';
|
||||
export { TbHexagon as IconRSForm } from 'react-icons/tb';
|
||||
export { TbTopologyRing as IconConsolidation } from 'react-icons/tb';
|
||||
export { LuNewspaper as IconDefinition } from 'react-icons/lu';
|
||||
export { LuDna as IconTerminology } from 'react-icons/lu';
|
||||
export { FaRegHandshake as IconConvention } from 'react-icons/fa6';
|
||||
export { LiaCloneSolid as IconChild } from 'react-icons/lia';
|
||||
export { RiParentLine as IconParent } from 'react-icons/ri';
|
||||
export { TbTopologyRing as IconConsolidation } from 'react-icons/tb';
|
||||
export { BiSpa as IconPredecessor } from 'react-icons/bi';
|
||||
export { LuArchive as IconArchive } from 'react-icons/lu';
|
||||
export { LuDatabase as IconDatabase } from 'react-icons/lu';
|
||||
|
|
|
@ -1,35 +1,47 @@
|
|||
import clsx from 'clsx';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { globals } from '@/utils/constants';
|
||||
|
||||
import { CProps } from '../props';
|
||||
import MiniButton from './MiniButton';
|
||||
|
||||
interface IconValueProps extends CProps.Styling, CProps.Titled {
|
||||
interface ValueIconProps extends CProps.Styling, CProps.Titled {
|
||||
id?: string;
|
||||
icon: React.ReactNode;
|
||||
value: string | number;
|
||||
textClassName?: string;
|
||||
onClick?: (event: CProps.EventMouse) => void;
|
||||
smallThreshold?: number;
|
||||
dense?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
function IconValue({
|
||||
function ValueIcon({
|
||||
id,
|
||||
dense,
|
||||
value,
|
||||
icon,
|
||||
value,
|
||||
textClassName,
|
||||
disabled = true,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
className,
|
||||
smallThreshold,
|
||||
onClick,
|
||||
...restProps
|
||||
}: IconValueProps) {
|
||||
}: ValueIconProps) {
|
||||
const isSmall = useMemo(() => !smallThreshold || String(value).length < smallThreshold, [value, smallThreshold]);
|
||||
return (
|
||||
<div
|
||||
className={clsx('flex items-center text-right', { 'justify-between gap-6': !dense, 'gap-1': dense }, className)}
|
||||
className={clsx(
|
||||
'flex items-center',
|
||||
'text-right',
|
||||
'hover:cursor-default',
|
||||
{ 'justify-between gap-6': !dense, 'gap-1': dense },
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globals.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
|
@ -37,11 +49,11 @@ function IconValue({
|
|||
data-tooltip-hidden={hideTitle}
|
||||
>
|
||||
<MiniButton noHover noPadding icon={icon} disabled={disabled} onClick={onClick} />
|
||||
<span id={id} className='min-w-[1.2rem]'>
|
||||
<span id={id} className={clsx({ 'text-xs': !isSmall }, textClassName)}>
|
||||
{value}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default IconValue;
|
||||
export default ValueIcon;
|
|
@ -2,14 +2,14 @@ import clsx from 'clsx';
|
|||
|
||||
import { CProps } from '../props';
|
||||
|
||||
interface LabeledValueProps extends CProps.Styling {
|
||||
interface ValueLabeledProps extends CProps.Styling {
|
||||
id?: string;
|
||||
label: string;
|
||||
text: string | number;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
function LabeledValue({ id, label, text, title, className, ...restProps }: LabeledValueProps) {
|
||||
function ValueLabeled({ id, label, text, title, className, ...restProps }: ValueLabeledProps) {
|
||||
return (
|
||||
<div className={clsx('flex justify-between gap-6', className)} {...restProps}>
|
||||
<span title={title}>{label}</span>
|
||||
|
@ -18,4 +18,4 @@ function LabeledValue({ id, label, text, title, className, ...restProps }: Label
|
|||
);
|
||||
}
|
||||
|
||||
export default LabeledValue;
|
||||
export default ValueLabeled;
|
16
rsconcept/frontend/src/components/ui/ValueStats.tsx
Normal file
16
rsconcept/frontend/src/components/ui/ValueStats.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { CProps } from '../props';
|
||||
import ValueIcon from './ValueIcon';
|
||||
|
||||
interface ValueStatsProps extends CProps.Styling, CProps.Titled {
|
||||
id: string;
|
||||
icon: React.ReactNode;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
function ValueStats(props: ValueStatsProps) {
|
||||
return <ValueIcon dense smallThreshold={PARAMETER.statSmallThreshold} textClassName='min-w-[1.4rem]' {...props} />;
|
||||
}
|
||||
|
||||
export default ValueStats;
|
|
@ -1,5 +1,5 @@
|
|||
import Divider from '@/components/ui/Divider';
|
||||
import LabeledValue from '@/components/ui/LabeledValue';
|
||||
import ValueLabeled from '@/components/ui/ValueLabeled';
|
||||
import { IOperationSchemaStats } from '@/models/oss';
|
||||
|
||||
interface OssStatsProps {
|
||||
|
@ -14,13 +14,13 @@ function OssStats({ stats }: OssStatsProps) {
|
|||
<div className='flex flex-col sm:gap-1 sm:ml-6 sm:mt-8 sm:w-[16rem]'>
|
||||
<Divider margins='my-2' className='sm:hidden' />
|
||||
|
||||
<LabeledValue id='count_all' label='Всего операций' text={stats.count_operations} />
|
||||
<LabeledValue id='count_inputs' label='Загрузка' text={stats.count_inputs} />
|
||||
<LabeledValue id='count_synthesis' label='Синтез' text={stats.count_synthesis} />
|
||||
<ValueLabeled id='count_all' label='Всего операций' text={stats.count_operations} />
|
||||
<ValueLabeled id='count_inputs' label='Загрузка' text={stats.count_inputs} />
|
||||
<ValueLabeled id='count_synthesis' label='Синтез' text={stats.count_synthesis} />
|
||||
|
||||
<Divider margins='my-2' />
|
||||
|
||||
<LabeledValue id='count_schemas' label='Прикрепленные схемы' text={stats.count_schemas} />
|
||||
<ValueLabeled id='count_schemas' label='Прикрепленные схемы' text={stats.count_schemas} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
|||
}
|
||||
|
||||
return (
|
||||
<div className='overflow-y-auto' style={{ maxHeight: panelHeight }}>
|
||||
<div className='overflow-y-auto min-h-[20rem]' style={{ maxHeight: panelHeight }}>
|
||||
<ToolbarConstituenta
|
||||
activeCst={activeCst}
|
||||
disabled={disabled}
|
||||
|
|
|
@ -80,7 +80,7 @@ function ToolbarConstituenta({
|
|||
<MiniButton
|
||||
title='Создать конституенту после данной'
|
||||
icon={<IconNewItem size={'1.25rem'} className='icon-green' />}
|
||||
disabled={disabled}
|
||||
disabled={!controller.isContentEditable || controller.isProcessing}
|
||||
onClick={() => controller.createCst(activeCst?.cst_type, false)}
|
||||
/>
|
||||
<MiniButton
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useIntl } from 'react-intl';
|
|||
import { IconDateCreate, IconDateUpdate, IconEditor, IconFolder, IconOwner } from '@/components/Icons';
|
||||
import InfoUsers from '@/components/info/InfoUsers';
|
||||
import SelectUser from '@/components/select/SelectUser';
|
||||
import IconValue from '@/components/ui/IconValue';
|
||||
import ValueIcon from '@/components/ui/ValueIcon';
|
||||
import Overlay from '@/components/ui/Overlay';
|
||||
import Tooltip from '@/components/ui/Tooltip';
|
||||
import { useAccessMode } from '@/context/AccessModeContext';
|
||||
|
@ -47,7 +47,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
|
|||
|
||||
return (
|
||||
<div className='flex flex-col'>
|
||||
<IconValue
|
||||
<ValueIcon
|
||||
className='sm:mb-1 text-ellipsis max-w-[30rem]'
|
||||
icon={<IconFolder size='1.25rem' className='icon-primary' />}
|
||||
value={item.location}
|
||||
|
@ -68,7 +68,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
|
|||
) : null}
|
||||
</Overlay>
|
||||
) : null}
|
||||
<IconValue
|
||||
<ValueIcon
|
||||
className='sm:mb-1'
|
||||
icon={<IconOwner size='1.25rem' className='icon-primary' />}
|
||||
value={getUserLabel(item.owner)}
|
||||
|
@ -78,7 +78,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
|
|||
/>
|
||||
|
||||
<div className='sm:mb-1 flex justify-between items-center'>
|
||||
<IconValue
|
||||
<ValueIcon
|
||||
id='editor_stats'
|
||||
dense
|
||||
icon={<IconEditor size='1.25rem' className='icon-primary' />}
|
||||
|
@ -90,7 +90,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
|
|||
<InfoUsers items={item?.editors ?? []} prefix={prefixes.user_editors} />
|
||||
</Tooltip>
|
||||
|
||||
<IconValue
|
||||
<ValueIcon
|
||||
dense
|
||||
disabled
|
||||
icon={<IconDateUpdate size='1.25rem' className='clr-text-green' />}
|
||||
|
@ -98,7 +98,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
|
|||
title='Дата обновления'
|
||||
/>
|
||||
|
||||
<IconValue
|
||||
<ValueIcon
|
||||
dense
|
||||
disabled
|
||||
icon={<IconDateCreate size='1.25rem' className='clr-text-green' />}
|
||||
|
|
|
@ -49,7 +49,7 @@ function EditorRSFormCard({ isModified, onDestroy, setIsModified }: EditorRSForm
|
|||
/>
|
||||
<AnimateFade
|
||||
onKeyDown={handleInput}
|
||||
className={clsx('sm:w-fit sm:max-w-fit max-w-[32rem]', 'mx-auto ', 'flex flex-col sm:flex-row px-6')}
|
||||
className={clsx('md:w-fit md:max-w-fit max-w-[32rem]', 'mx-auto ', 'flex flex-col md:flex-row px-6')}
|
||||
>
|
||||
<FlexColumn className='flex-shrink'>
|
||||
<FormRSForm id={globals.library_item_editor} isModified={isModified} setIsModified={setIsModified} />
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import {
|
||||
IconChild,
|
||||
IconConvention,
|
||||
IconDefinition,
|
||||
IconPredecessor,
|
||||
IconStatusError,
|
||||
IconStatusIncalculable,
|
||||
IconStatusOK,
|
||||
IconStatusProperty
|
||||
IconStatusProperty,
|
||||
IconTerminology
|
||||
} from '@/components/Icons';
|
||||
import IconValue from '@/components/ui/IconValue';
|
||||
import LabeledValue from '@/components/ui/LabeledValue';
|
||||
import ValueStats from '@/components/ui/ValueStats';
|
||||
import { type IRSFormStats } from '@/models/rsform';
|
||||
|
||||
interface RSFormStatsProps {
|
||||
|
@ -19,120 +21,119 @@ function RSFormStats({ stats }: RSFormStatsProps) {
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<div className='flex flex-col mt-3 sm:gap-1 sm:ml-6 sm:mt-8 sm:w-[16rem]'>
|
||||
<div className='grid grid-cols-4 gap-1 mb-3 justify-items-start sm:justify-items-end'>
|
||||
<div className='col-span-2 text-left w-full flex gap-3 sm:pl-3'>
|
||||
<div className='flex flex-col mt-3 md:gap-1 md:ml-6 md:mt-8 md:w-[18rem] w-[25rem]'>
|
||||
<div className='grid grid-cols-4 gap-1 mb-3 justify-items-end'>
|
||||
<div className='col-span-2 w-fit flex gap-3'>
|
||||
<span>Всего</span>
|
||||
<span>{stats.count_all}</span>
|
||||
</div>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_owned'
|
||||
dense
|
||||
icon={<IconPredecessor size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_all - stats.count_inherited}
|
||||
title='Собственные'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_inherited'
|
||||
dense
|
||||
icon={<IconChild size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_inherited}
|
||||
title='Наследованные'
|
||||
/>
|
||||
|
||||
<IconValue
|
||||
<ValueStats
|
||||
className='col-start-1'
|
||||
id='count_ok'
|
||||
dense
|
||||
icon={<IconStatusOK size='1.25rem' className='clr-text-green' />}
|
||||
value={stats.count_all - stats.count_errors - stats.count_property - stats.count_incalculable}
|
||||
title='Корректные'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_property'
|
||||
dense
|
||||
icon={<IconStatusProperty size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_errors}
|
||||
title='Неразмерные'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_incalculable'
|
||||
dense
|
||||
icon={<IconStatusIncalculable size='1.25rem' className='clr-text-red' />}
|
||||
value={stats.count_incalculable}
|
||||
title='Невычислимые'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_errors'
|
||||
dense
|
||||
icon={<IconStatusError size='1.25rem' className='clr-text-red' />}
|
||||
value={stats.count_errors}
|
||||
title='Некорректные'
|
||||
/>
|
||||
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_base'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>X#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>X</span>}
|
||||
value={stats.count_base}
|
||||
title='Базисные множества'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_constant'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>C#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>C</span>}
|
||||
value={stats.count_constant}
|
||||
title='Константные множества'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_structured'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>S#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>S</span>}
|
||||
value={stats.count_structured}
|
||||
title='Родовые структуры'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_axiom'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>A#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>A</span>}
|
||||
value={stats.count_axiom}
|
||||
title='Аксиомы'
|
||||
/>
|
||||
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_term'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>D#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>D</span>}
|
||||
value={stats.count_term}
|
||||
title='Термы'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_function'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>F#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>F</span>}
|
||||
value={stats.count_function}
|
||||
title='Терм-функции'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_predicate'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>P#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>P</span>}
|
||||
value={stats.count_predicate}
|
||||
title='Предикат-функции'
|
||||
/>
|
||||
<IconValue
|
||||
<ValueStats
|
||||
id='count_theorem'
|
||||
dense
|
||||
icon={<span className='font-math clr-text-default'>T#</span>}
|
||||
icon={<span className='font-math clr-text-default md:pr-1 pl-1 md:pl-0'>T</span>}
|
||||
value={stats.count_theorem}
|
||||
title='Теоремы'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='sm:pl-3 max-w-[10rem] sm:max-w-[12rem]'>
|
||||
<LabeledValue id='count_text_term' label='Термины' text={stats.count_text_term} />
|
||||
<LabeledValue id='count_definition' label='Определения' text={stats.count_definition} />
|
||||
<LabeledValue id='count_convention' label='Конвенции' text={stats.count_convention} />
|
||||
<ValueStats
|
||||
id='count_text_term'
|
||||
icon={<IconTerminology size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_text_term}
|
||||
title='Термины'
|
||||
/>
|
||||
<ValueStats
|
||||
id='count_definition'
|
||||
icon={<IconDefinition size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_definition}
|
||||
title='Определения'
|
||||
/>
|
||||
<ValueStats
|
||||
id='count_convention'
|
||||
icon={<IconConvention size='1.25rem' className='clr-text-primary' />}
|
||||
value={stats.count_convention}
|
||||
title='Конвенции'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -30,6 +30,8 @@ export const PARAMETER = {
|
|||
ossLongLabel: 14, // characters - threshold for long labels - small font
|
||||
ossTruncateLabel: 28, // characters - threshold for long labels - truncate
|
||||
|
||||
statSmallThreshold: 3, // characters - threshold for small labels - small font
|
||||
|
||||
logicLabel: 'LOGIC',
|
||||
exteorVersion: '4.9.3',
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user