Skip to content

Commit 6d3cf01

Browse files
authored
Fix/modular element not found (#139)
* Fix notification error message after loading external reference see #135
1 parent 2afbb1d commit 6d3cf01

File tree

10 files changed

+121
-77
lines changed

10 files changed

+121
-77
lines changed

core/apps/ame/src/app/startup.service.ts

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
* SPDX-License-Identifier: MPL-2.0
1212
*/
1313

14-
import {NamespacesCacheService} from '@ame/cache';
15-
import {EditorService, FileHandlingService, ShapeSettingsService} from '@ame/editor';
16-
import {BaseMetaModelElement} from '@ame/meta-model';
14+
import {EditorService, FileHandlingService} from '@ame/editor';
1715
import {MigratorService} from '@ame/migrator';
1816
import {MxGraphService} from '@ame/mx-graph';
1917
import {
@@ -24,9 +22,9 @@ import {
2422
ModelSavingTrackerService,
2523
StartupPayload,
2624
} from '@ame/shared';
27-
import {Injectable, NgZone, inject} from '@angular/core';
25+
import {inject, Injectable, NgZone} from '@angular/core';
2826
import {NavigationEnd, Router} from '@angular/router';
29-
import {Observable, filter, of, sample, switchMap, take, tap} from 'rxjs';
27+
import {filter, Observable, of, sample, switchMap, take, tap} from 'rxjs';
3028
import {SidebarStateService} from '@ame/sidebar';
3129
import {LanguageTranslationService} from '@ame/translation';
3230

@@ -42,8 +40,6 @@ export class StartupService {
4240
private modelSaveTracker: ModelSavingTrackerService,
4341
private electronTunnelService: ElectronTunnelService,
4442
private loadingScreenService: LoadingScreenService,
45-
private shapeSettingsSettings: ShapeSettingsService,
46-
private namespaceCacheService: NamespacesCacheService,
4743
private fileHandlingService: FileHandlingService,
4844
private mxGraphService: MxGraphService,
4945
private translate: LanguageTranslationService,
@@ -91,29 +87,15 @@ export class StartupService {
9187
rdfAspectModel: model,
9288
namespaceFileName: options ? `${options.namespace}:${options.file}` : '',
9389
fromWorkspace: options?.fromWorkspace,
90+
editElementUrn: options?.editElement,
9491
})
9592
: of(this.fileHandlingService.createEmptyModel()),
9693
),
9794
),
9895
tap(() => {
99-
this.editElement(options?.editElement);
10096
this.modelSaveTracker.updateSavedModel();
10197
this.loadingScreenService.close();
10298
}),
10399
);
104100
}
105-
106-
editElement(modelUrn: string) {
107-
if (!modelUrn) {
108-
return;
109-
}
110-
111-
const element = this.namespaceCacheService.currentCachedFile.getElement<BaseMetaModelElement>(modelUrn);
112-
if (element) {
113-
this.shapeSettingsSettings.editModel(element);
114-
requestAnimationFrame(() => {
115-
this.mxGraphService.navigateToCellByUrn(element.aspectModelUrn);
116-
});
117-
}
118-
}
119101
}

core/apps/ame/src/assets/i18n/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@
430430
"LOCATE_ELEMENT": "Locate element",
431431
"OPEN_ELEMENT": "Open element",
432432
"OPEN_ELEMENT_IN_NEW_WINDOW": "Open element in new window"
433+
},
434+
"NOTIFICATION": {
435+
"EDIT_VIEW_UNAVAILABLE": "Edit View Unavailable",
436+
"EDIT_VIEW_UNAVAILABLE_MESSAGE": "The element you`re trying to edit doesn`t exist. Please check if the element ID is correct or if it has been removed."
433437
}
434438
}
435439
},

core/electron-libs/windows-manager.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ class WindowsManager {
346346
if (!id) {
347347
return;
348348
}
349+
349350
event.sender.send(RESPONSE_WINDOW_DATA, {id, options});
350351
};
351352

core/libs/cache/src/lib/cached-file.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ export class CachedFile {
8686
return [...this.cachedElements.values()];
8787
}
8888

