R: Migrating to zustand for local state management pt3

This commit is contained in:
Ivan 2025-01-15 22:16:27 +03:00
parent 912fd22bfa
commit b9ee1b9d08
14 changed files with 167 additions and 155 deletions

View File

@ -9,6 +9,8 @@ import { NavigationState } from '@/context/NavigationContext';
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout'; import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
import { GlobalTooltips } from './GlobalTooltips';
function ApplicationLayout() { function ApplicationLayout() {
const mainHeight = useMainHeight(); const mainHeight = useMainHeight();
const viewportHeight = useViewportHeight(); const viewportHeight = useViewportHeight();
@ -27,6 +29,8 @@ function ApplicationLayout() {
pauseOnFocusLoss={false} pauseOnFocusLoss={false}
/> />
<GlobalTooltips />
<Navigation /> <Navigation />
<div <div

View File

@ -4,7 +4,6 @@ import { ErrorBoundary } from 'react-error-boundary';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';
import { AuthState } from '@/context/AuthContext'; import { AuthState } from '@/context/AuthContext';
import { OptionsState } from '@/context/ConceptOptionsContext';
import { GlobalOssState } from '@/context/GlobalOssContext'; import { GlobalOssState } from '@/context/GlobalOssContext';
import { LibraryState } from '@/context/LibraryContext'; import { LibraryState } from '@/context/LibraryContext';
import { UsersState } from '@/context/UsersContext'; import { UsersState } from '@/context/UsersContext';
@ -31,11 +30,11 @@ function GlobalProviders({ children }: React.PropsWithChildren) {
onError={logError} onError={logError}
> >
<IntlProvider locale='ru' defaultLocale='ru'> <IntlProvider locale='ru' defaultLocale='ru'>
<OptionsState>
<UsersState> <UsersState>
<AuthState> <AuthState>
<LibraryState> <LibraryState>
<GlobalOssState> <GlobalOssState>
{children} {children}
@ -43,7 +42,6 @@ function GlobalProviders({ children }: React.PropsWithChildren) {
</LibraryState> </LibraryState>
</AuthState> </AuthState>
</UsersState> </UsersState>
</OptionsState>
</IntlProvider> </IntlProvider>
</ErrorBoundary>); </ErrorBoundary>);
} }

View File

@ -0,0 +1,32 @@
'use client';
import InfoConstituenta from '@/components/info/InfoConstituenta';
import Loader from '@/components/ui/Loader';
import Tooltip from '@/components/ui/Tooltip';
import { useTooltipsStore } from '@/stores/tooltips';
import { globals } from '@/utils/constants';
export const GlobalTooltips = () => {
const hoverCst = useTooltipsStore(state => state.activeCst);
return (
<>
<Tooltip
float
id={globals.tooltip}
layer='z-topmost'
place='right-start'
className='mt-8 max-w-[20rem] break-words'
/>
<Tooltip
float
id={globals.value_tooltip}
layer='z-topmost'
className='max-w-[calc(min(40rem,100dvw-2rem))] text-justify'
/>
<Tooltip clickable id={globals.constituenta_tooltip} layer='z-modalTooltip' className='max-w-[30rem]'>
{hoverCst ? <InfoConstituenta data={hoverCst} onClick={event => event.stopPropagation()} /> : <Loader />}
</Tooltip>
</>
);
};

View File

@ -1,7 +1,7 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstClass, IConstituenta } from '@/models/rsform'; import { CstClass, IConstituenta } from '@/models/rsform';
import { useTooltipsStore } from '@/stores/tooltips';
import { APP_COLORS, colorFgCstStatus } from '@/styling/color'; import { APP_COLORS, colorFgCstStatus } from '@/styling/color';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
@ -19,7 +19,7 @@ interface BadgeConstituentaProps extends CProps.Styling {
* Displays a badge with a constituenta alias and information tooltip. * Displays a badge with a constituenta alias and information tooltip.
*/ */
function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) { function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstituentaProps) {
const { setHoverCst } = useConceptOptions(); const setActiveCst = useTooltipsStore(state => state.setActiveCst);
return ( return (
<div <div
@ -39,7 +39,7 @@ function BadgeConstituenta({ value, prefixID, className, style }: BadgeConstitue
...style ...style
}} }}
data-tooltip-id={globals.constituenta_tooltip} data-tooltip-id={globals.constituenta_tooltip}
onMouseEnter={() => setHoverCst(value)} onMouseEnter={() => setActiveCst(value)}
> >
{value.alias} {value.alias}
</div> </div>

