@finos/legend-application-studio 22.2.0 → 22.2.1
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/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/EditorGraphState.d.ts.map +1 -1
- package/lib/stores/EditorGraphState.js +10 -46
- package/lib/stores/EditorGraphState.js.map +1 -1
- package/lib/stores/EditorStore.d.ts +1 -1
- package/lib/stores/EditorStore.d.ts.map +1 -1
- package/lib/stores/EditorStore.js +8 -6
- package/lib/stores/EditorStore.js.map +1 -1
- package/lib/stores/EditorTabManagerState.d.ts +1 -2
- package/lib/stores/EditorTabManagerState.d.ts.map +1 -1
- package/lib/stores/EditorTabManagerState.js +2 -14
- package/lib/stores/EditorTabManagerState.js.map +1 -1
- package/lib/stores/ExplorerTreeState.d.ts.map +1 -1
- package/lib/stores/ExplorerTreeState.js +1 -3
- package/lib/stores/ExplorerTreeState.js.map +1 -1
- 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 +1 -0
- package/lib/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js.map +1 -1
- package/lib/stores/project-viewer/ProjectViewerStore.d.ts.map +1 -1
- package/lib/stores/project-viewer/ProjectViewerStore.js +1 -1
- package/lib/stores/project-viewer/ProjectViewerStore.js.map +1 -1
- package/lib/stores/sidebar-state/LocalChangesState.d.ts +16 -3
- package/lib/stores/sidebar-state/LocalChangesState.d.ts.map +1 -1
- package/lib/stores/sidebar-state/LocalChangesState.js +143 -246
- package/lib/stores/sidebar-state/LocalChangesState.js.map +1 -1
- package/package.json +10 -10
- package/src/stores/EditorGraphState.ts +18 -49
- package/src/stores/EditorStore.ts +12 -10
- package/src/stores/EditorTabManagerState.ts +1 -20
- package/src/stores/ExplorerTreeState.ts +4 -6
- package/src/stores/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.ts +2 -0
- package/src/stores/project-viewer/ProjectViewerStore.ts +3 -1
- package/src/stores/sidebar-state/LocalChangesState.ts +279 -450
|
@@ -189,6 +189,8 @@ export abstract class LocalChangesState {
|
|
|
189
189
|
refreshWorkspaceSyncStatus: flow,
|
|
190
190
|
refreshLocalChanges: flow,
|
|
191
191
|
pushLocalChanges: flow,
|
|
192
|
+
processConflicts: flow,
|
|
193
|
+
restartChangeDetection: flow,
|
|
192
194
|
});
|
|
193
195
|
|
|
194
196
|
this.editorStore = editorStore;
|
|
@@ -306,198 +308,15 @@ export abstract class LocalChangesState {
|
|
|
306
308
|
|
|
307
309
|
abstract refreshLocalChanges(): GeneratorFn<void>;
|
|
308
310
|
|
|
309
|
-
abstract
|
|
310
|
-
}
|
|
311
|
+
abstract processConflicts(): GeneratorFn<void>;
|
|
311
312
|
|
|
312
|
-
|
|
313
|
-
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
314
|
-
super(editorStore, sdlcState);
|
|
315
|
-
makeObservable(this, {
|
|
316
|
-
openPotentialWorkspacePullConflict: action,
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
openLocalChange(diff: EntityDiff): void {
|
|
320
|
-
const fromEntityGetter = (
|
|
321
|
-
entityPath: string | undefined,
|
|
322
|
-
): Entity | undefined => {
|
|
323
|
-
if (entityPath) {
|
|
324
|
-
return this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
325
|
-
(e) => e.path === entityPath,
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
return undefined;
|
|
329
|
-
};
|
|
330
|
-
const toEntityGetter = (
|
|
331
|
-
entityPath: string | undefined,
|
|
332
|
-
): Entity | undefined => {
|
|
333
|
-
if (!entityPath) {
|
|
334
|
-
return undefined;
|
|
335
|
-
}
|
|
336
|
-
const element =
|
|
337
|
-
this.editorStore.graphManagerState.graph.getNullableElement(entityPath);
|
|
338
|
-
if (!element) {
|
|
339
|
-
return undefined;
|
|
340
|
-
}
|
|
341
|
-
const entity =
|
|
342
|
-
this.editorStore.graphManagerState.graphManager.elementToEntity(
|
|
343
|
-
element,
|
|
344
|
-
{
|
|
345
|
-
pruneSourceInformation: true,
|
|
346
|
-
},
|
|
347
|
-
);
|
|
348
|
-
return entity;
|
|
349
|
-
};
|
|
350
|
-
const fromEntity = EntityDiff.shouldOldEntityExist(diff)
|
|
351
|
-
? guaranteeNonNullable(
|
|
352
|
-
fromEntityGetter(diff.getValidatedOldPath()),
|
|
353
|
-
`Can't find entity with path '${diff.oldPath}'`,
|
|
354
|
-
)
|
|
355
|
-
: undefined;
|
|
356
|
-
const toEntity = EntityDiff.shouldNewEntityExist(diff)
|
|
357
|
-
? guaranteeNonNullable(
|
|
358
|
-
toEntityGetter(diff.getValidatedNewPath()),
|
|
359
|
-
`Can't find entity with path '${diff.newPath}'`,
|
|
360
|
-
)
|
|
361
|
-
: undefined;
|
|
362
|
-
this.editorStore.tabManagerState.openTab(
|
|
363
|
-
new EntityDiffViewState(
|
|
364
|
-
this.editorStore,
|
|
365
|
-
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
366
|
-
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
367
|
-
diff.oldPath,
|
|
368
|
-
diff.newPath,
|
|
369
|
-
fromEntity,
|
|
370
|
-
toEntity,
|
|
371
|
-
fromEntityGetter,
|
|
372
|
-
toEntityGetter,
|
|
373
|
-
),
|
|
374
|
-
);
|
|
375
|
-
}
|
|
313
|
+
abstract getLocalChanges(): EntityChange[];
|
|
376
314
|
|
|
377
|
-
|
|
378
|
-
const fromEntityGetter = (
|
|
379
|
-
entityPath: string | undefined,
|
|
380
|
-
): Entity | undefined => {
|
|
381
|
-
if (entityPath) {
|
|
382
|
-
return this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
383
|
-
(e) => e.path === entityPath,
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
return undefined;
|
|
387
|
-
};
|
|
388
|
-
const toEntityGetter = (
|
|
389
|
-
entityPath: string | undefined,
|
|
390
|
-
): Entity | undefined => {
|
|
391
|
-
if (entityPath) {
|
|
392
|
-
return this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.entities.find(
|
|
393
|
-
(e) => e.path === entityPath,
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
|
-
return undefined;
|
|
397
|
-
};
|
|
398
|
-
const fromEntity = EntityDiff.shouldOldEntityExist(diff)
|
|
399
|
-
? guaranteeNonNullable(
|
|
400
|
-
fromEntityGetter(diff.getValidatedOldPath()),
|
|
401
|
-
`Can't find entity with path '${diff.oldPath}'`,
|
|
402
|
-
)
|
|
403
|
-
: undefined;
|
|
404
|
-
const toEntity = EntityDiff.shouldNewEntityExist(diff)
|
|
405
|
-
? guaranteeNonNullable(
|
|
406
|
-
toEntityGetter(diff.getValidatedNewPath()),
|
|
407
|
-
`Can't find entity with path '${diff.newPath}'`,
|
|
408
|
-
)
|
|
409
|
-
: undefined;
|
|
410
|
-
this.editorStore.tabManagerState.openTab(
|
|
411
|
-
new EntityDiffViewState(
|
|
412
|
-
this.editorStore,
|
|
413
|
-
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
414
|
-
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
415
|
-
diff.oldPath,
|
|
416
|
-
diff.newPath,
|
|
417
|
-
fromEntity,
|
|
418
|
-
toEntity,
|
|
419
|
-
fromEntityGetter,
|
|
420
|
-
toEntityGetter,
|
|
421
|
-
),
|
|
422
|
-
);
|
|
423
|
-
}
|
|
315
|
+
abstract getCurrentHashIndexes(): Map<string, string>;
|
|
424
316
|
|
|
425
|
-
|
|
426
|
-
const baseEntityGetter = (
|
|
427
|
-
entityPath: string | undefined,
|
|
428
|
-
): Entity | undefined =>
|
|
429
|
-
entityPath
|
|
430
|
-
? this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
431
|
-
(e) => e.path === entityPath,
|
|
432
|
-
)
|
|
433
|
-
: undefined;
|
|
434
|
-
const currentChangeEntityGetter = (
|
|
435
|
-
entityPath: string | undefined,
|
|
436
|
-
): Entity | undefined =>
|
|
437
|
-
entityPath
|
|
438
|
-
? this.editorStore.graphManagerState.graph.allOwnElements
|
|
439
|
-
.map((element) =>
|
|
440
|
-
this.editorStore.graphManagerState.graphManager.elementToEntity(
|
|
441
|
-
element,
|
|
442
|
-
),
|
|
443
|
-
)
|
|
444
|
-
.find((e) => e.path === entityPath)
|
|
445
|
-
: undefined;
|
|
446
|
-
const incomingChangeEntityGetter = (
|
|
447
|
-
entityPath: string | undefined,
|
|
448
|
-
): Entity | undefined =>
|
|
449
|
-
entityPath
|
|
450
|
-
? this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.entities.find(
|
|
451
|
-
(e) => e.path === entityPath,
|
|
452
|
-
)
|
|
453
|
-
: undefined;
|
|
454
|
-
const conflictEditorState = new EntityChangeConflictEditorState(
|
|
455
|
-
this.editorStore,
|
|
456
|
-
this.editorStore.conflictResolutionState,
|
|
457
|
-
conflict.entityPath,
|
|
458
|
-
SPECIAL_REVISION_ALIAS.WORKSPACE_BASE,
|
|
459
|
-
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
460
|
-
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
461
|
-
baseEntityGetter(conflict.entityPath),
|
|
462
|
-
currentChangeEntityGetter(conflict.entityPath),
|
|
463
|
-
incomingChangeEntityGetter(conflict.entityPath),
|
|
464
|
-
baseEntityGetter,
|
|
465
|
-
currentChangeEntityGetter,
|
|
466
|
-
incomingChangeEntityGetter,
|
|
467
|
-
);
|
|
468
|
-
conflictEditorState.setReadOnly(true);
|
|
469
|
-
this.editorStore.tabManagerState.openTab(conflictEditorState);
|
|
470
|
-
}
|
|
317
|
+
abstract stopChangeDetection(): void;
|
|
471
318
|
|
|
472
|
-
|
|
473
|
-
const startTime = Date.now();
|
|
474
|
-
this.refreshLocalChangesDetectorState.inProgress();
|
|
475
|
-
try {
|
|
476
|
-
// ======= (RE)START CHANGE DETECTION =======
|
|
477
|
-
this.editorStore.changeDetectionState.stop();
|
|
478
|
-
yield Promise.all([
|
|
479
|
-
this.sdlcState.buildWorkspaceLatestRevisionEntityHashesIndex(),
|
|
480
|
-
this.editorStore.changeDetectionState.preComputeGraphElementHashes(),
|
|
481
|
-
]);
|
|
482
|
-
this.editorStore.changeDetectionState.start();
|
|
483
|
-
this.editorStore.applicationStore.log.info(
|
|
484
|
-
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
485
|
-
Date.now() - startTime,
|
|
486
|
-
'ms',
|
|
487
|
-
);
|
|
488
|
-
// ======= FINISHED (RE)START CHANGE DETECTION =======
|
|
489
|
-
} catch (error) {
|
|
490
|
-
assertErrorThrown(error);
|
|
491
|
-
this.editorStore.applicationStore.log.error(
|
|
492
|
-
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
493
|
-
error,
|
|
494
|
-
);
|
|
495
|
-
this.editorStore.applicationStore.notifyError(error);
|
|
496
|
-
this.sdlcState.handleChangeDetectionRefreshIssue(error);
|
|
497
|
-
} finally {
|
|
498
|
-
this.refreshLocalChangesDetectorState.complete();
|
|
499
|
-
}
|
|
500
|
-
}
|
|
319
|
+
abstract restartChangeDetection(): GeneratorFn<void>;
|
|
501
320
|
|
|
502
321
|
*pushLocalChanges(pushMessage?: string): GeneratorFn<void> {
|
|
503
322
|
if (
|
|
@@ -507,29 +326,11 @@ export class FormLocalChangesState extends LocalChangesState {
|
|
|
507
326
|
return;
|
|
508
327
|
}
|
|
509
328
|
// check if the workspace is in conflict resolution mode
|
|
510
|
-
|
|
511
|
-
const isInConflictResolutionMode = (yield flowResult(
|
|
512
|
-
this.sdlcState.checkIfCurrentWorkspaceIsInConflictResolutionMode(),
|
|
513
|
-
)) as boolean;
|
|
514
|
-
if (isInConflictResolutionMode) {
|
|
515
|
-
this.editorStore.applicationStore.setBlockingAlert({
|
|
516
|
-
message: 'Workspace is in conflict resolution mode',
|
|
517
|
-
prompt: 'Please refresh the application',
|
|
518
|
-
});
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
} catch (error) {
|
|
522
|
-
assertErrorThrown(error);
|
|
523
|
-
this.editorStore.applicationStore.notifyWarning(
|
|
524
|
-
'Failed to check if current workspace is in conflict resolution mode',
|
|
525
|
-
);
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
329
|
+
yield flowResult(this.processConflicts());
|
|
528
330
|
|
|
529
331
|
this.pushChangesState.inProgress();
|
|
530
332
|
const startTime = Date.now();
|
|
531
|
-
const localChanges =
|
|
532
|
-
this.editorStore.graphState.computeLocalEntityChanges();
|
|
333
|
+
const localChanges = this.getLocalChanges();
|
|
533
334
|
if (!localChanges.length) {
|
|
534
335
|
this.pushChangesState.complete();
|
|
535
336
|
return;
|
|
@@ -587,8 +388,7 @@ export class FormLocalChangesState extends LocalChangesState {
|
|
|
587
388
|
this.pushChangesState.complete();
|
|
588
389
|
return;
|
|
589
390
|
}
|
|
590
|
-
const currentHashesIndex =
|
|
591
|
-
this.editorStore.changeDetectionState.snapshotLocalEntityHashesIndex();
|
|
391
|
+
const currentHashesIndex = this.getCurrentHashIndexes();
|
|
592
392
|
|
|
593
393
|
try {
|
|
594
394
|
const nullableRevisionChange =
|
|
@@ -626,7 +426,7 @@ export class FormLocalChangesState extends LocalChangesState {
|
|
|
626
426
|
|
|
627
427
|
// ======= (RE)START CHANGE DETECTION =======
|
|
628
428
|
|
|
629
|
-
this.
|
|
429
|
+
this.stopChangeDetection();
|
|
630
430
|
|
|
631
431
|
try {
|
|
632
432
|
/**
|
|
@@ -700,14 +500,7 @@ export class FormLocalChangesState extends LocalChangesState {
|
|
|
700
500
|
throw error;
|
|
701
501
|
}
|
|
702
502
|
}
|
|
703
|
-
yield this.
|
|
704
|
-
this.editorStore.changeDetectionState.start();
|
|
705
|
-
yield Promise.all([
|
|
706
|
-
this.editorStore.changeDetectionState.computeAggregatedWorkspaceChanges(
|
|
707
|
-
true,
|
|
708
|
-
),
|
|
709
|
-
]);
|
|
710
|
-
|
|
503
|
+
yield flowResult(this.restartChangeDetection());
|
|
711
504
|
this.editorStore.applicationStore.log.info(
|
|
712
505
|
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
713
506
|
Date.now() - syncFinishedTime,
|
|
@@ -739,263 +532,299 @@ export class FormLocalChangesState extends LocalChangesState {
|
|
|
739
532
|
}
|
|
740
533
|
}
|
|
741
534
|
|
|
742
|
-
export class
|
|
743
|
-
localChanges: EntityChange[] = [];
|
|
744
|
-
|
|
535
|
+
export class FormLocalChangesState extends LocalChangesState {
|
|
745
536
|
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
746
537
|
super(editorStore, sdlcState);
|
|
747
538
|
makeObservable(this, {
|
|
748
|
-
|
|
539
|
+
openPotentialWorkspacePullConflict: action,
|
|
749
540
|
});
|
|
750
541
|
}
|
|
542
|
+
openLocalChange(diff: EntityDiff): void {
|
|
543
|
+
const fromEntityGetter = (
|
|
544
|
+
entityPath: string | undefined,
|
|
545
|
+
): Entity | undefined => {
|
|
546
|
+
if (entityPath) {
|
|
547
|
+
return this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
548
|
+
(e) => e.path === entityPath,
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
return undefined;
|
|
552
|
+
};
|
|
553
|
+
const toEntityGetter = (
|
|
554
|
+
entityPath: string | undefined,
|
|
555
|
+
): Entity | undefined => {
|
|
556
|
+
if (!entityPath) {
|
|
557
|
+
return undefined;
|
|
558
|
+
}
|
|
559
|
+
const element =
|
|
560
|
+
this.editorStore.graphManagerState.graph.getNullableElement(entityPath);
|
|
561
|
+
if (!element) {
|
|
562
|
+
return undefined;
|
|
563
|
+
}
|
|
564
|
+
const entity =
|
|
565
|
+
this.editorStore.graphManagerState.graphManager.elementToEntity(
|
|
566
|
+
element,
|
|
567
|
+
{
|
|
568
|
+
pruneSourceInformation: true,
|
|
569
|
+
},
|
|
570
|
+
);
|
|
571
|
+
return entity;
|
|
572
|
+
};
|
|
573
|
+
const fromEntity = EntityDiff.shouldOldEntityExist(diff)
|
|
574
|
+
? guaranteeNonNullable(
|
|
575
|
+
fromEntityGetter(diff.getValidatedOldPath()),
|
|
576
|
+
`Can't find entity with path '${diff.oldPath}'`,
|
|
577
|
+
)
|
|
578
|
+
: undefined;
|
|
579
|
+
const toEntity = EntityDiff.shouldNewEntityExist(diff)
|
|
580
|
+
? guaranteeNonNullable(
|
|
581
|
+
toEntityGetter(diff.getValidatedNewPath()),
|
|
582
|
+
`Can't find entity with path '${diff.newPath}'`,
|
|
583
|
+
)
|
|
584
|
+
: undefined;
|
|
585
|
+
this.editorStore.tabManagerState.openTab(
|
|
586
|
+
new EntityDiffViewState(
|
|
587
|
+
this.editorStore,
|
|
588
|
+
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
589
|
+
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
590
|
+
diff.oldPath,
|
|
591
|
+
diff.newPath,
|
|
592
|
+
fromEntity,
|
|
593
|
+
toEntity,
|
|
594
|
+
fromEntityGetter,
|
|
595
|
+
toEntityGetter,
|
|
596
|
+
),
|
|
597
|
+
);
|
|
598
|
+
}
|
|
751
599
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
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,
|
|
600
|
+
openWorkspacePullChange(diff: EntityDiff): void {
|
|
601
|
+
const fromEntityGetter = (
|
|
602
|
+
entityPath: string | undefined,
|
|
603
|
+
): Entity | undefined => {
|
|
604
|
+
if (entityPath) {
|
|
605
|
+
return this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
606
|
+
(e) => e.path === entityPath,
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
return undefined;
|
|
610
|
+
};
|
|
611
|
+
const toEntityGetter = (
|
|
612
|
+
entityPath: string | undefined,
|
|
613
|
+
): Entity | undefined => {
|
|
614
|
+
if (entityPath) {
|
|
615
|
+
return this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.entities.find(
|
|
616
|
+
(e) => e.path === entityPath,
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
return undefined;
|
|
620
|
+
};
|
|
621
|
+
const fromEntity = EntityDiff.shouldOldEntityExist(diff)
|
|
622
|
+
? guaranteeNonNullable(
|
|
623
|
+
fromEntityGetter(diff.getValidatedOldPath()),
|
|
624
|
+
`Can't find entity with path '${diff.oldPath}'`,
|
|
625
|
+
)
|
|
626
|
+
: undefined;
|
|
627
|
+
const toEntity = EntityDiff.shouldNewEntityExist(diff)
|
|
628
|
+
? guaranteeNonNullable(
|
|
629
|
+
toEntityGetter(diff.getValidatedNewPath()),
|
|
630
|
+
`Can't find entity with path '${diff.newPath}'`,
|
|
631
|
+
)
|
|
632
|
+
: undefined;
|
|
633
|
+
this.editorStore.tabManagerState.openTab(
|
|
634
|
+
new EntityDiffViewState(
|
|
635
|
+
this.editorStore,
|
|
636
|
+
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
637
|
+
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
638
|
+
diff.oldPath,
|
|
639
|
+
diff.newPath,
|
|
640
|
+
fromEntity,
|
|
641
|
+
toEntity,
|
|
642
|
+
fromEntityGetter,
|
|
643
|
+
toEntityGetter,
|
|
806
644
|
),
|
|
807
645
|
);
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
openPotentialWorkspacePullConflict(conflict: EntityChangeConflict): void {
|
|
649
|
+
const baseEntityGetter = (
|
|
650
|
+
entityPath: string | undefined,
|
|
651
|
+
): Entity | undefined =>
|
|
652
|
+
entityPath
|
|
653
|
+
? this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState.entities.find(
|
|
654
|
+
(e) => e.path === entityPath,
|
|
655
|
+
)
|
|
656
|
+
: undefined;
|
|
657
|
+
const currentChangeEntityGetter = (
|
|
658
|
+
entityPath: string | undefined,
|
|
659
|
+
): Entity | undefined =>
|
|
660
|
+
entityPath
|
|
661
|
+
? this.editorStore.graphManagerState.graph.allOwnElements
|
|
662
|
+
.map((element) =>
|
|
663
|
+
this.editorStore.graphManagerState.graphManager.elementToEntity(
|
|
664
|
+
element,
|
|
665
|
+
),
|
|
666
|
+
)
|
|
667
|
+
.find((e) => e.path === entityPath)
|
|
668
|
+
: undefined;
|
|
669
|
+
const incomingChangeEntityGetter = (
|
|
670
|
+
entityPath: string | undefined,
|
|
671
|
+
): Entity | undefined =>
|
|
672
|
+
entityPath
|
|
673
|
+
? this.editorStore.changeDetectionState.workspaceRemoteLatestRevisionState.entities.find(
|
|
674
|
+
(e) => e.path === entityPath,
|
|
675
|
+
)
|
|
676
|
+
: undefined;
|
|
677
|
+
const conflictEditorState = new EntityChangeConflictEditorState(
|
|
678
|
+
this.editorStore,
|
|
679
|
+
this.editorStore.conflictResolutionState,
|
|
680
|
+
conflict.entityPath,
|
|
681
|
+
SPECIAL_REVISION_ALIAS.WORKSPACE_BASE,
|
|
682
|
+
SPECIAL_REVISION_ALIAS.LOCAL,
|
|
683
|
+
SPECIAL_REVISION_ALIAS.WORKSPACE_HEAD,
|
|
684
|
+
baseEntityGetter(conflict.entityPath),
|
|
685
|
+
currentChangeEntityGetter(conflict.entityPath),
|
|
686
|
+
incomingChangeEntityGetter(conflict.entityPath),
|
|
687
|
+
baseEntityGetter,
|
|
688
|
+
currentChangeEntityGetter,
|
|
689
|
+
incomingChangeEntityGetter,
|
|
690
|
+
);
|
|
691
|
+
conflictEditorState.setReadOnly(true);
|
|
692
|
+
this.editorStore.tabManagerState.openTab(conflictEditorState);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
*refreshLocalChanges(): GeneratorFn<void> {
|
|
696
|
+
const startTime = Date.now();
|
|
697
|
+
this.refreshLocalChangesDetectorState.inProgress();
|
|
698
|
+
try {
|
|
699
|
+
// ======= (RE)START CHANGE DETECTION =======
|
|
700
|
+
this.editorStore.changeDetectionState.stop();
|
|
701
|
+
yield Promise.all([
|
|
702
|
+
this.sdlcState.buildWorkspaceLatestRevisionEntityHashesIndex(),
|
|
703
|
+
this.editorStore.changeDetectionState.preComputeGraphElementHashes(),
|
|
704
|
+
]);
|
|
705
|
+
this.editorStore.changeDetectionState.start();
|
|
706
|
+
this.editorStore.applicationStore.log.info(
|
|
707
|
+
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
708
|
+
Date.now() - startTime,
|
|
709
|
+
'ms',
|
|
826
710
|
);
|
|
827
|
-
|
|
828
|
-
|
|
711
|
+
// ======= FINISHED (RE)START CHANGE DETECTION =======
|
|
712
|
+
} catch (error) {
|
|
713
|
+
assertErrorThrown(error);
|
|
714
|
+
this.editorStore.applicationStore.log.error(
|
|
715
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
716
|
+
error,
|
|
829
717
|
);
|
|
830
|
-
this.editorStore.applicationStore.
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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;
|
|
718
|
+
this.editorStore.applicationStore.notifyError(error);
|
|
719
|
+
this.sdlcState.handleChangeDetectionRefreshIssue(error);
|
|
720
|
+
} finally {
|
|
721
|
+
this.refreshLocalChangesDetectorState.complete();
|
|
854
722
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
*processConflicts(): GeneratorFn<void> {
|
|
858
726
|
try {
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
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`,
|
|
727
|
+
const isInConflictResolutionMode = (yield flowResult(
|
|
728
|
+
this.sdlcState.checkIfCurrentWorkspaceIsInConflictResolutionMode(),
|
|
729
|
+
)) as boolean;
|
|
730
|
+
if (isInConflictResolutionMode) {
|
|
731
|
+
this.editorStore.applicationStore.setBlockingAlert({
|
|
732
|
+
message: 'Workspace is in conflict resolution mode',
|
|
733
|
+
prompt: 'Please refresh the application',
|
|
734
|
+
});
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
} catch (error) {
|
|
738
|
+
assertErrorThrown(error);
|
|
739
|
+
this.editorStore.applicationStore.notifyWarning(
|
|
740
|
+
'Failed to check if current workspace is in conflict resolution mode',
|
|
880
741
|
);
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
const syncFinishedTime = Date.now();
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
885
745
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
'ms',
|
|
890
|
-
);
|
|
891
|
-
this.localChanges = [];
|
|
746
|
+
getLocalChanges(): EntityChange[] {
|
|
747
|
+
return this.editorStore.graphState.computeLocalEntityChanges();
|
|
748
|
+
}
|
|
892
749
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
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
|
|
750
|
+
getCurrentHashIndexes(): Map<string, string> {
|
|
751
|
+
return this.editorStore.changeDetectionState.snapshotLocalEntityHashesIndex();
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
stopChangeDetection(): void {
|
|
755
|
+
this.editorStore.changeDetectionState.stop();
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
*restartChangeDetection(): GeneratorFn<void> {
|
|
759
|
+
yield this.editorStore.changeDetectionState.preComputeGraphElementHashes();
|
|
760
|
+
this.editorStore.changeDetectionState.start();
|
|
761
|
+
yield Promise.all([
|
|
762
|
+
this.editorStore.changeDetectionState.computeAggregatedWorkspaceChanges(
|
|
763
|
+
true,
|
|
764
|
+
),
|
|
765
|
+
]);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
export class TextLocalChangesState extends LocalChangesState {
|
|
770
|
+
localChanges: EntityChange[] = [];
|
|
771
|
+
|
|
772
|
+
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
773
|
+
super(editorStore, sdlcState);
|
|
774
|
+
makeObservable(this, {
|
|
775
|
+
setLocalChanges: action,
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
setLocalChanges(val: EntityChange[]): void {
|
|
780
|
+
this.localChanges = val;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
*refreshLocalChanges(): GeneratorFn<void> {
|
|
784
|
+
this.refreshLocalChangesDetectorState.inProgress();
|
|
785
|
+
try {
|
|
786
|
+
yield Promise.all([
|
|
787
|
+
this.sdlcState.buildWorkspaceLatestRevisionEntityHashesIndex(),
|
|
788
|
+
this.editorStore.changeDetectionState.preComputeGraphElementHashes(),
|
|
789
|
+
]);
|
|
967
790
|
this.editorStore.changeDetectionState.computeLocalChangesInTextMode(
|
|
968
791
|
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState
|
|
969
792
|
.entities,
|
|
970
793
|
);
|
|
971
|
-
|
|
972
|
-
this.editorStore.applicationStore.log.info(
|
|
973
|
-
LogEvent.create(CHANGE_DETECTION_EVENT.CHANGE_DETECTION_RESTARTED),
|
|
974
|
-
Date.now() - syncFinishedTime,
|
|
975
|
-
'ms',
|
|
976
|
-
);
|
|
977
|
-
// ======= FINISHED (RE)START CHANGE DETECTION =======
|
|
978
794
|
} catch (error) {
|
|
979
795
|
assertErrorThrown(error);
|
|
980
796
|
this.editorStore.applicationStore.log.error(
|
|
981
797
|
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE),
|
|
982
798
|
error,
|
|
983
799
|
);
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
error.response.status === HttpStatus.CONFLICT
|
|
987
|
-
) {
|
|
988
|
-
// NOTE: a confict here indicates that the reference revision ID sent along with update call
|
|
989
|
-
// does not match the HEAD of the workspace, therefore, we need to prompt user to refresh the application
|
|
990
|
-
this.editorStore.applicationStore.notifyWarning(
|
|
991
|
-
'Syncing failed. Current workspace revision is not the latest. Please backup your work and refresh the application',
|
|
992
|
-
);
|
|
993
|
-
// TODO: maybe we should do more here, e.g. prompt the user to download the patch, but that is for later
|
|
994
|
-
} else {
|
|
995
|
-
this.editorStore.applicationStore.notifyError(error);
|
|
996
|
-
}
|
|
800
|
+
this.editorStore.applicationStore.notifyError(error);
|
|
801
|
+
this.sdlcState.handleChangeDetectionRefreshIssue(error);
|
|
997
802
|
} finally {
|
|
998
|
-
this.
|
|
803
|
+
this.refreshLocalChangesDetectorState.complete();
|
|
999
804
|
}
|
|
1000
805
|
}
|
|
806
|
+
|
|
807
|
+
*processConflicts(): GeneratorFn<void> {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
getLocalChanges(): EntityChange[] {
|
|
812
|
+
return this.localChanges;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
getCurrentHashIndexes(): Map<string, string> {
|
|
816
|
+
return this.editorStore.changeDetectionState
|
|
817
|
+
.workspaceLocalLatestRevisionState.currentEntityHashesIndex;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
stopChangeDetection(): void {
|
|
821
|
+
this.localChanges = [];
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
*restartChangeDetection(): GeneratorFn<void> {
|
|
825
|
+
this.editorStore.changeDetectionState.computeLocalChangesInTextMode(
|
|
826
|
+
this.editorStore.changeDetectionState.workspaceLocalLatestRevisionState
|
|
827
|
+
.entities,
|
|
828
|
+
);
|
|
829
|
+
}
|
|
1001
830
|
}
|