diff --git a/rsconcept/frontend/src/app/Navigation/NavigationContext.tsx b/rsconcept/frontend/src/app/Navigation/NavigationContext.tsx index 1d622dd6..752e4fe4 100644 --- a/rsconcept/frontend/src/app/Navigation/NavigationContext.tsx +++ b/rsconcept/frontend/src/app/Navigation/NavigationContext.tsx @@ -1,6 +1,6 @@ 'use client'; -import { createContext, useContext, useEffect, useState } from 'react'; +import { createContext, use, useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; export interface NavigationProps { @@ -23,9 +23,9 @@ interface INavigationContext { setIsBlocked: (value: boolean) => void; } -const NavigationContext = createContext(null); +export const NavigationContext = createContext(null); export const useConceptNavigation = () => { - const context = useContext(NavigationContext); + const context = use(NavigationContext); if (!context) { throw new Error('useConceptNavigation has to be used within '); } diff --git a/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx b/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx index 1ce36d05..a831d904 100644 --- a/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx +++ b/rsconcept/frontend/src/features/oss/pages/OssPage/OssEditContext.tsx @@ -1,6 +1,6 @@ 'use client'; -import { createContext, useContext, useEffect, useState } from 'react'; +import { createContext, use, useEffect, useState } from 'react'; import { urls, useConceptNavigation } from '@/app'; import { useAuthSuspense } from '@/features/auth'; @@ -44,9 +44,9 @@ export interface IOssEditContext { setSelected: React.Dispatch>; } -const OssEditContext = createContext(null); +export const OssEditContext = createContext(null); export const useOssEdit = () => { - const context = useContext(OssEditContext); + const context = use(OssEditContext); if (context === null) { throw new Error('useOssEdit has to be used within '); } diff --git a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx index e142f8ce..7e2939b5 100644 --- a/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx +++ b/rsconcept/frontend/src/features/rsform/dialogs/DlgCstTemplate/TemplateContext.tsx @@ -1,6 +1,6 @@ 'use client'; -import { createContext, useContext, useState } from 'react'; +import { createContext, use, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { useDialogsStore } from '@/stores/dialogs'; @@ -25,9 +25,9 @@ export interface ITemplateContext { onChangeFilterCategory: (newFilterCategory: IConstituenta | null) => void; } -const TemplateContext = createContext(null); +export const TemplateContext = createContext(null); export const useTemplateContext = () => { - const context = useContext(TemplateContext); + const context = use(TemplateContext); if (context === null) { throw new Error('useTemplateContext has to be used within '); } diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorControls.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorControls.tsx index ff193de3..13cc24af 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorControls.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorConstituenta/EditorControls.tsx @@ -18,7 +18,7 @@ interface EditorControlsProps { } export function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsProps) { - const { schema } = useRSEdit(); + const schema = useRSEdit().schema; const { isModified } = useModificationStore(); const isProcessing = useMutatingRSForm(); diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx index 00a4e244..dfe94c96 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorRSExpression/EditorRSExpression.tsx @@ -61,7 +61,7 @@ export function EditorRSExpression({ onShowTypeGraph, ...restProps }: EditorRSExpressionProps) { - const { schema } = useRSEdit(); + const schema = useRSEdit().schema; const [isModified, setIsModified] = useState(false); const rsInput = useRef(null); diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/SchemasGuide.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/SchemasGuide.tsx index 6a01f75f..c93cfb86 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/SchemasGuide.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/EditorTermGraph/SchemasGuide.tsx @@ -8,8 +8,8 @@ import { colorBgSchemas } from '../../../colors'; import { useRSEdit } from '../RSEditContext'; export function SchemasGuide() { - const { items: libraryItems } = useLibrary(); - const { schema } = useRSEdit(); + const libraryItems = useLibrary().items; + const schema = useRSEdit().schema; const schemas = (() => { const processed = new Set(); diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx index 7d29f833..354a7a2e 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/RSEditContext.tsx @@ -1,6 +1,6 @@ 'use client'; -import { createContext, useContext, useEffect, useState } from 'react'; +import { createContext, use, useEffect, useState } from 'react'; import { urls, useConceptNavigation } from '@/app'; import { useAuthSuspense } from '@/features/auth'; @@ -66,9 +66,9 @@ export interface IRSEditContext { promptTemplate: () => void; } -const RSEditContext = createContext(null); +export const RSEditContext = createContext(null); export const useRSEdit = () => { - const context = useContext(RSEditContext); + const context = use(RSEditContext); if (context === null) { throw new Error('useRSEdit has to be used within '); } diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx index bb34bbfe..c8b1f28b 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx @@ -24,7 +24,7 @@ export function ConstituentsSearch({ dense }: ConstituentsSearchProps) { const setSource = useCstSearchStore(state => state.setSource); const toggleInherited = useCstSearchStore(state => state.toggleInherited); - const { schema } = useRSEdit(); + const schema = useRSEdit().schema; return (
diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx index 3c8ea05a..29ecc08a 100644 --- a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/TableSideConstituents.tsx @@ -9,11 +9,11 @@ import { PARAMETER, prefixes } from '@/utils/constants'; import { BadgeConstituenta } from '../../../components/BadgeConstituenta'; import { describeConstituenta } from '../../../labels'; -import { type IConstituenta, type IRSForm } from '../../../models/rsform'; -import { matchConstituenta } from '../../../models/rsformAPI'; -import { DependencyMode, useCstSearchStore } from '../../../stores/cstSearch'; +import { type IConstituenta } from '../../../models/rsform'; import { useRSEdit } from '../RSEditContext'; +import { useFilteredItems } from './useFilteredItems'; + const DESCRIPTION_MAX_SYMBOLS = 280; interface TableSideConstituentsProps { @@ -24,16 +24,8 @@ interface TableSideConstituentsProps { const columnHelper = createColumnHelper(); export function TableSideConstituents({ autoScroll = true, maxHeight }: TableSideConstituentsProps) { - const { schema, activeCst, navigateCst } = useRSEdit(); - - const query = useCstSearchStore(state => state.query); - const filterMatch = useCstSearchStore(state => state.match); - const filterSource = useCstSearchStore(state => state.source); - const includeInherited = useCstSearchStore(state => state.includeInherited); - - const graphFiltered = activeCst ? applyGraphQuery(schema, activeCst.id, filterSource) : schema.items; - const queryFiltered = query ? graphFiltered.filter(cst => matchConstituenta(cst, query, filterMatch)) : graphFiltered; - const items = !includeInherited ? queryFiltered.filter(cst => !cst.is_inherited) : queryFiltered; + const { activeCst, navigateCst } = useRSEdit(); + const items = useFilteredItems(); useEffect(() => { if (!activeCst) { @@ -125,34 +117,3 @@ export function TableSideConstituents({ autoScroll = true, maxHeight }: TableSid /> ); } - -// ====== Internals ========= -/** - * Filter list of {@link ILibraryItem} to a given graph query. - */ -function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): IConstituenta[] { - if (mode === DependencyMode.ALL) { - return target.items; - } - const ids = (() => { - switch (mode) { - case DependencyMode.OUTPUTS: { - return target.graph.nodes.get(pivot)?.outputs; - } - case DependencyMode.INPUTS: { - return target.graph.nodes.get(pivot)?.inputs; - } - case DependencyMode.EXPAND_OUTPUTS: { - return target.graph.expandAllOutputs([pivot]); - } - case DependencyMode.EXPAND_INPUTS: { - return target.graph.expandAllInputs([pivot]); - } - } - })(); - if (ids) { - return target.items.filter(cst => ids.find(id => id === cst.id)); - } else { - return target.items; - } -} diff --git a/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/useFilteredItems.tsx b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/useFilteredItems.tsx new file mode 100644 index 00000000..e1fe66c8 --- /dev/null +++ b/rsconcept/frontend/src/features/rsform/pages/RSFormPage/ViewConstituents/useFilteredItems.tsx @@ -0,0 +1,48 @@ +import { type IConstituenta, type IRSForm } from '../../../models/rsform'; +import { matchConstituenta } from '../../../models/rsformAPI'; +import { DependencyMode, useCstSearchStore } from '../../../stores/cstSearch'; +import { useRSEdit } from '../RSEditContext'; + +export function useFilteredItems() { + const { schema, activeCst } = useRSEdit(); + + const query = useCstSearchStore(state => state.query); + const filterMatch = useCstSearchStore(state => state.match); + const filterSource = useCstSearchStore(state => state.source); + const includeInherited = useCstSearchStore(state => state.includeInherited); + + const graphFiltered = activeCst ? applyGraphQuery(schema, activeCst.id, filterSource) : schema.items; + const queryFiltered = query ? graphFiltered.filter(cst => matchConstituenta(cst, query, filterMatch)) : graphFiltered; + const items = !includeInherited ? queryFiltered.filter(cst => !cst.is_inherited) : queryFiltered; + return items; +} + +/** + * Filter list of {@link ILibraryItem} to a given graph query. + */ +function applyGraphQuery(target: IRSForm, pivot: number, mode: DependencyMode): IConstituenta[] { + if (mode === DependencyMode.ALL) { + return target.items; + } + const ids = (() => { + switch (mode) { + case DependencyMode.OUTPUTS: { + return target.graph.nodes.get(pivot)?.outputs; + } + case DependencyMode.INPUTS: { + return target.graph.nodes.get(pivot)?.inputs; + } + case DependencyMode.EXPAND_OUTPUTS: { + return target.graph.expandAllOutputs([pivot]); + } + case DependencyMode.EXPAND_INPUTS: { + return target.graph.expandAllInputs([pivot]); + } + } + })(); + if (ids) { + return target.items.filter(cst => ids.find(id => id === cst.id)); + } else { + return target.items; + } +}