@finos/legend-application-query 13.4.15 → 13.4.17

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 (61) hide show
  1. package/lib/__lib__/LegendQueryEvent.d.ts +2 -1
  2. package/lib/__lib__/LegendQueryEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendQueryEvent.js +1 -0
  4. package/lib/__lib__/LegendQueryEvent.js.map +1 -1
  5. package/lib/__lib__/LegendQueryUserDataHelper.d.ts +23 -3
  6. package/lib/__lib__/LegendQueryUserDataHelper.d.ts.map +1 -1
  7. package/lib/__lib__/LegendQueryUserDataHelper.js +94 -14
  8. package/lib/__lib__/LegendQueryUserDataHelper.js.map +1 -1
  9. package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts +31 -0
  10. package/lib/__lib__/LegendQueryUserDataSpaceHelper.d.ts.map +1 -0
  11. package/lib/__lib__/LegendQueryUserDataSpaceHelper.js +54 -0
  12. package/lib/__lib__/LegendQueryUserDataSpaceHelper.js.map +1 -0
  13. package/lib/components/CloneQueryServiceSetup.js +1 -2
  14. package/lib/components/CloneQueryServiceSetup.js.map +1 -1
  15. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts +1 -1
  16. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
  17. package/lib/components/Core_LegendQueryApplicationPlugin.js +58 -16
  18. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
  19. package/lib/components/CreateMappingQuerySetup.js +1 -2
  20. package/lib/components/CreateMappingQuerySetup.js.map +1 -1
  21. package/lib/components/LegendQueryAppInfo.d.ts +21 -0
  22. package/lib/components/LegendQueryAppInfo.d.ts.map +1 -0
  23. package/lib/components/LegendQueryAppInfo.js +46 -0
  24. package/lib/components/LegendQueryAppInfo.js.map +1 -0
  25. package/lib/components/QueryEditor.d.ts.map +1 -1
  26. package/lib/components/QueryEditor.js +9 -8
  27. package/lib/components/QueryEditor.js.map +1 -1
  28. package/lib/components/QueryEdtiorExistingQueryVersionRevertModal.js +1 -1
  29. package/lib/components/QueryEdtiorExistingQueryVersionRevertModal.js.map +1 -1
  30. package/lib/components/data-space/DataSpaceQuerySetup.js +1 -1
  31. package/lib/components/data-space/DataSpaceQuerySetup.js.map +1 -1
  32. package/lib/index.css +2 -2
  33. package/lib/index.css.map +1 -1
  34. package/lib/package.json +3 -3
  35. package/lib/stores/QueryEditorStore.d.ts +3 -0
  36. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  37. package/lib/stores/QueryEditorStore.js +13 -1
  38. package/lib/stores/QueryEditorStore.js.map +1 -1
  39. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts +2 -0
  40. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +1 -1
  41. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +21 -2
  42. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +1 -1
  43. package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts +10 -2
  44. package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts.map +1 -1
  45. package/lib/stores/data-space/DataSpaceQuerySetupState.js +53 -3
  46. package/lib/stores/data-space/DataSpaceQuerySetupState.js.map +1 -1
  47. package/package.json +13 -13
  48. package/src/__lib__/LegendQueryEvent.ts +2 -0
  49. package/src/__lib__/LegendQueryUserDataHelper.ts +192 -18
  50. package/src/__lib__/LegendQueryUserDataSpaceHelper.ts +98 -0
  51. package/src/components/CloneQueryServiceSetup.tsx +1 -1
  52. package/src/components/Core_LegendQueryApplicationPlugin.tsx +89 -41
  53. package/src/components/CreateMappingQuerySetup.tsx +1 -1
  54. package/src/components/LegendQueryAppInfo.tsx +153 -0
  55. package/src/components/QueryEditor.tsx +15 -11
  56. package/src/components/QueryEdtiorExistingQueryVersionRevertModal.tsx +1 -1
  57. package/src/components/data-space/DataSpaceQuerySetup.tsx +1 -1
  58. package/src/stores/QueryEditorStore.ts +19 -0
  59. package/src/stores/data-space/DataSpaceQueryCreatorStore.ts +59 -0
  60. package/src/stores/data-space/DataSpaceQuerySetupState.ts +92 -4
  61. package/tsconfig.json +2 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ CopyIcon,
