@finos/legend-application-query 13.8.29 → 13.8.31
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__/LegendQueryEvent.d.ts +3 -0
- package/lib/__lib__/LegendQueryEvent.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryEvent.js +3 -0
- package/lib/__lib__/LegendQueryEvent.js.map +1 -1
- package/lib/__lib__/LegendQueryNavigation.d.ts +12 -0
- package/lib/__lib__/LegendQueryNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryNavigation.js +16 -0
- package/lib/__lib__/LegendQueryNavigation.js.map +1 -1
- package/lib/__lib__/LegendQueryTelemetryHelper.d.ts +3 -0
- package/lib/__lib__/LegendQueryTelemetryHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendQueryTelemetryHelper.js +9 -0
- package/lib/__lib__/LegendQueryTelemetryHelper.js.map +1 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
- package/lib/components/Core_LegendQueryApplicationPlugin.js +15 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
- package/lib/components/LegendQueryWebApplication.d.ts.map +1 -1
- package/lib/components/LegendQueryWebApplication.js +2 -1
- package/lib/components/LegendQueryWebApplication.js.map +1 -1
- package/lib/components/QueryEditor.d.ts.map +1 -1
- package/lib/components/QueryEditor.js +12 -2
- package/lib/components/QueryEditor.js.map +1 -1
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.d.ts.map +1 -1
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js +6 -40
- package/lib/components/data-product/LegendQueryDataProductQueryBuilder.js.map +1 -1
- package/lib/components/ingest/IngestInfo.d.ts +32 -0
- package/lib/components/ingest/IngestInfo.d.ts.map +1 -0
- package/lib/components/ingest/IngestInfo.js +63 -0
- package/lib/components/ingest/IngestInfo.js.map +1 -0
- package/lib/components/ingest/IngestQueryBuilderSetupPanel.d.ts +18 -0
- package/lib/components/ingest/IngestQueryBuilderSetupPanel.d.ts.map +1 -0
- package/lib/components/ingest/IngestQueryBuilderSetupPanel.js +77 -0
- package/lib/components/ingest/IngestQueryBuilderSetupPanel.js.map +1 -0
- package/lib/components/ingest/IngestQueryCreator.d.ts +27 -0
- package/lib/components/ingest/IngestQueryCreator.d.ts.map +1 -0
- package/lib/components/ingest/IngestQueryCreator.js +45 -0
- package/lib/components/ingest/IngestQueryCreator.js.map +1 -0
- package/lib/components/shared/LakehouseRuntimeConfigModal.d.ts +29 -0
- package/lib/components/shared/LakehouseRuntimeConfigModal.d.ts.map +1 -0
- package/lib/components/shared/LakehouseRuntimeConfigModal.js +60 -0
- package/lib/components/shared/LakehouseRuntimeConfigModal.js.map +1 -0
- package/lib/index.css +1 -1
- package/lib/light-mode.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryEditorStore.d.ts +10 -0
- package/lib/stores/QueryEditorStore.d.ts.map +1 -1
- package/lib/stores/QueryEditorStore.js +81 -2
- package/lib/stores/QueryEditorStore.js.map +1 -1
- package/lib/stores/ingest/IngestLegendQueryBuilderState.d.ts +122 -0
- package/lib/stores/ingest/IngestLegendQueryBuilderState.d.ts.map +1 -0
- package/lib/stores/ingest/IngestLegendQueryBuilderState.js +191 -0
- package/lib/stores/ingest/IngestLegendQueryBuilderState.js.map +1 -0
- package/lib/stores/ingest/IngestQueryCreatorStore.d.ts +75 -0
- package/lib/stores/ingest/IngestQueryCreatorStore.d.ts.map +1 -0
- package/lib/stores/ingest/IngestQueryCreatorStore.js +169 -0
- package/lib/stores/ingest/IngestQueryCreatorStore.js.map +1 -0
- package/lib/stores/ingest/IngestQueryGraphHelper.d.ts +58 -0
- package/lib/stores/ingest/IngestQueryGraphHelper.d.ts.map +1 -0
- package/lib/stores/ingest/IngestQueryGraphHelper.js +72 -0
- package/lib/stores/ingest/IngestQueryGraphHelper.js.map +1 -0
- package/package.json +13 -13
- package/src/__lib__/LegendQueryEvent.ts +3 -0
- package/src/__lib__/LegendQueryNavigation.ts +35 -0
- package/src/__lib__/LegendQueryTelemetryHelper.ts +15 -0
- package/src/components/Core_LegendQueryApplicationPlugin.tsx +20 -0
- package/src/components/LegendQueryWebApplication.tsx +14 -0
- package/src/components/QueryEditor.tsx +25 -1
- package/src/components/data-product/LegendQueryDataProductQueryBuilder.tsx +7 -127
- package/src/components/ingest/IngestInfo.tsx +197 -0
- package/src/components/ingest/IngestQueryBuilderSetupPanel.tsx +204 -0
- package/src/components/ingest/IngestQueryCreator.tsx +75 -0
- package/src/components/shared/LakehouseRuntimeConfigModal.tsx +148 -0
- package/src/stores/QueryEditorStore.ts +131 -1
- package/src/stores/ingest/IngestLegendQueryBuilderState.ts +259 -0
- package/src/stores/ingest/IngestQueryCreatorStore.ts +262 -0
- package/src/stores/ingest/IngestQueryGraphHelper.ts +120 -0
- package/tsconfig.json +7 -0
|
@@ -76,8 +76,10 @@ import {
|
|
|
76
76
|
QueryDataProductNativeExecutionContextInfo,
|
|
77
77
|
QueryDataProductModelAccessExecutionContextInfo,
|
|
78
78
|
QueryDataProductLakehouseExecutionContextInfo,
|
|
79
|
+
QueryIngestExecutionContextInfo,
|
|
79
80
|
ModelAccessPointGroup,
|
|
80
81
|
type DataProduct,
|
|
82
|
+
IngestDefinition,
|
|
81
83
|
LakehouseRuntime,
|
|
82
84
|
V1_DATA_PRODUCT_ELEMENT_PROTOCOL_TYPE,
|
|
83
85
|
V1_DataProductArtifact,
|
|
@@ -152,6 +154,11 @@ import { generateDataSpaceQueryCreatorRoute } from '../__lib__/DSL_DataSpace_Leg
|
|
|
152
154
|
import { hasDataSpaceInfoBeenVisited } from '../__lib__/LegendQueryUserDataSpaceHelper.js';
|
|
153
155
|
import { LegendQueryDataSpaceQueryBuilderState } from './data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js';
|
|
154
156
|
import { LegendQueryDataProductQueryBuilderState } from './data-product/query-builder/LegendQueryDataProductQueryBuilderState.js';
|
|
157
|
+
import { IngestLegendQueryBuilderState } from './ingest/IngestLegendQueryBuilderState.js';
|
|
158
|
+
import {
|
|
159
|
+
fetchIngestEntitiesByClassifier,
|
|
160
|
+
swapIngestInGraph,
|
|
161
|
+
} from './ingest/IngestQueryGraphHelper.js';
|
|
155
162
|
import { DataProductSelectorState } from './data-space/DataProductSelectorState.js';
|
|
156
163
|
import {
|
|
157
164
|
decorateEnvWithRealm,
|
|
@@ -317,6 +324,7 @@ export abstract class QueryEditorStore {
|
|
|
317
324
|
showAppInfo = false;
|
|
318
325
|
showDataspaceInfo = false;
|
|
319
326
|
showDataProductInfo = false;
|
|
327
|
+
showIngestInfo = false;
|
|
320
328
|
enableMinialGraphForDataSpaceLoadingPerformance = true;
|
|
321
329
|
|
|
322
330
|
constructor(
|
|
@@ -331,6 +339,7 @@ export abstract class QueryEditorStore {
|
|
|
331
339
|
showAppInfo: observable,
|
|
332
340
|
showDataspaceInfo: observable,
|
|
333
341
|
showDataProductInfo: observable,
|
|
342
|
+
showIngestInfo: observable,
|
|
334
343
|
queryBuilderState: observable,
|
|
335
344
|
enableMinialGraphForDataSpaceLoadingPerformance: observable,
|
|
336
345
|
isPerformingBlockingAction: computed,
|
|
@@ -339,6 +348,7 @@ export abstract class QueryEditorStore {
|
|
|
339
348
|
setShowAppInfo: action,
|
|
340
349
|
setShowDataspaceInfo: action,
|
|
341
350
|
setShowDataProductInfo: action,
|
|
351
|
+
setShowIngestInfo: action,
|
|
342
352
|
setEnableMinialGraphForDataSpaceLoadingPerformance: action,
|
|
343
353
|
initialize: flow,
|
|
344
354
|
buildGraph: flow,
|
|
@@ -453,6 +463,10 @@ export abstract class QueryEditorStore {
|
|
|
453
463
|
this.showDataProductInfo = val;
|
|
454
464
|
}
|
|
455
465
|
|
|
466
|
+
setShowIngestInfo(val: boolean): void {
|
|
467
|
+
this.showIngestInfo = val;
|
|
468
|
+
}
|
|
469
|
+
|
|
456
470
|
setShowRegisterServiceModal(val: boolean): void {
|
|
457
471
|
this.showRegisterServiceModal = val;
|
|
458
472
|
}
|
|
@@ -1926,13 +1940,64 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
|
|
|
1926
1940
|
queryInfo?.executionContext instanceof
|
|
1927
1941
|
QueryDataProductModelAccessExecutionContextInfo ||
|
|
1928
1942
|
queryInfo?.executionContext instanceof
|
|
1929
|
-
QueryDataProductLakehouseExecutionContextInfo
|
|
1943
|
+
QueryDataProductLakehouseExecutionContextInfo ||
|
|
1944
|
+
queryInfo?.executionContext instanceof QueryIngestExecutionContextInfo
|
|
1930
1945
|
)
|
|
1931
1946
|
) {
|
|
1932
1947
|
yield flowResult(this.buildFullGraph());
|
|
1948
|
+
} else if (
|
|
1949
|
+
queryInfo?.executionContext instanceof QueryIngestExecutionContextInfo
|
|
1950
|
+
) {
|
|
1951
|
+
// Mirror the creator-store flow: build a graph containing only the
|
|
1952
|
+
// referenced ingest definition. The full project entity fetch is
|
|
1953
|
+
// skipped, but we still list every ingest in the project so the source
|
|
1954
|
+
// dropdown can show them and `swapIngestDefinition` can build a
|
|
1955
|
+
// different one on demand.
|
|
1956
|
+
yield* this.buildIngestGraph(
|
|
1957
|
+
queryInfo.groupId,
|
|
1958
|
+
queryInfo.artifactId,
|
|
1959
|
+
queryInfo.versionId,
|
|
1960
|
+
queryInfo.executionContext.ingestDefinitionPath,
|
|
1961
|
+
);
|
|
1933
1962
|
}
|
|
1934
1963
|
}
|
|
1935
1964
|
|
|
1965
|
+
/**
|
|
1966
|
+
* Cached ingest entities for the existing-query flow. Populated by
|
|
1967
|
+
* {@link buildIngestGraph} (called from {@link buildGraph}) and consumed by
|
|
1968
|
+
* {@link initQueryBuildStateFromQuery} to back the source dropdown +
|
|
1969
|
+
* {@link IngestLegendQueryBuilderState.swapIngest} callback.
|
|
1970
|
+
*/
|
|
1971
|
+
private _ingestEntitiesByPath: Map<string, Entity> = new Map();
|
|
1972
|
+
|
|
1973
|
+
private *buildIngestGraph(
|
|
1974
|
+
groupId: string,
|
|
1975
|
+
artifactId: string,
|
|
1976
|
+
versionId: string,
|
|
1977
|
+
ingestDefinitionPath: string,
|
|
1978
|
+
): GeneratorFn<void> {
|
|
1979
|
+
yield this.graphManagerState.initializeSystem();
|
|
1980
|
+
|
|
1981
|
+
this._ingestEntitiesByPath = (yield fetchIngestEntitiesByClassifier(
|
|
1982
|
+
this.depotServerClient,
|
|
1983
|
+
groupId,
|
|
1984
|
+
artifactId,
|
|
1985
|
+
versionId,
|
|
1986
|
+
)) as Map<string, Entity>;
|
|
1987
|
+
|
|
1988
|
+
const target = this._ingestEntitiesByPath.get(ingestDefinitionPath);
|
|
1989
|
+
if (!target) {
|
|
1990
|
+
throw new Error(
|
|
1991
|
+
`Can't find ingest definition '${ingestDefinitionPath}' in project ${groupId}:${artifactId}:${versionId}`,
|
|
1992
|
+
);
|
|
1993
|
+
}
|
|
1994
|
+
yield swapIngestInGraph(this.graphManagerState, target, {
|
|
1995
|
+
groupId,
|
|
1996
|
+
artifactId,
|
|
1997
|
+
versionId,
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
|
|
1936
2001
|
override async setUpEditorState(): Promise<void> {
|
|
1937
2002
|
const queryInfo = await this.graphManagerState.graphManager.getQueryInfo(
|
|
1938
2003
|
this.queryId,
|
|
@@ -2191,6 +2256,71 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
|
|
|
2191
2256
|
},
|
|
2192
2257
|
);
|
|
2193
2258
|
return queryBuilderState;
|
|
2259
|
+
} else if (exec instanceof QueryIngestExecutionContextInfo) {
|
|
2260
|
+
// The graph was already populated by `buildIngestGraph` (above) with
|
|
2261
|
+
// just the referenced ingest definition. Resolve it, build the adhoc
|
|
2262
|
+
// lakehouse runtime, and stand up the ingest query builder state.
|
|
2263
|
+
const ingestDefinition = guaranteeType(
|
|
2264
|
+
this.graphManagerState.graph.getElement(exec.ingestDefinitionPath),
|
|
2265
|
+
IngestDefinition,
|
|
2266
|
+
`Can't find ingest definition '${exec.ingestDefinitionPath}'`,
|
|
2267
|
+
);
|
|
2268
|
+
const projectInfo = this.getProjectInfo();
|
|
2269
|
+
const adhocRuntime = await this.createLakehousePackageableRuntime(
|
|
2270
|
+
exec.ingestDefinitionPath,
|
|
2271
|
+
projectInfo,
|
|
2272
|
+
);
|
|
2273
|
+
this.graphManagerState.graph.addElement(adhocRuntime, '_internal_');
|
|
2274
|
+
|
|
2275
|
+
// Tracked separately from the closure on `ingestQueryBuilderState` so
|
|
2276
|
+
// the swap callback can capture it directly without forming a self-
|
|
2277
|
+
// reference (which trips the `no-unsafe-assignment` rule).
|
|
2278
|
+
let currentIngestPath = exec.ingestDefinitionPath;
|
|
2279
|
+
const swapIngest = async (path: string): Promise<IngestDefinition> => {
|
|
2280
|
+
// Mirror `IngestQueryCreatorStore.swapIngestDefinition`: rebuild
|
|
2281
|
+
// the requested ingest in place of the current one. The entity
|
|
2282
|
+
// cache was populated up front by `buildIngestGraph`.
|
|
2283
|
+
const entity = this._ingestEntitiesByPath.get(path);
|
|
2284
|
+
if (!entity) {
|
|
2285
|
+
throw new Error(
|
|
2286
|
+
`Can't find ingest definition '${path}' in project ${projectInfo.groupId}:${projectInfo.artifactId}:${projectInfo.versionId}`,
|
|
2287
|
+
);
|
|
2288
|
+
}
|
|
2289
|
+
const next = await swapIngestInGraph(this.graphManagerState, entity, {
|
|
2290
|
+
currentPath: currentIngestPath,
|
|
2291
|
+
groupId: projectInfo.groupId,
|
|
2292
|
+
artifactId: projectInfo.artifactId,
|
|
2293
|
+
versionId: projectInfo.versionId,
|
|
2294
|
+
});
|
|
2295
|
+
currentIngestPath = next.path;
|
|
2296
|
+
return next;
|
|
2297
|
+
};
|
|
2298
|
+
|
|
2299
|
+
const ingestQueryBuilderState = new IngestLegendQueryBuilderState(
|
|
2300
|
+
this.applicationStore,
|
|
2301
|
+
undefined,
|
|
2302
|
+
this.graphManagerState,
|
|
2303
|
+
QueryBuilderDataBrowserWorkflow.INSTANCE,
|
|
2304
|
+
new QueryBuilderActionConfig_QueryApplication(this),
|
|
2305
|
+
ingestDefinition,
|
|
2306
|
+
Array.from(this._ingestEntitiesByPath.keys()),
|
|
2307
|
+
swapIngest,
|
|
2308
|
+
adhocRuntime,
|
|
2309
|
+
projectInfo,
|
|
2310
|
+
this.applicationStore.config.options.queryBuilderConfig,
|
|
2311
|
+
{
|
|
2312
|
+
groupId: projectInfo.groupId,
|
|
2313
|
+
artifactId: projectInfo.artifactId,
|
|
2314
|
+
versionId: projectInfo.versionId,
|
|
2315
|
+
queryId: queryInfo.id,
|
|
2316
|
+
},
|
|
2317
|
+
);
|
|
2318
|
+
await ingestQueryBuilderState.changeAccessorOwner(ingestDefinition);
|
|
2319
|
+
await ingestQueryBuilderState.changeAccessor({
|
|
2320
|
+
tableName: exec.dataSet,
|
|
2321
|
+
});
|
|
2322
|
+
ingestQueryBuilderState.changeSelectedRuntime(adhocRuntime);
|
|
2323
|
+
return ingestQueryBuilderState;
|
|
2194
2324
|
}
|
|
2195
2325
|
throw new UnsupportedOperationError(`Unsupported query execution context`);
|
|
2196
2326
|
}
|
|
@@ -0,0 +1,259 @@
|
|
|
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
|
+
type Accessor,
|
|
19
|
+
type AccessorOwner,
|
|
20
|
+
type GraphManagerState,
|
|
21
|
+
type IngestDefinition,
|
|
22
|
+
type PackageableElement,
|
|
23
|
+
type PackageableRuntime,
|
|
24
|
+
type QueryExecutionContext,
|
|
25
|
+
LakehouseRuntime,
|
|
26
|
+
QueryIngestExecutionContext,
|
|
27
|
+
} from '@finos/legend-graph';
|
|
28
|
+
import {
|
|
29
|
+
AccessorQueryBuilderState,
|
|
30
|
+
type QueryBuilderActionConfig,
|
|
31
|
+
type QueryBuilderConfig,
|
|
32
|
+
type QueryBuilderWorkflowState,
|
|
33
|
+
} from '@finos/legend-query-builder';
|
|
34
|
+
import type { GenericLegendApplicationStore } from '@finos/legend-application';
|
|
35
|
+
import type {
|
|
36
|
+
ProjectGAVCoordinates,
|
|
37
|
+
QueryableSourceInfo,
|
|
38
|
+
} from '@finos/legend-storage';
|
|
39
|
+
import { action, makeObservable, observable, runInAction } from 'mobx';
|
|
40
|
+
import { assertErrorThrown } from '@finos/legend-shared';
|
|
41
|
+
import { renderIngestQueryBuilderSetupPanelContent } from '../../components/ingest/IngestQueryBuilderSetupPanel.js';
|
|
42
|
+
import { generateIngestQueryCreatorRoute } from '../../__lib__/LegendQueryNavigation.js';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Query builder state for an ingest-backed query.
|
|
46
|
+
*
|
|
47
|
+
* Extends {@link AccessorQueryBuilderState} because an ingest definition is
|
|
48
|
+
* already an `AccessorOwner` (see `AccessorQueryBuilderState.accessorOwners`)
|
|
49
|
+
* and ingest queries don't require a mapping (`requiresMappingForExecution`
|
|
50
|
+
* is already `false` in the base class).
|
|
51
|
+
*
|
|
52
|
+
* The execution context produced here is a {@link QueryIngestExecutionContext}
|
|
53
|
+
* carrying `ingestDefinitionPath` and `dataSet` — the same two values the
|
|
54
|
+
* route handler resolved from the URL.
|
|
55
|
+
*/
|
|
56
|
+
export class IngestLegendQueryBuilderState extends AccessorQueryBuilderState {
|
|
57
|
+
/**
|
|
58
|
+
* Currently selected & graph-resolved ingest definition. Observable so the
|
|
59
|
+
* setup panel re-renders when the user picks a different ingest from the
|
|
60
|
+
* source dropdown.
|
|
61
|
+
*/
|
|
62
|
+
ingestDefinition: IngestDefinition;
|
|
63
|
+
/**
|
|
64
|
+
* All ingest definition paths discovered in the project (fetched up front
|
|
65
|
+
* via depot's classifier-scoped entities endpoint). Only `ingestDefinition`
|
|
66
|
+
* is actually built into the graph — the others are surfaced as paths so
|
|
67
|
+
* the user can switch without paying the cost of building them all.
|
|
68
|
+
*/
|
|
69
|
+
readonly allIngestPaths: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Swap callback wired by {@link IngestQueryCreatorStore}. Deletes the
|
|
72
|
+
* currently built ingest from the graph, builds the target one from its
|
|
73
|
+
* cached entity, and returns the new metamodel instance.
|
|
74
|
+
*/
|
|
75
|
+
readonly swapIngest: (path: string) => Promise<IngestDefinition>;
|
|
76
|
+
readonly project: ProjectGAVCoordinates;
|
|
77
|
+
/**
|
|
78
|
+
* Adhoc lakehouse runtime built from the user's lakehouse environment +
|
|
79
|
+
* consumer warehouse, mirroring how `LegendQueryDataProductQueryBuilderState`
|
|
80
|
+
* builds its runtime for model-access / lakehouse access points. Created by
|
|
81
|
+
* the creator store (where the depot/lakehouse clients live) and injected
|
|
82
|
+
* here so the editor can execute against it without a packaged runtime.
|
|
83
|
+
*/
|
|
84
|
+
readonly adhocRuntime: PackageableRuntime;
|
|
85
|
+
/**
|
|
86
|
+
* Loading flag flipped while {@link changeIngestDefinition} is fetching /
|
|
87
|
+
* rebuilding the newly selected ingest. Lets the setup panel disable the
|
|
88
|
+
* source dropdown during the swap so we don't get overlapping changes.
|
|
89
|
+
*/
|
|
90
|
+
isSwappingIngest = false;
|
|
91
|
+
|
|
92
|
+
constructor(
|
|
93
|
+
applicationStore: GenericLegendApplicationStore,
|
|
94
|
+
accessor: Accessor | undefined,
|
|
95
|
+
graphManagerState: GraphManagerState,
|
|
96
|
+
workflow: QueryBuilderWorkflowState,
|
|
97
|
+
actionConfig: QueryBuilderActionConfig,
|
|
98
|
+
ingestDefinition: IngestDefinition,
|
|
99
|
+
allIngestPaths: string[],
|
|
100
|
+
swapIngest: (path: string) => Promise<IngestDefinition>,
|
|
101
|
+
adhocRuntime: PackageableRuntime,
|
|
102
|
+
project: ProjectGAVCoordinates,
|
|
103
|
+
config?: QueryBuilderConfig | undefined,
|
|
104
|
+
sourceInfo?: QueryableSourceInfo | undefined,
|
|
105
|
+
) {
|
|
106
|
+
super(
|
|
107
|
+
applicationStore,
|
|
108
|
+
accessor,
|
|
109
|
+
graphManagerState,
|
|
110
|
+
workflow,
|
|
111
|
+
actionConfig,
|
|
112
|
+
config,
|
|
113
|
+
sourceInfo,
|
|
114
|
+
);
|
|
115
|
+
makeObservable(this, {
|
|
116
|
+
ingestDefinition: observable,
|
|
117
|
+
isSwappingIngest: observable,
|
|
118
|
+
changeIngestDefinition: action,
|
|
119
|
+
});
|
|
120
|
+
this.ingestDefinition = ingestDefinition;
|
|
121
|
+
this.allIngestPaths = allIngestPaths;
|
|
122
|
+
this.swapIngest = swapIngest;
|
|
123
|
+
this.adhocRuntime = adhocRuntime;
|
|
124
|
+
this.project = project;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
override TEMPORARY__setupPanelContentRenderer = (): React.ReactNode =>
|
|
128
|
+
renderIngestQueryBuilderSetupPanelContent(this);
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The currently selected data set. Derived from `sourceAccessor` so it
|
|
132
|
+
* stays in sync with `changeAccessor` (e.g. when the user picks a different
|
|
133
|
+
* data set, or when {@link changeIngestDefinition} re-points the source).
|
|
134
|
+
*/
|
|
135
|
+
get dataSet(): string {
|
|
136
|
+
return this.sourceAccessor?.accessor ?? '';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
override getQueryExecutionContext(): QueryExecutionContext {
|
|
140
|
+
const exec = new QueryIngestExecutionContext();
|
|
141
|
+
exec.ingestDefinitionPath = this.ingestDefinition.path;
|
|
142
|
+
exec.dataSet = this.dataSet;
|
|
143
|
+
return exec;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The deep-link flow opens the editor against a single, pre-resolved ingest
|
|
148
|
+
* definition. The user shouldn't be picking a different owner, but we still
|
|
149
|
+
* surface the current ingest so the source dropdown reflects the selection
|
|
150
|
+
* instead of rendering the empty "Choose a source..." placeholder.
|
|
151
|
+
*
|
|
152
|
+
* The full list of selectable ingests is exposed separately via
|
|
153
|
+
* {@link allIngestPaths} (the others aren't built into the graph yet — see
|
|
154
|
+
* {@link changeIngestDefinition}).
|
|
155
|
+
*/
|
|
156
|
+
override get accessorOwners(): AccessorOwner[] {
|
|
157
|
+
return [this.ingestDefinition];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Execution always goes through {@link adhocRuntime} (selected by the
|
|
162
|
+
* creator store). Return an empty list so the runtime dropdown is hidden
|
|
163
|
+
* and the user can't override it.
|
|
164
|
+
*/
|
|
165
|
+
override get compatibleRuntimes(): PackageableRuntime[] {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The adhoc lakehouse runtime is registered on the graph under the
|
|
171
|
+
* `_internal_` package so the editor can resolve it, but it is not part
|
|
172
|
+
* of the published project. Surface it as a floating execution element so
|
|
173
|
+
* it's bundled into the execution payload at run time (mirrors what the
|
|
174
|
+
* data-product flow does for its lakehouse runtime).
|
|
175
|
+
*/
|
|
176
|
+
override get floatingExecutionElements(): PackageableElement[] | undefined {
|
|
177
|
+
return this.graphManagerState.graph.origin !== undefined
|
|
178
|
+
? [this.adhocRuntime]
|
|
179
|
+
: undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Convenience accessor: the underlying {@link LakehouseRuntime} on the
|
|
184
|
+
* adhoc runtime, if any. Used by the setup panel to feed the runtime
|
|
185
|
+
* configuration modal.
|
|
186
|
+
*/
|
|
187
|
+
get lakehouseRuntime(): LakehouseRuntime | undefined {
|
|
188
|
+
return this.adhocRuntime.runtimeValue instanceof LakehouseRuntime
|
|
189
|
+
? this.adhocRuntime.runtimeValue
|
|
190
|
+
: undefined;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Swap the active ingest definition to the one at `path`. Triggered by the
|
|
195
|
+
* source dropdown in {@link IngestQueryBuilderSetupPanel}. Delegates the
|
|
196
|
+
* graph mutation (delete current, build new) to {@link swapIngest} and then
|
|
197
|
+
* rewires the source accessor so the editor reflects the new ingest's
|
|
198
|
+
* datasets.
|
|
199
|
+
*/
|
|
200
|
+
async changeIngestDefinition(path: string): Promise<void> {
|
|
201
|
+
if (path === this.ingestDefinition.path || this.isSwappingIngest) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
runInAction(() => {
|
|
205
|
+
this.isSwappingIngest = true;
|
|
206
|
+
});
|
|
207
|
+
try {
|
|
208
|
+
const next = await this.swapIngest(path);
|
|
209
|
+
runInAction(() => {
|
|
210
|
+
this.ingestDefinition = next;
|
|
211
|
+
});
|
|
212
|
+
// Re-derive `sourceAccessor` against the new ingest. The previously
|
|
213
|
+
// selected data set most likely doesn't exist on the new ingest, so
|
|
214
|
+
// pick the first available one (if any).
|
|
215
|
+
await this.changeAccessorOwner(next);
|
|
216
|
+
const firstAccessor = this.accessors[0];
|
|
217
|
+
if (firstAccessor) {
|
|
218
|
+
await this.changeAccessor(firstAccessor);
|
|
219
|
+
}
|
|
220
|
+
} catch (error) {
|
|
221
|
+
assertErrorThrown(error);
|
|
222
|
+
this.applicationStore.notificationService.notifyError(error);
|
|
223
|
+
} finally {
|
|
224
|
+
runInAction(() => {
|
|
225
|
+
this.isSwappingIngest = false;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Copies the deep-link to this ingest query set up (GAV + ingest definition
|
|
232
|
+
* path + data set) to the user's clipboard. Mirrors
|
|
233
|
+
* `LegendQueryDataProductQueryBuilderState.copyDataProductLinkToClipBoard`.
|
|
234
|
+
*/
|
|
235
|
+
copyIngestQueryLinkToClipBoard(): void {
|
|
236
|
+
const route =
|
|
237
|
+
this.applicationStore.navigationService.navigator.generateAddress(
|
|
238
|
+
generateIngestQueryCreatorRoute(
|
|
239
|
+
this.project.groupId,
|
|
240
|
+
this.project.artifactId,
|
|
241
|
+
this.project.versionId,
|
|
242
|
+
this.ingestDefinition.path,
|
|
243
|
+
this.dataSet,
|
|
244
|
+
),
|
|
245
|
+
);
|
|
246
|
+
navigator.clipboard
|
|
247
|
+
.writeText(route)
|
|
248
|
+
.then(() =>
|
|
249
|
+
this.applicationStore.notificationService.notifySuccess(
|
|
250
|
+
'Copied ingest query set up link to clipboard',
|
|
251
|
+
),
|
|
252
|
+
)
|
|
253
|
+
.catch(() =>
|
|
254
|
+
this.applicationStore.notificationService.notifyError(
|
|
255
|
+
'Error copying ingest query set up link to clipboard',
|
|
256
|
+
),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|