@finos/legend-application-data-cube 0.3.2 → 0.3.3

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 (112) hide show
  1. package/lib/__lib__/LegendDataCubeNavigation.d.ts +2 -0
  2. package/lib/__lib__/LegendDataCubeNavigation.d.ts.map +1 -1
  3. package/lib/__lib__/LegendDataCubeNavigation.js +2 -0
  4. package/lib/__lib__/LegendDataCubeNavigation.js.map +1 -1
  5. package/lib/application/LegendDataCubeApplicationConfig.d.ts +4 -0
  6. package/lib/application/LegendDataCubeApplicationConfig.d.ts.map +1 -1
  7. package/lib/application/LegendDataCubeApplicationConfig.js +5 -0
  8. package/lib/application/LegendDataCubeApplicationConfig.js.map +1 -1
  9. package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.d.ts +18 -0
  10. package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.d.ts.map +1 -0
  11. package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.js +48 -0
  12. package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.js.map +1 -0
  13. package/lib/components/LegendDataCubeBlockingWindow.d.ts +2 -1
  14. package/lib/components/LegendDataCubeBlockingWindow.d.ts.map +1 -1
  15. package/lib/components/LegendDataCubeBlockingWindow.js +8 -3
  16. package/lib/components/LegendDataCubeBlockingWindow.js.map +1 -1
  17. package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.d.ts +42 -0
  18. package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.d.ts.map +1 -0
  19. package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.js +104 -0
  20. package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.js.map +1 -0
  21. package/lib/components/builder/LegendDataCubeBuilder.d.ts +5 -0
  22. package/lib/components/builder/LegendDataCubeBuilder.d.ts.map +1 -1
  23. package/lib/components/builder/LegendDataCubeBuilder.js +26 -5
  24. package/lib/components/builder/LegendDataCubeBuilder.js.map +1 -1
  25. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.d.ts.map +1 -1
  26. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js +1 -1
  27. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js.map +1 -1
  28. package/lib/components/builder/LegendDataCubePartialSourceLoader.d.ts +19 -0
  29. package/lib/components/builder/LegendDataCubePartialSourceLoader.d.ts.map +1 -0
  30. package/lib/components/builder/LegendDataCubePartialSourceLoader.js +50 -0
  31. package/lib/components/builder/LegendDataCubePartialSourceLoader.js.map +1 -0
  32. package/lib/components/builder/LegendDataCubeSourceViewer.d.ts.map +1 -1
  33. package/lib/components/builder/LegendDataCubeSourceViewer.js +61 -1
  34. package/lib/components/builder/LegendDataCubeSourceViewer.js.map +1 -1
  35. package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.d.ts.map +1 -1
  36. package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.js +1 -2
  37. package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.js.map +1 -1
  38. package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.d.ts +22 -0
  39. package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.d.ts.map +1 -0
  40. package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.js +28 -0
  41. package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.js.map +1 -0
  42. package/lib/index.css +2 -2
  43. package/lib/index.css.map +1 -1
  44. package/lib/package.json +3 -1
  45. package/lib/stores/LegendDataCubeBaseStore.d.ts +2 -1
  46. package/lib/stores/LegendDataCubeBaseStore.d.ts.map +1 -1
  47. package/lib/stores/LegendDataCubeBaseStore.js +6 -3
  48. package/lib/stores/LegendDataCubeBaseStore.js.map +1 -1
  49. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts +6 -3
  50. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts.map +1 -1
  51. package/lib/stores/LegendDataCubeDataCubeEngine.js +127 -106
  52. package/lib/stores/LegendDataCubeDataCubeEngine.js.map +1 -1
  53. package/lib/stores/LegendDataCubeDuckDBEngine.d.ts +11 -4
  54. package/lib/stores/LegendDataCubeDuckDBEngine.d.ts.map +1 -1
  55. package/lib/stores/LegendDataCubeDuckDBEngine.js +83 -16
  56. package/lib/stores/LegendDataCubeDuckDBEngine.js.map +1 -1
  57. package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts +4 -0
  58. package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts.map +1 -1
  59. package/lib/stores/builder/LegendDataCubeBuilderStore.js +58 -17
  60. package/lib/stores/builder/LegendDataCubeBuilderStore.js.map +1 -1
  61. package/lib/stores/builder/LegendDataCubeLoaderState.d.ts +11 -2
  62. package/lib/stores/builder/LegendDataCubeLoaderState.d.ts.map +1 -1
  63. package/lib/stores/builder/LegendDataCubeLoaderState.js +28 -1
  64. package/lib/stores/builder/LegendDataCubeLoaderState.js.map +1 -1
  65. package/lib/stores/builder/LegendDataCubeSourceLoaderState.d.ts +44 -0
  66. package/lib/stores/builder/LegendDataCubeSourceLoaderState.d.ts.map +1 -0
  67. package/lib/stores/builder/LegendDataCubeSourceLoaderState.js +101 -0
  68. package/lib/stores/builder/LegendDataCubeSourceLoaderState.js.map +1 -0
  69. package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.d.ts +3 -2
  70. package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.d.ts.map +1 -1
  71. package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.js +7 -10
  72. package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.js.map +1 -1
  73. package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.d.ts +29 -0
  74. package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.d.ts.map +1 -0
  75. package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.js +25 -0
  76. package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.js.map +1 -0
  77. package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.d.ts +43 -0
  78. package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.d.ts.map +1 -0
  79. package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.js +142 -0
  80. package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.js.map +1 -0
  81. package/lib/stores/model/LegendQueryDataCubeSource.d.ts +2 -1
  82. package/lib/stores/model/LegendQueryDataCubeSource.d.ts.map +1 -1
  83. package/lib/stores/model/LegendQueryDataCubeSource.js +1 -0
  84. package/lib/stores/model/LegendQueryDataCubeSource.js.map +1 -1
  85. package/lib/stores/model/LocalFileDataCubeSource.d.ts +3 -8
  86. package/lib/stores/model/LocalFileDataCubeSource.d.ts.map +1 -1
  87. package/lib/stores/model/LocalFileDataCubeSource.js +5 -15
  88. package/lib/stores/model/LocalFileDataCubeSource.js.map +1 -1
  89. package/package.json +13 -11
  90. package/src/__lib__/LegendDataCubeNavigation.ts +21 -0
  91. package/src/application/LegendDataCubeApplicationConfig.ts +10 -0
  92. package/src/application/__test-utils__/LegendDataCubeApplicationTestUtils.ts +52 -0
  93. package/src/components/LegendDataCubeBlockingWindow.tsx +8 -2
  94. package/src/components/__test-utils__/LegendDataCubeStoreTestUtils.tsx +231 -0
  95. package/src/components/builder/LegendDataCubeBuilder.tsx +51 -6
  96. package/src/components/builder/LegendDataCubeBuilderStoreProvider.tsx +3 -0
  97. package/src/components/builder/LegendDataCubePartialSourceLoader.tsx +108 -0
  98. package/src/components/builder/LegendDataCubeSourceViewer.tsx +171 -1
  99. package/src/components/builder/source/LocalFileDataCubeSourceBuilder.tsx +1 -2
  100. package/src/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.tsx +60 -0
  101. package/src/stores/LegendDataCubeBaseStore.ts +13 -6
  102. package/src/stores/LegendDataCubeDataCubeEngine.ts +161 -120
  103. package/src/stores/LegendDataCubeDuckDBEngine.ts +101 -17
  104. package/src/stores/builder/LegendDataCubeBuilderStore.tsx +96 -24
  105. package/src/stores/builder/LegendDataCubeLoaderState.tsx +44 -1
  106. package/src/stores/builder/LegendDataCubeSourceLoaderState.tsx +145 -0
  107. package/src/stores/builder/source/LocalFileDataCubeSourceBuilderState.ts +9 -14
  108. package/src/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.ts +41 -0
  109. package/src/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.ts +217 -0
  110. package/src/stores/model/LegendQueryDataCubeSource.ts +2 -0
  111. package/src/stores/model/LocalFileDataCubeSource.ts +6 -15
  112. package/tsconfig.json +8 -1
