From d0c7d7cc45863c545cff2b3333ea901811c5d9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Mon, 22 Jul 2024 15:30:49 +0200 Subject: [PATCH 01/12] chore: preliminary refactoring --- .../base/renderTarget/RevealRenderTarget.ts | 2 +- .../observations/ObservationsCache.ts | 2 +- .../observations/ObservationsDomainObject.ts | 2 +- .../concrete/observations/models.ts | 6 +- .../concrete/observations/network.ts | 2 +- .../concrete/observations/types.ts | 2 +- .../components/CacheProvider/FdmNodeCache.ts | 114 ++-- .../CacheProvider/NodeCacheProvider.tsx | 2 +- .../CacheProvider/RevisionFdmNodeCache.ts | 120 ++-- .../src/components/CacheProvider/requests.ts | 24 +- .../src/components/CacheProvider/types.ts | 22 +- .../src/components/Reveal3DResources/types.ts | 2 +- .../useCalculateCadStyling.tsx | 4 +- .../components/RevealCanvas/SDKProvider.tsx | 2 +- .../components/RevealToolbar/SceneList.tsx | 2 +- .../RevealToolbar/SelectSceneButton.tsx | 2 +- .../RuleBasedOutputsSelector.tsx | 2 +- .../components/RuleBasedOutputs/constants.ts | 2 +- .../hooks/useDeleteRuleInstance.tsx | 2 +- .../src/components/RuleBasedOutputs/types.ts | 2 +- .../src/components/RuleBasedOutputs/utils.ts | 2 +- .../src/components/SceneContainer/Queries.tsx | 2 +- .../network/getCadModelsForFdmInstance.ts | 2 +- .../src/hooks/network/getRelationships.ts | 2 +- .../hooks/network/getSourceRelationships.ts | 2 +- .../hooks/network/getTargetRelationships.ts | 2 +- react-components/src/hooks/types.ts | 2 +- react-components/src/hooks/useClickedNode.tsx | 2 +- react-components/src/index.ts | 6 +- .../src/query/use3dNodeByExternalId.tsx | 2 +- .../query/use3dRelatedDirectConnections.ts | 23 +- .../src/query/use3dRelatedEdgeConnections.ts | 4 +- react-components/src/query/use3dScenes.tsx | 2 +- .../useAssetsAndTimeseriesLinkageDataQuery.ts | 2 +- .../src/query/useModelsForInstanceQuery.ts | 4 +- react-components/src/query/useSceneConfig.ts | 2 +- .../src/query/useSearchMappedEquipmentFDM.tsx | 2 +- react-components/src/utilities/FdmSDK.ts | 568 ------------------ .../src/utilities/fdmViewsExist.ts | 2 +- .../src/utilities/globalDataModels.ts | 2 +- react-components/src/utilities/types.ts | 60 -- .../stories/CadStylingCache.stories.tsx | 2 +- .../stories/SearchHooks.stories.tsx | 2 +- 43 files changed, 211 insertions(+), 806 deletions(-) delete mode 100644 react-components/src/utilities/FdmSDK.ts delete mode 100644 react-components/src/utilities/types.ts diff --git a/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts b/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts index 55a1e3a9561..c5c583d4460 100644 --- a/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts +++ b/react-components/src/architecture/base/renderTarget/RevealRenderTarget.ts @@ -31,7 +31,7 @@ import { Range3 } from '../utilities/geometry/Range3'; import { getBoundingBoxFromPlanes } from '../utilities/geometry/getBoundingBoxFromPlanes'; import { Changes } from '../domainObjectsHelpers/Changes'; import { type CogniteClient } from '@cognite/sdk/dist/src'; -import { FdmSDK } from '../../../utilities/FdmSDK'; +import { FdmSDK } from '../../../data-providers/FdmSDK'; const DIRECTIONAL_LIGHT_NAME = 'DirectionalLight'; diff --git a/react-components/src/architecture/concrete/observations/ObservationsCache.ts b/react-components/src/architecture/concrete/observations/ObservationsCache.ts index c5f6b05d26c..bc9cca6fe0d 100644 --- a/react-components/src/architecture/concrete/observations/ObservationsCache.ts +++ b/react-components/src/architecture/concrete/observations/ObservationsCache.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type FdmSDK } from '../../../utilities/FdmSDK'; +import { type FdmSDK } from '../../../data-providers/FdmSDK'; import { type ObservationFdmNode, type ObservationProperties } from './models'; import { type Observation } from './types'; diff --git a/react-components/src/architecture/concrete/observations/ObservationsDomainObject.ts b/react-components/src/architecture/concrete/observations/ObservationsDomainObject.ts index 21530203a68..c4bde335ff6 100644 --- a/react-components/src/architecture/concrete/observations/ObservationsDomainObject.ts +++ b/react-components/src/architecture/concrete/observations/ObservationsDomainObject.ts @@ -5,7 +5,7 @@ import { VisualDomainObject } from '../../base/domainObjects/VisualDomainObject' import { type ThreeView } from '../../base/views/ThreeView'; import { ObservationsView } from './ObservationsView'; import { type TranslateKey } from '../../base/utilities/TranslateKey'; -import { type FdmSDK } from '../../../utilities/FdmSDK'; +import { type FdmSDK } from '../../../data-providers/FdmSDK'; import { Changes } from '../../base/domainObjectsHelpers/Changes'; import { ObservationsCache } from './ObservationsCache'; import { PanelInfo } from '../../base/domainObjectsHelpers/PanelInfo'; diff --git a/react-components/src/architecture/concrete/observations/models.ts b/react-components/src/architecture/concrete/observations/models.ts index 139bb37f811..346d16f2676 100644 --- a/react-components/src/architecture/concrete/observations/models.ts +++ b/react-components/src/architecture/concrete/observations/models.ts @@ -1,7 +1,11 @@ /*! * Copyright 2024 Cognite AS */ -import { type DmsUniqueIdentifier, type FdmNode, type Source } from '../../../utilities/FdmSDK'; +import { + type DmsUniqueIdentifier, + type FdmNode, + type Source +} from '../../../data-providers/FdmSDK'; export type ObservationProperties = { // "ID as the node appears in the Source system" diff --git a/react-components/src/architecture/concrete/observations/network.ts b/react-components/src/architecture/concrete/observations/network.ts index 98eb4d17a9a..09460c77bcd 100644 --- a/react-components/src/architecture/concrete/observations/network.ts +++ b/react-components/src/architecture/concrete/observations/network.ts @@ -7,7 +7,7 @@ import { type DmsUniqueIdentifier, type FdmSDK, type InstanceFilter -} from '../../../utilities/FdmSDK'; +} from '../../../data-providers/FdmSDK'; import { type ObservationFdmNode, OBSERVATION_SOURCE, type ObservationProperties } from './models'; import { v4 as uuid } from 'uuid'; diff --git a/react-components/src/architecture/concrete/observations/types.ts b/react-components/src/architecture/concrete/observations/types.ts index a7271501ec5..92ea743dda6 100644 --- a/react-components/src/architecture/concrete/observations/types.ts +++ b/react-components/src/architecture/concrete/observations/types.ts @@ -8,7 +8,7 @@ import { } from '@cognite/reveal'; import { type ObservationProperties } from './models'; import { type Vector3 } from 'three'; -import { type FdmNode } from '../../../utilities/FdmSDK'; +import { type FdmNode } from '../../../data-providers/FdmSDK'; import { type DomainObjectIntersection } from '../../base/domainObjectsHelpers/DomainObjectIntersection'; import { type ObservationsDomainObject } from './ObservationsDomainObject'; diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 20f1b18e011..74b97d0d9cc 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -3,16 +3,11 @@ */ import { type Node3D, type CogniteClient, type CogniteExternalId } from '@cognite/sdk'; -import { - type Source, - type DmsUniqueIdentifier, - type EdgeItem, - type FdmSDK -} from '../../utilities/FdmSDK'; +import { type Source, type DmsUniqueIdentifier, type FdmSDK } from '../../data-providers/FdmSDK'; import { RevisionFdmNodeCache } from './RevisionFdmNodeCache'; import { - type FdmEdgeWithNode, - type FdmCadEdge, + type FdmConnectionWithNode, + type FdmCadConnection, type ModelRevisionKey, type RevisionId, type NodeId, @@ -37,7 +32,7 @@ import { import { partition } from 'lodash'; import assert from 'assert'; -import { fetchNodesForNodeIds, inspectNodes } from './requests'; +import { fdmEdgesToCadConnections, fetchNodesForNodeIds, inspectNodes } from './requests'; import { type ThreeDModelFdmMappings } from '../../hooks/types'; export class FdmNodeCache { @@ -104,7 +99,7 @@ export class FdmNodeCache { ); const mappings = createMapWithAccumulatedValues( - relevantCachedEdgeData.map((data) => [data.edge.startNode.externalId, data.cadNode]) + relevantCachedEdgeData.map((data) => [data.connection.instance.externalId, data.cadNode]) ); return { @@ -141,7 +136,7 @@ export class FdmNodeCache { private getRelevantExternalIdToNodeMapForRevision( { modelId, revisionId }: ModelRevisionId, - edges: FdmEdgeWithNode[] | undefined, + edges: FdmConnectionWithNode[] | undefined, relevantFdmKeySet: Set ): ThreeDModelFdmMappings { if (edges === undefined || edges.length === 0) @@ -150,7 +145,7 @@ export class FdmNodeCache { const relevantEdges = intersectWithStartNodeIdSet(edges, relevantFdmKeySet); const externalIdToNodeMap = createMapWithAccumulatedValues( - relevantEdges.map((edge) => [edge.edge.startNode.externalId, edge.cadNode]) + relevantEdges.map((edge) => [edge.connection.instance.externalId, edge.cadNode]) ); return { @@ -203,7 +198,7 @@ export class FdmNodeCache { private getCachedEdgesForRevision(id: { modelId: number; revisionId: number; - }): [ModelRevisionKey, FdmEdgeWithNode[]] { + }): [ModelRevisionKey, FdmConnectionWithNode[]] { const revisionCache = this.getOrCreateRevisionCache(id.modelId, id.revisionId); const revisionKey = createModelRevisionKey(id.modelId, id.revisionId); @@ -212,7 +207,7 @@ export class FdmNodeCache { return [revisionKey, cachedRevisionEdges]; } - private writeRevisionDataToCache(modelMap: Map): void { + private writeRevisionDataToCache(modelMap: Map): void { for (const [revisionKey, data] of modelMap.entries()) { const [modelId, revisionId] = revisionKeyToIds(revisionKey); const revisionCache = this.getOrCreateRevisionCache(modelId, revisionId); @@ -228,16 +223,16 @@ export class FdmNodeCache { private async getAndCacheRevisionToEdgesMap( modelRevisionIds: ModelRevisionId[], fetchViews: boolean - ): Promise> { + ): Promise> { const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); - const edges = await this.getEdgesForRevisions(revisionIds, this._fdmClient); + const connections = await this.getEdgesForRevisions(revisionIds, this._fdmClient); - const edgesWithOptionalViews = fetchViews - ? await this.getViewsForEdges(edges) - : edges.map((edge) => ({ edge })); + const connectionsWithOptionalViews = fetchViews + ? await this.getViewsForConnections(connections) + : connections.map((connection) => ({ connection })); const revisionToEdgesMap = await createRevisionToEdgesMap( - edgesWithOptionalViews, + connectionsWithOptionalViews, modelRevisionIds, this._cdfClient ); @@ -257,16 +252,16 @@ export class FdmNodeCache { return revisionCache.getClosestParentFdmData(treeIndex); } - private async getViewsForEdges( - edges: FdmCadEdge[] - ): Promise> { + private async getViewsForConnections( + connections: FdmCadConnection[] + ): Promise> { const nodeInspectionResults = await inspectNodes( this._fdmClient, - edges.map((edge) => edge.startNode) + connections.map((connection) => connection.instance) ); - const dataWithViews = edges.map((edge, ind) => ({ - edge, + const dataWithViews = connections.map((connection, ind) => ({ + connection, view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] })); @@ -276,7 +271,7 @@ export class FdmNodeCache { private async getEdgesForRevisions( revisionIds: number[], fdmClient: FdmSDK - ): Promise>> { + ): Promise { if (revisionIds.length === 0) return []; const versionedPropertiesKey = `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`; @@ -291,7 +286,7 @@ export class FdmNodeCache { 'edge', SYSTEM_3D_EDGE_SOURCE ); - return mappings.instances; + return fdmEdgesToCadConnections(mappings.instances); } private getOrCreateRevisionCache(modelId: number, revisionId: number): RevisionFdmNodeCache { @@ -317,57 +312,57 @@ export class FdmNodeCache { } async function createRevisionToEdgesMap( - edgesWithViews: Array<{ edge: FdmCadEdge; view?: Source }>, + connectionsWithView: Array<{ connection: FdmCadConnection; view?: Source }>, modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient -): Promise> { - const revisionToNodeIdsMap = createRevisionToNodeIdMap(edgesWithViews); +): Promise> { + const revisionToNodeIdsMap = createRevisionToNodeIdMap(connectionsWithView); const modelNodeIdToNodeMap = await createModelNodeIdToNodeMap( revisionToNodeIdsMap, modelRevisionIds, cdfClient ); - return edgesWithViews.reduce((map, edgeWithView) => { - const edgeRevisionId = edgeWithView.edge.properties.revisionId; + return connectionsWithView.reduce((map, connectionWithView) => { + const edgeRevisionId = connectionWithView.connection.revisionId; const modelRevisionId = modelRevisionIds.find((p) => p.revisionId === edgeRevisionId); if (modelRevisionId === undefined) return map; - const value = createFdmEdgeWithNode( + const value = createFdmConnectionWithNode( modelRevisionId, modelNodeIdToNodeMap, - edgeWithView.edge, - edgeWithView.view + connectionWithView.connection, + connectionWithView.view ); - insertEdgeIntoMapList(value, map, modelRevisionId); + insertConnectionIntoMapList(value, map, modelRevisionId); return map; - }, new Map()); + }, new Map()); } -function createFdmEdgeWithNode( +function createFdmConnectionWithNode( modelRevisionId: ModelRevisionId, modelNodeIdToNodeMap: Map, - edge: FdmCadEdge, + connection: FdmCadConnection, view?: Source -): FdmEdgeWithNode { +): FdmConnectionWithNode { const revisionNodeIdKey = createModelNodeIdKey( modelRevisionId.modelId, modelRevisionId.revisionId, - edge.properties.revisionNodeId + connection.nodeId ); const node = modelNodeIdToNodeMap.get(revisionNodeIdKey); assert(node !== undefined); - return { edge, cadNode: node, view }; + return { connection, cadNode: node, view }; } -function insertEdgeIntoMapList( - value: FdmEdgeWithNode, - map: Map, +function insertConnectionIntoMapList( + value: FdmConnectionWithNode, + map: Map, modelRevisionId: ModelRevisionId ): void { const modelRevisionIdKey: ModelRevisionKey = createModelRevisionKey( @@ -375,12 +370,12 @@ function insertEdgeIntoMapList( modelRevisionId.revisionId ); - const edgesForModel = map.get(modelRevisionIdKey); + const connectionsForModel = map.get(modelRevisionIdKey); - if (edgesForModel === undefined) { + if (connectionsForModel === undefined) { map.set(modelRevisionIdKey, [value]); } else { - edgesForModel.push(value); + connectionsForModel.push(value); } } @@ -408,17 +403,17 @@ async function createModelNodeIdToNodeMap( } function createRevisionToNodeIdMap( - edgesWithViews: Array<{ edge: FdmCadEdge; view?: Source }> + connections: Array<{ connection: FdmCadConnection; view?: Source }> ): Map { - return edgesWithViews.reduce((revisionNodeIdMap, edgeWithView) => { - const { revisionNodeId, revisionId } = edgeWithView.edge.properties; + return connections.reduce((revisionNodeIdMap, connectionWithView) => { + const { nodeId, revisionId } = connectionWithView.connection; const nodeIdsInRevision = revisionNodeIdMap.get(revisionId); if (nodeIdsInRevision !== undefined) { - nodeIdsInRevision.push(revisionNodeId); + nodeIdsInRevision.push(nodeId); } else { - revisionNodeIdMap.set(revisionId, [revisionNodeId]); + revisionNodeIdMap.set(revisionId, [nodeId]); } return revisionNodeIdMap; @@ -426,11 +421,14 @@ function createRevisionToNodeIdMap( } function intersectWithStartNodeIdSet( - edges: FdmEdgeWithNode[], + connections: FdmConnectionWithNode[], relevantFdmKeySet: Set -): FdmEdgeWithNode[] { - return edges.filter((edgeData) => { - const fdmKey = createFdmKey(edgeData.edge.startNode.space, edgeData.edge.startNode.externalId); +): FdmConnectionWithNode[] { + return connections.filter((connectionData) => { + const fdmKey = createFdmKey( + connectionData.connection.instance.space, + connectionData.connection.instance.externalId + ); return relevantFdmKeySet.has(fdmKey); }); } diff --git a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx index 4fea3358a70..d81089a8d8f 100644 --- a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx @@ -9,7 +9,7 @@ import { useFdmSdk, useSDK } from '../RevealCanvas/SDKProvider'; import { type FdmNodeDataPromises, type ModelRevisionToEdgeMap } from './types'; import assert from 'assert'; -import { type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { type TypedReveal3DModel } from '../Reveal3DResources/types'; import { type ThreeDModelFdmMappings } from '../../hooks/types'; import { DEFAULT_QUERY_STALE_TIME } from '../../utilities/constants'; diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index d30a563f65e..f82650dd38b 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -3,13 +3,13 @@ */ import { type CogniteClient, type Node3D } from '@cognite/sdk'; -import { type Source, type FdmSDK, type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; +import { type Source, type FdmSDK, type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { type TreeIndex, - type FdmEdgeWithNode, - type FdmCadEdge, + type FdmConnectionWithNode, + type FdmCadConnection, type FdmNodeDataPromises, - type CadNodeWithEdges, + type CadNodeWithConnections, type AncestorQueryResult } from './types'; @@ -31,7 +31,7 @@ export class RevisionFdmNodeCache { private readonly _modelId: number; private readonly _revisionId: number; - private readonly _treeIndexToFdmEdges = new Map(); + private readonly _treeIndexToFdmConnections = new Map(); private readonly _modelInstances: Promise; @@ -50,7 +50,7 @@ export class RevisionFdmNodeCache { } public getClosestParentFdmData(searchTreeIndex: number): FdmNodeDataPromises { - const cachedFdmData = this._treeIndexToFdmEdges.get(searchTreeIndex); + const cachedFdmData = this._treeIndexToFdmConnections.get(searchTreeIndex); if (cachedFdmData === undefined) { return this.findAndCacheNodeDataFromAncestors(searchTreeIndex); @@ -65,7 +65,7 @@ export class RevisionFdmNodeCache { const cadAndFdmNodesPromise = Promise.resolve({ cadNode: cachedFdmData[0].cadNode, - fdmIds: cachedFdmData.map((data) => data.edge.startNode) + fdmIds: cachedFdmData.map((data) => data.connection.instance) }); const viewsPromise = this.assertOrFetchViewsForNodeData(searchTreeIndex, cachedFdmData); @@ -75,7 +75,7 @@ export class RevisionFdmNodeCache { private async assertOrFetchViewsForNodeData( searchTreeIndex: number, - cachedFdmData: FdmEdgeWithNode[] + cachedFdmData: FdmConnectionWithNode[] ): Promise { if (checkDefinedView(cachedFdmData)) { return cachedFdmData.map((data) => data.view); @@ -84,7 +84,7 @@ export class RevisionFdmNodeCache { const cadNode = cachedFdmData[0].cadNode; const cadNodeWithEdges = { cadNode, - edges: cachedFdmData.map((data) => data.edge) + connections: cachedFdmData.map((data) => data.connection) }; return await this.getAndCacheViewsPromiseForNodeData(cadNodeWithEdges, [ @@ -100,7 +100,10 @@ export class RevisionFdmNodeCache { const cadAndFdmNodesPromise = cadAndEdgesPromise.then((cadAndEdges) => cadAndEdges === undefined ? undefined - : { cadNode: cadAndEdges.cadNode, fdmIds: cadAndEdges.edges.map((edge) => edge.startNode) } + : { + cadNode: cadAndEdges.cadNode, + fdmIds: cadAndEdges.connections.map((edge) => edge.instance) + } ); const viewsPromise = this.getViewsPromiseFromDataPromises( @@ -112,7 +115,7 @@ export class RevisionFdmNodeCache { } private async getViewsPromiseFromDataPromises( - cadAndEdgesPromise: Promise, + cadAndEdgesPromise: Promise, ancestorDataPromise: Promise ): Promise { const cadAndEdges = await cadAndEdgesPromise; @@ -120,12 +123,12 @@ export class RevisionFdmNodeCache { const ancestorTreeIndexes = ancestorsWithSameMapping.map((ancestor) => ancestor.treeIndex); const cachedTreeIndexesDescending = ancestorTreeIndexes - .filter((treeIndex) => this._treeIndexToFdmEdges.has(treeIndex)) + .filter((treeIndex) => this._treeIndexToFdmConnections.has(treeIndex)) .sort((a, b) => b - a); const cachedNodeData = cachedTreeIndexesDescending.length !== 0 - ? this._treeIndexToFdmEdges.get(cachedTreeIndexesDescending[0]) + ? this._treeIndexToFdmConnections.get(cachedTreeIndexesDescending[0]) : undefined; if (checkDefinedView(cachedNodeData)) { @@ -138,11 +141,11 @@ export class RevisionFdmNodeCache { private async getCadAndEdgesPromiseForAncestorData( ancestorDataPromise: Promise - ): Promise { - const { edges, ancestorsWithSameMapping, firstMappedAncestorTreeIndex } = + ): Promise { + const { connections, ancestorsWithSameMapping, firstMappedAncestorTreeIndex } = await ancestorDataPromise; - if (edges.length === 0) { + if (connections.length === 0) { this.setCacheDataForTreeIndices( ancestorsWithSameMapping.map((a) => a.treeIndex), [] @@ -156,17 +159,20 @@ export class RevisionFdmNodeCache { assert(firstMappedAncestor !== undefined); - return { cadNode: firstMappedAncestor, edges }; + return { cadNode: firstMappedAncestor, connections }; } - private setCacheDataForTreeIndices(treeIndices: number[], nodeData: FdmEdgeWithNode[]): void { + private setCacheDataForTreeIndices( + treeIndices: number[], + nodeData: FdmConnectionWithNode[] + ): void { treeIndices.forEach((treeIndex) => { - this._treeIndexToFdmEdges.set(treeIndex, nodeData); + this._treeIndexToFdmConnections.set(treeIndex, nodeData); }); } private async getAndCacheViewsPromiseForNodeData( - cadAndFdmIds: CadNodeWithEdges | undefined, + cadAndFdmIds: CadNodeWithConnections | undefined, ancestorIndicesWithSameMapping: TreeIndex[] ): Promise { if (cadAndFdmIds === undefined) { @@ -176,15 +182,15 @@ export class RevisionFdmNodeCache { const nodeInspectionResults = await inspectNodes( this._fdmClient, - cadAndFdmIds.edges.map((edge) => edge.startNode) + cadAndFdmIds.connections.map((edge) => edge.instance) ); const views = nodeInspectionResults.items.map( (item) => item.inspectionResults.involvedViews[0] ); - const dataWithViews = cadAndFdmIds.edges.map((edge, ind) => ({ - edge, + const dataWithViews = cadAndFdmIds.connections.map((connection, ind) => ({ + connection, cadNode: cadAndFdmIds.cadNode, view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] })); @@ -205,51 +211,59 @@ export class RevisionFdmNodeCache { const ancestorMappings = await this.getMappingEdgesForAncestors(ancestors); if (ancestorMappings.length === 0) { - return { edges: [], ancestorsWithSameMapping: ancestors, firstMappedAncestorTreeIndex: -1 }; + return { + connections: [], + ancestorsWithSameMapping: ancestors, + firstMappedAncestorTreeIndex: -1 + }; } - const edgesWithCorrespondingTreeIndex = this.combineEdgesWithTreeIndex( + const connectionsWithCorrespondingTreeIndex = this.combineEdgesWithTreeIndex( ancestorMappings, ancestors ); - const firstMappedAncestorTreeIndex = findLargestTreeIndex(edgesWithCorrespondingTreeIndex); + const firstMappedAncestorTreeIndex = findLargestTreeIndex( + connectionsWithCorrespondingTreeIndex + ); return getAncestorDataForTreeIndex( firstMappedAncestorTreeIndex, - edgesWithCorrespondingTreeIndex, + connectionsWithCorrespondingTreeIndex, ancestors ); } private combineEdgesWithTreeIndex( - mappingEdges: FdmCadEdge[], + mappingEdges: FdmCadConnection[], nodes: Node3D[] - ): Array<{ edge: FdmCadEdge; treeIndex: TreeIndex }> { - return mappingEdges.map((edge) => { + ): Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> { + return mappingEdges.map((connection) => { const ancestorConnectedToEdge = nodes.find( - (ancestor) => ancestor.id === edge.properties.revisionNodeId + (ancestor) => ancestor.id === connection.revisionId ); assert(ancestorConnectedToEdge !== undefined); return { - edge, + connection, treeIndex: ancestorConnectedToEdge.treeIndex }; }); } - private async getMappingEdgesForAncestors(ancestors: Node3D[]): Promise { + private async getMappingEdgesForAncestors(ancestors: Node3D[]): Promise { const cachedFirstMappedAncestor = ancestors - .filter((ancestor) => this._treeIndexToFdmEdges.has(ancestor.treeIndex)) + .filter((ancestor) => this._treeIndexToFdmConnections.has(ancestor.treeIndex)) .sort((nodeA, nodeB) => nodeB.treeIndex - nodeA.treeIndex)[0]; if (cachedFirstMappedAncestor !== undefined) { - const edgesAndNodes = this._treeIndexToFdmEdges.get(cachedFirstMappedAncestor.treeIndex); + const edgesAndNodes = this._treeIndexToFdmConnections.get( + cachedFirstMappedAncestor.treeIndex + ); assert(edgesAndNodes !== undefined); - return edgesAndNodes.map((edge) => edge.edge); + return edgesAndNodes.map((edge) => edge.connection); } const modelInstances = await this._modelInstances; if (modelInstances === undefined) { @@ -263,22 +277,22 @@ export class RevisionFdmNodeCache { ancestors.map((a) => a.id) ); - return ancestorMappings.edges; + return ancestorMappings; } public async fetchViewsForAllEdges(): Promise { - const allEdgesWithoutView = this.getAllEdges().filter((edge) => edge.view === undefined); + const allConnectionsWithoutView = this.getAllEdges().filter((edge) => edge.view === undefined); - if (allEdgesWithoutView.length === 0) { + if (allConnectionsWithoutView.length === 0) { return; } const nodeInspectionResults = await inspectNodes( this._fdmClient, - allEdgesWithoutView.map((edge) => edge.edge.startNode) + allConnectionsWithoutView.map((connection) => connection.connection.instance) ); - allEdgesWithoutView.forEach((fdmEdgeWithNode, ind) => { + allConnectionsWithoutView.forEach((fdmEdgeWithNode, ind) => { const edgeWithView = { ...fdmEdgeWithNode, view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] @@ -288,11 +302,11 @@ export class RevisionFdmNodeCache { }); } - public insertTreeIndexMappings(treeIndex: TreeIndex, edge: FdmEdgeWithNode): void { - const edgeArray = this._treeIndexToFdmEdges.get(treeIndex); + public insertTreeIndexMappings(treeIndex: TreeIndex, edge: FdmConnectionWithNode): void { + const edgeArray = this._treeIndexToFdmConnections.get(treeIndex); if (edgeArray === undefined) { - this._treeIndexToFdmEdges.set(treeIndex, [edge]); + this._treeIndexToFdmConnections.set(treeIndex, [edge]); } else { const presentEdge = edgeArray?.find((e) => e.cadNode.id === edge.cadNode.id); @@ -305,13 +319,13 @@ export class RevisionFdmNodeCache { } } - public getAllEdges(): FdmEdgeWithNode[] { - return [...this._treeIndexToFdmEdges.values()].flat(); + public getAllEdges(): FdmConnectionWithNode[] { + return [...this._treeIndexToFdmConnections.values()].flat(); } } function findLargestTreeIndex( - edgesWithTreeIndex: Array<{ edge: FdmCadEdge; treeIndex: TreeIndex }> + edgesWithTreeIndex: Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> ): TreeIndex { const maxTreeIndex = max(edgesWithTreeIndex.map((e) => e.treeIndex)); assert(maxTreeIndex !== undefined); @@ -320,25 +334,25 @@ function findLargestTreeIndex( function getAncestorDataForTreeIndex( treeIndex: TreeIndex, - edgesWithTreeIndex: Array<{ edge: FdmCadEdge; treeIndex: TreeIndex }>, + connectionsWithTreeIndex: Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }>, ancestors: Node3D[] ): AncestorQueryResult { - const edgesForTreeIndex = edgesWithTreeIndex.filter( + const edgesForTreeIndex = connectionsWithTreeIndex.filter( (edgeAndTreeIndex) => edgeAndTreeIndex.treeIndex === treeIndex ); const ancestorsBelowTreeIndex = ancestors.filter((ancestor) => ancestor.treeIndex >= treeIndex); return { - edges: edgesForTreeIndex.map((result) => result.edge), + connections: edgesForTreeIndex.map((result) => result.connection), ancestorsWithSameMapping: ancestorsBelowTreeIndex, firstMappedAncestorTreeIndex: treeIndex }; } export function checkDefinedView( - edges?: FdmEdgeWithNode[] -): edges is Array> { + edges?: FdmConnectionWithNode[] +): edges is Array> { if (edges === undefined) return false; - return edges?.every((edge): edge is Required => edge.view !== undefined); + return edges?.every((edge): edge is Required => edge.view !== undefined); } diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index 23f9a2071f7..ffc8490eeee 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -7,9 +7,10 @@ import { type Source, type DmsUniqueIdentifier, type FdmSDK, - type InspectResultList -} from '../../utilities/FdmSDK'; -import { type FdmCadEdge } from './types'; + type InspectResultList, + type EdgeItem +} from '../../data-providers/FdmSDK'; +import { type FdmCadConnection } from './types'; import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE, @@ -62,7 +63,7 @@ export async function getMappingEdgesForNodeIds( revisionId: number, fdmClient: FdmSDK, ancestorIds: CogniteInternalId[] -): Promise<{ edges: FdmCadEdge[] }> { +): Promise { const filter = { and: [ { @@ -97,13 +98,24 @@ export async function getMappingEdgesForNodeIds( ] }; - const instances = await fdmClient.filterAllInstances( + const results = await fdmClient.filterAllInstances( filter, 'edge', SYSTEM_3D_EDGE_SOURCE ); - return { edges: instances.instances }; + return fdmEdgesToCadConnections(results.instances); +} + +export function fdmEdgesToCadConnections( + edges: Array> +): FdmCadConnection[] { + return edges.map((instance) => ({ + nodeId: instance.properties.revisionNodeId, + revisionId: instance.properties.revisionId, + modelId: Number(instance.endNode.externalId), + instance: instance.startNode + })); } export async function inspectNodes( diff --git a/react-components/src/components/CacheProvider/types.ts b/react-components/src/components/CacheProvider/types.ts index e1ac16a90c4..63c861ecfe8 100644 --- a/react-components/src/components/CacheProvider/types.ts +++ b/react-components/src/components/CacheProvider/types.ts @@ -8,16 +8,24 @@ import { type Node3D, type AnnotationsCogniteAnnotationTypesImagesAssetLink } from '@cognite/sdk'; -import { type DmsUniqueIdentifier, type Source, type EdgeItem } from '../../utilities/FdmSDK'; -import { type InModel3dEdgeProperties } from '../../utilities/globalDataModels'; +import { type DmsUniqueIdentifier, type Source } from '../../data-providers/FdmSDK'; import { type AssetAnnotationImage360Info } from '@cognite/reveal'; import { type Vector3 } from 'three'; -export type FdmCadEdge = EdgeItem; -export type FdmEdgeWithNode = { edge: FdmCadEdge; cadNode: Node3D; view?: Source }; +export type FdmCadConnection = { + instance: DmsUniqueIdentifier; + modelId: number; + revisionId: number; + nodeId: number; +}; +export type FdmConnectionWithNode = { + connection: FdmCadConnection; + cadNode: Node3D; + view?: Source; +}; export type CadNodeWithFdmIds = { cadNode: Node3D; fdmIds: DmsUniqueIdentifier[] }; -export type CadNodeWithEdges = { cadNode: Node3D; edges: FdmCadEdge[] }; +export type CadNodeWithConnections = { cadNode: Node3D; connections: FdmCadConnection[] }; export type FdmNodeDataPromises = { cadAndFdmNodesPromise: Promise; viewsPromise: Promise; @@ -30,7 +38,7 @@ export type ModelRevisionAssetNodesResult = { }; export type AncestorQueryResult = { - edges: FdmCadEdge[]; + connections: FdmCadConnection[]; ancestorsWithSameMapping: Node3D[]; firstMappedAncestorTreeIndex: number; }; @@ -49,7 +57,7 @@ export type FdmKey = `${string}/${string}`; export type ModelNodeIdKey = `${ModelId}/${RevisionId}/${NodeId}`; export type ModelAssetIdKey = `${ModelId}/${RevisionId}/${AssetId}`; -export type ModelRevisionToEdgeMap = Map; +export type ModelRevisionToEdgeMap = Map; export type PointCloudAnnotationModel = AnnotationModel & { data: AnnotationsBoundingVolume }; diff --git a/react-components/src/components/Reveal3DResources/types.ts b/react-components/src/components/Reveal3DResources/types.ts index d94e75e93a2..1b97ef561a8 100644 --- a/react-components/src/components/Reveal3DResources/types.ts +++ b/react-components/src/components/Reveal3DResources/types.ts @@ -9,7 +9,7 @@ import { } from '@cognite/reveal'; import { type Matrix4 } from 'three'; -import { type DmsUniqueIdentifier, type Source } from '../../utilities/FdmSDK'; +import { type DmsUniqueIdentifier, type Source } from '../../data-providers/FdmSDK'; import { type CogniteInternalId, type Node3D } from '@cognite/sdk'; import { type TreeIndexStylingGroup } from '../CadModelContainer/types'; diff --git a/react-components/src/components/Reveal3DResources/useCalculateCadStyling.tsx b/react-components/src/components/Reveal3DResources/useCalculateCadStyling.tsx index 8fa743a5482..c9365e183a1 100644 --- a/react-components/src/components/Reveal3DResources/useCalculateCadStyling.tsx +++ b/react-components/src/components/Reveal3DResources/useCalculateCadStyling.tsx @@ -16,7 +16,7 @@ import { import { useMemo } from 'react'; import { type NodeId, - type FdmEdgeWithNode, + type FdmConnectionWithNode, type AssetId, type ModelRevisionAssetNodesResult } from '../CacheProvider/types'; @@ -326,7 +326,7 @@ function extractDefaultStyles(typedModels: CadModelOptions[]): StyledModel[] { } function getMappedStyleGroupFromFdm( - edges: FdmEdgeWithNode[], + edges: FdmConnectionWithNode[], mapped: NodeAppearance ): TreeIndexStylingGroup { const indexSet = new IndexSet(); diff --git a/react-components/src/components/RevealCanvas/SDKProvider.tsx b/react-components/src/components/RevealCanvas/SDKProvider.tsx index 77283bf5ba8..0279afe588d 100644 --- a/react-components/src/components/RevealCanvas/SDKProvider.tsx +++ b/react-components/src/components/RevealCanvas/SDKProvider.tsx @@ -3,7 +3,7 @@ */ import React, { useContext, createContext, useMemo } from 'react'; import { type CogniteClient } from '@cognite/sdk'; -import { FdmSDK } from '../../utilities/FdmSDK'; +import { FdmSDK } from '../../data-providers/FdmSDK'; const SdkContext = createContext(null); const FdmSdkContext = createContext(null); diff --git a/react-components/src/components/RevealToolbar/SceneList.tsx b/react-components/src/components/RevealToolbar/SceneList.tsx index 9aacc982b07..676114abcf2 100644 --- a/react-components/src/components/RevealToolbar/SceneList.tsx +++ b/react-components/src/components/RevealToolbar/SceneList.tsx @@ -5,7 +5,7 @@ import { type ReactElement } from 'react'; import { Menu } from '@cognite/cogs.js'; import { use3dScenes } from '../../query/use3dScenes'; -import { type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; export type SceneWithName = DmsUniqueIdentifier & { name: string }; diff --git a/react-components/src/components/RevealToolbar/SelectSceneButton.tsx b/react-components/src/components/RevealToolbar/SelectSceneButton.tsx index 9646b50427c..5da90c56ea8 100644 --- a/react-components/src/components/RevealToolbar/SelectSceneButton.tsx +++ b/react-components/src/components/RevealToolbar/SelectSceneButton.tsx @@ -6,7 +6,7 @@ import { useCallback, useState, type ReactElement } from 'react'; import { Button, Dropdown, Menu, Tooltip as CogsTooltip } from '@cognite/cogs.js'; import { use3dScenes } from '../../query/use3dScenes'; import { useTranslation } from '../i18n/I18n'; -import { type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { SceneList, type SceneWithName } from './SceneList'; import styled from 'styled-components'; diff --git a/react-components/src/components/RuleBasedOutputs/RuleBasedOutputsSelector.tsx b/react-components/src/components/RuleBasedOutputs/RuleBasedOutputsSelector.tsx index 8173c898fa3..b1e48b76191 100644 --- a/react-components/src/components/RuleBasedOutputs/RuleBasedOutputsSelector.tsx +++ b/react-components/src/components/RuleBasedOutputs/RuleBasedOutputsSelector.tsx @@ -9,7 +9,7 @@ import { generateRuleBasedOutputs } from './utils'; import { use3dModels } from '../../hooks/use3dModels'; import { type Datapoints, type Asset, type AssetMapping3D } from '@cognite/sdk'; import { isDefined } from '../../utilities/isDefined'; -import { type AssetIdsAndTimeseries } from '../../utilities/types'; +import { type AssetIdsAndTimeseries } from '../../data-providers/types'; import { useAssetsAndTimeseriesLinkageDataQuery } from '../../query/useAssetsAndTimeseriesLinkageDataQuery'; import { useAssetMappedNodesForRevisions } from '../CacheProvider/AssetMappingAndNode3DCacheProvider'; import { type CadModelOptions } from '../Reveal3DResources/types'; diff --git a/react-components/src/components/RuleBasedOutputs/constants.ts b/react-components/src/components/RuleBasedOutputs/constants.ts index 11ce0b083c6..1aed5afdb6e 100644 --- a/react-components/src/components/RuleBasedOutputs/constants.ts +++ b/react-components/src/components/RuleBasedOutputs/constants.ts @@ -2,7 +2,7 @@ * Copyright 2024 Cognite AS */ -import { type Source } from '../../utilities/FdmSDK'; +import { type Source } from '../../data-providers/FdmSDK'; export const RULE_BASED_OUTPUTS_VIEW: Source = { type: 'view', diff --git a/react-components/src/components/RuleBasedOutputs/hooks/useDeleteRuleInstance.tsx b/react-components/src/components/RuleBasedOutputs/hooks/useDeleteRuleInstance.tsx index ba0326cc04d..9f23e204139 100644 --- a/react-components/src/components/RuleBasedOutputs/hooks/useDeleteRuleInstance.tsx +++ b/react-components/src/components/RuleBasedOutputs/hooks/useDeleteRuleInstance.tsx @@ -6,7 +6,7 @@ import { useFdmSdk } from '../../RevealCanvas/SDKProvider'; import { RULE_BASED_OUTPUTS_VIEW } from '../constants'; import { type ExternalIdsResultList, type RuleOutputSet } from '../types'; import { fdmViewsExist } from '../../../utilities/fdmViewsExist'; -import { type FdmNode } from '../../../utilities/FdmSDK'; +import { type FdmNode } from '../../../data-providers/FdmSDK'; export const useDeleteRuleInstance = (): (( ruleOutputSet: FdmNode diff --git a/react-components/src/components/RuleBasedOutputs/types.ts b/react-components/src/components/RuleBasedOutputs/types.ts index a4fa20cbedc..4bdd4311c03 100644 --- a/react-components/src/components/RuleBasedOutputs/types.ts +++ b/react-components/src/components/RuleBasedOutputs/types.ts @@ -3,7 +3,7 @@ */ import { type TreeIndexNodeCollection, type NumericRange } from '@cognite/reveal'; -import { type FdmNode, type EdgeItem, type DmsUniqueIdentifier } from '../../utilities/FdmSDK'; +import { type FdmNode, type EdgeItem, type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; import { type AssetStylingGroup, type FdmPropertyType } from '../Reveal3DResources/types'; import { type Datapoints, type Asset, type Timeseries } from '@cognite/sdk'; diff --git a/react-components/src/components/RuleBasedOutputs/utils.ts b/react-components/src/components/RuleBasedOutputs/utils.ts index ac7753b20aa..c269f2d54e0 100644 --- a/react-components/src/components/RuleBasedOutputs/utils.ts +++ b/react-components/src/components/RuleBasedOutputs/utils.ts @@ -27,7 +27,7 @@ import { type AssetMapping3D, type Asset, type Datapoints } from '@cognite/sdk'; import { type AssetStylingGroup } from '../Reveal3DResources/types'; import { isDefined } from '../../utilities/isDefined'; import { assertNever } from '../../utilities/assertNever'; -import { type AssetIdsAndTimeseries } from '../../utilities/types'; +import { type AssetIdsAndTimeseries } from '../../data-providers/types'; const checkStringExpressionStatement = ( triggerTypeData: TriggerTypeData[], diff --git a/react-components/src/components/SceneContainer/Queries.tsx b/react-components/src/components/SceneContainer/Queries.tsx index 09c00771a4c..1bbdc68f1fe 100644 --- a/react-components/src/components/SceneContainer/Queries.tsx +++ b/react-components/src/components/SceneContainer/Queries.tsx @@ -2,7 +2,7 @@ * Copyright 2023 Cognite AS */ -import { type Query } from '../../utilities/FdmSDK'; +import { type Query } from '../../data-providers/FdmSDK'; export function createGetSceneQuery(sceneExternalId: string, sceneSpaceId: string): Query { return { diff --git a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts b/react-components/src/hooks/network/getCadModelsForFdmInstance.ts index e67685f7f4d..88855aa4ab8 100644 --- a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts +++ b/react-components/src/hooks/network/getCadModelsForFdmInstance.ts @@ -2,7 +2,7 @@ * Copyright 2024 Cognite AS */ import { type TaggedAddCadResourceOptions } from '../../components/Reveal3DResources/types'; -import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../utilities/FdmSDK'; +import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../data-providers/FdmSDK'; import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE diff --git a/react-components/src/hooks/network/getRelationships.ts b/react-components/src/hooks/network/getRelationships.ts index b55a5468ca3..1a532016f4a 100644 --- a/react-components/src/hooks/network/getRelationships.ts +++ b/react-components/src/hooks/network/getRelationships.ts @@ -10,7 +10,7 @@ import { import { getSourceRelationships } from './getSourceRelationships'; import { getTargetRelationships } from './getTargetRelationships'; -import { type ExtendedRelationship } from '../../utilities/types'; +import { type ExtendedRelationship } from '../../data-providers/types'; type Payload = { resourceExternalIds: CogniteExternalId[]; diff --git a/react-components/src/hooks/network/getSourceRelationships.ts b/react-components/src/hooks/network/getSourceRelationships.ts index 8d3d7c1f815..4bc6f12a8ad 100644 --- a/react-components/src/hooks/network/getSourceRelationships.ts +++ b/react-components/src/hooks/network/getSourceRelationships.ts @@ -9,7 +9,7 @@ import { } from '@cognite/sdk'; import { filterRelationships } from './filterRelationships'; -import { type ExtendedRelationship } from '../../utilities/types'; +import { type ExtendedRelationship } from '../../data-providers/types'; type Payload = { targetExternalIds: CogniteExternalId[]; diff --git a/react-components/src/hooks/network/getTargetRelationships.ts b/react-components/src/hooks/network/getTargetRelationships.ts index 01f4425910f..baeca78e13c 100644 --- a/react-components/src/hooks/network/getTargetRelationships.ts +++ b/react-components/src/hooks/network/getTargetRelationships.ts @@ -9,7 +9,7 @@ import { } from '@cognite/sdk'; import { filterRelationships } from './filterRelationships'; -import { type ExtendedRelationship } from '../../utilities/types'; +import { type ExtendedRelationship } from '../../data-providers/types'; type Payload = { sourceExternalIds: CogniteExternalId[]; diff --git a/react-components/src/hooks/types.ts b/react-components/src/hooks/types.ts index 05154ed08f7..de917dd2588 100644 --- a/react-components/src/hooks/types.ts +++ b/react-components/src/hooks/types.ts @@ -2,7 +2,7 @@ * Copyright 2023 Cognite AS */ import { type Node3D, type CogniteExternalId, type Asset } from '@cognite/sdk'; -import { type DmsUniqueIdentifier } from '../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { type AssetAnnotationImage360Info } from '@cognite/reveal'; export type ThreeDModelFdmMappings = { diff --git a/react-components/src/hooks/useClickedNode.tsx b/react-components/src/hooks/useClickedNode.tsx index 4f65043ef6d..690ec1d2c60 100644 --- a/react-components/src/hooks/useClickedNode.tsx +++ b/react-components/src/hooks/useClickedNode.tsx @@ -16,7 +16,7 @@ import { type NodeAssetMappingResult } from '../components/CacheProvider/AssetMa import { usePointCloudAnnotationMappingForAssetId } from '../components/CacheProvider/PointCloudAnnotationCacheProvider'; import { type PointCloudAnnotationMappedAssetData } from './types'; import { MOUSE, Vector2 } from 'three'; -import { type DmsUniqueIdentifier, type Source } from '../utilities/FdmSDK'; +import { type DmsUniqueIdentifier, type Source } from '../data-providers/FdmSDK'; import { useRenderTarget, useReveal } from '../components/RevealCanvas/ViewerContext'; export type AssetMappingDataResult = { diff --git a/react-components/src/index.ts b/react-components/src/index.ts index e5e054f9764..be2fd01ac16 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -120,8 +120,8 @@ export { type ThreeDModelFdmMappings } from './hooks/types'; export type { CameraNavigationActions } from './hooks/useCameraNavigation'; -export type { Source, DmsUniqueIdentifier } from './utilities/FdmSDK'; -export type { FdmInstanceWithView } from './utilities/types'; +export type { Source, DmsUniqueIdentifier } from './data-providers/FdmSDK'; +export type { FdmInstanceWithView } from './data-providers/types'; export type { QualitySettings } from './components/RevealToolbar/SettingsContainer/types'; export type { SceneIdentifiers } from './components/SceneContainer/sceneTypes'; @@ -165,4 +165,4 @@ export { RuleBasedOutputsPanel } from './components/RuleBasedOutputs/RuleBasedOu // Functions export { getRuleTriggerTypes } from './components/RuleBasedOutputs/utils'; -export type { InstanceReference, AssetInstanceReference } from './utilities/types'; +export type { InstanceReference, AssetInstanceReference } from './data-providers/types'; diff --git a/react-components/src/query/use3dNodeByExternalId.tsx b/react-components/src/query/use3dNodeByExternalId.tsx index 6db9dad1d01..9d4cb767628 100644 --- a/react-components/src/query/use3dNodeByExternalId.tsx +++ b/react-components/src/query/use3dNodeByExternalId.tsx @@ -4,7 +4,7 @@ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { useFdmNodeCache } from '../components/CacheProvider/NodeCacheProvider'; import { type Node3D } from '@cognite/sdk'; -import { type DmsUniqueIdentifier } from '../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { useReveal } from '../components/RevealCanvas/ViewerContext'; export const use3dNodeByExternalId = ({ diff --git a/react-components/src/query/use3dRelatedDirectConnections.ts b/react-components/src/query/use3dRelatedDirectConnections.ts index 968f7950c2c..06e85af14f0 100644 --- a/react-components/src/query/use3dRelatedDirectConnections.ts +++ b/react-components/src/query/use3dRelatedDirectConnections.ts @@ -4,9 +4,9 @@ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; -import { type Source, type DmsUniqueIdentifier } from '../utilities/FdmSDK'; +import { type Source, type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import assert from 'assert'; -import { type FdmInstanceWithView } from '../utilities/types'; +import { type FdmInstanceWithView } from '../data-providers/types'; export function use3dRelatedDirectConnections( instance: DmsUniqueIdentifier | undefined @@ -30,18 +30,15 @@ export function use3dRelatedDirectConnections( ) ).items[0]; - const directlyRelatedObjects = Object.values(instanceContent.properties) - .map((spaceScope) => - Object.values(spaceScope) - .map((fieldValues) => - Object.values(fieldValues).filter( - (value: any): value is DmsUniqueIdentifier => - value.externalId !== undefined && value.space !== undefined - ) + const directlyRelatedObjects = Object.values(instanceContent.properties).flatMap( + (spaceScope) => + Object.values(spaceScope).flatMap((fieldValues) => + Object.values(fieldValues).filter( + (value: any): value is DmsUniqueIdentifier => + value.externalId !== undefined && value.space !== undefined ) - .flat() - ) - .flat(); + ) + ); if (directlyRelatedObjects.length === 0) { return []; diff --git a/react-components/src/query/use3dRelatedEdgeConnections.ts b/react-components/src/query/use3dRelatedEdgeConnections.ts index 7add1876f3b..8d798f21b89 100644 --- a/react-components/src/query/use3dRelatedEdgeConnections.ts +++ b/react-components/src/query/use3dRelatedEdgeConnections.ts @@ -4,9 +4,9 @@ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; -import { type DmsUniqueIdentifier } from '../utilities/FdmSDK'; +import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { zipWith } from 'lodash'; -import { type FdmInstanceWithView } from '../utilities/types'; +import { type FdmInstanceWithView } from '../data-providers/types'; import assert from 'assert'; import { SYSTEM_3D_EDGE_SOURCE } from '../utilities/globalDataModels'; diff --git a/react-components/src/query/use3dScenes.tsx b/react-components/src/query/use3dScenes.tsx index 033900a3e9f..e1024e353fb 100644 --- a/react-components/src/query/use3dScenes.tsx +++ b/react-components/src/query/use3dScenes.tsx @@ -6,7 +6,7 @@ import { type QueryFunction, useQuery, type UseQueryResult } from '@tanstack/rea import { useSDK } from '../components/RevealCanvas/SDKProvider'; import { type CogniteClient } from '@cognite/sdk'; import { useMemo } from 'react'; -import { type EdgeItem, FdmSDK, type Query, type NodeItem } from '../utilities/FdmSDK'; +import { type EdgeItem, FdmSDK, type Query, type NodeItem } from '../data-providers/FdmSDK'; import { type SceneConfigurationProperties, type Cdf3dRevisionProperties, diff --git a/react-components/src/query/useAssetsAndTimeseriesLinkageDataQuery.ts b/react-components/src/query/useAssetsAndTimeseriesLinkageDataQuery.ts index b422e5287ea..c57288bca66 100644 --- a/react-components/src/query/useAssetsAndTimeseriesLinkageDataQuery.ts +++ b/react-components/src/query/useAssetsAndTimeseriesLinkageDataQuery.ts @@ -20,7 +20,7 @@ import { type AssetIdsAndTimeseries, type AssetAndTimeseriesIds, type AssetIdsAndTimeseriesData -} from '../utilities/types'; +} from '../data-providers/types'; import { queryKeys } from '../utilities/queryKeys'; import { getTimeseriesByIds } from '../hooks/network/getTimeseriesByIds'; import { isDefined } from '../utilities/isDefined'; diff --git a/react-components/src/query/useModelsForInstanceQuery.ts b/react-components/src/query/useModelsForInstanceQuery.ts index 3cee5c41a8d..29f82507b83 100644 --- a/react-components/src/query/useModelsForInstanceQuery.ts +++ b/react-components/src/query/useModelsForInstanceQuery.ts @@ -2,7 +2,7 @@ * Copyright 2024 Cognite AS */ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { type DmsUniqueIdentifier, type FdmSDK } from '../utilities/FdmSDK'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../data-providers/FdmSDK'; import { getCadModelsForAsset } from '../hooks/network/getCadModelsForAsset'; import { getPointCloudModelsForAsset } from '../hooks/network/getPointCloudModelsForAsset'; import { useFdmSdk, useSDK } from '../components/RevealCanvas/SDKProvider'; @@ -15,7 +15,7 @@ import { type InstanceReference, isAssetInstance, isDmsInstance -} from '../utilities/types'; +} from '../data-providers/types'; import { uniqBy } from 'lodash'; import { createAddOptionsKey } from '../utilities/createAddOptionsKey'; diff --git a/react-components/src/query/useSceneConfig.ts b/react-components/src/query/useSceneConfig.ts index 304eb274a5e..a0e5245a37f 100644 --- a/react-components/src/query/useSceneConfig.ts +++ b/react-components/src/query/useSceneConfig.ts @@ -19,7 +19,7 @@ import { type Skybox } from '../components/SceneContainer/sceneTypes'; import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; -import { type Source, type FdmSDK } from '../utilities/FdmSDK'; +import { type Source, type FdmSDK } from '../data-providers/FdmSDK'; import { type SceneConfigurationProperties } from '../hooks/types'; import { fdmViewsExist } from '../utilities/fdmViewsExist'; diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 0995befaf26..81bfcd7fa28 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -13,7 +13,7 @@ import { type Space, type ExternalId, type InstanceFilter -} from '../utilities/FdmSDK'; +} from '../data-providers/FdmSDK'; import { useSDK } from '../components/RevealCanvas/SDKProvider'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from '../utilities/globalDataModels'; diff --git a/react-components/src/utilities/FdmSDK.ts b/react-components/src/utilities/FdmSDK.ts deleted file mode 100644 index fee52ce6d6d..00000000000 --- a/react-components/src/utilities/FdmSDK.ts +++ /dev/null @@ -1,568 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ - -import { type CogniteClient } from '@cognite/sdk'; -import { type FdmPropertyType } from '../components/Reveal3DResources/types'; - -type InstanceType = 'node' | 'edge'; -type EdgeDirection = 'source' | 'destination'; - -export type InstanceFilter = Record; -type ViewPropertyReference = any; - -export type ExternalId = string; -export type Space = string; - -export type Item = { - instanceType: InstanceType; -} & DmsUniqueIdentifier; - -export type Source = { - type: 'view'; -} & SimpleSource; - -export type SimpleSource = { - version: string; -} & DmsUniqueIdentifier; - -export type DmsUniqueIdentifier = { - space: Space; - externalId: ExternalId; -}; - -export type ViewQueryFilter = { - view: Source; -}; - -export type ResultSetExpression = (NodeResultSetExpression | EdgeResultSetExpression) & { - limit?: number; - sort?: any[]; -}; - -export type NodeResultSetExpression = { - nodes: { - filter?: InstanceFilter; - from?: string; - through?: ViewPropertyReference; - chainTo?: EdgeDirection; - direction?: 'outwards' | 'inwards'; - }; -}; - -export type EdgeResultSetExpression = { - edges: { - filter?: InstanceFilter; - chainTo?: EdgeDirection; - from?: string; - nodeFilter?: InstanceFilter; - terminationFilter?: InstanceFilter; - maxDistance?: number; - direction?: 'outwards' | 'inwards'; - limitEach?: number; - }; -}; - -type SourceProperties = { - source: Source; - properties: readonly string[]; -}; - -export type Query = { - with: Record; - select: Record; - parameters?: Record; - cursors?: Record; -}; - -type QuerySelect = { - sources?: readonly SourceProperties[]; -}; - -export type EdgeItem> = { - instanceType: 'edge'; - version: number; - type: DmsUniqueIdentifier; - space: string; - externalId: string; - createdTime: number; - lastUpdatedTime: number; - startNode: DmsUniqueIdentifier; - endNode: DmsUniqueIdentifier; - properties: EdgeProperties; -}; - -export type NodeItem> = { - instanceType: 'node'; - version: number; - space: string; - externalId: string; - createdTime: number; - lastUpdatedTime: number; - deletedTime: number; - properties: FdmPropertyType; -}; - -export type FdmNode> = { - instanceType: 'node'; - version: number; - space: string; - externalId: string; - createdTime: number; - lastUpdatedTime: number; - deletedTime: number; - properties: PropertyType; -}; - -export type CreateInstanceItem> = { - instanceType: InstanceType; - externalId: string; - space: string; - sources: Array<{ source: Source; properties: PropertyType }>; -}; - -type InspectionOperations = - | { involvedContainers: Record; involvedViews?: Record } - | { involvedContainers?: Record; involvedViews: Record }; - -export type InspectFilter = { - inspectionOperations: InspectionOperations; - items: Array<{ instanceType: InstanceType; externalId: string; space: string }>; -}; - -export type InspectResult = { - involvedContainers: Array<{ - type: 'container'; - space: string; - externalId: string; - }>; - involvedViews: Source[]; -}; - -export type InspectResultList = { - items: Array<{ - instanceType: InstanceType; - externalId: string; - space: string; - inspectionResults: InspectResult; - }>; -}; - -type SelectKey = keyof T['select']; - -export type QueryResult = { - items: Record, NodeItem[] | EdgeItem[]>; - nextCursor: Record, string> | undefined; -}; - -export type ExternalIdsResultList = { - items: Array>; - typing?: Record< - string, - Record< - string, - Record< - string, - { - nullable?: boolean; - autoIncrement?: boolean; - defaultValue?: any; - description?: string; - name?: string; - type: { type: string }; - } - > - > - >; -}; - -export type ViewItem = { - externalId: string; - space: string; - version: string; - createdTime: number; - lastUpdatedTime: number; - writable: boolean; - usedFor: string; - isGlobal: boolean; - properties: Record>; - name: string; - implements: Source[]; -}; - -export type DataModelListResponse = { - items: Array<{ views: Source[] }>; -}; - -export class FdmSDK { - private readonly _sdk: CogniteClient; - private readonly _byIdsEndpoint: string; - private readonly _listEndpoint: string; - private readonly _inspectEndpoint: string; - private readonly _searchEndpoint: string; - private readonly _queryEndpoint: string; - private readonly _listViewsEndpoint: string; - private readonly _viewsByIdEndpoint: string; - private readonly _listDataModelsEndpoint: string; - private readonly _createUpdateInstancesEndpoint: string; - private readonly _deleteInstancesEndpoint: string; - - constructor(sdk: CogniteClient) { - const baseUrl = sdk.getBaseUrl(); - const project = sdk.project; - - const instancesBaseUrl = `${baseUrl}/api/v1/projects/${project}/models/instances`; - const viewsBaseUrl = `${baseUrl}/api/v1/projects/${project}/models/views`; - - this._listEndpoint = `${instancesBaseUrl}/list`; - this._queryEndpoint = `${instancesBaseUrl}/query`; - this._byIdsEndpoint = `${instancesBaseUrl}/byids`; - this._inspectEndpoint = `${instancesBaseUrl}/inspect`; - this._searchEndpoint = `${instancesBaseUrl}/search`; - this._listDataModelsEndpoint = `${baseUrl}/api/v1/projects/${project}/models/datamodels`; - this._viewsByIdEndpoint = `${viewsBaseUrl}/byids`; - this._listViewsEndpoint = viewsBaseUrl; - this._createUpdateInstancesEndpoint = instancesBaseUrl; - this._deleteInstancesEndpoint = `${instancesBaseUrl}/delete`; - - this._sdk = sdk; - } - - public async listViews( - space: string, - includeInheritedProperties: boolean = true - ): Promise<{ views: ViewItem[] }> { - const result = await this._sdk.get(this._listViewsEndpoint, { - params: { - includeInheritedProperties, - space - } - }); - - if (result.status === 200) { - return { views: result.data.items as ViewItem[] }; - } - throw new Error(`Failed to list views. Status: ${result.status}`); - } - - // eslint-disable-next-line no-dupe-class-members - public async searchInstances< - PropertiesType extends Record = Record - >( - searchedView: Source, - query: string, - instanceType?: InstanceType, - limit?: number, - filter?: InstanceFilter, - properties?: string[] - ): Promise<{ instances: Array | NodeItem> }>; - - // eslint-disable-next-line no-dupe-class-members - public async searchInstances< - PropertiesType extends Record = Record - >( - searchedView: Source, - query: string, - instanceType?: 'edge', - limit?: number, - filter?: InstanceFilter, - properties?: string[] - ): Promise<{ instances: Array> }>; - - // eslint-disable-next-line no-dupe-class-members - public async searchInstances>( - searchedView: Source, - query: string, - instanceType?: 'node', - limit?: number, - filter?: InstanceFilter, - properties?: string[] - ): Promise<{ instances: Array> }>; - - // eslint-disable-next-line no-dupe-class-members - public async searchInstances< - PropertiesType extends Record = Record - >( - searchedView: Source, - query: string, - instanceType?: InstanceType, - limit: number = 1000, - filter?: InstanceFilter, - properties?: string[] - ): Promise<{ instances: Array | NodeItem> }> { - filter = makeSureNonEmptyFilterForRequest(filter); - - const data: any = { - view: searchedView, - query, - instanceType, - filter, - properties, - limit - }; - - const result = await this._sdk.post(this._searchEndpoint, { data }); - - if (result.status === 200) { - hoistInstanceProperties( - searchedView, - result.data.items as Array> | Array> - ); - - return { instances: result.data.items }; - } - throw new Error(`Failed to search for instances. Status: ${result.status}`); - } - - // eslint-disable-next-line no-dupe-class-members - public async filterInstances>( - filter: InstanceFilter | undefined, - instanceType: InstanceType, - source: Source, - cursor?: string - ): Promise<{ - instances: Array | FdmNode>; - nextCursor?: string; - }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterInstances>( - filter: InstanceFilter | undefined, - instanceType: 'node', - source: Source, - cursor?: string - ): Promise<{ instances: Array>; nextCursor?: string }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterInstances>( - filter: InstanceFilter | undefined, - instanceType: 'edge', - source: Source, - cursor?: string - ): Promise<{ instances: Array>; nextCursor?: string }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterInstances>( - filter: InstanceFilter | undefined, - instanceType: InstanceType, - source: Source, - cursor?: string - ): Promise<{ - instances: Array | FdmNode>; - nextCursor?: string; - }> { - const data: any = { filter, instanceType }; - if (source !== null) { - data.sources = [{ source }]; - } - if (cursor !== undefined) { - data.cursor = cursor; - } - - const result = await this._sdk.post(this._listEndpoint, { data }); - - if (result.status !== 200) { - throw new Error(`Failed to fetch instances. Status: ${result.status}`); - } - - const typedResult = result.data.items as Array< - EdgeItem> | NodeItem> - >; - - hoistInstanceProperties(source, typedResult); - - return { - instances: result.data.items, - nextCursor: result.data.nextCursor - }; - } - - // eslint-disable-next-line no-dupe-class-members - public async filterAllInstances>( - filter: InstanceFilter, - instanceType: InstanceType, - source: Source - ): Promise<{ instances: Array | FdmNode> }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterAllInstances>( - filter: InstanceFilter, - instanceType: 'edge', - source: Source - ): Promise<{ instances: Array> }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterAllInstances>( - filter: InstanceFilter, - instanceType: 'node', - source: Source - ): Promise<{ instances: Array> }>; - - // eslint-disable-next-line no-dupe-class-members - public async filterAllInstances>( - filter: InstanceFilter | undefined, - instanceType: InstanceType, - source: Source - ): Promise<{ instances: Array | FdmNode> }> { - filter = makeSureNonEmptyFilterForRequest(filter); - - let mappings = await this.filterInstances(filter, instanceType, source); - - while (mappings.nextCursor !== undefined) { - const nextMappings = await this.filterInstances( - filter, - instanceType, - source, - mappings.nextCursor - ); - - mappings = { - instances: [...mappings.instances, ...nextMappings.instances], - nextCursor: nextMappings.nextCursor - }; - } - - return { instances: mappings.instances }; - } - - public async getByExternalIds( - queries: Array<{ instanceType: InstanceType; externalId: string; space: string }>, - source?: Source - ): Promise> { - const data: any = { items: queries, includeTyping: true }; - if (source !== null) { - data.sources = [{ source }]; - } - - const result = await this._sdk.post(this._byIdsEndpoint, { data }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to fetch instances. Status: ${result.status}`); - } - - public async createInstance( - queries: Array> - ): Promise> { - const data: any = { - items: queries, - autoCreateStartNodes: false, - autoCreateEndNodes: false, - skipOnVersionConflict: false, - replace: false - }; - - const result = await this._sdk.post(this._createUpdateInstancesEndpoint, { data }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to create instances. Status: ${result.status}`); - } - - public async editInstance( - queries: Array<{ - instanceType: InstanceType; - externalId: string; - space: string; - sources: [{ source: Source; properties: any }]; - }> - ): Promise> { - const data: any = { - items: queries, - autoCreateStartNodes: false, - autoCreateEndNodes: false, - skipOnVersionConflict: false, - replace: false - }; - - const result = await this._sdk.post(this._createUpdateInstancesEndpoint, { data }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to edit instances. Status: ${result.status}`); - } - - public async deleteInstances( - queries: Array<{ - instanceType: InstanceType; - externalId: string; - space: string; - }> - ): Promise> { - if (queries.length === 0) { - return { items: [] }; - } - - const data: any = { - items: queries - }; - - const result = await this._sdk.post(this._deleteInstancesEndpoint, { data }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to delete instances. Status: ${result.status}`); - } - - public async inspectInstances(inspectFilter: InspectFilter): Promise { - const result = await this._sdk.post(this._inspectEndpoint, { data: inspectFilter }); - - if (result.status === 200) { - return result.data as InspectResultList; - } - throw new Error(`Failed to fetch instances`); - } - - public async getViewsByIds(views: Source[]): Promise<{ items: ViewItem[] }> { - const result = await this._sdk.post(this._viewsByIdEndpoint, { - data: { - items: views.map((view) => ({ - externalId: view.externalId, - space: view.space, - version: view.version - })) - } - }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to fetch instances. Status: ${result.status}`); - } - - public async queryNodesAndEdges(query: T): Promise> { - const result = await this._sdk.post(this._queryEndpoint, { data: query }); - if (result.status === 200) { - return { items: result.data.items, nextCursor: result.data.nextCursor }; - } - throw new Error(`Failed to fetch instances. Status: ${result.status}`); - } - - public async listDataModels(): Promise { - const result = await this._sdk.get(this._listDataModelsEndpoint, { params: { limit: 1000 } }); - if (result.status === 200) { - return result.data; - } - throw new Error(`Failed to fetch data models. Status: ${result.status}`); - } -} - -function hoistInstanceProperties( - source: Source, - instances: Array> | NodeItem>> -): void { - if (source === undefined) { - return; - } - const propertyKey = `${source.externalId}/${source.version}`; - instances.forEach((instance) => { - if (instance.properties[source.space][propertyKey] !== undefined) { - instance.properties = instance.properties[source.space][propertyKey]; - } - }); -} - -function makeSureNonEmptyFilterForRequest( - filter: InstanceFilter | undefined -): InstanceFilter | undefined { - return filter !== undefined && Object.keys(filter).length === 0 ? undefined : filter; -} diff --git a/react-components/src/utilities/fdmViewsExist.ts b/react-components/src/utilities/fdmViewsExist.ts index e716f9a1d5a..3a4de2d3819 100644 --- a/react-components/src/utilities/fdmViewsExist.ts +++ b/react-components/src/utilities/fdmViewsExist.ts @@ -1,7 +1,7 @@ /*! * Copyright 2024 Cognite AS */ -import { type FdmSDK, type Source } from './FdmSDK'; +import { type FdmSDK, type Source } from '../data-providers/FdmSDK'; export async function fdmViewsExist(fdmSdk: FdmSDK, neededViews: Source[]): Promise { const views = await fdmSdk.getViewsByIds(neededViews); diff --git a/react-components/src/utilities/globalDataModels.ts b/react-components/src/utilities/globalDataModels.ts index c3260a5f679..2842822a433 100644 --- a/react-components/src/utilities/globalDataModels.ts +++ b/react-components/src/utilities/globalDataModels.ts @@ -1,7 +1,7 @@ /*! * Copyright 2023 Cognite AS */ -import { type DmsUniqueIdentifier, type Source } from './FdmSDK'; +import { type DmsUniqueIdentifier, type Source } from '../data-providers/FdmSDK'; export const SYSTEM_SPACE_3D_SCHEMA = 'cdf_3d_schema'; // Data model, views, containers and types for edges diff --git a/react-components/src/utilities/types.ts b/react-components/src/utilities/types.ts deleted file mode 100644 index 7101cb245d4..00000000000 --- a/react-components/src/utilities/types.ts +++ /dev/null @@ -1,60 +0,0 @@ -/*! - * Copyright 2024 Cognite AS - */ -import { - type Datapoints, - type Timeseries, - type ExternalId, - type InternalId, - type Metadata, - type Relationship -} from '@cognite/sdk/'; -import { type DmsUniqueIdentifier, type Source } from './FdmSDK'; - -export type FdmInstanceWithView = DmsUniqueIdentifier & { view: Source }; - -export type AssetInstanceReference = { assetId: number }; -export type InstanceReference = AssetInstanceReference | DmsUniqueIdentifier; - -export function isAssetInstance(instance: InstanceReference): instance is AssetInstanceReference { - return 'assetId' in instance; -} - -export function isDmsInstance(instance: InstanceReference): instance is DmsUniqueIdentifier { - return 'externalId' in instance && 'space' in instance; -} - -export type RelationshipsFilterInternal = { - labels?: string[]; -}; - -export type ExtendedRelationship = { - relation: 'Source' | 'Target'; -} & Relationship; - -export type RelationshipSourceAndTarget = { - source: RelationshipSourceAndTargetData; - target: RelationshipSourceAndTargetData; -}; -export type RelationshipSourceAndTargetData = { - externalId?: string; - id?: number; - metadata?: Metadata; -}; - -export type RelationshipData = ExtendedRelationship & RelationshipSourceAndTarget; - -export type AssetIdsAndTimeseries = { - assetIds?: Partial; - timeseries?: Timeseries | undefined; -}; - -export type AssetAndTimeseriesIds = { - assetIds: Partial; - timeseriesIds: Partial; -}; - -export type AssetIdsAndTimeseriesData = { - assetIdsWithTimeseries: AssetIdsAndTimeseries[]; - timeseriesDatapoints: Datapoints[]; -}; diff --git a/react-components/stories/CadStylingCache.stories.tsx b/react-components/stories/CadStylingCache.stories.tsx index 601fdc9b551..804e3aa2493 100644 --- a/react-components/stories/CadStylingCache.stories.tsx +++ b/react-components/stories/CadStylingCache.stories.tsx @@ -59,7 +59,7 @@ const Models = ({ addModelOptions }: CogniteCadModelProps): JSX.Element => { () => data ?.get(`${platformModelOptions.modelId}/${platformModelOptions.revisionId}`) - ?.map((edgeWithNode) => edgeWithNode.edge.properties.revisionNodeId), + ?.map((edgeWithNode) => edgeWithNode.connection.nodeId), [data] ); diff --git a/react-components/stories/SearchHooks.stories.tsx b/react-components/stories/SearchHooks.stories.tsx index ef94d796c82..bcfe7066047 100644 --- a/react-components/stories/SearchHooks.stories.tsx +++ b/react-components/stories/SearchHooks.stories.tsx @@ -35,7 +35,7 @@ import { useSearchAssetsMappedPointCloudAnnotations } from '../src/query/useSearchAssetsMappedPointCloudAnnotations'; import { isEqual } from 'lodash'; -import { type NodeItem } from '../src/utilities/FdmSDK'; +import { type NodeItem } from '../src/data-providers/FdmSDK'; import { Button, Input } from '@cognite/cogs.js'; import { is360ImageAddOptions } from '../src/components/Reveal3DResources/typeGuards'; From 62ebfd7de05ad8e135c766d3be5196431ed2d293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Tue, 23 Jul 2024 16:37:22 +0200 Subject: [PATCH 02/12] temp: WIP legacy Fdm3dDataProvider --- .../components/CacheProvider/FdmNodeCache.ts | 2 +- .../CacheProvider/RevisionFdmNodeCache.ts | 15 +- .../src/components/CacheProvider/requests.ts | 83 +-- .../RevealCanvas/FdmDataProviderContext.ts | 15 + .../components/RevealCanvas/SDKProvider.tsx | 27 +- .../src/data-providers/Fdm3dDataProvider.ts | 58 ++ react-components/src/data-providers/FdmSDK.ts | 568 ++++++++++++++++++ .../LegacyFdm3dDataProvider.ts | 65 ++ .../createMappedEquipmentQuery.ts | 70 +++ .../legacy-fdm-provider/dataModels.ts} | 2 +- .../fdmEdgesToCadConnections.ts | 14 + .../filterNodesByMappedTo3d.ts | 227 +++++++ .../legacy-fdm-provider/getDMSModels.ts | 27 + .../getEdgeConnected3dInstances.ts | 90 +++ .../getFdmConnectionsForNodeIds.ts | 54 ++ .../legacy-fdm-provider/listMappedFdmNodes.ts | 85 +++ react-components/src/data-providers/types.ts | 60 ++ .../network/getCadModelsForFdmInstance.ts | 2 +- react-components/src/index.ts | 2 +- .../query/use3dRelatedDirectConnections.ts | 5 +- .../src/query/use3dRelatedEdgeConnections.ts | 97 +-- .../src/query/useSearchMappedEquipmentFDM.tsx | 398 +----------- 22 files changed, 1404 insertions(+), 562 deletions(-) create mode 100644 react-components/src/components/RevealCanvas/FdmDataProviderContext.ts create mode 100644 react-components/src/data-providers/Fdm3dDataProvider.ts create mode 100644 react-components/src/data-providers/FdmSDK.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts rename react-components/src/{utilities/globalDataModels.ts => data-providers/legacy-fdm-provider/dataModels.ts} (91%) create mode 100644 react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts create mode 100644 react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts create mode 100644 react-components/src/data-providers/types.ts diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 74b97d0d9cc..5b3bf2159c8 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -27,7 +27,7 @@ import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA -} from '../../utilities/globalDataModels'; +} from '../../data-providers/legacy-fdm-provider/dataModels'; import { partition } from 'lodash'; diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index f82650dd38b..329b6bf1148 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -13,20 +13,17 @@ import { type AncestorQueryResult } from './types'; -import { - fetchAncestorNodesForTreeIndex, - getDMSModels, - getMappingEdgesForNodeIds, - inspectNodes -} from './requests'; +import { fetchAncestorNodesForTreeIndex, inspectNodes } from './requests'; import { max } from 'lodash'; import assert from 'assert'; +import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; export class RevisionFdmNodeCache { private readonly _cogniteClient: CogniteClient; private readonly _fdmClient: FdmSDK; + private readonly _fdmDataProvider: Fdm3dDataProvider; private readonly _modelId: number; private readonly _revisionId: number; @@ -38,15 +35,17 @@ export class RevisionFdmNodeCache { constructor( cogniteClient: CogniteClient, fdmClient: FdmSDK, + fdmDataProvider: Fdm3dDataProvider, modelId: number, revisionId: number ) { this._cogniteClient = cogniteClient; this._fdmClient = fdmClient; + this._fdmDataProvider = fdmDataProvider; this._modelId = modelId; this._revisionId = revisionId; - this._modelInstances = getDMSModels(this._modelId, this._fdmClient).catch(() => undefined); + this._modelInstances = fdmDataProvider.getDMSModels(this._modelId).catch(() => undefined); } public getClosestParentFdmData(searchTreeIndex: number): FdmNodeDataPromises { @@ -270,7 +269,7 @@ export class RevisionFdmNodeCache { return []; } - const ancestorMappings = await getMappingEdgesForNodeIds( + const ancestorMappings = await getFdmConnectionsForNodeIds( modelInstances, this._revisionId, this._fdmClient, diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index ffc8490eeee..4649b103e48 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -17,7 +17,7 @@ import { SYSTEM_SPACE_3D_SCHEMA, SYSTEM_SPACE_3D_MODEL_ID, SYSTEM_SPACE_3D_MODEL_VERSION -} from '../../utilities/globalDataModels'; +} from '../../data-providers/legacy-fdm-provider/dataModels'; import { chunk } from 'lodash'; export async function fetchAncestorNodesForTreeIndex( @@ -37,87 +37,6 @@ export async function fetchAncestorNodesForTreeIndex( return ancestorNodes.items; } -export async function getDMSModels( - modelId: number, - fdmClient: FdmSDK -): Promise { - const filter = { - equals: { - property: ['node', 'externalId'], - value: `${modelId}` - } - }; - const sources: Source = { - type: 'view', - space: SYSTEM_SPACE_3D_SCHEMA, - externalId: SYSTEM_SPACE_3D_MODEL_ID, - version: SYSTEM_SPACE_3D_MODEL_VERSION - }; - - const modelResults = await fdmClient.filterInstances(filter, 'node', sources); - return modelResults.instances; -} - -export async function getMappingEdgesForNodeIds( - models: DmsUniqueIdentifier[], - revisionId: number, - fdmClient: FdmSDK, - ancestorIds: CogniteInternalId[] -): Promise { - const filter = { - and: [ - { - in: { - property: ['edge', 'endNode'], - values: models.map((model) => ({ - externalId: model.externalId, - space: model.space - })) - } - }, - { - equals: { - property: [ - SYSTEM_3D_EDGE_SOURCE.space, - `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, - 'revisionId' - ], - value: revisionId - } - }, - { - in: { - property: [ - SYSTEM_3D_EDGE_SOURCE.space, - `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, - 'revisionNodeId' - ], - values: ancestorIds - } - } - ] - }; - - const results = await fdmClient.filterAllInstances( - filter, - 'edge', - SYSTEM_3D_EDGE_SOURCE - ); - - return fdmEdgesToCadConnections(results.instances); -} - -export function fdmEdgesToCadConnections( - edges: Array> -): FdmCadConnection[] { - return edges.map((instance) => ({ - nodeId: instance.properties.revisionNodeId, - revisionId: instance.properties.revisionId, - modelId: Number(instance.endNode.externalId), - instance: instance.startNode - })); -} - export async function inspectNodes( fdmClient: FdmSDK, dataNodes: DmsUniqueIdentifier[] diff --git a/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts b/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts new file mode 100644 index 00000000000..5640d5e842d --- /dev/null +++ b/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts @@ -0,0 +1,15 @@ +import { FdmSDK } from '../../data-providers/FdmSDK'; +import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +import { createContext } from 'react'; + +/** + * Includes both the low-level SDK and a higher-level fdm3dDataprovider. + * The latter is adviced used (and extended) for all 3D-related queries, while the + * FdmSDK can be used for all other queries + */ +export type FdmDataProviderContextContent = { + fdmSdk: FdmSDK; + fdm3dDataProvider: Fdm3dDataProvider; +}; + +export const FdmSdkContext = createContext(null); diff --git a/react-components/src/components/RevealCanvas/SDKProvider.tsx b/react-components/src/components/RevealCanvas/SDKProvider.tsx index 0279afe588d..e75b368b625 100644 --- a/react-components/src/components/RevealCanvas/SDKProvider.tsx +++ b/react-components/src/components/RevealCanvas/SDKProvider.tsx @@ -3,20 +3,26 @@ */ import React, { useContext, createContext, useMemo } from 'react'; import { type CogniteClient } from '@cognite/sdk'; +import { FdmSdkContext } from './FdmDataProviderContext'; import { FdmSDK } from '../../data-providers/FdmSDK'; +import { LegacyFdm3dDataProvider } from '../../data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider'; +import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; const SdkContext = createContext(null); -const FdmSdkContext = createContext(null); + SdkContext.displayName = 'CogniteSdkProvider'; FdmSdkContext.displayName = 'FdmSdkProvider'; type Props = { sdk: CogniteClient; children: any }; + export function SDKProvider({ sdk, children }: Props): React.ReactElement { const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); + const fdm3dDataProvider = new LegacyFdm3dDataProvider(fdmSdk); + const content = useMemo(() => ({ fdmSdk, fdm3dDataProvider }), [fdmSdk, fdm3dDataProvider]); return ( - {children} + {children} ); } @@ -37,11 +43,22 @@ export const useSDK = (userSdk?: CogniteClient): CogniteClient => { }; export const useFdmSdk = (): FdmSDK => { - const fdmSdk = useContext(FdmSdkContext); - if (fdmSdk === null) { + const fdmProvider = useContext(FdmSdkContext); + if (fdmProvider === null) { throw new Error( `FdmSdkContext not found, add '' around your component/app` ); } - return fdmSdk; + return fdmProvider.fdmSdk; +}; + +export const useFdm3dDataProvider = (): Fdm3dDataProvider => { + const fdmProvider = useContext(FdmSdkContext); + if (fdmProvider === null) { + throw new Error( + `FdmSdkContext not found, add '' around your component/app` + ); + } + + return fdmProvider.fdm3dDataProvider; }; diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts new file mode 100644 index 00000000000..3c23f9fdb8d --- /dev/null +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -0,0 +1,58 @@ +/*! + * Copyright 2024 Cognite AS + */ +import { + InstanceFilter, + NodeItem, + Source, + type DmsUniqueIdentifier, + type ViewItem +} from './FdmSDK'; +import { type AddModelOptions } from '@cognite/reveal'; +import { type InstancesWithView } from '../query/useSearchMappedEquipmentFDM'; +import { type FdmCadConnection } from '../components/CacheProvider/types'; +import { TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; + +export type Fdm3dDataProvider = { + is3dView: (view: ViewItem) => boolean; // use3drelatedDirectConnection + getDMSModels(modelId: number): Promise; + getEdgeConnected3dInstances: (instance: DmsUniqueIdentifier) => Promise; // use3drelateddirectconnection + getFdmConnectionsForNodeIds( + models: DmsUniqueIdentifier[], + revisionId: number, + nodeIds: number[] + ): Promise; // CacheProvider / requests.ts / getFdmConnectionsForNodeIds + + listMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instancesFilter: InstanceFilter | undefined, + limit: number + ): Promise; // useSearchMappedEquipmentFdm + + listAllMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined + ): Promise; + + filterNodesByMappedTo3d( + nodes: InstancesWithView[], + models: AddModelOptions[], + spacesToSearch: string[] + ): Promise; // useSearchMappedEquipmentFdm + getModelsForInstance(instance: DmsUniqueIdentifier): Promise; // useModelsForInstanceQuery (only support CAD for now?) + getCadConnectionsForRevisions(revisions: number[]): Promise; // FdmNodeCache.ts / getEdgesForRevisions +}; + +/* use3dRelatedDirectConnections() - + use3dRelatedEdgeConnections(related3dEdgesQuery) - + `useSearchMappedEquipmentFDM`( + createMappedEquipmentQuery, + createCheckMappedEquipmentQuery, + createInModelsFilter + ) - + getCadModelsForFdmInstance.ts(getCadModelsForFdmInstance) - + CacheProvider / requests.ts(getMappingEdgesForNodeIds, getDMSModels) - + FdmNodeCache.ts(getEdgesForRevisions); +*/ diff --git a/react-components/src/data-providers/FdmSDK.ts b/react-components/src/data-providers/FdmSDK.ts new file mode 100644 index 00000000000..fee52ce6d6d --- /dev/null +++ b/react-components/src/data-providers/FdmSDK.ts @@ -0,0 +1,568 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { type CogniteClient } from '@cognite/sdk'; +import { type FdmPropertyType } from '../components/Reveal3DResources/types'; + +type InstanceType = 'node' | 'edge'; +type EdgeDirection = 'source' | 'destination'; + +export type InstanceFilter = Record; +type ViewPropertyReference = any; + +export type ExternalId = string; +export type Space = string; + +export type Item = { + instanceType: InstanceType; +} & DmsUniqueIdentifier; + +export type Source = { + type: 'view'; +} & SimpleSource; + +export type SimpleSource = { + version: string; +} & DmsUniqueIdentifier; + +export type DmsUniqueIdentifier = { + space: Space; + externalId: ExternalId; +}; + +export type ViewQueryFilter = { + view: Source; +}; + +export type ResultSetExpression = (NodeResultSetExpression | EdgeResultSetExpression) & { + limit?: number; + sort?: any[]; +}; + +export type NodeResultSetExpression = { + nodes: { + filter?: InstanceFilter; + from?: string; + through?: ViewPropertyReference; + chainTo?: EdgeDirection; + direction?: 'outwards' | 'inwards'; + }; +}; + +export type EdgeResultSetExpression = { + edges: { + filter?: InstanceFilter; + chainTo?: EdgeDirection; + from?: string; + nodeFilter?: InstanceFilter; + terminationFilter?: InstanceFilter; + maxDistance?: number; + direction?: 'outwards' | 'inwards'; + limitEach?: number; + }; +}; + +type SourceProperties = { + source: Source; + properties: readonly string[]; +}; + +export type Query = { + with: Record; + select: Record; + parameters?: Record; + cursors?: Record; +}; + +type QuerySelect = { + sources?: readonly SourceProperties[]; +}; + +export type EdgeItem> = { + instanceType: 'edge'; + version: number; + type: DmsUniqueIdentifier; + space: string; + externalId: string; + createdTime: number; + lastUpdatedTime: number; + startNode: DmsUniqueIdentifier; + endNode: DmsUniqueIdentifier; + properties: EdgeProperties; +}; + +export type NodeItem> = { + instanceType: 'node'; + version: number; + space: string; + externalId: string; + createdTime: number; + lastUpdatedTime: number; + deletedTime: number; + properties: FdmPropertyType; +}; + +export type FdmNode> = { + instanceType: 'node'; + version: number; + space: string; + externalId: string; + createdTime: number; + lastUpdatedTime: number; + deletedTime: number; + properties: PropertyType; +}; + +export type CreateInstanceItem> = { + instanceType: InstanceType; + externalId: string; + space: string; + sources: Array<{ source: Source; properties: PropertyType }>; +}; + +type InspectionOperations = + | { involvedContainers: Record; involvedViews?: Record } + | { involvedContainers?: Record; involvedViews: Record }; + +export type InspectFilter = { + inspectionOperations: InspectionOperations; + items: Array<{ instanceType: InstanceType; externalId: string; space: string }>; +}; + +export type InspectResult = { + involvedContainers: Array<{ + type: 'container'; + space: string; + externalId: string; + }>; + involvedViews: Source[]; +}; + +export type InspectResultList = { + items: Array<{ + instanceType: InstanceType; + externalId: string; + space: string; + inspectionResults: InspectResult; + }>; +}; + +type SelectKey = keyof T['select']; + +export type QueryResult = { + items: Record, NodeItem[] | EdgeItem[]>; + nextCursor: Record, string> | undefined; +}; + +export type ExternalIdsResultList = { + items: Array>; + typing?: Record< + string, + Record< + string, + Record< + string, + { + nullable?: boolean; + autoIncrement?: boolean; + defaultValue?: any; + description?: string; + name?: string; + type: { type: string }; + } + > + > + >; +}; + +export type ViewItem = { + externalId: string; + space: string; + version: string; + createdTime: number; + lastUpdatedTime: number; + writable: boolean; + usedFor: string; + isGlobal: boolean; + properties: Record>; + name: string; + implements: Source[]; +}; + +export type DataModelListResponse = { + items: Array<{ views: Source[] }>; +}; + +export class FdmSDK { + private readonly _sdk: CogniteClient; + private readonly _byIdsEndpoint: string; + private readonly _listEndpoint: string; + private readonly _inspectEndpoint: string; + private readonly _searchEndpoint: string; + private readonly _queryEndpoint: string; + private readonly _listViewsEndpoint: string; + private readonly _viewsByIdEndpoint: string; + private readonly _listDataModelsEndpoint: string; + private readonly _createUpdateInstancesEndpoint: string; + private readonly _deleteInstancesEndpoint: string; + + constructor(sdk: CogniteClient) { + const baseUrl = sdk.getBaseUrl(); + const project = sdk.project; + + const instancesBaseUrl = `${baseUrl}/api/v1/projects/${project}/models/instances`; + const viewsBaseUrl = `${baseUrl}/api/v1/projects/${project}/models/views`; + + this._listEndpoint = `${instancesBaseUrl}/list`; + this._queryEndpoint = `${instancesBaseUrl}/query`; + this._byIdsEndpoint = `${instancesBaseUrl}/byids`; + this._inspectEndpoint = `${instancesBaseUrl}/inspect`; + this._searchEndpoint = `${instancesBaseUrl}/search`; + this._listDataModelsEndpoint = `${baseUrl}/api/v1/projects/${project}/models/datamodels`; + this._viewsByIdEndpoint = `${viewsBaseUrl}/byids`; + this._listViewsEndpoint = viewsBaseUrl; + this._createUpdateInstancesEndpoint = instancesBaseUrl; + this._deleteInstancesEndpoint = `${instancesBaseUrl}/delete`; + + this._sdk = sdk; + } + + public async listViews( + space: string, + includeInheritedProperties: boolean = true + ): Promise<{ views: ViewItem[] }> { + const result = await this._sdk.get(this._listViewsEndpoint, { + params: { + includeInheritedProperties, + space + } + }); + + if (result.status === 200) { + return { views: result.data.items as ViewItem[] }; + } + throw new Error(`Failed to list views. Status: ${result.status}`); + } + + // eslint-disable-next-line no-dupe-class-members + public async searchInstances< + PropertiesType extends Record = Record + >( + searchedView: Source, + query: string, + instanceType?: InstanceType, + limit?: number, + filter?: InstanceFilter, + properties?: string[] + ): Promise<{ instances: Array | NodeItem> }>; + + // eslint-disable-next-line no-dupe-class-members + public async searchInstances< + PropertiesType extends Record = Record + >( + searchedView: Source, + query: string, + instanceType?: 'edge', + limit?: number, + filter?: InstanceFilter, + properties?: string[] + ): Promise<{ instances: Array> }>; + + // eslint-disable-next-line no-dupe-class-members + public async searchInstances>( + searchedView: Source, + query: string, + instanceType?: 'node', + limit?: number, + filter?: InstanceFilter, + properties?: string[] + ): Promise<{ instances: Array> }>; + + // eslint-disable-next-line no-dupe-class-members + public async searchInstances< + PropertiesType extends Record = Record + >( + searchedView: Source, + query: string, + instanceType?: InstanceType, + limit: number = 1000, + filter?: InstanceFilter, + properties?: string[] + ): Promise<{ instances: Array | NodeItem> }> { + filter = makeSureNonEmptyFilterForRequest(filter); + + const data: any = { + view: searchedView, + query, + instanceType, + filter, + properties, + limit + }; + + const result = await this._sdk.post(this._searchEndpoint, { data }); + + if (result.status === 200) { + hoistInstanceProperties( + searchedView, + result.data.items as Array> | Array> + ); + + return { instances: result.data.items }; + } + throw new Error(`Failed to search for instances. Status: ${result.status}`); + } + + // eslint-disable-next-line no-dupe-class-members + public async filterInstances>( + filter: InstanceFilter | undefined, + instanceType: InstanceType, + source: Source, + cursor?: string + ): Promise<{ + instances: Array | FdmNode>; + nextCursor?: string; + }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterInstances>( + filter: InstanceFilter | undefined, + instanceType: 'node', + source: Source, + cursor?: string + ): Promise<{ instances: Array>; nextCursor?: string }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterInstances>( + filter: InstanceFilter | undefined, + instanceType: 'edge', + source: Source, + cursor?: string + ): Promise<{ instances: Array>; nextCursor?: string }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterInstances>( + filter: InstanceFilter | undefined, + instanceType: InstanceType, + source: Source, + cursor?: string + ): Promise<{ + instances: Array | FdmNode>; + nextCursor?: string; + }> { + const data: any = { filter, instanceType }; + if (source !== null) { + data.sources = [{ source }]; + } + if (cursor !== undefined) { + data.cursor = cursor; + } + + const result = await this._sdk.post(this._listEndpoint, { data }); + + if (result.status !== 200) { + throw new Error(`Failed to fetch instances. Status: ${result.status}`); + } + + const typedResult = result.data.items as Array< + EdgeItem> | NodeItem> + >; + + hoistInstanceProperties(source, typedResult); + + return { + instances: result.data.items, + nextCursor: result.data.nextCursor + }; + } + + // eslint-disable-next-line no-dupe-class-members + public async filterAllInstances>( + filter: InstanceFilter, + instanceType: InstanceType, + source: Source + ): Promise<{ instances: Array | FdmNode> }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterAllInstances>( + filter: InstanceFilter, + instanceType: 'edge', + source: Source + ): Promise<{ instances: Array> }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterAllInstances>( + filter: InstanceFilter, + instanceType: 'node', + source: Source + ): Promise<{ instances: Array> }>; + + // eslint-disable-next-line no-dupe-class-members + public async filterAllInstances>( + filter: InstanceFilter | undefined, + instanceType: InstanceType, + source: Source + ): Promise<{ instances: Array | FdmNode> }> { + filter = makeSureNonEmptyFilterForRequest(filter); + + let mappings = await this.filterInstances(filter, instanceType, source); + + while (mappings.nextCursor !== undefined) { + const nextMappings = await this.filterInstances( + filter, + instanceType, + source, + mappings.nextCursor + ); + + mappings = { + instances: [...mappings.instances, ...nextMappings.instances], + nextCursor: nextMappings.nextCursor + }; + } + + return { instances: mappings.instances }; + } + + public async getByExternalIds( + queries: Array<{ instanceType: InstanceType; externalId: string; space: string }>, + source?: Source + ): Promise> { + const data: any = { items: queries, includeTyping: true }; + if (source !== null) { + data.sources = [{ source }]; + } + + const result = await this._sdk.post(this._byIdsEndpoint, { data }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to fetch instances. Status: ${result.status}`); + } + + public async createInstance( + queries: Array> + ): Promise> { + const data: any = { + items: queries, + autoCreateStartNodes: false, + autoCreateEndNodes: false, + skipOnVersionConflict: false, + replace: false + }; + + const result = await this._sdk.post(this._createUpdateInstancesEndpoint, { data }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to create instances. Status: ${result.status}`); + } + + public async editInstance( + queries: Array<{ + instanceType: InstanceType; + externalId: string; + space: string; + sources: [{ source: Source; properties: any }]; + }> + ): Promise> { + const data: any = { + items: queries, + autoCreateStartNodes: false, + autoCreateEndNodes: false, + skipOnVersionConflict: false, + replace: false + }; + + const result = await this._sdk.post(this._createUpdateInstancesEndpoint, { data }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to edit instances. Status: ${result.status}`); + } + + public async deleteInstances( + queries: Array<{ + instanceType: InstanceType; + externalId: string; + space: string; + }> + ): Promise> { + if (queries.length === 0) { + return { items: [] }; + } + + const data: any = { + items: queries + }; + + const result = await this._sdk.post(this._deleteInstancesEndpoint, { data }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to delete instances. Status: ${result.status}`); + } + + public async inspectInstances(inspectFilter: InspectFilter): Promise { + const result = await this._sdk.post(this._inspectEndpoint, { data: inspectFilter }); + + if (result.status === 200) { + return result.data as InspectResultList; + } + throw new Error(`Failed to fetch instances`); + } + + public async getViewsByIds(views: Source[]): Promise<{ items: ViewItem[] }> { + const result = await this._sdk.post(this._viewsByIdEndpoint, { + data: { + items: views.map((view) => ({ + externalId: view.externalId, + space: view.space, + version: view.version + })) + } + }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to fetch instances. Status: ${result.status}`); + } + + public async queryNodesAndEdges(query: T): Promise> { + const result = await this._sdk.post(this._queryEndpoint, { data: query }); + if (result.status === 200) { + return { items: result.data.items, nextCursor: result.data.nextCursor }; + } + throw new Error(`Failed to fetch instances. Status: ${result.status}`); + } + + public async listDataModels(): Promise { + const result = await this._sdk.get(this._listDataModelsEndpoint, { params: { limit: 1000 } }); + if (result.status === 200) { + return result.data; + } + throw new Error(`Failed to fetch data models. Status: ${result.status}`); + } +} + +function hoistInstanceProperties( + source: Source, + instances: Array> | NodeItem>> +): void { + if (source === undefined) { + return; + } + const propertyKey = `${source.externalId}/${source.version}`; + instances.forEach((instance) => { + if (instance.properties[source.space][propertyKey] !== undefined) { + instance.properties = instance.properties[source.space][propertyKey]; + } + }); +} + +function makeSureNonEmptyFilterForRequest( + filter: InstanceFilter | undefined +): InstanceFilter | undefined { + return filter !== undefined && Object.keys(filter).length === 0 ? undefined : filter; +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts new file mode 100644 index 00000000000..9b90cb5d15e --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -0,0 +1,65 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; +import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; +import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; +import { getFdmConnectionsForNodeIds } from './getFdmConnectionsForNodeIds'; +import { getDMSModels } from './getDMSModels'; +import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; +import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; + +export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { + readonly _fdmSdk: FdmSDK; + + constructor(fdmSdk: FdmSDK) { + this._fdmSdk = fdmSdk; + } + + is3dView(view: ViewItem): boolean { + return Object.keys(view.properties).some((propName) => propName === 'inModel3d'); + } + + getDMSModels(modelId: number): Promise { + return getDMSModels(this._fdmSdk, modelId); + } + + getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { + return getEdgeConnected3dInstances(this._fdmSdk, instance); + } + + getFdmConnectionsForNodeIds( + models: DmsUniqueIdentifier[], + revisionId: number, + nodeIds: number[] + ): Promise { + return getFdmConnectionsForNodeIds(this._fdmSdk, models, revisionId, nodeIds); + } + + listMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined, + limit: number + ): Promise { + return listMappedFdmNodes(this._fdmSdk, models, sourcesToSearch, instanceFilter, limit); + } // useSearchMappedEquipmentFdm + + listAllMappedFdmNodes(models: AddModelOptions[], sourcesToSearch: Source[]): Promise { + return listAllMappedFdmNodes(this._fdmSdk, models, sourcesToSearch); + } + + filterNodesByMappedTo3d( + nodes: InstancesWithView[], + models: AddModelOptions[], + spacesToSearch: string[] + ): Promise { + return filterNodesByMappedTo3d(this._fdmSdk, nodes, models, spacesToSearch); + } + + getModelsForInstance(instance: DmsUniqueIdentifier): Promise { + // useModelsForInstanceQuery (only support CAD for now?) + } + getCadConnectionsForRevisions(revisions: number[]): Promise; // FdmNodeCache.ts / getEdgesForRevisions +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts new file mode 100644 index 00000000000..05b781062bc --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts @@ -0,0 +1,70 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { InstanceFilter, Query, Source } from '../FdmSDK'; +import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; + +export function createMappedEquipmentQuery( + models: AddModelOptions[], + views: Source[], + instanceFilter: InstanceFilter | undefined, + limit: number = 10000, + cursors?: Record +): Query { + return { + with: { + mapped_edges: { + edges: { + filter: createInModelsFilter(models) + }, + limit + }, + mapped_nodes: { + nodes: { + from: 'mapped_edges', + chainTo: 'source', + filter: instanceFilter + }, + limit + }, + mapped_edges_2: { + edges: { + from: 'mapped_nodes', + direction: 'inwards', + maxDistance: 1 + } + }, + mapped_nodes_2: { + nodes: { + from: 'mapped_edges_2', + chainTo: 'destination', + filter: instanceFilter + } + } + }, + cursors, + select: { + mapped_nodes_2: { + sources: views.map((view) => ({ source: view, properties: [] })) + }, + mapped_edges_2: {}, + mapped_edges: { + sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] + }, + mapped_nodes: { + sources: views.map((view) => ({ source: view, properties: [] })) + } + } + }; +} + +function createInModelsFilter(models: AddModelOptions[]): { in: any } { + return { + in: { + property: [ + SYSTEM_3D_EDGE_SOURCE.space, + `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, + 'revisionId' + ], + values: models.map((model) => model.revisionId) + } + }; +} diff --git a/react-components/src/utilities/globalDataModels.ts b/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts similarity index 91% rename from react-components/src/utilities/globalDataModels.ts rename to react-components/src/data-providers/legacy-fdm-provider/dataModels.ts index 2842822a433..c341f71c12c 100644 --- a/react-components/src/utilities/globalDataModels.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts @@ -1,7 +1,7 @@ /*! * Copyright 2023 Cognite AS */ -import { type DmsUniqueIdentifier, type Source } from '../data-providers/FdmSDK'; +import { type DmsUniqueIdentifier, type Source } from '../FdmSDK'; export const SYSTEM_SPACE_3D_SCHEMA = 'cdf_3d_schema'; // Data model, views, containers and types for edges diff --git a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts new file mode 100644 index 00000000000..fab19b3ba5e --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts @@ -0,0 +1,14 @@ +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { EdgeItem } from '../FdmSDK'; +import { InModel3dEdgeProperties } from './dataModels'; + +export function fdmEdgesToCadConnections( + edges: Array> +): FdmCadConnection[] { + return edges.map((instance) => ({ + nodeId: instance.properties.revisionNodeId, + revisionId: instance.properties.revisionId, + modelId: Number(instance.endNode.externalId), + instance: instance.startNode + })); +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts new file mode 100644 index 00000000000..048f4327ba3 --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts @@ -0,0 +1,227 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { + DmsUniqueIdentifier, + EdgeItem, + ExternalId, + FdmSDK, + NodeItem, + Query, + Source +} from '../FdmSDK'; +import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; +import { getDMSModels } from './getDMSModels'; +import { FdmKey } from '../../components/CacheProvider/types'; + +export async function filterNodesByMappedTo3d( + fdmSdk: FdmSDK, + nodesWithViews: InstancesWithView[], + models: AddModelOptions[], + spacesToSearch: string[] +): Promise { + const nodes = nodesWithViews.flatMap((result) => result.instances); + const views = nodesWithViews.map((result) => result.view); + + if (nodes.length === 0) { + return nodesWithViews; + } + + const directlyMappedNodes = nodes.map((node) => getDirectRelationProperties(node)).flat(); + + const mappedEquipmentQuery = createCheckMappedEquipmentQuery( + nodes, + directlyMappedNodes, + models, + views + ); + const queryResult = await fdmSdk.queryNodesAndEdges(mappedEquipmentQuery); + + const { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap } = await createMappedEquipmentMaps( + fdmSdk, + queryResult.items.mapped_edges as EdgeItem[], + models, + spacesToSearch + ); + + const filteredSearchResults: InstancesWithView[] = []; + + for (const searchResult of nodesWithViews) { + const filteredInstances = searchResult.instances.filter((instance) => + checkInstanceWithMappedEquipmentMaps( + mappedEquipmentFirstLevelMap, + equipmentSecondLevelMap, + instance + ) + ); + + filteredSearchResults.push({ view: searchResult.view, instances: filteredInstances }); + } + + return filteredSearchResults; +} + +function createCheckMappedEquipmentQuery( + instances: NodeItem[], + directlyMappedNodes: DmsUniqueIdentifier[], + models: AddModelOptions[], + views: Source[], + limit: number = 1000 +): Query { + return { + with: { + mapped_nodes: { + nodes: { + filter: { + in: { + property: ['node', 'externalId'], + values: instances + .map((instance) => instance.externalId) + .concat(directlyMappedNodes.map((node) => node.externalId)) + } + } + }, + limit + }, + mapped_edges: { + edges: { + from: 'mapped_nodes', + direction: 'outwards', + nodeFilter: { + in: { + property: ['node', 'externalId'], + values: models.map((model) => model.modelId.toString()) + } + }, + maxDistance: 2 + }, + limit: 10000 + } + }, + select: { + mapped_edges: { + sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] + }, + mapped_nodes: { + sources: views.map((view) => ({ source: view, properties: [] })) + } + } + }; +} + +async function createMappedEquipmentMaps( + fdmSdk: FdmSDK, + allEdges: EdgeItem[], + models: AddModelOptions[], + spacesToSearch: string[] +): Promise<{ + mappedEquipmentFirstLevelMap: Record; + equipmentSecondLevelMap: Record; +}> { + const mappedEquipmentFirstLevelMap: Record = {}; + const equipmentSecondLevelMap: Record = {}; + + const modelsMap = await createModelsMap(fdmSdk, models); + + for (const edge of allEdges) { + const { space: endSpace, externalId: endExternalId } = edge.endNode; + const { space, externalId } = edge.startNode; + + const isModelsMapped = models.some( + ({ modelId, revisionId }) => + modelId.toString() === endExternalId && + revisionId.toString() === getRevisionIdFromEdge(edge) + ); + + const modelInstances = modelsMap.get(endExternalId); + + if (modelInstances?.find((model) => model.space === endSpace) !== undefined && isModelsMapped) { + const key = `${space}/${externalId}`; + + const keyEdges = mappedEquipmentFirstLevelMap[key]; + mappedEquipmentFirstLevelMap[key] = keyEdges !== undefined ? keyEdges.concat(edge) : [edge]; + continue; + } + + if (spacesToSearch.includes(endSpace)) { + const key = `${space}/${externalId}`; + + const keyEdges = equipmentSecondLevelMap[key]; + + equipmentSecondLevelMap[key] = keyEdges !== undefined ? keyEdges.concat(edge) : [edge]; + continue; + } + } + + return { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap }; +} + +function getRevisionIdFromEdge(edge: EdgeItem): string | undefined { + return (edge.properties as any)?.[SYSTEM_SPACE_3D_SCHEMA]?.[ + `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}` + ]?.revisionId?.toString(); +} + +async function createModelsMap( + fdmSdk: FdmSDK, + models: AddModelOptions[] +): Promise> { + const modelInstances = await Promise.all( + models.map(async (model) => await getDMSModels(fdmSdk, model.modelId)) + ); + return new Map( + modelInstances.map((modelInstanceList, ind) => [`${models[ind].modelId}`, modelInstanceList]) + ); +} + +function checkInstanceWithMappedEquipmentMaps( + mappedEquipmentFirstLevelMap: Record, + equipmentSecondLevelMap: Record, + instance: NodeItem +): boolean { + const key: FdmKey = `${instance.space}/${instance.externalId}`; + const directRelationProperties = getDirectRelationProperties(instance); + const isMappedFirstLevel = mappedEquipmentFirstLevelMap[key] !== undefined; + const isSecondLevelWithEdge = equipmentSecondLevelMap[key] !== undefined; + const isSecondLevelWithDirectRelation = directRelationProperties.length > 0; + + if (isMappedFirstLevel) { + return true; + } + + if (isSecondLevelWithEdge) { + return equipmentSecondLevelMap[key].some((edge) => { + const { space, externalId } = edge.endNode; + + const secondLevelKey: FdmKey = `${space}/${externalId}`; + const isMappedWithEdge = mappedEquipmentFirstLevelMap[secondLevelKey] !== undefined; + + return isMappedWithEdge; + }); + } + + if (isSecondLevelWithDirectRelation) { + const isMappedWithDirectRelation = directRelationProperties.some( + ({ externalId, space }) => + mappedEquipmentFirstLevelMap[`${space}/${externalId}`] !== undefined + ); + + return isMappedWithDirectRelation; + } + + return false; +} + +function getDirectRelationProperties(searchResultNode: NodeItem): DmsUniqueIdentifier[] { + const directRelations: DmsUniqueIdentifier[] = []; + const nodeProperties = searchResultNode.properties; + + Object.keys(nodeProperties).forEach((propertyKey) => { + const { space, externalId } = nodeProperties[propertyKey] as any; + + if (space !== undefined && externalId !== undefined) { + directRelations.push({ space, externalId }); + } + }); + + return directRelations; +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts b/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts new file mode 100644 index 00000000000..31f529a9ec1 --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts @@ -0,0 +1,27 @@ +import { DmsUniqueIdentifier, FdmSDK, Source } from '../FdmSDK'; +import { + SYSTEM_SPACE_3D_MODEL_ID, + SYSTEM_SPACE_3D_MODEL_VERSION, + SYSTEM_SPACE_3D_SCHEMA +} from './dataModels'; + +export async function getDMSModels( + fdmClient: FdmSDK, + modelId: number +): Promise { + const filter = { + equals: { + property: ['node', 'externalId'], + value: `${modelId}` + } + }; + const sources: Source = { + type: 'view', + space: SYSTEM_SPACE_3D_SCHEMA, + externalId: SYSTEM_SPACE_3D_MODEL_ID, + version: SYSTEM_SPACE_3D_MODEL_VERSION + }; + + const modelResults = await fdmClient.filterInstances(filter, 'node', sources); + return modelResults.instances; +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts new file mode 100644 index 00000000000..41c0a38d183 --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts @@ -0,0 +1,90 @@ +import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; + +export async function getEdgeConnected3dInstances( + fdmSdk: FdmSDK, + instance: DmsUniqueIdentifier +): Promise { + const nodesResult = await fdmSdk.queryNodesAndEdges({ + ...related3dEdgesQuery, + parameters: { + instanceExternalId: instance.externalId, + instanceSpace: instance.space + } + }); + + return nodesResult.items.connected_objects_with_3d.map((obj) => ({ + instanceType: 'node' as const, + externalId: obj.externalId, + space: obj.space + })); +} + +const related3dEdgesQuery = { + with: { + start_instance: { + nodes: { + filter: { + and: [ + { + equals: { + property: ['node', 'externalId'], + value: { parameter: 'instanceExternalId' } + } + }, + { + equals: { + property: ['node', 'space'], + value: { parameter: 'instanceSpace' } + } + } + ] + } + }, + limit: 1 + }, + start_to_object_edges: { + edges: { + from: 'start_instance', + maxDistance: 1, + direction: 'outwards' + }, + limit: 1000 + }, + connected_objects_with_3d: { + nodes: { + from: 'start_to_object_edges', + chainTo: 'destination' + }, + limit: 1000 + }, + edges_of_3d_type: { + edges: { + from: 'connected_objects_with_3d', + maxDistance: 1, + direction: 'outwards', + filter: { + and: [ + { + hasData: [SYSTEM_3D_EDGE_SOURCE] + } + ] + } + } + }, + nodes_with_3d_connection: { + nodes: { + from: 'edges_of_3d_type', + chainTo: 'source' + }, + limit: 1000 + } + }, + select: { + start_instance: {}, + start_to_object_edges: {}, + connected_objects_with_3d: {}, + edges_of_3d_type: {}, + nodes_with_3d_connection: {} + } +} as const; diff --git a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts new file mode 100644 index 00000000000..e7834706652 --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts @@ -0,0 +1,54 @@ +import { CogniteInternalId } from '@cognite/sdk/dist/src'; +import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; +import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; + +export async function getFdmConnectionsForNodeIds( + fdmClient: FdmSDK, + models: DmsUniqueIdentifier[], + revisionId: number, + nodeIds: CogniteInternalId[] +): Promise { + const filter = { + and: [ + { + in: { + property: ['edge', 'endNode'], + values: models.map((model) => ({ + externalId: model.externalId, + space: model.space + })) + } + }, + { + equals: { + property: [ + SYSTEM_3D_EDGE_SOURCE.space, + `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, + 'revisionId' + ], + value: revisionId + } + }, + { + in: { + property: [ + SYSTEM_3D_EDGE_SOURCE.space, + `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, + 'revisionNodeId' + ], + values: nodeIds + } + } + ] + }; + + const results = await fdmClient.filterAllInstances( + filter, + 'edge', + SYSTEM_3D_EDGE_SOURCE + ); + + return fdmEdgesToCadConnections(results.instances); +} diff --git a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts new file mode 100644 index 00000000000..a783adff3ff --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts @@ -0,0 +1,85 @@ +import { AddModelOptions } from '@cognite/reveal'; +import { FdmSDK, InstanceFilter, NodeItem, Query, Source } from '../FdmSDK'; +import { createMappedEquipmentQuery } from './createMappedEquipmentQuery'; +import { chunk, isEqual } from 'lodash'; + +export async function listMappedFdmNodes( + fdmSdk: FdmSDK, + models: AddModelOptions[], + sourcesToSearch: Source[], + instanceFilter: InstanceFilter | undefined, + limit: number +): Promise { + const result = await fdmSdk.queryNodesAndEdges( + createMappedEquipmentQuery(models, sourcesToSearch, instanceFilter, limit) + ); + + return result.items.mapped_nodes.concat(result.items.mapped_nodes_2) as NodeItem[]; +} + +export async function listAllMappedFdmNodes( + fdmSdk: FdmSDK, + models: AddModelOptions[], + sourcesToSearch: Source[] +): Promise { + const queries = createChunkedMappedEquipmentQueries(models, sourcesToSearch, 10000); + + const mappedEquipment: NodeItem[] = []; + for (const query of queries) { + let currentPage = await fdmSdk.queryNodesAndEdges(query); + + const mappedNodes = currentPage.items.mapped_nodes as NodeItem[]; + const mappedNodesParents = currentPage.items.mapped_nodes_2 as NodeItem[]; + mappedEquipment.push( + ...mappedNodes.concat(mappedNodesParents).map((node) => removeEmptyProperties(node)) + ); + + while (!isEqual(currentPage.nextCursor, {})) { + query.cursors = currentPage.nextCursor; + + currentPage = await fdmSdk.queryNodesAndEdges(query); + + const cleanedNodes = currentPage.items.mapped_nodes.map((node) => + removeEmptyProperties(node as NodeItem) + ); + const cleanedNodesParents = currentPage.items.mapped_nodes_2.map((node) => + removeEmptyProperties(node as NodeItem) + ); + + mappedEquipment.push(...cleanedNodes.concat(cleanedNodesParents)); + } + } + + return mappedEquipment; +} + +function createChunkedMappedEquipmentQueries( + models: AddModelOptions[], + views: Source[], + limit: number = 10000, + cursors?: Record +): Query[] { + const viewChunks = chunk(views, 10); + return viewChunks.map((viewChunk) => + createMappedEquipmentQuery(models, viewChunk, undefined, limit, cursors) + ); +} + +function removeEmptyProperties(queryResultNode: NodeItem): NodeItem { + Object.keys(queryResultNode.properties).forEach((space) => { + const currentSpaceProperties = queryResultNode.properties[space]; + const newProperties: Record> = {}; + + Object.keys(currentSpaceProperties).forEach((view) => { + const currentViewProperties = currentSpaceProperties[view]; + + if (Object.keys(currentViewProperties).length !== 0) { + newProperties[view] = currentViewProperties; + } + }); + + queryResultNode.properties[space] = newProperties; + }); + + return queryResultNode; +} diff --git a/react-components/src/data-providers/types.ts b/react-components/src/data-providers/types.ts new file mode 100644 index 00000000000..7101cb245d4 --- /dev/null +++ b/react-components/src/data-providers/types.ts @@ -0,0 +1,60 @@ +/*! + * Copyright 2024 Cognite AS + */ +import { + type Datapoints, + type Timeseries, + type ExternalId, + type InternalId, + type Metadata, + type Relationship +} from '@cognite/sdk/'; +import { type DmsUniqueIdentifier, type Source } from './FdmSDK'; + +export type FdmInstanceWithView = DmsUniqueIdentifier & { view: Source }; + +export type AssetInstanceReference = { assetId: number }; +export type InstanceReference = AssetInstanceReference | DmsUniqueIdentifier; + +export function isAssetInstance(instance: InstanceReference): instance is AssetInstanceReference { + return 'assetId' in instance; +} + +export function isDmsInstance(instance: InstanceReference): instance is DmsUniqueIdentifier { + return 'externalId' in instance && 'space' in instance; +} + +export type RelationshipsFilterInternal = { + labels?: string[]; +}; + +export type ExtendedRelationship = { + relation: 'Source' | 'Target'; +} & Relationship; + +export type RelationshipSourceAndTarget = { + source: RelationshipSourceAndTargetData; + target: RelationshipSourceAndTargetData; +}; +export type RelationshipSourceAndTargetData = { + externalId?: string; + id?: number; + metadata?: Metadata; +}; + +export type RelationshipData = ExtendedRelationship & RelationshipSourceAndTarget; + +export type AssetIdsAndTimeseries = { + assetIds?: Partial; + timeseries?: Timeseries | undefined; +}; + +export type AssetAndTimeseriesIds = { + assetIds: Partial; + timeseriesIds: Partial; +}; + +export type AssetIdsAndTimeseriesData = { + assetIdsWithTimeseries: AssetIdsAndTimeseries[]; + timeseriesDatapoints: Datapoints[]; +}; diff --git a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts b/react-components/src/hooks/network/getCadModelsForFdmInstance.ts index 88855aa4ab8..8565c123729 100644 --- a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts +++ b/react-components/src/hooks/network/getCadModelsForFdmInstance.ts @@ -6,7 +6,7 @@ import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../data import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE -} from '../../utilities/globalDataModels'; +} from '../../data-providers/legacy-fdm-provider/dataModels'; import { isDefined } from '../../utilities/isDefined'; type ModelForInstancesResponse = { diff --git a/react-components/src/index.ts b/react-components/src/index.ts index be2fd01ac16..19eb1b71bfa 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -58,7 +58,7 @@ export { use3dNodeByExternalId } from './query/use3dNodeByExternalId'; export { useAllMappedEquipmentFDM, useSearchMappedEquipmentFDM, - type SearchResultsWithView + type InstancesWithView } from './query/useSearchMappedEquipmentFDM'; export { useSearchMappedEquipmentAssetMappings, diff --git a/react-components/src/query/use3dRelatedDirectConnections.ts b/react-components/src/query/use3dRelatedDirectConnections.ts index 06e85af14f0..71740214153 100644 --- a/react-components/src/query/use3dRelatedDirectConnections.ts +++ b/react-components/src/query/use3dRelatedDirectConnections.ts @@ -3,7 +3,7 @@ */ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useFdmSdk } from '../components/RevealCanvas/SDKProvider'; import { type Source, type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import assert from 'assert'; import { type FdmInstanceWithView } from '../data-providers/types'; @@ -12,6 +12,7 @@ export function use3dRelatedDirectConnections( instance: DmsUniqueIdentifier | undefined ): UseQueryResult { const fdmSdk = useFdmSdk(); + const fdmDataProvider = useFdm3dDataProvider(); return useQuery({ queryKey: ['reveal-react-components', 'get-3d-related-direct-connections'], @@ -67,7 +68,7 @@ export function use3dRelatedDirectConnections( const viewResultIndex = viewToDeduplicatedIndexMap.get(createViewKey(view)); assert(viewResultIndex !== undefined); const propsForView = viewProps.items[viewResultIndex]; - return Object.keys(propsForView.properties).some((propName) => propName === 'inModel3d'); + return fdmDataProvider.is3dView(propsForView); }); return threeDRelatedViews.map(([index, view]) => ({ diff --git a/react-components/src/query/use3dRelatedEdgeConnections.ts b/react-components/src/query/use3dRelatedEdgeConnections.ts index 8d798f21b89..53a5879040b 100644 --- a/react-components/src/query/use3dRelatedEdgeConnections.ts +++ b/react-components/src/query/use3dRelatedEdgeConnections.ts @@ -3,17 +3,16 @@ */ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { useFdmSdk } from '../components/RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useFdmSdk } from '../components/RevealCanvas/SDKProvider'; import { type DmsUniqueIdentifier } from '../data-providers/FdmSDK'; import { zipWith } from 'lodash'; import { type FdmInstanceWithView } from '../data-providers/types'; -import assert from 'assert'; -import { SYSTEM_3D_EDGE_SOURCE } from '../utilities/globalDataModels'; export function use3dRelatedEdgeConnections( fdmId: DmsUniqueIdentifier | undefined ): UseQueryResult { const fdmSdk = useFdmSdk(); + const fdmDataProvider = useFdm3dDataProvider(); return useQuery({ queryKey: [ @@ -23,31 +22,22 @@ export function use3dRelatedEdgeConnections( fdmId?.space ], queryFn: async () => { - assert(fdmId !== undefined); - const nodesResult = await fdmSdk.queryNodesAndEdges({ - ...related3dEdgesQuery, - parameters: { - instanceExternalId: fdmId.externalId, - instanceSpace: fdmId.space - } - }); + if (fdmId === undefined) { + return []; + } - const nodeIds = nodesResult.items.connected_objects_with_3d.map((obj) => ({ - instanceType: 'node' as const, - externalId: obj.externalId, - space: obj.space - })); + const relatedInstances = await fdmDataProvider.getEdgeConnected3dInstances(fdmId); - if (nodeIds.length === 0) { + if (relatedInstances.length === 0) { return []; } const views = await fdmSdk.inspectInstances({ inspectionOperations: { involvedViews: {} }, - items: nodeIds + items: relatedInstances.map((instance) => ({ ...instance, instanceType: 'node' })) }); - return zipWith(nodeIds, views.items, (node, view) => ({ + return zipWith(relatedInstances, views.items, (node, view) => ({ ...node, view: view.inspectionResults.involvedViews[0] })); @@ -55,72 +45,3 @@ export function use3dRelatedEdgeConnections( enabled: fdmId !== undefined }); } - -const related3dEdgesQuery = { - with: { - start_instance: { - nodes: { - filter: { - and: [ - { - equals: { - property: ['node', 'externalId'], - value: { parameter: 'instanceExternalId' } - } - }, - { - equals: { - property: ['node', 'space'], - value: { parameter: 'instanceSpace' } - } - } - ] - } - }, - limit: 1 - }, - start_to_object_edges: { - edges: { - from: 'start_instance', - maxDistance: 1, - direction: 'outwards' - }, - limit: 1000 - }, - connected_objects_with_3d: { - nodes: { - from: 'start_to_object_edges', - chainTo: 'destination' - }, - limit: 1000 - }, - edges_of_3d_type: { - edges: { - from: 'connected_objects_with_3d', - maxDistance: 1, - direction: 'outwards', - filter: { - and: [ - { - hasData: [SYSTEM_3D_EDGE_SOURCE] - } - ] - } - } - }, - nodes_with_3d_connection: { - nodes: { - from: 'edges_of_3d_type', - chainTo: 'source' - }, - limit: 1000 - } - }, - select: { - start_instance: {}, - start_to_object_edges: {}, - connected_objects_with_3d: {}, - edges_of_3d_type: {}, - nodes_with_3d_connection: {} - } -} as const; diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 81bfcd7fa28..5bc0fa79bfb 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -4,41 +4,34 @@ import { type CogniteClient } from '@cognite/sdk'; import { useMemo } from 'react'; import { - type EdgeItem, type NodeItem, FdmSDK, type Source, type Query, type DmsUniqueIdentifier, - type Space, - type ExternalId, type InstanceFilter } from '../data-providers/FdmSDK'; -import { useSDK } from '../components/RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useFdmSdk, useSDK } from '../components/RevealCanvas/SDKProvider'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from '../utilities/globalDataModels'; import { type AddModelOptions } from '@cognite/reveal'; import { isEqual, uniq, chunk } from 'lodash'; -import { getDMSModels } from '../components/CacheProvider/requests'; +import { Fdm3dDataProvider } from '../data-providers/Fdm3dDataProvider'; -export type SearchResultsWithView = { view: Source; instances: NodeItem[] }; - -type FdmKey = `${Space}/${ExternalId}`; +export type InstancesWithView = { view: Source; instances: NodeItem[] }; export const useSearchMappedEquipmentFDM = ( query: string, viewsToSearch: DmsUniqueIdentifier[], models: AddModelOptions[], instancesFilter: InstanceFilter | undefined, - limit: number = 100, - userSdk?: CogniteClient -): UseQueryResult => { + limit: number = 100 +): UseQueryResult => { if (limit > 1000) { throw new Error('Limit cannot be greater than 1000'); } - const sdk = useSDK(userSdk); - const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); + const fdmSdk = useFdmSdk(); + const fdmDataProvider = useFdm3dDataProvider(); const spacesToSearch = useMemo( () => uniq(viewsToSearch.map((view) => view.space)), @@ -55,7 +48,7 @@ export const useSearchMappedEquipmentFDM = ( const sources = await createSourcesFromViews(viewsToSearch, fdmSdk); const chunkedSources = chunk(sources, 10); - const queryResults: SearchResultsWithView[] = []; + const queryResults: InstancesWithView[] = []; for (const sourceChunk of chunkedSources) { queryResults.push( @@ -66,6 +59,7 @@ export const useSearchMappedEquipmentFDM = ( models, instancesFilter, fdmSdk, + fdmDataProvider, limit )) ); @@ -83,16 +77,18 @@ const searchNodesWithViewsAndModels = async ( models: AddModelOptions[], instancesFilter: InstanceFilter | undefined, fdmSdk: FdmSDK, + fdmDataProvider: Fdm3dDataProvider, limit: number = 100 -): Promise => { +): Promise => { if (query === '') { - const result = await fdmSdk.queryNodesAndEdges( - createMappedEquipmentQuery(models, sourcesToSearch, limit) + const nodeItems = await fdmDataProvider.listMappedFdmNodes( + models, + sourcesToSearch, + instancesFilter, + limit ); - const transformedResults = convertQueryNodeItemsToSearchResultsWithViews( - result.items.mapped_nodes.concat(result.items.mapped_nodes_2) as NodeItem[] - ); + const transformedResults = convertQueryNodeItemsToSearchResultsWithViews(nodeItems); const combinedWithOtherViews = sourcesToSearch.map((view) => ({ view, @@ -105,7 +101,7 @@ const searchNodesWithViewsAndModels = async ( return combinedWithOtherViews; } - const searchResults: SearchResultsWithView[] = []; + const searchResults: InstancesWithView[] = []; for (const view of sourcesToSearch) { const result = await fdmSdk.searchInstances(view, query, 'node', limit, instancesFilter); @@ -115,86 +111,32 @@ const searchNodesWithViewsAndModels = async ( instances: result.instances }); } - const filteredSearchResults = await filterSearchResultsByMappedTo3DModels( - fdmSdk, - searchResults, - models, - spacesToSearch - ); - return filteredSearchResults; + return fdmDataProvider.filterNodesByMappedTo3d(searchResults, models, spacesToSearch); }; export const useAllMappedEquipmentFDM = ( models: AddModelOptions[], - viewsToSearch: DmsUniqueIdentifier[], - userSdk?: CogniteClient + viewsToSearch: DmsUniqueIdentifier[] ): UseQueryResult => { - const sdk = useSDK(userSdk); - - const fdmSdk = useMemo(() => new FdmSDK(sdk), [sdk]); + const fdmSdk = useFdmSdk(); + const fdmDataProvider = useFdm3dDataProvider(); return useQuery({ queryKey: ['reveal', 'react-components', 'all-mapped-equipment-fdm', viewsToSearch], queryFn: async () => { const viewSources = await createSourcesFromViews(viewsToSearch, fdmSdk); - const queries = createChunkedMappedEquipmentQueries(models, viewSources, 10000); - - const mappedEquipment: NodeItem[] = []; - for (const query of queries) { - let currentPage = await fdmSdk.queryNodesAndEdges(query); - - const mappedNodes = currentPage.items.mapped_nodes as NodeItem[]; - const mappedNodesParents = currentPage.items.mapped_nodes_2 as NodeItem[]; - mappedEquipment.push( - ...mappedNodes.concat(mappedNodesParents).map((node) => removeEmptyProperties(node)) - ); - - while (!isEqual(currentPage.nextCursor, {})) { - query.cursors = currentPage.nextCursor; - - currentPage = await fdmSdk.queryNodesAndEdges(query); - - const cleanedNodes = currentPage.items.mapped_nodes.map((node) => - removeEmptyProperties(node as NodeItem) - ); - const cleanedNodesParents = currentPage.items.mapped_nodes_2.map((node) => - removeEmptyProperties(node as NodeItem) - ); - - mappedEquipment.push(...cleanedNodes.concat(cleanedNodesParents)); - } - } - return mappedEquipment; + return fdmDataProvider.listAllMappedFdmNodes(models, viewSources, undefined); }, staleTime: Infinity }); }; -function removeEmptyProperties(queryResultNode: NodeItem): NodeItem { - Object.keys(queryResultNode.properties).forEach((space) => { - const currentSpaceProperties = queryResultNode.properties[space]; - const newProperties: Record> = {}; - - Object.keys(currentSpaceProperties).forEach((view) => { - const currentViewProperties = currentSpaceProperties[view]; - - if (Object.keys(currentViewProperties).length !== 0) { - newProperties[view] = currentViewProperties; - } - }); - - queryResultNode.properties[space] = newProperties; - }); - - return queryResultNode; -} - function convertQueryNodeItemsToSearchResultsWithViews( queryItems: NodeItem[] -): SearchResultsWithView[] { - return queryItems.reduce((acc, fdmNode) => { +): InstancesWithView[] { + return queryItems.reduce((acc, fdmNode) => { const cleanedNode = removeEmptyProperties(fdmNode); Object.keys(cleanedNode.properties).forEach((space) => { @@ -237,296 +179,6 @@ function convertQueryNodeItemsToSearchResultsWithViews( }, []); } -async function createMappedEquipmentMaps( - allEdges: EdgeItem[], - models: AddModelOptions[], - spacesToSearch: string[], - fdmSdk: FdmSDK -): Promise<{ - mappedEquipmentFirstLevelMap: Record; - equipmentSecondLevelMap: Record; -}> { - const mappedEquipmentFirstLevelMap: Record = {}; - const equipmentSecondLevelMap: Record = {}; - - const modelsMap = await createModelsMap(models, fdmSdk); - - for (const edge of allEdges) { - const { space: endSpace, externalId: endExternalId } = edge.endNode; - const { space, externalId } = edge.startNode; - - const isModelsMapped = models.some( - ({ modelId, revisionId }) => - modelId.toString() === endExternalId && - revisionId.toString() === getRevisionIdFromEdge(edge) - ); - - const modelInstances = modelsMap.get(endExternalId); - - if (modelInstances?.find((model) => model.space === endSpace) !== undefined && isModelsMapped) { - const key = `${space}/${externalId}`; - - const keyEdges = mappedEquipmentFirstLevelMap[key]; - mappedEquipmentFirstLevelMap[key] = keyEdges !== undefined ? keyEdges.concat(edge) : [edge]; - continue; - } - - if (spacesToSearch.includes(endSpace)) { - const key = `${space}/${externalId}`; - - const keyEdges = equipmentSecondLevelMap[key]; - - equipmentSecondLevelMap[key] = keyEdges !== undefined ? keyEdges.concat(edge) : [edge]; - continue; - } - } - - return { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap }; -} - -async function createModelsMap( - models: AddModelOptions[], - fdmSdk: FdmSDK -): Promise> { - const modelInstances = await Promise.all( - models.map(async (model) => await getDMSModels(model.modelId, fdmSdk)) - ); - return new Map( - modelInstances.map((modelInstanceList, ind) => [`${models[ind].modelId}`, modelInstanceList]) - ); -} - -function createCheckMappedEquipmentQuery( - instances: NodeItem[], - directlyMappedNodes: DmsUniqueIdentifier[], - models: AddModelOptions[], - views: Source[], - limit: number = 1000 -): Query { - return { - with: { - mapped_nodes: { - nodes: { - filter: { - in: { - property: ['node', 'externalId'], - values: instances - .map((instance) => instance.externalId) - .concat(directlyMappedNodes.map((node) => node.externalId)) - } - } - }, - limit - }, - mapped_edges: { - edges: { - from: 'mapped_nodes', - direction: 'outwards', - nodeFilter: { - in: { - property: ['node', 'externalId'], - values: models.map((model) => model.modelId.toString()) - } - }, - maxDistance: 2 - }, - limit: 10000 - } - }, - select: { - mapped_edges: { - sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] - }, - mapped_nodes: { - sources: views.map((view) => ({ source: view, properties: [] })) - } - } - }; -} - -function createChunkedMappedEquipmentQueries( - models: AddModelOptions[], - views: Source[], - limit: number = 10000, - cursors?: Record -): Query[] { - const viewChunks = chunk(views, 10); - return viewChunks.map((viewChunk) => - createMappedEquipmentQuery(models, viewChunk, limit, cursors) - ); -} - -function createMappedEquipmentQuery( - models: AddModelOptions[], - views: Source[], - limit: number = 10000, - cursors?: Record -): Query { - return { - with: { - mapped_edges: { - edges: { - filter: createInModelsFilter(models) - }, - limit - }, - mapped_nodes: { - nodes: { - from: 'mapped_edges', - chainTo: 'source' - }, - limit - }, - mapped_edges_2: { - edges: { - from: 'mapped_nodes', - direction: 'inwards', - maxDistance: 1 - } - }, - mapped_nodes_2: { - nodes: { - from: 'mapped_edges_2', - chainTo: 'destination' - } - } - }, - cursors, - select: { - mapped_nodes_2: { - sources: views.map((view) => ({ source: view, properties: [] })) - }, - mapped_edges_2: {}, - mapped_edges: { - sources: [{ source: SYSTEM_3D_EDGE_SOURCE, properties: [] }] - }, - mapped_nodes: { - sources: views.map((view) => ({ source: view, properties: [] })) - } - } - }; -} - -function createInModelsFilter(models: AddModelOptions[]): { in: any } { - return { - in: { - property: [ - SYSTEM_3D_EDGE_SOURCE.space, - `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`, - 'revisionId' - ], - values: models.map((model) => model.revisionId) - } - }; -} - -async function filterSearchResultsByMappedTo3DModels( - fdmSdk: FdmSDK, - searchResults: SearchResultsWithView[], - models: AddModelOptions[], - spacesToSearch: string[] -): Promise { - const filteredSearchResults: SearchResultsWithView[] = []; - - const searchResultsNodes = searchResults.flatMap((result) => result.instances); - const searchResultsViews = searchResults.map((result) => result.view); - const directlyMappedNodes = searchResultsNodes - .map((node) => getDirectRelationProperties(node)) - .flat(); - - if (searchResultsNodes.length === 0) { - return searchResults; - } - - const mappedEquipmentQuery = createCheckMappedEquipmentQuery( - searchResultsNodes, - directlyMappedNodes, - models, - searchResultsViews - ); - const queryResult = await fdmSdk.queryNodesAndEdges(mappedEquipmentQuery); - - const { mappedEquipmentFirstLevelMap, equipmentSecondLevelMap } = await createMappedEquipmentMaps( - queryResult.items.mapped_edges as EdgeItem[], - models, - spacesToSearch, - fdmSdk - ); - - for (const searchResult of searchResults) { - const filteredInstances = searchResult.instances.filter((instance) => - checkInstanceWithMappedEquipmentMaps( - mappedEquipmentFirstLevelMap, - equipmentSecondLevelMap, - instance - ) - ); - - filteredSearchResults.push({ view: searchResult.view, instances: filteredInstances }); - } - - return filteredSearchResults; -} - -function checkInstanceWithMappedEquipmentMaps( - mappedEquipmentFirstLevelMap: Record, - equipmentSecondLevelMap: Record, - instance: NodeItem -): boolean { - const key: FdmKey = `${instance.space}/${instance.externalId}`; - const directRelationProperties = getDirectRelationProperties(instance); - const isMappedFirstLevel = mappedEquipmentFirstLevelMap[key] !== undefined; - const isSecondLevelWithEdge = equipmentSecondLevelMap[key] !== undefined; - const isSecondLevelWithDirectRelation = directRelationProperties.length > 0; - - if (isMappedFirstLevel) { - return true; - } - - if (isSecondLevelWithEdge) { - return equipmentSecondLevelMap[key].some((edge) => { - const { space, externalId } = edge.endNode; - - const secondLevelKey: FdmKey = `${space}/${externalId}`; - const isMappedWithEdge = mappedEquipmentFirstLevelMap[secondLevelKey] !== undefined; - - return isMappedWithEdge; - }); - } - - if (isSecondLevelWithDirectRelation) { - const isMappedWithDirectRelation = directRelationProperties.some( - ({ externalId, space }) => - mappedEquipmentFirstLevelMap[`${space}/${externalId}`] !== undefined - ); - - return isMappedWithDirectRelation; - } - - return false; -} - -function getRevisionIdFromEdge(edge: EdgeItem): string | undefined { - return (edge.properties as any)?.[SYSTEM_SPACE_3D_SCHEMA]?.[ - `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}` - ]?.revisionId?.toString(); -} - -function getDirectRelationProperties(searchResultNode: NodeItem): DmsUniqueIdentifier[] { - const directRelations: DmsUniqueIdentifier[] = []; - const nodeProperties = searchResultNode.properties; - - Object.keys(nodeProperties).forEach((propertyKey) => { - const { space, externalId } = nodeProperties[propertyKey] as any; - - if (space !== undefined && externalId !== undefined) { - directRelations.push({ space, externalId }); - } - }); - - return directRelations; -} - async function createSourcesFromViews( viewsToSearch: DmsUniqueIdentifier[], fdmSdk: FdmSDK From 0529497caf95df04ca2532fa3b852dec2467f295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 24 Jul 2024 11:19:24 +0200 Subject: [PATCH 03/12] fix: compile errors --- .../components/CacheProvider/FdmNodeCache.ts | 17 ++++++++++++---- .../CacheProvider/NodeCacheProvider.tsx | 6 ++++-- .../CacheProvider/RevisionFdmNodeCache.ts | 7 +++---- .../LegacyFdm3dDataProvider.ts | 5 ++++- .../legacy-fdm-provider/listMappedFdmNodes.ts | 20 +------------------ .../src/query/useSearchMappedEquipmentFDM.tsx | 1 + .../src/utilities/removeEmptyProperties.ts | 20 +++++++++++++++++++ 7 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 react-components/src/utilities/removeEmptyProperties.ts diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 5b3bf2159c8..e3d81044512 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -32,20 +32,28 @@ import { import { partition } from 'lodash'; import assert from 'assert'; -import { fdmEdgesToCadConnections, fetchNodesForNodeIds, inspectNodes } from './requests'; +import { fetchNodesForNodeIds, inspectNodes } from './requests'; import { type ThreeDModelFdmMappings } from '../../hooks/types'; +import { fdmEdgesToCadConnections } from '../../data-providers/legacy-fdm-provider/fdmEdgesToCadConnections'; +import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; export class FdmNodeCache { private readonly _revisionNodeCaches = new Map(); private readonly _cdfClient: CogniteClient; private readonly _fdmClient: FdmSDK; + private readonly _fdm3dDataProvider: Fdm3dDataProvider; private readonly _completeRevisions = new Set(); - public constructor(cdfClient: CogniteClient, fdmClient: FdmSDK) { + public constructor( + cdfClient: CogniteClient, + fdmClient: FdmSDK, + fdm3dDataProvider: Fdm3dDataProvider + ) { this._cdfClient = cdfClient; this._fdmClient = fdmClient; + this._fdm3dDataProvider = fdm3dDataProvider; } public async getMappingsForFdmIds( @@ -225,7 +233,7 @@ export class FdmNodeCache { fetchViews: boolean ): Promise> { const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); - const connections = await this.getEdgesForRevisions(revisionIds, this._fdmClient); + const connections = await this.getConnectionsForRevision(revisionIds, this._fdmClient); const connectionsWithOptionalViews = fetchViews ? await this.getViewsForConnections(connections) @@ -268,7 +276,7 @@ export class FdmNodeCache { return dataWithViews; } - private async getEdgesForRevisions( + private async getConnectionsForRevision( revisionIds: number[], fdmClient: FdmSDK ): Promise { @@ -301,6 +309,7 @@ export class FdmNodeCache { const newRevisionCache = new RevisionFdmNodeCache( this._cdfClient, this._fdmClient, + this._fdm3dDataProvider, modelId, revisionId ); diff --git a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx index d81089a8d8f..0c8b011e404 100644 --- a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx @@ -5,7 +5,7 @@ import { type ReactElement, type ReactNode, createContext, useContext, useMemo } from 'react'; import { FdmNodeCache } from './FdmNodeCache'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { useFdmSdk, useSDK } from '../RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useFdmSdk, useSDK } from '../RevealCanvas/SDKProvider'; import { type FdmNodeDataPromises, type ModelRevisionToEdgeMap } from './types'; import assert from 'assert'; @@ -103,12 +103,14 @@ export const useFdmAssetMappings = ( export function NodeCacheProvider({ children }: { children?: ReactNode }): ReactElement { const fdmClient = useFdmSdk(); + const fdm3dDataProvider = useFdm3dDataProvider(); const cdfClient = useSDK(); const revealKeepAliveData = useRevealKeepAlive(); const fdmCache = useMemo(() => { const cache = - revealKeepAliveData?.fdmNodeCache.current ?? new FdmNodeCache(cdfClient, fdmClient); + revealKeepAliveData?.fdmNodeCache.current ?? + new FdmNodeCache(cdfClient, fdmClient, fdm3dDataProvider); const isRevealKeepAliveContextProvided = revealKeepAliveData !== undefined; if (isRevealKeepAliveContextProvided) { diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index 329b6bf1148..07a499f8f25 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -23,7 +23,7 @@ import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; export class RevisionFdmNodeCache { private readonly _cogniteClient: CogniteClient; private readonly _fdmClient: FdmSDK; - private readonly _fdmDataProvider: Fdm3dDataProvider; + private readonly _fdm3dDataProvider: Fdm3dDataProvider; private readonly _modelId: number; private readonly _revisionId: number; @@ -41,7 +41,7 @@ export class RevisionFdmNodeCache { ) { this._cogniteClient = cogniteClient; this._fdmClient = fdmClient; - this._fdmDataProvider = fdmDataProvider; + this._fdm3dDataProvider = fdmDataProvider; this._modelId = modelId; this._revisionId = revisionId; @@ -269,10 +269,9 @@ export class RevisionFdmNodeCache { return []; } - const ancestorMappings = await getFdmConnectionsForNodeIds( + const ancestorMappings = await this._fdm3dDataProvider.getFdmConnectionsForNodeIds( modelInstances, this._revisionId, - this._fdmClient, ancestors.map((a) => a.id) ); diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index 9b90cb5d15e..8da9359b560 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -60,6 +60,9 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { getModelsForInstance(instance: DmsUniqueIdentifier): Promise { // useModelsForInstanceQuery (only support CAD for now?) + return Promise.resolve([]); } - getCadConnectionsForRevisions(revisions: number[]): Promise; // FdmNodeCache.ts / getEdgesForRevisions + getCadConnectionsForRevisions(revisions: number[]): Promise { + return Promise.resolve([]); + } // FdmNodeCache.ts / getEdgesForRevisions } diff --git a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts index a783adff3ff..96ab7b238d8 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts @@ -2,6 +2,7 @@ import { AddModelOptions } from '@cognite/reveal'; import { FdmSDK, InstanceFilter, NodeItem, Query, Source } from '../FdmSDK'; import { createMappedEquipmentQuery } from './createMappedEquipmentQuery'; import { chunk, isEqual } from 'lodash'; +import { removeEmptyProperties } from '../../utilities/removeEmptyProperties'; export async function listMappedFdmNodes( fdmSdk: FdmSDK, @@ -64,22 +65,3 @@ function createChunkedMappedEquipmentQueries( createMappedEquipmentQuery(models, viewChunk, undefined, limit, cursors) ); } - -function removeEmptyProperties(queryResultNode: NodeItem): NodeItem { - Object.keys(queryResultNode.properties).forEach((space) => { - const currentSpaceProperties = queryResultNode.properties[space]; - const newProperties: Record> = {}; - - Object.keys(currentSpaceProperties).forEach((view) => { - const currentViewProperties = currentSpaceProperties[view]; - - if (Object.keys(currentViewProperties).length !== 0) { - newProperties[view] = currentViewProperties; - } - }); - - queryResultNode.properties[space] = newProperties; - }); - - return queryResultNode; -} diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 5bc0fa79bfb..2dd2c1d0315 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -16,6 +16,7 @@ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { type AddModelOptions } from '@cognite/reveal'; import { isEqual, uniq, chunk } from 'lodash'; import { Fdm3dDataProvider } from '../data-providers/Fdm3dDataProvider'; +import { removeEmptyProperties } from '../utilities/removeEmptyProperties'; export type InstancesWithView = { view: Source; instances: NodeItem[] }; diff --git a/react-components/src/utilities/removeEmptyProperties.ts b/react-components/src/utilities/removeEmptyProperties.ts new file mode 100644 index 00000000000..909c4dfca44 --- /dev/null +++ b/react-components/src/utilities/removeEmptyProperties.ts @@ -0,0 +1,20 @@ +import { NodeItem } from '../data-providers/FdmSDK'; + +export function removeEmptyProperties(queryResultNode: NodeItem): NodeItem { + Object.keys(queryResultNode.properties).forEach((space) => { + const currentSpaceProperties = queryResultNode.properties[space]; + const newProperties: Record> = {}; + + Object.keys(currentSpaceProperties).forEach((view) => { + const currentViewProperties = currentSpaceProperties[view]; + + if (Object.keys(currentViewProperties).length !== 0) { + newProperties[view] = currentViewProperties; + } + }); + + queryResultNode.properties[space] = newProperties; + }); + + return queryResultNode; +} From c4c4bb19e4894e2179266d0ed08c026528f96fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 24 Jul 2024 13:13:58 +0200 Subject: [PATCH 04/12] chore: finish current stage of legacy implementation --- .../components/CacheProvider/FdmNodeCache.ts | 23 +-------------- .../src/data-providers/Fdm3dDataProvider.ts | 2 +- .../LegacyFdm3dDataProvider.ts | 10 ++++--- .../getCadConnectionsForRevision.ts | 29 +++++++++++++++++++ .../getCadModelsForFdmInstance.ts | 11 +++---- .../src/query/useModelsForInstanceQuery.ts | 17 ++--------- 6 files changed, 44 insertions(+), 48 deletions(-) create mode 100644 react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts rename react-components/src/{hooks/network => data-providers/legacy-fdm-provider}/getCadModelsForFdmInstance.ts (90%) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index e3d81044512..29f407feb96 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -233,7 +233,7 @@ export class FdmNodeCache { fetchViews: boolean ): Promise> { const revisionIds = modelRevisionIds.map((modelRevisionId) => modelRevisionId.revisionId); - const connections = await this.getConnectionsForRevision(revisionIds, this._fdmClient); + const connections = await this._fdm3dDataProvider.getCadConnectionsForRevisions(revisionIds); const connectionsWithOptionalViews = fetchViews ? await this.getViewsForConnections(connections) @@ -276,27 +276,6 @@ export class FdmNodeCache { return dataWithViews; } - private async getConnectionsForRevision( - revisionIds: number[], - fdmClient: FdmSDK - ): Promise { - if (revisionIds.length === 0) return []; - - const versionedPropertiesKey = `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`; - const filter = { - in: { - property: [SYSTEM_SPACE_3D_SCHEMA, versionedPropertiesKey, 'revisionId'], - values: revisionIds - } - }; - const mappings = await fdmClient.filterAllInstances( - filter, - 'edge', - SYSTEM_3D_EDGE_SOURCE - ); - return fdmEdgesToCadConnections(mappings.instances); - } - private getOrCreateRevisionCache(modelId: number, revisionId: number): RevisionFdmNodeCache { const revisionKey = createModelRevisionKey(modelId, revisionId); diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index 3c23f9fdb8d..3505807039b 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -41,7 +41,7 @@ export type Fdm3dDataProvider = { models: AddModelOptions[], spacesToSearch: string[] ): Promise; // useSearchMappedEquipmentFdm - getModelsForInstance(instance: DmsUniqueIdentifier): Promise; // useModelsForInstanceQuery (only support CAD for now?) + getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise; // useModelsForInstanceQuery (only support CAD for now?) getCadConnectionsForRevisions(revisions: number[]): Promise; // FdmNodeCache.ts / getEdgesForRevisions }; diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index 8da9359b560..e21946407b7 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -9,6 +9,8 @@ import { getFdmConnectionsForNodeIds } from './getFdmConnectionsForNodeIds'; import { getDMSModels } from './getDMSModels'; import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; +import { getCadModelsForFdmInstance } from './getCadModelsForFdmInstance'; +import { getConnectionsForRevision } from './getCadConnectionsForRevision'; export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { readonly _fdmSdk: FdmSDK; @@ -58,11 +60,11 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { return filterNodesByMappedTo3d(this._fdmSdk, nodes, models, spacesToSearch); } - getModelsForInstance(instance: DmsUniqueIdentifier): Promise { - // useModelsForInstanceQuery (only support CAD for now?) - return Promise.resolve([]); + getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { + return getCadModelsForFdmInstance(this._fdmSdk, instance); } + getCadConnectionsForRevisions(revisions: number[]): Promise { - return Promise.resolve([]); + return getConnectionsForRevision(revisions, this._fdmSdk); } // FdmNodeCache.ts / getEdgesForRevisions } diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts new file mode 100644 index 00000000000..aff86f72ffe --- /dev/null +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts @@ -0,0 +1,29 @@ +import { FdmCadConnection } from '../../components/CacheProvider/types'; +import { FdmSDK } from '../FdmSDK'; +import { + InModel3dEdgeProperties, + SYSTEM_3D_EDGE_SOURCE, + SYSTEM_SPACE_3D_SCHEMA +} from './dataModels'; +import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; + +export async function getConnectionsForRevision( + revisionIds: number[], + fdmClient: FdmSDK +): Promise { + if (revisionIds.length === 0) return []; + + const versionedPropertiesKey = `${SYSTEM_3D_EDGE_SOURCE.externalId}/${SYSTEM_3D_EDGE_SOURCE.version}`; + const filter = { + in: { + property: [SYSTEM_SPACE_3D_SCHEMA, versionedPropertiesKey, 'revisionId'], + values: revisionIds + } + }; + const mappings = await fdmClient.filterAllInstances( + filter, + 'edge', + SYSTEM_3D_EDGE_SOURCE + ); + return fdmEdgesToCadConnections(mappings.instances); +} diff --git a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts similarity index 90% rename from react-components/src/hooks/network/getCadModelsForFdmInstance.ts rename to react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts index 8565c123729..6ef01ee9b70 100644 --- a/react-components/src/hooks/network/getCadModelsForFdmInstance.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadModelsForFdmInstance.ts @@ -2,11 +2,8 @@ * Copyright 2024 Cognite AS */ import { type TaggedAddCadResourceOptions } from '../../components/Reveal3DResources/types'; -import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../../data-providers/FdmSDK'; -import { - type InModel3dEdgeProperties, - SYSTEM_3D_EDGE_SOURCE -} from '../../data-providers/legacy-fdm-provider/dataModels'; +import { type DmsUniqueIdentifier, type EdgeItem, type FdmSDK } from '../FdmSDK'; +import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { isDefined } from '../../utilities/isDefined'; type ModelForInstancesResponse = { @@ -14,8 +11,8 @@ type ModelForInstancesResponse = { }; export async function getCadModelsForFdmInstance( - instance: DmsUniqueIdentifier, - sdk: FdmSDK + sdk: FdmSDK, + instance: DmsUniqueIdentifier ): Promise { const result = ( await sdk.queryNodesAndEdges({ diff --git a/react-components/src/query/useModelsForInstanceQuery.ts b/react-components/src/query/useModelsForInstanceQuery.ts index 29f82507b83..3e5761aee63 100644 --- a/react-components/src/query/useModelsForInstanceQuery.ts +++ b/react-components/src/query/useModelsForInstanceQuery.ts @@ -2,13 +2,11 @@ * Copyright 2024 Cognite AS */ import { type UseQueryResult, useQuery } from '@tanstack/react-query'; -import { type DmsUniqueIdentifier, type FdmSDK } from '../data-providers/FdmSDK'; import { getCadModelsForAsset } from '../hooks/network/getCadModelsForAsset'; import { getPointCloudModelsForAsset } from '../hooks/network/getPointCloudModelsForAsset'; -import { useFdmSdk, useSDK } from '../components/RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useSDK } from '../components/RevealCanvas/SDKProvider'; import { type CogniteClient } from '@cognite/sdk'; import { type TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; -import { getCadModelsForFdmInstance } from '../hooks/network/getCadModelsForFdmInstance'; import { getImage360CollectionsForAsset } from '../hooks/network/getImage360CollectionsForAsset'; import { type AssetInstanceReference, @@ -23,7 +21,7 @@ export const useModelsForInstanceQuery = ( instance: InstanceReference | undefined ): UseQueryResult => { const cogniteClient = useSDK(); - const fdmSdk = useFdmSdk(); + const fdm3dDataProvider = useFdm3dDataProvider(); return useQuery({ queryKey: ['reveal', 'react-components', instance], @@ -37,7 +35,7 @@ export const useModelsForInstanceQuery = ( } if (isDmsInstance(instance)) { - return await getModelsForFdmInstance(instance, fdmSdk); + return fdm3dDataProvider.getCadModelsForInstance(instance); } }, enabled: instance !== undefined @@ -61,12 +59,3 @@ async function getModelsForAssetInstance( return uniqBy(results, createAddOptionsKey); } - -async function getModelsForFdmInstance( - instance: DmsUniqueIdentifier, - fdmSdk: FdmSDK -): Promise { - const cadModelsPromise = getCadModelsForFdmInstance(instance, fdmSdk); - - return await cadModelsPromise; -} From 620b554626bbd5908ffac6aad2338a97e43aa1e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 24 Jul 2024 13:29:10 +0200 Subject: [PATCH 05/12] chore: lint fix --- .../components/CacheProvider/FdmNodeCache.ts | 9 +-- .../CacheProvider/RevisionFdmNodeCache.ts | 2 +- .../src/components/CacheProvider/requests.ts | 14 +---- .../RevealCanvas/FdmDataProviderContext.ts | 7 ++- .../components/RevealCanvas/SDKProvider.tsx | 2 +- .../src/data-providers/Fdm3dDataProvider.ts | 30 +++++----- .../LegacyFdm3dDataProvider.ts | 59 ++++++++++++------- .../createMappedEquipmentQuery.ts | 7 ++- .../fdmEdgesToCadConnections.ts | 9 ++- .../filterNodesByMappedTo3d.ts | 23 ++++---- .../getCadConnectionsForRevision.ts | 9 ++- .../legacy-fdm-provider/getDMSModels.ts | 5 +- .../getEdgeConnected3dInstances.ts | 5 +- .../getFdmConnectionsForNodeIds.ts | 11 ++-- .../legacy-fdm-provider/listMappedFdmNodes.ts | 13 +++- .../src/query/useModelsForInstanceQuery.ts | 2 +- .../src/query/useSearchMappedEquipmentFDM.tsx | 12 ++-- .../src/utilities/removeEmptyProperties.ts | 5 +- 18 files changed, 129 insertions(+), 95 deletions(-) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 29f407feb96..c5a584aff93 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -17,25 +17,20 @@ import { type FdmKey, type FdmNodeDataPromises } from './types'; + import { createFdmKey, createModelNodeIdKey, createModelRevisionKey, revisionKeyToIds } from './idAndKeyTranslation'; -import { - type InModel3dEdgeProperties, - SYSTEM_3D_EDGE_SOURCE, - SYSTEM_SPACE_3D_SCHEMA -} from '../../data-providers/legacy-fdm-provider/dataModels'; import { partition } from 'lodash'; import assert from 'assert'; import { fetchNodesForNodeIds, inspectNodes } from './requests'; import { type ThreeDModelFdmMappings } from '../../hooks/types'; -import { fdmEdgesToCadConnections } from '../../data-providers/legacy-fdm-provider/fdmEdgesToCadConnections'; -import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; export class FdmNodeCache { private readonly _revisionNodeCaches = new Map(); diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index 07a499f8f25..a74195fe170 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -18,7 +18,7 @@ import { fetchAncestorNodesForTreeIndex, inspectNodes } from './requests'; import { max } from 'lodash'; import assert from 'assert'; -import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; export class RevisionFdmNodeCache { private readonly _cogniteClient: CogniteClient; diff --git a/react-components/src/components/CacheProvider/requests.ts b/react-components/src/components/CacheProvider/requests.ts index 4649b103e48..439298ede92 100644 --- a/react-components/src/components/CacheProvider/requests.ts +++ b/react-components/src/components/CacheProvider/requests.ts @@ -2,22 +2,12 @@ * Copyright 2023 Cognite AS */ -import { type CogniteClient, type CogniteInternalId, type Node3D } from '@cognite/sdk'; +import { type CogniteClient, type Node3D } from '@cognite/sdk'; import { - type Source, type DmsUniqueIdentifier, type FdmSDK, - type InspectResultList, - type EdgeItem + type InspectResultList } from '../../data-providers/FdmSDK'; -import { type FdmCadConnection } from './types'; -import { - type InModel3dEdgeProperties, - SYSTEM_3D_EDGE_SOURCE, - SYSTEM_SPACE_3D_SCHEMA, - SYSTEM_SPACE_3D_MODEL_ID, - SYSTEM_SPACE_3D_MODEL_VERSION -} from '../../data-providers/legacy-fdm-provider/dataModels'; import { chunk } from 'lodash'; export async function fetchAncestorNodesForTreeIndex( diff --git a/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts b/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts index 5640d5e842d..94f7ef55d29 100644 --- a/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts +++ b/react-components/src/components/RevealCanvas/FdmDataProviderContext.ts @@ -1,5 +1,8 @@ -import { FdmSDK } from '../../data-providers/FdmSDK'; -import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +/*! + * Copyright 2024 Cognite AS + */ +import { type FdmSDK } from '../../data-providers/FdmSDK'; +import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; import { createContext } from 'react'; /** diff --git a/react-components/src/components/RevealCanvas/SDKProvider.tsx b/react-components/src/components/RevealCanvas/SDKProvider.tsx index e75b368b625..c4ff4889fff 100644 --- a/react-components/src/components/RevealCanvas/SDKProvider.tsx +++ b/react-components/src/components/RevealCanvas/SDKProvider.tsx @@ -6,7 +6,7 @@ import { type CogniteClient } from '@cognite/sdk'; import { FdmSdkContext } from './FdmDataProviderContext'; import { FdmSDK } from '../../data-providers/FdmSDK'; import { LegacyFdm3dDataProvider } from '../../data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider'; -import { Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; +import { type Fdm3dDataProvider } from '../../data-providers/Fdm3dDataProvider'; const SdkContext = createContext(null); diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index 3505807039b..af51193f0bf 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -2,47 +2,47 @@ * Copyright 2024 Cognite AS */ import { - InstanceFilter, - NodeItem, - Source, + type InstanceFilter, + type NodeItem, + type Source, type DmsUniqueIdentifier, type ViewItem } from './FdmSDK'; import { type AddModelOptions } from '@cognite/reveal'; import { type InstancesWithView } from '../query/useSearchMappedEquipmentFDM'; import { type FdmCadConnection } from '../components/CacheProvider/types'; -import { TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; +import { type TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; export type Fdm3dDataProvider = { is3dView: (view: ViewItem) => boolean; // use3drelatedDirectConnection - getDMSModels(modelId: number): Promise; + getDMSModels: (modelId: number) => Promise; getEdgeConnected3dInstances: (instance: DmsUniqueIdentifier) => Promise; // use3drelateddirectconnection - getFdmConnectionsForNodeIds( + getFdmConnectionsForNodeIds: ( models: DmsUniqueIdentifier[], revisionId: number, nodeIds: number[] - ): Promise; // CacheProvider / requests.ts / getFdmConnectionsForNodeIds + ) => Promise; // CacheProvider / requests.ts / getFdmConnectionsForNodeIds - listMappedFdmNodes( + listMappedFdmNodes: ( models: AddModelOptions[], sourcesToSearch: Source[], instancesFilter: InstanceFilter | undefined, limit: number - ): Promise; // useSearchMappedEquipmentFdm + ) => Promise; // useSearchMappedEquipmentFdm - listAllMappedFdmNodes( + listAllMappedFdmNodes: ( models: AddModelOptions[], sourcesToSearch: Source[], instanceFilter: InstanceFilter | undefined - ): Promise; + ) => Promise; - filterNodesByMappedTo3d( + filterNodesByMappedTo3d: ( nodes: InstancesWithView[], models: AddModelOptions[], spacesToSearch: string[] - ): Promise; // useSearchMappedEquipmentFdm - getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise; // useModelsForInstanceQuery (only support CAD for now?) - getCadConnectionsForRevisions(revisions: number[]): Promise; // FdmNodeCache.ts / getEdgesForRevisions + ) => Promise; // useSearchMappedEquipmentFdm + getCadModelsForInstance: (instance: DmsUniqueIdentifier) => Promise; // useModelsForInstanceQuery (only support CAD for now?) + getCadConnectionsForRevisions: (revisions: number[]) => Promise; // FdmNodeCache.ts / getEdgesForRevisions }; /* use3dRelatedDirectConnections() - diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index e21946407b7..b2da4c20af4 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -1,9 +1,19 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { Fdm3dDataProvider } from '../Fdm3dDataProvider'; -import { DmsUniqueIdentifier, FdmSDK, InstanceFilter, NodeItem, Source, ViewItem } from '../FdmSDK'; -import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; -import { TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; +/*! + * Copyright 2024 Cognite AS + */ +import { type AddModelOptions } from '@cognite/reveal'; +import { type FdmCadConnection } from '../../components/CacheProvider/types'; +import { type Fdm3dDataProvider } from '../Fdm3dDataProvider'; +import { + type DmsUniqueIdentifier, + type FdmSDK, + type InstanceFilter, + type NodeItem, + type Source, + type ViewItem +} from '../FdmSDK'; +import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +import { type TaggedAddResourceOptions } from '../../components/Reveal3DResources/types'; import { getEdgeConnected3dInstances } from './getEdgeConnected3dInstances'; import { getFdmConnectionsForNodeIds } from './getFdmConnectionsForNodeIds'; import { getDMSModels } from './getDMSModels'; @@ -23,48 +33,53 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { return Object.keys(view.properties).some((propName) => propName === 'inModel3d'); } - getDMSModels(modelId: number): Promise { - return getDMSModels(this._fdmSdk, modelId); + async getDMSModels(modelId: number): Promise { + return await getDMSModels(this._fdmSdk, modelId); } - getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { - return getEdgeConnected3dInstances(this._fdmSdk, instance); + async getEdgeConnected3dInstances(instance: DmsUniqueIdentifier): Promise { + return await getEdgeConnected3dInstances(this._fdmSdk, instance); } - getFdmConnectionsForNodeIds( + async getFdmConnectionsForNodeIds( models: DmsUniqueIdentifier[], revisionId: number, nodeIds: number[] ): Promise { - return getFdmConnectionsForNodeIds(this._fdmSdk, models, revisionId, nodeIds); + return await getFdmConnectionsForNodeIds(this._fdmSdk, models, revisionId, nodeIds); } - listMappedFdmNodes( + async listMappedFdmNodes( models: AddModelOptions[], sourcesToSearch: Source[], instanceFilter: InstanceFilter | undefined, limit: number ): Promise { - return listMappedFdmNodes(this._fdmSdk, models, sourcesToSearch, instanceFilter, limit); + return await listMappedFdmNodes(this._fdmSdk, models, sourcesToSearch, instanceFilter, limit); } // useSearchMappedEquipmentFdm - listAllMappedFdmNodes(models: AddModelOptions[], sourcesToSearch: Source[]): Promise { - return listAllMappedFdmNodes(this._fdmSdk, models, sourcesToSearch); + async listAllMappedFdmNodes( + models: AddModelOptions[], + sourcesToSearch: Source[] + ): Promise { + return await listAllMappedFdmNodes(this._fdmSdk, models, sourcesToSearch); } - filterNodesByMappedTo3d( + async filterNodesByMappedTo3d( nodes: InstancesWithView[], models: AddModelOptions[], spacesToSearch: string[] ): Promise { - return filterNodesByMappedTo3d(this._fdmSdk, nodes, models, spacesToSearch); + return await filterNodesByMappedTo3d(this._fdmSdk, nodes, models, spacesToSearch); } - getCadModelsForInstance(instance: DmsUniqueIdentifier): Promise { - return getCadModelsForFdmInstance(this._fdmSdk, instance); + async getCadModelsForInstance( + instance: DmsUniqueIdentifier + ): Promise { + return await getCadModelsForFdmInstance(this._fdmSdk, instance); } - getCadConnectionsForRevisions(revisions: number[]): Promise { - return getConnectionsForRevision(revisions, this._fdmSdk); + async getCadConnectionsForRevisions(revisions: number[]): Promise { + return await getConnectionsForRevision(revisions, this._fdmSdk); } // FdmNodeCache.ts / getEdgesForRevisions } diff --git a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts index 05b781062bc..2d2929b3165 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/createMappedEquipmentQuery.ts @@ -1,5 +1,8 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { InstanceFilter, Query, Source } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type AddModelOptions } from '@cognite/reveal'; +import { type InstanceFilter, type Query, type Source } from '../FdmSDK'; import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; export function createMappedEquipmentQuery( diff --git a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts index fab19b3ba5e..c6009087191 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/fdmEdgesToCadConnections.ts @@ -1,6 +1,9 @@ -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { EdgeItem } from '../FdmSDK'; -import { InModel3dEdgeProperties } from './dataModels'; +/*! + * Copyright 2024 Cognite AS + */ +import { type FdmCadConnection } from '../../components/CacheProvider/types'; +import { type EdgeItem } from '../FdmSDK'; +import { type InModel3dEdgeProperties } from './dataModels'; export function fdmEdgesToCadConnections( edges: Array> diff --git a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts index 048f4327ba3..161e0b0d3bd 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/filterNodesByMappedTo3d.ts @@ -1,17 +1,20 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; +/*! + * Copyright 2024 Cognite AS + */ +import { type AddModelOptions } from '@cognite/reveal'; +import { type InstancesWithView } from '../../query/useSearchMappedEquipmentFDM'; import { - DmsUniqueIdentifier, - EdgeItem, - ExternalId, - FdmSDK, - NodeItem, - Query, - Source + type DmsUniqueIdentifier, + type EdgeItem, + type ExternalId, + type FdmSDK, + type NodeItem, + type Query, + type Source } from '../FdmSDK'; import { SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; import { getDMSModels } from './getDMSModels'; -import { FdmKey } from '../../components/CacheProvider/types'; +import { type FdmKey } from '../../components/CacheProvider/types'; export async function filterNodesByMappedTo3d( fdmSdk: FdmSDK, diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts index aff86f72ffe..30e74b7f1a0 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts @@ -1,7 +1,10 @@ -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { FdmSDK } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type FdmCadConnection } from '../../components/CacheProvider/types'; +import { type FdmSDK } from '../FdmSDK'; import { - InModel3dEdgeProperties, + type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE, SYSTEM_SPACE_3D_SCHEMA } from './dataModels'; diff --git a/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts b/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts index 31f529a9ec1..047a5996d2f 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getDMSModels.ts @@ -1,4 +1,7 @@ -import { DmsUniqueIdentifier, FdmSDK, Source } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type DmsUniqueIdentifier, type FdmSDK, type Source } from '../FdmSDK'; import { SYSTEM_SPACE_3D_MODEL_ID, SYSTEM_SPACE_3D_MODEL_VERSION, diff --git a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts index 41c0a38d183..4ea8c044b6d 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getEdgeConnected3dInstances.ts @@ -1,5 +1,8 @@ +/*! + * Copyright 2024 Cognite AS + */ import { SYSTEM_3D_EDGE_SOURCE } from './dataModels'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; export async function getEdgeConnected3dInstances( fdmSdk: FdmSDK, diff --git a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts index e7834706652..ad3bd5206c5 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getFdmConnectionsForNodeIds.ts @@ -1,7 +1,10 @@ -import { CogniteInternalId } from '@cognite/sdk/dist/src'; -import { DmsUniqueIdentifier, FdmSDK } from '../FdmSDK'; -import { FdmCadConnection } from '../../components/CacheProvider/types'; -import { InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; +/*! + * Copyright 2024 Cognite AS + */ +import { type CogniteInternalId } from '@cognite/sdk/dist/src'; +import { type DmsUniqueIdentifier, type FdmSDK } from '../FdmSDK'; +import { type FdmCadConnection } from '../../components/CacheProvider/types'; +import { type InModel3dEdgeProperties, SYSTEM_3D_EDGE_SOURCE } from './dataModels'; import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; export async function getFdmConnectionsForNodeIds( diff --git a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts index 96ab7b238d8..57f1369875d 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/listMappedFdmNodes.ts @@ -1,5 +1,14 @@ -import { AddModelOptions } from '@cognite/reveal'; -import { FdmSDK, InstanceFilter, NodeItem, Query, Source } from '../FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type AddModelOptions } from '@cognite/reveal'; +import { + type FdmSDK, + type InstanceFilter, + type NodeItem, + type Query, + type Source +} from '../FdmSDK'; import { createMappedEquipmentQuery } from './createMappedEquipmentQuery'; import { chunk, isEqual } from 'lodash'; import { removeEmptyProperties } from '../../utilities/removeEmptyProperties'; diff --git a/react-components/src/query/useModelsForInstanceQuery.ts b/react-components/src/query/useModelsForInstanceQuery.ts index 3e5761aee63..316606312ef 100644 --- a/react-components/src/query/useModelsForInstanceQuery.ts +++ b/react-components/src/query/useModelsForInstanceQuery.ts @@ -35,7 +35,7 @@ export const useModelsForInstanceQuery = ( } if (isDmsInstance(instance)) { - return fdm3dDataProvider.getCadModelsForInstance(instance); + return await fdm3dDataProvider.getCadModelsForInstance(instance); } }, enabled: instance !== undefined diff --git a/react-components/src/query/useSearchMappedEquipmentFDM.tsx b/react-components/src/query/useSearchMappedEquipmentFDM.tsx index 2dd2c1d0315..45da5749830 100644 --- a/react-components/src/query/useSearchMappedEquipmentFDM.tsx +++ b/react-components/src/query/useSearchMappedEquipmentFDM.tsx @@ -1,21 +1,19 @@ /*! * Copyright 2023 Cognite AS */ -import { type CogniteClient } from '@cognite/sdk'; import { useMemo } from 'react'; import { type NodeItem, - FdmSDK, + type FdmSDK, type Source, - type Query, type DmsUniqueIdentifier, type InstanceFilter } from '../data-providers/FdmSDK'; -import { useFdm3dDataProvider, useFdmSdk, useSDK } from '../components/RevealCanvas/SDKProvider'; +import { useFdm3dDataProvider, useFdmSdk } from '../components/RevealCanvas/SDKProvider'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { type AddModelOptions } from '@cognite/reveal'; import { isEqual, uniq, chunk } from 'lodash'; -import { Fdm3dDataProvider } from '../data-providers/Fdm3dDataProvider'; +import { type Fdm3dDataProvider } from '../data-providers/Fdm3dDataProvider'; import { removeEmptyProperties } from '../utilities/removeEmptyProperties'; export type InstancesWithView = { view: Source; instances: NodeItem[] }; @@ -113,7 +111,7 @@ const searchNodesWithViewsAndModels = async ( }); } - return fdmDataProvider.filterNodesByMappedTo3d(searchResults, models, spacesToSearch); + return await fdmDataProvider.filterNodesByMappedTo3d(searchResults, models, spacesToSearch); }; export const useAllMappedEquipmentFDM = ( @@ -128,7 +126,7 @@ export const useAllMappedEquipmentFDM = ( queryFn: async () => { const viewSources = await createSourcesFromViews(viewsToSearch, fdmSdk); - return fdmDataProvider.listAllMappedFdmNodes(models, viewSources, undefined); + return await fdmDataProvider.listAllMappedFdmNodes(models, viewSources, undefined); }, staleTime: Infinity }); diff --git a/react-components/src/utilities/removeEmptyProperties.ts b/react-components/src/utilities/removeEmptyProperties.ts index 909c4dfca44..2930e402bfd 100644 --- a/react-components/src/utilities/removeEmptyProperties.ts +++ b/react-components/src/utilities/removeEmptyProperties.ts @@ -1,4 +1,7 @@ -import { NodeItem } from '../data-providers/FdmSDK'; +/*! + * Copyright 2024 Cognite AS + */ +import { type NodeItem } from '../data-providers/FdmSDK'; export function removeEmptyProperties(queryResultNode: NodeItem): NodeItem { Object.keys(queryResultNode.properties).forEach((space) => { From 4ff38eb5de64233c91df4a8c176b3d47084d4da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 24 Jul 2024 13:35:25 +0200 Subject: [PATCH 06/12] chore: type check fixes --- .../stories/SearchHooks.stories.tsx | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/react-components/stories/SearchHooks.stories.tsx b/react-components/stories/SearchHooks.stories.tsx index bcfe7066047..52368daf22d 100644 --- a/react-components/stories/SearchHooks.stories.tsx +++ b/react-components/stories/SearchHooks.stories.tsx @@ -71,8 +71,7 @@ const StoryContent = ({ resources }: { resources: AddResourceOptions[] }): React viewsToSearch, filteredResources, undefined, - 100, - sdk + 100 ); const { data: assetSearchData } = useSearchMappedEquipmentAssetMappings( @@ -82,7 +81,7 @@ const StoryContent = ({ resources }: { resources: AddResourceOptions[] }): React sdk ); - const { data: allEquipment } = useAllMappedEquipmentFDM(filteredResources, viewsToSearch, sdk); + const { data: allEquipment } = useAllMappedEquipmentFDM(filteredResources, viewsToSearch); const { data: allAssets, @@ -248,21 +247,19 @@ const StoryContent = ({ resources }: { resources: AddResourceOptions[] }): React return ( <> - - - - - - - + + + + +

Mapped equipment

{ return ( - - - + + + + + ); } }; From 12b4d7faf2e2b18dc2f8e5103eaf082b26f4f555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 25 Jul 2024 13:36:46 +0200 Subject: [PATCH 07/12] chore: more renames --- .../components/CacheProvider/FdmNodeCache.ts | 34 +++++++++---------- .../CacheProvider/RevisionFdmNodeCache.ts | 12 +++---- .../src/hooks/useCameraNavigation.tsx | 2 +- .../src/query/use3dNodeByExternalId.tsx | 5 ++- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index c5a584aff93..19b3a3e0dcd 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -51,8 +51,8 @@ export class FdmNodeCache { this._fdm3dDataProvider = fdm3dDataProvider; } - public async getMappingsForFdmIds( - externalIds: DmsUniqueIdentifier[], + public async getMappingsForFdmInstances( + instances: DmsUniqueIdentifier[], modelRevisionIds: ModelRevisionId[] ): Promise { const [cachedModelRevisionIds, nonCachedModelRevisionIds] = partition( @@ -64,11 +64,11 @@ export class FdmNodeCache { ); const nonCachedModelMappings = await this.getNonCachedModelMappings( - externalIds, + instances, nonCachedModelRevisionIds ); - const cachedModelMappings = this.getCachedModelMappings(cachedModelRevisionIds, externalIds); + const cachedModelMappings = this.getCachedModelMappings(cachedModelRevisionIds, instances); const combinedList = [...cachedModelMappings, ...nonCachedModelMappings]; return combinedList; @@ -96,7 +96,7 @@ export class FdmNodeCache { modelRevisionId.revisionId ); - const relevantCachedEdgeData = intersectWithStartNodeIdSet( + const relevantCachedEdgeData = intersectWithFdmKeySet( revisionCache.getAllEdges(), relevantFdmKeySet ); @@ -112,43 +112,41 @@ export class FdmNodeCache { } private async getNonCachedModelMappings( - uniqueIds: DmsUniqueIdentifier[], + instances: DmsUniqueIdentifier[], modelRevisions: ModelRevisionId[] ): Promise { - if (modelRevisions.length === 0 || uniqueIds.length === 0) { + if (modelRevisions.length === 0 || instances.length === 0) { return []; } - const fdmKeySet = new Set(uniqueIds.map((id) => createFdmKey(id.space, id.externalId))); + const fdmKeySet = new Set(instances.map((id) => createFdmKey(id.space, id.externalId))); const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(modelRevisions, false); - const modelDataPromises = modelRevisions.map(async ({ modelId, revisionId }) => { + return modelRevisions.map(({ modelId, revisionId }) => { const revisionKey = createModelRevisionKey(modelId, revisionId); - const edges = revisionToEdgesMap.get(revisionKey); + const connections = revisionToEdgesMap.get(revisionKey); return this.getRelevantExternalIdToNodeMapForRevision( { modelId, revisionId }, - edges, + connections, fdmKeySet ); }); - - return await Promise.all(modelDataPromises); } private getRelevantExternalIdToNodeMapForRevision( { modelId, revisionId }: ModelRevisionId, - edges: FdmConnectionWithNode[] | undefined, + connections: FdmConnectionWithNode[] | undefined, relevantFdmKeySet: Set ): ThreeDModelFdmMappings { - if (edges === undefined || edges.length === 0) + if (connections === undefined || connections.length === 0) return { modelId, revisionId, mappings: new Map() }; - const relevantEdges = intersectWithStartNodeIdSet(edges, relevantFdmKeySet); + const relevantConnections = intersectWithFdmKeySet(connections, relevantFdmKeySet); const externalIdToNodeMap = createMapWithAccumulatedValues( - relevantEdges.map((edge) => [edge.connection.instance.externalId, edge.cadNode]) + relevantConnections.map((edge) => [edge.connection.instance.externalId, edge.cadNode]) ); return { @@ -403,7 +401,7 @@ function createRevisionToNodeIdMap( }, new Map()); } -function intersectWithStartNodeIdSet( +function intersectWithFdmKeySet( connections: FdmConnectionWithNode[], relevantFdmKeySet: Set ): FdmConnectionWithNode[] { diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index a74195fe170..5fefeeaca20 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -233,19 +233,17 @@ export class RevisionFdmNodeCache { } private combineEdgesWithTreeIndex( - mappingEdges: FdmCadConnection[], + mappingConnections: FdmCadConnection[], nodes: Node3D[] ): Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> { - return mappingEdges.map((connection) => { - const ancestorConnectedToEdge = nodes.find( - (ancestor) => ancestor.id === connection.revisionId - ); + return mappingConnections.map((connection) => { + const nodeInConnection = nodes.find((node) => node.id === connection.nodeId); - assert(ancestorConnectedToEdge !== undefined); + assert(nodeInConnection !== undefined); return { connection, - treeIndex: ancestorConnectedToEdge.treeIndex + treeIndex: nodeInConnection.treeIndex }; }); } diff --git a/react-components/src/hooks/useCameraNavigation.tsx b/react-components/src/hooks/useCameraNavigation.tsx index 3930e3bf681..e71bc1ad24f 100644 --- a/react-components/src/hooks/useCameraNavigation.tsx +++ b/react-components/src/hooks/useCameraNavigation.tsx @@ -56,7 +56,7 @@ export const useCameraNavigation = (): CameraNavigationActions => { })); const modelMappings = ( - await fdmNodeCache.cache.getMappingsForFdmIds(instances, modelsRevisionIds) + await fdmNodeCache.cache.getMappingsForFdmInstances(instances, modelsRevisionIds) ).find((model) => model.mappings.size > 0); const nodeIds = [...(modelMappings?.mappings.values() ?? [])].flat().map((node) => node.id); diff --git a/react-components/src/query/use3dNodeByExternalId.tsx b/react-components/src/query/use3dNodeByExternalId.tsx index 9d4cb767628..db82fcf3dff 100644 --- a/react-components/src/query/use3dNodeByExternalId.tsx +++ b/react-components/src/query/use3dNodeByExternalId.tsx @@ -30,7 +30,10 @@ export const use3dNodeByExternalId = ({ })); const modelMappings = ( - await fdmNodeCache.cache.getMappingsForFdmIds([{ externalId, space }], modelsRevisionIds) + await fdmNodeCache.cache.getMappingsForFdmInstances( + [{ externalId, space }], + modelsRevisionIds + ) ).find((model) => model.mappings.size > 0); const node3d = modelMappings?.mappings.get(externalId)?.[0]; From 083487b9d0b92460571203b267a834fa6d82079f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 25 Jul 2024 13:37:01 +0200 Subject: [PATCH 08/12] chore: use models in dependency array in revision mapping fetch --- .../components/CacheProvider/NodeCacheProvider.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx index 0c8b011e404..2dc8be8bc14 100644 --- a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx @@ -92,10 +92,14 @@ export const useFdmAssetMappings = ( const nodeCacheContent = useFdmNodeCache(); return useQuery({ - queryKey: ['reveal', 'react-components', 'fdm-asset-mappings', fdmAssetExternalIds], - queryFn: async () => { - return await nodeCacheContent.cache.getMappingsForFdmIds(fdmAssetExternalIds, models); - }, + queryKey: [ + 'reveal', + 'react-components', + 'fdm-asset-mappings', + fdmAssetExternalIds, + models.map((model) => [model.modelId, model.revisionId]) + ], + queryFn: () => nodeCacheContent.cache.getMappingsForFdmInstances(fdmAssetExternalIds, models), enabled: fdmAssetExternalIds.length > 0 && models.length > 0, staleTime: DEFAULT_QUERY_STALE_TIME }); From 16f61081f513db942f5f10669eed85593f6a81a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 25 Jul 2024 13:42:20 +0200 Subject: [PATCH 09/12] chore: cleanup --- .../CacheProvider/NodeCacheProvider.tsx | 3 +- .../src/data-providers/Fdm3dDataProvider.ts | 31 +++++++------------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx index 2dc8be8bc14..090065f514c 100644 --- a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx @@ -99,7 +99,8 @@ export const useFdmAssetMappings = ( fdmAssetExternalIds, models.map((model) => [model.modelId, model.revisionId]) ], - queryFn: () => nodeCacheContent.cache.getMappingsForFdmInstances(fdmAssetExternalIds, models), + queryFn: async () => + await nodeCacheContent.cache.getMappingsForFdmInstances(fdmAssetExternalIds, models), enabled: fdmAssetExternalIds.length > 0 && models.length > 0, staleTime: DEFAULT_QUERY_STALE_TIME }); diff --git a/react-components/src/data-providers/Fdm3dDataProvider.ts b/react-components/src/data-providers/Fdm3dDataProvider.ts index af51193f0bf..065050068e2 100644 --- a/react-components/src/data-providers/Fdm3dDataProvider.ts +++ b/react-components/src/data-providers/Fdm3dDataProvider.ts @@ -14,21 +14,24 @@ import { type FdmCadConnection } from '../components/CacheProvider/types'; import { type TaggedAddResourceOptions } from '../components/Reveal3DResources/types'; export type Fdm3dDataProvider = { - is3dView: (view: ViewItem) => boolean; // use3drelatedDirectConnection + is3dView: (view: ViewItem) => boolean; + getDMSModels: (modelId: number) => Promise; - getEdgeConnected3dInstances: (instance: DmsUniqueIdentifier) => Promise; // use3drelateddirectconnection + + getEdgeConnected3dInstances: (instance: DmsUniqueIdentifier) => Promise; + getFdmConnectionsForNodeIds: ( models: DmsUniqueIdentifier[], revisionId: number, nodeIds: number[] - ) => Promise; // CacheProvider / requests.ts / getFdmConnectionsForNodeIds + ) => Promise; listMappedFdmNodes: ( models: AddModelOptions[], sourcesToSearch: Source[], instancesFilter: InstanceFilter | undefined, limit: number - ) => Promise; // useSearchMappedEquipmentFdm + ) => Promise; listAllMappedFdmNodes: ( models: AddModelOptions[], @@ -40,19 +43,9 @@ export type Fdm3dDataProvider = { nodes: InstancesWithView[], models: AddModelOptions[], spacesToSearch: string[] - ) => Promise; // useSearchMappedEquipmentFdm - getCadModelsForInstance: (instance: DmsUniqueIdentifier) => Promise; // useModelsForInstanceQuery (only support CAD for now?) - getCadConnectionsForRevisions: (revisions: number[]) => Promise; // FdmNodeCache.ts / getEdgesForRevisions -}; + ) => Promise; + + getCadModelsForInstance: (instance: DmsUniqueIdentifier) => Promise; -/* use3dRelatedDirectConnections() - - use3dRelatedEdgeConnections(related3dEdgesQuery) - - `useSearchMappedEquipmentFDM`( - createMappedEquipmentQuery, - createCheckMappedEquipmentQuery, - createInModelsFilter - ) - - getCadModelsForFdmInstance.ts(getCadModelsForFdmInstance) - - CacheProvider / requests.ts(getMappingEdgesForNodeIds, getDMSModels) - - FdmNodeCache.ts(getEdgesForRevisions); -*/ + getCadConnectionsForRevisions: (revisions: number[]) => Promise; +}; From 52a2c2ab7557da7d84b4c79279a4ad08ff99e2e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 25 Jul 2024 13:42:54 +0200 Subject: [PATCH 10/12] chore: remove comments --- .../legacy-fdm-provider/LegacyFdm3dDataProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index b2da4c20af4..bfdb34a2137 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -56,7 +56,7 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { limit: number ): Promise { return await listMappedFdmNodes(this._fdmSdk, models, sourcesToSearch, instanceFilter, limit); - } // useSearchMappedEquipmentFdm + } async listAllMappedFdmNodes( models: AddModelOptions[], @@ -81,5 +81,5 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { async getCadConnectionsForRevisions(revisions: number[]): Promise { return await getConnectionsForRevision(revisions, this._fdmSdk); - } // FdmNodeCache.ts / getEdgesForRevisions + } } From 061f52ced578ca1b9463731459f91be0cb56de8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Thu, 25 Jul 2024 14:01:00 +0200 Subject: [PATCH 11/12] chore: remove unused code --- .../legacy-fdm-provider/dataModels.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts b/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts index c341f71c12c..c0b362cabbf 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/dataModels.ts @@ -1,24 +1,13 @@ /*! * Copyright 2023 Cognite AS */ -import { type DmsUniqueIdentifier, type Source } from '../FdmSDK'; +import { type Source } from '../FdmSDK'; export const SYSTEM_SPACE_3D_SCHEMA = 'cdf_3d_schema'; // Data model, views, containers and types for edges export const SYSTEM_SPACE_3D_MODEL_ID = 'Cdf3dModel'; export const SYSTEM_SPACE_3D_MODEL_VERSION = '1'; -export const SYSTEM_3D_NODE_TYPE: DmsUniqueIdentifier = { - externalId: 'Cdf3dEntity', - space: SYSTEM_SPACE_3D_SCHEMA -}; - -// Type of edge that connects equipment to 3D -export const SYSTEM_3D_EDGE_TYPE: DmsUniqueIdentifier = { - externalId: 'cdf3dEntityConnection', - space: SYSTEM_SPACE_3D_SCHEMA -}; - // Source of view that contains edge properties export const SYSTEM_3D_EDGE_SOURCE: Source = { type: 'view', From 2238b7f1e4ca067534fb146cdde3dedd076dc4f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Fri, 26 Jul 2024 16:47:59 +0200 Subject: [PATCH 12/12] chore: call things connections, not edges --- .../components/CacheProvider/FdmNodeCache.ts | 66 ++++++++----- .../CacheProvider/NodeCacheProvider.tsx | 4 +- .../CacheProvider/RevisionFdmNodeCache.ts | 97 ++++++++++--------- .../src/components/CacheProvider/types.ts | 2 +- .../LegacyFdm3dDataProvider.ts | 4 +- .../getCadConnectionsForRevision.ts | 2 +- 6 files changed, 99 insertions(+), 76 deletions(-) diff --git a/react-components/src/components/CacheProvider/FdmNodeCache.ts b/react-components/src/components/CacheProvider/FdmNodeCache.ts index 19b3a3e0dcd..2132d33b899 100644 --- a/react-components/src/components/CacheProvider/FdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/FdmNodeCache.ts @@ -12,7 +12,7 @@ import { type RevisionId, type NodeId, type ModelNodeIdKey, - type ModelRevisionToEdgeMap, + type ModelRevisionToConnectionMap, type ModelRevisionId, type FdmKey, type FdmNodeDataPromises @@ -96,13 +96,16 @@ export class FdmNodeCache { modelRevisionId.revisionId ); - const relevantCachedEdgeData = intersectWithFdmKeySet( - revisionCache.getAllEdges(), + const relevantCachedConnectionData = intersectWithFdmKeySet( + revisionCache.getAllConnections(), relevantFdmKeySet ); const mappings = createMapWithAccumulatedValues( - relevantCachedEdgeData.map((data) => [data.connection.instance.externalId, data.cadNode]) + relevantCachedConnectionData.map((data) => [ + data.connection.instance.externalId, + data.cadNode + ]) ); return { @@ -121,11 +124,14 @@ export class FdmNodeCache { const fdmKeySet = new Set(instances.map((id) => createFdmKey(id.space, id.externalId))); - const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap(modelRevisions, false); + const revisionToConnectionsMap = await this.getAndCacheRevisionToConnectionsMap( + modelRevisions, + false + ); return modelRevisions.map(({ modelId, revisionId }) => { const revisionKey = createModelRevisionKey(modelId, revisionId); - const connections = revisionToEdgesMap.get(revisionKey); + const connections = revisionToConnectionsMap.get(revisionKey); return this.getRelevantExternalIdToNodeMapForRevision( { modelId, revisionId }, @@ -146,7 +152,10 @@ export class FdmNodeCache { const relevantConnections = intersectWithFdmKeySet(connections, relevantFdmKeySet); const externalIdToNodeMap = createMapWithAccumulatedValues( - relevantConnections.map((edge) => [edge.connection.instance.externalId, edge.cadNode]) + relevantConnections.map((connection) => [ + connection.connection.instance.externalId, + connection.cadNode + ]) ); return { @@ -159,7 +168,7 @@ export class FdmNodeCache { public async getAllMappingExternalIds( modelRevisionIds: ModelRevisionId[], fetchViews: boolean = false - ): Promise { + ): Promise { const [cachedRevisionIds, nonCachedRevisionIds] = partition(modelRevisionIds, (ids) => { const key = createModelRevisionKey(ids.modelId, ids.revisionId); return this._completeRevisions.has(key); @@ -169,18 +178,20 @@ export class FdmNodeCache { await this.fetchAllViewsForCachedRevisions(cachedRevisionIds); } - const cachedEdges = cachedRevisionIds.map((id) => this.getCachedEdgesForRevision(id)); + const cachedConnections = cachedRevisionIds.map((id) => + this.getCachedConnectionsForRevision(id) + ); - const revisionToEdgesMap = await this.getAndCacheRevisionToEdgesMap( + const revisionToConnectionsMap = await this.getAndCacheRevisionToConnectionsMap( nonCachedRevisionIds, fetchViews ); - cachedEdges.forEach(([revisionKey, edges]) => { - revisionToEdgesMap.set(revisionKey, edges); + cachedConnections.forEach(([revisionKey, connections]) => { + revisionToConnectionsMap.set(revisionKey, connections); }); - return revisionToEdgesMap; + return revisionToConnectionsMap; } private async fetchAllViewsForCachedRevisions( @@ -192,20 +203,20 @@ export class FdmNodeCache { for (const revision of revisions) { const revisionCache = this.getOrCreateRevisionCache(revision.modelId, revision.revisionId); - await revisionCache.fetchViewsForAllEdges(); + await revisionCache.fetchViewsForAllConnections(); } } - private getCachedEdgesForRevision(id: { + private getCachedConnectionsForRevision(id: { modelId: number; revisionId: number; }): [ModelRevisionKey, FdmConnectionWithNode[]] { const revisionCache = this.getOrCreateRevisionCache(id.modelId, id.revisionId); const revisionKey = createModelRevisionKey(id.modelId, id.revisionId); - const cachedRevisionEdges = revisionCache.getAllEdges(); + const cachedRevisionConnections = revisionCache.getAllConnections(); - return [revisionKey, cachedRevisionEdges]; + return [revisionKey, cachedRevisionConnections]; } private writeRevisionDataToCache(modelMap: Map): void { @@ -213,15 +224,18 @@ export class FdmNodeCache { const [modelId, revisionId] = revisionKeyToIds(revisionKey); const revisionCache = this.getOrCreateRevisionCache(modelId, revisionId); - data.forEach((edgeAndNode) => { - revisionCache.insertTreeIndexMappings(edgeAndNode.cadNode.treeIndex, edgeAndNode); + data.forEach((connectionAndNode) => { + revisionCache.insertTreeIndexMappings( + connectionAndNode.cadNode.treeIndex, + connectionAndNode + ); }); this._completeRevisions.add(revisionKey); } } - private async getAndCacheRevisionToEdgesMap( + private async getAndCacheRevisionToConnectionsMap( modelRevisionIds: ModelRevisionId[], fetchViews: boolean ): Promise> { @@ -232,15 +246,15 @@ export class FdmNodeCache { ? await this.getViewsForConnections(connections) : connections.map((connection) => ({ connection })); - const revisionToEdgesMap = await createRevisionToEdgesMap( + const revisionToConnectionsMap = await createRevisionToConnectionsMap( connectionsWithOptionalViews, modelRevisionIds, this._cdfClient ); - this.writeRevisionDataToCache(revisionToEdgesMap); + this.writeRevisionDataToCache(revisionToConnectionsMap); - return revisionToEdgesMap; + return revisionToConnectionsMap; } public getClosestParentDataPromises( @@ -292,7 +306,7 @@ export class FdmNodeCache { } } -async function createRevisionToEdgesMap( +async function createRevisionToConnectionsMap( connectionsWithView: Array<{ connection: FdmCadConnection; view?: Source }>, modelRevisionIds: ModelRevisionId[], cdfClient: CogniteClient @@ -305,8 +319,8 @@ async function createRevisionToEdgesMap( ); return connectionsWithView.reduce((map, connectionWithView) => { - const edgeRevisionId = connectionWithView.connection.revisionId; - const modelRevisionId = modelRevisionIds.find((p) => p.revisionId === edgeRevisionId); + const connectionRevisionId = connectionWithView.connection.revisionId; + const modelRevisionId = modelRevisionIds.find((p) => p.revisionId === connectionRevisionId); if (modelRevisionId === undefined) return map; diff --git a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx index 090065f514c..7c5b97b54a0 100644 --- a/react-components/src/components/CacheProvider/NodeCacheProvider.tsx +++ b/react-components/src/components/CacheProvider/NodeCacheProvider.tsx @@ -6,7 +6,7 @@ import { type ReactElement, type ReactNode, createContext, useContext, useMemo } import { FdmNodeCache } from './FdmNodeCache'; import { type UseQueryResult, useQuery } from '@tanstack/react-query'; import { useFdm3dDataProvider, useFdmSdk, useSDK } from '../RevealCanvas/SDKProvider'; -import { type FdmNodeDataPromises, type ModelRevisionToEdgeMap } from './types'; +import { type FdmNodeDataPromises, type ModelRevisionToConnectionMap } from './types'; import assert from 'assert'; import { type DmsUniqueIdentifier } from '../../data-providers/FdmSDK'; @@ -36,7 +36,7 @@ export const useMappedEdgesForRevisions = ( modelRevisionIds: Array<{ modelId: number; revisionId: number }>, fetchViews = false, enabled = true -): UseQueryResult => { +): UseQueryResult => { const content = useFdmNodeCache(); return useQuery({ diff --git a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts index 5fefeeaca20..f40de99e7ef 100644 --- a/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts +++ b/react-components/src/components/CacheProvider/RevisionFdmNodeCache.ts @@ -81,12 +81,12 @@ export class RevisionFdmNodeCache { } const cadNode = cachedFdmData[0].cadNode; - const cadNodeWithEdges = { + const cadNodeWithConnections = { cadNode, connections: cachedFdmData.map((data) => data.connection) }; - return await this.getAndCacheViewsPromiseForNodeData(cadNodeWithEdges, [ + return await this.getAndCacheViewsPromiseForNodeData(cadNodeWithConnections, [ cadNode.treeIndex, searchTreeIndex ]); @@ -95,18 +95,19 @@ export class RevisionFdmNodeCache { private findAndCacheNodeDataFromAncestors(treeIndex: TreeIndex): FdmNodeDataPromises { const ancestorDataPromise = this.getClosestParentMapping(treeIndex); - const cadAndEdgesPromise = this.getCadAndEdgesPromiseForAncestorData(ancestorDataPromise); - const cadAndFdmNodesPromise = cadAndEdgesPromise.then((cadAndEdges) => - cadAndEdges === undefined + const cadAndConnectionsPromise = + this.getCadAndConnectionsPromiseForAncestorData(ancestorDataPromise); + const cadAndFdmNodesPromise = cadAndConnectionsPromise.then((cadAndConnections) => + cadAndConnections === undefined ? undefined : { - cadNode: cadAndEdges.cadNode, - fdmIds: cadAndEdges.connections.map((edge) => edge.instance) + cadNode: cadAndConnections.cadNode, + fdmIds: cadAndConnections.connections.map((connection) => connection.instance) } ); const viewsPromise = this.getViewsPromiseFromDataPromises( - cadAndEdgesPromise, + cadAndConnectionsPromise, ancestorDataPromise ); @@ -114,10 +115,10 @@ export class RevisionFdmNodeCache { } private async getViewsPromiseFromDataPromises( - cadAndEdgesPromise: Promise, + cadAndConnectionsPromise: Promise, ancestorDataPromise: Promise ): Promise { - const cadAndEdges = await cadAndEdgesPromise; + const cadAndConnections = await cadAndConnectionsPromise; const { ancestorsWithSameMapping } = await ancestorDataPromise; const ancestorTreeIndexes = ancestorsWithSameMapping.map((ancestor) => ancestor.treeIndex); @@ -135,10 +136,10 @@ export class RevisionFdmNodeCache { return cachedNodeData.map((data) => data.view); } - return await this.getAndCacheViewsPromiseForNodeData(cadAndEdges, ancestorTreeIndexes); + return await this.getAndCacheViewsPromiseForNodeData(cadAndConnections, ancestorTreeIndexes); } - private async getCadAndEdgesPromiseForAncestorData( + private async getCadAndConnectionsPromiseForAncestorData( ancestorDataPromise: Promise ): Promise { const { connections, ancestorsWithSameMapping, firstMappedAncestorTreeIndex } = @@ -181,7 +182,7 @@ export class RevisionFdmNodeCache { const nodeInspectionResults = await inspectNodes( this._fdmClient, - cadAndFdmIds.connections.map((edge) => edge.instance) + cadAndFdmIds.connections.map((connection) => connection.instance) ); const views = nodeInspectionResults.items.map( @@ -207,7 +208,7 @@ export class RevisionFdmNodeCache { this._cogniteClient ); - const ancestorMappings = await this.getMappingEdgesForAncestors(ancestors); + const ancestorMappings = await this.getMappingConnectionsForAncestors(ancestors); if (ancestorMappings.length === 0) { return { @@ -217,7 +218,7 @@ export class RevisionFdmNodeCache { }; } - const connectionsWithCorrespondingTreeIndex = this.combineEdgesWithTreeIndex( + const connectionsWithCorrespondingTreeIndex = this.combineConnectionsWithTreeIndex( ancestorMappings, ancestors ); @@ -232,7 +233,7 @@ export class RevisionFdmNodeCache { ); } - private combineEdgesWithTreeIndex( + private combineConnectionsWithTreeIndex( mappingConnections: FdmCadConnection[], nodes: Node3D[] ): Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> { @@ -248,19 +249,21 @@ export class RevisionFdmNodeCache { }); } - private async getMappingEdgesForAncestors(ancestors: Node3D[]): Promise { + private async getMappingConnectionsForAncestors( + ancestors: Node3D[] + ): Promise { const cachedFirstMappedAncestor = ancestors .filter((ancestor) => this._treeIndexToFdmConnections.has(ancestor.treeIndex)) .sort((nodeA, nodeB) => nodeB.treeIndex - nodeA.treeIndex)[0]; if (cachedFirstMappedAncestor !== undefined) { - const edgesAndNodes = this._treeIndexToFdmConnections.get( + const connectionsAndNodes = this._treeIndexToFdmConnections.get( cachedFirstMappedAncestor.treeIndex ); - assert(edgesAndNodes !== undefined); + assert(connectionsAndNodes !== undefined); - return edgesAndNodes.map((edge) => edge.connection); + return connectionsAndNodes.map((connection) => connection.connection); } const modelInstances = await this._modelInstances; if (modelInstances === undefined) { @@ -276,8 +279,10 @@ export class RevisionFdmNodeCache { return ancestorMappings; } - public async fetchViewsForAllEdges(): Promise { - const allConnectionsWithoutView = this.getAllEdges().filter((edge) => edge.view === undefined); + public async fetchViewsForAllConnections(): Promise { + const allConnectionsWithoutView = this.getAllConnections().filter( + (connection) => connection.view === undefined + ); if (allConnectionsWithoutView.length === 0) { return; @@ -288,42 +293,44 @@ export class RevisionFdmNodeCache { allConnectionsWithoutView.map((connection) => connection.connection.instance) ); - allConnectionsWithoutView.forEach((fdmEdgeWithNode, ind) => { - const edgeWithView = { - ...fdmEdgeWithNode, + allConnectionsWithoutView.forEach((fdmConnectionWithNode, ind) => { + const connectionWithView = { + ...fdmConnectionWithNode, view: nodeInspectionResults.items[ind].inspectionResults.involvedViews[0] }; - this.insertTreeIndexMappings(edgeWithView.cadNode.treeIndex, edgeWithView); + this.insertTreeIndexMappings(connectionWithView.cadNode.treeIndex, connectionWithView); }); } - public insertTreeIndexMappings(treeIndex: TreeIndex, edge: FdmConnectionWithNode): void { - const edgeArray = this._treeIndexToFdmConnections.get(treeIndex); + public insertTreeIndexMappings(treeIndex: TreeIndex, connection: FdmConnectionWithNode): void { + const connectionArray = this._treeIndexToFdmConnections.get(treeIndex); - if (edgeArray === undefined) { - this._treeIndexToFdmConnections.set(treeIndex, [edge]); + if (connectionArray === undefined) { + this._treeIndexToFdmConnections.set(treeIndex, [connection]); } else { - const presentEdge = edgeArray?.find((e) => e.cadNode.id === edge.cadNode.id); + const presentConnection = connectionArray?.find( + (e) => e.cadNode.id === connection.cadNode.id + ); - if (presentEdge !== undefined) { - presentEdge.view = edge.view; + if (presentConnection !== undefined) { + presentConnection.view = connection.view; return; } - edgeArray.push(edge); + connectionArray.push(connection); } } - public getAllEdges(): FdmConnectionWithNode[] { + public getAllConnections(): FdmConnectionWithNode[] { return [...this._treeIndexToFdmConnections.values()].flat(); } } function findLargestTreeIndex( - edgesWithTreeIndex: Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> + connectionsWithTreeIndex: Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }> ): TreeIndex { - const maxTreeIndex = max(edgesWithTreeIndex.map((e) => e.treeIndex)); + const maxTreeIndex = max(connectionsWithTreeIndex.map((e) => e.treeIndex)); assert(maxTreeIndex !== undefined); return maxTreeIndex; } @@ -333,22 +340,24 @@ function getAncestorDataForTreeIndex( connectionsWithTreeIndex: Array<{ connection: FdmCadConnection; treeIndex: TreeIndex }>, ancestors: Node3D[] ): AncestorQueryResult { - const edgesForTreeIndex = connectionsWithTreeIndex.filter( - (edgeAndTreeIndex) => edgeAndTreeIndex.treeIndex === treeIndex + const connectionsForTreeIndex = connectionsWithTreeIndex.filter( + (connectionAndTreeIndex) => connectionAndTreeIndex.treeIndex === treeIndex ); const ancestorsBelowTreeIndex = ancestors.filter((ancestor) => ancestor.treeIndex >= treeIndex); return { - connections: edgesForTreeIndex.map((result) => result.connection), + connections: connectionsForTreeIndex.map((result) => result.connection), ancestorsWithSameMapping: ancestorsBelowTreeIndex, firstMappedAncestorTreeIndex: treeIndex }; } export function checkDefinedView( - edges?: FdmConnectionWithNode[] -): edges is Array> { - if (edges === undefined) return false; + connections?: FdmConnectionWithNode[] +): connections is Array> { + if (connections === undefined) return false; - return edges?.every((edge): edge is Required => edge.view !== undefined); + return connections?.every( + (connection): connection is Required => connection.view !== undefined + ); } diff --git a/react-components/src/components/CacheProvider/types.ts b/react-components/src/components/CacheProvider/types.ts index 63c861ecfe8..f41eb2d28b6 100644 --- a/react-components/src/components/CacheProvider/types.ts +++ b/react-components/src/components/CacheProvider/types.ts @@ -57,7 +57,7 @@ export type FdmKey = `${string}/${string}`; export type ModelNodeIdKey = `${ModelId}/${RevisionId}/${NodeId}`; export type ModelAssetIdKey = `${ModelId}/${RevisionId}/${AssetId}`; -export type ModelRevisionToEdgeMap = Map; +export type ModelRevisionToConnectionMap = Map; export type PointCloudAnnotationModel = AnnotationModel & { data: AnnotationsBoundingVolume }; diff --git a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts index bfdb34a2137..c56e1315a94 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/LegacyFdm3dDataProvider.ts @@ -20,7 +20,7 @@ import { getDMSModels } from './getDMSModels'; import { listAllMappedFdmNodes, listMappedFdmNodes } from './listMappedFdmNodes'; import { filterNodesByMappedTo3d } from './filterNodesByMappedTo3d'; import { getCadModelsForFdmInstance } from './getCadModelsForFdmInstance'; -import { getConnectionsForRevision } from './getCadConnectionsForRevision'; +import { getCadConnectionsForRevision } from './getCadConnectionsForRevision'; export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { readonly _fdmSdk: FdmSDK; @@ -80,6 +80,6 @@ export class LegacyFdm3dDataProvider implements Fdm3dDataProvider { } async getCadConnectionsForRevisions(revisions: number[]): Promise { - return await getConnectionsForRevision(revisions, this._fdmSdk); + return await getCadConnectionsForRevision(revisions, this._fdmSdk); } } diff --git a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts index 30e74b7f1a0..8496224cebf 100644 --- a/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts +++ b/react-components/src/data-providers/legacy-fdm-provider/getCadConnectionsForRevision.ts @@ -10,7 +10,7 @@ import { } from './dataModels'; import { fdmEdgesToCadConnections } from './fdmEdgesToCadConnections'; -export async function getConnectionsForRevision( +export async function getCadConnectionsForRevision( revisionIds: number[], fdmClient: FdmSDK ): Promise {