mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactoring constants + small UI fixes
This commit is contained in:
parent
16252b2145
commit
a10bda8af3
|
@ -4,6 +4,7 @@ import { motion } from 'framer-motion';
|
||||||
import { IconPin, IconUnpin } from '@/components/Icons';
|
import { IconPin, IconUnpin } from '@/components/Icons';
|
||||||
import { useConceptOptions } from '@/context/OptionsContext';
|
import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
import { animateNavigationToggle } from '@/styling/animations';
|
import { animateNavigationToggle } from '@/styling/animations';
|
||||||
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
function ToggleNavigationButton() {
|
function ToggleNavigationButton() {
|
||||||
const { noNavigationAnimation, toggleNoNavigation } = useConceptOptions();
|
const { noNavigationAnimation, toggleNoNavigation } = useConceptOptions();
|
||||||
|
@ -11,7 +12,6 @@ function ToggleNavigationButton() {
|
||||||
<motion.button
|
<motion.button
|
||||||
type='button'
|
type='button'
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
title={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
|
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'absolute top-0 right-0 z-navigation flex items-center justify-center',
|
'absolute top-0 right-0 z-navigation flex items-center justify-center',
|
||||||
'clr-btn-nav',
|
'clr-btn-nav',
|
||||||
|
@ -21,6 +21,8 @@ function ToggleNavigationButton() {
|
||||||
initial={false}
|
initial={false}
|
||||||
animate={noNavigationAnimation ? 'off' : 'on'}
|
animate={noNavigationAnimation ? 'off' : 'on'}
|
||||||
variants={animateNavigationToggle}
|
variants={animateNavigationToggle}
|
||||||
|
data-tooltip-id={globals.tooltip}
|
||||||
|
data-tooltip-content={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
|
||||||
>
|
>
|
||||||
{!noNavigationAnimation ? <IconPin /> : null}
|
{!noNavigationAnimation ? <IconPin /> : null}
|
||||||
{noNavigationAnimation ? <IconUnpin /> : null}
|
{noNavigationAnimation ? <IconUnpin /> : null}
|
||||||
|
|
|
@ -22,7 +22,8 @@ export { LuGlasses as IconReader } from 'react-icons/lu';
|
||||||
export { FiBell as IconFollow } from 'react-icons/fi';
|
export { FiBell as IconFollow } from 'react-icons/fi';
|
||||||
export { FiBellOff as IconFollowOff } from 'react-icons/fi';
|
export { FiBellOff as IconFollowOff } from 'react-icons/fi';
|
||||||
|
|
||||||
export { BiListUl as IconList } from 'react-icons/bi';
|
export { TbColumns as IconList } from 'react-icons/tb';
|
||||||
|
export { TbColumnsOff as IconListOff } from 'react-icons/tb';
|
||||||
export { BiFontFamily as IconText } from 'react-icons/bi';
|
export { BiFontFamily as IconText } from 'react-icons/bi';
|
||||||
export { BiFont as IconTextOff } from 'react-icons/bi';
|
export { BiFont as IconTextOff } from 'react-icons/bi';
|
||||||
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
export { RiTreeLine as IconTree } from 'react-icons/ri';
|
||||||
|
|
|
@ -4,8 +4,6 @@ import EmbedYoutube from '@/components/ui/EmbedYoutube';
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
import { external_urls, youtube } from '@/utils/constants';
|
import { external_urls, youtube } from '@/utils/constants';
|
||||||
|
|
||||||
const OPT_VIDEO_H = 1080;
|
|
||||||
|
|
||||||
function HelpRSLang() {
|
function HelpRSLang() {
|
||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
|
|
||||||
|
@ -13,7 +11,7 @@ function HelpRSLang() {
|
||||||
const viewH = windowSize.height ?? 0;
|
const viewH = windowSize.height ?? 0;
|
||||||
const viewW = windowSize.width ?? 0;
|
const viewW = windowSize.width ?? 0;
|
||||||
const availableWidth = viewW - (windowSize.isSmall ? 35 : 290);
|
const availableWidth = viewW - (windowSize.isSmall ? 35 : 290);
|
||||||
return Math.min(OPT_VIDEO_H, viewH - 320, Math.floor((availableWidth * 9) / 16));
|
return Math.min(1080, viewH - 320, Math.floor((availableWidth * 9) / 16));
|
||||||
}, [windowSize]);
|
}, [windowSize]);
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
|
|
@ -8,8 +8,7 @@ import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||||
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
|
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
|
||||||
import { RSErrorType } from '@/models/rslang';
|
import { RSErrorType } from '@/models/rslang';
|
||||||
import { DataCallback, postCheckExpression } from '@/utils/backendAPI';
|
import { DataCallback, postCheckExpression } from '@/utils/backendAPI';
|
||||||
|
import { PARAMETER } from '@/utils/constants';
|
||||||
const LOGIC_TYPIFICATION = 'LOGIC';
|
|
||||||
|
|
||||||
function useCheckExpression({ schema }: { schema?: IRSForm }) {
|
function useCheckExpression({ schema }: { schema?: IRSForm }) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
@ -47,17 +46,17 @@ function checkTypeConsistency(type: CstType, typification: string, args: IArgume
|
||||||
case CstType.CONSTANT:
|
case CstType.CONSTANT:
|
||||||
case CstType.STRUCTURED:
|
case CstType.STRUCTURED:
|
||||||
case CstType.TERM:
|
case CstType.TERM:
|
||||||
return typification !== LOGIC_TYPIFICATION && args.length === 0;
|
return typification !== PARAMETER.logicLabel && args.length === 0;
|
||||||
|
|
||||||
case CstType.AXIOM:
|
case CstType.AXIOM:
|
||||||
case CstType.THEOREM:
|
case CstType.THEOREM:
|
||||||
return typification === LOGIC_TYPIFICATION && args.length === 0;
|
return typification === PARAMETER.logicLabel && args.length === 0;
|
||||||
|
|
||||||
case CstType.FUNCTION:
|
case CstType.FUNCTION:
|
||||||
return typification !== LOGIC_TYPIFICATION && args.length !== 0;
|
return typification !== PARAMETER.logicLabel && args.length !== 0;
|
||||||
|
|
||||||
case CstType.PREDICATE:
|
case CstType.PREDICATE:
|
||||||
return typification === LOGIC_TYPIFICATION && args.length !== 0;
|
return typification === PARAMETER.logicLabel && args.length !== 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,10 @@
|
||||||
|
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
const KEY_NAME_ESC = 'Escape';
|
|
||||||
const KEY_EVENT_TYPE = 'keyup';
|
|
||||||
|
|
||||||
function useEscapeKey(handleClose: () => void) {
|
function useEscapeKey(handleClose: () => void) {
|
||||||
const handleEscKey = useCallback(
|
const handleEscKey = useCallback(
|
||||||
(event: KeyboardEvent) => {
|
(event: KeyboardEvent) => {
|
||||||
if (event.key === KEY_NAME_ESC) {
|
if (event.key === 'Escape') {
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -16,9 +13,9 @@ function useEscapeKey(handleClose: () => void) {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.addEventListener(KEY_EVENT_TYPE, handleEscKey, false);
|
document.addEventListener('keyup', handleEscKey, false);
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener(KEY_EVENT_TYPE, handleEscKey, false);
|
document.removeEventListener('keyup', handleEscKey, false);
|
||||||
};
|
};
|
||||||
}, [handleEscKey]);
|
}, [handleEscKey]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { SMALL_SCREEN_WIDTH } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
function useWindowSize() {
|
function useWindowSize() {
|
||||||
const isClient = typeof window === 'object';
|
const isClient = typeof window === 'object';
|
||||||
|
@ -11,7 +11,7 @@ function useWindowSize() {
|
||||||
return {
|
return {
|
||||||
width: isClient ? window.innerWidth : undefined,
|
width: isClient ? window.innerWidth : undefined,
|
||||||
height: isClient ? window.innerHeight : undefined,
|
height: isClient ? window.innerHeight : undefined,
|
||||||
isSmall: isClient && window.innerWidth < SMALL_SCREEN_WIDTH
|
isSmall: isClient && window.innerWidth < PARAMETER.smallScreen
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,7 @@ export function loadRSFormData(input: IRSFormData): IRSForm {
|
||||||
result.graph = new Graph();
|
result.graph = new Graph();
|
||||||
result.stats = calculateStats(result.items);
|
result.stats = calculateStats(result.items);
|
||||||
|
|
||||||
const derivationLookup: Map<ConstituentaID, ConstituentaID> = new Map();
|
|
||||||
result.items.forEach(cst => {
|
result.items.forEach(cst => {
|
||||||
derivationLookup.set(cst.id, cst.id);
|
|
||||||
cst.derived_from = cst.id;
|
cst.derived_from = cst.id;
|
||||||
cst.derived_children = [];
|
cst.derived_children = [];
|
||||||
cst.derived_children_alias = [];
|
cst.derived_children_alias = [];
|
||||||
|
@ -51,7 +49,9 @@ export function loadRSFormData(input: IRSFormData): IRSForm {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Calculate derivation of constituents based on formal definition analysis
|
// Calculate derivation of constituents based on formal definition analysis
|
||||||
|
const derivationLookup: Map<ConstituentaID, ConstituentaID> = new Map();
|
||||||
result.graph.topologicalOrder().forEach(id => {
|
result.graph.topologicalOrder().forEach(id => {
|
||||||
|
derivationLookup.set(id, id);
|
||||||
const cst = result.items.find(item => item.id === id)!;
|
const cst = result.items.find(item => item.id === id)!;
|
||||||
if (cst.cst_type === CstType.STRUCTURED) {
|
if (cst.cst_type === CstType.STRUCTURED) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useLayoutEffect } from 'react';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { TIMEOUT_UI_REFRESH } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
function HomePage() {
|
function HomePage() {
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
|
@ -13,11 +13,11 @@ function HomePage() {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push(urls.manuals);
|
router.push(urls.manuals);
|
||||||
}, TIMEOUT_UI_REFRESH);
|
}, PARAMETER.refreshTimeout);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push(urls.library);
|
router.push(urls.library);
|
||||||
}, TIMEOUT_UI_REFRESH);
|
}, PARAMETER.refreshTimeout);
|
||||||
}
|
}
|
||||||
}, [router, user]);
|
}, [router, user]);
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,6 @@ import ViewConstituents from '../ViewConstituents';
|
||||||
import ConstituentaToolbar from './ConstituentaToolbar';
|
import ConstituentaToolbar from './ConstituentaToolbar';
|
||||||
import FormConstituenta from './FormConstituenta';
|
import FormConstituenta from './FormConstituenta';
|
||||||
|
|
||||||
// Max height of content for left editor pane.
|
|
||||||
const UNFOLDED_HEIGHT = '59.1rem';
|
|
||||||
|
|
||||||
// Threshold window width to switch layout.
|
// Threshold window width to switch layout.
|
||||||
const SIDELIST_LAYOUT_THRESHOLD = 1100; // px
|
const SIDELIST_LAYOUT_THRESHOLD = 1100; // px
|
||||||
|
|
||||||
|
@ -119,7 +116,6 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
|
||||||
schema={controller.schema}
|
schema={controller.schema}
|
||||||
expression={activeCst?.definition_formal ?? ''}
|
expression={activeCst?.definition_formal ?? ''}
|
||||||
isBottom={isNarrow}
|
isBottom={isNarrow}
|
||||||
baseHeight={UNFOLDED_HEIGHT}
|
|
||||||
activeID={activeCst?.id}
|
activeID={activeCst?.id}
|
||||||
onOpenEdit={onOpenEdit}
|
onOpenEdit={onOpenEdit}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useCallback, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { FaRegKeyboard } from 'react-icons/fa6';
|
import { FaRegKeyboard } from 'react-icons/fa6';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { IconList, IconText, IconTree } from '@/components/Icons';
|
import { IconList, IconListOff, IconText, IconTextOff, IconTree } from '@/components/Icons';
|
||||||
import BadgeHelp from '@/components/man/BadgeHelp';
|
import BadgeHelp from '@/components/man/BadgeHelp';
|
||||||
import RSInput from '@/components/RSInput';
|
import RSInput from '@/components/RSInput';
|
||||||
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
||||||
|
@ -164,19 +164,21 @@ function EditorRSExpression({
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Изменить шрифт'
|
title='Изменить шрифт'
|
||||||
onClick={toggleFont}
|
onClick={toggleFont}
|
||||||
icon={<IconText size='1.25rem' className={mathFont === 'math' ? 'icon-primary' : ''} />}
|
icon={
|
||||||
|
mathFont === 'math' ? <IconText size='1.25rem' className='icon-primary' /> : <IconTextOff size='1.25rem' />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{!disabled || model.processing ? (
|
{!disabled || model.processing ? (
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Отображение специальной клавиатуры'
|
title='Отображение специальной клавиатуры'
|
||||||
onClick={() => setShowControls(prev => !prev)}
|
|
||||||
icon={<FaRegKeyboard size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
|
icon={<FaRegKeyboard size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
|
||||||
|
onClick={() => setShowControls(prev => !prev)}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Отображение списка конституент'
|
title='Отображение списка конституент'
|
||||||
|
icon={showList ? <IconList size='1.25rem' className='icon-primary' /> : <IconListOff size='1.25rem' />}
|
||||||
onClick={onToggleList}
|
onClick={onToggleList}
|
||||||
icon={<IconList size='1.25rem' className={showList ? 'icon-primary' : ''} />}
|
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Дерево разбора выражения'
|
title='Дерево разбора выражения'
|
||||||
|
|
|
@ -14,7 +14,7 @@ import useLocalStorage from '@/hooks/useLocalStorage';
|
||||||
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
|
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
|
||||||
import { ConstituentaID, CstType } from '@/models/rsform';
|
import { ConstituentaID, CstType } from '@/models/rsform';
|
||||||
import { colorBgGraphNode } from '@/styling/color';
|
import { colorBgGraphNode } from '@/styling/color';
|
||||||
import { storage, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants';
|
import { PARAMETER, storage } from '@/utils/constants';
|
||||||
|
|
||||||
import { useRSEdit } from '../RSEditContext';
|
import { useRSEdit } from '../RSEditContext';
|
||||||
import GraphSelectors from './GraphSelectors';
|
import GraphSelectors from './GraphSelectors';
|
||||||
|
@ -141,7 +141,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
|
||||||
setLayout(newLayout);
|
setLayout(newLayout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setToggleResetView(prev => !prev);
|
setToggleResetView(prev => !prev);
|
||||||
}, TIMEOUT_GRAPH_REFRESH);
|
}, PARAMETER.graphRefreshDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeParams = useCallback(
|
const handleChangeParams = useCallback(
|
||||||
|
@ -173,7 +173,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
|
||||||
}));
|
}));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setToggleResetView(prev => !prev);
|
setToggleResetView(prev => !prev);
|
||||||
}, TIMEOUT_GRAPH_REFRESH);
|
}, PARAMETER.graphRefreshDelay);
|
||||||
}, [setFilterParams, setToggleResetView]);
|
}, [setFilterParams, setToggleResetView]);
|
||||||
|
|
||||||
const graph = useMemo(
|
const graph = useMemo(
|
||||||
|
|
|
@ -6,7 +6,7 @@ import GraphUI, { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, useSelectio
|
||||||
import { useConceptOptions } from '@/context/OptionsContext';
|
import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
import { ConstituentaID } from '@/models/rsform';
|
import { ConstituentaID } from '@/models/rsform';
|
||||||
import { graphDarkT, graphLightT } from '@/styling/color';
|
import { graphDarkT, graphLightT } from '@/styling/color';
|
||||||
import { resources } from '@/utils/constants';
|
import { PARAMETER, resources } from '@/utils/constants';
|
||||||
|
|
||||||
interface TermGraphProps {
|
interface TermGraphProps {
|
||||||
nodes: GraphNode[];
|
nodes: GraphNode[];
|
||||||
|
@ -25,8 +25,6 @@ interface TermGraphProps {
|
||||||
toggleResetView: boolean;
|
toggleResetView: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TREE_SIZE_MILESTONE = 50;
|
|
||||||
|
|
||||||
function TermGraph({
|
function TermGraph({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
|
@ -114,7 +112,7 @@ function TermGraph({
|
||||||
maxNodeSize={8}
|
maxNodeSize={8}
|
||||||
cameraMode={orbit ? 'orbit' : is3D ? 'rotate' : 'pan'}
|
cameraMode={orbit ? 'orbit' : is3D ? 'rotate' : 'pan'}
|
||||||
layoutOverrides={
|
layoutOverrides={
|
||||||
layout.includes('tree') ? { nodeLevelRatio: nodes.length < TREE_SIZE_MILESTONE ? 3 : 1 } : undefined
|
layout.includes('tree') ? { nodeLevelRatio: nodes.length < PARAMETER.smallTreeNodes ? 3 : 1 } : undefined
|
||||||
}
|
}
|
||||||
labelFontUrl={resources.graph_font}
|
labelFontUrl={resources.graph_font}
|
||||||
theme={darkMode ? graphDarkT : graphLightT}
|
theme={darkMode ? graphDarkT : graphLightT}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
import { useRSForm } from '@/context/RSFormContext';
|
import { useRSForm } from '@/context/RSFormContext';
|
||||||
import useQueryStrings from '@/hooks/useQueryStrings';
|
import useQueryStrings from '@/hooks/useQueryStrings';
|
||||||
import { ConstituentaID, IConstituenta, IConstituentaMeta } from '@/models/rsform';
|
import { ConstituentaID, IConstituenta, IConstituentaMeta } from '@/models/rsform';
|
||||||
import { prefixes, TIMEOUT_UI_REFRESH } from '@/utils/constants';
|
import { PARAMETER, prefixes } from '@/utils/constants';
|
||||||
import { labelVersion } from '@/utils/labels';
|
import { labelVersion } from '@/utils/labels';
|
||||||
|
|
||||||
import EditorConstituenta from './EditorConstituenta';
|
import EditorConstituenta from './EditorConstituenta';
|
||||||
|
@ -124,7 +124,7 @@ function RSTabs() {
|
||||||
inline: 'nearest'
|
inline: 'nearest'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, TIMEOUT_UI_REFRESH);
|
}, PARAMETER.refreshTimeout);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeTab, navigateTab]
|
[activeTab, navigateTab]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { useMemo, useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { useConceptOptions } from '@/context/OptionsContext';
|
import { useConceptOptions } from '@/context/OptionsContext';
|
||||||
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
|
||||||
|
@ -11,33 +11,22 @@ import { animateSideView } from '@/styling/animations';
|
||||||
import ConstituentsSearch from './ConstituentsSearch';
|
import ConstituentsSearch from './ConstituentsSearch';
|
||||||
import ConstituentsTable from './ConstituentsTable';
|
import ConstituentsTable from './ConstituentsTable';
|
||||||
|
|
||||||
// Height that should be left to accommodate navigation panel + bottom margin
|
|
||||||
const LOCAL_NAVIGATION_H = '2.1rem';
|
|
||||||
|
|
||||||
// Window width cutoff for expression show
|
// Window width cutoff for expression show
|
||||||
const COLUMN_EXPRESSION_HIDE_THRESHOLD = 1500;
|
const COLUMN_EXPRESSION_HIDE_THRESHOLD = 1500;
|
||||||
|
|
||||||
interface ViewConstituentsProps {
|
interface ViewConstituentsProps {
|
||||||
expression: string;
|
expression: string;
|
||||||
isBottom?: boolean;
|
isBottom?: boolean;
|
||||||
baseHeight: string;
|
|
||||||
activeID?: ConstituentaID;
|
activeID?: ConstituentaID;
|
||||||
schema?: IRSForm;
|
schema?: IRSForm;
|
||||||
onOpenEdit: (cstID: ConstituentaID) => void;
|
onOpenEdit: (cstID: ConstituentaID) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ViewConstituents({ expression, schema, activeID, isBottom, baseHeight, onOpenEdit }: ViewConstituentsProps) {
|
function ViewConstituents({ expression, schema, activeID, isBottom, onOpenEdit }: ViewConstituentsProps) {
|
||||||
const { noNavigation } = useConceptOptions();
|
const { calculateHeight } = useConceptOptions();
|
||||||
|
|
||||||
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
||||||
|
|
||||||
const maxHeight = useMemo(() => {
|
|
||||||
const siblingHeight = `${baseHeight} - ${LOCAL_NAVIGATION_H}`;
|
|
||||||
return noNavigation
|
|
||||||
? `calc(min(100vh - 8.2rem, ${siblingHeight}))`
|
|
||||||
: `calc(min(100vh - 11.7rem, ${siblingHeight}))`;
|
|
||||||
}, [noNavigation, baseHeight]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
@ -58,7 +47,7 @@ function ViewConstituents({ expression, schema, activeID, isBottom, baseHeight,
|
||||||
setFiltered={setFilteredData}
|
setFiltered={setFilteredData}
|
||||||
/>
|
/>
|
||||||
<ConstituentsTable
|
<ConstituentsTable
|
||||||
maxHeight={isBottom ? '12rem' : maxHeight}
|
maxHeight={isBottom ? '12rem' : calculateHeight('8.2rem')}
|
||||||
items={filteredData}
|
items={filteredData}
|
||||||
activeID={activeID}
|
activeID={activeID}
|
||||||
onOpenEdit={onOpenEdit}
|
onOpenEdit={onOpenEdit}
|
||||||
|
|
|
@ -10,24 +10,16 @@ export const buildConstants = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General UI timeout [in ms] for waiting for render.
|
* Global application Parameters. The place where magic numbers are put to rest.
|
||||||
*/
|
*/
|
||||||
export const TIMEOUT_UI_REFRESH = 100;
|
export const PARAMETER = {
|
||||||
|
smallScreen: 640, // == tailwind:xs
|
||||||
|
smallTreeNodes: 50, // amount of nodes threshold for size increase for large graphs
|
||||||
|
refreshTimeout: 100, // milliseconds delay for post-refresh actions
|
||||||
|
graphRefreshDelay: 10, // milliseconds delay for graph viewpoint reset
|
||||||
|
|
||||||
/**
|
logicLabel: 'LOGIC'
|
||||||
* Threshold for small screen size optimizations.
|
};
|
||||||
*/
|
|
||||||
export const SMALL_SCREEN_WIDTH = 640; // == tailwind:xs
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timeout [in ms] for graph refresh.
|
|
||||||
*/
|
|
||||||
export const TIMEOUT_GRAPH_REFRESH = 200;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exteor file extension for RSForm.
|
|
||||||
*/
|
|
||||||
export const EXTEOR_TRS_FILE = '.trs';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numeric limitations.
|
* Numeric limitations.
|
||||||
|
@ -36,6 +28,11 @@ export const limits = {
|
||||||
library_alias_len: 12
|
library_alias_len: 12
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exteor file extension for RSForm.
|
||||||
|
*/
|
||||||
|
export const EXTEOR_TRS_FILE = '.trs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regex patterns for data validation.
|
* Regex patterns for data validation.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user