View File

@ -1,56 +0,0 @@
'use client';
import { createContext, useContext, useState } from 'react';
import InfoConstituenta from '@/components/info/InfoConstituenta';
import Loader from '@/components/ui/Loader';
import Tooltip from '@/components/ui/Tooltip';
import { IConstituenta } from '@/models/rsform';
import { globals } from '@/utils/constants';
import { contextOutsideScope } from '@/utils/labels';
interface IOptionsContext {
setHoverCst: (newValue: IConstituenta | undefined) => void;
}
const OptionsContext = createContext<IOptionsContext | null>(null);
export const useConceptOptions = () => {
const context = useContext(OptionsContext);
if (!context) {
throw new Error(contextOutsideScope('useConceptTheme', 'ThemeState'));
}
return context;
};
export const OptionsState = ({ children }: React.PropsWithChildren) => {
const [hoverCst, setHoverCst] = useState<IConstituenta | undefined>(undefined);
return (
<OptionsContext
value={{
setHoverCst
}}
>
<>
<Tooltip
float
id={globals.tooltip}
layer='z-topmost'
place='right-start'
className='mt-8 max-w-[20rem] break-words'
/>
<Tooltip
float
id={globals.value_tooltip}
layer='z-topmost'
className='max-w-[calc(min(40rem,100dvw-2rem))] text-justify'
/>
<Tooltip clickable id={globals.constituenta_tooltip} layer='z-modalTooltip' className='max-w-[30rem]'>
{hoverCst ? <InfoConstituenta data={hoverCst} onClick={event => event.stopPropagation()} /> : <Loader />}
</Tooltip>
{children}
</>
</OptionsContext>
);
};

View File

@ -1,31 +0,0 @@
'use client';
import { useEffect, useState } from 'react';
import { storage } from '@/utils/constants';
function useLocalStorage<ValueType>(key: string, defaultValue: ValueType | (() => ValueType)) {
const prefixedKey = `${storage.PREFIX}${key}`;
const [value, setValue] = useState<ValueType>(() => {
const loadedJson = localStorage.getItem(prefixedKey);
if (loadedJson != null) {
return JSON.parse(loadedJson) as ValueType;
} else if (typeof defaultValue === 'function') {
return (defaultValue as () => ValueType)();
} else {
return defaultValue;
}
});
useEffect(() => {
if (value === undefined) {
localStorage.removeItem(prefixedKey);
} else {
localStorage.setItem(prefixedKey, JSON.stringify(value));
}
}, [prefixedKey, value]);
return [value, setValue] as [ValueType, typeof setValue];
}
export default useLocalStorage;

View File

