diff --git a/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx b/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx index 8a299edc..7e096958 100644 --- a/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx +++ b/rsconcept/frontend/src/features/help/items/ui/help-oss-graph.tsx @@ -41,7 +41,7 @@ export function HelpOssGraph() { Вписать в экран
  • - Панель связанной КС + Панель содержания
  • Диалог настроек diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx index a6596e67..c9232482 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/oss-flow.tsx @@ -236,7 +236,6 @@ export function OssFlow() { showPanel ? 'translate-x-0' : 'opacity-0 translate-x-full pointer-events-none' )} isMounted={showPanel} - selectedItems={selectedItems} /> ); diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/block-stats.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/block-stats.tsx new file mode 100644 index 00000000..8c6b1190 --- /dev/null +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/block-stats.tsx @@ -0,0 +1,24 @@ +import { OperationType } from '../../../../backend/types'; +import { OssStats } from '../../../../components/oss-stats'; +import { type IBlock, type IOperationSchema, NodeType } from '../../../../models/oss'; + +interface BlockStatsProps { + target: IBlock; + oss: IOperationSchema; +} + +export function BlockStats({ target, oss }: BlockStatsProps) { + const contents = oss.hierarchy.expandAllOutputs([target.nodeID]); + const items = contents.map(item => oss.itemByNodeID.get(item)).filter(item => !!item); + const operations = items.filter(item => item.nodeType === NodeType.OPERATION); + const blockStats = { + count_all: contents.length, + count_inputs: operations.filter(item => item.operation_type === OperationType.INPUT).length, + count_synthesis: operations.filter(item => item.operation_type === OperationType.SYNTHESIS).length, + count_schemas: operations.filter(item => !!item.result).length, + count_owned: operations.filter(item => !!item.result && item.is_owned).length, + count_block: contents.length - operations.length + }; + + return ; +} diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/side-panel.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/side-panel.tsx index 38f9d637..4251e724 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/side-panel.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/side-panel.tsx @@ -10,19 +10,23 @@ import { useMainHeight } from '@/stores/app-layout'; import { usePreferencesStore } from '@/stores/preferences'; import { PARAMETER } from '@/utils/constants'; -import { type IOssItem, NodeType } from '../../../../models/oss'; +import { NodeType } from '../../../../models/oss'; +import { useOssEdit } from '../../oss-edit-context'; +import { BlockStats } from './block-stats'; import { ViewSchema } from './view-schema'; interface SidePanelProps { - selectedItems: IOssItem[]; className?: string; isMounted: boolean; } -export function SidePanel({ selectedItems, isMounted, className }: SidePanelProps) { +export function SidePanel({ isMounted, className }: SidePanelProps) { + const { schema, isMutable, selectedItems } = useOssEdit(); const selectedOperation = selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null; + const selectedBlock = + selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.BLOCK ? selectedItems[0] : null; const selectedSchema = selectedOperation?.result ?? null; const debouncedMounted = useDebounce(isMounted, PARAMETER.moveDuration); @@ -52,21 +56,23 @@ export function SidePanel({ selectedItems, isMounted, className }: SidePanelProp 'mt-0 mb-1', 'font-medium text-sm select-none self-center', 'transition-transform', - selectedSchema && 'translate-x-16' + selectedSchema && 'translate-x-20' )} > - Содержание КС + Содержание - {!selectedOperation ? ( -
    Выделите операцию для просмотра
    - ) : !selectedSchema ? ( + {!selectedOperation && !selectedBlock ? ( +
    Выделите операцию или блок для просмотра
    + ) : null} + {selectedOperation && !selectedSchema ? (
    Отсутствует концептуальная схема для выбранной операции
    - ) : debouncedMounted ? ( + ) : selectedOperation && selectedSchema && debouncedMounted ? ( }> - + ) : null} + {selectedBlock ? : null} ); } diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/toolbar-constituents.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/toolbar-constituents.tsx index b0156bca..21dcb538 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/toolbar-constituents.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/toolbar-constituents.tsx @@ -16,6 +16,7 @@ import { type RO } from '@/utils/meta'; interface ToolbarConstituentsProps { schema: IRSForm; + isMutable: boolean; activeCst: IConstituenta | null; setActive: (cstID: number) => void; resetActive: () => void; @@ -27,6 +28,7 @@ export function ToolbarConstituents({ activeCst, setActive, resetActive, + isMutable, className }: ToolbarConstituentsProps) { const router = useConceptNavigation(); @@ -162,33 +164,33 @@ export function ToolbarConstituents({ title='Создать конституенту' icon={} onClick={createCst} - disabled={isProcessing} + disabled={!isMutable || isProcessing} /> } onClick={cloneCst} - disabled={!activeCst || isProcessing} + disabled={!isMutable || !activeCst || isProcessing} /> } - disabled={!activeCst || isProcessing || activeCst?.is_inherited} + disabled={!isMutable || !activeCst || isProcessing || activeCst?.is_inherited} /> } onClick={moveUp} - disabled={!activeCst || isProcessing || schema.items.length < 2 || hasSearch} + disabled={!isMutable || !activeCst || isProcessing || schema.items.length < 2 || hasSearch} /> } onClick={moveDown} - disabled={!activeCst || isProcessing || schema.items.length < 2 || hasSearch} + disabled={!isMutable || !activeCst || isProcessing || schema.items.length < 2 || hasSearch} /> ); diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/view-schema.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/view-schema.tsx index 89b4964f..32fb8bf0 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/view-schema.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/side-panel/view-schema.tsx @@ -10,9 +10,10 @@ import { ToolbarConstituents } from './toolbar-constituents'; interface ViewSchemaProps { schemaID: number; + isMutable: boolean; } -export function ViewSchema({ schemaID }: ViewSchemaProps) { +export function ViewSchema({ schemaID, isMutable }: ViewSchemaProps) { const { schema } = useRSFormSuspense({ itemID: schemaID }); const [activeID, setActiveID] = useState(null); const activeCst = activeID ? schema.cstByID.get(activeID) ?? null : null; @@ -25,6 +26,7 @@ export function ViewSchema({ schemaID }: ViewSchemaProps) { className='absolute -top-7 left-1' schema={schema} activeCst={activeCst} + isMutable={isMutable} setActive={setActiveID} resetActive={() => setActiveID(null)} /> diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx index a4456e93..898583fd 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-graph/toolbar-oss-graph.tsx @@ -115,7 +115,7 @@ export function ToolbarOssGraph({ onClick={resetView} /> } onClick={toggleShowSidePanel} /> diff --git a/rsconcept/frontend/src/features/rsform/components/view-constituents/table-side-constituents.tsx b/rsconcept/frontend/src/features/rsform/components/view-constituents/table-side-constituents.tsx index ce8d4f9d..7a1c0a7d 100644 --- a/rsconcept/frontend/src/features/rsform/components/view-constituents/table-side-constituents.tsx +++ b/rsconcept/frontend/src/features/rsform/components/view-constituents/table-side-constituents.tsx @@ -98,7 +98,7 @@ export function TableSideConstituents({ noDataComponent={

    Список конституент пуст

    -

    Измените параметры фильтра

    +

    Измените параметры фильтра или создайте конституенту

    } onRowClicked={onActivate ? cst => onActivate(cst) : undefined}