@@ -41,6 +41,7 @@ import {
41
41
  ActionState,
42
42
  assertErrorThrown,
43
43
  formatDate,
44
+ guaranteeNonNullable,
44
45
  isString,
45
46
  uuid,
46
47
  } from '@finos/legend-shared';
@@ -58,7 +59,10 @@ import {
58
59
  import type { DepotServerClient } from '@finos/legend-server-depot';
59
60
  import { LegendDataCubeBlockingWindowState } from '../../components/LegendDataCubeBlockingWindow.js';
60
61
  import { LegendDataCubeDeleteConfirmation } from '../../components/builder/LegendDataCubeDeleteConfirmation.js';
61
- import { LegendDataCubeAbout } from '../../components/builder/LegendDataCubeBuilder.js';
62
+ import {
63
+ LegendDataCubeAbout,
64
+ LegendDataCubeReleaseLogManager,
65
+ } from '../../components/builder/LegendDataCubeBuilder.js';
62
66
  import { LegendDataCubeSourceViewer } from '../../components/builder/LegendDataCubeSourceViewer.js';
63
67
 
64
68
  export class LegendDataCubeBuilderState {
@@ -121,6 +125,8 @@ export class LegendDataCubeBuilderStore {
121
125
 
122
126
  readonly initializeState = ActionState.create();
123
127
  readonly aboutDisplay: DisplayState;
128
+ readonly releaseLogDisplay: DisplayState;
129
+ readonly releaseNotesDisplay: DisplayState;
124
130
 
125
131
  readonly creator: LegendDataCubeCreatorState;
126
132
 
@@ -169,6 +175,23 @@ export class LegendDataCubeBuilderStore {
169
175
  },
170
176
  );
171
177
 
178
+ this.releaseLogDisplay = this.layoutService.newDisplay(
179
+ 'Release Log',
180
+ () => <LegendDataCubeReleaseLogManager showOnlyLatestNotes={false} />,
181
+ {
182
+ ...DEFAULT_ALERT_WINDOW_CONFIG,
183
+ height: 500,
184
+ },
185
+ );
186
+ this.releaseNotesDisplay = this.layoutService.newDisplay(
187
+ 'Release Notes',
188
+ () => <LegendDataCubeReleaseLogManager showOnlyLatestNotes={true} />,
189
+ {
190
+ ...DEFAULT_ALERT_WINDOW_CONFIG,
191
+ height: 350,
192
+ },
193
+ );
194
+
172
195
  this.creator = new LegendDataCubeCreatorState(this);
173
196
  this.loader = new LegendDataCubeLoaderState(this);
174
197
  this.saverDisplay = new LegendDataCubeBlockingWindowState(
@@ -253,6 +276,38 @@ export class LegendDataCubeBuilderStore {
253
276
  }
254
277
  }
255
278
 
279
+ loadPartialSourceDataCube() {
280
+ if (!this.loader.isPartialSourceResolved()) {
281
+ this.application.navigationService.navigator.updateCurrentLocation(
282
+ generateBuilderRoute(null),
283
+ );
284
+ }
285
+ try {
286
+ const persistentDataCube = guaranteeNonNullable(
287
+ this.loader.getPersistentDataCube(),
288
+ );
289
+ const dataCubeId = persistentDataCube.id;
290
+ const specification = DataCubeSpecification.serialization.fromJson(
291
+ persistentDataCube.content,
292
+ );
293
+ specification.source = guaranteeNonNullable(
294
+ this.loader.getResolvedSource(),
295
+ );
296
+ this.postLoad(specification, persistentDataCube, dataCubeId);
297
+ this.loadState.pass();
298
+ } catch (error) {
299
+ assertErrorThrown(error);
300
+ this.alertService.alertError(error, {
301
+ message: `DataCube Load Failure: ${error.message}`,
302
+ });
303
+ this.application.navigationService.navigator.updateCurrentLocation(
304
+ generateBuilderRoute(null),
305
+ );
306
+ this.loadState.fail();
307
+ throw error;
308
+ }
309
+ }
310
+
256
311
  async loadDataCube(dataCubeId: string | undefined) {
257
312
  // internalize the parameters and clean them from the URL
258
313
  const sourceData =
@@ -295,31 +350,16 @@ export class LegendDataCubeBuilderStore {
295
350
  const specification = DataCubeSpecification.serialization.fromJson(
296
351
  persistentDataCube.content,
297
352
  );
298
- this.setBuilder(
299
- new LegendDataCubeBuilderState(specification, persistentDataCube),
300
- );
301
- this.updateWindowTitle(persistentDataCube);
302
353
 
303
- // update the list of stack of recently viewed DataCubes
304
- const recentlyViewedDataCubes = this.getRecentlyViewedDataCubes();
305
- const idx = recentlyViewedDataCubes.findIndex(
306
- (data) => data === dataCubeId,
307
- );
308
- if (idx === -1) {
309
- if (
310
- recentlyViewedDataCubes.length >= RECENTLY_VIEWED_DATA_CUBES_LIMIT
311
- ) {
312
- recentlyViewedDataCubes.pop();
313
- }
314
- recentlyViewedDataCubes.unshift(dataCubeId);
315
- } else {
316
- recentlyViewedDataCubes.splice(idx, 1);
317
- recentlyViewedDataCubes.unshift(dataCubeId);
354
+ if (this.loader.isPartialSource(specification.source)) {
355
+ this.loader.resolvePartialSource(
356
+ specification.source,
357
+ persistentDataCube,
358
+ );
359
+ return;
318
360
  }
319
- this.application.userDataService.persistValue(
320
- LegendDataCubeUserDataKey.RECENTLY_VIEWED_DATA_CUBES,
321
- recentlyViewedDataCubes,
322
- );
361
+
362
+ this.postLoad(specification, persistentDataCube, dataCubeId);
323
363
 
324
364
  this.loadState.pass();
325
365
  } catch (error) {
@@ -336,6 +376,36 @@ export class LegendDataCubeBuilderStore {
336
376
  }
337
377
  }
338
378
 
379
+ private postLoad(
380
+ specification: DataCubeSpecification,
381
+ persistentDataCube: PersistentDataCube,
382
+ dataCubeId: string,
383
+ ) {
384
+ this.setBuilder(
385
+ new LegendDataCubeBuilderState(specification, persistentDataCube),
386
+ );
387
+ this.updateWindowTitle(persistentDataCube);
388
+
389
+ // update the list of stack of recently viewed DataCubes
390
+ const recentlyViewedDataCubes = this.getRecentlyViewedDataCubes();
391
+ const idx = recentlyViewedDataCubes.findIndex(
392
+ (data) => data === dataCubeId,
393
+ );
394
+ if (idx === -1) {
395
+ if (recentlyViewedDataCubes.length >= RECENTLY_VIEWED_DATA_CUBES_LIMIT) {
396
+ recentlyViewedDataCubes.pop();
397
+ }
398
+ recentlyViewedDataCubes.unshift(dataCubeId);
399
+ } else {
400
+ recentlyViewedDataCubes.splice(idx, 1);
401
+ recentlyViewedDataCubes.unshift(dataCubeId);
402
+ }
403
+ this.application.userDataService.persistValue(
404
+ LegendDataCubeUserDataKey.RECENTLY_VIEWED_DATA_CUBES,
405
+ recentlyViewedDataCubes,
406
+ );
407
+ }
408
+
339
409
  private async generatePersistentDataCube(
340
410
  api: DataCubeAPI,
341
411
  name: string,
@@ -391,6 +461,7 @@ export class LegendDataCubeBuilderStore {
391
461
  // Another way to avoid reloading the whole app it to force update
392
462
  // the <DataCube/> component using the key prop that ties to an ID
393
463
  // of the builder.
464
+ this.builder.setPersistentDataCube(newPersistentDataCube);
394
465
  this.application.navigationService.navigator.updateCurrentLocation(
395
466
  generateBuilderRoute(newPersistentDataCube.id),
396
467
  );
@@ -439,6 +510,7 @@ export class LegendDataCubeBuilderStore {
439
510
  // Another way to avoid reloading the whole app it to force update
440
511
  // the <DataCube/> component using the key prop that ties to an ID
441
512
  // of the builder.
513
+ this.builder.setPersistentDataCube(newPersistentDataCube);
442
514
  this.application.navigationService.navigator.updateCurrentLocation(
443
515
  generateBuilderRoute(newPersistentDataCube.id),
444
516
  );
@@ -24,8 +24,14 @@ import {
24
24
  QuerySearchSpecification,
25
25
  QuerySearchSortBy,
26
26
  type V1_PureGraphManager,
27
+ type PersistentDataCube,
27
28
  } from '@finos/legend-graph';
28
- import { ActionState, assertErrorThrown, LogEvent } from '@finos/legend-shared';
29
+ import {
30
+ ActionState,
31
+ assertErrorThrown,
32
+ LogEvent,
33
+ type PlainObject,
34
+ } from '@finos/legend-shared';
29
35
  import { makeObservable, observable, action } from 'mobx';
30
36
  import type { LegendDataCubeBuilderStore } from './LegendDataCubeBuilderStore.js';
31
37
  import { LegendDataCubeUserDataKey } from '../../__lib__/LegendDataCubeUserData.js';
@@ -36,6 +42,9 @@ import {
36
42
  } from '@finos/legend-data-cube';
37
43
  import { LegendDataCubeLoader } from '../../components/builder/LegendDataCubeLoader.js';
38
44
  import { generateBuilderRoute } from '../../__lib__/LegendDataCubeNavigation.js';
45
+ import { LOCAL_FILE_QUERY_DATA_CUBE_SOURCE_TYPE } from '../model/LocalFileDataCubeSource.js';
46
+ import { LegendDataCubeSourceLoaderState } from './LegendDataCubeSourceLoaderState.js';
47
+ import type { LegendDataCubeBlockingWindowState } from '../../components/LegendDataCubeBlockingWindow.js';
39
48
 
40
49
  export const DATA_CUBE_LOADER_TYPEAHEAD_SEARCH_LIMIT = 50;
41
50
  export const DATA_CUBE_LOADER_DEFAULT_SEARCH_LIMIT = 10;
@@ -64,6 +73,9 @@ export class LegendDataCubeLoaderState {
64
73
  showingDefaultResults = true;
65
74
  sortBy = DataCubeSortByType.LAST_VIEWED;
66
75
 
76
+ readonly sourceLoader: LegendDataCubeSourceLoaderState;
77
+ readonly sourceLoaderDisplay: LegendDataCubeBlockingWindowState;
78
+
67
79
  constructor(store: LegendDataCubeBuilderStore) {
68
80
  makeObservable(this, {
69
81
  showingDefaultResults: observable,
@@ -89,6 +101,7 @@ export class LegendDataCubeLoaderState {
89
101
  this._store = store;
90
102
  this._graphManager = store.graphManager;
91
103
  this._alertService = store.alertService;
104
+ this.sourceLoader = new LegendDataCubeSourceLoaderState(store);
92
105
 
93
106
  this.display = store.layoutService.newDisplay(
94
107
  'Load DataCube',
@@ -99,6 +112,7 @@ export class LegendDataCubeLoaderState {
99
112
  minWidth: 500,
100
113
  },
101
114
  );
115
+ this.sourceLoaderDisplay = this.sourceLoader.display;
102
116
  }
103
117
 
104
118
  setSearchText(val: string) {
@@ -145,6 +159,35 @@ export class LegendDataCubeLoaderState {
145
159
  );
146
160
  }
147
161
 
162
+ isPartialSource(source: PlainObject): boolean {
163
+ const type = source._type as string;
164
+ if (type === LOCAL_FILE_QUERY_DATA_CUBE_SOURCE_TYPE) {
165
+ this.sourceLoader.setPartialSourceResolved(false);
166
+ return true;
167
+ }
168
+ return false;
169
+ }
170
+
171
+ isPartialSourceResolved() {
172
+ return this.sourceLoader.partialSourceResolved;
173
+ }
174
+
175
+ getResolvedSource() {
176
+ return this.sourceLoader.source;
177
+ }
178
+
179
+ getPersistentDataCube() {
180
+ return this.sourceLoader.persistentDataCube;
181
+ }
182
+
183
+ resolvePartialSource(
184
+ partialSource: PlainObject,
185
+ persistentDataCube: PersistentDataCube | undefined,
186
+ ) {
187
+ this.sourceLoader.initialize(partialSource, persistentDataCube);
188
+ this.sourceLoaderDisplay.open();
189
+ }
190
+
148
191
  async searchDataCubes(searchText: string) {
149
192
  // for the initial search, i.e. no search config is specified, fetch the default entries if possible
150
193
  if (!this.canPerformAdvancedSearch(searchText)) {
@@ -0,0 +1,145 @@
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
+ import {
17
+ ActionState,
18
+ assertErrorThrown,
19
+ guaranteeNonNullable,
20
+ UnsupportedOperationError,
21
+ type PlainObject,
22
+ } from '@finos/legend-shared';
23
+ import { makeObservable, observable, action } from 'mobx';
24
+ import type { LegendDataCubeBuilderStore } from './LegendDataCubeBuilderStore.js';
25
+ import {
26
+ DEFAULT_TOOL_PANEL_WINDOW_CONFIG,
27
+ type DataCubeAlertService,
28
+ } from '@finos/legend-data-cube';
29
+ import { LegendDataCubePartialSourceLoader } from '../../components/builder/LegendDataCubePartialSourceLoader.js';
30
+ import type { LegendDataCubeDataCubeEngine } from '../LegendDataCubeDataCubeEngine.js';
31
+ import type { LegendDataCubeApplicationStore } from '../LegendDataCubeBaseStore.js';
32
+ import type { LegendDataCubePartialSourceLoaderState } from './source/loader/LegendDataCubePartialSourceLoaderState.js';
33
+ import { LocalFileDataCubePartialSourceLoaderState } from './source/loader/LocalFileDataCubePartialSourceLoaderState.js';
34
+ import { LOCAL_FILE_QUERY_DATA_CUBE_SOURCE_TYPE } from '../model/LocalFileDataCubeSource.js';
35
+ import { LegendDataCubeBlockingWindowState } from '../../components/LegendDataCubeBlockingWindow.js';
36
+ import type { PersistentDataCube } from '@finos/legend-graph';
37
+
38
+ export enum LegendDataCubeSourceLoaderType {
39
+ LOCAL_FILE = 'Local File',
40
+ }
41
+
42
+ export class LegendDataCubeSourceLoaderState {
43
+ private readonly _application: LegendDataCubeApplicationStore;
44
+ private readonly _engine: LegendDataCubeDataCubeEngine;
45
+ private readonly _alertService: DataCubeAlertService;
46
+
47
+ source: PlainObject | undefined;
48
+ persistentDataCube: PersistentDataCube | undefined;
49
+
50
+ readonly display: LegendDataCubeBlockingWindowState;
51
+ readonly searchState = ActionState.create();
52
+ readonly finalizeState = ActionState.create();
53
+
54
+ partialSourceLoader: LegendDataCubePartialSourceLoaderState;
55
+
56
+ partialSourceResolved = false;
57
+
58
+ constructor(store: LegendDataCubeBuilderStore) {
59
+ makeObservable(this, {
60
+ source: observable,
61
+ setSource: action,
62
+
63
+ partialSourceResolved: observable,
64
+ setPartialSourceResolved: action,
65
+ });
66
+
67
+ this._application = store.application;
68
+ this._engine = store.engine;
69
+ this._alertService = store.alertService;
70
+ this.partialSourceLoader = this.createSourceLoader(
71
+ LOCAL_FILE_QUERY_DATA_CUBE_SOURCE_TYPE,
72
+ );
73
+
74
+ this.display = new LegendDataCubeBlockingWindowState(
75
+ 'Load DataCube',
76
+ () => <LegendDataCubePartialSourceLoader />,
77
+ {
78
+ ...DEFAULT_TOOL_PANEL_WINDOW_CONFIG,
79
+ width: 500,
80
+ minWidth: 500,
81
+ },
82
+ () => {
83
+ store.loader.sourceLoaderDisplay.close();
84
+ store.loadPartialSourceDataCube();
85
+ },
86
+ );
87
+ }
88
+
89
+ initialize(
90
+ source: PlainObject,
91
+ persistentDataCube: PersistentDataCube | undefined,
92
+ ) {
93
+ this.setSource(source);
94
+ this.setPersistentDataCube(persistentDataCube);
95
+ }
96
+
97
+ setSource(source: PlainObject) {
98
+ this.source = source;
99
+ }
100
+
101
+ setPersistentDataCube(persistentDataCube: PersistentDataCube | undefined) {
102
+ this.persistentDataCube = guaranteeNonNullable(persistentDataCube);
103
+ }
104
+
105
+ setPartialSourceResolved(sourceResolved: boolean) {
106
+ this.partialSourceResolved = sourceResolved;
107
+ }
108
+
109
+ changeSourceLoader(type: string): void {
110
+ this.partialSourceLoader = this.createSourceLoader(type);
111
+ }
112
+
113
+ private createSourceLoader(
114
+ type: string,
115
+ ): LegendDataCubePartialSourceLoaderState {
116
+ // We can add more partial sources
117
+ switch (type) {
118
+ case LOCAL_FILE_QUERY_DATA_CUBE_SOURCE_TYPE:
119
+ return new LocalFileDataCubePartialSourceLoaderState(
120
+ this._application,
121
+ this._engine,
122
+ );
123
+ default:
124
+ throw new UnsupportedOperationError(
125
+ `Can't create source loader for unsupported type '${type}'`,
126
+ );
127
+ }
128
+ }
129
+
130
+ async finalize() {
131
+ try {
132
+ this.finalizeState.inProgress();
133
+ this.setSource(await this.partialSourceLoader.load(this.source));
134
+ this.display.close();
135
+ this.finalizeState.pass();
136
+ this.setPartialSourceResolved(true);
137
+ } catch (error) {
138
+ assertErrorThrown(error);
139
+ this._alertService.alertError(error, {
140
+ message: `DataCube Source Load Failure: ${error.message}`,
141
+ });
142
+ this.finalizeState.fail();
143
+ }
144
+ }
145
+ }
@@ -17,7 +17,7 @@
17
17
  import {
18
18
  ActionState,
19
19
  csvStringify,
20
- guaranteeType,
20
+ guaranteeNonNullable,
21
21
  IllegalStateError,
22
22
  parseCSVFile,
23
23
  type PlainObject,
@@ -30,7 +30,6 @@ import type { LegendDataCubeApplicationStore } from '../../LegendDataCubeBaseSto
30
30
  import { action, makeObservable, observable } from 'mobx';
31
31
  import type { LegendDataCubeDataCubeEngine } from '../../LegendDataCubeDataCubeEngine.js';
32
32
  import {
33
- LocalFileDataCubeSource,
34
33
  LocalFileDataCubeSourceFormat,
35
34
  RawLocalFileQueryDataCubeSource,
36
35
  } from '../../model/LocalFileDataCubeSource.js';
@@ -39,7 +38,7 @@ export class LocalFileDataCubeSourceBuilderState extends LegendDataCubeSourceBui
39
38
  readonly processState = ActionState.create();
40
39
 
41
40
  fileName?: string | undefined;
42
- fileFormat?: string | undefined;
41
+ fileFormat?: LocalFileDataCubeSourceFormat | undefined;
43
42
  // NOTE: type string is suitable for CSV/Excel, etc. but will not be appropriate
44
43
  // for other format that we want to support, e.g. arrow/parquet
45
44
  fileData?: string | undefined;
@@ -74,7 +73,7 @@ export class LocalFileDataCubeSourceBuilderState extends LegendDataCubeSourceBui
74
73
  this.fileName = fileName;
75
74
  }
76
75
 
77
- setFileFormat(format: string | undefined) {
76
+ setFileFormat(format: LocalFileDataCubeSourceFormat | undefined) {
78
77
  this.fileFormat = format;
79
78
  }
80
79
 
@@ -114,7 +113,7 @@ export class LocalFileDataCubeSourceBuilderState extends LegendDataCubeSourceBui
114
113
  csvStringify(result.data, { escapeChar: `'`, quoteChar: `'` }),
115
114
  );
116
115
  this.setFileName(fileName);
117
- this.setFileFormat(fileFormat);
116
+ this.setFileFormat(LocalFileDataCubeSourceFormat.CSV);
118
117
  this.setRowCount(result.data.length);
119
118
  this.setPreviewText(
120
119
  csvStringify(result.data.slice(0, 100), {
@@ -160,19 +159,15 @@ export class LocalFileDataCubeSourceBuilderState extends LegendDataCubeSourceBui
160
159
  );
161
160
  }
162
161
 
163
- const source = guaranteeType(
162
+ const tableDetails = guaranteeNonNullable(
164
163
  await this._engine.ingestLocalFileData(this.fileData, this.fileFormat),
165
- LocalFileDataCubeSource,
166
- `Can't generate data source`,
164
+ `Can't generate source data: failed to ingest data from local file`,
167
165
  );
168
166
  const rawSource = new RawLocalFileQueryDataCubeSource();
169
- rawSource.count = this.rowCount;
170
167
  rawSource.fileName = this.fileName;
171
- rawSource.db = source.db;
172
- rawSource.model = source.model;
173
- rawSource.schema = source.schema;
174
- rawSource.table = source.table;
175
- rawSource.runtime = source.runtime;
168
+ rawSource.fileFormat = this.fileFormat;
169
+ rawSource._ref = tableDetails.dbReference;
170
+ rawSource.columnNames = tableDetails.columnNames;
176
171
 
177
172
  return RawLocalFileQueryDataCubeSource.serialization.toJson(rawSource);
178
173
  }
@@ -0,0 +1,41 @@
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 { type PlainObject } from '@finos/legend-shared';
18
+ import type { LegendDataCubeApplicationStore } from '../../../LegendDataCubeBaseStore.js';
19
+ import type { LegendDataCubeDataCubeEngine } from '../../../LegendDataCubeDataCubeEngine.js';
20
+ import type { LegendDataCubeSourceLoaderType } from '../../LegendDataCubeSourceLoaderState.js';
21
+
22
+ export abstract class LegendDataCubePartialSourceLoaderState {
23
+ protected readonly _application: LegendDataCubeApplicationStore;
24
+ protected readonly _engine: LegendDataCubeDataCubeEngine;
25
+
26
+ constructor(
27
+ application: LegendDataCubeApplicationStore,
28
+ engine: LegendDataCubeDataCubeEngine,
29
+ ) {
30
+ this._application = application;
31
+ this._engine = engine;
32
+ }
33
+
34
+ abstract initialize(): void;
35
+
36
+ abstract get label(): LegendDataCubeSourceLoaderType;
37
+
38
+ abstract get isValid(): boolean;
39
+
40
+ abstract load(source: PlainObject | undefined): Promise<PlainObject>;
41
+ }