codecharta-visualization 1.89.0 → 1.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/app.module.ts +16 -2
- package/app/codeCharta/assets/gameObjectsFile.json +75 -0
- package/app/codeCharta/codeCharta.model.ts +1 -10
- package/app/codeCharta/services/idToBuilding/idToBuilding.service.ts +17 -0
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.spec.ts +14 -23
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.ts +7 -5
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.spec.ts +3 -1
- package/app/codeCharta/state/effects/nodeContextMenu/rightClickedCodeMapNode.selector.ts +1 -1
- package/app/codeCharta/state/effects/trackEventUsageData/trackEventUsageData.effect.spec.ts +56 -0
- package/app/codeCharta/state/effects/trackEventUsageData/trackEventUsageData.effect.ts +49 -0
- package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.ts +2 -1
- package/app/codeCharta/state/injector.service.ts +0 -4
- package/app/codeCharta/state/selectors/accumulatedData/idToNode.selector.spec.ts +15 -0
- package/app/codeCharta/state/selectors/accumulatedData/idToNode.selector.ts +16 -0
- package/app/codeCharta/state/selectors/selectedNode.selector.ts +5 -2
- package/app/codeCharta/state/state.module.ts +0 -4
- package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.ts +1 -5
- package/app/codeCharta/state/store/state.actions.ts +0 -2
- package/app/codeCharta/state/store/state.reducer.ts +0 -2
- package/app/codeCharta/state/store/state.splitter.ts +0 -10
- package/app/codeCharta/state/store.service.ts +0 -16
- package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.spec.ts +5 -1
- package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.html +0 -1
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.spec.ts +3 -45
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.ts +2 -8
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.html +1 -1
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.spec.ts +3 -2
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/secondaryMetrics.selector.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.spec.ts +26 -23
- package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/util/showAttributeTypeSelector.selector.spec.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/util/showAttributeTypeSelector.selector.ts +2 -2
- package/app/codeCharta/ui/codeMap/codeMap.mouseEvent.service.spec.ts +28 -45
- package/app/codeCharta/ui/codeMap/codeMap.mouseEvent.service.ts +7 -11
- package/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts +4 -46
- package/app/codeCharta/ui/codeMap/threeViewer/threeSceneService.spec.ts +26 -19
- package/app/codeCharta/ui/codeMap/threeViewer/threeSceneService.ts +13 -25
- package/app/codeCharta/ui/codeMap/threeViewer/threeViewer.module.ts +3 -0
- package/app/codeCharta/ui/dialog/dialog.globalSettings.component.ts +3 -5
- package/app/codeCharta/ui/dialog/dialog.globalSettings.e2e.ts +1 -1
- package/app/codeCharta/ui/fileChooser/fileChooser.component.spec.ts +1 -0
- package/app/codeCharta/ui/fileChooser/fileChooser.component.ts +6 -1
- package/app/codeCharta/ui/fileChooser/fileChooser.e2e.ts +5 -0
- package/app/codeCharta/ui/filePanel/filePanel.component.html +1 -0
- package/app/codeCharta/ui/filePanel/filePanel.component.spec.ts +7 -0
- package/app/codeCharta/ui/filePanel/filePanel.component.ts +1 -2
- package/app/codeCharta/ui/filePanel/filePanel.module.ts +2 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.html +7 -1
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.scss +6 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.ts +2 -1
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.html +3 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.scss +9 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.ts +11 -0
- package/app/codeCharta/ui/rangeSlider/rangeSlider.component.ts +9 -33
- package/app/codeCharta/util/__snapshots__/usageDataTracker.spec.ts.snap +1 -16
- package/app/codeCharta/util/codeMapHelper.ts +3 -2
- package/app/codeCharta/util/customConfigHelper.ts +4 -16
- package/app/codeCharta/util/dataMocks.ts +0 -8
- package/app/codeCharta/util/envDetector.ts +0 -4
- package/app/codeCharta/util/gameObjectsParser/__snapshots__/gameObjectsImporter.spec.ts.snap +121 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsImporter.spec.ts +11 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsImporter.ts +170 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsMocks.ts +75 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsSchema.json +271 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsValidator.spec.ts +18 -0
- package/app/codeCharta/util/gameObjectsParser/gameObjectsValidator.ts +7 -0
- package/app/codeCharta/util/nodeDecorator.ts +1 -0
- package/app/codeCharta/util/usageDataTracker.spec.ts +36 -76
- package/app/codeCharta/util/usageDataTracker.ts +20 -31
- package/conf/webpack.config.js +7 -7
- package/dist/webpack/bundle.js +871 -1260
- package/dist/webpack/bundle.js.map +1 -1
- package/package.json +10 -11
- package/app/codeCharta/state/selectors/selectedBuilding.selector.ts +0 -8
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.actions.ts +0 -22
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.reducer.spec.ts +0 -33
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.reducer.ts +0 -14
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.selector.ts +0 -3
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.service.spec.ts +0 -40
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.service.ts +0 -23
- package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.splitter.ts +0 -6
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.actions.ts +0 -22
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.reducer.spec.ts +0 -39
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.reducer.ts +0 -11
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.selector.ts +0 -4
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.service.spec.ts +0 -57
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.service.ts +0 -23
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.splitter.ts +0 -6
- package/app/codeCharta/state/store/lookUp/lookUp.actions.ts +0 -27
- package/app/codeCharta/state/store/lookUp/lookUp.reducer.ts +0 -10
- package/app/codeCharta/state/store/lookUp/lookUp.selector.ts +0 -3
- package/app/codeCharta/state/store/lookUp/lookUp.splitter.ts +0 -19
- package/app/codeCharta/ui/removeFileButton/removeFileButton.component.html +0 -5
- package/app/codeCharta/ui/removeFileButton/removeFileButton.component.scss +0 -41
- package/app/codeCharta/ui/removeFileButton/removeFileButton.component.ts +0 -18
- package/app/codeCharta/ui/removeFileButton/removeFileButton.module.ts +0 -7
- package/app/codeCharta/util/codeChartaFileStorage.spec.ts +0 -73
- package/app/codeCharta/util/codeChartaStorage.ts +0 -62
- package/app/codeCharta/util/lazyLoader.spec.ts +0 -33
- package/app/codeCharta/util/lazyLoader.ts +0 -50
- package/dist/webpack/vendors-node_modules_open_index_js.bundle.js +0 -1036
- package/dist/webpack/vendors-node_modules_open_index_js.bundle.js.map +0 -1
|
@@ -8,17 +8,12 @@ export interface StoreSubscriber {
|
|
|
8
8
|
onStoreChanged(actionType: string)
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export interface StoreExtendedSubscriber {
|
|
12
|
-
onStoreChangedExtended(actionType: string, data?: unknown)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
export interface DispatchOptions {
|
|
16
12
|
silent: boolean
|
|
17
13
|
}
|
|
18
14
|
|
|
19
15
|
export class StoreService {
|
|
20
16
|
static STORE_CHANGED_EVENT = "store-changed"
|
|
21
|
-
private static STORE_CHANGED_EXTENDED_EVENT = "store-changed-extended"
|
|
22
17
|
private store = Store.store
|
|
23
18
|
private originalDispatch: typeof Store.store.dispatch
|
|
24
19
|
|
|
@@ -39,7 +34,6 @@ export class StoreService {
|
|
|
39
34
|
this.originalDispatch(atomicAction)
|
|
40
35
|
if (!options.silent) {
|
|
41
36
|
this.notify(atomicAction.type)
|
|
42
|
-
this.notifyExtended(atomicAction.type, atomicAction.payload)
|
|
43
37
|
}
|
|
44
38
|
}
|
|
45
39
|
|
|
@@ -54,19 +48,9 @@ export class StoreService {
|
|
|
54
48
|
this.$rootScope.$broadcast(StoreService.STORE_CHANGED_EVENT, { actionType })
|
|
55
49
|
}
|
|
56
50
|
|
|
57
|
-
private notifyExtended(actionType: string, payload?: unknown) {
|
|
58
|
-
this.$rootScope.$broadcast(StoreService.STORE_CHANGED_EXTENDED_EVENT, { actionType, payload })
|
|
59
|
-
}
|
|
60
|
-
|
|
61
51
|
static subscribe($rootScope: IRootScopeService, subscriber: StoreSubscriber) {
|
|
62
52
|
$rootScope.$on(StoreService.STORE_CHANGED_EVENT, (_event_, data) => {
|
|
63
53
|
subscriber.onStoreChanged(data.actionType)
|
|
64
54
|
})
|
|
65
55
|
}
|
|
66
|
-
|
|
67
|
-
static subscribeDetailedData($rootScope: IRootScopeService, subscriber: StoreExtendedSubscriber) {
|
|
68
|
-
$rootScope.$on(StoreService.STORE_CHANGED_EXTENDED_EVENT, (_event_, data) => {
|
|
69
|
-
subscriber.onStoreChangedExtended(data.actionType, data.payload)
|
|
70
|
-
})
|
|
71
|
-
}
|
|
72
56
|
}
|
|
@@ -95,7 +95,11 @@ describe("AttributeSideBarComponent", () => {
|
|
|
95
95
|
})
|
|
96
96
|
|
|
97
97
|
it("should display attribute type selectors for folders", async () => {
|
|
98
|
-
mockedSelectedNodeSelector.mockImplementation(() =>
|
|
98
|
+
mockedSelectedNodeSelector.mockImplementation(() => {
|
|
99
|
+
const node = klona(TEST_NODE_FOLDER)
|
|
100
|
+
node["children"] = [{}]
|
|
101
|
+
return node
|
|
102
|
+
})
|
|
99
103
|
|
|
100
104
|
const { container } = await render(AttributeSideBarComponent, { excludeComponentDeclaration: true })
|
|
101
105
|
|
|
@@ -2,7 +2,7 @@ import "./attributeSideBar.component.scss"
|
|
|
2
2
|
import { Observable, map } from "rxjs"
|
|
3
3
|
import { Component, Inject } from "@angular/core"
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { CodeMapNode } from "../../codeCharta.model"
|
|
6
6
|
import { Store } from "../../state/angular-redux/store"
|
|
7
7
|
import { isAttributeSideBarVisibleSelector } from "../../state/store/appSettings/isAttributeSideBarVisible/isAttributeSideBarVisible.selector"
|
|
8
8
|
import { selectedNodeSelector } from "../../state/selectors/selectedNode.selector"
|
|
@@ -14,7 +14,7 @@ import { accumulatedDataSelector } from "../../state/selectors/accumulatedData/a
|
|
|
14
14
|
})
|
|
15
15
|
export class AttributeSideBarComponent {
|
|
16
16
|
isSideBarVisible$: Observable<boolean>
|
|
17
|
-
selectedNode$: Observable<
|
|
17
|
+
selectedNode$: Observable<CodeMapNode>
|
|
18
18
|
fileName$: Observable<string>
|
|
19
19
|
|
|
20
20
|
constructor(@Inject(Store) store: Store) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<ng-container *ngIf="node">
|
|
2
2
|
<i class="close-icon fa fa-times" (click)="closeSideBar()"></i>
|
|
3
3
|
|
|
4
|
-
<h2 *ngIf="!node.link" data-testid="file-opener" class="node-name" (click)="handleClickNodeName()">{{ node.name }}</h2>
|
|
5
4
|
<div *ngIf="node.link" data-testid="file-link" matTooltip="{{ node.link }}" [matTooltipShowDelay]="200" class="node-name">
|
|
6
5
|
<a class="node-link" href="{{ node.link }}" target="_blank" rel="noopener noreferrer">
|
|
7
6
|
<h2>{{ node.name }} </h2>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TestBed } from "@angular/core/testing"
|
|
2
|
-
import { render
|
|
3
|
-
|
|
4
|
-
import { LazyLoader } from "../../../util/lazyLoader"
|
|
2
|
+
import { render } from "@testing-library/angular"
|
|
3
|
+
import { CodeMapNode } from "../../../codeCharta.model"
|
|
5
4
|
import { AttributeSideBarModule } from "../attributeSideBar.module"
|
|
6
5
|
import { AttributeSideBarHeaderSectionComponent } from "./attributeSideBarHeaderSection.component"
|
|
7
6
|
|
|
@@ -12,56 +11,15 @@ describe("attributeSideBarHeaderSection", () => {
|
|
|
12
11
|
})
|
|
13
12
|
})
|
|
14
13
|
|
|
15
|
-
it("should have file opener when given node has no link and open it on click if it is a leaf", async () => {
|
|
16
|
-
const { container } = await render(AttributeSideBarHeaderSectionComponent, {
|
|
17
|
-
excludeComponentDeclaration: true,
|
|
18
|
-
componentProperties: {
|
|
19
|
-
node: { name: "myNode", isLeaf: true, path: "./myNode.ts", link: undefined },
|
|
20
|
-
fileName: "myNode.ts"
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
expect(container.querySelector("[data-testid=file-link]")).toBe(null)
|
|
25
|
-
const fileOpener = container.querySelector("[data-testid=file-opener]")
|
|
26
|
-
expect(fileOpener).not.toBe(null)
|
|
27
|
-
|
|
28
|
-
// @ts-ignore
|
|
29
|
-
const openFileMock = jest.spyOn(LazyLoader, "openFile").mockImplementation(() => {})
|
|
30
|
-
fireEvent.click(fileOpener)
|
|
31
|
-
|
|
32
|
-
expect(openFileMock).toHaveBeenCalledWith("myNode.ts", "./myNode.ts")
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it("should have file opener when given node has no link but don't open it on click if it isn't a leaf", async () => {
|
|
36
|
-
const { container } = await render(AttributeSideBarHeaderSectionComponent, {
|
|
37
|
-
excludeComponentDeclaration: true,
|
|
38
|
-
componentProperties: {
|
|
39
|
-
node: { name: "myNode", isLeaf: false, path: "./myNode.ts", link: undefined },
|
|
40
|
-
fileName: "myNode.ts"
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
expect(container.querySelector("[data-testid=file-link]")).toBe(null)
|
|
45
|
-
const fileOpener = container.querySelector("[data-testid=file-opener]")
|
|
46
|
-
expect(fileOpener).not.toBe(null)
|
|
47
|
-
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
const openFileMock = jest.spyOn(LazyLoader, "openFile").mockReset()
|
|
50
|
-
fireEvent.click(fileOpener)
|
|
51
|
-
|
|
52
|
-
expect(openFileMock).not.toHaveBeenCalled()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
14
|
it("should have file link when given node has a link", async () => {
|
|
56
15
|
const { container } = await render(AttributeSideBarHeaderSectionComponent, {
|
|
57
16
|
excludeComponentDeclaration: true,
|
|
58
17
|
componentProperties: {
|
|
59
|
-
node: { name: "myNode",
|
|
18
|
+
node: { name: "myNode", children: [{}], path: "./myNode.ts", link: "myNode.com" } as CodeMapNode,
|
|
60
19
|
fileName: "myNode.ts"
|
|
61
20
|
}
|
|
62
21
|
})
|
|
63
22
|
|
|
64
|
-
expect(container.querySelector("[data-testid=file-opener]")).toBe(null)
|
|
65
23
|
expect(container.querySelector("[data-testid=file-link] a[href='myNode.com']")).not.toBe(null)
|
|
66
24
|
})
|
|
67
25
|
})
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import "./attributeSideBarHeaderSection.component.scss"
|
|
2
2
|
import { Component, Inject, Input } from "@angular/core"
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { LazyLoader } from "../../../util/lazyLoader"
|
|
4
|
+
import { CodeMapNode } from "../../../codeCharta.model"
|
|
6
5
|
import { Store } from "../../../state/angular-redux/store"
|
|
7
6
|
import { closeAttributeSideBar } from "../../../state/store/appSettings/isAttributeSideBarVisible/isAttributeSideBarVisible.actions"
|
|
8
7
|
|
|
@@ -11,16 +10,11 @@ import { closeAttributeSideBar } from "../../../state/store/appSettings/isAttrib
|
|
|
11
10
|
template: require("./attributeSideBarHeaderSection.component.html")
|
|
12
11
|
})
|
|
13
12
|
export class AttributeSideBarHeaderSectionComponent {
|
|
14
|
-
@Input() node: Pick<
|
|
13
|
+
@Input() node: Pick<CodeMapNode, "children" | "name" | "link" | "path">
|
|
15
14
|
@Input() fileName: string
|
|
16
15
|
|
|
17
16
|
constructor(@Inject(Store) private store: Store) {}
|
|
18
17
|
|
|
19
|
-
handleClickNodeName() {
|
|
20
|
-
if (!this.node.isLeaf) return
|
|
21
|
-
LazyLoader.openFile(this.fileName, this.node.path)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
18
|
closeSideBar() {
|
|
25
19
|
this.store.dispatch(closeAttributeSideBar())
|
|
26
20
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<p class="cc-node-path">
|
|
2
2
|
<span *ngIf="node">
|
|
3
3
|
{{ node.path }}
|
|
4
|
-
<span *ngIf="
|
|
4
|
+
<span *ngIf="node.children?.length && fileCountDescription$ | async as fileCountDescription" class="cc-node-file-count">
|
|
5
5
|
({{ fileCountDescription }})
|
|
6
6
|
</span>
|
|
7
7
|
</span>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { render } from "@testing-library/angular"
|
|
2
|
+
import { CodeMapNode } from "../../../../codeCharta.model"
|
|
2
3
|
|
|
3
4
|
import { selectedNodeSelector } from "../../../../state/selectors/selectedNode.selector"
|
|
4
5
|
import { NodePathComponent } from "./nodePath.component"
|
|
@@ -18,7 +19,7 @@ describe("nodePathComponent", () => {
|
|
|
18
19
|
})
|
|
19
20
|
|
|
20
21
|
it("should display only node path, when a file is selected", async () => {
|
|
21
|
-
const node = {
|
|
22
|
+
const node = { path: "some/file.ts" }
|
|
22
23
|
selectedNodeSelectorMock.mockImplementation(() => node)
|
|
23
24
|
|
|
24
25
|
const { container } = await render(NodePathComponent, { componentProperties: { node } })
|
|
@@ -27,7 +28,7 @@ describe("nodePathComponent", () => {
|
|
|
27
28
|
|
|
28
29
|
it("should display node path and fileCountDescription,, when a folder is selected", async () => {
|
|
29
30
|
const node = {
|
|
30
|
-
|
|
31
|
+
children: [{}] as CodeMapNode[],
|
|
31
32
|
path: "some/folder",
|
|
32
33
|
attributes: { unary: 2 }
|
|
33
34
|
}
|
|
@@ -2,7 +2,7 @@ import { Component, Inject, Input } from "@angular/core"
|
|
|
2
2
|
import { Observable } from "rxjs"
|
|
3
3
|
|
|
4
4
|
import { Store } from "../../../../state/angular-redux/store"
|
|
5
|
-
import {
|
|
5
|
+
import { CodeMapNode } from "../../../../codeCharta.model"
|
|
6
6
|
import { fileCountDescriptionSelector } from "./fileCountDescription.selector"
|
|
7
7
|
|
|
8
8
|
@Component({
|
|
@@ -10,7 +10,7 @@ import { fileCountDescriptionSelector } from "./fileCountDescription.selector"
|
|
|
10
10
|
template: require("./nodePath.component.html")
|
|
11
11
|
})
|
|
12
12
|
export class NodePathComponent {
|
|
13
|
-
@Input() node?: Pick<
|
|
13
|
+
@Input() node?: Pick<CodeMapNode, "path" | "children">
|
|
14
14
|
fileCountDescription$: Observable<string | undefined>
|
|
15
15
|
|
|
16
16
|
constructor(@Inject(Store) store: Store) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CodeMapNode } from "../../../codeCharta.model"
|
|
2
2
|
import { createSelector } from "../../../state/angular-redux/store"
|
|
3
3
|
import { selectedNodeSelector } from "../../../state/selectors/selectedNode.selector"
|
|
4
4
|
import { CcState } from "../../../state/store/store"
|
|
5
5
|
import { PrimaryMetricNames, primaryMetricNamesSelector } from "../attributeSideBarPrimaryMetrics/primaryMetricNames.selector"
|
|
6
6
|
import { Metric } from "../util/metric"
|
|
7
7
|
|
|
8
|
-
export const _calculateSecondaryMetrics = (primaryMetricNames: PrimaryMetricNames, node?:
|
|
8
|
+
export const _calculateSecondaryMetrics = (primaryMetricNames: PrimaryMetricNames, node?: Pick<CodeMapNode, "attributes">) => {
|
|
9
9
|
if (!node) return [] as Metric[]
|
|
10
10
|
|
|
11
11
|
const primaryMetricNamesList = Object.values(primaryMetricNames)
|
package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.spec.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/angular"
|
|
2
|
-
|
|
2
|
+
import { mocked } from "ts-jest/utils"
|
|
3
|
+
import { idToNodeSelector } from "../../../state/selectors/accumulatedData/idToNode.selector"
|
|
3
4
|
import { Store } from "../../../state/store/store"
|
|
5
|
+
|
|
4
6
|
import { ColorConverter } from "../../../util/color/colorConverter"
|
|
5
|
-
import { CodeMapBuilding } from "../../codeMap/rendering/codeMapBuilding"
|
|
6
7
|
import { MetricDeltaSelectedComponent } from "./metricDeltaSelected.component"
|
|
7
8
|
|
|
9
|
+
jest.mock("../../../state/selectors/accumulatedData/idToNode.selector", () => ({
|
|
10
|
+
idToNodeSelector: jest.fn()
|
|
11
|
+
}))
|
|
12
|
+
const mockedIdToNodeSelector = mocked(idToNodeSelector)
|
|
13
|
+
jest.mock("../../../state/store/appStatus/selectedBuildingId/selectedBuildingId.selector", () => ({
|
|
14
|
+
selectedBuildingIdSelector: () => 0
|
|
15
|
+
}))
|
|
16
|
+
|
|
8
17
|
describe("MetricDeltaSelectedComponent", () => {
|
|
9
18
|
const areColorsEqual = (hex: string, styleColor: string) => {
|
|
10
19
|
const formattedHex = ColorConverter.convertHexToRgba(hex).replace(/,1\)$/, ")").replace("a", "")
|
|
@@ -12,21 +21,13 @@ describe("MetricDeltaSelectedComponent", () => {
|
|
|
12
21
|
return formattedHex === formattedStyleColor
|
|
13
22
|
}
|
|
14
23
|
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
Store["initialize"]()
|
|
17
|
-
})
|
|
18
|
-
|
|
19
24
|
it("should not show, if there is no delta value", async () => {
|
|
20
25
|
await render(MetricDeltaSelectedComponent)
|
|
21
26
|
expect(screen.queryByText(/Δ/)).toBe(null)
|
|
22
27
|
})
|
|
23
28
|
|
|
24
29
|
it("should show in positive delta color when selected building has a positive delta value", async () => {
|
|
25
|
-
|
|
26
|
-
const state = Store.store.getState()
|
|
27
|
-
state.appStatus.selectedBuildingId = 0
|
|
28
|
-
state.lookUp.idToBuilding = new Map()
|
|
29
|
-
state.lookUp.idToBuilding.set(0, fakeCodeMapBuilding)
|
|
30
|
+
mockIdToNodeSelector({ rloc: 2 })
|
|
30
31
|
|
|
31
32
|
await render(MetricDeltaSelectedComponent, {
|
|
32
33
|
componentProperties: { metricName: "rloc" }
|
|
@@ -34,15 +35,13 @@ describe("MetricDeltaSelectedComponent", () => {
|
|
|
34
35
|
|
|
35
36
|
const metricDeltaSelectedDomNode = screen.queryByText(/Δ2/)
|
|
36
37
|
expect(metricDeltaSelectedDomNode).toBeTruthy()
|
|
37
|
-
expect(areColorsEqual(
|
|
38
|
+
expect(areColorsEqual(Store.store.getState().appSettings.mapColors.positiveDelta, metricDeltaSelectedDomNode.style.color)).toBe(
|
|
39
|
+
true
|
|
40
|
+
)
|
|
38
41
|
})
|
|
39
42
|
|
|
40
43
|
it("should show in negative delta color when selected building has a negative delta value", async () => {
|
|
41
|
-
|
|
42
|
-
const state = Store.store.getState()
|
|
43
|
-
state.appStatus.selectedBuildingId = 0
|
|
44
|
-
state.lookUp.idToBuilding = new Map()
|
|
45
|
-
state.lookUp.idToBuilding.set(0, fakeCodeMapBuilding)
|
|
44
|
+
mockIdToNodeSelector({ rloc: -2 })
|
|
46
45
|
|
|
47
46
|
await render(MetricDeltaSelectedComponent, {
|
|
48
47
|
componentProperties: { metricName: "rloc" }
|
|
@@ -50,15 +49,13 @@ describe("MetricDeltaSelectedComponent", () => {
|
|
|
50
49
|
|
|
51
50
|
const metricDeltaSelectedDomNode = screen.queryByText(/Δ-2/)
|
|
52
51
|
expect(metricDeltaSelectedDomNode).toBeTruthy()
|
|
53
|
-
expect(areColorsEqual(
|
|
52
|
+
expect(areColorsEqual(Store.store.getState().appSettings.mapColors.negativeDelta, metricDeltaSelectedDomNode.style.color)).toBe(
|
|
53
|
+
true
|
|
54
|
+
)
|
|
54
55
|
})
|
|
55
56
|
|
|
56
57
|
it("should update when its metricName changes", async () => {
|
|
57
|
-
|
|
58
|
-
const state = Store.store.getState()
|
|
59
|
-
state.appStatus.selectedBuildingId = 0
|
|
60
|
-
state.lookUp.idToBuilding = new Map()
|
|
61
|
-
state.lookUp.idToBuilding.set(0, fakeCodeMapBuilding)
|
|
58
|
+
mockIdToNodeSelector({ rloc: 2, mcc: 4 })
|
|
62
59
|
|
|
63
60
|
const { rerender } = await render(MetricDeltaSelectedComponent, {
|
|
64
61
|
componentProperties: { metricName: "rloc" }
|
|
@@ -68,4 +65,10 @@ describe("MetricDeltaSelectedComponent", () => {
|
|
|
68
65
|
await rerender({ metricName: "mcc" })
|
|
69
66
|
expect(screen.queryByText(/Δ4/)).toBeTruthy()
|
|
70
67
|
})
|
|
68
|
+
|
|
69
|
+
function mockIdToNodeSelector(deltas: Record<string, unknown>) {
|
|
70
|
+
const idToNode = new Map()
|
|
71
|
+
idToNode.set(0, { id: 0, deltas })
|
|
72
|
+
mockedIdToNodeSelector.mockImplementation(() => idToNode)
|
|
73
|
+
}
|
|
71
74
|
})
|
package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Component, Inject, Input, OnInit } from "@angular/core"
|
|
2
2
|
import { Observable } from "rxjs"
|
|
3
3
|
|
|
4
|
-
import { MapColors,
|
|
4
|
+
import { MapColors, CodeMapNode } from "../../../codeCharta.model"
|
|
5
5
|
import { Store } from "../../../state/angular-redux/store"
|
|
6
6
|
import { selectedNodeSelector } from "../../../state/selectors/selectedNode.selector"
|
|
7
7
|
import { mapColorsSelector } from "../../../state/store/appSettings/mapColors/mapColors.selector"
|
|
@@ -13,7 +13,7 @@ import { mapColorsSelector } from "../../../state/store/appSettings/mapColors/ma
|
|
|
13
13
|
export class MetricDeltaSelectedComponent implements OnInit {
|
|
14
14
|
@Input() metricName: string
|
|
15
15
|
|
|
16
|
-
selectedNode$: Observable<
|
|
16
|
+
selectedNode$: Observable<CodeMapNode>
|
|
17
17
|
mapColors$: Observable<MapColors>
|
|
18
18
|
|
|
19
19
|
constructor(@Inject(Store) private store: Store) {}
|
|
@@ -2,10 +2,10 @@ import { _shouldShowAttributeType } from "./showAttributeTypeSelector.selector"
|
|
|
2
2
|
|
|
3
3
|
describe("_shouldShowAttributeType", () => {
|
|
4
4
|
it("should return true for none leaves", () => {
|
|
5
|
-
expect(_shouldShowAttributeType({
|
|
5
|
+
expect(_shouldShowAttributeType({ children: [{}] })).toBe(true)
|
|
6
6
|
})
|
|
7
7
|
|
|
8
8
|
it("should return false for leaves", () => {
|
|
9
|
-
expect(_shouldShowAttributeType({
|
|
9
|
+
expect(_shouldShowAttributeType({})).toBe(false)
|
|
10
10
|
})
|
|
11
11
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Node } from "../../../codeCharta.model"
|
|
2
1
|
import { createSelector } from "../../../state/angular-redux/store"
|
|
3
2
|
import { selectedNodeSelector } from "../../../state/selectors/selectedNode.selector"
|
|
3
|
+
import { isLeaf, MaybeLeaf } from "../../../util/codeMapHelper"
|
|
4
4
|
|
|
5
|
-
export const _shouldShowAttributeType = (node?:
|
|
5
|
+
export const _shouldShowAttributeType = (node?: MaybeLeaf) => node && !isLeaf(node)
|
|
6
6
|
|
|
7
7
|
export const showAttributeTypeSelectorSelector = createSelector([selectedNodeSelector], _shouldShowAttributeType)
|
|
@@ -9,31 +9,27 @@ import { getService, instantiateModule } from "../../../../mocks/ng.mockhelper"
|
|
|
9
9
|
import { ThreeRendererService } from "./threeViewer/threeRendererService"
|
|
10
10
|
import { ViewCubeMouseEventsService } from "../viewCube/viewCube.mouseEvents.service"
|
|
11
11
|
import { CodeMapBuilding } from "./rendering/codeMapBuilding"
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
CONSTANT_HIGHLIGHT,
|
|
15
|
-
FILE_META,
|
|
16
|
-
TEST_FILE_WITH_PATHS,
|
|
17
|
-
TEST_NODE_LEAF,
|
|
18
|
-
TEST_NODES,
|
|
19
|
-
withMockedEventMethods
|
|
20
|
-
} from "../../util/dataMocks"
|
|
21
|
-
import { BlacklistType, CCFile, CodeMapNode, Node } from "../../codeCharta.model"
|
|
12
|
+
import { CODE_MAP_BUILDING, CONSTANT_HIGHLIGHT, TEST_FILE_WITH_PATHS, TEST_NODES, withMockedEventMethods } from "../../util/dataMocks"
|
|
13
|
+
import { BlacklistType, CodeMapNode, Node } from "../../codeCharta.model"
|
|
22
14
|
import { BlacklistService } from "../../state/store/fileSettings/blacklist/blacklist.service"
|
|
23
15
|
import { FilesService } from "../../state/store/files/files.service"
|
|
24
16
|
import { StoreService } from "../../state/store.service"
|
|
25
17
|
import { NodeDecorator } from "../../util/nodeDecorator"
|
|
26
|
-
import { setIdToBuilding } from "../../state/store/lookUp/idToBuilding/idToBuilding.actions"
|
|
27
|
-
import { setIdToNode } from "../../state/store/lookUp/idToNode/idToNode.actions"
|
|
28
18
|
import { klona } from "klona"
|
|
29
19
|
import { CodeMapLabelService } from "./codeMap.label.service"
|
|
30
20
|
import { CodeMapMesh } from "./rendering/codeMapMesh"
|
|
31
21
|
import { BufferGeometry, Material, Object3D, Raycaster, Vector3 } from "three"
|
|
32
|
-
import { CodeMapPreRenderService } from "./codeMap.preRender.service"
|
|
33
|
-
import { LazyLoader } from "../../util/lazyLoader"
|
|
34
22
|
import { ThreeViewerService } from "./threeViewer/threeViewerService"
|
|
35
23
|
import { setShowMetricLabelNameValue } from "../../state/store/appSettings/showMetricLabelNameValue/showMetricLabelNameValue.actions"
|
|
36
24
|
import { setShowMetricLabelNodeName } from "../../state/store/appSettings/showMetricLabelNodeName/showMetricLabelNodeName.actions"
|
|
25
|
+
import { mocked } from "ts-jest/utils"
|
|
26
|
+
import { idToNodeSelector } from "../../state/selectors/accumulatedData/idToNode.selector"
|
|
27
|
+
import { IdToBuildingService } from "../../services/idToBuilding/idToBuilding.service"
|
|
28
|
+
|
|
29
|
+
jest.mock("../../state/selectors/accumulatedData/idToNode.selector", () => ({
|
|
30
|
+
idToNodeSelector: jest.fn()
|
|
31
|
+
}))
|
|
32
|
+
const mockedIdToNodeSelector = mocked(idToNodeSelector)
|
|
37
33
|
|
|
38
34
|
describe("codeMapMouseEventService", () => {
|
|
39
35
|
let codeMapMouseEventService: CodeMapMouseEventService
|
|
@@ -46,12 +42,11 @@ describe("codeMapMouseEventService", () => {
|
|
|
46
42
|
let threeUpdateCycleService: ThreeUpdateCycleService
|
|
47
43
|
let storeService: StoreService
|
|
48
44
|
let codeMapLabelService: CodeMapLabelService
|
|
49
|
-
let codeMapPreRenderService: CodeMapPreRenderService
|
|
50
45
|
let viewCubeMouseEventsService: ViewCubeMouseEventsService
|
|
51
46
|
let threeViewerService: ThreeViewerService
|
|
47
|
+
let idToBuildingService: IdToBuildingService
|
|
52
48
|
|
|
53
49
|
let codeMapBuilding: CodeMapBuilding
|
|
54
|
-
let file: CCFile
|
|
55
50
|
|
|
56
51
|
beforeEach(() => {
|
|
57
52
|
restartSystem()
|
|
@@ -84,12 +79,11 @@ describe("codeMapMouseEventService", () => {
|
|
|
84
79
|
threeUpdateCycleService = getService<ThreeUpdateCycleService>("threeUpdateCycleService")
|
|
85
80
|
storeService = getService<StoreService>("storeService")
|
|
86
81
|
codeMapLabelService = getService<CodeMapLabelService>("codeMapLabelService")
|
|
87
|
-
codeMapPreRenderService = getService<CodeMapPreRenderService>("codeMapPreRenderService")
|
|
88
82
|
viewCubeMouseEventsService = getService<ViewCubeMouseEventsService>("viewCubeMouseEventsService")
|
|
89
83
|
threeViewerService = getService<ThreeViewerService>("threeViewerService")
|
|
84
|
+
idToBuildingService = getService<IdToBuildingService>("idToBuilding")
|
|
90
85
|
|
|
91
86
|
codeMapBuilding = klona(CODE_MAP_BUILDING)
|
|
92
|
-
file = klona(TEST_FILE_WITH_PATHS)
|
|
93
87
|
document.body.style.cursor = CursorType.Default
|
|
94
88
|
}
|
|
95
89
|
|
|
@@ -103,9 +97,9 @@ describe("codeMapMouseEventService", () => {
|
|
|
103
97
|
threeUpdateCycleService,
|
|
104
98
|
storeService,
|
|
105
99
|
codeMapLabelService,
|
|
106
|
-
codeMapPreRenderService,
|
|
107
100
|
viewCubeMouseEventsService,
|
|
108
|
-
threeViewerService
|
|
101
|
+
threeViewerService,
|
|
102
|
+
idToBuildingService
|
|
109
103
|
)
|
|
110
104
|
|
|
111
105
|
codeMapMouseEventService["oldMouse"] = { x: 1, y: 1 }
|
|
@@ -350,7 +344,7 @@ describe("codeMapMouseEventService", () => {
|
|
|
350
344
|
|
|
351
345
|
function setAnimatedLabel(label: Object3D) {
|
|
352
346
|
// At first, animate a label
|
|
353
|
-
threeSceneService = new ThreeSceneService($rootScope, storeService)
|
|
347
|
+
threeSceneService = new ThreeSceneService($rootScope, storeService, idToBuildingService)
|
|
354
348
|
threeSceneService["mapMesh"] = new CodeMapMesh(TEST_NODES, storeService.getState(), false)
|
|
355
349
|
threeSceneService["highlighted"] = [CODE_MAP_BUILDING]
|
|
356
350
|
threeSceneService["constantHighlight"] = CONSTANT_HIGHLIGHT
|
|
@@ -387,17 +381,18 @@ describe("codeMapMouseEventService", () => {
|
|
|
387
381
|
|
|
388
382
|
describe("updateHovering", () => {
|
|
389
383
|
beforeEach(() => {
|
|
384
|
+
mockedIdToNodeSelector.mockImplementation(() => {
|
|
385
|
+
const idToNode = new Map<number, CodeMapNode>()
|
|
386
|
+
idToNode.set(codeMapBuilding.node.id, codeMapBuilding.node as unknown as CodeMapNode)
|
|
387
|
+
return idToNode
|
|
388
|
+
})
|
|
390
389
|
threeSceneService.getMapMesh = jest.fn().mockReturnValue({
|
|
391
390
|
checkMouseRayMeshIntersection: jest.fn()
|
|
392
391
|
})
|
|
393
392
|
codeMapMouseEventService["transformHTMLToSceneCoordinates"] = jest.fn().mockReturnValue({ x: 0, y: 1 })
|
|
394
393
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const idToNode = new Map<number, CodeMapNode>()
|
|
398
|
-
idToNode.set(file.map.id, file.map)
|
|
399
|
-
storeService.dispatch(setIdToBuilding(idToBuilding))
|
|
400
|
-
storeService.dispatch(setIdToNode(idToNode))
|
|
394
|
+
idToBuildingService.setIdToBuilding([CODE_MAP_BUILDING])
|
|
395
|
+
|
|
401
396
|
threeSceneService.resetLabel = jest.fn()
|
|
402
397
|
threeSceneService.getLabelForHoveredNode = jest.fn()
|
|
403
398
|
threeSceneService.animateLabel = jest.fn()
|
|
@@ -692,18 +687,6 @@ describe("codeMapMouseEventService", () => {
|
|
|
692
687
|
|
|
693
688
|
expect($window.open).toHaveBeenCalledWith("NO_LINK", "_blank")
|
|
694
689
|
})
|
|
695
|
-
|
|
696
|
-
it("should call open file if selected.node.link is undefined", () => {
|
|
697
|
-
LazyLoader.openFile = jest.fn()
|
|
698
|
-
const node: Node = klona(TEST_NODE_LEAF)
|
|
699
|
-
node.isLeaf = true
|
|
700
|
-
node.link = null
|
|
701
|
-
threeSceneService.getSelectedBuilding = jest.fn().mockReturnValue(new CodeMapBuilding(200, null, node, null))
|
|
702
|
-
codeMapPreRenderService.getRenderFileMeta = jest.fn().mockReturnValue(klona(FILE_META))
|
|
703
|
-
codeMapMouseEventService.onDocumentDoubleClick()
|
|
704
|
-
|
|
705
|
-
expect(LazyLoader.openFile).toHaveBeenCalled()
|
|
706
|
-
})
|
|
707
690
|
})
|
|
708
691
|
|
|
709
692
|
describe("onDocumentMouseEnter", () => {
|
|
@@ -770,12 +753,12 @@ describe("codeMapMouseEventService", () => {
|
|
|
770
753
|
|
|
771
754
|
describe("hoverBuilding", () => {
|
|
772
755
|
beforeEach(() => {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
756
|
+
mockedIdToNodeSelector.mockImplementation(() => {
|
|
757
|
+
const idToNode = new Map<number, CodeMapNode>()
|
|
758
|
+
idToNode.set(codeMapBuilding.node.id, codeMapBuilding.node as unknown as CodeMapNode)
|
|
759
|
+
return idToNode
|
|
760
|
+
})
|
|
761
|
+
idToBuildingService.setIdToBuilding([codeMapBuilding])
|
|
779
762
|
})
|
|
780
763
|
|
|
781
764
|
it("should set the highlight when to is not null", () => {
|
|
@@ -13,12 +13,12 @@ import { StoreService } from "../../state/store.service"
|
|
|
13
13
|
import { hierarchy } from "d3-hierarchy"
|
|
14
14
|
import { Intersection, Object3D, Raycaster } from "three"
|
|
15
15
|
import { CodeMapLabelService } from "./codeMap.label.service"
|
|
16
|
-
import { LazyLoader } from "../../util/lazyLoader"
|
|
17
|
-
import { CodeMapPreRenderService } from "./codeMap.preRender.service"
|
|
18
16
|
import { ThreeViewerService } from "./threeViewer/threeViewerService"
|
|
19
17
|
import { setHoveredBuildingPath } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
|
|
20
18
|
import { hoveredBuildingPathSelector } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.selector"
|
|
21
19
|
import { setRightClickedNodeData } from "../../state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions"
|
|
20
|
+
import { idToNodeSelector } from "../../state/selectors/accumulatedData/idToNode.selector"
|
|
21
|
+
import { IdToBuildingService } from "../../services/idToBuilding/idToBuilding.service"
|
|
22
22
|
|
|
23
23
|
interface Coordinates {
|
|
24
24
|
x: number
|
|
@@ -71,9 +71,9 @@ export class CodeMapMouseEventService implements ViewCubeEventPropagationSubscri
|
|
|
71
71
|
private threeUpdateCycleService: ThreeUpdateCycleService,
|
|
72
72
|
private storeService: StoreService,
|
|
73
73
|
private codeMapLabelService: CodeMapLabelService,
|
|
74
|
-
private codeMapPreRenderService: CodeMapPreRenderService,
|
|
75
74
|
private viewCubeMouseEventsService: ViewCubeMouseEventsService,
|
|
76
|
-
private threeViewerService: ThreeViewerService
|
|
75
|
+
private threeViewerService: ThreeViewerService,
|
|
76
|
+
private idToBuilding: IdToBuildingService
|
|
77
77
|
) {
|
|
78
78
|
"ngInject"
|
|
79
79
|
this.threeUpdateCycleService.register(() => this.threeRendererService.render())
|
|
@@ -297,10 +297,6 @@ export class CodeMapMouseEventService implements ViewCubeEventPropagationSubscri
|
|
|
297
297
|
this.$window.open(sourceLink, "_blank")
|
|
298
298
|
return
|
|
299
299
|
}
|
|
300
|
-
const fileName = this.codeMapPreRenderService.getRenderFileMeta().fileName
|
|
301
|
-
if (fileName) {
|
|
302
|
-
LazyLoader.openFile(fileName, selectedBuilding.node.path)
|
|
303
|
-
}
|
|
304
300
|
}
|
|
305
301
|
}
|
|
306
302
|
|
|
@@ -396,10 +392,10 @@ export class CodeMapMouseEventService implements ViewCubeEventPropagationSubscri
|
|
|
396
392
|
private hoverBuilding(hoveredBuilding: CodeMapBuilding) {
|
|
397
393
|
CodeMapMouseEventService.changeCursorIndicator(CursorType.Pointer)
|
|
398
394
|
|
|
399
|
-
const
|
|
400
|
-
const codeMapNode =
|
|
395
|
+
const idToNode = idToNodeSelector(this.storeService.getState())
|
|
396
|
+
const codeMapNode = idToNode.get(hoveredBuilding.node.id)
|
|
401
397
|
for (const { data } of hierarchy(codeMapNode)) {
|
|
402
|
-
const building =
|
|
398
|
+
const building = this.idToBuilding.get(data.id)
|
|
403
399
|
if (building) {
|
|
404
400
|
this.threeSceneService.addBuildingToHighlightingList(building)
|
|
405
401
|
}
|