-
+ setFocus(null)}
+ showInputs={filter.focusShowInputs}
+ toggleShowInputs={toggleFocusInputs}
+ showOutputs={filter.focusShowOutputs}
+ toggleShowOutputs={toggleFocusOutputs}
+ />
{!focusCst ? (
Выбор {selected.length} из {schema.stats?.count_all ?? 0}
-
+
@@ -180,6 +210,8 @@ export function TGFlow() {
nodeTypes={TGNodeTypes}
edgeTypes={TGEdgeTypes}
onContextMenu={event => event.preventDefault()}
+ onNodeContextMenu={handleNodeContextMenu}
+ onNodeDoubleClick={handleNodeDoubleClick}
/>
);
diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/toolbar-focused-cst.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/toolbar-focused-cst.tsx
index cb2e9ec0..2bfd7464 100644
--- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/toolbar-focused-cst.tsx
+++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/toolbar-focused-cst.tsx
@@ -1,45 +1,40 @@
-'use client';
+import { type IConstituenta } from '@/features/rsform/models/rsform';
import { MiniButton } from '@/components/control';
import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/icons';
+import { cn } from '@/components/utils';
-import { useTermGraphStore } from '../../../stores/term-graph';
-import { useRSEdit } from '../rsedit-context';
+interface ToolbarFocusedCstProps {
+ className?: string;
+ focus: IConstituenta | null;
+ resetFocus: () => void;
-export function ToolbarFocusedCst() {
- const { setFocus, focusCst } = useRSEdit();
+ showInputs: boolean;
+ toggleShowInputs: () => void;
- const filter = useTermGraphStore(state => state.filter);
- const setFilter = useTermGraphStore(state => state.setFilter);
+ showOutputs: boolean;
+ toggleShowOutputs: () => void;
+}
- function resetFocus() {
- setFocus(null);
- }
-
- function handleShowInputs() {
- setFilter({
- ...filter,
- focusShowInputs: !filter.focusShowInputs
- });
- }
-
- function handleShowOutputs() {
- setFilter({
- ...filter,
- focusShowOutputs: !filter.focusShowOutputs
- });
- }
-
- if (!focusCst) {
+export function ToolbarFocusedCst({
+ focus,
+ resetFocus,
+ className,
+ showInputs,
+ toggleShowInputs,
+ showOutputs,
+ toggleShowOutputs
+}: ToolbarFocusedCstProps) {
+ if (!focus) {
return null;
}
return (
-
+
Фокус
- {focusCst.alias}
+ {focus.alias}
@@ -49,14 +44,14 @@ export function ToolbarFocusedCst() {
onClick={resetFocus}
/>
}
- onClick={handleShowInputs}
+ title={showInputs ? 'Скрыть поставщиков' : 'Отобразить поставщиков'}
+ icon={
}
+ onClick={toggleShowInputs}
/>
}
- onClick={handleShowOutputs}
+ title={showOutputs ? 'Скрыть потребителей' : 'Отобразить потребителей'}
+ icon={
}
+ onClick={toggleShowOutputs}
/>
);
diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/use-filtered-graph.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/use-filtered-graph.tsx
index 87a65e26..2fe78037 100644
--- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/use-filtered-graph.tsx
+++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-term-graph/use-filtered-graph.tsx
@@ -14,7 +14,7 @@ export function useFilteredGraph() {
}
// ====== Internals =========
-function produceFilteredGraph(schema: IRSForm, params: GraphFilterParams, focusCst: IConstituenta | null) {
+export function produceFilteredGraph(schema: IRSForm, params: GraphFilterParams, focusCst: IConstituenta | null) {
const filtered = schema.graph.clone();
const allowedTypes: CstType[] = (() => {
const result: CstType[] = [];
diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/rsedit-context.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/rsedit-context.tsx
index 69007e54..ef5dbf2e 100644
--- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/rsedit-context.tsx
+++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/rsedit-context.tsx
@@ -9,7 +9,7 @@ export const RSTabID = {
CARD: 0,
CST_LIST: 1,
CST_EDIT: 2,
- TERM_GRAPH: 3
+ GRAPH: 3
} as const;
export type RSTabID = (typeof RSTabID)[keyof typeof RSTabID];
diff --git a/rsconcept/frontend/src/features/rsform/stores/term-graph.ts b/rsconcept/frontend/src/features/rsform/stores/term-graph.ts
index ca899a23..f439de89 100644
--- a/rsconcept/frontend/src/features/rsform/stores/term-graph.ts
+++ b/rsconcept/frontend/src/features/rsform/stores/term-graph.ts
@@ -32,6 +32,8 @@ export interface GraphFilterParams {
interface TermGraphStore {
filter: GraphFilterParams;
setFilter: (value: GraphFilterParams) => void;
+ toggleFocusInputs: () => void;
+ toggleFocusOutputs: () => void;
foldHidden: boolean;
toggleFoldHidden: () => void;
@@ -63,6 +65,10 @@ export const useTermGraphStore = create
()(
allowTheorem: true
},
setFilter: value => set({ filter: value }),
+ toggleFocusInputs: () =>
+ set(state => ({ filter: { ...state.filter, focusShowInputs: !state.filter.focusShowInputs } })),
+ toggleFocusOutputs: () =>
+ set(state => ({ filter: { ...state.filter, focusShowOutputs: !state.filter.focusShowOutputs } })),
foldHidden: false,
toggleFoldHidden: () => set(state => ({ foldHidden: !state.foldHidden })),
diff --git a/rsconcept/frontend/src/stores/dialogs.ts b/rsconcept/frontend/src/stores/dialogs.ts
index ee8d45f7..a279258d 100644
--- a/rsconcept/frontend/src/stores/dialogs.ts
+++ b/rsconcept/frontend/src/stores/dialogs.ts
@@ -12,6 +12,7 @@ import { type DlgDeleteOperationProps } from '@/features/oss/dialogs/dlg-delete-
import { type DlgEditBlockProps } from '@/features/oss/dialogs/dlg-edit-block';
import { type DlgEditOperationProps } from '@/features/oss/dialogs/dlg-edit-operation/dlg-edit-operation';
import { type DlgRelocateConstituentsProps } from '@/features/oss/dialogs/dlg-relocate-constituents';
+import { type DlgShowTermGraphProps } from '@/features/oss/dialogs/dlg-show-term-graph/dlg-show-term-graph';
import { type DlgCreateCstProps } from '@/features/rsform/dialogs/dlg-create-cst/dlg-create-cst';
import { type DlgCstTemplateProps } from '@/features/rsform/dialogs/dlg-cst-template/dlg-cst-template';
import { type DlgDeleteCstProps } from '@/features/rsform/dialogs/dlg-delete-cst/dlg-delete-cst';
@@ -61,7 +62,8 @@ export const DialogType = {
SHOW_QR_CODE: 21,
SHOW_AST: 22,
SHOW_TYPE_GRAPH: 23,
- GRAPH_PARAMETERS: 24
+ GRAPH_PARAMETERS: 24,
+ SHOW_TERM_GRAPH: 25
} as const;
export type DialogType = (typeof DialogType)[keyof typeof DialogType];
@@ -88,6 +90,7 @@ interface DialogsStore {
showInlineSynthesis: (props: DlgInlineSynthesisProps) => void;
showShowAST: (props: DlgShowASTProps) => void;
showShowTypeGraph: (props: DlgShowTypeGraphProps) => void;
+ showShowTermGraph: (props: DlgShowTermGraphProps) => void;
showChangeInputSchema: (props: DlgChangeInputSchemaProps) => void;
showChangeLocation: (props: DlgChangeLocationProps) => void;
showCloneLibraryItem: (props: DlgCloneLibraryItemProps) => void;
@@ -127,6 +130,7 @@ export const useDialogsStore = create()(set => ({
showInlineSynthesis: props => set({ active: DialogType.INLINE_SYNTHESIS, props: props }),
showShowAST: props => set({ active: DialogType.SHOW_AST, props: props }),
showShowTypeGraph: props => set({ active: DialogType.SHOW_TYPE_GRAPH, props: props }),
+ showShowTermGraph: props => set({ active: DialogType.SHOW_TERM_GRAPH, props: props }),
showChangeInputSchema: props => set({ active: DialogType.CHANGE_INPUT_SCHEMA, props: props }),
showChangeLocation: props => set({ active: DialogType.CHANGE_LOCATION, props: props }),
showCloneLibraryItem: props => set({ active: DialogType.CLONE_LIBRARY_ITEM, props: props }),