All files / app/codeCharta/ui/metricChooser nodeSelection.service.ts

100% Statements 24/24
90% Branches 9/10
100% Functions 8/8
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 4411x 11x 11x   11x 11x 11x 11x 11x     11x   8x 8x       30x 30x 30x   30x 29x         30x 29x 29x         29x 29x 29x 35x          
import { Injectable } from "@angular/core"
import { Store } from "@ngrx/store"
import { Observable, combineLatest, filter, map } from "rxjs"
import { CcState, CodeMapNode, Node } from "../../codeCharta.model"
import { AccumulatedData, accumulatedDataSelector } from "../../state/selectors/accumulatedData/accumulatedData.selector"
import { hoveredNodeSelector } from "../../state/selectors/hoveredNode.selector"
import { dynamicSettingsSelector } from "../../state/store/dynamicSettings/dynamicSettings.selector"
import { CodeMapRenderService } from "../codeMap/codeMap.render.service"
import { selectedNodeSelector } from "../../state/selectors/selectedNode.selector"
 
@Injectable({ providedIn: "root" })
export class NodeSelectionService {
    constructor(
        private store: Store<CcState>,
        private codeMapRenderService: CodeMapRenderService
    ) {}
 
    createNodeObservable(): Observable<CodeMapNode | Node> {
        const hoveredNode$ = this.store.select(hoveredNodeSelector)
        const selectedNode$ = this.store.select(selectedNodeSelector)
        const topLevelNode$ = this.createTopLevelNodeObservable()
 
        return combineLatest([hoveredNode$, selectedNode$, topLevelNode$]).pipe(
            map(([hoveredNode, selectedNode, topLevelNode]) => hoveredNode ?? selectedNode ?? topLevelNode)
        )
    }
 
    private createTopLevelNodeObservable(): Observable<Node> {
        return combineLatest([this.store.select(accumulatedDataSelector), this.store.select(dynamicSettingsSelector)]).pipe(
            filter(([accumulatedData]) => Boolean(accumulatedData.unifiedMapNode)),
            map(([accumulatedData]) => this.findTopLevelNode(accumulatedData))
        )
    }
 
    private findTopLevelNode(accumulatedData: AccumulatedData): Node {
        const nodes = this.codeMapRenderService.getNodes(accumulatedData.unifiedMapNode)
        const visibleSortedNodes = this.codeMapRenderService.sortVisibleNodesByHeightDescending(nodes)
        return visibleSortedNodes.reduce(
            (previous, current) => (previous.attributes.unary > current.attributes.unary ? previous : current),
            visibleSortedNodes[0]
        )
    }
}