codecharta-visualization 1.88.0 → 1.89.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 +20 -10
- package/app/codeCharta/codeCharta.component.html +0 -2
- package/app/codeCharta/codeCharta.model.ts +1 -0
- package/app/codeCharta/services/ajs-upgraded-providers.ts +13 -0
- package/app/codeCharta/state/angular-redux/effects/createEffect.spec.ts +37 -0
- package/app/codeCharta/state/angular-redux/effects/createEffect.ts +25 -0
- package/app/codeCharta/state/angular-redux/effects/effects.module.ts +36 -0
- package/app/codeCharta/state/angular-redux/ofType.ts +11 -0
- package/app/codeCharta/state/angular-redux/state.ts +12 -0
- package/app/codeCharta/state/angular-redux/store.ts +1 -1
- package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/addBlacklistItemsIfNotResultsInEmptyMap.effect.spec.ts +60 -0
- package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/addBlacklistItemsIfNotResultsInEmptyMap.effect.ts +56 -0
- package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/resultsInEmptyMap.ts +22 -0
- package/app/codeCharta/state/effects/nodeContextMenu/excludeButton/excludeButton.component.html +3 -0
- package/app/codeCharta/state/effects/nodeContextMenu/excludeButton/excludeButton.component.ts +26 -0
- package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.html +13 -0
- package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.spec.ts +55 -0
- package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.ts +34 -0
- package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.module.ts +11 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.html +0 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.spec.ts +2 -2
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.ts +5 -5
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.module.ts +1 -1
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.spec.ts +0 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.ts +2 -2
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.html +6 -0
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.spec.ts +64 -0
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.ts +39 -0
- package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.module.ts +11 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.html +3 -3
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.scss +0 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.spec.ts +2 -2
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.ts +6 -6
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.module.ts +1 -1
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.spec.ts +0 -0
- package/app/codeCharta/state/effects/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.ts +29 -0
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/nodeContextMenu.e2e.ts +4 -16
- package/app/codeCharta/{ui → state/effects}/nodeContextMenu/nodeContextMenu.po.ts +1 -1
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenu.service.spec.ts +78 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenu.service.ts +72 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/lastPartOfNodePath.pipe.spec.ts +11 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/lastPartOfNodePath.pipe.ts +8 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.html +17 -0
- package/app/codeCharta/{ui/nodeContextMenu/nodeContextMenu.component.scss → state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.scss} +6 -11
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.spec.ts +49 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.ts +19 -0
- package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.module.ts +18 -0
- package/app/codeCharta/state/effects/nodeContextMenu/openNodeContextMenu.effect.spec.ts +32 -0
- package/app/codeCharta/state/effects/nodeContextMenu/openNodeContextMenu.effect.ts +33 -0
- package/app/codeCharta/state/effects/nodeContextMenu/rightClickedCodeMapNode.selector.ts +8 -0
- package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.spec.ts +47 -0
- package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.ts +18 -0
- package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/areAllNecessaryRenderDataAvailable.selector.ts +30 -0
- package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areDynamicSettingsAvailable.spec.ts +36 -0
- package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areDynamicSettingsAvailable.ts +10 -0
- package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areMetricsAvailable.spec.ts +13 -0
- package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areMetricsAvailable.ts +8 -0
- package/app/codeCharta/state/store/appSettings/appSettings.actions.ts +2 -0
- package/app/codeCharta/state/store/appSettings/appSettings.reducer.ts +2 -0
- package/app/codeCharta/state/store/appSettings/invertArea/invertArea.actions.ts +32 -0
- package/app/codeCharta/state/store/appSettings/invertArea/invertArea.reducer.spec.ts +26 -0
- package/app/codeCharta/state/store/appSettings/invertArea/invertArea.reducer.ts +12 -0
- package/app/codeCharta/state/store/appSettings/invertArea/invertArea.selector.ts +3 -0
- package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.spec.ts +14 -3
- package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.ts +41 -6
- package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.actions.ts +33 -2
- package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.reducer.spec.ts +17 -1
- package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.reducer.ts +3 -1
- package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.service.spec.ts +1 -19
- package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.service.ts +5 -28
- package/app/codeCharta/state/store/lookUp/idToNode/idToNode.selector.ts +4 -0
- package/app/codeCharta/state/store/lookUp/lookUp.selector.ts +3 -0
- package/app/codeCharta/state/store/metricData/nodeMetricData/nodeMetricData.service.ts +0 -4
- package/app/codeCharta/state/store/store.ts +5 -1
- package/app/codeCharta/state/store.service.spec.ts +20 -7
- package/app/codeCharta/state/store.service.ts +3 -36
- package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.html +3 -1
- package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.scss +6 -2
- package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.ts +1 -1
- package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.module.ts +3 -0
- package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.po.ts +4 -4
- package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.html +1 -0
- package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.scss +26 -0
- package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.spec.ts +29 -0
- package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.ts +24 -0
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/aggregationType.pipe.spec.ts +19 -0
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/{aggregationSymbol.pipe.ts → aggregationType.pipe.ts} +4 -4
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.html +4 -12
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.scss +11 -20
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.spec.ts +8 -15
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.module.ts +2 -2
- package/app/codeCharta/ui/codeMap/codeMap.preRender.service.spec.ts +1 -9
- package/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts +9 -32
- package/app/codeCharta/ui/dialogs/dialogs.ts +3 -0
- package/app/codeCharta/ui/dialogs/errorDialog/errorDialog.component.html +7 -0
- package/app/codeCharta/ui/dialogs/errorDialog/errorDialog.component.ts +9 -0
- package/app/codeCharta/ui/mapTreeView/mapTreeView.level.e2e.ts +1 -1
- package/app/codeCharta/ui/mapTreeView/mapTreeView.level.po.ts +1 -1
- package/app/codeCharta/ui/ribbonBar/ribbonBar.component.html +2 -2
- package/app/codeCharta/ui/ribbonBar/ribbonBar.e2e.ts +3 -3
- package/app/codeCharta/ui/searchBar/searchBar.component.html +5 -0
- package/app/codeCharta/ui/searchBar/searchBar.component.scss +11 -0
- package/app/codeCharta/ui/searchBar/searchBar.component.spec.ts +10 -0
- package/app/codeCharta/ui/searchBar/searchBar.component.ts +1 -1
- package/app/codeCharta/ui/sortingOption/sortingOption.component.spec.ts +1 -1
- package/app/codeCharta/ui/ui.ts +0 -2
- package/app/codeCharta/util/algorithm/treeMapLayout/treeMapGenerator.spec.ts +1 -1
- package/app/codeCharta/util/algorithm/treeMapLayout/treeMapGenerator.ts +14 -7
- package/app/codeCharta/util/customConfigBuilder.ts +1 -0
- package/app/codeCharta/util/dataMocks.ts +2 -0
- package/app/codeCharta/util/reduxHelper.ts +11 -0
- package/app/material/material.module.ts +17 -1
- package/conf/webpack.loaders.js +4 -1
- package/dist/webpack/bundle.js +4582 -950
- package/dist/webpack/bundle.js.map +1 -1
- package/package.json +2 -2
- package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/aggregationSymbol.pipe.spec.ts +0 -19
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.ts +0 -29
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.spec.ts +0 -15
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.ts +0 -9
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.html +0 -45
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.spec.ts +0 -365
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.ts +0 -198
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.module.ts +0 -15
package/app/app.module.ts
CHANGED
|
@@ -19,18 +19,23 @@ import { LegendPanelComponent } from "./codeCharta/ui/legendPanel/legendPanel.co
|
|
|
19
19
|
import { LegendPanelModule } from "./codeCharta/ui/legendPanel/legendPanel.module"
|
|
20
20
|
import { ColorPickerForMapColorModule } from "./codeCharta/ui/colorPickerForMapColor/colorPickerForMapColor.module"
|
|
21
21
|
import { ColorPickerForMapColorComponent } from "./codeCharta/ui/colorPickerForMapColor/colorPickerForMapColor.component"
|
|
22
|
-
import { FocusButtonsModule } from "./codeCharta/ui/nodeContextMenu/focusButtons/focusButtons.module"
|
|
23
|
-
import { FocusButtonsComponent } from "./codeCharta/ui/nodeContextMenu/focusButtons/focusButtons.component"
|
|
24
22
|
import { FilePanelFileSelectorComponent } from "./codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component"
|
|
25
23
|
import { FilePanelStateButtonsComponent } from "./codeCharta/ui/filePanel/filePanelStateButtons/filePanelStateButtons.component"
|
|
26
24
|
import { FilePanelDeltaSelectorComponent } from "./codeCharta/ui/filePanel/filePanelDeltaSelector/filePanelDeltaSelector.component"
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
25
|
+
import { EffectsModule } from "./codeCharta/state/angular-redux/effects/effects.module"
|
|
26
|
+
import { UnfocusNodesOnLoadingMapEffect } from "./codeCharta/state/effects/unfocusNodesOnLoadingMap.effect"
|
|
27
|
+
import { AddBlacklistItemsIfNotResultsInEmptyMapEffect } from "./codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/addBlacklistItemsIfNotResultsInEmptyMap.effect"
|
|
28
|
+
import { dialogs } from "./codeCharta/ui/dialogs/dialogs"
|
|
29
|
+
import { threeSceneServiceProvider } from "./codeCharta/services/ajs-upgraded-providers"
|
|
30
|
+
import { NodeContextMenuCardModule } from "./codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.module"
|
|
31
|
+
import { OpenNodeContextMenuEffect } from "./codeCharta/state/effects/nodeContextMenu/openNodeContextMenu.effect"
|
|
32
|
+
import { InvertAreaOptionComponent } from "./codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component"
|
|
29
33
|
|
|
30
34
|
@NgModule({
|
|
31
35
|
imports: [
|
|
32
36
|
BrowserModule,
|
|
33
37
|
UpgradeModule,
|
|
38
|
+
EffectsModule.forRoot([UnfocusNodesOnLoadingMapEffect, AddBlacklistItemsIfNotResultsInEmptyMapEffect, OpenNodeContextMenuEffect]),
|
|
34
39
|
MapTreeViewModule,
|
|
35
40
|
MatchingFilesCounterModule,
|
|
36
41
|
AttributeSideBarModule,
|
|
@@ -39,10 +44,16 @@ import { MarkFolderRowModule } from "./codeCharta/ui/nodeContextMenu/markFolderR
|
|
|
39
44
|
Export3DMapButtonModule,
|
|
40
45
|
LegendPanelModule,
|
|
41
46
|
ColorPickerForMapColorModule,
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
NodeContextMenuCardModule
|
|
48
|
+
],
|
|
49
|
+
providers: [threeSceneServiceProvider],
|
|
50
|
+
declarations: [
|
|
51
|
+
FilePanelFileSelectorComponent,
|
|
52
|
+
FilePanelStateButtonsComponent,
|
|
53
|
+
FilePanelDeltaSelectorComponent,
|
|
54
|
+
InvertAreaOptionComponent,
|
|
55
|
+
...dialogs
|
|
44
56
|
],
|
|
45
|
-
declarations: [FilePanelFileSelectorComponent, FilePanelStateButtonsComponent, FilePanelDeltaSelectorComponent],
|
|
46
57
|
entryComponents: [
|
|
47
58
|
MapTreeViewComponent,
|
|
48
59
|
MatchingFilesCounterComponent,
|
|
@@ -51,12 +62,11 @@ import { MarkFolderRowModule } from "./codeCharta/ui/nodeContextMenu/markFolderR
|
|
|
51
62
|
LegendPanelComponent,
|
|
52
63
|
LabelledColorPickerComponent,
|
|
53
64
|
ColorPickerForMapColorComponent,
|
|
54
|
-
FocusButtonsComponent,
|
|
55
65
|
FilePanelFileSelectorComponent,
|
|
56
66
|
FilePanelStateButtonsComponent,
|
|
57
67
|
FilePanelDeltaSelectorComponent,
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
InvertAreaOptionComponent,
|
|
69
|
+
...dialogs
|
|
60
70
|
]
|
|
61
71
|
})
|
|
62
72
|
export class AppModule {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InjectionToken, Injector } from "@angular/core"
|
|
2
|
+
|
|
3
|
+
export const ThreeSceneServiceToken = new InjectionToken("ThreeSceneService")
|
|
4
|
+
|
|
5
|
+
export function ThreeSceneServiceFactory(injector: Injector) {
|
|
6
|
+
return injector.get("threeSceneService")
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const threeSceneServiceProvider = {
|
|
10
|
+
provide: ThreeSceneServiceToken,
|
|
11
|
+
useFactory: ThreeSceneServiceFactory,
|
|
12
|
+
deps: ["$injector"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { mocked } from "ts-jest/utils"
|
|
2
|
+
import { Subject } from "rxjs"
|
|
3
|
+
import { Store } from "../../store/store"
|
|
4
|
+
import { createEffect } from "./createEffect"
|
|
5
|
+
|
|
6
|
+
jest.mock("../../store/store", () => ({
|
|
7
|
+
Store: {}
|
|
8
|
+
}))
|
|
9
|
+
const MockedStore = mocked(Store)
|
|
10
|
+
|
|
11
|
+
describe("createEffect", () => {
|
|
12
|
+
let source
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
source = new Subject()
|
|
16
|
+
MockedStore.dispatch = jest.fn()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
source.complete()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it("should observe and dispatch each received value", () => {
|
|
24
|
+
createEffect(() => source)
|
|
25
|
+
source.next({ type: "some-action-type" })
|
|
26
|
+
source.next({ type: "some-other-action-type" })
|
|
27
|
+
expect(MockedStore.dispatch).toHaveBeenCalledTimes(2)
|
|
28
|
+
expect(MockedStore.dispatch.mock.calls[0][0]).toEqual({ type: "some-action-type" })
|
|
29
|
+
expect(MockedStore.dispatch.mock.calls[1][0]).toEqual({ type: "some-other-action-type" })
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("should not dispatch if dispatch is set to false", () => {
|
|
33
|
+
createEffect(() => source, { dispatch: false })
|
|
34
|
+
source.next({ type: "some-action-type" })
|
|
35
|
+
expect(MockedStore.dispatch).not.toHaveBeenCalled()
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Action } from "redux"
|
|
2
|
+
import { Observable } from "rxjs"
|
|
3
|
+
import { Store } from "../../store/store"
|
|
4
|
+
|
|
5
|
+
type DontDispatchConfig = { dispatch: false }
|
|
6
|
+
type DispatchConfig = { dispatch?: true }
|
|
7
|
+
type Config = DispatchConfig | DontDispatchConfig
|
|
8
|
+
|
|
9
|
+
/** Simple placeholder for NgRx's createEffect. The goal is to provide the
|
|
10
|
+
* same api as NgRx, so that we can switch to NgRx in the long run.
|
|
11
|
+
* Please note that its functionality is very minimal so far.
|
|
12
|
+
*/
|
|
13
|
+
export function createEffect(source: () => Observable<unknown>, config?: Config) {
|
|
14
|
+
source().subscribe(output => {
|
|
15
|
+
if (config?.dispatch === false) return
|
|
16
|
+
|
|
17
|
+
if (!isAction(output)) throw new Error("output must be an action")
|
|
18
|
+
|
|
19
|
+
Store.dispatch(output)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isAction(something: unknown): something is Action {
|
|
24
|
+
return something && Object.prototype.hasOwnProperty.call(something, "type")
|
|
25
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { APP_INITIALIZER, Inject, InjectionToken, ModuleWithProviders, NgModule, Optional, SkipSelf } from "@angular/core"
|
|
2
|
+
import { Action } from "redux"
|
|
3
|
+
import { Observable, Subject } from "rxjs"
|
|
4
|
+
|
|
5
|
+
export type Actions = Observable<Action>
|
|
6
|
+
export const ActionsToken = new InjectionToken<Actions>("Actions")
|
|
7
|
+
|
|
8
|
+
/** Simple placeholder for NgRx's EffectsModule. The goal is to provide the
|
|
9
|
+
* same api as NgRx, so that we can switch to NgRx in the long run.
|
|
10
|
+
*/
|
|
11
|
+
@NgModule({})
|
|
12
|
+
export class EffectsModule {
|
|
13
|
+
static actions$ = new Subject<Action>()
|
|
14
|
+
|
|
15
|
+
constructor(@Optional() @SkipSelf() @Inject(EffectsModule) parentModule?: EffectsModule) {
|
|
16
|
+
if (parentModule) throw new Error("EffectsModule is already loaded. Import it in the AppModule only")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static forRoot(effects = []): ModuleWithProviders<EffectsModule> {
|
|
20
|
+
return {
|
|
21
|
+
ngModule: EffectsModule,
|
|
22
|
+
providers: [
|
|
23
|
+
{ provide: ActionsToken, useValue: EffectsModule.actions$ },
|
|
24
|
+
effects,
|
|
25
|
+
{
|
|
26
|
+
provide: APP_INITIALIZER,
|
|
27
|
+
deps: effects,
|
|
28
|
+
useFactory: () => () => {
|
|
29
|
+
// initialized effects"
|
|
30
|
+
},
|
|
31
|
+
multi: true
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Action } from "redux"
|
|
2
|
+
import { filter, map, Observable } from "rxjs"
|
|
3
|
+
|
|
4
|
+
export function ofType<T extends Action>(type: string) {
|
|
5
|
+
return function (source: Observable<Action>) {
|
|
6
|
+
return source.pipe(
|
|
7
|
+
filter(action => action.type === type),
|
|
8
|
+
map(action => action as T)
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ApplicationInitStatus } from "@angular/core"
|
|
2
|
+
import { TestBed } from "@angular/core/testing"
|
|
3
|
+
import { MatDialog } from "@angular/material/dialog"
|
|
4
|
+
import { Action } from "redux"
|
|
5
|
+
import { Subject } from "rxjs"
|
|
6
|
+
import { BlacklistType } from "../../../codeCharta.model"
|
|
7
|
+
import { FILE_STATES_JAVA } from "../../../util/dataMocks"
|
|
8
|
+
|
|
9
|
+
import { EffectsModule } from "../../angular-redux/effects/effects.module"
|
|
10
|
+
import { setFiles } from "../../store/files/files.actions"
|
|
11
|
+
import { addBlacklistItems, addBlacklistItemsIfNotResultsInEmptyMap } from "../../store/fileSettings/blacklist/blacklist.actions"
|
|
12
|
+
import { Store } from "../../store/store"
|
|
13
|
+
import { AddBlacklistItemsIfNotResultsInEmptyMapEffect } from "./addBlacklistItemsIfNotResultsInEmptyMap.effect"
|
|
14
|
+
|
|
15
|
+
describe("AddBlacklistItemsIfNotResultsInEmptyMapEffect", () => {
|
|
16
|
+
const mockedDialog = { open: jest.fn() }
|
|
17
|
+
let storeDispatchSpy
|
|
18
|
+
|
|
19
|
+
beforeEach(async () => {
|
|
20
|
+
Store["initialize"]()
|
|
21
|
+
storeDispatchSpy = jest.spyOn(Store, "dispatch")
|
|
22
|
+
mockedDialog.open = jest.fn()
|
|
23
|
+
|
|
24
|
+
EffectsModule.actions$ = new Subject<Action>()
|
|
25
|
+
TestBed.configureTestingModule({
|
|
26
|
+
imports: [EffectsModule.forRoot([AddBlacklistItemsIfNotResultsInEmptyMapEffect])],
|
|
27
|
+
providers: [{ provide: MatDialog, useValue: mockedDialog }]
|
|
28
|
+
})
|
|
29
|
+
await TestBed.inject(ApplicationInitStatus).donePromise
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
EffectsModule.actions$.complete()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("should ignore a not relevant action", () => {
|
|
37
|
+
EffectsModule.actions$.next({ type: "whatever" })
|
|
38
|
+
expect(storeDispatchSpy).not.toHaveBeenCalled()
|
|
39
|
+
expect(mockedDialog.open).not.toHaveBeenCalled()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it("should not blacklist items if it would lead to an empty map but show error dialog", () => {
|
|
43
|
+
EffectsModule.actions$.next(addBlacklistItemsIfNotResultsInEmptyMap([{ type: BlacklistType.exclude, path: "foo/bar" }]))
|
|
44
|
+
expect(storeDispatchSpy).not.toHaveBeenCalledWith(addBlacklistItems([{ type: BlacklistType.exclude, path: "foo/bar" }]))
|
|
45
|
+
expect(mockedDialog.open).toHaveBeenCalledTimes(1)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("should blacklist items if it doesn't lead to an empty map", () => {
|
|
49
|
+
Store.dispatch(setFiles(FILE_STATES_JAVA))
|
|
50
|
+
|
|
51
|
+
EffectsModule.actions$.next(
|
|
52
|
+
addBlacklistItemsIfNotResultsInEmptyMap([{ type: BlacklistType.exclude, path: "/root/src/main/file1.java" }])
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
expect(storeDispatchSpy).toHaveBeenCalledWith(
|
|
56
|
+
addBlacklistItems([{ type: BlacklistType.exclude, path: "/root/src/main/file1.java" }])
|
|
57
|
+
)
|
|
58
|
+
expect(mockedDialog.open).not.toHaveBeenCalled()
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Inject, Injectable } from "@angular/core"
|
|
2
|
+
import { Actions, ActionsToken } from "../../angular-redux/effects/effects.module"
|
|
3
|
+
import { MatDialog } from "@angular/material/dialog"
|
|
4
|
+
import { createEffect } from "../../angular-redux/effects/createEffect"
|
|
5
|
+
import { filter, map, tap, withLatestFrom } from "rxjs"
|
|
6
|
+
import {
|
|
7
|
+
addBlacklistItems,
|
|
8
|
+
AddBlacklistItemsIfNotResultsInEmptyMapAction,
|
|
9
|
+
BlacklistActions
|
|
10
|
+
} from "../../store/fileSettings/blacklist/blacklist.actions"
|
|
11
|
+
import { visibleFileStatesSelector } from "../../selectors/visibleFileStates.selector"
|
|
12
|
+
import { blacklistSelector } from "../../store/fileSettings/blacklist/blacklist.selector"
|
|
13
|
+
import { Store } from "../../angular-redux/store"
|
|
14
|
+
import { resultsInEmptyMap } from "./resultsInEmptyMap"
|
|
15
|
+
import { ErrorDialogComponent } from "../../../ui/dialogs/errorDialog/errorDialog.component"
|
|
16
|
+
import { ofType } from "../../angular-redux/ofType"
|
|
17
|
+
|
|
18
|
+
@Injectable()
|
|
19
|
+
export class AddBlacklistItemsIfNotResultsInEmptyMapEffect {
|
|
20
|
+
constructor(
|
|
21
|
+
@Inject(ActionsToken) private actions$: Actions,
|
|
22
|
+
@Inject(Store) private store: Store,
|
|
23
|
+
@Inject(MatDialog) private dialog: MatDialog
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
private visibleFiles$ = this.store.select(visibleFileStatesSelector)
|
|
27
|
+
private blacklist$ = this.store.select(blacklistSelector)
|
|
28
|
+
private doBlacklistItemsResultInEmptyMap$ = this.actions$.pipe(
|
|
29
|
+
ofType<AddBlacklistItemsIfNotResultsInEmptyMapAction>(BlacklistActions.ADD_BLACKLIST_ITEMS_IF_NOT_RESULTS_IN_EMPTY_MAP),
|
|
30
|
+
withLatestFrom(this.visibleFiles$, this.blacklist$),
|
|
31
|
+
map(([addBlacklistItemsIfNotResultsInEmptyMapAction, visibleFiles, blacklist]) => ({
|
|
32
|
+
items: addBlacklistItemsIfNotResultsInEmptyMapAction.payload,
|
|
33
|
+
resultsInEmptyMap: resultsInEmptyMap(visibleFiles, blacklist, addBlacklistItemsIfNotResultsInEmptyMapAction.payload)
|
|
34
|
+
}))
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
showErrorDialogIfBlacklistItemsResultInEmptyMap$ = createEffect(
|
|
38
|
+
() =>
|
|
39
|
+
this.doBlacklistItemsResultInEmptyMap$.pipe(
|
|
40
|
+
filter(event => event.resultsInEmptyMap),
|
|
41
|
+
tap(() => {
|
|
42
|
+
this.dialog.open(ErrorDialogComponent, {
|
|
43
|
+
data: { title: "Blacklist Error", message: "Excluding all buildings is not possible." }
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
),
|
|
47
|
+
{ dispatch: false }
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
addBlacklistItems$ = createEffect(() =>
|
|
51
|
+
this.doBlacklistItemsResultInEmptyMap$.pipe(
|
|
52
|
+
filter(event => !event.resultsInEmptyMap),
|
|
53
|
+
map(event => addBlacklistItems(event.items))
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
}
|
package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/resultsInEmptyMap.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { hierarchy, HierarchyNode } from "d3-hierarchy"
|
|
2
|
+
import { BlacklistItem, BlacklistType, CCFile, CodeMapNode } from "../../../codeCharta.model"
|
|
3
|
+
import { FileState } from "../../../model/files/files"
|
|
4
|
+
import { isLeaf, isPathBlacklisted } from "../../../util/codeMapHelper"
|
|
5
|
+
|
|
6
|
+
export const resultsInEmptyMap = (
|
|
7
|
+
visibleFiles: FileState[],
|
|
8
|
+
currentBlacklist: BlacklistItem[],
|
|
9
|
+
itemsToBeBlackListened: BlacklistItem[]
|
|
10
|
+
) => {
|
|
11
|
+
const newBlacklist = [...currentBlacklist, ...itemsToBeBlackListened]
|
|
12
|
+
for (const { file } of visibleFiles) if (!resultsInEmptyFile(file, newBlacklist)) return false
|
|
13
|
+
return true
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const resultsInEmptyFile = (file: CCFile, blacklist: BlacklistItem[]) => {
|
|
17
|
+
for (const node of hierarchy(file.map)) if (isNodeIncluded(node, blacklist)) return false
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const isNodeIncluded = (node: HierarchyNode<CodeMapNode>, blacklist: Array<BlacklistItem>) =>
|
|
22
|
+
isLeaf(node) && node.data.path && !isPathBlacklisted(node.data.path, blacklist, BlacklistType.exclude)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Component, Inject, Input } from "@angular/core"
|
|
2
|
+
import { BlacklistType, CodeMapNode } from "../../../../codeCharta.model"
|
|
3
|
+
import { Store } from "../../../angular-redux/store"
|
|
4
|
+
import { addBlacklistItemsIfNotResultsInEmptyMap } from "../../../store/fileSettings/blacklist/blacklist.actions"
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: "cc-exclude-button",
|
|
8
|
+
template: require("./excludeButton.component.html")
|
|
9
|
+
})
|
|
10
|
+
export class ExcludeButtonComponent {
|
|
11
|
+
@Input() codeMapNode: Pick<CodeMapNode, "path" | "type">
|
|
12
|
+
|
|
13
|
+
constructor(@Inject(Store) private store: Store) {}
|
|
14
|
+
|
|
15
|
+
excludeNode() {
|
|
16
|
+
this.store.dispatch(
|
|
17
|
+
addBlacklistItemsIfNotResultsInEmptyMap([
|
|
18
|
+
{
|
|
19
|
+
path: this.codeMapNode.path,
|
|
20
|
+
type: BlacklistType.exclude,
|
|
21
|
+
nodeType: this.codeMapNode.type
|
|
22
|
+
}
|
|
23
|
+
])
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
}
|
package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<button
|
|
2
|
+
mat-button
|
|
3
|
+
*ngIf="!codeMapNode?.isFlattened"
|
|
4
|
+
(click)="flattenNode()"
|
|
5
|
+
title="Flatten node and children-nodes, but keep an empty space"
|
|
6
|
+
>
|
|
7
|
+
<img alt="flattenIcon" class="png-icon" src="../../../../../assets/flatten.png" />
|
|
8
|
+
FLATTEN
|
|
9
|
+
</button>
|
|
10
|
+
<button mat-button *ngIf="codeMapNode?.isFlattened" (click)="unFlattenNode()" title="Show node and children-nodes">
|
|
11
|
+
<img alt="flattenIcon" class="png-icon" src="../../../../../assets/flatten.png" />
|
|
12
|
+
SHOW
|
|
13
|
+
</button>
|
package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.spec.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/angular"
|
|
2
|
+
import { TestBed } from "@angular/core/testing"
|
|
3
|
+
import { FlattenButtonsComponent } from "./flattenButtons.component"
|
|
4
|
+
import { FlattenButtonsModule } from "./flattenButtons.module"
|
|
5
|
+
import { BlacklistType, NodeType } from "../../../../codeCharta.model"
|
|
6
|
+
import userEvent from "@testing-library/user-event"
|
|
7
|
+
import { Store } from "../../../store/store"
|
|
8
|
+
|
|
9
|
+
describe("flattenButtonsComponent", () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
Store["initialize"]()
|
|
12
|
+
TestBed.configureTestingModule({
|
|
13
|
+
imports: [FlattenButtonsModule]
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it("should show flatten button for a not flattened node", async () => {
|
|
18
|
+
await render(FlattenButtonsComponent, {
|
|
19
|
+
excludeComponentDeclaration: true,
|
|
20
|
+
componentProperties: { codeMapNode: { path: "/root/foo.ts", type: NodeType.FILE, isFlattened: false } }
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
expect(screen.queryByText("SHOW")).toBe(null)
|
|
24
|
+
expect(screen.queryByText("FLATTEN")).not.toBe(null)
|
|
25
|
+
|
|
26
|
+
userEvent.click(screen.queryByText("FLATTEN"))
|
|
27
|
+
expect(Store.store.getState().fileSettings.blacklist).toContainEqual({
|
|
28
|
+
nodeType: NodeType.FILE,
|
|
29
|
+
path: "/root/foo.ts",
|
|
30
|
+
type: BlacklistType.flatten
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("should show un-flatten button for a flattened node", async () => {
|
|
35
|
+
Store.store.getState().fileSettings.blacklist.push({
|
|
36
|
+
nodeType: NodeType.FILE,
|
|
37
|
+
path: "/root/foo.ts",
|
|
38
|
+
type: BlacklistType.flatten
|
|
39
|
+
})
|
|
40
|
+
await render(FlattenButtonsComponent, {
|
|
41
|
+
excludeComponentDeclaration: true,
|
|
42
|
+
componentProperties: { codeMapNode: { path: "/root/foo.ts", type: NodeType.FILE, isFlattened: true } }
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
expect(screen.queryByText("FLATTEN")).toBe(null)
|
|
46
|
+
expect(screen.queryByText("SHOW")).not.toBe(null)
|
|
47
|
+
|
|
48
|
+
userEvent.click(screen.queryByText("SHOW"))
|
|
49
|
+
expect(Store.store.getState().fileSettings.blacklist).not.toContainEqual({
|
|
50
|
+
nodeType: NodeType.FILE,
|
|
51
|
+
path: "/root/foo.ts",
|
|
52
|
+
type: BlacklistType.flatten
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Component, Inject, Input } from "@angular/core"
|
|
2
|
+
import { BlacklistType, CodeMapNode } from "../../../../codeCharta.model"
|
|
3
|
+
import { Store } from "../../../angular-redux/store"
|
|
4
|
+
import { addBlacklistItem, removeBlacklistItem } from "../../../store/fileSettings/blacklist/blacklist.actions"
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: "cc-flatten-buttons",
|
|
8
|
+
template: require("./flattenButtons.component.html")
|
|
9
|
+
})
|
|
10
|
+
export class FlattenButtonsComponent {
|
|
11
|
+
@Input() codeMapNode: Pick<CodeMapNode, "path" | "type" | "isFlattened">
|
|
12
|
+
|
|
13
|
+
constructor(@Inject(Store) private store: Store) {}
|
|
14
|
+
|
|
15
|
+
flattenNode() {
|
|
16
|
+
this.store.dispatch(
|
|
17
|
+
addBlacklistItem({
|
|
18
|
+
path: this.codeMapNode.path,
|
|
19
|
+
type: BlacklistType.flatten,
|
|
20
|
+
nodeType: this.codeMapNode.type
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
unFlattenNode() {
|
|
26
|
+
this.store.dispatch(
|
|
27
|
+
removeBlacklistItem({
|
|
28
|
+
path: this.codeMapNode.path,
|
|
29
|
+
type: BlacklistType.flatten,
|
|
30
|
+
nodeType: this.codeMapNode.type
|
|
31
|
+
})
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CommonModule } from "@angular/common"
|
|
2
|
+
import { NgModule } from "@angular/core"
|
|
3
|
+
import { MaterialModule } from "../../../../../material/material.module"
|
|
4
|
+
import { FlattenButtonsComponent } from "./flattenButtons.component"
|
|
5
|
+
|
|
6
|
+
@NgModule({
|
|
7
|
+
imports: [CommonModule, MaterialModule],
|
|
8
|
+
declarations: [FlattenButtonsComponent],
|
|
9
|
+
exports: [FlattenButtonsComponent]
|
|
10
|
+
})
|
|
11
|
+
export class FlattenButtonsModule {}
|
package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.html
RENAMED
|
File without changes
|
|
@@ -3,9 +3,9 @@ import { TestBed } from "@angular/core/testing"
|
|
|
3
3
|
|
|
4
4
|
import { FocusButtonsComponent } from "./focusButtons.component"
|
|
5
5
|
import { FocusButtonsModule } from "./focusButtons.module"
|
|
6
|
-
import { focusedNodePathSelector } from "../../../
|
|
6
|
+
import { focusedNodePathSelector } from "../../../store/dynamicSettings/focusedNodePath/focusedNodePath.selector"
|
|
7
7
|
|
|
8
|
-
jest.mock("../../../
|
|
8
|
+
jest.mock("../../../store/dynamicSettings/focusedNodePath/focusedNodePath.selector", () => ({
|
|
9
9
|
focusedNodePathSelector: jest.fn()
|
|
10
10
|
}))
|
|
11
11
|
const mockedFocusedNodePathSelector = focusedNodePathSelector as jest.Mock
|
package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.ts
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Component, Inject, Input } from "@angular/core"
|
|
2
2
|
import { Observable, map } from "rxjs"
|
|
3
3
|
|
|
4
|
-
import { CodeMapNode } from "
|
|
5
|
-
import { Store } from "../../../
|
|
6
|
-
import { currentFocusedNodePathSelector } from "../../../
|
|
7
|
-
import { focusNode, unfocusAllNodes, unfocusNode } from "../../../
|
|
8
|
-
import { focusedNodePathSelector } from "../../../
|
|
4
|
+
import { CodeMapNode } from "../../../../codeCharta.model"
|
|
5
|
+
import { Store } from "../../../angular-redux/store"
|
|
6
|
+
import { currentFocusedNodePathSelector } from "../../../store/dynamicSettings/focusedNodePath/currentFocused.selector"
|
|
7
|
+
import { focusNode, unfocusAllNodes, unfocusNode } from "../../../store/dynamicSettings/focusedNodePath/focusedNodePath.actions"
|
|
8
|
+
import { focusedNodePathSelector } from "../../../store/dynamicSettings/focusedNodePath/focusedNodePath.selector"
|
|
9
9
|
|
|
10
10
|
@Component({
|
|
11
11
|
selector: "cc-focus-buttons",
|
package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.module.ts
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CommonModule } from "@angular/common"
|
|
2
2
|
import { NgModule } from "@angular/core"
|
|
3
3
|
|
|
4
|
-
import { MaterialModule } from "
|
|
4
|
+
import { MaterialModule } from "../../../../../material/material.module"
|
|
5
5
|
import { FocusButtonsComponent } from "./focusButtons.component"
|
|
6
6
|
import { IsNodeFocusedPipe } from "./isNodeFocused.pipe"
|
|
7
7
|
|
package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.spec.ts
RENAMED
|
File without changes
|
package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.ts
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Pipe, PipeTransform } from "@angular/core"
|
|
2
2
|
|
|
3
|
-
import { CodeMapNode } from "
|
|
3
|
+
import { CodeMapNode } from "../../../../codeCharta.model"
|
|
4
4
|
|
|
5
5
|
type IsNodeFocusedType = {
|
|
6
6
|
isNodeFocused: boolean
|
|
@@ -10,7 +10,7 @@ type IsNodeFocusedType = {
|
|
|
10
10
|
@Pipe({ name: "isNodeFocused" })
|
|
11
11
|
export class IsNodeFocusedPipe implements PipeTransform {
|
|
12
12
|
transform(focusedNodePath: string | undefined, node: Pick<CodeMapNode, "path">): IsNodeFocusedType {
|
|
13
|
-
if (!focusedNodePath)
|
|
13
|
+
if (!focusedNodePath || !node)
|
|
14
14
|
return {
|
|
15
15
|
isNodeFocused: false,
|
|
16
16
|
isParentFocused: false
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<button mat-button *ngIf="!isHighlighted" title="Highlight node constantly" (click)="addNodeToConstantHighlight()">
|
|
2
|
+
<i class="fa fa-cubes"></i> KEEP HIGHLIGHT
|
|
3
|
+
</button>
|
|
4
|
+
<button mat-button *ngIf="isHighlighted" title="Remove constant highlight" (click)="removeNodeFromConstantHighlight()">
|
|
5
|
+
<i class="fa fa-cubes"></i> REMOVE HIGHLIGHT
|
|
6
|
+
</button>
|