@ -19,12 +19,12 @@ import {
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import { useOSS } from '@/context/OssContext'; import { useOSS } from '@/context/OssContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import { OssNode } from '@/models/miscellaneous'; import { OssNode } from '@/models/miscellaneous';
import { OperationID } from '@/models/oss'; import { OperationID } from '@/models/oss';
import { useMainHeight } from '@/stores/appLayout'; import { useMainHeight } from '@/stores/appLayout';
import { useOSSGraphStore } from '@/stores/ossGraph';
import { APP_COLORS } from '@/styling/color'; import { APP_COLORS } from '@/styling/color';
import { PARAMETER, storage } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { errors } from '@/utils/labels'; import { errors } from '@/utils/labels';
import { useOssEdit } from '../OssEditContext'; import { useOssEdit } from '../OssEditContext';
@ -46,9 +46,9 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
const controller = useOssEdit(); const controller = useOssEdit();
const flow = useReactFlow(); const flow = useReactFlow();
const [showGrid, setShowGrid] = useLocalStorage<boolean>(storage.ossShowGrid, false); const showGrid = useOSSGraphStore(state => state.showGrid);
const [edgeAnimate, setEdgeAnimate] = useLocalStorage<boolean>(storage.ossEdgeAnimate, false); const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
const [edgeStraight, setEdgeStraight] = useLocalStorage<boolean>(storage.ossEdgeStraight, false); const edgeStraight = useOSSGraphStore(state => state.edgeStraight);
const [nodes, setNodes, onNodesChange] = useNodesState([]); const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]);
@ -277,9 +277,6 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
<Overlay position='top-[1.9rem] pt-1 right-1/2 translate-x-1/2' className='rounded-b-2xl cc-blur'> <Overlay position='top-[1.9rem] pt-1 right-1/2 translate-x-1/2' className='rounded-b-2xl cc-blur'>
<ToolbarOssGraph <ToolbarOssGraph
isModified={isModified} isModified={isModified}
showGrid={showGrid}
edgeAnimate={edgeAnimate}
edgeStraight={edgeStraight}
onFitView={() => flow.fitView({ duration: PARAMETER.zoomDuration })} onFitView={() => flow.fitView({ duration: PARAMETER.zoomDuration })}
onCreate={() => handleCreateOperation(controller.selected)} onCreate={() => handleCreateOperation(controller.selected)}
onDelete={handleDeleteSelected} onDelete={handleDeleteSelected}
@ -288,9 +285,6 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
onResetPositions={() => setToggleReset(prev => !prev)} onResetPositions={() => setToggleReset(prev => !prev)}
onSavePositions={handleSavePositions} onSavePositions={handleSavePositions}
onSaveImage={handleSaveImage} onSaveImage={handleSaveImage}
toggleShowGrid={() => setShowGrid(prev => !prev)}
toggleEdgeAnimate={() => setEdgeAnimate(prev => !prev)}
toggleEdgeStraight={() => setEdgeStraight(prev => !prev)}
/> />
</Overlay> </Overlay>
{menuProps ? ( {menuProps ? (

View File

@ -21,6 +21,7 @@ import BadgeHelp from '@/components/info/BadgeHelp';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import { HelpTopic } from '@/models/miscellaneous'; import { HelpTopic } from '@/models/miscellaneous';
import { OperationType } from '@/models/oss'; import { OperationType } from '@/models/oss';
import { useOSSGraphStore } from '@/stores/ossGraph';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { prepareTooltip } from '@/utils/labels'; import { prepareTooltip } from '@/utils/labels';
@ -28,9 +29,6 @@ import { useOssEdit } from '../OssEditContext';
interface ToolbarOssGraphProps { interface ToolbarOssGraphProps {
isModified: boolean; isModified: boolean;
showGrid: boolean;
edgeAnimate: boolean;
edgeStraight: boolean;
onCreate: () => void; onCreate: () => void;
onDelete: () => void; onDelete: () => void;
onEdit: () => void; onEdit: () => void;
@ -39,16 +37,10 @@ interface ToolbarOssGraphProps {
onSaveImage: () => void; onSaveImage: () => void;
onSavePositions: () => void; onSavePositions: () => void;
onResetPositions: () => void; onResetPositions: () => void;
toggleShowGrid: () => void;
toggleEdgeAnimate: () => void;
toggleEdgeStraight: () => void;
} }
function ToolbarOssGraph({ function ToolbarOssGraph({
isModified, isModified,
showGrid,
edgeAnimate,
edgeStraight,
onCreate, onCreate,
onDelete, onDelete,
onEdit, onEdit,
@ -56,13 +48,18 @@ function ToolbarOssGraph({
onFitView, onFitView,
onSaveImage, onSaveImage,
onSavePositions, onSavePositions,
onResetPositions, onResetPositions
toggleShowGrid,
toggleEdgeAnimate,
toggleEdgeStraight
}: ToolbarOssGraphProps) { }: ToolbarOssGraphProps) {
const controller = useOssEdit(); const controller = useOssEdit();
const selectedOperation = controller.schema?.operationByID.get(controller.selected[0]); const selectedOperation = controller.schema?.operationByID.get(controller.selected[0]);
const showGrid = useOSSGraphStore(state => state.showGrid);
const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
const edgeStraight = useOSSGraphStore(state => state.edgeStraight);
const toggleShowGrid = useOSSGraphStore(state => state.toggleShowGrid);
const toggleEdgeAnimate = useOSSGraphStore(state => state.toggleEdgeAnimate);
const toggleEdgeStraight = useOSSGraphStore(state => state.toggleEdgeStraight);
const readyForSynthesis = (() => { const readyForSynthesis = (() => {
if (!selectedOperation || selectedOperation.operation_type !== OperationType.SYNTHESIS) { if (!selectedOperation || selectedOperation.operation_type !== OperationType.SYNTHESIS) {
return false; return false;

View File

@ -6,12 +6,12 @@ import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { GraphColoring } from '@/models/miscellaneous'; import { GraphColoring } from '@/models/miscellaneous';
import { ConstituentaID, IRSForm } from '@/models/rsform'; import { ConstituentaID, IRSForm } from '@/models/rsform';
import { useFitHeight } from '@/stores/appLayout'; import { useFitHeight } from '@/stores/appLayout';
import { useTermGraphStore } from '@/stores/termGraph'; import { useTermGraphStore } from '@/stores/termGraph';
import { useTooltipsStore } from '@/stores/tooltips';
import { APP_COLORS, colorBgGraphNode } from '@/styling/color'; import { APP_COLORS, colorBgGraphNode } from '@/styling/color';
import { globals, PARAMETER, prefixes } from '@/utils/constants'; import { globals, PARAMETER, prefixes } from '@/utils/constants';
@ -32,7 +32,7 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
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 { setHoverCst } = useConceptOptions(); const setActiveCst = useTooltipsStore(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(cstID: ConstituentaID, event: CProps.EventMouse) { function handleClick(cstID: ConstituentaID, event: CProps.EventMouse) {
@ -110,7 +110,7 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
onClick={event => handleClick(cstID, event)} onClick={event => handleClick(cstID, event)}
onDoubleClick={() => onEdit(cstID)} onDoubleClick={() => onEdit(cstID)}
data-tooltip-id={globals.constituenta_tooltip} data-tooltip-id={globals.constituenta_tooltip}
onMouseEnter={() => setHoverCst(cst)} onMouseEnter={() => setActiveCst(cst)}
> >
{cst.alias} {cst.alias}
</button> </button>

View File

@ -1,18 +1,16 @@
'use client'; 'use client';
import { useEffect, useState } from 'react'; import { useEffect } from 'react';
import { IconChild } from '@/components/Icons'; import { IconChild } from '@/components/Icons';
import SelectGraphFilter from '@/components/select/SelectGraphFilter'; import SelectGraphFilter from '@/components/select/SelectGraphFilter';
import SelectMatchMode from '@/components/select/SelectMatchMode'; import SelectMatchMode from '@/components/select/SelectMatchMode';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import SearchBar from '@/components/ui/SearchBar'; import SearchBar from '@/components/ui/SearchBar';
import useLocalStorage from '@/hooks/useLocalStorage';
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
import { applyGraphFilter } from '@/models/miscellaneousAPI'; import { applyGraphFilter } from '@/models/miscellaneousAPI';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI'; import { matchConstituenta } from '@/models/rsformAPI';
import { storage } from '@/utils/constants'; import { useCstSearchStore } from '@/stores/cstSearch';
interface ConstituentsSearchProps { interface ConstituentsSearchProps {
schema?: IRSForm; schema?: IRSForm;
@ -23,10 +21,14 @@ interface ConstituentsSearchProps {
} }
function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFiltered }: ConstituentsSearchProps) { function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFiltered }: ConstituentsSearchProps) {
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL); const query = useCstSearchStore(state => state.query);
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL); const filterMatch = useCstSearchStore(state => state.match);
const [filterText, setFilterText] = useState(''); const filterSource = useCstSearchStore(state => state.source);
const [showInherited, setShowInherited] = useLocalStorage(storage.cstFilterShowInherited, true); const includeInherited = useCstSearchStore(state => state.includeInherited);
const setQuery = useCstSearchStore(state => state.setQuery);
const setMatch = useCstSearchStore(state => state.setMatch);
const setSource = useCstSearchStore(state => state.setSource);
const toggleInherited = useCstSearchStore(state => state.toggleInherited);
useEffect(() => { useEffect(() => {
if (!schema || schema.items.length === 0) { if (!schema || schema.items.length === 0) {
@ -39,15 +41,15 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFilt
} else { } else {
result = applyGraphFilter(schema, activeID, filterSource); result = applyGraphFilter(schema, activeID, filterSource);
} }
if (filterText) { if (query) {
result = result.filter(cst => matchConstituenta(cst, filterText, filterMatch)); result = result.filter(cst => matchConstituenta(cst, query, filterMatch));
} }
if (!showInherited) { if (!includeInherited) {
result = result.filter(cst => !cst.is_inherited); result = result.filter(cst => !cst.is_inherited);
} }
setFiltered(result); setFiltered(result);
}, [ }, [
filterText, query,
setFiltered, setFiltered,
filterSource, filterSource,
activeExpression, activeExpression,
@ -55,7 +57,7 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFilt
schema, schema,
filterMatch, filterMatch,
activeID, activeID,
showInherited includeInherited
]); ]);
return ( return (
@ -64,18 +66,18 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFilt
id='constituents_search' id='constituents_search'
noBorder noBorder
className='min-w-[6rem] w-[6rem] mr-2 flex-grow' className='min-w-[6rem] w-[6rem] mr-2 flex-grow'
query={filterText} query={query}
onChangeQuery={setFilterText} onChangeQuery={setQuery}
/> />
<SelectMatchMode value={filterMatch} onChange={newValue => setFilterMatch(newValue)} dense={dense} /> <SelectMatchMode value={filterMatch} onChange={newValue => setMatch(newValue)} dense={dense} />
<SelectGraphFilter value={filterSource} onChange={newValue => setFilterSource(newValue)} dense={dense} /> <SelectGraphFilter value={filterSource} onChange={newValue => setSource(newValue)} dense={dense} />
{schema && schema?.stats.count_inherited > 0 ? ( {schema && schema?.stats.count_inherited > 0 ? (
<MiniButton <MiniButton
noHover noHover
titleHtml={`Наследованные: <b>${showInherited ? 'отображать' : 'скрывать'}</b>`} titleHtml={`Наследованные: <b>${includeInherited ? 'отображать' : 'скрывать'}</b>`}
icon={<IconChild size='1rem' className={showInherited ? 'icon-primary' : 'clr-text-controls'} />} icon={<IconChild size='1rem' className={includeInherited ? 'icon-primary' : 'clr-text-controls'} />}
className='h-fit self-center' className='h-fit self-center'
onClick={() => setShowInherited(prev => !prev)} onClick={toggleInherited}
/> />
) : null} ) : null}
</div> </div>

View File

@ -0,0 +1,42 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
interface CstSearchStore {
query: string;
setQuery: (value: string) => void;
match: CstMatchMode;
setMatch: (value: CstMatchMode) => void;
source: DependencyMode;
setSource: (value: DependencyMode) => void;
includeInherited: boolean;
toggleInherited: () => void;
}
export const useCstSearchStore = create<CstSearchStore>()(
persist(
set => ({
query: '',
setQuery: value => set({ query: value }),
match: CstMatchMode.ALL,
setMatch: value => set({ match: value }),
source: DependencyMode.ALL,
setSource: value => set({ source: value }),
includeInherited: true,
toggleInherited: () => set(state => ({ includeInherited: !state.includeInherited }))
}),
{
version: 1,
partialize: state => ({
match: state.match,
source: state.source,
includeInherited: state.includeInherited
}),
name: 'portal.constituenta.search'
}
)
);

View File

@ -0,0 +1,32 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface OSSGraphStore {
showGrid: boolean;
toggleShowGrid: () => void;
edgeAnimate: boolean;
toggleEdgeAnimate: () => void;
edgeStraight: boolean;
toggleEdgeStraight: () => void;
}
export const useOSSGraphStore = create<OSSGraphStore>()(
persist(
set => ({
showGrid: false,
toggleShowGrid: () => set(state => ({ showGrid: !state.showGrid })),
edgeAnimate: false,
toggleEdgeAnimate: () => set(state => ({ edgeAnimate: !state.edgeAnimate })),
edgeStraight: false,
toggleEdgeStraight: () => set(state => ({ edgeStraight: !state.edgeStraight }))
}),
{
version: 1,
name: 'portal.ossGraph'
}
)
);

View File

@ -0,0 +1,13 @@
import { create } from 'zustand';
import { IConstituenta } from '@/models/rsform';
interface TooltipsStore {
activeCst: IConstituenta | undefined;
setActiveCst: (value: IConstituenta | undefined) => void;
}
export const useTooltipsStore = create<TooltipsStore>()(set => ({
activeCst: undefined,
setActiveCst: value => set({ activeCst: value })
}));

View File

@ -102,21 +102,6 @@ export const external_urls = {
restAPI: 'https://api.portal.acconcept.ru' restAPI: 'https://api.portal.acconcept.ru'
}; };
/**
* Local storage ID.
*/
export const storage = {
PREFIX: 'portal.',
ossShowGrid: 'oss.show_grid',
ossEdgeStraight: 'oss.edge_straight',
ossEdgeAnimate: 'oss.edge_animate',
cstFilterMatch: 'cst.filter.match',
cstFilterGraph: 'cst.filter.graph',
cstFilterShowInherited: 'cst.filter.show_inherited'
};
/** /**
* Global element ID. * Global element ID.
*/ */