@finos/legend-application-studio 28.21.6 → 28.21.7

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.
Files changed (26) hide show
  1. package/lib/__lib__/LegendStudioUserDataHelper.d.ts +23 -1
  2. package/lib/__lib__/LegendStudioUserDataHelper.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioUserDataHelper.js +66 -1
  4. package/lib/__lib__/LegendStudioUserDataHelper.js.map +1 -1
  5. package/lib/components/workspace-setup/RecentWorkspacesPanel.d.ts.map +1 -1
  6. package/lib/components/workspace-setup/RecentWorkspacesPanel.js +11 -5
  7. package/lib/components/workspace-setup/RecentWorkspacesPanel.js.map +1 -1
  8. package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
  9. package/lib/components/workspace-setup/WorkspaceSetup.js +5 -6
  10. package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
  11. package/lib/index.css +2 -2
  12. package/lib/index.css.map +1 -1
  13. package/lib/package.json +1 -1
  14. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  15. package/lib/stores/editor/EditorStore.js +3 -0
  16. package/lib/stores/editor/EditorStore.js.map +1 -1
  17. package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts +6 -2
  18. package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
  19. package/lib/stores/workspace-setup/WorkspaceSetupStore.js +60 -8
  20. package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
  21. package/package.json +3 -3
  22. package/src/__lib__/LegendStudioUserDataHelper.ts +107 -2
  23. package/src/components/workspace-setup/RecentWorkspacesPanel.tsx +29 -9
  24. package/src/components/workspace-setup/WorkspaceSetup.tsx +5 -6
  25. package/src/stores/editor/EditorStore.ts +3 -0
  26. package/src/stores/workspace-setup/WorkspaceSetupStore.ts +79 -9
