@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.
- package/lib/__lib__/LegendDataCubeNavigation.d.ts +2 -0
- package/lib/__lib__/LegendDataCubeNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendDataCubeNavigation.js +2 -0
- package/lib/__lib__/LegendDataCubeNavigation.js.map +1 -1
- package/lib/application/LegendDataCubeApplicationConfig.d.ts +4 -0
- package/lib/application/LegendDataCubeApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendDataCubeApplicationConfig.js +5 -0
- package/lib/application/LegendDataCubeApplicationConfig.js.map +1 -1
- package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.d.ts +18 -0
- package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.d.ts.map +1 -0
- package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.js +48 -0
- package/lib/application/__test-utils__/LegendDataCubeApplicationTestUtils.js.map +1 -0
- package/lib/components/LegendDataCubeBlockingWindow.d.ts +2 -1
- package/lib/components/LegendDataCubeBlockingWindow.d.ts.map +1 -1
- package/lib/components/LegendDataCubeBlockingWindow.js +8 -3
- package/lib/components/LegendDataCubeBlockingWindow.js.map +1 -1
- package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.d.ts +42 -0
- package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.d.ts.map +1 -0
- package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.js +104 -0
- package/lib/components/__test-utils__/LegendDataCubeStoreTestUtils.js.map +1 -0
- package/lib/components/builder/LegendDataCubeBuilder.d.ts +5 -0
- package/lib/components/builder/LegendDataCubeBuilder.d.ts.map +1 -1
- package/lib/components/builder/LegendDataCubeBuilder.js +26 -5
- package/lib/components/builder/LegendDataCubeBuilder.js.map +1 -1
- package/lib/components/builder/LegendDataCubeBuilderStoreProvider.d.ts.map +1 -1
- package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js +1 -1
- package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js.map +1 -1
- package/lib/components/builder/LegendDataCubePartialSourceLoader.d.ts +19 -0
- package/lib/components/builder/LegendDataCubePartialSourceLoader.d.ts.map +1 -0
- package/lib/components/builder/LegendDataCubePartialSourceLoader.js +50 -0
- package/lib/components/builder/LegendDataCubePartialSourceLoader.js.map +1 -0
- package/lib/components/builder/LegendDataCubeSourceViewer.d.ts.map +1 -1
- package/lib/components/builder/LegendDataCubeSourceViewer.js +61 -1
- package/lib/components/builder/LegendDataCubeSourceViewer.js.map +1 -1
- package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.d.ts.map +1 -1
- package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.js +1 -2
- package/lib/components/builder/source/LocalFileDataCubeSourceBuilder.js.map +1 -1
- package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.d.ts +22 -0
- package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.d.ts.map +1 -0
- package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.js +28 -0
- package/lib/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.js.map +1 -0
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +3 -1
- package/lib/stores/LegendDataCubeBaseStore.d.ts +2 -1
- package/lib/stores/LegendDataCubeBaseStore.d.ts.map +1 -1
- package/lib/stores/LegendDataCubeBaseStore.js +6 -3
- package/lib/stores/LegendDataCubeBaseStore.js.map +1 -1
- package/lib/stores/LegendDataCubeDataCubeEngine.d.ts +6 -3
- package/lib/stores/LegendDataCubeDataCubeEngine.d.ts.map +1 -1
- package/lib/stores/LegendDataCubeDataCubeEngine.js +127 -106
- package/lib/stores/LegendDataCubeDataCubeEngine.js.map +1 -1
- package/lib/stores/LegendDataCubeDuckDBEngine.d.ts +11 -4
- package/lib/stores/LegendDataCubeDuckDBEngine.d.ts.map +1 -1
- package/lib/stores/LegendDataCubeDuckDBEngine.js +83 -16
- package/lib/stores/LegendDataCubeDuckDBEngine.js.map +1 -1
- package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts +4 -0
- package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts.map +1 -1
- package/lib/stores/builder/LegendDataCubeBuilderStore.js +58 -17
- package/lib/stores/builder/LegendDataCubeBuilderStore.js.map +1 -1
- package/lib/stores/builder/LegendDataCubeLoaderState.d.ts +11 -2
- package/lib/stores/builder/LegendDataCubeLoaderState.d.ts.map +1 -1
- package/lib/stores/builder/LegendDataCubeLoaderState.js +28 -1
- package/lib/stores/builder/LegendDataCubeLoaderState.js.map +1 -1
- package/lib/stores/builder/LegendDataCubeSourceLoaderState.d.ts +44 -0
- package/lib/stores/builder/LegendDataCubeSourceLoaderState.d.ts.map +1 -0
- package/lib/stores/builder/LegendDataCubeSourceLoaderState.js +101 -0
- package/lib/stores/builder/LegendDataCubeSourceLoaderState.js.map +1 -0
- package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.d.ts +3 -2
- package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.d.ts.map +1 -1
- package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.js +7 -10
- package/lib/stores/builder/source/LocalFileDataCubeSourceBuilderState.js.map +1 -1
- package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.d.ts +29 -0
- package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.d.ts.map +1 -0
- package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.js +25 -0
- package/lib/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.js.map +1 -0
- package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.d.ts +43 -0
- package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.d.ts.map +1 -0
- package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.js +142 -0
- package/lib/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.js.map +1 -0
- package/lib/stores/model/LegendQueryDataCubeSource.d.ts +2 -1
- package/lib/stores/model/LegendQueryDataCubeSource.d.ts.map +1 -1
- package/lib/stores/model/LegendQueryDataCubeSource.js +1 -0
- package/lib/stores/model/LegendQueryDataCubeSource.js.map +1 -1
- package/lib/stores/model/LocalFileDataCubeSource.d.ts +3 -8
- package/lib/stores/model/LocalFileDataCubeSource.d.ts.map +1 -1
- package/lib/stores/model/LocalFileDataCubeSource.js +5 -15
- package/lib/stores/model/LocalFileDataCubeSource.js.map +1 -1
- package/package.json +13 -11
- package/src/__lib__/LegendDataCubeNavigation.ts +21 -0
- package/src/application/LegendDataCubeApplicationConfig.ts +10 -0
- package/src/application/__test-utils__/LegendDataCubeApplicationTestUtils.ts +52 -0
- package/src/components/LegendDataCubeBlockingWindow.tsx +8 -2
- package/src/components/__test-utils__/LegendDataCubeStoreTestUtils.tsx +231 -0
- package/src/components/builder/LegendDataCubeBuilder.tsx +51 -6
- package/src/components/builder/LegendDataCubeBuilderStoreProvider.tsx +3 -0
- package/src/components/builder/LegendDataCubePartialSourceLoader.tsx +108 -0
- package/src/components/builder/LegendDataCubeSourceViewer.tsx +171 -1
- package/src/components/builder/source/LocalFileDataCubeSourceBuilder.tsx +1 -2
- package/src/components/builder/source/loader/LocalFileDataCubePartialSourceLoader.tsx +60 -0
- package/src/stores/LegendDataCubeBaseStore.ts +13 -6
- package/src/stores/LegendDataCubeDataCubeEngine.ts +161 -120
- package/src/stores/LegendDataCubeDuckDBEngine.ts +101 -17
- package/src/stores/builder/LegendDataCubeBuilderStore.tsx +96 -24
- package/src/stores/builder/LegendDataCubeLoaderState.tsx +44 -1
- package/src/stores/builder/LegendDataCubeSourceLoaderState.tsx +145 -0
- package/src/stores/builder/source/LocalFileDataCubeSourceBuilderState.ts +9 -14
- package/src/stores/builder/source/loader/LegendDataCubePartialSourceLoaderState.ts +41 -0
- package/src/stores/builder/source/loader/LocalFileDataCubePartialSourceLoaderState.ts +217 -0
- package/src/stores/model/LegendQueryDataCubeSource.ts +2 -0
- package/src/stores/model/LocalFileDataCubeSource.ts +6 -15
- 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 {
|
|
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
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
320
|
-
|
|
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 {
|
|
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
|
-
|
|
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?:
|
|
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:
|
|
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(
|
|
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
|
|
162
|
+
const tableDetails = guaranteeNonNullable(
|
|
164
163
|
await this._engine.ingestLocalFileData(this.fileData, this.fileFormat),
|
|
165
|
-
|
|
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.
|
|
172
|
-
rawSource.
|
|
173
|
-
rawSource.
|
|
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
|
+
}
|