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.
Files changed (124) hide show
  1. package/app/app.module.ts +20 -10
  2. package/app/codeCharta/codeCharta.component.html +0 -2
  3. package/app/codeCharta/codeCharta.model.ts +1 -0
  4. package/app/codeCharta/services/ajs-upgraded-providers.ts +13 -0
  5. package/app/codeCharta/state/angular-redux/effects/createEffect.spec.ts +37 -0
  6. package/app/codeCharta/state/angular-redux/effects/createEffect.ts +25 -0
  7. package/app/codeCharta/state/angular-redux/effects/effects.module.ts +36 -0
  8. package/app/codeCharta/state/angular-redux/ofType.ts +11 -0
  9. package/app/codeCharta/state/angular-redux/state.ts +12 -0
  10. package/app/codeCharta/state/angular-redux/store.ts +1 -1
  11. package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/addBlacklistItemsIfNotResultsInEmptyMap.effect.spec.ts +60 -0
  12. package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/addBlacklistItemsIfNotResultsInEmptyMap.effect.ts +56 -0
  13. package/app/codeCharta/state/effects/addBlacklistItemsIfNotResultsInEmptyMap/resultsInEmptyMap.ts +22 -0
  14. package/app/codeCharta/state/effects/nodeContextMenu/excludeButton/excludeButton.component.html +3 -0
  15. package/app/codeCharta/state/effects/nodeContextMenu/excludeButton/excludeButton.component.ts +26 -0
  16. package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.html +13 -0
  17. package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.spec.ts +55 -0
  18. package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.component.ts +34 -0
  19. package/app/codeCharta/state/effects/nodeContextMenu/flattenButtons/flattenButtons.module.ts +11 -0
  20. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.html +0 -0
  21. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.spec.ts +2 -2
  22. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.component.ts +5 -5
  23. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/focusButtons.module.ts +1 -1
  24. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.spec.ts +0 -0
  25. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/focusButtons/isNodeFocused.pipe.ts +2 -2
  26. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.html +6 -0
  27. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.spec.ts +64 -0
  28. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.ts +39 -0
  29. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.module.ts +11 -0
  30. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.html +3 -3
  31. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.scss +0 -0
  32. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.spec.ts +2 -2
  33. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.component.ts +6 -6
  34. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/markFolderRow.module.ts +1 -1
  35. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.spec.ts +0 -0
  36. package/app/codeCharta/state/effects/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.ts +29 -0
  37. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/nodeContextMenu.e2e.ts +4 -16
  38. package/app/codeCharta/{ui → state/effects}/nodeContextMenu/nodeContextMenu.po.ts +1 -1
  39. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenu.service.spec.ts +78 -0
  40. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenu.service.ts +72 -0
  41. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/lastPartOfNodePath.pipe.spec.ts +11 -0
  42. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/lastPartOfNodePath.pipe.ts +8 -0
  43. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.html +17 -0
  44. package/app/codeCharta/{ui/nodeContextMenu/nodeContextMenu.component.scss → state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.scss} +6 -11
  45. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.spec.ts +49 -0
  46. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.ts +19 -0
  47. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.module.ts +18 -0
  48. package/app/codeCharta/state/effects/nodeContextMenu/openNodeContextMenu.effect.spec.ts +32 -0
  49. package/app/codeCharta/state/effects/nodeContextMenu/openNodeContextMenu.effect.ts +33 -0
  50. package/app/codeCharta/state/effects/nodeContextMenu/rightClickedCodeMapNode.selector.ts +8 -0
  51. package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.spec.ts +47 -0
  52. package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.ts +18 -0
  53. package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/areAllNecessaryRenderDataAvailable.selector.ts +30 -0
  54. package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areDynamicSettingsAvailable.spec.ts +36 -0
  55. package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areDynamicSettingsAvailable.ts +10 -0
  56. package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areMetricsAvailable.spec.ts +13 -0
  57. package/app/codeCharta/state/selectors/allNecessaryRenderDataAvailable/utils/areMetricsAvailable.ts +8 -0
  58. package/app/codeCharta/state/store/appSettings/appSettings.actions.ts +2 -0
  59. package/app/codeCharta/state/store/appSettings/appSettings.reducer.ts +2 -0
  60. package/app/codeCharta/state/store/appSettings/invertArea/invertArea.actions.ts +32 -0
  61. package/app/codeCharta/state/store/appSettings/invertArea/invertArea.reducer.spec.ts +26 -0
  62. package/app/codeCharta/state/store/appSettings/invertArea/invertArea.reducer.ts +12 -0
  63. package/app/codeCharta/state/store/appSettings/invertArea/invertArea.selector.ts +3 -0
  64. package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.spec.ts +14 -3
  65. package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.ts +41 -6
  66. package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.actions.ts +33 -2
  67. package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.reducer.spec.ts +17 -1
  68. package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.reducer.ts +3 -1
  69. package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.service.spec.ts +1 -19
  70. package/app/codeCharta/state/store/fileSettings/blacklist/blacklist.service.ts +5 -28
  71. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.selector.ts +4 -0
  72. package/app/codeCharta/state/store/lookUp/lookUp.selector.ts +3 -0
  73. package/app/codeCharta/state/store/metricData/nodeMetricData/nodeMetricData.service.ts +0 -4
  74. package/app/codeCharta/state/store/store.ts +5 -1
  75. package/app/codeCharta/state/store.service.spec.ts +20 -7
  76. package/app/codeCharta/state/store.service.ts +3 -36
  77. package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.html +3 -1
  78. package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.scss +6 -2
  79. package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.component.ts +1 -1
  80. package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.module.ts +3 -0
  81. package/app/codeCharta/ui/areaSettingsPanel/areaSettingsPanel.po.ts +4 -4
  82. package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.html +1 -0
  83. package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.scss +26 -0
  84. package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.spec.ts +29 -0
  85. package/app/codeCharta/ui/areaSettingsPanel/invertAreaOption/invertAreaOption.component.ts +24 -0
  86. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/aggregationType.pipe.spec.ts +19 -0
  87. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/{aggregationSymbol.pipe.ts → aggregationType.pipe.ts} +4 -4
  88. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.html +4 -12
  89. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.scss +11 -20
  90. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.component.spec.ts +8 -15
  91. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/attributeTypeSelector.module.ts +2 -2
  92. package/app/codeCharta/ui/codeMap/codeMap.preRender.service.spec.ts +1 -9
  93. package/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts +9 -32
  94. package/app/codeCharta/ui/dialogs/dialogs.ts +3 -0
  95. package/app/codeCharta/ui/dialogs/errorDialog/errorDialog.component.html +7 -0
  96. package/app/codeCharta/ui/dialogs/errorDialog/errorDialog.component.ts +9 -0
  97. package/app/codeCharta/ui/mapTreeView/mapTreeView.level.e2e.ts +1 -1
  98. package/app/codeCharta/ui/mapTreeView/mapTreeView.level.po.ts +1 -1
  99. package/app/codeCharta/ui/ribbonBar/ribbonBar.component.html +2 -2
  100. package/app/codeCharta/ui/ribbonBar/ribbonBar.e2e.ts +3 -3
  101. package/app/codeCharta/ui/searchBar/searchBar.component.html +5 -0
  102. package/app/codeCharta/ui/searchBar/searchBar.component.scss +11 -0
  103. package/app/codeCharta/ui/searchBar/searchBar.component.spec.ts +10 -0
  104. package/app/codeCharta/ui/searchBar/searchBar.component.ts +1 -1
  105. package/app/codeCharta/ui/sortingOption/sortingOption.component.spec.ts +1 -1
  106. package/app/codeCharta/ui/ui.ts +0 -2
  107. package/app/codeCharta/util/algorithm/treeMapLayout/treeMapGenerator.spec.ts +1 -1
  108. package/app/codeCharta/util/algorithm/treeMapLayout/treeMapGenerator.ts +14 -7
  109. package/app/codeCharta/util/customConfigBuilder.ts +1 -0
  110. package/app/codeCharta/util/dataMocks.ts +2 -0
  111. package/app/codeCharta/util/reduxHelper.ts +11 -0
  112. package/app/material/material.module.ts +17 -1
  113. package/conf/webpack.loaders.js +4 -1
  114. package/dist/webpack/bundle.js +4582 -950
  115. package/dist/webpack/bundle.js.map +1 -1
  116. package/package.json +2 -2
  117. package/app/codeCharta/ui/attributeSideBar/attributeTypeSelector/aggregationSymbol.pipe.spec.ts +0 -19
  118. package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.ts +0 -29
  119. package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.spec.ts +0 -15
  120. package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.ts +0 -9
  121. package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.html +0 -45
  122. package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.spec.ts +0 -365
  123. package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.ts +0 -198
  124. package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.module.ts +0 -15