19
+ Dialog,
20
+ InfoCircleIcon,
21
+ Modal,
22
+ ModalBody,
23
+ ModalHeader,
24
+ ModalHeaderActions,
25
+ ModalTitle,
26
+ TimesIcon,
27
+ } from '@finos/legend-art';
28
+ import { isNonNullable } from '@finos/legend-shared';
29
+ import { useQueryEditorStore } from './QueryEditorStoreProvider.js';
30
+
31
+ export const LegendQueryInfo: React.FC<{
32
+ open: boolean;
33
+ closeModal: () => void;
34
+ }> = (props) => {
35
+ const { open, closeModal } = props;
36
+ const editorStore = useQueryEditorStore();
37
+ const applicationStore = editorStore.applicationStore;
38
+ const config = applicationStore.config;
39
+ const copyInfo = (): void => {
40
+ applicationStore.clipboardService
41
+ .copyTextToClipboard(
42
+ [
43
+ `Environment: ${config.env}`,
44
+ `Version: ${config.appVersion}`,
45
+ `Revision: ${config.appVersionCommitId}`,
46
+ `Build Time: ${config.appVersionBuildTime}`,
47
+ `Engine Server: ${config.engineServerUrl}`,
48
+ `Depot Server: ${config.depotServerUrl}`,
49
+ ]
50
+ .filter(isNonNullable)
51
+ .join('\n'),
52
+ )
53
+ .then(() =>
54
+ applicationStore.notificationService.notifySuccess(
55
+ 'Copied application info to clipboard',
56
+ ),
57
+ )
58
+ .catch(applicationStore.alertUnhandledError);
59
+ };
60
+
61
+ const goToReleaseLog = (): void => {
62
+ closeModal();
63
+ applicationStore.releaseNotesService.setReleaseLog(true);
64
+ };
65
+
66
+ return (
67
+ <Dialog onClose={closeModal} open={open}>
68
+ <Modal
69
+ darkMode={
70
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
71
+ }
72
+ className="modal--scrollable app__info"
73
+ >
74
+ <ModalHeader>
75
+ <ModalTitle icon={<InfoCircleIcon />} title="About Legend Query" />
76
+ <ModalHeaderActions>
77
+ <button
78
+ className="modal__header__action"
79
+ tabIndex={-1}
80
+ onClick={copyInfo}
81
+ title="Copy application info"
82
+ >
83
+ <CopyIcon />
84
+ </button>
85
+ <button
86
+ className="modal__header__action"
87
+ tabIndex={-1}
88
+ onClick={closeModal}
89
+ >
90
+ <TimesIcon />
91
+ </button>
92
+ </ModalHeaderActions>
93
+ </ModalHeader>
94
+ <ModalBody>
95
+ <div className="app__info__entry">
96
+ <div className="app__info__entry__title">Environment:</div>
97
+ <div className="app__info__entry__value">{config.env}</div>
98
+ </div>
99
+ <div className="app__info__entry">
100
+ <div className="app__info__entry__title">Version:</div>
101
+ <div className="app__info__entry__value">{config.appVersion}</div>
102
+ </div>
103
+ <div className="app__info__entry">
104
+ <div className="app__info__entry__title">Revision:</div>
105
+ <div className="app__info__entry__value">
106
+ {config.appVersionCommitId}
107
+ </div>
108
+ </div>
109
+ <div className="app__info__entry">
110
+ <div className="app__info__entry__title">Build Time:</div>
111
+ <div className="app__info__entry__value">
112
+ {config.appVersionBuildTime}
113
+ </div>
114
+ </div>
115
+ <div className="app__info__entry">
116
+ <div
117
+ onClick={goToReleaseLog}
118
+ className="app__info__entry__value app__info__entry__value__action"
119
+ >
120
+ Details of Released Versions
121
+ </div>
122
+ </div>
123
+ <div className="app__info__group">
124
+ <div className="app__info__entry">
125
+ <div className="app__info__entry__title">Engine Server:</div>
126
+ <div className="app__info__entry__value">
127
+ <a
128
+ href={config.engineServerUrl}
129
+ target="_blank"
130
+ rel="noopener noreferrer"
131
+ >
132
+ {config.engineServerUrl}
133
+ </a>
134
+ </div>
135
+ </div>
136
+ <div className="app__info__entry">
137
+ <div className="app__info__entry__title">Depot Server:</div>
138
+ <div className="app__info__entry__value">
139
+ <a
140
+ href={config.depotServerUrl}
141
+ target="_blank"
142
+ rel="noopener noreferrer"
143
+ >
144
+ {config.depotServerUrl}
145
+ </a>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </ModalBody>
150
+ </Modal>
151
+ </Dialog>
152
+ );
153
+ };
@@ -45,7 +45,7 @@ import {
45
45
  SunIcon,
46
46
  } from '@finos/legend-art';
