All files / app/codeCharta/state/effects/nodeContextMenu nodeContextMenu.service.ts

92.68% Statements 38/41
78.57% Branches 11/14
88.88% Functions 8/9
92.3% Lines 36/39

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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 882x 2x 2x 2x 2x 2x     2x 7x     7x 7x       7x 1x     7x                       7x         7x   7x 1x     7x 7x 7x     7x 2x 2x 2x   2x   2x 1x       7x 3x 2x     1x     7x                 2x 2x       3x 4x      
import { Overlay, OverlayRef } from "@angular/cdk/overlay"
import { ComponentPortal } from "@angular/cdk/portal"
import { Injectable } from "@angular/core"
import { Store } from "@ngrx/store"
import { setRightClickedNodeData } from "../../store/appStatus/rightClickedNodeData/rightClickedNodeData.actions"
import { NodeContextMenuCardComponent } from "./nodeContextMenuCard/nodeContextMenuCard.component"
 
@Injectable({ providedIn: "root" })
export class NodeContextMenuService {
    private overlayReference: OverlayRef | null = null
 
    constructor(
        private overlay: Overlay,
        private store: Store
    ) {}
 
    open(x: number, y: number) {
        if (this.overlayReference) {
            this.resetOverlay()
        }
 
        const positionStrategy = this.overlay
            .position()
            .flexibleConnectedTo({ x, y })
            .withPositions([
                {
                    originX: "end",
                    originY: "bottom",
                    overlayX: "start",
                    overlayY: "top"
                }
            ])
 
        this.overlayReference = this.overlay.create({
            positionStrategy,
            scrollStrategy: this.overlay.scrollStrategies.close()
        })
 
        this.overlayReference.attach(new ComponentPortal(NodeContextMenuCardComponent))
 
        this.overlayReference.overlayElement.addEventListener("contextmenu", event => {
            event.preventDefault()
        })
 
        document.addEventListener("click", this.onLeftClickHideNodeContextMenu, false)
        document.addEventListener("mousedown", this.onRightClickHideNodeContextMenu, true)
        document.getElementById("codeMap").addEventListener("wheel", this.close, true)
    }
 
    close = () => {
        document.removeEventListener("click", this.onLeftClickHideNodeContextMenu, true)
        document.removeEventListener("mousedown", this.onRightClickHideNodeContextMenu, true)
        document.getElementById("codeMap").removeEventListener("wheel", this.close, true)
 
        this.store.dispatch(setRightClickedNodeData(null))
 
        if (this.overlayReference) {
            this.resetOverlay()
        }
    }
 
    private onLeftClickHideNodeContextMenu = (mouseEvent: MouseEvent) => {
        if (this.isEventFromColorPicker(mouseEvent)) {
            return
        }
 
        this.close()
    }
 
    private onRightClickHideNodeContextMenu = event => {
        Iif (event.button !== 2) {
            return
        }
        // Close on right click down, to close before the map gets potential moved by right clicked
        this.close()
    }
 
    resetOverlay() {
        this.overlayReference.dispose()
        this.overlayReference = null
    }
 
    private isEventFromColorPicker(mouseEvent: MouseEvent) {
        const elements = mouseEvent.composedPath() as Node[]
        return elements.some(element => element?.nodeName === "CC-COLOR-PICKER" || element?.nodeName === "COLOR-CHROME")
    }
}