Skip to content

Commit c330382

Browse files
authored
Fix/editor service functionality (#151)
* Fix auto save and validation logic * Removed save latest model and fix update last saved rdf
1 parent 0831607 commit c330382

File tree

9 files changed

+87
-87
lines changed

9 files changed

+87
-87
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,11 @@ export class FileHandlingService {
133133
return of(null);
134134
}),
135135
finalize(() => {
136+
this.modelSaveTracker.updateSavedModel(true);
136137
this.loadingScreenService.close();
137-
138138
if (this.modelService.getLoadedAspectModel().rdfModel) {
139139
this.shapeSettingsStateService.closeShapeSettings();
140140
}
141-
142141
this.sidebarService.workspace.close();
143142
}),
144143
);
@@ -226,6 +225,7 @@ export class FileHandlingService {
226225
}
227226

228227
this.modelService.addAspect(null);
228+
this.modelSaveTracker.updateSavedModel(true);
229229

230230
const loadExternalModels$ = this.editorService
231231
.loadExternalModels(newRdfModel)
@@ -326,7 +326,6 @@ export class FileHandlingService {
326326
filter(overwrite => overwrite !== false),
327327
switchMap(() => (modelState.isNamespaceChanged ? this.handleNamespaceChange(modelState) : of(null))),
328328
map(() => {
329-
this.editorService.updateLastSavedRdf(false, this.rdfService.serializeModel(this.rdfService.currentRdfModel), new Date());
330329
isChangeFileName = modelState.loadedFromWorkspace && modelState.isNameChanged && isOverwrite === null;
331330
isChangeNamespace = modelState.loadedFromWorkspace && modelState.isNamespaceChanged;
332331
return isChangeFileName || isChangeNamespace;

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

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,13 @@ import {
3434
delay,
3535
delayWhen,
3636
filter,
37-
finalize,
3837
first,
3938
forkJoin,
4039
map,
4140
mergeMap,
4241
Observable,
4342
of,
44-
retryWhen,
43+
retry,
4544
Subscription,
4645
switchMap,
4746
tap,
@@ -86,9 +85,9 @@ export class EditorService {
8685
private filterAttributes: FilterAttributesService = inject(FILTER_ATTRIBUTES);
8786
private configurationService: ConfigurationService = inject(ConfigurationService);
8887

89-
private validateModel$ = new BehaviorSubject<boolean>(this.settings.autoValidationEnabled);
9088
private validateModelSubscription$: Subscription;
91-
private lastSavedRDF$ = new BehaviorSubject<Partial<ILastSavedModel>>({});
89+
private saveModelSubscription$: Subscription;
90+
9291
private isAllShapesExpandedSubject = new BehaviorSubject<boolean>(true);
9392

9493
public isAllShapesExpanded$ = this.isAllShapesExpandedSubject.asObservable();
@@ -123,7 +122,7 @@ export class EditorService {
123122
private titleService: TitleService,
124123
private sidebarService: SidebarStateService,
125124
private shapeSettingsStateService: ShapeSettingsStateService,
126-
private modelSavingTrackerService: ModelSavingTrackerService,
125+
private modelSavingTracker: ModelSavingTrackerService,
127126
private electronSignalsService: ElectronSignalsService,
128127
private largeFileWarningService: LargeFileWarningService,
129128
private loadingScreenService: LoadingScreenService,
@@ -137,22 +136,11 @@ export class EditorService {
137136
}
138137
}
139138

140-
removeLastSavedRdf() {
141-
this.lastSavedRDF$.next({rdf: null, changed: true, date: null});
142-
}
143-
144-
updateLastSavedRdf(changed: boolean, model: string, saveDate: Date) {
145-
this.lastSavedRDF$.next({
146-
changed: changed,
147-
rdf: model,
148-
date: saveDate,
149-
});
150-
}
151-
152139
initCanvas(): void {
153140
this.mxGraphService.initGraph();
154141

155-
this.startValidateModel();
142+
this.enableAutoValidation();
143+
this.enableAutoSave();
156144

157145
mxEvent.addMouseWheelListener(
158146
mxUtils.bind(this, (evt, up) => {
@@ -249,7 +237,6 @@ export class EditorService {
249237

250238
loadNewAspectModel(payload: LoadModelPayload) {
251239
this.sidebarService.workspace.refresh();
252-
this.removeLastSavedRdf();
253240
this.notificationsService.info({title: 'Loading model', timeout: 2000});
254241

255242
let rdfModel: RdfModel = null;
@@ -266,7 +253,7 @@ export class EditorService {
266253
),
267254
),
268255
tap(() => {
269-
this.modelSavingTrackerService.updateSavedModel();
256+
this.modelSavingTracker.updateSavedModel();
270257
const [namespace, version, file] = (payload.namespaceFileName || this.rdfService.currentRdfModel.absoluteAspectModelFileName).split(
271258
':',
272259
);
@@ -705,16 +692,14 @@ export class EditorService {
705692
});
706693
}
707694

708-
refreshValidateModel() {
709-
this.validateModel$.next(this.settings.autoValidationEnabled);
695+
enableAutoValidation() {
696+
this.settings.autoValidationEnabled ? this.startValidateModel() : this.stopValidateModel();
710697
}
711698

712699
startValidateModel() {
713700
this.stopValidateModel();
714701
localStorage.removeItem(ValidateStatus.validating);
715-
if (this.settings.autoValidationEnabled) {
716-
this.validateModelSubscription$ = this.validateModel().subscribe();
717-
}
702+
this.validateModelSubscription$ = this.autoValidateModel().subscribe();
718703
}
719704

720705
stopValidateModel() {
@@ -724,30 +709,27 @@ export class EditorService {
724709
}
725710
}
726711

727-
validateModel(): Observable<ViolationError[]> {
728-
return this.validateModel$.asObservable().pipe(
712+
autoValidateModel(): Observable<ViolationError[]> {
713+
return of({}).pipe(
729714
delayWhen(() => timer(this.settings.validationTimerSeconds * 1000)),
730-
switchMap(() => this.validate().pipe(first())),
731-
tap(() => {
732-
localStorage.removeItem(ValidateStatus.validating);
733-
this.refreshValidateModel();
715+
switchMap(() => (this.namespaceCacheService.currentCachedFile.hasCachedElements() ? this.validate().pipe(first()) : of([]))),
716+
tap(() => localStorage.removeItem(ValidateStatus.validating)),
717+
tap(() => this.enableAutoValidation()),
718+
retry({
719+
delay: error => {
720+
if (!Object.values(SaveValidateErrorsCodes).includes(error?.type)) {
721+
this.logService.logError(`Error occurred while validating the current model (${error})`);
722+
this.notificationsService.error({
723+
title: this.translate.language.NOTIFICATION_SERVICE.VALIDATION_ERROR_TITLE,
724+
message: this.translate.language.NOTIFICATION_SERVICE.VALIDATION_ERROR_MESSAGE,
725+
timeout: 5000,
726+
});
727+
}
728+
localStorage.removeItem(ValidateStatus.validating);
729+
730+
return timer(this.settings.validationTimerSeconds * 1000);
731+
},
734732
}),
735-
retryWhen(errors =>
736-
errors.pipe(
737-
tap(error => {
738-
if (!Object.values(SaveValidateErrorsCodes).includes(error?.type)) {
739-
this.logService.logError(`Error occurred while validating the current model (${error})`);
740-
this.notificationsService.error({
741-
title: this.translate.language.NOTIFICATION_SERVICE.VALIDATION_ERROR_TITLE,
742-
message: this.translate.language.NOTIFICATION_SERVICE.VALIDATION_ERROR_MESSAGE,
743-
timeout: 5000,
744-
});
745-
}
746-
localStorage.removeItem(ValidateStatus.validating);
747-
}),
748-
delayWhen(() => timer(this.settings.validationTimerSeconds * 1000)),
749-
),
750-
),
751733
);
752734
}
753735

@@ -770,9 +752,41 @@ export class EditorService {
770752
);
771753
}
772754

773-
saveModel() {
755+
enableAutoSave(): void {
756+
this.settings.autoSaveEnabled ? this.startSaveModel() : this.stopSaveModel();
757+
}
758+
759+
startSaveModel(): void {
760+
this.stopSaveModel();
761+
this.saveModelSubscription$ = this.autoSaveModel().subscribe();
762+
}
763+
764+
stopSaveModel() {
765+
if (this.saveModelSubscription$) {
766+
this.saveModelSubscription$.unsubscribe();
767+
}
768+
}
769+
770+
autoSaveModel(): Observable<RdfModel | object> {
771+
return of({}).pipe(
772+
delayWhen(() => timer(this.settings.saveTimerSeconds * 1000)),
773+
switchMap(() =>
774+
this.namespaceCacheService.currentCachedFile.hasCachedElements() &&
775+
!this.rdfService.currentRdfModel.aspectModelFileName.includes('empty.ttl')
776+
? this.saveModel().pipe(first())
777+
: of([]),
778+
),
779+
tap(() => this.enableAutoSave()),
780+
retry({
781+
delay: () => timer(this.settings.saveTimerSeconds * 1000),
782+
}),
783+
);
784+
}
785+
786+
saveModel(): Observable<RdfModel | object> {
774787
return this.modelService.saveModel().pipe(
775788
tap(() => {
789+
this.modelSavingTracker.updateSavedModel();
776790
this.notificationsService.info({title: this.translate.language.NOTIFICATION_SERVICE.ASPECT_SAVED_SUCCESS});
777791
this.logService.logInfo('Aspect model was saved to the local folder');
778792
this.sidebarService.workspace.refresh();

core/libs/namespace-manager/src/lib/namespace-exporter/namespace-exporter-router.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import {NgModule} from '@angular/core';
1515
import {RouterModule, Routes} from '@angular/router';
16-
import {ErrorComponent} from '../shared/components';
16+
import {ErrorComponent} from '../shared';
1717
import {SelectNamespacesComponent, ExportSummaryComponent, ExportValidateComponent} from './components';
1818

1919
const routes: Routes = [

core/libs/rdf/src/lib/services/rdf.service.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,19 @@ import {LanguageTranslationService} from '@ame/translation';
2727
providedIn: 'root',
2828
})
2929
export class RdfService {
30-
private _latestSavedRDF: string;
3130
private _rdfSerializer: RdfSerializerService;
3231
private _settings: Settings;
32+
private _currentModel: RdfModel;
3333

3434
public externalRdfModels: Array<RdfModel> = [];
35-
public currentRdfModel: RdfModel;
35+
36+
get currentRdfModel(): RdfModel {
37+
return this._currentModel;
38+
}
39+
40+
set currentRdfModel(value: RdfModel) {
41+
this._currentModel = value;
42+
}
3643

3744
constructor(
3845
private logService: LogService,
@@ -79,26 +86,6 @@ export class RdfService {
7986
);
8087
}
8188

82-
saveLatestModel(rdfModel: RdfModel): Observable<{serializedModel: string; savedDate: Date}> {
83-
if (!rdfModel) {
84-
this.logService.logInfo('Model is null. Skipping saving.');
85-
return this.handleError(SaveValidateErrorsCodes.emptyModel);
86-
}
87-
88-
const serializedModel = this.serializeModel(rdfModel);
89-
if (this._latestSavedRDF === serializedModel) {
90-
this.logService.logInfo('Model not changed. Skipping saving');
91-
return this.handleError(SaveValidateErrorsCodes.notChangedModel);
92-
}
93-
94-
return this.modelApiService.saveLatest(serializedModel).pipe(
95-
map(() => {
96-
this._latestSavedRDF = serializedModel;
97-
return {serializedModel, savedDate: new Date()};
98-
}),
99-
);
100-
}
101-
10289
private handleError(errorCode: SaveValidateErrorsCodes): Observable<never> {
10390
return throwError(() => ({type: errorCode}));
10491
}

core/libs/rdf/src/lib/utils/rdf-model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import {DataFactory, NamedNode, Prefixes, Quad, Quad_Graph, Quad_Object, Quad_Predicate, Quad_Subject, Store, Util, Writer} from 'n3';
1515
import * as locale from 'locale-codes';
16-
import {InstantiatorListElement} from '../models/rdf-model.types';
16+
import {InstantiatorListElement} from '@ame/rdf/models';
1717
import {Samm, SammC, SammE, SammU} from '@ame/vocabulary';
1818
import {RdfModelUtil} from '@ame/rdf/utils/rdf-model-util';
1919
import {config} from '@ame/shared';

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,6 @@ export class ConfigurationService {
9494
return this.settings || DEFAULT_SETTINGS;
9595
}
9696

97-
toggleEditorNavigation() {
98-
// Mutates the original object. Can be removed once all components start relying on Observable stream.
99-
this.settings.showEditorNav = !this.settings.showEditorNav;
100-
this.setSettings(this.settings);
101-
}
102-
10397
toggleEditorMap() {
10498
// Mutates the original object. Can be removed once all components start relying on Observable stream.
10599
this.settings.showEditorMap = !this.settings.showEditorMap;

core/libs/settings-dialog/src/lib/strategy/automated-workflow-update.strategy.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class AutomatedWorkflowUpdateStrategy implements SettingsUpdateStrategy {
3333
settings.validationTimerSeconds = automatedWorkflow.get('validationTimerSeconds')?.value;
3434
settings.autoFormatEnabled = automatedWorkflow.get('autoFormatEnabled')?.value;
3535

36-
if (settings.autoValidationEnabled) this.editorService.refreshValidateModel();
36+
if (settings.autoValidationEnabled) this.editorService.enableAutoValidation();
37+
if (settings.autoSaveEnabled) this.editorService.enableAutoSave();
3738
}
3839
}

core/libs/shared/src/lib/services/model-saving-tracker.service.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
import {ModelService, RdfService} from '@ame/rdf/services';
1515
import {MxGraphService} from '@ame/mx-graph';
1616
import {Injectable, inject} from '@angular/core';
17-
import {map, take} from 'rxjs';
17+
import {map, take, Timestamp} from 'rxjs';
1818

1919
@Injectable({providedIn: 'root'})
2020
export class ModelSavingTrackerService {
2121
private modelService = inject(ModelService);
2222
private rdfService = inject(RdfService);
2323
private mxGraphService = inject(MxGraphService);
2424
private savedModel: string;
25+
private firstLoad: boolean;
2526

2627
private get currentModel$() {
2728
return this.modelService.synchronizeModelToRdf().pipe(
@@ -31,10 +32,15 @@ export class ModelSavingTrackerService {
3132
}
3233

3334
public get isSaved$() {
34-
return this.currentModel$.pipe(map(currentModel => this.savedModel === currentModel || !this.mxGraphService.getAllCells()?.length));
35+
return this.currentModel$.pipe(
36+
map(currentModel => (!this.firstLoad && this.savedModel === currentModel) || !this.mxGraphService.getAllCells()?.length),
37+
);
3538
}
3639

37-
public updateSavedModel() {
38-
this.currentModel$.subscribe(currentModel => (this.savedModel = currentModel));
40+
public updateSavedModel(firstLoad = false) {
41+
this.currentModel$.subscribe(currentModel => {
42+
this.firstLoad = firstLoad;
43+
this.savedModel = currentModel;
44+
});
3945
}
4046
}

core/libs/sidebar/src/lib/workspace/workspace-file-list/workspace-file-list.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ export class WorkspaceFileListComponent implements OnInit, OnDestroy {
175175
.subscribe(confirmed => {
176176
if (confirmed) {
177177
const serializeModel = this.rdfService.serializeModel(this.rdfService.currentRdfModel);
178-
this.editorService.updateLastSavedRdf(false, serializeModel, new Date());
179178
this.editorService.saveModel().subscribe();
180179
}
181180
// TODO improve this functionality

0 commit comments

Comments
 (0)