47
47
  import { observer } from 'mobx-react-lite';
48
- import { Fragment, useEffect, useMemo, useRef, useState } from 'react';
48
+ import { useEffect, useMemo, useRef, useState } from 'react';
49
49
  import {
50
50
  type MappingQueryCreatorPathParams,
51
51
  type ExistingQueryEditorPathParams,
@@ -58,6 +58,8 @@ import {
58
58
  import { ExistingQueryEditorStore } from '../stores/QueryEditorStore.js';
59
59
  import {
60
60
  LEGEND_APPLICATION_COLOR_THEME,
61
+ ReleaseLogManager,
62
+ ReleaseNotesManager,
61
63
  useApplicationStore,
62
64
  } from '@finos/legend-application';
63
65
  import { useParams } from '@finos/legend-application/browser';
@@ -76,10 +78,7 @@ import {
76
78
  type QueryBuilderState,
77
79
  } from '@finos/legend-query-builder';
78
80
 
79
- import {
80
- compareSemVerVersions,
81
- generateGAVCoordinates,
82
- } from '@finos/legend-storage';
81
+ import { generateGAVCoordinates } from '@finos/legend-storage';
83
82
  import {
84
83
  type Query,
85
84
  QueryDataSpaceExecutionContext,
@@ -88,7 +87,8 @@ import {
88
87
  import { LATEST_VERSION_ALIAS } from '@finos/legend-server-depot';
89
88
  import { buildVersionOption, type VersionOption } from './QuerySetup.js';
90
89
  import { QueryEditorExistingQueryVersionRevertModal } from './QueryEdtiorExistingQueryVersionRevertModal.js';
91
- import { debounce } from '@finos/legend-shared';
90
+ import { debounce, compareSemVerVersions } from '@finos/legend-shared';
91
+ import { LegendQueryInfo } from './LegendQueryAppInfo.js';
92
92
 
93
93
  const CreateQueryDialog = observer(() => {
94
94
  const editorStore = useQueryEditorStore();
@@ -588,8 +588,6 @@ export const QueryEditor = observer(() => {
588
588
  generateQuerySetupRoute(),
589
589
  ),
590
590
  );
591
- const goToReleaseLog = (): void =>
592
- applicationStore.releaseNotesService.setReleaseLog(true);
593
591
  // settings
594
592
  // NOTE: this is temporary until we find a better home for these settings in query builder
595
593
  const engineConfig =
@@ -612,6 +610,7 @@ export const QueryEditor = observer(() => {
612
610
  flowResult(editorStore.initialize()).catch(
613
611
  applicationStore.alertUnhandledError,
614
612
  );
613
+ applicationStore.releaseNotesService.updateViewedVersion();
615
614
  }, [editorStore, applicationStore]);
616
615
 
617
616
  return (
@@ -631,9 +630,6 @@ export const QueryEditor = observer(() => {
631
630
  <MenuContentItem onClick={goToQuerySetup}>
632
631
  Back to query setup
633
632
  </MenuContentItem>
634
- <MenuContentItem onClick={goToReleaseLog}>
635
- Legend Query Release Log
636
- </MenuContentItem>
637
633
  <MenuContentItem
638
634
  disabled={!appDocUrl}
639
635
  onClick={goToDocumentation}
@@ -724,6 +720,12 @@ export const QueryEditor = observer(() => {
724
720
  />
725
721
  )}
726
722
  {editorStore.queryCreatorState.showCreateModal && <CreateQueryDialog />}
723
+ {editorStore.showAppInfo && (
724
+ <LegendQueryInfo
725
+ open={editorStore.showAppInfo}
726
+ closeModal={() => editorStore.setShowAppInfo(false)}
727
+ />
728
+ )}
727
729
  {isExistingQuery &&
728
730
  editorStore.updateState.showQueryInfo &&
729
731
  editorStore.query && (
@@ -732,6 +734,8 @@ export const QueryEditor = observer(() => {
732
734
  query={editorStore.query}
733
735
  />
734
736
  )}
737
+ <ReleaseLogManager />
738
+ <ReleaseNotesManager />
735
739
  </div>
736
740
  );
737
741
  });
@@ -23,7 +23,7 @@ import {
23
23
  ModalFooterButton,
24
24
  } from '@finos/legend-art';
25
25
  import { LATEST_VERSION_ALIAS } from '@finos/legend-server-depot';
26
- import { compareSemVerVersions } from '@finos/legend-storage';
26
+ import { compareSemVerVersions } from '@finos/legend-shared';
27
27
  import { flowResult } from 'mobx';
28
28
  import { observer } from 'mobx-react-lite';
29
29
  import { useState, useEffect } from 'react';
@@ -95,7 +95,7 @@ const DataSpaceQuerySetupSetupPanelContent = observer(
95
95
  queryBuilderState.showAdvancedSearchPanel();
96
96
 
97
97
  useEffect(() => {
98
- flowResult(queryBuilderState.loadDataSpaces()).catch(
98
+ flowResult(queryBuilderState.initializeDataSpaceSetup()).catch(
99
99
  applicationStore.alertUnhandledError,
100
100
  );
101
101
  }, [queryBuilderState, applicationStore]);
@@ -123,6 +123,7 @@ import {
123
123
  retrieveAnalyticsResultCache,
124
124
  } from '@finos/legend-extension-dsl-data-space/graph';
125
125
  import { generateDataSpaceQueryCreatorRoute } from '../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
126
+ import { hasDataSpaceInfoBeenVisited } from '../__lib__/LegendQueryUserDataSpaceHelper.js';
126
127
 
127
128
  export const createViewProjectHandler =
128
129
  (applicationStore: LegendQueryApplicationStore) =>
@@ -314,6 +315,7 @@ export abstract class QueryEditorStore {
314
315
  queryCreatorState: QueryCreatorState;
315
316
  existingQueryName: string | undefined;
316
317
  showRegisterServiceModal = false;
318
+ showAppInfo = false;
317
319
 
318
320
  constructor(
319
321
  applicationStore: LegendQueryApplicationStore,
@@ -324,10 +326,12 @@ export abstract class QueryEditorStore {
324
326
  queryLoaderState: observable,
325
327
  existingQueryName: observable,
326
328
  showRegisterServiceModal: observable,
329
+ showAppInfo: observable,
327
330
  queryBuilderState: observable,
328
331
  isPerformingBlockingAction: computed,
329
332
  setExistingQueryName: action,
330
333
  setShowRegisterServiceModal: action,
334
+ setShowAppInfo: action,
331
335
  initialize: flow,
332
336
  buildGraph: flow,
333
337
  searchExistingQueryName: flow,
@@ -405,6 +409,10 @@ export abstract class QueryEditorStore {
405
409
  this.existingQueryName = val;
406
410
  }
407
411
 
412
+ setShowAppInfo(val: boolean): void {
413
+ this.showAppInfo = val;
414
+ }
415
+
408
416
  setShowRegisterServiceModal(val: boolean): void {
409
417
  this.showRegisterServiceModal = val;
410
418
  }
@@ -534,10 +542,15 @@ export abstract class QueryEditorStore {
534
542
  error,
535
543
  );
536
544
  this.applicationStore.notificationService.notifyError(error);
545
+ this.onInitializeFailure();
537
546
  this.initState.fail();
538
547
  }
539
548
  }
540
549
 
550
+ onInitializeFailure(): void {
551
+ // Do Nothing
552
+ }
553
+
541
554
  *searchExistingQueryName(searchText: string): GeneratorFn<void> {
542
555
  const isValidSearchString =
543
556
  searchText.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH;
@@ -1234,6 +1247,10 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
1234
1247
  versionId: projectInfo.versionId,
1235
1248
  dataSpace: dataSpace.path,
1236
1249
  };
1250
+ const visitedDataSpaces =
1251
+ LegendQueryUserDataHelper.getRecentlyVisitedDataSpaces(
1252
+ this.applicationStore.userDataService,
1253
+ );
1237
1254
  const dataSpaceQueryBuilderState = new DataSpaceQueryBuilderState(
1238
1255
  this.applicationStore,
1239
1256
  this.graphManagerState,
@@ -1313,6 +1330,8 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
1313
1330
  projectInfo,
1314
1331
  this.applicationStore.config.options.queryBuilderConfig,
1315
1332
  sourceInfo,
1333
+ (dataSpaceInfo: DataSpaceInfo) =>
1334
+ hasDataSpaceInfoBeenVisited(dataSpaceInfo, visitedDataSpaces),
1316
1335
  );
1317
1336
  const mappingModelCoverageAnalysisResult =
1318
1337
  dataSpaceAnalysisResult?.executionContextsIndex.get(
@@ -29,8 +29,11 @@ import {
29
29
  LATEST_VERSION_ALIAS,
30
30
  } from '@finos/legend-server-depot';
31
31
  import {
32
+ LogEvent,
33
+ assertErrorThrown,
32
34
  guaranteeNonNullable,
33
35
  guaranteeType,
36
+ returnUndefOnError,
34
37
  uuid,
35
38
  } from '@finos/legend-shared';
36
39
  import {
@@ -59,6 +62,13 @@ import {
59
62
  type DataSpaceInfo,
60
63
  } from '@finos/legend-extension-dsl-data-space/application';
61
64
  import { generateDataSpaceQueryCreatorRoute } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
65
+ import { LegendQueryUserDataHelper } from '../../__lib__/LegendQueryUserDataHelper.js';
66
+ import {
67
+ createVisitedDataSpaceId,
68
+ hasDataSpaceInfoBeenVisited,
69
+ createSimpleVisitedDataspace,
70
+ } from '../../__lib__/LegendQueryUserDataSpaceHelper.js';
71
+ import { LEGEND_QUERY_APP_EVENT } from '../../__lib__/LegendQueryEvent.js';
62
72
 
63
73
  export class DataSpaceQueryCreatorStore extends QueryEditorStore {
64
74
  readonly groupId: string;
@@ -144,6 +154,10 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
144
154
  versionId: projectInfo.versionId,
145
155
  dataSpace: dataSpace.path,
146
156
  };
157
+ const visitedDataSpaces =
158
+ LegendQueryUserDataHelper.getRecentlyVisitedDataSpaces(
159
+ this.applicationStore.userDataService,
160
+ );
147
161
  const queryBuilderState = new DataSpaceQueryBuilderState(
148
162
  this.applicationStore,
149
163
  this.graphManagerState,
@@ -193,6 +207,15 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
193
207
  queryBuilderState.class?.path,
194
208
  ),
195
209
  );
210
+ returnUndefOnError(() =>
211
+ LegendQueryUserDataHelper.updateVisitedDataSpaceExecContext(
212
+ this.applicationStore.userDataService,
213
+ this.groupId,
214
+ this.artifactId,
215
+ dataSpace.path,
216
+ ec.name,
217
+ ),
218
+ );
196
219
  },
197
220
  (runtimeValue: Runtime) => {
198
221
  const runtimePointer = guaranteeType(runtimeValue, RuntimePointer);
@@ -235,6 +258,8 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
235
258
  projectInfo,
236
259
  this.applicationStore.config.options.queryBuilderConfig,
237
260
  sourceInfo,
261
+ (dataSpaceInfo: DataSpaceInfo) =>
262
+ hasDataSpaceInfoBeenVisited(dataSpaceInfo, visitedDataSpaces),
238
263
  );
239
264
  queryBuilderState.setExecutionContext(executionContext);
240
265
  queryBuilderState.propagateExecutionContextChange(executionContext);
@@ -257,9 +282,32 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
257
282
  );
258
283
  }
259
284
 
285
+ // add to visited dataspaces
286
+ this.addVisitedDataSpace(executionContext.name);
260
287
  return queryBuilderState;
261
288
  }
262
289
 
290
+ addVisitedDataSpace(execName: string | undefined): void {
291
+ try {
292
+ LegendQueryUserDataHelper.addVisitedDatspace(
293
+ this.applicationStore.userDataService,
294
+ createSimpleVisitedDataspace(
295
+ this.groupId,
296
+ this.artifactId,
297
+ this.versionId,
298
+ this.dataSpacePath,
299
+ execName,
300
+ ),
301
+ );
302
+ } catch (error) {
303
+ assertErrorThrown(error);
304
+ this.applicationStore.logService.warn(
305
+ LogEvent.create(LEGEND_QUERY_APP_EVENT.LOCAL_STORAGE_PERSIST_ERROR),
306
+ error.message,
307
+ );
308
+ }
309
+ }
310
+
263
311
  getPersistConfiguration(
264
312
  lambda: RawLambda,
265
313
  options?: { update?: boolean | undefined },
@@ -283,4 +331,15 @@ export class DataSpaceQueryCreatorStore extends QueryEditorStore {
283
331
  },
284
332
  };
285
333
  }
334
+
335
+ override onInitializeFailure(): void {
336
+ LegendQueryUserDataHelper.removeRecentlyViewedDataSpace(
337
+ this.applicationStore.userDataService,
338
+ createVisitedDataSpaceId(
339
+ this.groupId,
340
+ this.artifactId,
341
+ this.dataSpacePath,
342
+ ),
343
+ );
344
+ }
286
345
  }
@@ -22,13 +22,13 @@ import {
22
22
  } from '@finos/legend-server-depot';
23
23
  import type { GraphManagerState, RawLambda } from '@finos/legend-graph';
24
24
  import { type GenericLegendApplicationStore } from '@finos/legend-application';
25
- import { action, flow, makeObservable, observable } from 'mobx';
25
+ import { action, flow, flowResult, makeObservable, observable } from 'mobx';
26
26
  import {
27
27
  type QueryBuilderConfig,
28
28
  QueryBuilderState,
29
29
  QueryBuilderDataBrowserWorkflow,
30
30
  } from '@finos/legend-query-builder';
31
- import type { ProjectGAVCoordinates } from '@finos/legend-storage';
31
+ import type { Entity, ProjectGAVCoordinates } from '@finos/legend-storage';
32
32
  import {
33
33
  ActionState,
34
34
  assertErrorThrown,
@@ -51,7 +51,13 @@ import {
51
51
  import { generateDataSpaceQueryCreatorRoute } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
52
52
  import { renderDataSpaceQuerySetupSetupPanelContent } from '../../components/data-space/DataSpaceQuerySetup.js';
53
53
  import { DataSpaceAdvancedSearchState } from '@finos/legend-extension-dsl-data-space/application-query';
54
+ import type { VisitedDataspace } from '../../__lib__/LegendQueryUserDataSpaceHelper.js';
55
+ import { LegendQueryUserDataHelper } from '../../__lib__/LegendQueryUserDataHelper.js';
54
56
 
57
+ type DataSpaceVisitedEntity = {
58
+ visited: VisitedDataspace;
59
+ entity: Entity;
60
+ };
55
61
  export class DataSpaceQuerySetupState extends QueryBuilderState {
56
62
  editorStore: QueryEditorStore;
57
63
  readonly depotServerClient: DepotServerClient;
@@ -107,7 +113,9 @@ export class DataSpaceQuerySetupState extends QueryBuilderState {
107
113
  advancedSearchState: observable,
108
114
  showAdvancedSearchPanel: action,
109
115
  hideAdvancedSearchPanel: action,
110
- loadDataSpaces: flow,
116
+ initializeDataSpaceSetup: flow,
117
+ redirectIfPossible: flow,
118
+ hyrdateVisitedDataSpace: flow,
111
119
  });
112
120
 
113
121
  this.editorStore = editorStore;
@@ -144,9 +152,29 @@ export class DataSpaceQuerySetupState extends QueryBuilderState {
144
152
  this.advancedSearchState = undefined;
145
153
  }
146
154
 
147
- *loadDataSpaces(): GeneratorFn<void> {
155
+ *initializeDataSpaceSetup(): GeneratorFn<void> {
148
156
  this.loadDataSpacesState.inProgress();
149
157
  try {
158
+ const hydrated = (yield flowResult(this.redirectIfPossible())) as
159
+ | DataSpaceVisitedEntity
160
+ | undefined;
161
+ if (hydrated) {
162
+ this.applicationStore.navigationService.navigator.goToLocation(
163
+ generateDataSpaceQueryCreatorRoute(
164
+ guaranteeNonNullable(hydrated.visited.groupId),
165
+ guaranteeNonNullable(hydrated.visited.artifactId),
166
+ hydrated.visited.versionId ?? LATEST_VERSION_ALIAS,
167
+ hydrated.visited.path,
168
+ hydrated.visited.execContext ??
169
+ (hydrated.entity.content.defaultExecutionContext as string),
170
+ undefined,
171
+ undefined,
172
+ ),
173
+ );
174
+ this.loadDataSpacesState.complete();
175
+ return;
176
+ }
177
+
150
178
  this.dataSpaces = (
151
179
  (yield this.depotServerClient.getEntitiesByClassifier(
152
180
  DATA_SPACE_ELEMENT_CLASSIFIER_PATH,
@@ -162,6 +190,66 @@ export class DataSpaceQuerySetupState extends QueryBuilderState {
162
190
  this.applicationStore.notificationService.notifyError(error);
163
191
  }
164
192
  }
193
+
194
+ *redirectIfPossible(): GeneratorFn<DataSpaceVisitedEntity | undefined> {
195
+ const visitedQueries =
196
+ LegendQueryUserDataHelper.getRecentlyVisitedDataSpaces(
197
+ this.applicationStore.userDataService,
198
+ );
199
+ let redirect: DataSpaceVisitedEntity | undefined = undefined;
200
+ for (let i = 0; i < visitedQueries.length; i++) {
201
+ const visited = visitedQueries[i];
202
+ if (visited) {
203
+ const hydrated = (yield flowResult(
204
+ this.hyrdateVisitedDataSpace(visited),
205
+ )) as DataSpaceVisitedEntity | undefined;
206
+ if (hydrated) {
207
+ redirect = hydrated;
208
+ break;
209
+ }
210
+ }
211
+ }
212
+ return redirect;
213
+ }
214
+
215
+ *hyrdateVisitedDataSpace(
216
+ visited: VisitedDataspace,
217
+ ): GeneratorFn<DataSpaceVisitedEntity | undefined> {
218
+ try {
219
+ const entity = (yield this.depotServerClient.getVersionEntity(
220
+ visited.groupId,
221
+ visited.artifactId,
222
+ visited.versionId ?? LATEST_VERSION_ALIAS,
223
+ visited.path,
224
+ )) as Entity;
225
+ const content = entity.content as {
226
+ executionContexts: { name: string }[];
227
+ };
228
+ if (visited.execContext) {
229
+ const found = content.executionContexts.find(
230
+ (e) => e.name === visited.execContext,
231
+ );
232
+ if (!found) {
233
+ visited.execContext = undefined;
234
+ return {
235
+ visited,
236
+ entity,
237
+ };
238
+ }
239
+ }
240
+ return {
241
+ visited,
242
+ entity,
243
+ };
244
+ } catch (error) {
245
+ assertErrorThrown(error);
246
+ LegendQueryUserDataHelper.removeRecentlyViewedDataSpace(
247
+ this.applicationStore.userDataService,
248
+ visited.id,
249
+ );
250
+ }
251
+ return undefined;
252
+ }
165
253
  }
166
254
 
167
255
  export class DataSpaceQuerySetupStore extends QueryEditorStore {
package/tsconfig.json CHANGED
@@ -57,6 +57,7 @@
57
57
  "./src/__lib__/LegendQueryNavigation.ts",
58
58
  "./src/__lib__/LegendQueryTelemetryHelper.ts",
59
59
  "./src/__lib__/LegendQueryUserDataHelper.ts",
60
+ "./src/__lib__/LegendQueryUserDataSpaceHelper.ts",
60
61
  "./src/application/Core_LegendQuery_LegendApplicationPlugin.ts",
61
62
  "./src/application/LegendQueryApplicationConfig.ts",
62
63
  "./src/application/LegendQueryPluginManager.ts",
@@ -79,6 +80,7 @@
79
80
  "./src/components/Core_LegendQueryApplicationPlugin.tsx",
80
81
  "./src/components/CreateMappingQuerySetup.tsx",
81
82
  "./src/components/EditExistingQuerySetup.tsx",
83
+ "./src/components/LegendQueryAppInfo.tsx",
82
84
  "./src/components/LegendQueryFrameworkProvider.tsx",
83
85
  "./src/components/LegendQueryWebApplication.tsx",
84
86
  "./src/components/LoadProjectServiceQuerySetup.tsx",