codecharta-visualization 1.87.1 → 1.88.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 +18 -8
- package/app/codeCharta/codeCharta.component.ts +2 -0
- package/app/codeCharta/codeCharta.model.ts +2 -0
- package/app/codeCharta/codeCharta.service.spec.ts +41 -50
- package/app/codeCharta/codeCharta.service.ts +33 -32
- package/app/codeCharta/e2e/url.e2e.ts +1 -1
- package/app/codeCharta/state/store/appStatus/appStatus.reducer.ts +3 -1
- package/app/codeCharta/state/store/appStatus/appStatus.selector.ts +3 -0
- package/app/codeCharta/state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions.ts +23 -0
- package/app/codeCharta/state/store/appStatus/rightClickedNodeData/rightClickedNodeData.reducer.ts +15 -0
- package/app/codeCharta/state/store/appStatus/rightClickedNodeData/rightClickedNodeData.selector.ts +4 -0
- package/app/codeCharta/state/store/state.actions.ts +3 -1
- package/app/codeCharta/ui/codeMap/codeMap.mouseEvent.service.ts +6 -8
- package/app/codeCharta/ui/customConfigs/customConfigs.component.html +9 -9
- package/app/codeCharta/ui/dialog/dialog.addCustomConfigSettings.component.html +2 -2
- package/app/codeCharta/ui/dialog/dialog.changelog.component.scss +15 -0
- package/app/codeCharta/ui/dialog/dialog.changelog.component.spec.ts +15 -15
- package/app/codeCharta/ui/dialog/dialog.changelog.component.ts +2 -1
- package/app/codeCharta/ui/dialog/dialog.service.spec.ts +68 -0
- package/app/codeCharta/ui/dialog/dialog.service.ts +38 -17
- package/app/codeCharta/ui/edgeChooser/edgeChooser.e2e.ts +3 -2
- package/app/codeCharta/ui/fileChooser/fileChooser.e2e.ts +5 -6
- package/app/codeCharta/ui/filePanel/filePanel.component.html +24 -106
- package/app/codeCharta/ui/filePanel/filePanel.component.scss +12 -57
- package/app/codeCharta/ui/filePanel/filePanel.component.spec.ts +40 -72
- package/app/codeCharta/ui/filePanel/filePanel.component.ts +29 -81
- package/app/codeCharta/ui/filePanel/filePanel.module.ts +13 -1
- package/app/codeCharta/ui/filePanel/filePanel.po.ts +6 -24
- package/app/codeCharta/ui/filePanel/filePanelDeltaSelector/filePanelDeltaSelector.component.html +23 -0
- package/app/codeCharta/ui/filePanel/filePanelDeltaSelector/filePanelDeltaSelector.component.ts +18 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.html +18 -0
- package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.ts +16 -0
- package/app/codeCharta/ui/filePanel/filePanelStateButtons/filePanelStateButtons.component.html +18 -0
- package/app/codeCharta/ui/filePanel/filePanelStateButtons/filePanelStateButtons.component.ts +11 -0
- package/app/codeCharta/ui/mapTreeView/mapTreeView.level.e2e.ts +7 -5
- package/app/codeCharta/ui/mapTreeView/mapTreeViewLevel/mapTreeViewLevel.component.html +1 -1
- package/app/codeCharta/ui/mapTreeView/mapTreeViewLevel/mapTreeViewLevel.component.spec.ts +6 -16
- package/app/codeCharta/ui/mapTreeView/mapTreeViewLevel/mapTreeViewLevel.component.ts +15 -11
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.component.html +22 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.component.scss +31 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.component.spec.ts +35 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.component.ts +30 -0
- package/app/codeCharta/ui/nodeContextMenu/{markFolderColorPicker/markFolderColorPicker.module.ts → markFolderRow/markFolderRow.module.ts} +4 -5
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.spec.ts +17 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/markFolderItems.selector.ts +29 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.spec.ts +15 -0
- package/app/codeCharta/ui/nodeContextMenu/markFolderRow/selectors/rightClickedNode.selector.ts +9 -0
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.html +2 -15
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.scss +0 -15
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.spec.ts +10 -119
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.ts +40 -134
- package/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.module.ts +2 -2
- package/app/codeCharta/ui/ribbonBar/ribbonBar.component.html +1 -1
- package/app/codeCharta/ui/toolBar/toolBar.component.html +1 -1
- package/app/codeCharta/ui/toolBar/toolBar.component.scss +1 -1
- package/app/codeCharta/ui/ui.ts +2 -2
- package/app/codeCharta/util/customConfigHelper.spec.ts +155 -60
- package/app/codeCharta/util/customConfigHelper.ts +33 -3
- package/app/codeCharta/util/dataMocks.ts +4 -2
- package/app/codeCharta/util/fileValidator.spec.ts +69 -182
- package/app/codeCharta/util/fileValidator.ts +61 -37
- package/dist/webpack/bundle.js +852 -485
- package/dist/webpack/bundle.js.map +1 -1
- package/package.json +1 -1
- package/app/codeCharta/ui/nodeContextMenu/markFolderColorPicker/markFolderColorPicker.component.html +0 -9
- package/app/codeCharta/ui/nodeContextMenu/markFolderColorPicker/markFolderColorPicker.component.scss +0 -13
- package/app/codeCharta/ui/nodeContextMenu/markFolderColorPicker/markFolderColorPicker.component.ts +0 -10
package/app/app.module.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { Inject, NgModule } from "@angular/core"
|
|
|
4
4
|
import { BrowserModule } from "@angular/platform-browser"
|
|
5
5
|
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"
|
|
6
6
|
import { UpgradeModule } from "@angular/upgrade/static"
|
|
7
|
-
|
|
7
|
+
import { FormsModule } from "@angular/forms"
|
|
8
|
+
import { MaterialModule } from "./material/material.module"
|
|
8
9
|
import { MapTreeViewModule } from "./codeCharta/ui/mapTreeView/mapTreeView.module"
|
|
9
10
|
import { MapTreeViewComponent } from "./codeCharta/ui/mapTreeView/mapTreeView.component"
|
|
10
11
|
import { MatchingFilesCounterComponent } from "./codeCharta/ui/matchingFilesCounter/matchingFilesCounter.component"
|
|
@@ -18,10 +19,13 @@ import { LegendPanelComponent } from "./codeCharta/ui/legendPanel/legendPanel.co
|
|
|
18
19
|
import { LegendPanelModule } from "./codeCharta/ui/legendPanel/legendPanel.module"
|
|
19
20
|
import { ColorPickerForMapColorModule } from "./codeCharta/ui/colorPickerForMapColor/colorPickerForMapColor.module"
|
|
20
21
|
import { ColorPickerForMapColorComponent } from "./codeCharta/ui/colorPickerForMapColor/colorPickerForMapColor.component"
|
|
21
|
-
import { MarkFolderColorPickerModule } from "./codeCharta/ui/nodeContextMenu/markFolderColorPicker/markFolderColorPicker.module"
|
|
22
|
-
import { MarkFolderColorPickerComponent } from "./codeCharta/ui/nodeContextMenu/markFolderColorPicker/markFolderColorPicker.component"
|
|
23
22
|
import { FocusButtonsModule } from "./codeCharta/ui/nodeContextMenu/focusButtons/focusButtons.module"
|
|
24
23
|
import { FocusButtonsComponent } from "./codeCharta/ui/nodeContextMenu/focusButtons/focusButtons.component"
|
|
24
|
+
import { FilePanelFileSelectorComponent } from "./codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component"
|
|
25
|
+
import { FilePanelStateButtonsComponent } from "./codeCharta/ui/filePanel/filePanelStateButtons/filePanelStateButtons.component"
|
|
26
|
+
import { FilePanelDeltaSelectorComponent } from "./codeCharta/ui/filePanel/filePanelDeltaSelector/filePanelDeltaSelector.component"
|
|
27
|
+
import { MarkFolderRowComponent } from "./codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.component"
|
|
28
|
+
import { MarkFolderRowModule } from "./codeCharta/ui/nodeContextMenu/markFolderRow/markFolderRow.module"
|
|
25
29
|
|
|
26
30
|
@NgModule({
|
|
27
31
|
imports: [
|
|
@@ -30,13 +34,15 @@ import { FocusButtonsComponent } from "./codeCharta/ui/nodeContextMenu/focusButt
|
|
|
30
34
|
MapTreeViewModule,
|
|
31
35
|
MatchingFilesCounterModule,
|
|
32
36
|
AttributeSideBarModule,
|
|
37
|
+
MaterialModule,
|
|
38
|
+
FormsModule,
|
|
33
39
|
Export3DMapButtonModule,
|
|
34
40
|
LegendPanelModule,
|
|
35
41
|
ColorPickerForMapColorModule,
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
FocusButtonsModule,
|
|
43
|
+
MarkFolderRowModule
|
|
38
44
|
],
|
|
39
|
-
declarations: [],
|
|
45
|
+
declarations: [FilePanelFileSelectorComponent, FilePanelStateButtonsComponent, FilePanelDeltaSelectorComponent],
|
|
40
46
|
entryComponents: [
|
|
41
47
|
MapTreeViewComponent,
|
|
42
48
|
MatchingFilesCounterComponent,
|
|
@@ -45,8 +51,12 @@ import { FocusButtonsComponent } from "./codeCharta/ui/nodeContextMenu/focusButt
|
|
|
45
51
|
LegendPanelComponent,
|
|
46
52
|
LabelledColorPickerComponent,
|
|
47
53
|
ColorPickerForMapColorComponent,
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
FocusButtonsComponent,
|
|
55
|
+
FilePanelFileSelectorComponent,
|
|
56
|
+
FilePanelStateButtonsComponent,
|
|
57
|
+
FilePanelDeltaSelectorComponent,
|
|
58
|
+
FocusButtonsComponent,
|
|
59
|
+
MarkFolderRowComponent
|
|
50
60
|
]
|
|
51
61
|
})
|
|
52
62
|
export class AppModule {
|
|
@@ -76,6 +76,8 @@ export class CodeChartaController {
|
|
|
76
76
|
this.codeChartaService.loadFiles(values)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
// TODO: Please make sure that this function works fine on Github pages with
|
|
80
|
+
// the updated file selection (no more single mode!)
|
|
79
81
|
private setRenderStateFromUrl() {
|
|
80
82
|
const renderState = this.urlUtils.getParameterByName("mode")
|
|
81
83
|
const files = getCCFiles(this.storeService.getState().files)
|
|
@@ -5,6 +5,7 @@ import { CodeMapBuilding } from "./ui/codeMap/rendering/codeMapBuilding"
|
|
|
5
5
|
import { FileState } from "./model/files/files"
|
|
6
6
|
import { CustomConfig } from "./model/customConfig/customConfig.api.model"
|
|
7
7
|
import Rectangle from "./util/algorithm/streetLayout/rectangle"
|
|
8
|
+
import { RightClickedNodeData } from "./state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions"
|
|
8
9
|
|
|
9
10
|
export interface NameDataPair {
|
|
10
11
|
fileName: string
|
|
@@ -404,6 +405,7 @@ export interface LookUp {
|
|
|
404
405
|
export interface AppStatus {
|
|
405
406
|
hoveredBuildingPath: string | null
|
|
406
407
|
selectedBuildingId: number | null
|
|
408
|
+
rightClickedNodeData: RightClickedNodeData
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
export enum PanelSelection {
|
|
@@ -6,9 +6,9 @@ import { BlacklistType, CCFile, NodeMetricData, NodeType } from "./codeCharta.mo
|
|
|
6
6
|
import { StoreService } from "./state/store.service"
|
|
7
7
|
import { removeFile, resetFiles } from "./state/store/files/files.actions"
|
|
8
8
|
import { ExportBlacklistType, ExportCCFile } from "./codeCharta.api.model"
|
|
9
|
-
import { getCCFiles,
|
|
9
|
+
import { getCCFiles, isPartialState } from "./model/files/files.helper"
|
|
10
10
|
import { DialogService } from "./ui/dialog/dialog.service"
|
|
11
|
-
import {
|
|
11
|
+
import { CCFileValidationResult, ERROR_MESSAGES } from "./util/fileValidator"
|
|
12
12
|
import packageJson from "../../package.json"
|
|
13
13
|
import { clone } from "./util/clone"
|
|
14
14
|
import { nodeMetricDataSelector } from "./state/selectors/accumulatedData/metricData/nodeMetricData.selector"
|
|
@@ -53,8 +53,7 @@ describe("codeChartaService", () => {
|
|
|
53
53
|
|
|
54
54
|
function withMockedDialogService() {
|
|
55
55
|
dialogService = codeChartaService["dialogService"] = jest.fn().mockReturnValue({
|
|
56
|
-
|
|
57
|
-
showValidationWarningDialog: jest.fn()
|
|
56
|
+
showValidationDialog: jest.fn()
|
|
58
57
|
})()
|
|
59
58
|
}
|
|
60
59
|
|
|
@@ -137,7 +136,7 @@ describe("codeChartaService", () => {
|
|
|
137
136
|
])
|
|
138
137
|
|
|
139
138
|
expect(getCCFiles(storeService.getState().files)[0]).toEqual(expected)
|
|
140
|
-
expect(
|
|
139
|
+
expect(isPartialState(storeService.getState().files)).toBeTruthy()
|
|
141
140
|
})
|
|
142
141
|
|
|
143
142
|
it("should load a valid file and update root data", async () => {
|
|
@@ -150,9 +149,8 @@ describe("codeChartaService", () => {
|
|
|
150
149
|
])
|
|
151
150
|
|
|
152
151
|
expect(getCCFiles(storeService.getState().files)[0]).toEqual(expected)
|
|
153
|
-
expect(
|
|
154
|
-
expect(dialogService.
|
|
155
|
-
expect(dialogService.showValidationErrorDialog).not.toHaveBeenCalled()
|
|
152
|
+
expect(isPartialState(storeService.getState().files)).toBeTruthy()
|
|
153
|
+
expect(dialogService.showValidationDialog).not.toHaveBeenCalled()
|
|
156
154
|
|
|
157
155
|
expect(CodeChartaService.ROOT_NAME).toEqual(expected.map.name)
|
|
158
156
|
expect(CodeChartaService.ROOT_PATH).toEqual(`/${expected.map.name}`)
|
|
@@ -253,7 +251,7 @@ describe("codeChartaService", () => {
|
|
|
253
251
|
await codeChartaService.loadFiles([{ fileName: "SecondFile", content: valid2ndFileContent, fileSize: 42 }])
|
|
254
252
|
|
|
255
253
|
expect(storeService.getState().files[0].selectedAs).toEqual("None")
|
|
256
|
-
expect(storeService.getState().files[1].selectedAs).toEqual("
|
|
254
|
+
expect(storeService.getState().files[1].selectedAs).toEqual("Partial")
|
|
257
255
|
})
|
|
258
256
|
|
|
259
257
|
it("should load the default scenario after loading a valid file", async () => {
|
|
@@ -287,41 +285,50 @@ describe("codeChartaService", () => {
|
|
|
287
285
|
})
|
|
288
286
|
|
|
289
287
|
it("should show error on invalid file", async () => {
|
|
290
|
-
const expectedError:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
288
|
+
const expectedError: CCFileValidationResult[] = [
|
|
289
|
+
{
|
|
290
|
+
fileName,
|
|
291
|
+
errors: [ERROR_MESSAGES.fileIsInvalid],
|
|
292
|
+
warnings: []
|
|
293
|
+
}
|
|
294
|
+
]
|
|
294
295
|
|
|
295
296
|
await codeChartaService.loadFiles([{ fileName, content: null, fileSize: 0 }])
|
|
296
297
|
|
|
297
298
|
expect(storeService.getState().files).toHaveLength(0)
|
|
298
|
-
expect(dialogService.
|
|
299
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledWith(expectedError)
|
|
299
300
|
})
|
|
300
301
|
|
|
301
302
|
it("should show error on a random string", async () => {
|
|
302
|
-
const expectedError:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
const expectedError: CCFileValidationResult[] = [
|
|
304
|
+
{
|
|
305
|
+
fileName,
|
|
306
|
+
errors: [ERROR_MESSAGES.apiVersionIsInvalid],
|
|
307
|
+
warnings: []
|
|
308
|
+
}
|
|
309
|
+
]
|
|
306
310
|
|
|
307
311
|
await codeChartaService.loadFiles([{ fileName, fileSize: 42, content: "string" as unknown as ExportCCFile }])
|
|
308
312
|
|
|
309
313
|
expect(storeService.getState().files).toHaveLength(0)
|
|
310
|
-
expect(dialogService.
|
|
314
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledWith(expectedError)
|
|
311
315
|
})
|
|
312
316
|
|
|
313
317
|
it("should show error if a file is missing a required property", async () => {
|
|
314
|
-
const expectedError:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
const expectedError: CCFileValidationResult[] = [
|
|
319
|
+
{
|
|
320
|
+
fileName,
|
|
321
|
+
errors: ["Required error: should have required property 'projectName'"],
|
|
322
|
+
warnings: []
|
|
323
|
+
}
|
|
324
|
+
]
|
|
318
325
|
|
|
319
326
|
const invalidFileContent = validFileContent
|
|
320
327
|
delete invalidFileContent.projectName
|
|
321
328
|
await codeChartaService.loadFiles([{ fileName, fileSize: 42, content: invalidFileContent }])
|
|
322
329
|
|
|
323
330
|
expect(storeService.getState().files).toHaveLength(0)
|
|
324
|
-
expect(dialogService.
|
|
331
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledWith(expectedError)
|
|
325
332
|
})
|
|
326
333
|
|
|
327
334
|
it("should convert old blacklist type", async () => {
|
|
@@ -339,46 +346,30 @@ describe("codeChartaService", () => {
|
|
|
339
346
|
expect(getCCFiles(storeService.getState().files)[0].settings.fileSettings.blacklist).toEqual(blacklist)
|
|
340
347
|
})
|
|
341
348
|
|
|
342
|
-
it("should break the loop after the first invalid file was validated", async () => {
|
|
343
|
-
const expectedError: CCValidationResult = {
|
|
344
|
-
error: ["Required error: should have required property 'projectName'"],
|
|
345
|
-
warning: []
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const invalidFileContent = validFileContent
|
|
349
|
-
delete invalidFileContent.projectName
|
|
350
|
-
|
|
351
|
-
await codeChartaService.loadFiles([
|
|
352
|
-
{ fileName, content: invalidFileContent, fileSize: 42 },
|
|
353
|
-
{ fileName, content: invalidFileContent, fileSize: 42 }
|
|
354
|
-
])
|
|
355
|
-
|
|
356
|
-
expect(dialogService.showValidationErrorDialog).toHaveBeenCalledTimes(1)
|
|
357
|
-
expect(dialogService.showValidationErrorDialog).toHaveBeenCalledWith(expectedError)
|
|
358
|
-
})
|
|
359
|
-
|
|
360
349
|
it("should not show a validation error if filenames are duplicated when their path is different", async () => {
|
|
361
350
|
validFileContent.nodes[0].children[0].name = "duplicate"
|
|
362
351
|
validFileContent.nodes[0].children[1].children[0].name = "duplicate"
|
|
363
352
|
|
|
364
353
|
await codeChartaService.loadFiles([{ fileName, content: validFileContent, fileSize: 42 }])
|
|
365
354
|
|
|
366
|
-
expect(dialogService.
|
|
355
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledTimes(0)
|
|
367
356
|
expect(storeService.getState().files).toHaveLength(1)
|
|
368
357
|
})
|
|
369
358
|
|
|
370
359
|
it("should show a validation error if two files in a folder have the same name", async () => {
|
|
371
360
|
validFileContent.nodes[0].children[1].children[0].name = "duplicate"
|
|
372
361
|
validFileContent.nodes[0].children[1].children[1].name = "duplicate"
|
|
373
|
-
const expectedError:
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
362
|
+
const expectedError: CCFileValidationResult[] = [
|
|
363
|
+
{
|
|
364
|
+
fileName,
|
|
365
|
+
errors: [`${ERROR_MESSAGES.nodesNotUnique} Found duplicate of File with path: /root/Parent Leaf/duplicate`],
|
|
366
|
+
warnings: []
|
|
367
|
+
}
|
|
368
|
+
]
|
|
377
369
|
|
|
378
370
|
await codeChartaService.loadFiles([{ fileName, content: validFileContent, fileSize: 42 }])
|
|
379
371
|
|
|
380
|
-
expect(dialogService.
|
|
381
|
-
expect(dialogService.showValidationErrorDialog).toHaveBeenCalledWith(expectedError)
|
|
372
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledWith(expectedError)
|
|
382
373
|
})
|
|
383
374
|
|
|
384
375
|
it("should not show a validation error if two files in a folder have the same name but different type", async () => {
|
|
@@ -389,7 +380,7 @@ describe("codeChartaService", () => {
|
|
|
389
380
|
|
|
390
381
|
await codeChartaService.loadFiles([{ fileName, content: validFileContent, fileSize: 42 }])
|
|
391
382
|
|
|
392
|
-
expect(dialogService.
|
|
383
|
+
expect(dialogService.showValidationDialog).toHaveBeenCalledTimes(0)
|
|
393
384
|
expect(storeService.getState().files).toHaveLength(1)
|
|
394
385
|
})
|
|
395
386
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CCFileValidationResult, checkErrors, checkWarnings } from "./util/fileValidator"
|
|
2
2
|
import { NodeDecorator } from "./util/nodeDecorator"
|
|
3
3
|
import { StoreService } from "./state/store.service"
|
|
4
|
-
import { setFiles,
|
|
4
|
+
import { setFiles, setMultipleByNames } from "./state/store/files/files.actions"
|
|
5
5
|
import { DialogService } from "./ui/dialog/dialog.service"
|
|
6
6
|
import { setState } from "./state/store/state.actions"
|
|
7
7
|
import { ScenarioHelper } from "./util/scenarioHelper"
|
|
@@ -25,41 +25,46 @@ export class CodeChartaService {
|
|
|
25
25
|
|
|
26
26
|
async loadFiles(nameDataPairs: NameDataPair[]) {
|
|
27
27
|
this.fileStates = this.storeService.getState().files
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (error.error.length > 0) {
|
|
34
|
-
this.fileStates = []
|
|
35
|
-
this.recentFiles = []
|
|
36
|
-
this.storeService.dispatch(setIsLoadingFile(false))
|
|
37
|
-
await this.dialogService.showValidationErrorDialog(error)
|
|
38
|
-
break
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (error.warning.length > 0) {
|
|
42
|
-
this.addFile(nameDataPair)
|
|
43
|
-
this.addRecentFile(nameDataPair.fileName)
|
|
44
|
-
this.storeService.dispatch(setIsLoadingFile(false))
|
|
45
|
-
await this.dialogService.showValidationWarningDialog(error)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
28
|
+
const fileValidationResults: CCFileValidationResult[] = []
|
|
29
|
+
|
|
30
|
+
this.getValidationResults(nameDataPairs, fileValidationResults)
|
|
31
|
+
|
|
32
|
+
this.storeService.dispatch(setIsLoadingFile(false))
|
|
49
33
|
|
|
50
|
-
if (
|
|
34
|
+
if (fileValidationResults.length > 0) await this.dialogService.showValidationDialog(fileValidationResults)
|
|
35
|
+
|
|
36
|
+
if (this.recentFiles.length > 0) {
|
|
51
37
|
this.storeService.dispatch(setRecentFiles(this.recentFiles))
|
|
52
38
|
this.storeService.dispatch(setFiles(this.fileStates))
|
|
53
39
|
|
|
54
|
-
this.fileStates = []
|
|
55
|
-
this.recentFiles = []
|
|
56
|
-
|
|
57
40
|
const recentFile = this.storeService.getState().dynamicSettings.recentFiles[0]
|
|
58
41
|
const rootName = this.storeService.getState().files.find(f => f.file.fileMeta.fileName === recentFile).file.map.name
|
|
59
|
-
this.storeService.dispatch(
|
|
42
|
+
this.storeService.dispatch(setMultipleByNames(this.recentFiles))
|
|
60
43
|
|
|
61
44
|
CodeChartaService.updateRootData(rootName)
|
|
62
45
|
this.setDefaultScenario()
|
|
46
|
+
|
|
47
|
+
this.fileStates = []
|
|
48
|
+
this.recentFiles = []
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private getValidationResults(nameDataPairs: NameDataPair[], fileValidationResults: CCFileValidationResult[]) {
|
|
53
|
+
for (const nameDataPair of nameDataPairs) {
|
|
54
|
+
const fileValidationResult: CCFileValidationResult = {
|
|
55
|
+
fileName: nameDataPair?.fileName,
|
|
56
|
+
errors: [],
|
|
57
|
+
warnings: []
|
|
58
|
+
}
|
|
59
|
+
fileValidationResult.errors.push(...checkErrors(nameDataPair?.content))
|
|
60
|
+
|
|
61
|
+
if (fileValidationResult.errors.length === 0) {
|
|
62
|
+
fileValidationResult.warnings.push(...checkWarnings(nameDataPair?.content))
|
|
63
|
+
this.addFile(nameDataPair)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (fileValidationResult.errors.length > 0 || fileValidationResult.warnings.length > 0)
|
|
67
|
+
fileValidationResults.push(fileValidationResult)
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -129,8 +134,4 @@ export class CodeChartaService {
|
|
|
129
134
|
CodeChartaService.ROOT_NAME = rootName
|
|
130
135
|
CodeChartaService.ROOT_PATH = `/${CodeChartaService.ROOT_NAME}`
|
|
131
136
|
}
|
|
132
|
-
|
|
133
|
-
private addRecentFile(fileName: string) {
|
|
134
|
-
this.recentFiles.push(fileName)
|
|
135
|
-
}
|
|
136
137
|
}
|
|
@@ -63,7 +63,7 @@ describe("codecharta", () => {
|
|
|
63
63
|
it("should throw errors when file parameters in url are invalid and load sample data instead", async () => {
|
|
64
64
|
await goto(`${CC_URL}?file=invalid234`)
|
|
65
65
|
await handleErrorDialog()
|
|
66
|
-
await checkSelectedFileName("sample1.cc.json")
|
|
66
|
+
await checkSelectedFileName("sample1.cc.json, sample2.cc.json")
|
|
67
67
|
await checkAllFileNames(["sample1.cc.json", "sample2.cc.json"])
|
|
68
68
|
})
|
|
69
69
|
})
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { combineReducers } from "redux"
|
|
2
2
|
|
|
3
3
|
import { hoveredBuildingPath } from "./hoveredBuildingPath/hoveredBuildingPath.reducer"
|
|
4
|
+
import { rightClickedNodeData } from "./rightClickedNodeData/rightClickedNodeData.reducer"
|
|
4
5
|
import { selectedBuildingId } from "./selectedBuildingId/selectedBuildingId.reducer"
|
|
5
6
|
|
|
6
7
|
const appStatus = combineReducers({
|
|
7
8
|
hoveredBuildingPath,
|
|
8
|
-
selectedBuildingId
|
|
9
|
+
selectedBuildingId,
|
|
10
|
+
rightClickedNodeData
|
|
9
11
|
})
|
|
10
12
|
|
|
11
13
|
export default appStatus
|
package/app/codeCharta/state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Action } from "redux"
|
|
2
|
+
|
|
3
|
+
export enum RightClickedNodeDataActions {
|
|
4
|
+
SET_RIGHT_CLICKED_NODE_DATA = "SET_RIGHT_CLICKED_NODE_DATA"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type RightClickedNodeData = {
|
|
8
|
+
nodeId: number
|
|
9
|
+
xPositionOfRightClickEvent: number
|
|
10
|
+
yPositionOfRightClickEvent: number
|
|
11
|
+
} | null
|
|
12
|
+
|
|
13
|
+
export interface SetRightClickedNodeDataAction extends Action {
|
|
14
|
+
type: RightClickedNodeDataActions.SET_RIGHT_CLICKED_NODE_DATA
|
|
15
|
+
payload: RightClickedNodeData
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const defaultRightClickedNodeData: RightClickedNodeData = null
|
|
19
|
+
|
|
20
|
+
export const setRightClickedNodeData = (payload: RightClickedNodeData): SetRightClickedNodeDataAction => ({
|
|
21
|
+
type: RightClickedNodeDataActions.SET_RIGHT_CLICKED_NODE_DATA,
|
|
22
|
+
payload
|
|
23
|
+
})
|
package/app/codeCharta/state/store/appStatus/rightClickedNodeData/rightClickedNodeData.reducer.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultRightClickedNodeData,
|
|
3
|
+
RightClickedNodeData,
|
|
4
|
+
RightClickedNodeDataActions,
|
|
5
|
+
SetRightClickedNodeDataAction
|
|
6
|
+
} from "./rightClickedNodeData.actions"
|
|
7
|
+
|
|
8
|
+
export const rightClickedNodeData = (state: RightClickedNodeData = defaultRightClickedNodeData, action: SetRightClickedNodeDataAction) => {
|
|
9
|
+
switch (action.type) {
|
|
10
|
+
case RightClickedNodeDataActions.SET_RIGHT_CLICKED_NODE_DATA:
|
|
11
|
+
return action.payload
|
|
12
|
+
default:
|
|
13
|
+
return state
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -8,6 +8,7 @@ import { defaultTreeMapSettings } from "./treeMap/treeMap.actions"
|
|
|
8
8
|
import { defaultFiles } from "./files/files.actions"
|
|
9
9
|
import { defaultHoveredBuildingPath } from "./appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
|
|
10
10
|
import { defaultSelectedBuildingId } from "./appStatus/selectedBuildingId/selectedBuildingId.actions"
|
|
11
|
+
import { defaultRightClickedNodeData } from "./appStatus/rightClickedNodeData/rightClickedNodeData.actions"
|
|
11
12
|
|
|
12
13
|
export enum StateActions {
|
|
13
14
|
SET_STATE = "SET_STATE"
|
|
@@ -36,6 +37,7 @@ export const defaultState: State = {
|
|
|
36
37
|
files: defaultFiles,
|
|
37
38
|
appStatus: {
|
|
38
39
|
hoveredBuildingPath: defaultHoveredBuildingPath,
|
|
39
|
-
selectedBuildingId: defaultSelectedBuildingId
|
|
40
|
+
selectedBuildingId: defaultSelectedBuildingId,
|
|
41
|
+
rightClickedNodeData: defaultRightClickedNodeData
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -18,7 +18,7 @@ import { CodeMapPreRenderService } from "./codeMap.preRender.service"
|
|
|
18
18
|
import { ThreeViewerService } from "./threeViewer/threeViewerService"
|
|
19
19
|
import { setHoveredBuildingPath } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
|
|
20
20
|
import { hoveredBuildingPathSelector } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.selector"
|
|
21
|
-
import
|
|
21
|
+
import { setRightClickedNodeData } from "../../state/store/appStatus/rightClickedNodeData/rightClickedNodeData.actions"
|
|
22
22
|
|
|
23
23
|
interface Coordinates {
|
|
24
24
|
x: number
|
|
@@ -355,13 +355,11 @@ export class CodeMapMouseEventService implements ViewCubeEventPropagationSubscri
|
|
|
355
355
|
// Check if mouse moved to prevent the node context menu to show up
|
|
356
356
|
// after moving the map, when the cursor ends on a building.
|
|
357
357
|
if (building && !this.hasMouseMovedMoreThanThreePixels(this.mouseOnLastClick)) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
y: this.mouse.y
|
|
364
|
-
}
|
|
358
|
+
this.storeService.dispatch(
|
|
359
|
+
setRightClickedNodeData({
|
|
360
|
+
nodeId: building.node.id,
|
|
361
|
+
xPositionOfRightClickEvent: this.mouse.x,
|
|
362
|
+
yPositionOfRightClickEvent: this.mouse.y
|
|
365
363
|
})
|
|
366
364
|
)
|
|
367
365
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<div class="custom-configs">
|
|
2
2
|
<md-menu class="custom-configs-component">
|
|
3
|
-
<md-button class="custom-configs-button" ng-click="$ctrl.initView(); $mdMenu.open($event);" title="Open your saved Custom
|
|
3
|
+
<md-button class="custom-configs-button" ng-click="$ctrl.initView(); $mdMenu.open($event);" title="Open your saved Custom Views">
|
|
4
4
|
<i class="fa fa-cogs"></i>
|
|
5
5
|
</md-button>
|
|
6
6
|
|
|
7
7
|
<md-menu-content class="custom-configs-drop-down" width="7">
|
|
8
8
|
<md-menu-item class="custom-configs-item">
|
|
9
|
-
<md-button class="custom-configs-dialog-name" ng-disabled="true">Custom
|
|
9
|
+
<md-button class="custom-configs-dialog-name" ng-disabled="true">Custom Views</md-button>
|
|
10
10
|
|
|
11
11
|
<md-button
|
|
12
12
|
class="action-button"
|
|
13
13
|
onclick="document.getElementById('input-file-id').click()"
|
|
14
|
-
title="Upload Custom
|
|
14
|
+
title="Upload Custom View (.cc.config.json file)."
|
|
15
15
|
>
|
|
16
16
|
<i class="fa fa-folder-open" aria-hidden="true"></i>
|
|
17
17
|
</md-button>
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
ng-click="$ctrl.downloadPreloadedCustomConfigs()"
|
|
20
20
|
ng-disabled="!$ctrl._viewModel.hasDownloadableConfigs"
|
|
21
21
|
class="action-button"
|
|
22
|
-
title="Download Custom
|
|
22
|
+
title="Download Custom View related to currently uploaded maps, if any."
|
|
23
23
|
>
|
|
24
24
|
<i class="fa fa-download" aria-hidden="true"></i>
|
|
25
25
|
</md-button>
|
|
26
|
-
<md-button ng-click="$ctrl.showAddCustomConfigSettings()" class="action-button" title="Create new Custom
|
|
26
|
+
<md-button ng-click="$ctrl.showAddCustomConfigSettings()" class="action-button" title="Create new Custom View">
|
|
27
27
|
<i class="fa fa-plus" aria-hidden="true"></i>
|
|
28
28
|
</md-button>
|
|
29
29
|
</md-menu-item>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<md-divider></md-divider>
|
|
32
32
|
|
|
33
33
|
<md-menu-item ng-if="!$ctrl._viewModel.dropDownCustomConfigItemGroups.length" class="custom-configs-item">
|
|
34
|
-
<md-button disabled>It is time to add your first
|
|
34
|
+
<md-button disabled>It is time to add your first Custom View.</md-button>
|
|
35
35
|
</md-menu-item>
|
|
36
36
|
|
|
37
37
|
<md-menu-item
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
md-prevent-menu-close="md-prevent-menu-close"
|
|
47
47
|
>
|
|
48
48
|
<span class="collapse-trigger">
|
|
49
|
-
Custom
|
|
49
|
+
Custom View(s) in <strong>{{ customConfigItemGroup.mapSelectionMode | lowercase }}</strong> mode for
|
|
50
50
|
<strong>{{ customConfigItemGroup.mapNames }}</strong>
|
|
51
51
|
</span>
|
|
52
52
|
<i ng-show="!collapsed" class="collapse-icon fa fa-arrow-down"></i>
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
ng-click="$ctrl.toggleNonApplicableItems();"
|
|
89
89
|
md-prevent-menu-close="md-prevent-menu-close"
|
|
90
90
|
>
|
|
91
|
-
{{ $ctrl.isExpanded() ? "Hide non-applicable
|
|
91
|
+
{{ $ctrl.isExpanded() ? "Hide non-applicable Custom Views" : "Show non-applicable Custom Views" }}
|
|
92
92
|
<i ng-class="$ctrl.isExpanded() ? 'fa fa-angle-up' : 'fa fa-angle-down'"></i>
|
|
93
93
|
</button>
|
|
94
94
|
</md-menu-content>
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
<md-button
|
|
99
99
|
class="custom-configs-button plus"
|
|
100
100
|
ng-click="$ctrl.showAddCustomConfigSettings();"
|
|
101
|
-
title="Quick save current view as a Custom
|
|
101
|
+
title="Quick save current view as a Custom View"
|
|
102
102
|
>
|
|
103
103
|
<i class="fa fa-plus"></i>
|
|
104
104
|
</md-button>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<md-dialog class="custom-config-dialog">
|
|
2
2
|
<md-toolbar>
|
|
3
3
|
<div class="md-toolbar-tools">
|
|
4
|
-
<h2>Add Custom
|
|
4
|
+
<h2>Add Custom View</h2>
|
|
5
5
|
</div>
|
|
6
6
|
</md-toolbar>
|
|
7
7
|
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<md-button
|
|
35
35
|
ng-click="$ctrl.showPurgeConfirmDialog()"
|
|
36
36
|
class="md-warn"
|
|
37
|
-
title="Download old unused
|
|
37
|
+
title="Download old unused Custom Views as a backup file and then delete them in the browser."
|
|
38
38
|
>Download & Purge ...</md-button
|
|
39
39
|
>
|
|
40
40
|
</span>
|
|
@@ -33,11 +33,11 @@ describe("DialogChangelogController", () => {
|
|
|
33
33
|
expect(dialogChangelogController["_viewModel"].changes).not.toBeNull()
|
|
34
34
|
expect(dialogChangelogController["_viewModel"].changes[added]).toBeUndefined()
|
|
35
35
|
expect(dialogChangelogController["_viewModel"].changes[fixed]).toBe(
|
|
36
|
-
'<li>3 (<a href="">#3</a>)</li>\n' + '<li>4 (<a href="">#4</a>)</li>\n' + '<li>5 (<a href="">#5</a>)</li>'
|
|
36
|
+
'<li>3 (<a href="">#3</a>)</li><br>\n' + '<li>4 (<a href="">#4</a>)</li><br>\n' + '<li>5 (<a href="">#5</a>)</li><br>'
|
|
37
37
|
)
|
|
38
38
|
expect(dialogChangelogController["_viewModel"].changes[removed]).toBeUndefined()
|
|
39
39
|
expect(dialogChangelogController["_viewModel"].changes[changed]).toBeUndefined()
|
|
40
|
-
expect(dialogChangelogController["_viewModel"].changes[chore]).toBe('<li>6 (<a href="">#6</a>)</li>')
|
|
40
|
+
expect(dialogChangelogController["_viewModel"].changes[chore]).toBe('<li>6 (<a href="">#6</a>)</li><br>')
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
it("should extract the changes from changelog for 2 versions", () => {
|
|
@@ -47,24 +47,24 @@ describe("DialogChangelogController", () => {
|
|
|
47
47
|
|
|
48
48
|
expect(dialogChangelogController["_viewModel"].changes).not.toBeNull()
|
|
49
49
|
expect(dialogChangelogController["_viewModel"].changes[added]).toBe(
|
|
50
|
-
'<li>7 (<a href="">#7</a>)</li>\n' + '<li>8 (<a href="">#8</a>)</li>'
|
|
50
|
+
'<li>7 (<a href="">#7</a>)</li><br>\n' + '<li>8 (<a href="">#8</a>)</li><br>'
|
|
51
51
|
)
|
|
52
52
|
expect(dialogChangelogController["_viewModel"].changes[fixed]).toBe(
|
|
53
|
-
'<li>3 (<a href="">#3</a>)</li>\n' + '<li>4 (<a href="">#4</a>)</li>\n' + '<li>5 (<a href="">#5</a>)</li>'
|
|
53
|
+
'<li>3 (<a href="">#3</a>)</li><br>\n' + '<li>4 (<a href="">#4</a>)</li><br>\n' + '<li>5 (<a href="">#5</a>)</li><br>'
|
|
54
54
|
)
|
|
55
|
-
expect(dialogChangelogController["_viewModel"].changes[chore]).toBe('<li>6 (<a href="">#6</a>)</li>')
|
|
55
|
+
expect(dialogChangelogController["_viewModel"].changes[chore]).toBe('<li>6 (<a href="">#6</a>)</li><br>')
|
|
56
56
|
// Expect nested list to be correctly parsed
|
|
57
57
|
expect(dialogChangelogController["_viewModel"].changes[changed]).toBe(
|
|
58
|
-
"<li>\n" +
|
|
59
|
-
'<p>9 (<a href="">#9</a>)</p>\n' +
|
|
60
|
-
"</li>\n" +
|
|
61
|
-
"<li>\n" +
|
|
62
|
-
'<p>10 (<a href="">#10</a>)</p>\n' +
|
|
63
|
-
"<ul>\n" +
|
|
64
|
-
"<li>10.1</li>\n" +
|
|
65
|
-
"<li>10.2</li>\n" +
|
|
66
|
-
"</ul>\n" +
|
|
67
|
-
"</li>"
|
|
58
|
+
"<li><br>\n" +
|
|
59
|
+
'<p>9 (<a href="">#9</a>)</p><br>\n' +
|
|
60
|
+
"</li><br>\n" +
|
|
61
|
+
"<li><br>\n" +
|
|
62
|
+
'<p>10 (<a href="">#10</a>)</p><br>\n' +
|
|
63
|
+
"<ul><br>\n" +
|
|
64
|
+
"<li>10.1</li><br>\n" +
|
|
65
|
+
"<li>10.2</li><br>\n" +
|
|
66
|
+
"</ul><br>\n" +
|
|
67
|
+
"</li><br>"
|
|
68
68
|
)
|
|
69
69
|
expect(dialogChangelogController["_viewModel"].changes[removed]).toBeUndefined()
|
|
70
70
|
})
|