All files / app/codeCharta/state/effects/updateQueryParameters updateQueryParameters.effect.ts

100% Statements 62/62
94.11% Branches 16/17
100% Functions 8/8
100% Lines 61/61

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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 1106x 6x 6x 6x   6x 6x 6x   6x 6x 6x 6x 6x 6x       6x   6x 6x 6x 6x     6x   6x     7x     6x             6x 6x 6x 6x 1x     5x 5x 5x 5x 1x   4x     5x 1x   4x         17x   17x 17x 17x 17x   17x 55x 55x 12x 12x   43x       17x 5x     17x   17x       8x   8x 8x 8x   8x 29x 29x 26x       8x 8x      
import { Injectable } from "@angular/core"
import { Actions, createEffect, ofType } from "@ngrx/effects"
import { State, Store } from "@ngrx/store"
import { debounceTime, map, tap, withLatestFrom } from "rxjs"
import { CcState } from "../../../codeCharta.model"
import { LoadInitialFileService } from "../../../services/loadInitialFile/loadInitialFile.service"
import { metricDataSelector } from "../../selectors/accumulatedData/metricData/metricData.selector"
import { actionsRequiringUpdateQueryParameters } from "./actionsRequiringUpdateQueryParameters"
 
export enum MetricQueryParemter {
    areaMetric = "area",
    heightMetric = "height",
    colorMetric = "color",
    edgeMetric = "edge",
    currentFilesAreSampleFiles = "currentFilesAreSampleFiles"
}
 
@Injectable()
export class UpdateQueryParametersEffect {
    constructor(
        private loadInitialFileService: LoadInitialFileService,
        private actions$: Actions,
        private state: State<CcState>,
        private store: Store<CcState>
    ) {}
 
    saveMetricsInQueryParameters$ = createEffect(
        () =>
            this.actions$.pipe(
                ofType(...actionsRequiringUpdateQueryParameters),
                withLatestFrom(this.store.select(metricDataSelector)),
                map(metricData => metricData[1].edgeMetricData && metricData[1].edgeMetricData.length > 0),
                debounceTime(100),
                tap(isEdgeMetricDefined => {
                    this.updateMetricQueryParameters(isEdgeMetricDefined)
                })
            ),
        { dispatch: false }
    )
 
    private updateMetricQueryParameters(isEdgeMetricDefined: boolean): void {
        const state: CcState = this.state.getValue()
        const { edgeMetric, heightMetric, colorMetric, areaMetric } = state.dynamicSettings
        const isFileQueryParameterPresent = this.loadInitialFileService.checkFileQueryParameterPresent()
        if (!isFileQueryParameterPresent) {
            return
        }
 
        this.addOrUpdateQueryParameter(MetricQueryParemter.areaMetric, areaMetric)
        this.addOrUpdateQueryParameter(MetricQueryParemter.heightMetric, heightMetric)
        this.addOrUpdateQueryParameter(MetricQueryParemter.colorMetric, colorMetric)
        if (isEdgeMetricDefined) {
            this.addOrUpdateQueryParameter(MetricQueryParemter.edgeMetric, edgeMetric)
        } else {
            this.deleteQueryParameterIfExists(MetricQueryParemter.edgeMetric)
        }
 
        if (state.appStatus.currentFilesAreSampleFiles) {
            this.addOrUpdateQueryParameter(MetricQueryParemter.currentFilesAreSampleFiles, true)
        } else {
            this.deleteQueryParameterIfExists(MetricQueryParemter.currentFilesAreSampleFiles)
        }
    }
 
    private addOrUpdateQueryParameter(parameterName: string, parameterValue: string | number | boolean) {
        const newUrl = new URL(window.location.href)
 
        const queryString = newUrl.search.slice(1)
        const queryParts = queryString.length > 0 ? queryString.split("&") : []
        const updatedQuery = []
        let parameterFound = false
 
        for (const part of queryParts) {
            const key = part.split("=")[0]
            if (key === parameterName) {
                updatedQuery.push(`${parameterName}=${encodeURIComponent(parameterValue)}`)
                parameterFound = true
            } else {
                updatedQuery.push(part)
            }
        }
 
        if (!parameterFound) {
            updatedQuery.push(`${parameterName}=${encodeURIComponent(parameterValue)}`)
        }
 
        newUrl.search = updatedQuery.join("&")
 
        window.history.replaceState(null, "", newUrl.toString())
    }
 
    deleteQueryParameterIfExists(parameterName) {
        const newUrl = new URL(window.location.href)
 
        const queryString = newUrl.search.slice(1)
        const queryParts = queryString.length > 0 ? queryString.split("&") : []
        const updatedQuery = []
 
        for (const part of queryParts) {
            const [key, value] = part.split("=")
            if (key !== parameterName) {
                updatedQuery.push(`${key}=${value}`)
            }
        }
 
        newUrl.search = updatedQuery.join("&")
        window.history.replaceState(null, "", newUrl.toString())
    }
}