89+
hasCachedElements(): boolean {
90+
return this.cachedElements.size > 0;
91+
}
92+
8993
updateCachedElementKey(oldKey: string, newKey: string) {
9094
const resolvedEntry = this.cachedElements.get(oldKey);
9195
if (resolvedEntry) {
@@ -190,4 +194,8 @@ export class CachedFile {
190194
clearAnonymousElements() {
191195
this.anonymousElements = [];
192196
}
197+
198+
clearCache() {
199+
this.cachedElements.clear();
200+
}
193201
}

core/libs/editor/src/lib/editor-dialog/services/shape-settings.service.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
import {Injectable, NgZone} from '@angular/core';
1515
import {BaseMetaModelElement} from '@ame/meta-model';
1616
import {mxEvent, MxGraphAttributeService, MxGraphHelper, MxGraphService, MxGraphShapeSelectorService, mxUtils} from '@ame/mx-graph';
17-
import {BindingsService} from '@ame/shared';
17+
import {BindingsService, NotificationsService} from '@ame/shared';
1818
import {EditorService} from '../../editor.service';
1919
import {ShapeSettingsStateService} from './shape-settings-state.service';
2020
import {OpenReferencedElementService} from '../../open-element-window/open-element-window.service';
2121
import {BehaviorSubject} from 'rxjs';
22+
import {NamespacesCacheService} from '@ame/cache';
23+
import {LanguageTranslationService} from '@ame/translation';
2224

2325
@Injectable({providedIn: 'root'})
2426
export class ShapeSettingsService {
@@ -31,10 +33,13 @@ export class ShapeSettingsService {
3133
private mxGraphAttributeService: MxGraphAttributeService,
3234
private mxGraphService: MxGraphService,
3335
private mxGraphShapeSelectorService: MxGraphShapeSelectorService,
36+
private notificationsService: NotificationsService,
3437
private bindingsService: BindingsService,
3538
private editorService: EditorService,
3639
private shapeSettingsStateService: ShapeSettingsStateService,
3740
private openReferencedElementService: OpenReferencedElementService,
41+
private namespaceCacheService: NamespacesCacheService,
42+
private translate: LanguageTranslationService,
3843
private ngZone: NgZone,
3944
) {}
4045

@@ -112,4 +117,18 @@ export class ShapeSettingsService {
112117
this.shapeSettingsStateService.openShapeSettings();
113118
this.modelElement = elementModel;
114119
}
120+
121+
editModelByUrn(elementUrn: string) {
122+
const element = this.namespaceCacheService.currentCachedFile.getElement<BaseMetaModelElement>(elementUrn);
123+
if (!element) {
124+
this.notificationsService.error({
125+
title: this.translate.language.EDITOR_CANVAS.SHAPE_SETTING.NOTIFICATION.EDIT_VIEW_UNAVAILABLE,
126+
message: this.translate.language.EDITOR_CANVAS.SHAPE_SETTING.NOTIFICATION.EDIT_VIEW_UNAVAILABLE_MESSAGE,
127+
});
128+
129+
return;
130+
}
131+
132+
this.editModel(element);
133+
}
115134
}

core/libs/editor/src/lib/editor-toolbar/services/file-handling.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ export class FileHandlingService {
514514
.synchronizeModelToRdf()
515515
.pipe(finalize(() => subscription$.unsubscribe()))
516516
.subscribe((): void => {
517-
if (!this.modelService.getLoadedAspectModel().aspect) {
517+
if (!this.namespaceCacheService.currentCachedFile.hasCachedElements()) {
518518
this.notificationsService.info({
519519
title: this.translate.language.NOTIFICATION_DIALOG.NO_ASPECT_TITLE,
520520
timeout: 5000,

core/libs/editor/src/lib/editor.service.ts

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* SPDX-License-Identifier: MPL-2.0
1212
*/
1313

14-
import {inject, Injectable, NgZone} from '@angular/core';
14+
import {inject, Injectable, Injector, NgZone} from '@angular/core';
1515
import {
1616
AlertService,
1717
BrowserService,
@@ -71,7 +71,7 @@ import {ModelService, RdfService} from '@ame/rdf/services';
7171
import {RdfModel} from '@ame/rdf/utils';
7272
import {OpenApi, ViolationError} from './editor-toolbar';
7373
import {FILTER_ATTRIBUTES, FilterAttributesService, FiltersService} from '@ame/loader-filters';
74-
import {ShapeSettingsStateService} from './editor-dialog';
74+
import {ShapeSettingsService, ShapeSettingsStateService} from './editor-dialog';
7575
import {LargeFileWarningService} from './large-file-warning-dialog/large-file-warning-dialog.service';
7676
import {LoadModelPayload} from './models/load-model-payload.interface';
7777
import {LanguageTranslationService} from '@ame/translation';
@@ -91,21 +91,16 @@ export class EditorService {
9191
private isAllShapesExpandedSubject = new BehaviorSubject<boolean>(true);
9292

9393
public isAllShapesExpanded$ = this.isAllShapesExpandedSubject.asObservable();
94-
public loadModel$ = new BehaviorSubject<any>(null);
9594
public delayedBindings: Array<any> = [];
9695

97-
public get savedRdf$() {
98-
return this.lastSavedRDF$.asObservable();
99-
}
100-
101-
public get currentCachedFile(): CachedFile {
102-
return this.namespaceCacheService.currentCachedFile;
103-
}
104-
10596
private get settings() {
10697
return this.configurationService.getSettings();
10798
}
10899

100+
get shapeSettingsService(): ShapeSettingsService {
101+
return this.injector.get(ShapeSettingsService);
102+
}
103+
109104
constructor(
110105
private mxGraphService: MxGraphService,
111106
private mxGraphSetupService: MxGraphSetupService,
@@ -133,6 +128,7 @@ export class EditorService {
133128
private loadingScreenService: LoadingScreenService,
134129
private translate: LanguageTranslationService,
135130
private browserService: BrowserService,
131+
private injector: Injector,
136132
private ngZone: NgZone,
137133
) {
138134
if (!environment.production) {
@@ -262,6 +258,7 @@ export class EditorService {
262258
loadedRdfModel,
263259
payload.rdfAspectModel,
264260
payload.namespaceFileName || loadedRdfModel.absoluteAspectModelFileName,
261+
payload.editElementUrn,
265262
),
266263
),
267264
tap(() => {
@@ -343,12 +340,17 @@ export class EditorService {
343340
return this.modelApiService.generateOpenApiSpec(serializedModel, openApi);
344341
}
345342

346-
private loadCurrentModel(loadedRdfModel: RdfModel, rdfAspectModel: string, namespaceFileName: string): Observable<Aspect> {
343+
private loadCurrentModel(
344+
loadedRdfModel: RdfModel,
345+
rdfAspectModel: string,
346+
namespaceFileName: string,
347+
editElementUrn?: string,
348+
): Observable<Aspect> {
347349
return this.modelService.loadRdfModel(loadedRdfModel, rdfAspectModel, namespaceFileName).pipe(
348350
first(),
349351
tap((aspect: Aspect) => {
350352
this.removeOldGraph();
351-
this.initializeNewGraph();
353+
this.initializeNewGraph(editElementUrn);
352354
this.titleService.updateTitle(namespaceFileName || aspect?.aspectModelUrn, aspect ? 'Aspect' : 'Shared');
353355
}),
354356
catchError(error => {
@@ -364,7 +366,7 @@ export class EditorService {
364366
this.mxGraphService.deleteAllShapes();
365367
}
366368

367-
private initializeNewGraph() {
369+
private initializeNewGraph(editElementUrn?: string): void {
368370
try {
369371
const rdfModel = this.modelService.currentRdfModel;
370372
const mxGraphRenderer = new MxGraphRenderer(
@@ -376,52 +378,70 @@ export class EditorService {
376378
);
377379

378380
const elements = this.namespaceCacheService.currentCachedFile.getAllElements();
379-
this.largeFileWarningService
380-
.openDialog(elements.length)
381-
.pipe(
382-
first(),
383-
filter(response => response !== 'cancel'),
384-
tap(() => {
385-
this.loadingScreenService.close();
386-
requestAnimationFrame(() => {
387-
this.loadingScreenService.open({title: this.translate.language.LOADING_SCREEN_DIALOG.MODEL_GENERATION});
388-
});
389-
}),
390-
delay(500), // Modal animation waiting before apps is blocked by mxGraph
391-
switchMap(() => {
392-
return this.mxGraphService.updateGraph(() => {
393-
this.mxGraphService.firstTimeFold = true;
394-
MxGraphHelper.filterMode = this.filtersService.currentFilter.filterType;
395-
const rootElements = elements.filter(e => !e.parents.length);
396-
const filtered = this.filtersService.filter(rootElements);
397-
398-
for (const elementTree of filtered) {
399-
mxGraphRenderer.render(elementTree, null);
400-
}
401-
402-
this.mxGraphAttributeService.inCollapsedMode && this.mxGraphService.foldCells();
403-
});
404-
}),
405-
)
406-
.subscribe({
407-
next: () => {
408-
this.mxGraphService.formatShapes(true);
409-
this.mxGraphSetupService.centerGraph();
410-
localStorage.removeItem(ValidateStatus.validating);
411-
this.loadingScreenService.close();
412-
},
413-
error: () => {
414-
this.loadingScreenService.close();
415-
},
416-
});
381+
this.prepareGraphUpdate(mxGraphRenderer, elements, editElementUrn);
417382
} catch (error) {
418383
console.groupCollapsed('editor.service', error);
419384
console.groupEnd();
420-
421385
throwError(() => error);
422386
}
423387
}
424388

389+
private prepareGraphUpdate(mxGraphRenderer: MxGraphRenderer, elements: BaseMetaModelElement[], editElementUrn?: string): void {
390+
this.largeFileWarningService
391+
.openDialog(elements.length)
392+
.pipe(
393+
first(),
394+
filter(response => response !== 'cancel'),
395+
tap(() => this.toggleLoadingScreen()),
396+
delay(500), // Wait for modal animation
397+
switchMap(() => this.graphUpdateWorkflow(mxGraphRenderer, elements)),
398+
)
399+
.subscribe({
400+
next: () => this.finalizeGraphUpdate(editElementUrn),
401+
error: () => this.loadingScreenService.close(),
402+
});
403+
}
404+
405+
private toggleLoadingScreen(): void {
406+
this.loadingScreenService.close();
407+
requestAnimationFrame(() => {
408+
this.loadingScreenService.open({title: this.translate.language.LOADING_SCREEN_DIALOG.MODEL_GENERATION});
409+
});
410+
}
411+
412+
private graphUpdateWorkflow(mxGraphRenderer: MxGraphRenderer, elements: BaseMetaModelElement[]): Observable<boolean> {
413+
return this.mxGraphService.updateGraph(() => {
414+
this.mxGraphService.firstTimeFold = true;
415+
MxGraphHelper.filterMode = this.filtersService.currentFilter.filterType;
416+
const rootElements = elements.filter(e => !e.parents.length);
417+
const filtered = this.filtersService.filter(rootElements);
418+
419+
for (const elementTree of filtered) {
420+
mxGraphRenderer.render(elementTree, null);
421+
}
422+
423+
if (this.mxGraphAttributeService.inCollapsedMode) {
424+
this.mxGraphService.foldCells();
425+
}
426+
});
427+
}
428+
429+
private finalizeGraphUpdate(editElementUrn?: string): void {
430+
this.mxGraphService.formatShapes(true);
431+
this.handleEditOrCenterView(editElementUrn);
432+
localStorage.removeItem(ValidateStatus.validating);
433+
this.loadingScreenService.close();
434+
}
435+
436+
private handleEditOrCenterView(editElementUrn: string | null): void {
437+
if (editElementUrn) {
438+
this.shapeSettingsService.editModelByUrn(editElementUrn);
439+
this.mxGraphService.navigateToCellByUrn(editElementUrn);
440+
} else {
441+
this.mxGraphSetupService.centerGraph();
442+
}
443+
}
444+
425445
makeDraggable(element: HTMLDivElement, dragElement: HTMLDivElement) {
426446
const ds = mxUtils.makeDraggable(
427447
element,

core/libs/editor/src/lib/large-file-warning-dialog/large-file-warning-dialog.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import {Component, Inject} from '@angular/core';
1515
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
16+
import {NamespacesCacheService} from '@ame/cache';
1617

1718
@Component({
1819
templateUrl: './large-file-warning-dialog.html',
@@ -21,13 +22,15 @@ export class LargeFileWarningComponent {
2122
public elementsCount: number;
2223

2324
constructor(
25+
private namespacesCacheService: NamespacesCacheService,
2426
private dialogRef: MatDialogRef<LargeFileWarningComponent>,
2527
@Inject(MAT_DIALOG_DATA) private data: {elementsCount: number},
2628
) {
2729
this.elementsCount = data?.elementsCount || 0;
2830
}
2931

3032
close(response: 'open' | 'cancel') {
33+
if (response === 'cancel') this.namespacesCacheService.currentCachedFile.clearCache();
3134
this.dialogRef.close(response);
3235
}
3336
}

core/libs/editor/src/lib/models/load-model-payload.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ export interface LoadModelPayload {
1616
namespaceFileName?: string;
1717
isDefault?: boolean;
1818
fromWorkspace?: boolean;
19+
editElementUrn?: string;
1920
}

0 commit comments

Comments
 (0)