M: Refactor tooltips loading
This commit is contained in:
parent
efbeb2a343
commit
a470a6c475
|
@ -1,24 +1,9 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { Suspense } from 'react';
|
|
||||||
|
|
||||||
import { Tooltip } from '@/components/Container';
|
import { Tooltip } from '@/components/Container';
|
||||||
import { Loader } from '@/components/Loader';
|
|
||||||
import { useTooltipsStore } from '@/stores/tooltips';
|
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
const InfoConstituenta = React.lazy(() =>
|
|
||||||
import('@/features/rsform/components/InfoConstituenta').then(module => ({ default: module.InfoConstituenta }))
|
|
||||||
);
|
|
||||||
|
|
||||||
const InfoOperation = React.lazy(() =>
|
|
||||||
import('@/features/oss/components/InfoOperation').then(module => ({ default: module.InfoOperation }))
|
|
||||||
);
|
|
||||||
|
|
||||||
export const GlobalTooltips = () => {
|
export const GlobalTooltips = () => {
|
||||||
const hoverCst = useTooltipsStore(state => state.activeCst);
|
|
||||||
const hoverOperation = useTooltipsStore(state => state.activeOperation);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -34,27 +19,6 @@ export const GlobalTooltips = () => {
|
||||||
layer='z-topmost'
|
layer='z-topmost'
|
||||||
className='max-w-[calc(min(40rem,100dvw-2rem))] text-justify'
|
className='max-w-[calc(min(40rem,100dvw-2rem))] text-justify'
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
|
||||||
clickable
|
|
||||||
id={globalIDs.constituenta_tooltip}
|
|
||||||
layer='z-topmost'
|
|
||||||
className='max-w-[30rem]'
|
|
||||||
hidden={!hoverCst}
|
|
||||||
>
|
|
||||||
<Suspense fallback={<Loader />}>
|
|
||||||
{hoverCst ? <InfoConstituenta data={hoverCst} onClick={event => event.stopPropagation()} /> : null}
|
|
||||||
</Suspense>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip
|
|
||||||
id={globalIDs.operation_tooltip}
|
|
||||||
layer='z-topmost'
|
|
||||||
className='max-w-[35rem] max-h-[40rem] dense'
|
|
||||||
hidden={!hoverOperation}
|
|
||||||
>
|
|
||||||
<Suspense fallback={<Loader />}>
|
|
||||||
{hoverOperation ? <InfoOperation operation={hoverOperation} /> : null}
|
|
||||||
</Suspense>
|
|
||||||
</Tooltip>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Tooltip } from '@/components/Container';
|
||||||
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
|
import { useOperationTooltipStore } from '../stores/operationTooltip';
|
||||||
|
|
||||||
|
import { InfoOperation } from './InfoOperation';
|
||||||
|
|
||||||
|
export function OperationTooltip() {
|
||||||
|
const hoverOperation = useOperationTooltipStore(state => state.activeOperation);
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
id={globalIDs.operation_tooltip}
|
||||||
|
layer='z-topmost'
|
||||||
|
className='max-w-[35rem] max-h-[40rem] dense'
|
||||||
|
hidden={!hoverOperation}
|
||||||
|
>
|
||||||
|
{hoverOperation ? <InfoOperation operation={hoverOperation} /> : null}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
|
@ -14,13 +14,13 @@ import {
|
||||||
import { Overlay } from '@/components/Container';
|
import { Overlay } from '@/components/Container';
|
||||||
import { useMainHeight } from '@/stores/appLayout';
|
import { useMainHeight } from '@/stores/appLayout';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { useTooltipsStore } from '@/stores/tooltips';
|
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
import { useMutatingOss } from '../../../backend/useMutatingOss';
|
import { useMutatingOss } from '../../../backend/useMutatingOss';
|
||||||
import { useUpdatePositions } from '../../../backend/useUpdatePositions';
|
import { useUpdatePositions } from '../../../backend/useUpdatePositions';
|
||||||
import { GRID_SIZE } from '../../../models/ossAPI';
|
import { GRID_SIZE } from '../../../models/ossAPI';
|
||||||
import { type OssNode } from '../../../models/ossLayout';
|
import { type OssNode } from '../../../models/ossLayout';
|
||||||
|
import { useOperationTooltipStore } from '../../../stores/operationTooltip';
|
||||||
import { useOSSGraphStore } from '../../../stores/ossGraph';
|
import { useOSSGraphStore } from '../../../stores/ossGraph';
|
||||||
import { useOssEdit } from '../OssEditContext';
|
import { useOssEdit } from '../OssEditContext';
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export function OssFlow() {
|
||||||
|
|
||||||
const isProcessing = useMutatingOss();
|
const isProcessing = useMutatingOss();
|
||||||
|
|
||||||
const setHoverOperation = useTooltipsStore(state => state.setActiveOperation);
|
const setHoverOperation = useOperationTooltipStore(state => state.setActiveOperation);
|
||||||
|
|
||||||
const showGrid = useOSSGraphStore(state => state.showGrid);
|
const showGrid = useOSSGraphStore(state => state.showGrid);
|
||||||
const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
|
const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
import { Overlay } from '@/components/Container';
|
import { Overlay } from '@/components/Container';
|
||||||
import { IconConsolidation, IconRSForm } from '@/components/Icons';
|
import { IconConsolidation, IconRSForm } from '@/components/Icons';
|
||||||
import { Indicator } from '@/components/View';
|
import { Indicator } from '@/components/View';
|
||||||
import { useTooltipsStore } from '@/stores/tooltips';
|
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
import { OperationType } from '../../../../backend/types';
|
import { OperationType } from '../../../../backend/types';
|
||||||
import { type OssNodeInternal } from '../../../../models/ossLayout';
|
import { type OssNodeInternal } from '../../../../models/ossLayout';
|
||||||
|
import { useOperationTooltipStore } from '../../../../stores/operationTooltip';
|
||||||
|
|
||||||
// characters - threshold for long labels - small font
|
// characters - threshold for long labels - small font
|
||||||
const LONG_LABEL_CHARS = 14;
|
const LONG_LABEL_CHARS = 14;
|
||||||
|
@ -17,7 +17,7 @@ interface NodeCoreProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NodeCore({ node }: NodeCoreProps) {
|
export function NodeCore({ node }: NodeCoreProps) {
|
||||||
const setHover = useTooltipsStore(state => state.setActiveOperation);
|
const setHover = useOperationTooltipStore(state => state.setActiveOperation);
|
||||||
|
|
||||||
const hasFile = !!node.data.operation.result;
|
const hasFile = !!node.data.operation.result;
|
||||||
const longLabel = node.data.label.length > LONG_LABEL_CHARS;
|
const longLabel = node.data.label.length > LONG_LABEL_CHARS;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useParams } from 'react-router';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { urls, useBlockNavigation, useConceptNavigation } from '@/app';
|
import { urls, useBlockNavigation, useConceptNavigation } from '@/app';
|
||||||
|
import { ConstituentaTooltip } from '@/features/rsform/components';
|
||||||
|
|
||||||
import { isAxiosError } from '@/backend/apiTransport';
|
import { isAxiosError } from '@/backend/apiTransport';
|
||||||
import { TextURL } from '@/components/Control';
|
import { TextURL } from '@/components/Control';
|
||||||
|
@ -13,6 +14,8 @@ import { type ErrorData } from '@/components/InfoError';
|
||||||
import { useQueryStrings } from '@/hooks/useQueryStrings';
|
import { useQueryStrings } from '@/hooks/useQueryStrings';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
|
||||||
|
import { OperationTooltip } from '../../components/OperationTooltip';
|
||||||
|
|
||||||
import { OssEditState, OssTabID } from './OssEditContext';
|
import { OssEditState, OssTabID } from './OssEditContext';
|
||||||
import { OssTabs } from './OssTabs';
|
import { OssTabs } from './OssTabs';
|
||||||
|
|
||||||
|
@ -43,6 +46,8 @@ export function OssPage() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary FallbackComponent={ProcessError}>
|
<ErrorBoundary FallbackComponent={ProcessError}>
|
||||||
|
<OperationTooltip />
|
||||||
|
<ConstituentaTooltip />
|
||||||
<OssEditState itemID={urlData.id}>
|
<OssEditState itemID={urlData.id}>
|
||||||
<OssTabs activeTab={urlData.tab} />
|
<OssTabs activeTab={urlData.tab} />
|
||||||
</OssEditState>
|
</OssEditState>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import { type IOperation } from '../models/oss';
|
||||||
|
|
||||||
|
interface OperationTooltipStore {
|
||||||
|
activeOperation: IOperation | null;
|
||||||
|
setActiveOperation: (value: IOperation | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useOperationTooltipStore = create<OperationTooltipStore>()(set => ({
|
||||||
|
activeOperation: null,
|
||||||
|
setActiveOperation: value => set({ activeOperation: value })
|
||||||
|
}));
|
|
@ -1,12 +1,12 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { type Styling } from '@/components/props';
|
import { type Styling } from '@/components/props';
|
||||||
import { useTooltipsStore } from '@/stores/tooltips';
|
|
||||||
import { APP_COLORS } from '@/styling/colors';
|
import { APP_COLORS } from '@/styling/colors';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
import { colorFgCstStatus } from '../colors';
|
import { colorFgCstStatus } from '../colors';
|
||||||
import { CstClass, type IConstituenta } from '../models/rsform';
|
import { CstClass, type IConstituenta } from '../models/rsform';
|
||||||
|
import { useCstTooltipStore } from '../stores/cstTooltip';
|
||||||
|
|
||||||
interface BadgeConstituentaProps extends Styling {
|
interface BadgeConstituentaProps extends Styling {
|
||||||
/** Prefix for tooltip ID. */
|
/** Prefix for tooltip ID. */
|
||||||
|
@ -20,7 +20,7 @@ interface BadgeConstituentaProps extends Styling {
|
||||||
* Displays a badge with a constituenta alias and information tooltip.
|
* Displays a badge with a constituenta alias and information tooltip.
|
||||||
*/
|
*/
|
||||||
export function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) {
|
export function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) {
|
||||||
const setActiveCst = useTooltipsStore(state => state.setActiveCst);
|
const setActiveCst = useCstTooltipStore(state => state.setActiveCst);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Tooltip } from '@/components/Container';
|
||||||
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
|
import { useCstTooltipStore } from '../stores/cstTooltip';
|
||||||
|
|
||||||
|
import { InfoConstituenta } from './InfoConstituenta';
|
||||||
|
|
||||||
|
export function ConstituentaTooltip() {
|
||||||
|
const hoverCst = useCstTooltipStore(state => state.activeCst);
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
clickable
|
||||||
|
id={globalIDs.constituenta_tooltip}
|
||||||
|
layer='z-topmost'
|
||||||
|
className='max-w-[30rem]'
|
||||||
|
hidden={!hoverCst}
|
||||||
|
>
|
||||||
|
{hoverCst ? <InfoConstituenta data={hoverCst} onClick={event => event.stopPropagation()} /> : null}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
export { ConstituentaTooltip } from './ConstituentaTooltip';
|
||||||
export { PickMultiConstituenta } from './PickMultiConstituenta';
|
export { PickMultiConstituenta } from './PickMultiConstituenta';
|
||||||
export { PickSubstitutions } from './PickSubstitutions';
|
export { PickSubstitutions } from './PickSubstitutions';
|
||||||
export { ToolbarRSFormCard } from './ToolbarRSFormCard';
|
export { ToolbarRSFormCard } from './ToolbarRSFormCard';
|
||||||
|
|
|
@ -7,12 +7,12 @@ import { MiniButton } from '@/components/Control';
|
||||||
import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
|
import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
|
||||||
import { useWindowSize } from '@/hooks/useWindowSize';
|
import { useWindowSize } from '@/hooks/useWindowSize';
|
||||||
import { useFitHeight } from '@/stores/appLayout';
|
import { useFitHeight } from '@/stores/appLayout';
|
||||||
import { useTooltipsStore } from '@/stores/tooltips';
|
|
||||||
import { APP_COLORS } from '@/styling/colors';
|
import { APP_COLORS } from '@/styling/colors';
|
||||||
import { globalIDs, PARAMETER, prefixes } from '@/utils/constants';
|
import { globalIDs, PARAMETER, prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
import { colorBgGraphNode } from '../../../colors';
|
import { colorBgGraphNode } from '../../../colors';
|
||||||
import { type IConstituenta } from '../../../models/rsform';
|
import { type IConstituenta } from '../../../models/rsform';
|
||||||
|
import { useCstTooltipStore } from '../../../stores/cstTooltip';
|
||||||
import { useTermGraphStore } from '../../../stores/termGraph';
|
import { useTermGraphStore } from '../../../stores/termGraph';
|
||||||
import { useRSEdit } from '../RSEditContext';
|
import { useRSEdit } from '../RSEditContext';
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export function ViewHidden({ items }: ViewHiddenProps) {
|
||||||
const localSelected = items.filter(id => selected.includes(id));
|
const localSelected = items.filter(id => selected.includes(id));
|
||||||
const isFolded = useTermGraphStore(state => state.foldHidden);
|
const isFolded = useTermGraphStore(state => state.foldHidden);
|
||||||
const toggleFolded = useTermGraphStore(state => state.toggleFoldHidden);
|
const toggleFolded = useTermGraphStore(state => state.toggleFoldHidden);
|
||||||
const setActiveCst = useTooltipsStore(state => state.setActiveCst);
|
const setActiveCst = useCstTooltipStore(state => state.setActiveCst);
|
||||||
const hiddenHeight = useFitHeight(windowSize.isSmall ? '10.4rem + 2px' : '12.5rem + 2px');
|
const hiddenHeight = useFitHeight(windowSize.isSmall ? '10.4rem + 2px' : '12.5rem + 2px');
|
||||||
|
|
||||||
function handleClick(event: React.MouseEvent<Element>, cstID: number) {
|
function handleClick(event: React.MouseEvent<Element>, cstID: number) {
|
||||||
|
|
|
@ -14,6 +14,8 @@ import { type ErrorData } from '@/components/InfoError';
|
||||||
import { useQueryStrings } from '@/hooks/useQueryStrings';
|
import { useQueryStrings } from '@/hooks/useQueryStrings';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
|
||||||
|
import { ConstituentaTooltip } from '../../components/ConstituentaTooltip';
|
||||||
|
|
||||||
import { RSEditState, RSTabID } from './RSEditContext';
|
import { RSEditState, RSTabID } from './RSEditContext';
|
||||||
import { RSTabs } from './RSTabs';
|
import { RSTabs } from './RSTabs';
|
||||||
|
|
||||||
|
@ -57,6 +59,7 @@ export function RSFormPage() {
|
||||||
<ProcessError error={error as ErrorData} isArchive={!!urlData.version} itemID={urlData.id} />
|
<ProcessError error={error as ErrorData} isArchive={!!urlData.version} itemID={urlData.id} />
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
<ConstituentaTooltip />
|
||||||
<RSEditState itemID={urlData.id} activeVersion={urlData.version} activeTab={urlData.tab}>
|
<RSEditState itemID={urlData.id} activeVersion={urlData.version} activeTab={urlData.tab}>
|
||||||
<RSTabs activeID={urlData.activeID} activeTab={urlData.tab} />
|
<RSTabs activeID={urlData.activeID} activeTab={urlData.tab} />
|
||||||
</RSEditState>
|
</RSEditState>
|
||||||
|
|
13
rsconcept/frontend/src/features/rsform/stores/cstTooltip.ts
Normal file
13
rsconcept/frontend/src/features/rsform/stores/cstTooltip.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { create } from 'zustand';
|
||||||
|
|
||||||
|
import { type IConstituenta } from '../models/rsform';
|
||||||
|
|
||||||
|
interface CstTooltipStore {
|
||||||
|
activeCst: IConstituenta | null;
|
||||||
|
setActiveCst: (value: IConstituenta | null) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCstTooltipStore = create<CstTooltipStore>()(set => ({
|
||||||
|
activeCst: null,
|
||||||
|
setActiveCst: value => set({ activeCst: value })
|
||||||
|
}));
|
|
@ -1,19 +0,0 @@
|
||||||
import { create } from 'zustand';
|
|
||||||
|
|
||||||
import { type IOperation } from '@/features/oss';
|
|
||||||
import { type IConstituenta } from '@/features/rsform';
|
|
||||||
|
|
||||||
interface TooltipsStore {
|
|
||||||
activeCst: IConstituenta | null;
|
|
||||||
setActiveCst: (value: IConstituenta | null) => void;
|
|
||||||
activeOperation: IOperation | null;
|
|
||||||
setActiveOperation: (value: IOperation | null) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useTooltipsStore = create<TooltipsStore>()(set => ({
|
|
||||||
activeCst: null,
|
|
||||||
setActiveCst: value => set({ activeCst: value }),
|
|
||||||
|
|
||||||
activeOperation: null,
|
|
||||||
setActiveOperation: value => set({ activeOperation: value })
|
|
||||||
}));
|
|
Loading…
Reference in New Issue
Block a user