@@ -11,6 +11,8 @@ import { setMargin } from "./store/dynamicSettings/margin/margin.actions"
11
11
  import { setCamera } from "./store/appSettings/camera/camera.actions"
12
12
  import { setIsLoadingMap } from "./store/appSettings/isLoadingMap/isLoadingMap.actions"
13
13
  import { toggleSortingOrderAscending } from "./store/appSettings/sortingOrderAscending/sortingOrderAscending.actions"
14
+ import { EffectsModule } from "./angular-redux/effects/effects.module"
15
+ import { Subject } from "rxjs"
14
16
 
15
17
  describe("StoreService", () => {
16
18
  let storeService: StoreService
@@ -110,19 +112,30 @@ describe("StoreService", () => {
110
112
  expect($rootScope.$broadcast).not.toHaveBeenCalled()
111
113
  })
112
114
 
113
- it("should dispatch an action silently and not show the loading-gif", () => {
115
+ it("should show not the loading-gif when an action is triggered, that doesn't change the loading-gif state", () => {
114
116
  storeService.dispatch(setIsLoadingMap(false))
115
-
116
- storeService.dispatch(setCamera(), { silent: true })
117
+ storeService.dispatch(toggleSortingOrderAscending())
117
118
 
118
119
  expect(storeService.getState().appSettings.isLoadingMap).toBeFalsy()
119
120
  })
120
121
 
121
- it("should show not the loading-gif when an action is triggered, that doesn't change the loading-gif state", () => {
122
- storeService.dispatch(setIsLoadingMap(false))
123
- storeService.dispatch(toggleSortingOrderAscending())
122
+ describe("connection to action subject", () => {
123
+ beforeEach(() => {
124
+ EffectsModule.actions$ = new Subject()
125
+ })
124
126
 
125
- expect(storeService.getState().appSettings.isLoadingMap).toBeFalsy()
127
+ afterEach(() => {
128
+ EffectsModule.actions$.complete()
129
+ })
130
+
131
+ it("should trigger a new action value on dispatch", () => {
132
+ const subscription = jest.fn()
133
+ EffectsModule.actions$.subscribe(subscription)
134
+
135
+ storeService.dispatch({ type: "something" })
136
+
137
+ expect(subscription).toHaveBeenCalledWith({ type: "something" })
138
+ })
126
139
  })
127
140
  })
128
141
  })
@@ -1,20 +1,8 @@
1
1
  import { IRootScopeService } from "angular"
2
2
  import { splitStateActions } from "./store/state.splitter"
3
- import { IsLoadingMapActions, setIsLoadingMap } from "./store/appSettings/isLoadingMap/isLoadingMap.actions"
4
- import { IsLoadingFileActions } from "./store/appSettings/isLoadingFile/isLoadingFile.actions"
5
3
  import { CCAction, State } from "../codeCharta.model"
6
- import { SearchPanelModeActions } from "./store/appSettings/searchPanelMode/searchPanelMode.actions"
7
- import { isActionOfType } from "../util/reduxHelper"
8
- import { SortingOrderAscendingActions } from "./store/appSettings/sortingOrderAscending/sortingOrderAscending.actions"
9
- import { SortingOptionActions } from "./store/dynamicSettings/sortingOption/sortingOption.actions"
10
- import { IsAttributeSideBarVisibleActions } from "./store/appSettings/isAttributeSideBarVisible/isAttributeSideBarVisible.actions"
11
- import { PanelSelectionActions } from "./store/appSettings/panelSelection/panelSelection.actions"
12
- import { PresentationModeActions } from "./store/appSettings/isPresentationMode/isPresentationMode.actions"
13
- import { ExperimentalFeaturesEnabledActions } from "./store/appSettings/enableExperimentalFeatures/experimentalFeaturesEnabled.actions"
14
4
  import { Store } from "./store/store"
15
- import { ScreenshotToClipboardEnabledActions } from "./store/appSettings/enableClipboard/screenshotToClipboardEnabled.actions"
16
- import { HoveredBuildingPathActions } from "./store/appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
17
- import { unfocusAllNodes } from "./store/dynamicSettings/focusedNodePath/focusedNodePath.actions"
5
+ import { EffectsModule } from "./angular-redux/effects/effects.module"
18
6
 
19
7
  export interface StoreSubscriber {
20
8
  onStoreChanged(actionType: string)
@@ -47,29 +35,6 @@ export class StoreService {
47
35
  }
48
36
 
49
37
  dispatch(action: CCAction, options: DispatchOptions = { silent: false }) {
50
- if (
51
- !(
52
- isActionOfType(action.type, IsLoadingMapActions) ||
53
- isActionOfType(action.type, IsLoadingFileActions) ||
54
- isActionOfType(action.type, SortingOrderAscendingActions) ||
55
- isActionOfType(action.type, SearchPanelModeActions) ||
56
- isActionOfType(action.type, SortingOptionActions) ||
57
- isActionOfType(action.type, IsAttributeSideBarVisibleActions) ||
58
- isActionOfType(action.type, PanelSelectionActions) ||
59
- isActionOfType(action.type, PresentationModeActions) ||
60
- isActionOfType(action.type, ExperimentalFeaturesEnabledActions) ||
61
- isActionOfType(action.type, ScreenshotToClipboardEnabledActions) ||
62
- isActionOfType(action.type, HoveredBuildingPathActions) ||
63
- options.silent
64
- )
65
- ) {
66
- this.dispatch(setIsLoadingMap(true))
67
- }
68
-
69
- if (isActionOfType(action.type, IsLoadingFileActions)) {
70
- this.dispatch(unfocusAllNodes())
71
- }
72
-
73
38
  for (const atomicAction of splitStateActions(action)) {
74
39
  this.originalDispatch(atomicAction)
75
40
  if (!options.silent) {
@@ -77,6 +42,8 @@ export class StoreService {
77
42
  this.notifyExtended(atomicAction.type, atomicAction.payload)
78
43
  }
79
44
  }
45
+
46
+ EffectsModule.actions$.next(action)
80
47
  }
81
48
 
82
49
  getState(): State {
@@ -33,7 +33,7 @@
33
33
  ng-change="$ctrl.applyDynamicMargin()"
34
34
  title="Set margin to default (50px)."
35
35
  >
36
- Default margin (50px)
36
+ <span class="default-margin-text">Default margin (50px)</span>
37
37
  </md-checkbox>
38
38
  </md-input-container>
39
39
 
@@ -42,3 +42,5 @@
42
42
  tooltip="Reset area metric settings to their defaults"
43
43
  ></reset-settings-button-component>
44
44
  </div>
45
+
46
+ <cc-invert-area-option></cc-invert-area-option>
@@ -1,4 +1,4 @@
1
- area-settings-panel-component {
1
+ cc-area-settings-panel {
2
2
  background: white;
3
3
  border: 1px solid #b5b5b5;
4
4
  box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12);
@@ -16,6 +16,10 @@ area-settings-panel-component {
16
16
  top: 45px;
17
17
  right: 0;
18
18
 
19
+ .md-primary .md-label {
20
+ padding-top: 3px;
21
+ }
22
+
19
23
  md-slider-container {
20
24
  position: relative;
21
25
  .slider-title {
@@ -37,7 +41,7 @@ area-settings-panel-component {
37
41
  }
38
42
  }
39
43
 
40
- area-settings-panel-component.hidden {
44
+ cc-area-settings-panel.hidden {
41
45
  max-height: 0;
42
46
  opacity: 0;
43
47
  transition: max-height 200ms ease-in-out, opacity 0ms 200ms;
@@ -55,7 +55,7 @@ export class AreaSettingsPanelController implements FilesSelectionSubscriber, Dy
55
55
  }
56
56
 
57
57
  export const areaSettingsPanelComponent = {
58
- selector: "areaSettingsPanelComponent",
58
+ selector: "ccAreaSettingsPanel",
59
59
  template: require("./areaSettingsPanel.component.html"),
60
60
  controller: AreaSettingsPanelController
61
61
  }
@@ -1,7 +1,10 @@
1
1
  import "../../state/state.module"
2
2
  import angular from "angular"
3
3
  import { areaSettingsPanelComponent } from "./areaSettingsPanel.component"
4
+ import { downgradeComponent } from "@angular/upgrade/static"
5
+ import { InvertAreaOptionComponent } from "./invertAreaOption/invertAreaOption.component"
4
6
 
5
7
  angular
6
8
  .module("app.codeCharta.ui.areaSettingsPanel", ["app.codeCharta.state", "app.codeCharta.ui.codeMap"])
7
9
  .component(areaSettingsPanelComponent.selector, areaSettingsPanelComponent)
10
+ .directive("ccInvertAreaOption", downgradeComponent({ component: InvertAreaOptionComponent }))
@@ -2,21 +2,21 @@ import { clickButtonOnPageElement } from "../../../puppeteer.helper"
2
2
 
3
3
  export const AreaSettingsPanelPageObject = {
4
4
  async toggleDefaultMargin() {
5
- await clickButtonOnPageElement("area-settings-panel-component md-checkbox")
5
+ await clickButtonOnPageElement("cc-area-settings-panel md-checkbox")
6
6
  return this.isDefaultMarginEnabled()
7
7
  },
8
8
 
9
9
  async isDefaultMarginEnabled() {
10
- return page.$eval("area-settings-panel-component md-checkbox", element => element.className.includes("md-checked"))
10
+ return page.$eval("cc-area-settings-panel md-checkbox", element => element.className.includes("md-checked"))
11
11
  },
12
12
 
13
13
  async toggleMarginBoundingBox() {
14
- const marginToggleBoxHandle = await page.$("area-settings-panel-component md-checkbox .md-container")
14
+ const marginToggleBoxHandle = await page.$("cc-area-settings-panel md-checkbox .md-container")
15
15
  return marginToggleBoxHandle.boundingBox()
16
16
  },
17
17
 
18
18
  async resetButtonBoundingBox() {
19
- const resetBoxHandle = await page.$("area-settings-panel-component reset-settings-button-component")
19
+ const resetBoxHandle = await page.$("cc-area-settings-panel reset-settings-button-component")
20
20
  return resetBoxHandle.boundingBox()
21
21
  }
22
22
  }
@@ -0,0 +1 @@
1
+ <mat-checkbox class="invertAreaCheckbox" [checked]="isInvertedArea$ | async" (change)="toggleInvertingArea()">Invert Area</mat-checkbox>
@@ -0,0 +1,26 @@
1
+ cc-invert-area-option {
2
+ .mat-checkbox-layout {
3
+ padding-left: 4px;
4
+
5
+ .mat-checkbox-inner-container {
6
+ margin-right: 15px;
7
+ }
8
+ }
9
+
10
+ .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,
11
+ .mat-checkbox-checked.mat-accent .mat-checkbox-background,
12
+ .mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,
13
+ .mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element {
14
+ background-color: rgb(0, 150, 136);
15
+ }
16
+
17
+ .mat-checkbox-frame,
18
+ .mat-checkbox-background,
19
+ .mat-checkbox-anim-unchecked-checked .mat-checkbox-anim-checked-unchecked {
20
+ transform: scale(1.1);
21
+ }
22
+
23
+ mat-checkbox.invertAreaCheckbox .mat-checkbox-checkmark-path {
24
+ stroke: black !important;
25
+ }
26
+ }
@@ -0,0 +1,29 @@
1
+ import { Store } from "../../../state/store/store"
2
+ import { InvertAreaOptionComponent } from "./invertAreaOption.component"
3
+ import { fireEvent, render } from "@testing-library/angular"
4
+ import { TestBed } from "@angular/core/testing"
5
+ import { MaterialModule } from "../../../../material/material.module"
6
+ import { invertAreaSelector } from "../../../state/store/appSettings/invertArea/invertArea.selector"
7
+
8
+ describe("InvertAreaOptionComponent", () => {
9
+ beforeEach(() => {
10
+ Store["initialize"]()
11
+ TestBed.configureTestingModule({
12
+ imports: [MaterialModule]
13
+ })
14
+ })
15
+
16
+ it("should toggle inverting the area of buildings on click", async () => {
17
+ const { container } = await render(InvertAreaOptionComponent)
18
+ const isInvertedArea = invertAreaSelector(Store.store.getState())
19
+ const checkbox = container.querySelector("input")
20
+
21
+ expect(checkbox.checked).toBeFalsy()
22
+
23
+ fireEvent.click(checkbox)
24
+
25
+ expect(checkbox.checked).toBeTruthy()
26
+
27
+ expect(invertAreaSelector(Store.store.getState())).toBe(!isInvertedArea)
28
+ })
29
+ })
@@ -0,0 +1,24 @@
1
+ import "./invertAreaOption.component.scss"
2
+ import { Component, Inject, OnInit } from "@angular/core"
3
+ import { Store } from "../../../state/angular-redux/store"
4
+ import { invertAreaSelector } from "../../../state/store/appSettings/invertArea/invertArea.selector"
5
+ import { Observable } from "rxjs"
6
+ import { toggleInvertingArea } from "../../../state/store/appSettings/invertArea/invertArea.actions"
7
+
8
+ @Component({
9
+ selector: "cc-invert-area-option",
10
+ template: require("./invertAreaOption.component.html")
11
+ })
12
+ export class InvertAreaOptionComponent implements OnInit {
13
+ isInvertedArea$: Observable<boolean>
14
+
15
+ constructor(@Inject(Store) private store: Store) {}
16
+
17
+ ngOnInit(): void {
18
+ this.isInvertedArea$ = this.store.select(invertAreaSelector)
19
+ }
20
+
21
+ toggleInvertingArea() {
22
+ this.store.dispatch(toggleInvertingArea())
23
+ }
24
+ }
@@ -0,0 +1,19 @@
1
+ import { AttributeTypeValue } from "../../../codeCharta.model"
2
+ import { AggregationTypePipePipe } from "./aggregationType.pipe"
3
+
4
+ describe("aggregationSymbolPipe", () => {
5
+ it("should map `AttributeTypeValue.relative` to median", () => {
6
+ const getAttributeTypeOfNodesByMetricSelector = () => AttributeTypeValue.relative
7
+ expect(new AggregationTypePipePipe().transform("some-metric-name", getAttributeTypeOfNodesByMetricSelector)).toBe("median")
8
+ })
9
+
10
+ it("should map `AttributeTypeValue.absolute` to sum", () => {
11
+ const getAttributeTypeOfNodesByMetricSelector = () => AttributeTypeValue.absolute
12
+ expect(new AggregationTypePipePipe().transform("some-metric-name", getAttributeTypeOfNodesByMetricSelector)).toBe("sum")
13
+ })
14
+
15
+ it("should default to sum", () => {
16
+ const getAttributeTypeOfNodesByMetricSelector = () => "" as AttributeTypeValue
17
+ expect(new AggregationTypePipePipe().transform("some-metric-name", getAttributeTypeOfNodesByMetricSelector)).toBe("sum")
18
+ })
19
+ })
@@ -3,16 +3,16 @@ import { Pipe, PipeTransform } from "@angular/core"
3
3
  import { AttributeTypeValue } from "../../../codeCharta.model"
4
4
  import { GetAttributeTypeOfNodesByMetric } from "../../../state/selectors/getAttributeTypeOfNodesByMetric.selector"
5
5
 
6
- @Pipe({ name: "aggregationSymbolPipe" })
7
- export class AggregationSymbolPipe implements PipeTransform {
6
+ @Pipe({ name: "aggregationTypePipe" })
7
+ export class AggregationTypePipePipe implements PipeTransform {
8
8
  transform(metricName: string, getAttributeTypeOfNodesByMetricSelector: GetAttributeTypeOfNodesByMetric): string {
9
9
  const type = getAttributeTypeOfNodesByMetricSelector(metricName)
10
10
  switch (type) {
11
11
  case AttributeTypeValue.relative:
12
- return "x͂"
12
+ return "median"
13
13
  case AttributeTypeValue.absolute:
14
14
  default:
15
- return "Σ"
15
+ return "sum"
16
16
  }
17
17
  }
18
18
  }
@@ -1,12 +1,4 @@
1
- <div class="small-action-button transparent">
2
- <button mat-button [matMenuTriggerFor]="menu" title="Select attribute type" class="menu-button">
3
- <span class="symbol">{{ metricName | aggregationSymbolPipe: (getAttributeTypeOfNodesByMetric$ | async) }}</span>
4
- </button>
5
- </div>
6
-
7
- <mat-menu #menu>
8
- <div class="menu-header" mat-menu-item disabled>Set global aggregation for rloc</div>
9
- <mat-divider></mat-divider>
10
- <button mat-menu-item (click)="setToAbsolute()">Σ Sum</button>
11
- <button mat-menu-item (click)="setToRelative()">x͂ Median</button>
12
- </mat-menu>
1
+ <mat-button-toggle-group [value]="metricName | aggregationTypePipe: (getAttributeTypeOfNodesByMetric$ | async)">
2
+ <mat-button-toggle title="Select Sum" (click)="setToAbsolute()" value="sum">Σ</mat-button-toggle>
3
+ <mat-button-toggle title="Select Median" (click)="setToRelative()" value="median">x͂</mat-button-toggle>
4
+ </mat-button-toggle-group>
@@ -1,25 +1,16 @@
1
1
  cc-attribute-type-selector {
2
- display: inline-block;
3
- background-color: white;
4
- border-radius: 12px;
5
-
6
- .menu-button {
7
- height: 24px;
8
- width: 24px;
9
- min-width: 0;
10
- padding: 0;
11
- border-radius: 12px;
12
- vertical-align: top;
13
- transition: background-color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
2
+ .mat-button-toggle-group {
3
+ height: 18px;
4
+ align-items: center;
5
+ justify-content: space-evenly;
6
+ }
14
7
 
15
- &:hover {
16
- background-color: #c8c8c8;
17
- }
8
+ .mat-button-toggle-appearance-standard .mat-button-toggle-label-content {
9
+ padding: 0 7px 0 7px;
10
+ }
18
11
 
19
- .symbol {
20
- position: absolute;
21
- top: -5px;
22
- left: 8px;
23
- }
12
+ .mat-button-toggle-standalone.mat-button-toggle-appearance-standard,
13
+ .mat-button-toggle-group-appearance-standard {
14
+ border: 0.1px solid darkgrey;
24
15
  }
25
16
  }
@@ -1,5 +1,5 @@
1
1
  import { TestBed } from "@angular/core/testing"
2
- import { render, screen, fireEvent, waitForElementToBeRemoved } from "@testing-library/angular"
2
+ import { render, screen, fireEvent } from "@testing-library/angular"
3
3
 
4
4
  import { AttributeTypeSelectorModule } from "./attributeTypeSelector.module"
5
5
  import { Store } from "../../../state/store/store"
@@ -27,20 +27,12 @@ describe("attributeTypeSelector", () => {
27
27
  excludeComponentDeclaration: true
28
28
  })
29
29
 
30
- const initialDisplayedElement = await screen.findByText("Σ")
31
- expect(initialDisplayedElement).toBeTruthy()
30
+ const initialDisplayedElement = await screen.getByRole("button", { pressed: true })
31
+ expect(initialDisplayedElement.textContent).toBe("Σ")
32
32
 
33
- fireEvent.click(initialDisplayedElement)
34
- const medianMenuItem = await screen.findByText("x͂ Median")
35
- expect(medianMenuItem).toBeTruthy()
36
-
37
- fireEvent.click(medianMenuItem)
38
- await waitForElementToBeRemoved(() => {
39
- const medianMenuItem = screen.queryByText("x͂ Median")
40
- return medianMenuItem
41
- })
42
- const updatedDisplayedElement = await screen.findByText("x͂")
43
- expect(updatedDisplayedElement).toBeTruthy()
33
+ fireEvent.click(screen.getByText("x͂"))
34
+ const medianMenuItem = await screen.getByRole("button", { pressed: true })
35
+ expect(medianMenuItem.textContent).toBe("x͂")
44
36
  })
45
37
 
46
38
  it("should set aggregation symbol to absolute if attributeType is not available", async () => {
@@ -48,6 +40,7 @@ describe("attributeTypeSelector", () => {
48
40
  componentProperties: { metricName: "non-existing" },
49
41
  excludeComponentDeclaration: true
50
42
  })
51
- expect(await screen.findByText("Σ")).toBeTruthy()
43
+ const initialDisplayedElement = await screen.getByRole("button", { pressed: true })
44
+ expect(initialDisplayedElement.textContent).toBe("Σ")
52
45
  })
53
46
  })
@@ -3,11 +3,11 @@ import { CommonModule } from "@angular/common"
3
3
 
4
4
  import { AttributeTypeSelectorComponent } from "./attributeTypeSelector.component"
5
5
  import { MaterialModule } from "../../../../material/material.module"
6
- import { AggregationSymbolPipe } from "./aggregationSymbol.pipe"
6
+ import { AggregationTypePipePipe } from "./aggregationType.pipe"
7
7
 
8
8
  @NgModule({
9
9
  imports: [CommonModule, MaterialModule],
10
- declarations: [AttributeTypeSelectorComponent, AggregationSymbolPipe],
10
+ declarations: [AttributeTypeSelectorComponent, AggregationTypePipePipe],
11
11
  exports: [AttributeTypeSelectorComponent]
12
12
  })
13
13
  export class AttributeTypeSelectorModule {}
@@ -15,7 +15,6 @@ import { IsLoadingMapActions } from "../../state/store/appSettings/isLoadingMap/
15
15
  import { addFile, resetFiles, setDelta, setMultiple, setSingleByName } from "../../state/store/files/files.actions"
16
16
  import { addBlacklistItem, BlacklistActions, setBlacklist } from "../../state/store/fileSettings/blacklist/blacklist.actions"
17
17
  import { hierarchy } from "d3-hierarchy"
18
- import { NodeMetricDataService } from "../../state/store/metricData/nodeMetricData/nodeMetricData.service"
19
18
  import { MetricDataService } from "../../state/store/metricData/metricData.service"
20
19
  import { getCCFiles } from "../../model/files/files.helper"
21
20
  import { clone } from "../../util/clone"
@@ -29,7 +28,6 @@ describe("codeMapPreRenderService", () => {
29
28
  let codeMapPreRenderService: CodeMapPreRenderService
30
29
  let $rootScope: IRootScopeService
31
30
  let storeService: StoreService
32
- let nodeMetricDataService: NodeMetricDataService
33
31
  let codeMapRenderService: CodeMapRenderService
34
32
 
35
33
  let fileMeta: FileMeta
@@ -40,7 +38,6 @@ describe("codeMapPreRenderService", () => {
40
38
  rebuildService()
41
39
  withMockedEventMethods($rootScope)
42
40
  withMockedCodeMapRenderService()
43
- withMockedMetricService()
44
41
  withUnifiedMapAndFileMeta()
45
42
  storeService.dispatch(setDynamicSettings(STATE.dynamicSettings))
46
43
  })
@@ -50,7 +47,6 @@ describe("codeMapPreRenderService", () => {
50
47
 
51
48
  $rootScope = getService<IRootScopeService>("$rootScope")
52
49
  storeService = getService<StoreService>("storeService")
53
- nodeMetricDataService = getService<NodeMetricDataService>("nodeMetricDataService")
54
50
  codeMapRenderService = getService<CodeMapRenderService>("codeMapRenderService")
55
51
 
56
52
  fileMeta = clone(FILE_STATES[0].file.fileMeta)
@@ -73,7 +69,7 @@ describe("codeMapPreRenderService", () => {
73
69
  }
74
70
 
75
71
  function rebuildService() {
76
- codeMapPreRenderService = new CodeMapPreRenderService($rootScope, storeService, nodeMetricDataService, codeMapRenderService)
72
+ codeMapPreRenderService = new CodeMapPreRenderService($rootScope, storeService, codeMapRenderService)
77
73
  }
78
74
 
79
75
  function withMockedCodeMapRenderService() {
@@ -81,10 +77,6 @@ describe("codeMapPreRenderService", () => {
81
77
  codeMapRenderService.scaleMap = jest.fn()
82
78
  }
83
79
 
84
- function withMockedMetricService() {
85
- nodeMetricDataService.isMetricAvailable = jest.fn().mockReturnValue(true)
86
- }
87
-
88
80
  function withUnifiedMapAndFileMeta() {
89
81
  codeMapPreRenderService["unifiedMap"] = map
90
82
  codeMapPreRenderService["unifiedFileMeta"] = fileMeta
@@ -18,7 +18,6 @@ import { fileStatesAvailable } from "../../model/files/files.helper"
18
18
  import { PanelSelectionActions } from "../../state/store/appSettings/panelSelection/panelSelection.actions"
19
19
  import { PresentationModeActions } from "../../state/store/appSettings/isPresentationMode/isPresentationMode.actions"
20
20
  import { MetricDataService, MetricDataSubscriber } from "../../state/store/metricData/metricData.service"
21
- import { NodeMetricDataService } from "../../state/store/metricData/nodeMetricData/nodeMetricData.service"
22
21
  import { ExperimentalFeaturesEnabledActions } from "../../state/store/appSettings/enableExperimentalFeatures/experimentalFeaturesEnabled.actions"
23
22
  import { LayoutAlgorithmService, LayoutAlgorithmSubscriber } from "../../state/store/appSettings/layoutAlgorithm/layoutAlgorithm.service"
24
23
  import { trackEventUsageData, trackMapMetaData } from "../../util/usageDataTracker"
@@ -31,7 +30,8 @@ import { FocusedNodePathActions } from "../../state/store/dynamicSettings/focuse
31
30
  import { ColorRangeFromSubscriber, ColorRangeToSubscriber, RangeSliderController } from "../rangeSlider/rangeSlider.component"
32
31
  import { HoveredBuildingPathActions } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
33
32
  import { accumulatedDataSelector } from "../../state/selectors/accumulatedData/accumulatedData.selector"
34
- import { nodeMetricDataSelector } from "../../state/selectors/accumulatedData/metricData/nodeMetricData.selector"
33
+ import { areAllNecessaryRenderDataAvailableSelector } from "../../state/selectors/allNecessaryRenderDataAvailable/areAllNecessaryRenderDataAvailable.selector"
34
+ import { RightClickedNodeDataActions } from "../../state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions"
35
35
 
36
36
  export interface CodeMapPreRenderServiceSubscriber {
37
37
  onRenderMapChanged(map: CodeMapNode)
@@ -59,7 +59,6 @@ export class CodeMapPreRenderService
59
59
  constructor(
60
60
  private $rootScope: IRootScopeService,
61
61
  private storeService: StoreService,
62
- private nodeMetricDataService: NodeMetricDataService,
63
62
  private codeMapRenderService: CodeMapRenderService
64
63
  ) {
65
64
  "ngInject"
@@ -89,13 +88,7 @@ export class CodeMapPreRenderService
89
88
  }
90
89
 
91
90
  onStoreChanged(actionType: string) {
92
- if (isActionOfType(actionType, HoveredBuildingPathActions)) {
93
- // temporary hack:
94
- // this.debounceRendering() leads to a new MapMesh, which leads to a new render, which would revert hover
95
- // TODO We definitely need to improve this
96
- return
97
- }
98
-
91
+ // TODO: Get rid of this if else block. Why do we sometimes call this.debounceRendering() and sometimes this.codeMapRenderService.update()?
99
92
  if (
100
93
  this.allNecessaryRenderDataAvailable() &&
101
94
  !isActionOfType(actionType, ScalingActions) &&
@@ -107,7 +100,9 @@ export class CodeMapPreRenderService
107
100
  !isActionOfType(actionType, IsAttributeSideBarVisibleActions) &&
108
101
  !isActionOfType(actionType, PanelSelectionActions) &&
109
102
  !isActionOfType(actionType, PresentationModeActions) &&
110
- !isActionOfType(actionType, ExperimentalFeaturesEnabledActions)
103
+ !isActionOfType(actionType, ExperimentalFeaturesEnabledActions) &&
104
+ !isActionOfType(actionType, HoveredBuildingPathActions) &&
105
+ !isActionOfType(actionType, RightClickedNodeDataActions)
111
106
  ) {
112
107
  this.debounceRendering()
113
108
  this.debounceTracking(actionType)
@@ -175,30 +170,12 @@ export class CodeMapPreRenderService
175
170
  }
176
171
 
177
172
  private allNecessaryRenderDataAvailable() {
178
- return (
179
- nodeMetricDataSelector(this.storeService.getState()) !== null &&
180
- fileStatesAvailable(this.storeService.getState().files) &&
181
- this.areChosenMetricsInMetricData() &&
182
- Object.values(this.storeService.getState().dynamicSettings).every(x => {
183
- return x !== null && Object.values(x).every(v => v !== null)
184
- })
185
- )
186
- }
187
-
188
- private areChosenMetricsInMetricData() {
189
- const { dynamicSettings } = this.storeService.getState()
190
- return (
191
- this.nodeMetricDataService.isMetricAvailable(dynamicSettings.areaMetric) &&
192
- this.nodeMetricDataService.isMetricAvailable(dynamicSettings.colorMetric) &&
193
- this.nodeMetricDataService.isMetricAvailable(dynamicSettings.heightMetric)
194
- )
173
+ return areAllNecessaryRenderDataAvailableSelector(this.storeService.getState())
195
174
  }
196
175
 
197
176
  private removeLoadingGifs() {
198
- if (this.storeService.getState().appSettings.isLoadingFile) {
199
- this.storeService.dispatch(setIsLoadingFile(false))
200
- }
201
- this.storeService.dispatch(setIsLoadingMap(false))
177
+ if (this.storeService.getState().appSettings.isLoadingFile) this.storeService.dispatch(setIsLoadingFile(false))
178
+ if (this.storeService.getState().appSettings.isLoadingMap) this.storeService.dispatch(setIsLoadingMap(false))
202
179
  }
203
180
 
204
181
  private showLoadingMapGif() {
@@ -0,0 +1,3 @@
1
+ import { ErrorDialogComponent } from "./errorDialog/errorDialog.component"
2
+
3
+ export const dialogs = [ErrorDialogComponent]
@@ -0,0 +1,7 @@
1
+ <h1 mat-dialog-title>{{ data.title }}</h1>
2
+
3
+ <div mat-dialog-content>{{ data.message }}</div>
4
+
5
+ <div mat-dialog-actions align="end">
6
+ <button mat-button mat-dialog-close>OK</button>
7
+ </div>
@@ -0,0 +1,9 @@
1
+ import { Component, Inject } from "@angular/core"
2
+ import { MAT_DIALOG_DATA } from "@angular/material/dialog"
3
+
4
+ @Component({
5
+ template: require("./errorDialog.component.html")
6
+ })
7
+ export class ErrorDialogComponent {
8
+ constructor(@Inject(MAT_DIALOG_DATA) public data: { title: string; message: string }) {}
9
+ }
@@ -1,7 +1,7 @@
1
1
  import { goto } from "../../../puppeteer.helper"
2
2
  import { MapTreeViewLevelPageObject } from "./mapTreeView.level.po"
3
3
  import { SearchPanelModeSelectorPageObject } from "../searchPanelModeSelector/searchPanelModeSelector.po"
4
- import { NodeContextMenuPageObject } from "../nodeContextMenu/nodeContextMenu.po"
4
+ import { NodeContextMenuPageObject } from "../../state/effects/nodeContextMenu/nodeContextMenu.po"
5
5
 
6
6
  describe("MapTreeViewLevel", () => {
7
7
  let mapTreeViewLevel: MapTreeViewLevelPageObject
@@ -3,7 +3,7 @@ import { clickButtonOnPageElement } from "../../../puppeteer.helper"
3
3
  export class MapTreeViewLevelPageObject {
4
4
  async openContextMenu(path: string) {
5
5
  await clickButtonOnPageElement(`[id='${path}']`, { button: "right" })
6
- await page.waitForSelector("node-context-menu-component", { visible: true })
6
+ await page.waitForSelector("#codemap-context-menu", { visible: true })
7
7
  await page.waitForSelector(".tree-element-label.marked")
8
8
  }
9
9
 
@@ -45,11 +45,11 @@
45
45
  >Area Metric Options <i class="fa fa-angle-down"></i
46
46
  ></span>
47
47
  </div>
48
- <area-settings-panel-component
48
+ <cc-area-settings-panel
49
49
  ng-class="{
50
50
  hidden: $ctrl._viewModel.panelSelection !== $ctrl._viewModel.panelSelectionValues.AREA_PANEL_OPEN
51
51
  }"
52
- ></area-settings-panel-component>
52
+ ></cc-area-settings-panel>
53
53
  </md-card>
54
54
 
55
55
  <md-card