@finos/legend-application-studio 28.21.3 → 28.21.5
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/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js +3 -3
- package/lib/components/editor/editor-group/data-editor/EmbeddedDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts +3 -0
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +72 -52
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js +22 -1
- package/lib/components/editor/editor-group/dataProduct/DataProductEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts +23 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js +267 -0
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +113 -75
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.d.ts.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js +39 -5
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js.map +1 -1
- package/lib/components/editor/side-bar/DevMetadataPanel.d.ts.map +1 -1
- package/lib/components/editor/side-bar/DevMetadataPanel.js +37 -6
- package/lib/components/editor/side-bar/DevMetadataPanel.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 +17 -2
- 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 +56 -49
- 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 +4 -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 +4 -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 +113 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js +647 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +18 -4
- 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 +214 -53
- 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/testable/TestAssertionState.d.ts +17 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.js +46 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.js.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts +9 -0
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.d.ts.map +1 -1
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js +55 -0
- package/lib/stores/editor/sidebar-state/dev-metadata/DevMetadataState.js.map +1 -1
- package/package.json +16 -16
- package/src/components/editor/editor-group/data-editor/EmbeddedDataEditor.tsx +3 -0
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +331 -231
- package/src/components/editor/editor-group/dataProduct/DataProductEditor.tsx +32 -0
- package/src/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.tsx +935 -0
- package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +425 -308
- package/src/components/editor/editor-group/testable/TestableSharedComponents.tsx +160 -15
- package/src/components/editor/side-bar/DevMetadataPanel.tsx +194 -10
- package/src/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.ts +82 -51
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +4 -0
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.ts +927 -0
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +303 -72
- package/src/stores/editor/editor-state/element-editor-state/testable/TestAssertionState.ts +66 -0
- package/src/stores/editor/sidebar-state/dev-metadata/DevMetadataState.ts +76 -0
- package/tsconfig.json +2 -0
|
@@ -32,6 +32,10 @@ import {
|
|
|
32
32
|
} from '@finos/legend-graph';
|
|
33
33
|
import {
|
|
34
34
|
ContentType,
|
|
35
|
+
csvDecodeValue,
|
|
36
|
+
csvEncodeValue,
|
|
37
|
+
csvStringify,
|
|
38
|
+
parseCSVContent,
|
|
35
39
|
guaranteeNonEmptyString,
|
|
36
40
|
tryToFormatLosslessJSONString,
|
|
37
41
|
UnsupportedOperationError,
|
|
@@ -211,8 +215,12 @@ export class ModelStoreDataState extends EmbeddedDataState {
|
|
|
211
215
|
|
|
212
216
|
export class RelationElementState {
|
|
213
217
|
relationElement: RelationElement;
|
|
218
|
+
supportsColumnEditing: boolean;
|
|
214
219
|
|
|
215
|
-
constructor(
|
|
220
|
+
constructor(
|
|
221
|
+
relationElement: RelationElement,
|
|
222
|
+
options?: { supportsColumnEditing?: boolean },
|
|
223
|
+
) {
|
|
216
224
|
makeObservable(this, {
|
|
217
225
|
relationElement: observable,
|
|
218
226
|
addColumn: action,
|
|
@@ -224,6 +232,7 @@ export class RelationElementState {
|
|
|
224
232
|
clearAllData: action,
|
|
225
233
|
importCSV: action,
|
|
226
234
|
});
|
|
235
|
+
this.supportsColumnEditing = options?.supportsColumnEditing ?? true;
|
|
227
236
|
this.relationElement = relationElement;
|
|
228
237
|
this.relationElement = observe_RelationElement(relationElement);
|
|
229
238
|
}
|
|
@@ -268,10 +277,16 @@ export class RelationElementState {
|
|
|
268
277
|
|
|
269
278
|
updateRow(rowIndex: number, columnIndex: number, value: string): void {
|
|
270
279
|
if (this.relationElement.rows[rowIndex]) {
|
|
271
|
-
this.relationElement.rows[rowIndex].values[columnIndex] =
|
|
280
|
+
this.relationElement.rows[rowIndex].values[columnIndex] =
|
|
281
|
+
csvEncodeValue(value);
|
|
272
282
|
}
|
|
273
283
|
}
|
|
274
284
|
|
|
285
|
+
getDisplayValue(rowIndex: number, columnIndex: number): string {
|
|
286
|
+
const value = this.relationElement.rows[rowIndex]?.values[columnIndex];
|
|
287
|
+
return value !== undefined ? csvDecodeValue(value) : '';
|
|
288
|
+
}
|
|
289
|
+
|
|
275
290
|
clearAllData(): void {
|
|
276
291
|
this.relationElement.rows.splice(0);
|
|
277
292
|
}
|
|
@@ -280,7 +295,9 @@ export class RelationElementState {
|
|
|
280
295
|
return JSON.stringify(
|
|
281
296
|
{
|
|
282
297
|
columns: this.relationElement.columns,
|
|
283
|
-
data: this.relationElement.rows
|
|
298
|
+
data: this.relationElement.rows.map((row) => ({
|
|
299
|
+
values: row.values.map((v) => csvDecodeValue(v)),
|
|
300
|
+
})),
|
|
284
301
|
},
|
|
285
302
|
null,
|
|
286
303
|
2,
|
|
@@ -305,7 +322,7 @@ export class RelationElementState {
|
|
|
305
322
|
const insertStatements = this.relationElement.rows.map((row) => {
|
|
306
323
|
const values = this.relationElement.columns
|
|
307
324
|
.map((col, colIndex) => {
|
|
308
|
-
const value = row.values[colIndex] ?? '';
|
|
325
|
+
const value = csvDecodeValue(row.values[colIndex] ?? '');
|
|
309
326
|
if (value !== '') {
|
|
310
327
|
return `'${value.replace(/'/g, "''")}'`;
|
|
311
328
|
}
|
|
@@ -319,75 +336,50 @@ export class RelationElementState {
|
|
|
319
336
|
}
|
|
320
337
|
|
|
321
338
|
exportCSV(): string {
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const value = row.values[headerIndex] ?? '';
|
|
328
|
-
if (value.includes(',') || value.includes('"')) {
|
|
329
|
-
return `"${value.replace(/"/g, '""')}"`;
|
|
330
|
-
}
|
|
331
|
-
return value;
|
|
332
|
-
});
|
|
333
|
-
csvLines.push(values.join(','));
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
return csvLines.join('\n');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
private parseCSVLine(line: string): string[] {
|
|
340
|
-
const result: string[] = [];
|
|
341
|
-
let current = '';
|
|
342
|
-
let inQuotes = false;
|
|
343
|
-
|
|
344
|
-
for (let i = 0; i < line.length; i++) {
|
|
345
|
-
const char = line[i];
|
|
346
|
-
if (char === '"') {
|
|
347
|
-
inQuotes = !inQuotes;
|
|
348
|
-
} else if (char === ',' && !inQuotes) {
|
|
349
|
-
result.push(current.trim());
|
|
350
|
-
current = '';
|
|
351
|
-
} else {
|
|
352
|
-
current += char;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
result.push(current.trim());
|
|
356
|
-
return result;
|
|
339
|
+
// decode so that csvStringify does not double encode
|
|
340
|
+
const data = this.relationElement.rows.map((row) =>
|
|
341
|
+
row.values.map((v) => csvDecodeValue(v)),
|
|
342
|
+
);
|
|
343
|
+
return csvStringify([this.relationElement.columns, ...data]);
|
|
357
344
|
}
|
|
358
345
|
|
|
359
346
|
importCSV(csvContent: string): void {
|
|
360
|
-
const
|
|
361
|
-
if (
|
|
347
|
+
const parsed = parseCSVContent(csvContent);
|
|
348
|
+
if (parsed.length === 0) {
|
|
362
349
|
return;
|
|
363
350
|
}
|
|
364
351
|
|
|
365
|
-
const
|
|
366
|
-
if (!
|
|
352
|
+
const headers = parsed[0];
|
|
353
|
+
if (!headers) {
|
|
367
354
|
return;
|
|
368
355
|
}
|
|
369
356
|
|
|
370
|
-
const headers = this.parseCSVLine(firstLine);
|
|
371
357
|
this.relationElement.columns = headers;
|
|
372
|
-
|
|
373
|
-
this.relationElement.rows = lines.slice(1).map((line) => {
|
|
374
|
-
const values = this.parseCSVLine(line);
|
|
358
|
+
this.relationElement.rows = parsed.slice(1).map((values) => {
|
|
375
359
|
const row = new RelationRowTestData();
|
|
376
|
-
row.values =
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
});
|
|
360
|
+
row.values = headers.map((_, index) =>
|
|
361
|
+
csvEncodeValue(values[index] ?? ''),
|
|
362
|
+
);
|
|
380
363
|
return observe_RelationRowTestData(row);
|
|
381
364
|
});
|
|
382
365
|
}
|
|
383
366
|
}
|
|
384
367
|
|
|
368
|
+
export interface RelationElementAccessorOption {
|
|
369
|
+
label: string;
|
|
370
|
+
value: string;
|
|
371
|
+
columns: string[];
|
|
372
|
+
}
|
|
373
|
+
|
|
385
374
|
export class RelationElementsDataState extends EmbeddedDataState {
|
|
386
375
|
override embeddedData: RelationElementsData;
|
|
387
376
|
showImportCSVModal = false;
|
|
388
377
|
showNewRelationElementModal = false;
|
|
389
378
|
activeRelationElement: RelationElementState | undefined;
|
|
390
379
|
relationElementStates: RelationElementState[];
|
|
380
|
+
accessorOptions: RelationElementAccessorOption[] | undefined;
|
|
381
|
+
accessorTypeLabel: string | undefined;
|
|
382
|
+
refreshAccessorOptions: (() => Promise<void>) | undefined;
|
|
391
383
|
|
|
392
384
|
constructor(editorStore: EditorStore, embeddedData: RelationElementsData) {
|
|
393
385
|
super(editorStore, embeddedData);
|
|
@@ -396,10 +388,15 @@ export class RelationElementsDataState extends EmbeddedDataState {
|
|
|
396
388
|
showImportCSVModal: observable,
|
|
397
389
|
showNewRelationElementModal: observable,
|
|
398
390
|
activeRelationElement: observable,
|
|
391
|
+
relationElementStates: observable,
|
|
392
|
+
accessorOptions: observable,
|
|
393
|
+
accessorTypeLabel: observable,
|
|
399
394
|
setActiveRelationElement: action,
|
|
400
395
|
setShowImportCSVModal: action,
|
|
401
396
|
setShowNewRelationElementModal: action,
|
|
402
397
|
addRelationElement: action,
|
|
398
|
+
deleteRelationElement: action,
|
|
399
|
+
setAccessorOptions: action,
|
|
403
400
|
});
|
|
404
401
|
this.embeddedData = embeddedData;
|
|
405
402
|
this.relationElementStates = embeddedData.relationElements.map(
|
|
@@ -423,6 +420,18 @@ export class RelationElementsDataState extends EmbeddedDataState {
|
|
|
423
420
|
this.setActiveRelationElement(newElementState);
|
|
424
421
|
}
|
|
425
422
|
|
|
423
|
+
deleteRelationElement(relationElementState: RelationElementState): void {
|
|
424
|
+
const idx = this.relationElementStates.indexOf(relationElementState);
|
|
425
|
+
if (idx === -1) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
this.relationElementStates.splice(idx, 1);
|
|
429
|
+
this.embeddedData.relationElements.splice(idx, 1);
|
|
430
|
+
if (this.activeRelationElement === relationElementState) {
|
|
431
|
+
this.setActiveRelationElement(this.relationElementStates[0]);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
426
435
|
setShowImportCSVModal(show: boolean): void {
|
|
427
436
|
this.showImportCSVModal = show;
|
|
428
437
|
}
|
|
@@ -430,6 +439,28 @@ export class RelationElementsDataState extends EmbeddedDataState {
|
|
|
430
439
|
setShowNewRelationElementModal(show: boolean): void {
|
|
431
440
|
this.showNewRelationElementModal = show;
|
|
432
441
|
}
|
|
442
|
+
|
|
443
|
+
setAccessorOptions(
|
|
444
|
+
options: RelationElementAccessorOption[] | undefined,
|
|
445
|
+
typeLabel: string | undefined,
|
|
446
|
+
): void {
|
|
447
|
+
this.accessorOptions = options;
|
|
448
|
+
this.accessorTypeLabel = typeLabel;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
setRefreshAccessorOptions(fn: (() => Promise<void>) | undefined): void {
|
|
452
|
+
this.refreshAccessorOptions = fn;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
get availableAccessorOptions(): RelationElementAccessorOption[] {
|
|
456
|
+
if (!this.accessorOptions) {
|
|
457
|
+
return [];
|
|
458
|
+
}
|
|
459
|
+
const existingPaths = new Set(
|
|
460
|
+
this.relationElementStates.map((s) => s.relationElement.paths.join('.')),
|
|
461
|
+
);
|
|
462
|
+
return this.accessorOptions.filter((opt) => !existingPaths.has(opt.value));
|
|
463
|
+
}
|
|
433
464
|
}
|
|
434
465
|
|
|
435
466
|
export class RelationalCSVDataTableState {
|
package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts
CHANGED
|
@@ -109,6 +109,7 @@ import {
|
|
|
109
109
|
modelAccessPointGroup_setMapping,
|
|
110
110
|
dataProduct_setSupportInfoIfAbsent,
|
|
111
111
|
} from '../../../../graph-modifier/DSL_DataProduct_GraphModifierHelper.js';
|
|
112
|
+
import { DataProductTestableState } from './testable/DataProductTestableState.js';
|
|
112
113
|
import { LambdaEditorState, LineageState } from '@finos/legend-query-builder';
|
|
113
114
|
import {
|
|
114
115
|
DataProductElementEditorInitialConfiguration,
|
|
@@ -129,6 +130,7 @@ export enum DATA_PRODUCT_TAB {
|
|
|
129
130
|
SUPPORT = 'Support',
|
|
130
131
|
APG = 'APG',
|
|
131
132
|
OPERATIONAL = 'Operational',
|
|
133
|
+
TESTING = 'Testing',
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
export enum DATA_PRODUCT_TYPE {
|
|
@@ -966,6 +968,7 @@ export class DataProductEditorState extends ElementEditorState {
|
|
|
966
968
|
selectedGroupState: AccessPointGroupState | undefined;
|
|
967
969
|
selectedTab: DATA_PRODUCT_TAB;
|
|
968
970
|
modelledDataProduct = false;
|
|
971
|
+
testableState: DataProductTestableState;
|
|
969
972
|
|
|
970
973
|
constructor(
|
|
971
974
|
editorStore: EditorStore,
|
|
@@ -1015,6 +1018,7 @@ export class DataProductEditorState extends ElementEditorState {
|
|
|
1015
1018
|
this.deployOnOpen = elementConfig.deployOnOpen ?? false;
|
|
1016
1019
|
}
|
|
1017
1020
|
this.selectedTab = DATA_PRODUCT_TAB.HOME;
|
|
1021
|
+
this.testableState = new DataProductTestableState(this);
|
|
1018
1022
|
}
|
|
1019
1023
|
|
|
1020
1024
|
setDeployOnOpen(value: boolean): void {
|