@@ -93,7 +93,6 @@ export class WorkspaceSetupStore {
93
93
  loadWorkspacesState = ActionState.create();
94
94
  createWorkspaceState = ActionState.create();
95
95
  showCreateWorkspaceModal = false;
96
- showAdvancedWorkspaceFilterOptions = false;
97
96
 
98
97
  graphManagerState: GraphManagerState;
99
98
 
@@ -115,7 +114,6 @@ export class WorkspaceSetupStore {
115
114
  showCreateProjectModal: observable,
116
115
  workspaces: observable,
117
116
  currentWorkspace: observable,
118
- showAdvancedWorkspaceFilterOptions: observable,
119
117
  loadSandboxState: observable,
120
118
  showCreateWorkspaceModal: observable,
121
119
  sandboxProject: observable,
@@ -128,7 +126,6 @@ export class WorkspaceSetupStore {
128
126
  recentWorkspaces: observable,
129
127
  setShowCreateProjectModal: action,
130
128
  setShowCreateWorkspaceModal: action,
131
- setShowAdvancedWorkspaceFilterOptions: action,
132
129
  setImportProjectSuccessReport: action,
133
130
  setSandboxModal: action,
134
131
  changeWorkspace: action,
@@ -183,10 +180,6 @@ export class WorkspaceSetupStore {
183
180
  this.showCreateWorkspaceModal = val;
184
181
  }
185
182
 
186
- setShowAdvancedWorkspaceFilterOptions(val: boolean): void {
187
- this.showAdvancedWorkspaceFilterOptions = val;
188
- }
189
-
190
183
  setImportProjectSuccessReport(
191
184
  importProjectSuccessReport: ImportProjectSuccessReport | undefined,
192
185
  ): void {
@@ -262,6 +255,12 @@ export class WorkspaceSetupStore {
262
255
  * Fetches a project by id (used when the user picks a cached "recent"
263
256
  * project that may not be in the current search results) and switches to
264
257
  * it. If the project no longer exists, the entry is pruned from recents.
258
+ *
259
+ * NOTE: we deliberately don't short-circuit using the cached recent entry
260
+ * here. Going through `getProject` keeps the prune-on-404 path intact, and
261
+ * the cached metadata is already used elsewhere to make the UI feel fast
262
+ * (dropdown stubs in `WorkspaceSetup.tsx` and tile labels in
263
+ * `RecentWorkspacesPanel.tsx`).
265
264
  */
266
265
  *selectRecentProject(projectId: string): GeneratorFn<void> {
267
266
  this.selectRecentProjectState.inProgress();
@@ -304,6 +303,12 @@ export class WorkspaceSetupStore {
304
303
  message: `Sandbox project ${sandboxProject.projectId} created. Creating default workspace...`,
305
304
  showLoading: true,
306
305
  });
306
+ // Invalidate the cached sandbox info so loadSandboxProject re-fetches
307
+ // and persists the newly-created project id instead of reusing the
308
+ // stale "no sandbox yet" cache entry.
309
+ LegendStudioUserDataHelper.workspaceSetup_clearSandboxInfo(
310
+ this.applicationStore.userDataService,
311
+ );
307
312
  yield flowResult(this.loadSandboxProject());
308
313
  const sandbox = guaranteeType(
309
314
  this.sandboxProject,
@@ -460,10 +465,58 @@ export class WorkspaceSetupStore {
460
465
  if (this.enginePromise) {
461
466
  yield this.enginePromise;
462
467
  }
468
+
469
+ const userId = this.sdlcServerClient.currentUser?.userId;
470
+
471
+ // Fast path — if we have a recent, user-matching cache entry, use it to
472
+ // avoid the `userHasPrototypeProjectAccess` graph manager call and the
473
+ // sandbox-tag project search. We still hit SDLC once to confirm the
474
+ // cached projectId is alive, but `getProject(id)` is cheaper than the
475
+ // tagged search and self-invalidates on 404.
476
+ if (userId) {
477
+ const cached =
478
+ LegendStudioUserDataHelper.workspaceSetup_getCachedSandboxInfo(
479
+ this.applicationStore.userDataService,
480
+ userId,
481
+ );
482
+ if (cached) {
483
+ this.hasSandboxAccess = cached.hasAccess;
484
+ if (!cached.hasAccess) {
485
+ // No access, no project — nothing else to do.
486
+ this.sandboxProject = true;
487
+ this.loadSandboxState.pass();
488
+ return;
489
+ }
490
+ if (cached.projectId) {
491
+ try {
492
+ this.sandboxProject = Project.serialization.fromJson(
493
+ (yield this.sdlcServerClient.getProject(
494
+ cached.projectId,
495
+ )) as PlainObject<Project>,
496
+ );
497
+ this.loadSandboxState.pass();
498
+ return;
499
+ } catch {
500
+ // Cached sandbox project no longer exists on the server; drop
501
+ // the cache and fall through to the full refresh.
502
+ LegendStudioUserDataHelper.workspaceSetup_clearSandboxInfo(
503
+ this.applicationStore.userDataService,
504
+ );
505
+ }
506
+ } else {
507
+ // User has access but hasn't created a sandbox yet.
508
+ this.sandboxProject = true;
509
+ this.loadSandboxState.pass();
510
+ return;
511
+ }
512
+ }
513
+ }
514
+
515
+ // Slow path — original flow.
463
516
  const sandboxProject = (
464
517
  (yield this.sdlcServerClient.getProjects(
465
518
  undefined,
466
- this.sdlcServerClient.currentUser?.userId,
519
+ userId,
467
520
  [SANDBOX_SDLC_TAG],
468
521
  1,
469
522
  )) as PlainObject<Project>[]
@@ -471,7 +524,7 @@ export class WorkspaceSetupStore {
471
524
  if (this.hasSandboxAccess === undefined) {
472
525
  this.hasSandboxAccess =
473
526
  (yield this.graphManagerState.graphManager.userHasPrototypeProjectAccess(
474
- this.sdlcServerClient.currentUser?.userId ?? '',
527
+ userId ?? '',
475
528
  )) as boolean;
476
529
  }
477
530
  this.sandboxProject = true;
@@ -482,6 +535,23 @@ export class WorkspaceSetupStore {
482
535
  } else if (sandboxProject.length === 1) {
483
536
  this.sandboxProject = guaranteeNonNullable(sandboxProject[0]);
484
537
  }
538
+
539
+ // Persist the fresh result for next time. We only cache when we have
540
+ // a userId (cache is scoped per user); anonymous sessions skip this.
541
+ if (userId) {
542
+ LegendStudioUserDataHelper.workspaceSetup_recordSandboxInfo(
543
+ this.applicationStore.userDataService,
544
+ {
545
+ userId,
546
+ hasAccess: this.hasSandboxAccess,
547
+ projectId:
548
+ this.sandboxProject instanceof Project
549
+ ? this.sandboxProject.projectId
550
+ : undefined,
551
+ },
552
+ );
553
+ }
554
+
485
555
  this.loadSandboxState.pass();
486
556
  } catch (error) {
487
557
  this.sandboxProject = true;