@finos/legend-application-studio 22.1.5 → 22.2.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/lib/components/DSL_ExternalFormat_LegendStudioApplicationPlugin.d.ts +3 -1
- package/lib/components/DSL_ExternalFormat_LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/components/DSL_ExternalFormat_LegendStudioApplicationPlugin.js +15 -3
- package/lib/components/DSL_ExternalFormat_LegendStudioApplicationPlugin.js.map +1 -1
- package/lib/components/editor/edit-panel/GrammarTextEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/GrammarTextEditor.js +8 -0
- package/lib/components/editor/edit-panel/GrammarTextEditor.js.map +1 -1
- package/lib/components/editor/edit-panel/external-format-editor/DSL_ExternalFormat_ExternalFormatConnectionEditor.d.ts +1 -0
- package/lib/components/editor/edit-panel/external-format-editor/DSL_ExternalFormat_ExternalFormatConnectionEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/external-format-editor/DSL_ExternalFormat_ExternalFormatConnectionEditor.js +4 -0
- package/lib/components/editor/edit-panel/external-format-editor/DSL_ExternalFormat_ExternalFormatConnectionEditor.js.map +1 -1
- package/lib/components/editor/edit-panel/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
- package/lib/components/editor/edit-panel/project-configuration-editor/ProjectDependencyEditor.js +155 -59
- package/lib/components/editor/edit-panel/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
- package/lib/components/editor/side-bar/CreateNewElementModal.d.ts.map +1 -1
- package/lib/components/editor/side-bar/CreateNewElementModal.js +28 -23
- package/lib/components/editor/side-bar/CreateNewElementModal.js.map +1 -1
- package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
- package/lib/components/editor/side-bar/Explorer.js +1 -0
- package/lib/components/editor/side-bar/Explorer.js.map +1 -1
- package/lib/components/editor/side-bar/LocalChanges.d.ts.map +1 -1
- package/lib/components/editor/side-bar/LocalChanges.js +16 -3
- package/lib/components/editor/side-bar/LocalChanges.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +3 -3
- package/lib/stores/ChangeDetectionState.d.ts +3 -0
- package/lib/stores/ChangeDetectionState.d.ts.map +1 -1
- package/lib/stores/ChangeDetectionState.js +68 -1
- package/lib/stores/ChangeDetectionState.js.map +1 -1
- package/lib/stores/DSL_Mapping_LegendStudioApplicationPlugin_Extension.d.ts +15 -1
- package/lib/stores/DSL_Mapping_LegendStudioApplicationPlugin_Extension.d.ts.map +1 -1
- package/lib/stores/EditorGraphState.d.ts +9 -1
- package/lib/stores/EditorGraphState.d.ts.map +1 -1
- package/lib/stores/EditorGraphState.js +220 -38
- package/lib/stores/EditorGraphState.js.map +1 -1
- package/lib/stores/EditorStore.d.ts +2 -1
- package/lib/stores/EditorStore.d.ts.map +1 -1
- package/lib/stores/EditorStore.js +14 -2
- package/lib/stores/EditorStore.js.map +1 -1
- package/lib/stores/EditorTabManagerState.d.ts +3 -10
- package/lib/stores/EditorTabManagerState.d.ts.map +1 -1
- package/lib/stores/EditorTabManagerState.js +33 -37
- package/lib/stores/EditorTabManagerState.js.map +1 -1
- package/lib/stores/ExplorerTreeState.d.ts +2 -0
- package/lib/stores/ExplorerTreeState.d.ts.map +1 -1
- package/lib/stores/ExplorerTreeState.js +53 -0
- package/lib/stores/ExplorerTreeState.js.map +1 -1
- package/lib/stores/LegendStudioRouter.d.ts +1 -1
- package/lib/stores/LegendStudioRouter.d.ts.map +1 -1
- package/lib/stores/LegendStudioRouter.js.map +1 -1
- package/lib/stores/editor/NewElementState.d.ts +14 -9
- package/lib/stores/editor/NewElementState.d.ts.map +1 -1
- package/lib/stores/editor/NewElementState.js +38 -19
- package/lib/stores/editor/NewElementState.js.map +1 -1
- package/lib/stores/editor-state/FileGenerationViewerState.d.ts +1 -0
- package/lib/stores/editor-state/FileGenerationViewerState.d.ts.map +1 -1
- package/lib/stores/editor-state/FileGenerationViewerState.js +4 -0
- package/lib/stores/editor-state/FileGenerationViewerState.js.map +1 -1
- package/lib/stores/editor-state/GraphGenerationState.d.ts.map +1 -1
- package/lib/stores/editor-state/GraphGenerationState.js +4 -1
- package/lib/stores/editor-state/GraphGenerationState.js.map +1 -1
- package/lib/stores/editor-state/element-editor-state/ElementEditorState.d.ts +1 -0
- package/lib/stores/editor-state/element-editor-state/ElementEditorState.d.ts.map +1 -1
- package/lib/stores/editor-state/element-editor-state/ElementEditorState.js +4 -0
- package/lib/stores/editor-state/element-editor-state/ElementEditorState.js.map +1 -1
- package/lib/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts +46 -13
- package/lib/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts.map +1 -1
- package/lib/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js +176 -23
- package/lib/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js.map +1 -1
- package/lib/stores/sidebar-state/LocalChangesState.d.ts +14 -2
- package/lib/stores/sidebar-state/LocalChangesState.d.ts.map +1 -1
- package/lib/stores/sidebar-state/LocalChangesState.js +206 -30
- package/lib/stores/sidebar-state/LocalChangesState.js.map +1 -1
- package/package.json +12 -12
- package/src/components/DSL_ExternalFormat_LegendStudioApplicationPlugin.tsx +17 -3
- package/src/components/editor/edit-panel/GrammarTextEditor.tsx +14 -0
- package/src/components/editor/edit-panel/external-format-editor/DSL_ExternalFormat_ExternalFormatConnectionEditor.tsx +5 -0
- package/src/components/editor/edit-panel/project-configuration-editor/ProjectDependencyEditor.tsx +430 -169
- package/src/components/editor/side-bar/CreateNewElementModal.tsx +50 -43
- package/src/components/editor/side-bar/Explorer.tsx +1 -0
- package/src/components/editor/side-bar/LocalChanges.tsx +16 -6
- package/src/stores/ChangeDetectionState.ts +119 -0
- package/src/stores/DSL_Mapping_LegendStudioApplicationPlugin_Extension.ts +19 -1
- package/src/stores/EditorGraphState.ts +321 -44
- package/src/stores/EditorStore.ts +22 -2
- package/src/stores/EditorTabManagerState.ts +55 -37
- package/src/stores/ExplorerTreeState.ts +118 -0
- package/src/stores/LegendStudioRouter.ts +1 -1
- package/src/stores/editor/NewElementState.ts +57 -28
- package/src/stores/editor-state/FileGenerationViewerState.ts +5 -0
- package/src/stores/editor-state/GraphGenerationState.ts +9 -0
- package/src/stores/editor-state/element-editor-state/ElementEditorState.ts +5 -0
- package/src/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.ts +259 -34
- package/src/stores/sidebar-state/LocalChangesState.ts +338 -62
|
@@ -174,7 +174,7 @@ class PatchLoaderState {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
export class LocalChangesState {
|
|
177
|
+
export abstract class LocalChangesState {
|
|
178
178
|
readonly editorStore: EditorStore;
|
|
179
179
|
readonly sdlcState: EditorSDLCState;
|
|
180
180
|
readonly workspaceSyncState: WorkspaceSyncState;
|
|
@@ -186,7 +186,6 @@ export class LocalChangesState {
|
|
|
186
186
|
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
187
187
|
makeObservable(this, {
|
|
188
188
|
hasUnpushedChanges: computed,
|
|
189
|
-
openPotentialWorkspacePullConflict: action,
|
|
190
189
|
refreshWorkspaceSyncStatus: flow,
|
|
191
190
|
refreshLocalChanges: flow,
|
|
192
191
|
pushLocalChanges: flow,
|
|
@@ -245,6 +244,78 @@ export class LocalChangesState {
|
|
|
245
244
|
}
|
|
246
245
|
}
|
|
247
246
|
|
|
247
|
+
*refreshWorkspaceSyncStatus(): GeneratorFn<void> {
|
|
248
|
+
try {
|
|
249
|
+
this.refreshWorkspaceSyncStatusState.inProgress();
|
|
250
|
+
const currentRemoteRevision =
|
|
251
|
+
this.sdlcState.activeRemoteWorkspaceRevision;
|
|
252
|
+
yield flowResult(
|
|
253
|
+
this.sdlcState.fetchRemoteWorkspaceRevision(
|
|
254
|
+
this.sdlcState.activeProject.projectId,
|
|
255
|
+
this.sdlcState.activeWorkspace,
|
|
256
|
+
),
|
|
257
|
+
);
|
|
258
|
+
if (
|
|
259
|
+
currentRemoteRevision.id !==
|
|
260
|
+
this.sdlcState.activeRemoteWorkspaceRevision.id
|
|
261
|
+
) {
|
|
262
|
+
if (this.sdlcState.isWorkspaceOutOfSync) {
|
|
263
|
+
this.editorStore.localChangesState.workspaceSyncState.fetchIncomingRevisions();
|
|
264
|
+
const remoteWorkspaceEntities =
|
|
265
|
+
(yield this.editorStore.sdlcServerClient.getEntitiesByRevision(
|
|
266
|
+
this.sdlcState.activeProject.projectId,
|
|
267
|
+
this.sdlcState.activeWorkspace,
|
|
268
|
+
this.sdlcState.activeRemoteWorkspaceRevision.id,
|
|
269
|
+
)) as Entity[];
|
|
270
|
+
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.setEntities(
|
|
271
|
+
remoteWorkspaceEntities,
|
|
272
|
+
);
|
|
273
|
+
yield flowResult(
|
|
274
|
+
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.buildEntityHashesIndex(
|
|
275
|
+
remoteWorkspaceEntities,
|
|
276
|
+
LogEvent.create(
|
|
277
|
+
CHANGE_DETECTION_EVENT.CHANGE_DETECTION_LOCAL_HASHES_INDEX_BUILT,
|
|
278
|
+
),
|
|
279
|
+
),
|
|
280
|
+
);
|
|
281
|
+
yield flowResult(
|
|
282
|
+
this.editorStore.changeDetectionState.computeAggregatedWorkspaceRemoteChanges(),
|
|
283
|
+
);
|
|
284
|
+
} else {
|
|
285
|
+
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.setEntities(
|
|
286
|
+
[],
|
|
287
|
+
);
|
|
288
|
+
this.editorStore.changeDetectionState.setPotentialWorkspacePullConflicts(
|
|
289
|
+
[],
|
|
290
|
+
);
|
|
291
|
+
this.editorStore.changeDetectionState.setAggregatedWorkspaceRemoteChanges(
|
|
292
|
+
[],
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
assertErrorThrown(error);
|
|
298
|
+
this.editorStore.applicationStore.log.error(
|
|
299
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
300
|
+
error,
|
|
301
|
+
);
|
|
302
|
+
} finally {
|
|
303
|
+
this.refreshWorkspaceSyncStatusState.complete();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
abstract refreshLocalChanges(): GeneratorFn<void>;
|
|
308
|
+
|
|
309
|
+
abstract pushLocalChanges(pushMessage?: string): GeneratorFn<void>;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export class FormLocalChangesState extends LocalChangesState {
|
|
313
|
+
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
314
|
+
super(editorStore, sdlcState);
|
|
315
|
+
makeObservable(this, {
|
|
316
|
+
openPotentialWorkspacePullConflict: action,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
248
319
|
openLocalChange(diff: EntityDiff): void {
|
|
249
320
|
const fromEntityGetter = (
|
|
250
321
|
entityPath: string | undefined,
|
|
@@ -428,66 +499,6 @@ export class LocalChangesState {
|
|
|
428
499
|
}
|
|
429
500
|
}
|
|
430
501
|
|
|
431
|
-
*refreshWorkspaceSyncStatus(): GeneratorFn<void> {
|
|
432
|
-
try {
|
|
433
|
-
this.refreshWorkspaceSyncStatusState.inProgress();
|
|
434
|
-
const currentRemoteRevision =
|
|
435
|
-
this.sdlcState.activeRemoteWorkspaceRevision;
|
|
436
|
-
yield flowResult(
|
|
437
|
-
this.sdlcState.fetchRemoteWorkspaceRevision(
|
|
438
|
-
this.sdlcState.activeProject.projectId,
|
|
439
|
-
this.sdlcState.activeWorkspace,
|
|
440
|
-
),
|
|
441
|
-
);
|
|
442
|
-
if (
|
|
443
|
-
currentRemoteRevision.id !==
|
|
444
|
-
this.sdlcState.activeRemoteWorkspaceRevision.id
|
|
445
|
-
) {
|
|
446
|
-
if (this.sdlcState.isWorkspaceOutOfSync) {
|
|
447
|
-
this.editorStore.localChangesState.workspaceSyncState.fetchIncomingRevisions();
|
|
448
|
-
const remoteWorkspaceEntities =
|
|
449
|
-
(yield this.editorStore.sdlcServerClient.getEntitiesByRevision(
|
|
450
|
-
this.sdlcState.activeProject.projectId,
|
|
451
|
-
this.sdlcState.activeWorkspace,
|
|
452
|
-
this.sdlcState.activeRemoteWorkspaceRevision.id,
|
|
453
|
-
)) as Entity[];
|
|
454
|
-
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.setEntities(
|
|
455
|
-
remoteWorkspaceEntities,
|
|
456
|
-
);
|
|
457
|
-
yield flowResult(
|
|
458
|
-
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.buildEntityHashesIndex(
|
|
459
|
-
remoteWorkspaceEntities,
|
|
460
|
-
LogEvent.create(
|
|
461
|
-
CHANGE_DETECTION_EVENT.CHANGE_DETECTION_LOCAL_HASHES_INDEX_BUILT,
|
|
462
|
-
),
|
|
463
|
-
),
|
|
464
|
-
);
|
|
465
|
-
yield flowResult(
|
|
466
|
-
this.editorStore.changeDetectionState.computeAggregatedWorkspaceRemoteChanges(),
|
|
467
|
-
);
|
|
468
|
-
} else {
|
|
469
|
-
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.setEntities(
|
|
470
|
-
[],
|
|
471
|
-
);
|
|
472
|
-
this.editorStore.changeDetectionState.setPotentialWorkspacePullConflicts(
|
|
473
|
-
[],
|
|
474
|
-
);
|
|
475
|
-
this.editorStore.changeDetectionState.setAggregatedWorkspaceRemoteChanges(
|
|
476
|
-
[],
|
|
477
|
-
);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
} catch (error) {
|
|
481
|
-
assertErrorThrown(error);
|
|
482
|
-
this.editorStore.applicationStore.log.error(
|
|
483
|
-
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
484
|
-
error,
|
|
485
|
-
);
|
|
486
|
-
} finally {
|
|
487
|
-
this.refreshWorkspaceSyncStatusState.complete();
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
502
|
*pushLocalChanges(pushMessage?: string): GeneratorFn<void> {
|
|
492
503
|
if (
|
|
493
504
|
this.pushChangesState.isInProgress ||
|
|
@@ -578,6 +589,7 @@ export class LocalChangesState {
|
|
|
578
589
|
}
|
|
579
590
|
const currentHashesIndex =
|
|
580
591
|
this.editorStore.changeDetectionState.snapshotLocalEntityHashesIndex();
|
|
592
|
+
|
|
581
593
|
try {
|
|
582
594
|
const nullableRevisionChange =
|
|
583
595
|
(yield this.editorStore.sdlcServerClient.performEntityChanges(
|
|
@@ -613,7 +625,9 @@ export class LocalChangesState {
|
|
|
613
625
|
);
|
|
614
626
|
|
|
615
627
|
// ======= (RE)START CHANGE DETECTION =======
|
|
628
|
+
|
|
616
629
|
this.editorStore.changeDetectionState.stop();
|
|
630
|
+
|
|
617
631
|
try {
|
|
618
632
|
/**
|
|
619
633
|
* Here we try to rebuild local hash index. If failed, we will use local hash index, but for veracity, it's best to use entities
|
|
@@ -693,6 +707,268 @@ export class LocalChangesState {
|
|
|
693
707
|
true,
|
|
694
708
|
),
|
|
695
709
|
]);
|
|
710
|
+
|
|
711
|
+
this.editorStore.applicationStore.log.info(
|
|
712
|
+
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
713
|
+
Date.now() - syncFinishedTime,
|
|
714
|
+
'ms',
|
|
715
|
+
);
|
|
716
|
+
// ======= FINISHED (RE)START CHANGE DETECTION =======
|
|
717
|
+
} catch (error) {
|
|
718
|
+
assertErrorThrown(error);
|
|
719
|
+
this.editorStore.applicationStore.log.error(
|
|
720
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
721
|
+
error,
|
|
722
|
+
);
|
|
723
|
+
if (
|
|
724
|
+
error instanceof NetworkClientError &&
|
|
725
|
+
error.response.status === HttpStatus.CONFLICT
|
|
726
|
+
) {
|
|
727
|
+
// NOTE: a confict here indicates that the reference revision ID sent along with update call
|
|
728
|
+
// does not match the HEAD of the workspace, therefore, we need to prompt user to refresh the application
|
|
729
|
+
this.editorStore.applicationStore.notifyWarning(
|
|
730
|
+
'Syncing failed. Current workspace revision is not the latest. Please backup your work and refresh the application',
|
|
731
|
+
);
|
|
732
|
+
// TODO: maybe we should do more here, e.g. prompt the user to download the patch, but that is for later
|
|
733
|
+
} else {
|
|
734
|
+
this.editorStore.applicationStore.notifyError(error);
|
|
735
|
+
}
|
|
736
|
+
} finally {
|
|
737
|
+
this.pushChangesState.complete();
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
export class TextLocalChangesState extends LocalChangesState {
|
|
743
|
+
localChanges: EntityChange[] = [];
|
|
744
|
+
|
|
745
|
+
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
746
|
+
super(editorStore, sdlcState);
|
|
747
|
+
makeObservable(this, {
|
|
748
|
+
setLocalChanges: action,
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
setLocalChanges(val: EntityChange[]): void {
|
|
753
|
+
this.localChanges = val;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
*refreshLocalChanges(): GeneratorFn<void> {
|
|
757
|
+
const startTime = Date.now();
|
|
758
|
+
this.refreshLocalChangesDetectorState.inProgress();
|
|
759
|
+
try {
|
|
760
|
+
// ======= (RE)START CHANGE DETECTION =======
|
|
761
|
+
yield Promise.all([
|
|
762
|
+
this.sdlcState.buildWorkspaceLatestRevisionEntityHashesIndex(),
|
|
763
|
+
this.editorStore.changeDetectionState.preComputeGraphElementHashes(),
|
|
764
|
+
]);
|
|
765
|
+
this.editorStore.changeDetectionState.computeLocalChangesInTextMode(
|
|
766
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState
|
|
767
|
+
.entities,
|
|
768
|
+
);
|
|
769
|
+
this.editorStore.applicationStore.log.info(
|
|
770
|
+
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
771
|
+
Date.now() - startTime,
|
|
772
|
+
'ms',
|
|
773
|
+
);
|
|
774
|
+
// ======= FINISHED (RE)START CHANGE DETECTION =======
|
|
775
|
+
} catch (error) {
|
|
776
|
+
assertErrorThrown(error);
|
|
777
|
+
this.editorStore.applicationStore.log.error(
|
|
778
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
779
|
+
error,
|
|
780
|
+
);
|
|
781
|
+
this.editorStore.applicationStore.notifyError(error);
|
|
782
|
+
this.sdlcState.handleChangeDetectionRefreshIssue(error);
|
|
783
|
+
} finally {
|
|
784
|
+
this.refreshLocalChangesDetectorState.complete();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
*pushLocalChanges(pushMessage?: string): GeneratorFn<void> {
|
|
789
|
+
if (
|
|
790
|
+
this.pushChangesState.isInProgress ||
|
|
791
|
+
this.editorStore.workspaceUpdaterState.isUpdatingWorkspace
|
|
792
|
+
) {
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
this.pushChangesState.inProgress();
|
|
797
|
+
const startTime = Date.now();
|
|
798
|
+
if (!this.localChanges.length) {
|
|
799
|
+
this.pushChangesState.complete();
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
yield flowResult(
|
|
803
|
+
this.sdlcState.fetchRemoteWorkspaceRevision(
|
|
804
|
+
this.sdlcState.activeProject.projectId,
|
|
805
|
+
this.sdlcState.activeWorkspace,
|
|
806
|
+
),
|
|
807
|
+
);
|
|
808
|
+
if (this.sdlcState.isWorkspaceOutOfSync) {
|
|
809
|
+
// ensure changes have been computed for latest remote version
|
|
810
|
+
const remoteWorkspaceEntities =
|
|
811
|
+
(yield this.editorStore.sdlcServerClient.getEntitiesByRevision(
|
|
812
|
+
this.sdlcState.activeProject.projectId,
|
|
813
|
+
this.sdlcState.activeWorkspace,
|
|
814
|
+
this.sdlcState.activeRemoteWorkspaceRevision.id,
|
|
815
|
+
)) as Entity[];
|
|
816
|
+
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.setEntities(
|
|
817
|
+
remoteWorkspaceEntities,
|
|
818
|
+
);
|
|
819
|
+
yield flowResult(
|
|
820
|
+
this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.buildEntityHashesIndex(
|
|
821
|
+
remoteWorkspaceEntities,
|
|
822
|
+
LogEvent.create(
|
|
823
|
+
CHANGE_DETECTION_EVENT.CHANGE_DETECTION_LOCAL_HASHES_INDEX_BUILT,
|
|
824
|
+
),
|
|
825
|
+
),
|
|
826
|
+
);
|
|
827
|
+
yield flowResult(
|
|
828
|
+
this.editorStore.changeDetectionState.computeAggregatedWorkspaceRemoteChanges(),
|
|
829
|
+
);
|
|
830
|
+
this.editorStore.applicationStore.setActionAlertInfo({
|
|
831
|
+
message: 'Local workspace is out-of-sync',
|
|
832
|
+
prompt: 'Please pull remote changes before pushing your local changes',
|
|
833
|
+
type: ActionAlertType.CAUTION,
|
|
834
|
+
actions: [
|
|
835
|
+
{
|
|
836
|
+
label: 'Pull remote changes',
|
|
837
|
+
type: ActionAlertActionType.STANDARD,
|
|
838
|
+
default: true,
|
|
839
|
+
handler: (): void => {
|
|
840
|
+
this.editorStore.setActiveActivity(ACTIVITY_MODE.LOCAL_CHANGES);
|
|
841
|
+
flowResult(
|
|
842
|
+
this.editorStore.localChangesState.workspaceSyncState.pullChanges(),
|
|
843
|
+
).catch(this.editorStore.applicationStore.alertUnhandledError);
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
label: 'Cancel',
|
|
848
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
849
|
+
},
|
|
850
|
+
],
|
|
851
|
+
});
|
|
852
|
+
this.pushChangesState.complete();
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
const currentHashesIndex =
|
|
856
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState
|
|
857
|
+
.currentEntityHashesIndex;
|
|
858
|
+
try {
|
|
859
|
+
const nullableRevisionChange =
|
|
860
|
+
(yield this.editorStore.sdlcServerClient.performEntityChanges(
|
|
861
|
+
this.sdlcState.activeProject.projectId,
|
|
862
|
+
this.sdlcState.activeWorkspace,
|
|
863
|
+
{
|
|
864
|
+
message:
|
|
865
|
+
pushMessage ??
|
|
866
|
+
`pushed new changes from ${
|
|
867
|
+
this.editorStore.applicationStore.config.appName
|
|
868
|
+
} [potentially affected ${
|
|
869
|
+
this.localChanges.length === 1
|
|
870
|
+
? '1 entity'
|
|
871
|
+
: `${this.localChanges.length} entities`
|
|
872
|
+
}]`,
|
|
873
|
+
entityChanges: this.localChanges,
|
|
874
|
+
revisionId: this.sdlcState.activeRevision.id,
|
|
875
|
+
},
|
|
876
|
+
)) as PlainObject<Revision> | undefined;
|
|
877
|
+
const revisionChange = guaranteeNonNullable(
|
|
878
|
+
nullableRevisionChange,
|
|
879
|
+
`Can't push an empty change set. This may be due to an error with change detection`,
|
|
880
|
+
);
|
|
881
|
+
const latestRevision = Revision.serialization.fromJson(revisionChange);
|
|
882
|
+
this.sdlcState.setCurrentRevision(latestRevision); // update current revision to the latest
|
|
883
|
+
this.sdlcState.setWorkspaceLatestRevision(latestRevision);
|
|
884
|
+
const syncFinishedTime = Date.now();
|
|
885
|
+
|
|
886
|
+
this.editorStore.applicationStore.log.info(
|
|
887
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.WORKSPACE_LOCAL_CHANGES_PUSHED),
|
|
888
|
+
syncFinishedTime - startTime,
|
|
889
|
+
'ms',
|
|
890
|
+
);
|
|
891
|
+
this.localChanges = [];
|
|
892
|
+
|
|
893
|
+
// ======= (RE)START CHANGE DETECTION =======
|
|
894
|
+
try {
|
|
895
|
+
/**
|
|
896
|
+
* Here we try to rebuild local hash index. If failed, we will use local hash index, but for veracity, it's best to use entities
|
|
897
|
+
* coming from the server.
|
|
898
|
+
*/
|
|
899
|
+
const entities =
|
|
900
|
+
(yield this.editorStore.sdlcServerClient.getEntitiesByRevision(
|
|
901
|
+
this.sdlcState.activeProject.projectId,
|
|
902
|
+
this.sdlcState.activeWorkspace,
|
|
903
|
+
latestRevision.id,
|
|
904
|
+
)) as Entity[];
|
|
905
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.setEntities(
|
|
906
|
+
entities,
|
|
907
|
+
);
|
|
908
|
+
yield flowResult(
|
|
909
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.buildEntityHashesIndex(
|
|
910
|
+
entities,
|
|
911
|
+
LogEvent.create(
|
|
912
|
+
CHANGE_DETECTION_EVENT.CHANGE_DETECTION_LOCAL_HASHES_INDEX_BUILT,
|
|
913
|
+
),
|
|
914
|
+
),
|
|
915
|
+
);
|
|
916
|
+
this.editorStore.tabManagerState.refreshCurrentEntityDiffViewer();
|
|
917
|
+
} catch (error) {
|
|
918
|
+
assertErrorThrown(error);
|
|
919
|
+
/**
|
|
920
|
+
* NOTE: there is a known problem with the SDLC server where if we try to fetch the entities right after syncing, there is a chance
|
|
921
|
+
* that we get entities from the older commit (i.e. potentially some caching issue). As such, to account for this case, we will
|
|
922
|
+
* not try to get entities for the workspace HEAD, but for the revision returned from the syncing call (i.e. this must be the latest revision)
|
|
923
|
+
* if we get a 404, we will do a refresh and warn user about this. Otherwise, if we get other types of error, we will assume this is a network
|
|
924
|
+
* failure and use local workspace hashes index
|
|
925
|
+
*/
|
|
926
|
+
if (error instanceof NetworkClientError) {
|
|
927
|
+
if (error.response.status === HttpStatus.NOT_FOUND) {
|
|
928
|
+
this.editorStore.applicationStore.log.error(
|
|
929
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
930
|
+
`Can't fetch entities for the latest workspace revision immediately after syncing`,
|
|
931
|
+
error,
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
this.editorStore.applicationStore.setActionAlertInfo({
|
|
935
|
+
message: `Change detection engine failed to build hashes index for workspace after syncing`,
|
|
936
|
+
prompt:
|
|
937
|
+
'To fix this, you can either try to keep refreshing local changes until success or trust and reuse current workspace hashes index',
|
|
938
|
+
type: ActionAlertType.CAUTION,
|
|
939
|
+
actions: [
|
|
940
|
+
{
|
|
941
|
+
label: 'Use local hashes index',
|
|
942
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
943
|
+
handler: (): void => {
|
|
944
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.setEntityHashesIndex(
|
|
945
|
+
currentHashesIndex,
|
|
946
|
+
);
|
|
947
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.setIsBuildingEntityHashesIndex(
|
|
948
|
+
false,
|
|
949
|
+
);
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
label: 'Refresh changes',
|
|
954
|
+
type: ActionAlertActionType.STANDARD,
|
|
955
|
+
default: true,
|
|
956
|
+
handler: this.editorStore.applicationStore.guardUnhandledError(
|
|
957
|
+
() => flowResult(this.refreshLocalChanges()),
|
|
958
|
+
),
|
|
959
|
+
},
|
|
960
|
+
],
|
|
961
|
+
});
|
|
962
|
+
} else {
|
|
963
|
+
throw error;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
// compute the changes in text mode
|
|
967
|
+
this.editorStore.changeDetectionState.computeLocalChangesInTextMode(
|
|
968
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState
|
|
969
|
+
.entities,
|
|
970
|
+
);
|
|
971
|
+
|
|
696
972
|
this.editorStore.applicationStore.log.info(
|
|
697
973
|
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
698
974
|
Date.now() - syncFinishedTime,
|