diff --git a/CHANGELOG.md b/CHANGELOG.md index c903378066..b639b2fc0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Fixed 🐞 +- Fix saving the number of top-labels in custom configs [#3461](https://github.com/MaibornWolff/codecharta/pull/3461) - Fix parsers crashing after printing output to stdout [#3442](https://github.com/MaibornWolff/codecharta/pull/3442) - Fix removal of nodes with identical names in `modify` [#3446](https://github.com/MaibornWolff/codecharta/pull/3446) - Fix the highlighting of very high risk metrics to highlight only matching files [#3454](https://github.com/MaibornWolff/codecharta/pull/3454) diff --git a/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.spec.ts b/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.spec.ts index cc8206a10f..888c0dcfc3 100644 --- a/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.spec.ts +++ b/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.spec.ts @@ -1,13 +1,11 @@ import { TestBed } from "@angular/core/testing" import { Subject } from "rxjs" -import { Vector3 } from "three" import { CodeMapRenderService } from "../../../ui/codeMap/codeMap.render.service" import { ThreeRendererService } from "../../../ui/codeMap/threeViewer/threeRenderer.service" import { UploadFilesService } from "../../../ui/toolBar/uploadFilesButton/uploadFiles.service" import { wait } from "../../../util/testUtils/wait" import { accumulatedDataSelector } from "../../selectors/accumulatedData/accumulatedData.selector" import { setInvertArea } from "../../store/appSettings/invertArea/invertArea.actions" -import { setScaling } from "../../store/appSettings/scaling/scaling.actions" import { maxFPS, RenderCodeMapEffect } from "./renderCodeMap.effect" import { provideMockActions } from "@ngrx/effects/testing" import { Action } from "@ngrx/store" @@ -46,7 +44,7 @@ describe("renderCodeMapEffect", () => { actions$.complete() }) - it("should render throttled after actions requiring rerender, but not scale map", async () => { + it("should render throttled after actions requiring rerender and scale map", async () => { actions$.next(setInvertArea({ value: true })) actions$.next(setInvertArea({ value: true })) expect(codeMapRenderService.render).toHaveBeenCalledTimes(0) @@ -55,12 +53,6 @@ describe("renderCodeMapEffect", () => { await wait(maxFPS) expect(codeMapRenderService.render).toHaveBeenCalledTimes(1) expect(threeRendererService.render).toHaveBeenCalledTimes(1) - expect(codeMapRenderService.scaleMap).not.toHaveBeenCalled() - }) - - it("should scale map when scaling changes", async () => { - actions$.next(setScaling({ value: new Vector3(1, 1, 1) })) - await wait(maxFPS) expect(codeMapRenderService.scaleMap).toHaveBeenCalledTimes(1) }) diff --git a/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.ts b/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.ts index 9fc5e3e40d..e635aa4b1a 100644 --- a/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.ts +++ b/visualization/app/codeCharta/state/effects/renderCodeMapEffect/renderCodeMap.effect.ts @@ -7,7 +7,6 @@ import { CodeMapRenderService } from "../../../ui/codeMap/codeMap.render.service import { ThreeRendererService } from "../../../ui/codeMap/threeViewer/threeRenderer.service" import { UploadFilesService } from "../../../ui/toolBar/uploadFilesButton/uploadFiles.service" import { accumulatedDataSelector } from "../../selectors/accumulatedData/accumulatedData.selector" -import { setScaling } from "../../store/appSettings/scaling/scaling.actions" import { actionsRequiringRerender } from "./actionsRequiringRerender" import { setIsLoadingFile } from "../../store/appSettings/isLoadingFile/isLoadingFile.actions" import { setIsLoadingMap } from "../../store/appSettings/isLoadingMap/isLoadingMap.actions" @@ -31,12 +30,10 @@ export class RenderCodeMapEffect { combineLatest([this.store.select(accumulatedDataSelector), this.actionsRequiringRender$]).pipe( filter(([accumulatedData]) => Boolean(accumulatedData.unifiedMapNode)), throttleTime(maxFPS, asyncScheduler, { leading: false, trailing: true }), - tap(([accumulatedData, action]) => { + tap(([accumulatedData]) => { this.codeMapRenderService.render(accumulatedData.unifiedMapNode) + this.codeMapRenderService.scaleMap() this.threeRendererService.render() - if (action.type === setScaling.type) { - this.codeMapRenderService.scaleMap() - } }), share() ), diff --git a/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.spec.ts b/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.spec.ts new file mode 100644 index 0000000000..88085d00d1 --- /dev/null +++ b/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.spec.ts @@ -0,0 +1,78 @@ +import { MockStore, provideMockStore } from "@ngrx/store/testing" +import { UpdateVisibleTopLabelsEffect } from "./updateVisibleTopLabels.effect" +import { CcState } from "app/codeCharta/codeCharta.model" +import { TestBed } from "@angular/core/testing" +import { EffectsModule } from "@ngrx/effects" +import { State, StoreModule } from "@ngrx/store" +import { appReducers, setStateMiddleware } from "../../store/state.manager" +import { visibleFileStatesSelector } from "../../selectors/visibleFileStates.selector" +import { codeMapNodesSelector } from "../../selectors/accumulatedData/codeMapNodes.selector" +import { getLastAction } from "../../../../codeCharta/util/testUtils/store.utils" +import { setAmountOfTopLabels } from "../../store/appSettings/amountOfTopLabels/amountOfTopLabels.actions" + +describe("updateVisibleTopLabelsEffect", () => { + let store: MockStore + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + EffectsModule.forRoot([UpdateVisibleTopLabelsEffect]), + StoreModule.forRoot(appReducers, { metaReducers: [setStateMiddleware] }) + ], + providers: [ + provideMockStore({ + selectors: [ + { + selector: visibleFileStatesSelector, + value: [] + }, + { + selector: codeMapNodesSelector, + value: [ + { + name: "sample1.ts" + }, + { + name: "sample2.ts" + } + ] + } + ] + }), + { + provide: State, + useValue: { + getValue: () => ({ appSettings: { amountOfTopLabels: 5 } }) + } + } + ] + }) + store = TestBed.inject(MockStore) + }) + + it("should set amount of top labels to current app-settings when visible file-states are unchanged", async () => { + const visibleFileStates = [] + + store.overrideSelector(visibleFileStatesSelector, visibleFileStates as ReturnType) + store.refreshState() + + expect(await getLastAction(store)).toEqual(setAmountOfTopLabels({ value: 5 })) + }) + + it("should calculate the amount of top labels when visible-file-states are changed", async () => { + const visibleFileStates = [ + { + file: { + fileMeta: { + fileName: "sample1.cc.json" + } + } + } + ] + + store.overrideSelector(visibleFileStatesSelector, visibleFileStates as ReturnType) + store.refreshState() + + expect(await getLastAction(store)).toEqual(setAmountOfTopLabels({ value: 1 })) + }) +}) diff --git a/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.ts b/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.ts index 7cc0b0a750..68d2e08be9 100644 --- a/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.ts +++ b/visualization/app/codeCharta/state/effects/updateVisibleTopLabels/updateVisibleTopLabels.effect.ts @@ -1,23 +1,30 @@ +import stringify from "safe-stable-stringify" import { Injectable } from "@angular/core" +import { State, Store } from "@ngrx/store" import { createEffect } from "@ngrx/effects" +import { map, pairwise, withLatestFrom } from "rxjs" -import { map, withLatestFrom } from "rxjs" import { visibleFileStatesSelector } from "../../selectors/visibleFileStates.selector" import { codeMapNodesSelector } from "../../selectors/accumulatedData/codeMapNodes.selector" import { setAmountOfTopLabels } from "../../store/appSettings/amountOfTopLabels/amountOfTopLabels.actions" import { getNumberOfTopLabels } from "./getNumberOfTopLabels" -import { Store } from "@ngrx/store" import { CcState } from "../../../codeCharta.model" @Injectable() export class UpdateVisibleTopLabelsEffect { - constructor(private store: Store) {} + constructor(private store: Store, private state: State) {} updateVisibleTopLabels$ = createEffect(() => this.store.select(visibleFileStatesSelector).pipe( + pairwise(), withLatestFrom(this.store.select(codeMapNodesSelector)), - map(([, codeMapNodes]) => { - return setAmountOfTopLabels({ value: getNumberOfTopLabels(codeMapNodes) }) + map(([[previousVisibleFileStates, currentVisibleFileStates], codeMapNodes]) => { + const isUnchanged = stringify(previousVisibleFileStates) === stringify(currentVisibleFileStates) + const amountOfTopLabels = isUnchanged + ? this.state.getValue().appSettings.amountOfTopLabels + : getNumberOfTopLabels(codeMapNodes) + + return setAmountOfTopLabels({ value: amountOfTopLabels }) }) ) ) diff --git a/visualization/app/codeCharta/ui/ribbonBar/heightSettingsPanel/heightSettingsPanel.component.html b/visualization/app/codeCharta/ui/ribbonBar/heightSettingsPanel/heightSettingsPanel.component.html index 80d467b728..a67de9ad00 100644 --- a/visualization/app/codeCharta/ui/ribbonBar/heightSettingsPanel/heightSettingsPanel.component.html +++ b/visualization/app/codeCharta/ui/ribbonBar/heightSettingsPanel/heightSettingsPanel.component.html @@ -25,8 +25,8 @@ class="cc-height-settings-panel-row" title="Height" label="Height" - [step]="0.1" - [min]="0.1" + [step]="1" + [min]="1" [max]="5" [value]="(scaling$ | async).y" [onChange]="applyDebouncedScalingY" diff --git a/visualization/package-lock.json b/visualization/package-lock.json index fb9ea9d219..652dca03af 100644 --- a/visualization/package-lock.json +++ b/visualization/package-lock.json @@ -34,6 +34,7 @@ "pako": "^2.0.4", "percent-round": "^2.2.1", "rxjs": "^7.5.1", + "safe-stable-stringify": "^2.4.3", "shelljs": "^0.8.4", "three": "^0.126.1", "three-orbit-controls": "^82.1.0", @@ -18150,8 +18151,9 @@ } }, "node_modules/safe-stable-stringify": { - "version": "2.4.2", - "license": "MIT", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", "engines": { "node": ">=10" } diff --git a/visualization/package.json b/visualization/package.json index 6302785a15..20687b2f5e 100644 --- a/visualization/package.json +++ b/visualization/package.json @@ -88,6 +88,7 @@ "pako": "^2.0.4", "percent-round": "^2.2.1", "rxjs": "^7.5.1", + "safe-stable-stringify": "^2.4.3", "shelljs": "^0.8.4", "three": "^0.126.1", "three-orbit-controls": "^82.1.0",