@finos/legend-application-studio 28.21.22 → 28.21.24
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__/LegendStudioDocumentation.d.ts +2 -2
- package/lib/__lib__/LegendStudioDocumentation.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioDocumentation.js +1 -1
- package/lib/__lib__/LegendStudioDocumentation.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +2 -5
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js +13 -239
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +17 -3
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.d.ts +22 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.js +134 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.d.ts +89 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.js +144 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.d.ts.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js +14 -8
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js.map +1 -1
- package/lib/components/editor/ingest-definition-editor.css +1 -1
- package/lib/components/editor/ingest-definition-editor.css.map +1 -1
- package/lib/components/project-reviewer/ProjectReviewer.d.ts.map +1 -1
- package/lib/components/project-reviewer/ProjectReviewer.js +2 -1
- package/lib/components/project-reviewer/ProjectReviewer.js.map +1 -1
- package/lib/components/project-view/ProjectViewer.d.ts.map +1 -1
- package/lib/components/project-view/ProjectViewer.js +2 -2
- package/lib/components/project-view/ProjectViewer.js.map +1 -1
- package/lib/components/showcase/ShowcaseViewer.d.ts.map +1 -1
- package/lib/components/showcase/ShowcaseViewer.js +2 -2
- package/lib/components/showcase/ShowcaseViewer.js.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.js +98 -43
- package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js +1 -2
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts +8 -30
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js +7 -147
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +32 -28
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +8 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +15 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.d.ts +86 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.js +420 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.d.ts +62 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.js +138 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.js.map +1 -0
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts +10 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js +105 -12
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
- package/package.json +11 -11
- package/src/__lib__/LegendStudioDocumentation.ts +1 -1
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +2 -5
- package/src/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.tsx +19 -869
- package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +90 -34
- package/src/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.tsx +418 -0
- package/src/components/editor/editor-group/testable/LakehouseTestableEditor.tsx +564 -0
- package/src/components/editor/editor-group/testable/TestableSharedComponents.tsx +17 -9
- package/src/components/project-reviewer/ProjectReviewer.tsx +2 -0
- package/src/components/project-view/ProjectViewer.tsx +2 -1
- package/src/components/showcase/ShowcaseViewer.tsx +2 -1
- package/src/components/workspace-setup/WorkspaceSetup.tsx +169 -75
- package/src/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.ts +1 -2
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +1 -0
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.ts +18 -204
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +41 -36
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +16 -0
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.ts +654 -0
- package/src/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.ts +224 -0
- package/src/stores/workspace-setup/WorkspaceSetupStore.ts +125 -8
- package/tsconfig.json +4 -0
package/src/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-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
|
+
/**
|
|
18
|
+
* Shared utilities for Lakehouse test state:
|
|
19
|
+
* used by both DataProductTestableState and IngestTestableState.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
type Accessor,
|
|
24
|
+
type AccessorOwner,
|
|
25
|
+
type AbstractPureGraphManager,
|
|
26
|
+
type BaseDataResolver,
|
|
27
|
+
DataProduct,
|
|
28
|
+
IngestDefinition,
|
|
29
|
+
RelationElement,
|
|
30
|
+
RelationElementsData,
|
|
31
|
+
RelationRowTestData,
|
|
32
|
+
getAccessorItemLabelForElement,
|
|
33
|
+
observe_RelationElement,
|
|
34
|
+
observe_RelationRowTestData,
|
|
35
|
+
type PackageableElement,
|
|
36
|
+
} from '@finos/legend-graph';
|
|
37
|
+
import { noop } from '@finos/legend-shared';
|
|
38
|
+
import { runInAction } from 'mobx';
|
|
39
|
+
import type { EditorStore } from '../../../EditorStore.js';
|
|
40
|
+
import { RelationElementsDataState } from '../data/EmbeddedDataState.js';
|
|
41
|
+
|
|
42
|
+
// ─── Pure helpers ─────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
export const createEmptyRelationElement = (
|
|
45
|
+
itemId: string,
|
|
46
|
+
columns: string[] = [],
|
|
47
|
+
): RelationElement => {
|
|
48
|
+
const row = observe_RelationRowTestData(new RelationRowTestData());
|
|
49
|
+
row.values = columns.map(() => '');
|
|
50
|
+
const relationElement = new RelationElement();
|
|
51
|
+
relationElement.paths = [itemId];
|
|
52
|
+
relationElement.columns = columns;
|
|
53
|
+
relationElement.rows = [row];
|
|
54
|
+
return observe_RelationElement(relationElement);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const buildRelationElementsDataWithColumns = (
|
|
58
|
+
accessors: Accessor[],
|
|
59
|
+
): RelationElementsData => {
|
|
60
|
+
const relData = new RelationElementsData();
|
|
61
|
+
relData.relationElements = accessors.map((acc) => {
|
|
62
|
+
const itemId = acc.accessor || 'UNKNOWN';
|
|
63
|
+
const columns = acc.relationType.columns.map((col) => col.name);
|
|
64
|
+
return createEmptyRelationElement(itemId, columns);
|
|
65
|
+
});
|
|
66
|
+
return relData;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const isIngestOrDataProductAccessor = (
|
|
70
|
+
accessor: Accessor,
|
|
71
|
+
): accessor is Accessor =>
|
|
72
|
+
accessor.parentElement instanceof DataProduct ||
|
|
73
|
+
accessor.parentElement instanceof IngestDefinition;
|
|
74
|
+
|
|
75
|
+
export interface ElementDataItem {
|
|
76
|
+
id: string;
|
|
77
|
+
label: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const getElementDataItems = (
|
|
81
|
+
element: PackageableElement,
|
|
82
|
+
graphManager: AbstractPureGraphManager,
|
|
83
|
+
): ElementDataItem[] => {
|
|
84
|
+
if (element instanceof DataProduct) {
|
|
85
|
+
return element.accessPointGroups
|
|
86
|
+
.flatMap((g) => g.accessPoints)
|
|
87
|
+
.map((ap) => ({ id: ap.id, label: ap.id }));
|
|
88
|
+
}
|
|
89
|
+
if (element instanceof IngestDefinition) {
|
|
90
|
+
return graphManager
|
|
91
|
+
.getIngestDefinitionDatasetNames(element)
|
|
92
|
+
.map((name) => ({ id: name, label: name }));
|
|
93
|
+
}
|
|
94
|
+
return [];
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// ─── Shared element test data state ──────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Wraps a single BaseDataResolver within a test suite's testData array.
|
|
101
|
+
* Shared between DataProduct and Ingest test suite states — both populate
|
|
102
|
+
* test data by wiring BaseDataResolver entries to PackageableElements.
|
|
103
|
+
*/
|
|
104
|
+
export class LakehouseElementTestDataState {
|
|
105
|
+
readonly testData: BaseDataResolver;
|
|
106
|
+
readonly editorStore: EditorStore;
|
|
107
|
+
readonly relationElementsDataState: RelationElementsDataState | undefined;
|
|
108
|
+
|
|
109
|
+
constructor(testData: BaseDataResolver, editorStore: EditorStore) {
|
|
110
|
+
this.testData = testData;
|
|
111
|
+
this.editorStore = editorStore;
|
|
112
|
+
if (testData.data instanceof RelationElementsData) {
|
|
113
|
+
this.relationElementsDataState = new RelationElementsDataState(
|
|
114
|
+
editorStore,
|
|
115
|
+
testData.data,
|
|
116
|
+
);
|
|
117
|
+
this.initAccessorOptions();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get element(): PackageableElement {
|
|
122
|
+
return this.testData.element.value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
get itemLabel(): string {
|
|
126
|
+
return getAccessorItemLabelForElement(this.element as AccessorOwner);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private initAccessorOptions(): void {
|
|
130
|
+
const dataState = this.relationElementsDataState;
|
|
131
|
+
if (!dataState) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
this.refreshAccessorOptions(dataState).catch(noop);
|
|
135
|
+
dataState.setRefreshAccessorOptions(() =>
|
|
136
|
+
this.refreshAccessorOptions(dataState),
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private async refreshAccessorOptions(
|
|
141
|
+
dataState: RelationElementsDataState,
|
|
142
|
+
): Promise<void> {
|
|
143
|
+
const element = this.element;
|
|
144
|
+
const graphManager = this.editorStore.graphManagerState.graphManager;
|
|
145
|
+
const graph = this.editorStore.graphManagerState.graph;
|
|
146
|
+
const items = getElementDataItems(element, graphManager);
|
|
147
|
+
|
|
148
|
+
if (items.length === 0) {
|
|
149
|
+
dataState.setAccessorOptions(undefined, undefined);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const options = await Promise.all(
|
|
154
|
+
items.map(async (item) => {
|
|
155
|
+
let columns: string[] = [];
|
|
156
|
+
try {
|
|
157
|
+
if (element instanceof IngestDefinition) {
|
|
158
|
+
const accessor =
|
|
159
|
+
await graphManager.createAccessorFromPackageableElement(
|
|
160
|
+
element,
|
|
161
|
+
graph,
|
|
162
|
+
{ schemaName: undefined, tableName: item.id },
|
|
163
|
+
);
|
|
164
|
+
if (accessor) {
|
|
165
|
+
columns = accessor.relationType.columns.map((c) => c.name);
|
|
166
|
+
}
|
|
167
|
+
} else if (element instanceof DataProduct) {
|
|
168
|
+
const accessor = await graphManager.buildDataProductAccessor(
|
|
169
|
+
element,
|
|
170
|
+
graph,
|
|
171
|
+
{ tableName: item.id },
|
|
172
|
+
);
|
|
173
|
+
if (accessor) {
|
|
174
|
+
columns = accessor.relationType.columns.map((c) => c.name);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
// best-effort column resolution
|
|
179
|
+
}
|
|
180
|
+
return { label: item.label, value: item.id, columns };
|
|
181
|
+
}),
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
runInAction(() => {
|
|
185
|
+
dataState.setAccessorOptions(options, this.itemLabel);
|
|
186
|
+
const columnsByItem = new Map(
|
|
187
|
+
options
|
|
188
|
+
.filter((o) => o.columns.length > 0)
|
|
189
|
+
.map((o) => [o.value, o.columns]),
|
|
190
|
+
);
|
|
191
|
+
for (const relState of dataState.relationElementStates) {
|
|
192
|
+
const rel = relState.relationElement;
|
|
193
|
+
if (rel.columns.length === 0) {
|
|
194
|
+
const key = rel.paths[rel.paths.length - 1];
|
|
195
|
+
const cols = key ? columnsByItem.get(key) : undefined;
|
|
196
|
+
if (cols) {
|
|
197
|
+
rel.columns = cols;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ─── Shared interface for TestDataState ───────────────────────────────────────
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Structural interface satisfied by both DataProductTestDataState and
|
|
209
|
+
* IngestTestDataState. Used to type the shared LakehouseTestDataEditor
|
|
210
|
+
* component without importing the concrete state classes.
|
|
211
|
+
*/
|
|
212
|
+
export interface LakehouseTestDataStateBase {
|
|
213
|
+
elementTestDataStates: LakehouseElementTestDataState[];
|
|
214
|
+
selectedElementTestDataState: LakehouseElementTestDataState | undefined;
|
|
215
|
+
setSelectedElementTestDataState(
|
|
216
|
+
val: LakehouseElementTestDataState | undefined,
|
|
217
|
+
): void;
|
|
218
|
+
availableElementsToAdd: PackageableElement[];
|
|
219
|
+
showAddElementModal: boolean;
|
|
220
|
+
setShowAddElementModal(val: boolean): void;
|
|
221
|
+
addElement(path: string): void;
|
|
222
|
+
deleteElement(state: LakehouseElementTestDataState): void;
|
|
223
|
+
editorStore: EditorStore;
|
|
224
|
+
}
|
|
@@ -27,7 +27,9 @@ import {
|
|
|
27
27
|
guaranteeNonNullable,
|
|
28
28
|
guaranteeType,
|
|
29
29
|
exactSearch,
|
|
30
|
+
returnUndefOnError,
|
|
30
31
|
} from '@finos/legend-shared';
|
|
32
|
+
import { parseProjectIdentifier } from '@finos/legend-storage';
|
|
31
33
|
import { generateSetupRoute } from '../../__lib__/LegendStudioNavigation.js';
|
|
32
34
|
import {
|
|
33
35
|
type SDLCServerClient,
|
|
@@ -43,7 +45,6 @@ import {
|
|
|
43
45
|
import type { LegendStudioApplicationStore } from '../LegendStudioBaseStore.js';
|
|
44
46
|
import {
|
|
45
47
|
DEFAULT_TAB_SIZE,
|
|
46
|
-
DEFAULT_TYPEAHEAD_SEARCH_LIMIT,
|
|
47
48
|
DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH,
|
|
48
49
|
} from '@finos/legend-application';
|
|
49
50
|
import {
|
|
@@ -63,13 +64,33 @@ interface ImportProjectSuccessReport {
|
|
|
63
64
|
reviewUrl: string;
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
export interface ProjectSearchResult {
|
|
68
|
+
projects: Project[];
|
|
69
|
+
projectMatchedById?: Project | undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const PROD_PROJECT_ID_PREFIX = 'PROD';
|
|
73
|
+
const cleanProjectIdInput = (searchText: string): string | undefined => {
|
|
74
|
+
const parsed = returnUndefOnError(() =>
|
|
75
|
+
parseProjectIdentifier(searchText.trim()),
|
|
76
|
+
);
|
|
77
|
+
if (parsed === undefined) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return `${parsed.prefix ?? PROD_PROJECT_ID_PREFIX}-${parsed.id}`;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const PROJECT_SEARCH_FETCH_LIMIT = 30;
|
|
84
|
+
|
|
66
85
|
export class WorkspaceSetupStore {
|
|
67
86
|
readonly applicationStore: LegendStudioApplicationStore;
|
|
68
87
|
|
|
69
88
|
readonly sdlcServerClient: SDLCServerClient;
|
|
70
89
|
readonly initState = ActionState.create();
|
|
71
90
|
|
|
72
|
-
|
|
91
|
+
projectSearchResult: ProjectSearchResult = { projects: [] };
|
|
92
|
+
private projectSearchSyncCounter = 0;
|
|
93
|
+
private searchCache = new Map<string, ProjectSearchResult>();
|
|
73
94
|
currentProject?: Project | undefined;
|
|
74
95
|
currentProjectConfigurationStatus?: ProjectConfigurationStatus | undefined;
|
|
75
96
|
loadProjectsState = ActionState.create();
|
|
@@ -107,7 +128,7 @@ export class WorkspaceSetupStore {
|
|
|
107
128
|
sdlcServerClient: SDLCServerClient,
|
|
108
129
|
) {
|
|
109
130
|
makeObservable(this, {
|
|
110
|
-
|
|
131
|
+
projectSearchResult: observable,
|
|
111
132
|
currentProject: observable,
|
|
112
133
|
currentProjectConfigurationStatus: observable,
|
|
113
134
|
importProjectSuccessReport: observable,
|
|
@@ -134,6 +155,7 @@ export class WorkspaceSetupStore {
|
|
|
134
155
|
removeRecentProject: action,
|
|
135
156
|
removeRecentWorkspace: action,
|
|
136
157
|
clearRecents: action,
|
|
158
|
+
filterListOnInput: action,
|
|
137
159
|
initialize: flow,
|
|
138
160
|
loadProjects: flow,
|
|
139
161
|
loadSandboxProject: flow,
|
|
@@ -432,13 +454,82 @@ export class WorkspaceSetupStore {
|
|
|
432
454
|
}
|
|
433
455
|
}
|
|
434
456
|
|
|
457
|
+
private findPrefixCache(searchText: string): ProjectSearchResult | undefined {
|
|
458
|
+
let bestKey: string | undefined;
|
|
459
|
+
let bestEntry: ProjectSearchResult | undefined;
|
|
460
|
+
for (const [key, entry] of this.searchCache) {
|
|
461
|
+
const isStrictPrefix =
|
|
462
|
+
key.length < searchText.length && searchText.startsWith(key);
|
|
463
|
+
if (!isStrictPrefix) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (bestKey === undefined || key.length > bestKey.length) {
|
|
467
|
+
bestKey = key;
|
|
468
|
+
bestEntry = entry;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (!bestEntry) {
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const normalizedSearch = searchText.toLowerCase();
|
|
476
|
+
const projectMatchesSearch = (project: Project): boolean =>
|
|
477
|
+
project.name.toLowerCase().includes(normalizedSearch);
|
|
478
|
+
return {
|
|
479
|
+
projects: bestEntry.projects.filter(projectMatchesSearch),
|
|
480
|
+
projectMatchedById:
|
|
481
|
+
bestEntry.projectMatchedById &&
|
|
482
|
+
projectMatchesSearch(bestEntry.projectMatchedById)
|
|
483
|
+
? bestEntry.projectMatchedById
|
|
484
|
+
: undefined,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
filterListOnInput(searchText: string): void {
|
|
489
|
+
if (searchText.length === 0) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const exact = this.searchCache.get(searchText);
|
|
493
|
+
if (exact) {
|
|
494
|
+
this.projectSearchResult = exact;
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
const narrowed = this.findPrefixCache(searchText);
|
|
498
|
+
if (narrowed) {
|
|
499
|
+
this.projectSearchResult = narrowed;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
435
503
|
*loadProjects(searchText: string): GeneratorFn<void> {
|
|
436
504
|
const isValidSearchString =
|
|
437
505
|
searchText.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH;
|
|
506
|
+
const searchSyncCounter = ++this.projectSearchSyncCounter;
|
|
507
|
+
|
|
508
|
+
const cached = this.searchCache.get(searchText);
|
|
509
|
+
if (cached) {
|
|
510
|
+
this.projectSearchResult = cached;
|
|
511
|
+
this.loadProjectsState.pass();
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
this.projectSearchResult = { projects: this.projectSearchResult.projects };
|
|
438
516
|
this.loadProjectsState.inProgress();
|
|
517
|
+
|
|
518
|
+
if (searchText.length > 0) {
|
|
519
|
+
const narrowed = this.findPrefixCache(searchText);
|
|
520
|
+
if (narrowed) {
|
|
521
|
+
this.projectSearchResult = narrowed;
|
|
522
|
+
}
|
|
523
|
+
if (searchText.length <= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH) {
|
|
524
|
+
this.loadProjectsState.pass();
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
439
529
|
try {
|
|
440
|
-
|
|
441
|
-
|
|
530
|
+
const cleanedProjectId = cleanProjectIdInput(searchText);
|
|
531
|
+
const [searchResults, projectByIdResult] = (yield Promise.all([
|
|
532
|
+
this.sdlcServerClient.getProjects(
|
|
442
533
|
undefined,
|
|
443
534
|
// We apply an exact search on the input text because we show exact searches with
|
|
444
535
|
// custom selector. This avoids losing some results with the additional filtering.
|
|
@@ -448,11 +539,33 @@ export class WorkspaceSetupStore {
|
|
|
448
539
|
// `loadSandboxProject`); exclude them here so they do not appear
|
|
449
540
|
// in the main workspace setup project picker.
|
|
450
541
|
[SANDBOX_SDLC_TAG],
|
|
451
|
-
|
|
452
|
-
)
|
|
453
|
-
|
|
542
|
+
PROJECT_SEARCH_FETCH_LIMIT,
|
|
543
|
+
),
|
|
544
|
+
cleanedProjectId
|
|
545
|
+
? this.sdlcServerClient
|
|
546
|
+
.getProject(cleanedProjectId)
|
|
547
|
+
.catch(() => undefined)
|
|
548
|
+
: Promise.resolve(undefined),
|
|
549
|
+
])) as [PlainObject<Project>[], PlainObject<Project> | undefined];
|
|
550
|
+
|
|
551
|
+
if (searchSyncCounter !== this.projectSearchSyncCounter) {
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const projects = searchResults.map((v) =>
|
|
556
|
+
Project.serialization.fromJson(v),
|
|
557
|
+
);
|
|
558
|
+
const projectMatchedById = projectByIdResult
|
|
559
|
+
? Project.serialization.fromJson(projectByIdResult)
|
|
560
|
+
: undefined;
|
|
561
|
+
|
|
562
|
+
this.projectSearchResult = { projects, projectMatchedById };
|
|
563
|
+
this.searchCache.set(searchText, this.projectSearchResult);
|
|
454
564
|
this.loadProjectsState.pass();
|
|
455
565
|
} catch (error) {
|
|
566
|
+
if (searchSyncCounter !== this.projectSearchSyncCounter) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
456
569
|
assertErrorThrown(error);
|
|
457
570
|
this.applicationStore.notificationService.notifyError(error);
|
|
458
571
|
this.loadProjectsState.fail();
|
|
@@ -742,6 +855,8 @@ export class WorkspaceSetupStore {
|
|
|
742
855
|
`Project '${name}' is succesfully created`,
|
|
743
856
|
);
|
|
744
857
|
|
|
858
|
+
this.searchCache.clear();
|
|
859
|
+
|
|
745
860
|
yield flowResult(this.changeProject(createdProject));
|
|
746
861
|
|
|
747
862
|
this.setShowCreateProjectModal(false);
|
|
@@ -780,6 +895,8 @@ export class WorkspaceSetupStore {
|
|
|
780
895
|
reviewUrl: importReview.webURL,
|
|
781
896
|
});
|
|
782
897
|
|
|
898
|
+
this.searchCache.clear();
|
|
899
|
+
|
|
783
900
|
yield flowResult(this.changeProject(report.project));
|
|
784
901
|
} catch (error) {
|
|
785
902
|
assertErrorThrown(error);
|
package/tsconfig.json
CHANGED
|
@@ -144,6 +144,7 @@
|
|
|
144
144
|
"./src/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeM2MUdfFunctionActivatorEditorState.ts",
|
|
145
145
|
"./src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts",
|
|
146
146
|
"./src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts",
|
|
147
|
+
"./src/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.ts",
|
|
147
148
|
"./src/stores/editor/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts",
|
|
148
149
|
"./src/stores/editor/editor-state/element-editor-state/mapping/MappingDiagramGenerator.ts",
|
|
149
150
|
"./src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts",
|
|
@@ -168,6 +169,7 @@
|
|
|
168
169
|
"./src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts",
|
|
169
170
|
"./src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.ts",
|
|
170
171
|
"./src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestableState.ts",
|
|
172
|
+
"./src/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.ts",
|
|
171
173
|
"./src/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.ts",
|
|
172
174
|
"./src/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.ts",
|
|
173
175
|
"./src/stores/editor/editor-state/end-to-end-workflow-state/EndToEndWorkflowEditorState.ts",
|
|
@@ -296,6 +298,7 @@
|
|
|
296
298
|
"./src/components/editor/editor-group/function-activator/SnowflakeM2MUdfFunctionActivatorEditor.tsx",
|
|
297
299
|
"./src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx",
|
|
298
300
|
"./src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx",
|
|
301
|
+
"./src/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.tsx",
|
|
299
302
|
"./src/components/editor/editor-group/mapping-editor/ClassMappingEditor.tsx",
|
|
300
303
|
"./src/components/editor/editor-group/mapping-editor/EnumerationMappingEditor.tsx",
|
|
301
304
|
"./src/components/editor/editor-group/mapping-editor/FlatDataPropertyMappingEditor.tsx",
|
|
@@ -331,6 +334,7 @@
|
|
|
331
334
|
"./src/components/editor/editor-group/service-editor/testable/ServiceTestDataEditor.tsx",
|
|
332
335
|
"./src/components/editor/editor-group/service-editor/testable/ServiceTestableEditor.tsx",
|
|
333
336
|
"./src/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.tsx",
|
|
337
|
+
"./src/components/editor/editor-group/testable/LakehouseTestableEditor.tsx",
|
|
334
338
|
"./src/components/editor/editor-group/testable/TestableSharedComponents.tsx",
|
|
335
339
|
"./src/components/editor/editor-group/uml-editor/AssociationEditor.tsx",
|
|
336
340
|
"./src/components/editor/editor-group/uml-editor/ClassEditor.tsx",
|