@finos/legend-query-builder 2.1.5 → 2.1.7
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/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/QueryBuilderResultPanel.js +12 -12
- package/lib/components/QueryBuilderResultPanel.js.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts +12 -2
- package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.d.ts.map +1 -1
- package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js +145 -20
- package/lib/components/fetch-structure/QueryBuilderGraphFetchTreePanel.js.map +1 -1
- package/lib/index.css +1 -17
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +3 -0
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +19 -1
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeValueSpecificationBuilder.js +11 -11
- package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeValueSpecificationBuilder.js.map +1 -1
- package/package.json +4 -4
- package/src/components/QueryBuilderResultPanel.tsx +17 -14
- package/src/components/fetch-structure/QueryBuilderGraphFetchTreePanel.tsx +384 -63
- package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +34 -0
- package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeValueSpecificationBuilder.ts +11 -11
@@ -41,9 +41,21 @@ import {
|
|
41
41
|
ModalFooterButton,
|
42
42
|
ModalFooter,
|
43
43
|
SerializeIcon,
|
44
|
+
ResizablePanel,
|
45
|
+
ResizablePanelSplitter,
|
46
|
+
ResizablePanelGroup,
|
47
|
+
BufferIcon,
|
48
|
+
CustomSelectorInput,
|
49
|
+
FolderIcon,
|
44
50
|
} from '@finos/legend-art';
|
45
51
|
import { QUERY_BUILDER_TEST_ID } from '../../application/QueryBuilderTesting.js';
|
46
|
-
import {
|
52
|
+
import {
|
53
|
+
deepClone,
|
54
|
+
filterByType,
|
55
|
+
guaranteeNonNullable,
|
56
|
+
isNonNullable,
|
57
|
+
prettyCONSTName,
|
58
|
+
} from '@finos/legend-shared';
|
47
59
|
import {
|
48
60
|
type QueryBuilderGraphFetchTreeData,
|
49
61
|
type QueryBuilderGraphFetchTreeNodeData,
|
@@ -55,12 +67,51 @@ import {
|
|
55
67
|
QUERY_BUILDER_EXPLORER_TREE_DND_TYPE,
|
56
68
|
} from '../../stores/explorer/QueryBuilderExplorerState.js';
|
57
69
|
import {
|
70
|
+
type GraphFetchSerializationState,
|
71
|
+
GraphFetchExternalFormatSerializationState,
|
58
72
|
GraphFetchPureSerializationState,
|
59
73
|
PureSerializationConfig,
|
74
|
+
SERIALIZATION_TYPE,
|
60
75
|
type QueryBuilderGraphFetchTreeState,
|
61
76
|
} from '../../stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js';
|
62
77
|
import { getClassPropertyIcon } from '../shared/ElementIconUtils.js';
|
63
78
|
import { QueryBuilderTextEditorMode } from '../../stores/QueryBuilderTextEditorState.js';
|
79
|
+
import {
|
80
|
+
type PackageableElement,
|
81
|
+
Binding,
|
82
|
+
Package,
|
83
|
+
getDescendantsOfPackage,
|
84
|
+
} from '@finos/legend-graph';
|
85
|
+
import {
|
86
|
+
ActionAlertActionType,
|
87
|
+
ActionAlertType,
|
88
|
+
buildElementOption,
|
89
|
+
type PackageableElementOption,
|
90
|
+
} from '@finos/legend-application';
|
91
|
+
|
92
|
+
const getBindingFormatter = (props: {
|
93
|
+
darkMode?: boolean;
|
94
|
+
}): ((
|
95
|
+
option: PackageableElementOption<PackageableElement>,
|
96
|
+
) => React.ReactNode) =>
|
97
|
+
function BindingLabel(
|
98
|
+
option: PackageableElementOption<PackageableElement>,
|
99
|
+
): React.ReactNode {
|
100
|
+
const className = props.darkMode
|
101
|
+
? 'packageable-element-option-label--dark'
|
102
|
+
: 'packageable-element-option-label';
|
103
|
+
return (
|
104
|
+
<div className={className}>
|
105
|
+
<div className={`${className}__name`}>{option.label}</div>
|
106
|
+
{option.value.package && (
|
107
|
+
<div className={`${className}__tag`}>{option.value.path}</div>
|
108
|
+
)}
|
109
|
+
<div className={`${className}__tag`}>
|
110
|
+
{(option.value as Binding).contentType}
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
);
|
114
|
+
};
|
64
115
|
|
65
116
|
const QueryBuilderGraphFetchTreeNodeContainer: React.FC<
|
66
117
|
TreeNodeContainerProps<
|
@@ -287,22 +338,131 @@ const PureSerializationConfigModal = observer(
|
|
287
338
|
},
|
288
339
|
);
|
289
340
|
|
341
|
+
export const QueryBuilderGraphFetchExternalConfig = observer(
|
342
|
+
(props: {
|
343
|
+
graphFetchState: QueryBuilderGraphFetchTreeState;
|
344
|
+
serializationState: GraphFetchExternalFormatSerializationState;
|
345
|
+
serializationTreeData: QueryBuilderGraphFetchTreeData;
|
346
|
+
bindings: Binding[];
|
347
|
+
isReadOnly: boolean;
|
348
|
+
}) => {
|
349
|
+
const {
|
350
|
+
graphFetchState,
|
351
|
+
serializationState,
|
352
|
+
serializationTreeData,
|
353
|
+
bindings,
|
354
|
+
isReadOnly,
|
355
|
+
} = props;
|
356
|
+
const bindingOptions = bindings.map((result) => buildElementOption(result));
|
357
|
+
const selectedBinding = {
|
358
|
+
value: serializationState.targetBinding,
|
359
|
+
label: serializationState.targetBinding.name,
|
360
|
+
};
|
361
|
+
const onBindingChange = (
|
362
|
+
val: PackageableElementOption<Binding> | null,
|
363
|
+
): void => {
|
364
|
+
if (val !== null) {
|
365
|
+
serializationState.setBinding(val.value);
|
366
|
+
serializationState.setGraphFetchTree(serializationTreeData);
|
367
|
+
}
|
368
|
+
};
|
369
|
+
const onNodeSelect = (node: QueryBuilderGraphFetchTreeNodeData): void => {
|
370
|
+
if (node.childrenIds.length) {
|
371
|
+
node.isOpen = !node.isOpen;
|
372
|
+
}
|
373
|
+
};
|
374
|
+
const getChildNodes = (
|
375
|
+
node: QueryBuilderGraphFetchTreeNodeData,
|
376
|
+
): QueryBuilderGraphFetchTreeNodeData[] =>
|
377
|
+
node.childrenIds
|
378
|
+
.map((id) => serializationTreeData.nodes.get(id))
|
379
|
+
.filter(isNonNullable);
|
380
|
+
const removeNode = (node: QueryBuilderGraphFetchTreeNodeData): void => {
|
381
|
+
if (serializationTreeData.nodes.size === 1) {
|
382
|
+
graphFetchState.queryBuilderState.applicationStore.notificationService.notifyWarning(
|
383
|
+
'externalize serialization tree can not be empty',
|
384
|
+
);
|
385
|
+
} else {
|
386
|
+
removeNodeRecursively(serializationTreeData, node);
|
387
|
+
serializationState.setGraphFetchTree({ ...serializationTreeData });
|
388
|
+
}
|
389
|
+
};
|
390
|
+
|
391
|
+
return (
|
392
|
+
<div className="query-builder-graph-fetch-external-format">
|
393
|
+
<div className="service-execution-editor__configuration__items">
|
394
|
+
<div className="service-execution-editor__configuration__item">
|
395
|
+
<div className="btn--sm service-execution-editor__configuration__item__label">
|
396
|
+
<BufferIcon />
|
397
|
+
</div>
|
398
|
+
<CustomSelectorInput
|
399
|
+
className="panel__content__form__section__dropdown service-execution-editor__configuration__item__dropdown"
|
400
|
+
disabled={isReadOnly}
|
401
|
+
options={bindingOptions}
|
402
|
+
onChange={onBindingChange}
|
403
|
+
value={selectedBinding}
|
404
|
+
formatOptionLabel={getBindingFormatter({
|
405
|
+
darkMode: true,
|
406
|
+
})}
|
407
|
+
darkMode={true}
|
408
|
+
/>
|
409
|
+
</div>
|
410
|
+
<div className="service-execution-editor__configuration__item">
|
411
|
+
<div className="btn--sm service-execution-editor__configuration__item__label">
|
412
|
+
<FolderIcon />
|
413
|
+
</div>
|
414
|
+
<TreeView
|
415
|
+
components={{
|
416
|
+
TreeNodeContainer: QueryBuilderGraphFetchTreeNodeContainer,
|
417
|
+
}}
|
418
|
+
className="query-builder-graph-fetch-tree__container__tree"
|
419
|
+
treeData={serializationTreeData}
|
420
|
+
onNodeSelect={onNodeSelect}
|
421
|
+
getChildNodes={getChildNodes}
|
422
|
+
innerProps={{
|
423
|
+
isReadOnly,
|
424
|
+
removeNode,
|
425
|
+
}}
|
426
|
+
/>
|
427
|
+
</div>
|
428
|
+
</div>
|
429
|
+
</div>
|
430
|
+
);
|
431
|
+
},
|
432
|
+
);
|
433
|
+
|
290
434
|
export const QueryBuilderGraphFetchTreeExplorer = observer(
|
291
435
|
(props: {
|
292
436
|
graphFetchState: QueryBuilderGraphFetchTreeState;
|
293
|
-
|
437
|
+
serializationState: GraphFetchSerializationState;
|
294
438
|
treeData: QueryBuilderGraphFetchTreeData;
|
295
439
|
updateTreeData: (data: QueryBuilderGraphFetchTreeData) => void;
|
296
440
|
isReadOnly: boolean;
|
297
441
|
}) => {
|
298
442
|
const {
|
299
443
|
graphFetchState,
|
300
|
-
|
444
|
+
serializationState,
|
301
445
|
treeData,
|
302
446
|
updateTreeData,
|
303
447
|
isReadOnly,
|
304
448
|
} = props;
|
305
449
|
|
450
|
+
// Retrieve all bindings whose packageableElementIncludes contain the root class of main graph fetch tree
|
451
|
+
const compatibleBindings =
|
452
|
+
graphFetchState.queryBuilderState.graphManagerState.usableStores
|
453
|
+
.filter(filterByType(Binding))
|
454
|
+
.filter((b) => {
|
455
|
+
const elements = b.modelUnit.packageableElementIncludes.map(
|
456
|
+
(p) => p.value,
|
457
|
+
);
|
458
|
+
return elements
|
459
|
+
.filter(filterByType(Package))
|
460
|
+
.map((p) => Array.from(getDescendantsOfPackage(p)))
|
461
|
+
.flat()
|
462
|
+
.concat(elements.filter((e) => !(e instanceof Package)))
|
463
|
+
.includes(treeData.tree.class.value);
|
464
|
+
});
|
465
|
+
|
306
466
|
const onNodeSelect = (node: QueryBuilderGraphFetchTreeNodeData): void => {
|
307
467
|
if (node.childrenIds.length) {
|
308
468
|
node.isOpen = !node.isOpen;
|
@@ -319,6 +479,24 @@ export const QueryBuilderGraphFetchTreeExplorer = observer(
|
|
319
479
|
|
320
480
|
const removeNode = (node: QueryBuilderGraphFetchTreeNodeData): void => {
|
321
481
|
removeNodeRecursively(treeData, node);
|
482
|
+
if (treeData.nodes.size === 0) {
|
483
|
+
graphFetchState.setSerializationState(
|
484
|
+
new GraphFetchPureSerializationState(graphFetchState),
|
485
|
+
);
|
486
|
+
}
|
487
|
+
// Remove node from external format serialization tree as well
|
488
|
+
if (
|
489
|
+
serializationState instanceof
|
490
|
+
GraphFetchExternalFormatSerializationState &&
|
491
|
+
serializationState.treeData &&
|
492
|
+
serializationState.treeData.nodes.get(node.id)
|
493
|
+
) {
|
494
|
+
removeNodeRecursively(
|
495
|
+
serializationState.treeData,
|
496
|
+
guaranteeNonNullable(serializationState.treeData.nodes.get(node.id)),
|
497
|
+
);
|
498
|
+
updateTreeData({ ...serializationState.treeData });
|
499
|
+
}
|
322
500
|
updateTreeData({ ...treeData });
|
323
501
|
};
|
324
502
|
|
@@ -326,71 +504,202 @@ export const QueryBuilderGraphFetchTreeExplorer = observer(
|
|
326
504
|
graphFetchState.setChecked(!graphFetchState.isChecked);
|
327
505
|
|
328
506
|
const openConfigModal = (): void => {
|
329
|
-
|
507
|
+
if (serializationState instanceof GraphFetchPureSerializationState) {
|
508
|
+
serializationState.setConfigModal(true);
|
509
|
+
}
|
330
510
|
};
|
331
511
|
|
512
|
+
const onChangeSerializationType =
|
513
|
+
(implementationType: SERIALIZATION_TYPE): (() => void) =>
|
514
|
+
(): void => {
|
515
|
+
if (implementationType !== serializationState.getLabel()) {
|
516
|
+
graphFetchState.queryBuilderState.applicationStore.alertService.setActionAlertInfo(
|
517
|
+
{
|
518
|
+
message:
|
519
|
+
'Current graph-fetch will be lost when switching to a different serialization mode. Do you still want to proceed?',
|
520
|
+
type: ActionAlertType.CAUTION,
|
521
|
+
actions: [
|
522
|
+
{
|
523
|
+
label: 'Proceed',
|
524
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
525
|
+
handler:
|
526
|
+
graphFetchState.queryBuilderState.applicationStore.guardUnhandledError(
|
527
|
+
async () => {
|
528
|
+
switch (implementationType) {
|
529
|
+
case SERIALIZATION_TYPE.EXTERNAL_FORMAT:
|
530
|
+
if (
|
531
|
+
compatibleBindings.length > 0 &&
|
532
|
+
compatibleBindings[0]
|
533
|
+
) {
|
534
|
+
const externalizeState =
|
535
|
+
new GraphFetchExternalFormatSerializationState(
|
536
|
+
graphFetchState,
|
537
|
+
compatibleBindings[0],
|
538
|
+
undefined,
|
539
|
+
);
|
540
|
+
graphFetchState.setGraphFetchTree(treeData);
|
541
|
+
externalizeState.setGraphFetchTree(
|
542
|
+
deepClone(treeData),
|
543
|
+
);
|
544
|
+
graphFetchState.setSerializationState(
|
545
|
+
externalizeState,
|
546
|
+
);
|
547
|
+
} else {
|
548
|
+
graphFetchState.queryBuilderState.applicationStore.notificationService.notifyWarning(
|
549
|
+
`Can't switch to external format serialization: No compatible bindings found`,
|
550
|
+
);
|
551
|
+
}
|
552
|
+
break;
|
553
|
+
case SERIALIZATION_TYPE.PURE:
|
554
|
+
default:
|
555
|
+
graphFetchState.setSerializationState(
|
556
|
+
new GraphFetchPureSerializationState(
|
557
|
+
graphFetchState,
|
558
|
+
),
|
559
|
+
);
|
560
|
+
break;
|
561
|
+
}
|
562
|
+
},
|
563
|
+
),
|
564
|
+
},
|
565
|
+
{
|
566
|
+
label: 'Cancel',
|
567
|
+
type: ActionAlertActionType.PROCEED,
|
568
|
+
default: true,
|
569
|
+
},
|
570
|
+
],
|
571
|
+
},
|
572
|
+
);
|
573
|
+
}
|
574
|
+
};
|
575
|
+
|
332
576
|
return (
|
333
577
|
<div className="query-builder-graph-fetch-tree">
|
334
578
|
<div className="query-builder-graph-fetch-tree__toolbar">
|
579
|
+
<div className="query-builder__fetch__structure__modes">
|
580
|
+
{Object.values(SERIALIZATION_TYPE).map((type) => (
|
581
|
+
<button
|
582
|
+
onClick={onChangeSerializationType(type)}
|
583
|
+
className={clsx('query-builder__fetch__structure__mode', {
|
584
|
+
'query-builder__fetch__structure__mode--selected':
|
585
|
+
type === serializationState.getLabel(),
|
586
|
+
})}
|
587
|
+
key={type}
|
588
|
+
>
|
589
|
+
{prettyCONSTName(type)}
|
590
|
+
</button>
|
591
|
+
))}
|
592
|
+
</div>
|
335
593
|
<div className="query-builder-graph-fetch-tree__actions">
|
336
|
-
|
337
|
-
className="query-builder-graph-fetch-tree__actions__action
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
594
|
+
{serializationState instanceof GraphFetchPureSerializationState && (
|
595
|
+
<div className="query-builder-graph-fetch-tree__actions__action">
|
596
|
+
<button
|
597
|
+
className="query-builder-graph-fetch-tree__actions__action-btn__label"
|
598
|
+
onClick={openConfigModal}
|
599
|
+
title={`${
|
600
|
+
serializationState.config
|
601
|
+
? 'Edit pure serialization config'
|
602
|
+
: 'Add pure serialization config'
|
603
|
+
}`}
|
604
|
+
tabIndex={-1}
|
605
|
+
>
|
606
|
+
<SerializeIcon className="query-builder-graph-fetch-tree__actions__action-btn__label__icon" />
|
607
|
+
<div className="query-builder-graph-fetch-tree__actions__action-btn__label__title">
|
608
|
+
{serializationState.config ? 'Edit Config' : 'Add Config'}
|
609
|
+
</div>
|
610
|
+
</button>
|
349
611
|
</div>
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
onClick={toggleChecked}
|
355
|
-
>
|
356
|
-
<button
|
357
|
-
className={clsx('panel__content__form__section__toggler__btn', {
|
358
|
-
'panel__content__form__section__toggler__btn--toggled':
|
359
|
-
graphFetchState.isChecked,
|
360
|
-
})}
|
612
|
+
)}
|
613
|
+
<div
|
614
|
+
className={clsx('panel__content__form__section__toggler')}
|
615
|
+
onClick={toggleChecked}
|
361
616
|
>
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
617
|
+
<button
|
618
|
+
className={clsx('panel__content__form__section__toggler__btn', {
|
619
|
+
'panel__content__form__section__toggler__btn--toggled':
|
620
|
+
graphFetchState.isChecked,
|
621
|
+
})}
|
622
|
+
>
|
623
|
+
{graphFetchState.isChecked ? (
|
624
|
+
<CheckSquareIcon />
|
625
|
+
) : (
|
626
|
+
<SquareIcon />
|
627
|
+
)}
|
628
|
+
</button>
|
629
|
+
<div className="panel__content__form__section__toggler__prompt">
|
630
|
+
Check graph fetch
|
631
|
+
</div>
|
632
|
+
<div className="query-builder-graph-fetch-tree__toolbar__hint-icon">
|
633
|
+
<InfoCircleIcon title="With this enabled, while executing, violations of constraints will reported as part of the result, rather than causing a failure" />
|
634
|
+
</div>
|
369
635
|
</div>
|
370
636
|
</div>
|
371
637
|
</div>
|
372
638
|
<div className="query-builder-graph-fetch-tree__container">
|
373
|
-
{
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
639
|
+
{serializationState instanceof GraphFetchPureSerializationState &&
|
640
|
+
serializationState.configModal && (
|
641
|
+
<PureSerializationConfigModal
|
642
|
+
pureSerializationState={serializationState}
|
643
|
+
graphFetchState={graphFetchState}
|
644
|
+
config={
|
645
|
+
serializationState.config ?? new PureSerializationConfig()
|
646
|
+
}
|
647
|
+
/>
|
648
|
+
)}
|
649
|
+
<ResizablePanelGroup orientation="horizontal">
|
650
|
+
<ResizablePanel>
|
651
|
+
<div className="query-builder-graph-fetch-external-format__config-group">
|
652
|
+
<div className="query-builder-graph-fetch-external-format__config-group__header">
|
653
|
+
<div className="query-builder-graph-fetch-external-format__config-group__header__title">
|
654
|
+
Graph Fetch Tree
|
655
|
+
</div>
|
656
|
+
</div>
|
657
|
+
<div className="query-builder-graph-fetch-external-format__config-group__content">
|
658
|
+
<div className="query-builder-graph-fetch-external-format__config-group__item">
|
659
|
+
<TreeView
|
660
|
+
components={{
|
661
|
+
TreeNodeContainer:
|
662
|
+
QueryBuilderGraphFetchTreeNodeContainer,
|
663
|
+
}}
|
664
|
+
className="query-builder-graph-fetch-tree__container__tree"
|
665
|
+
treeData={treeData}
|
666
|
+
onNodeSelect={onNodeSelect}
|
667
|
+
getChildNodes={getChildNodes}
|
668
|
+
innerProps={{
|
669
|
+
isReadOnly,
|
670
|
+
removeNode,
|
671
|
+
}}
|
672
|
+
/>
|
673
|
+
</div>
|
674
|
+
</div>
|
675
|
+
</div>
|
676
|
+
</ResizablePanel>
|
677
|
+
<ResizablePanelSplitter />
|
678
|
+
{serializationState instanceof
|
679
|
+
GraphFetchExternalFormatSerializationState &&
|
680
|
+
serializationState.treeData && (
|
681
|
+
<ResizablePanel>
|
682
|
+
<div className="query-builder-graph-fetch-external-format__config-group">
|
683
|
+
<div className="query-builder-graph-fetch-external-format__config-group__header">
|
684
|
+
<div className="query-builder-graph-fetch-external-format__config-group__header__title">
|
685
|
+
Externalize
|
686
|
+
</div>
|
687
|
+
</div>
|
688
|
+
<div className="query-builder-graph-fetch-external-format__config-group__content">
|
689
|
+
<div className="query-builder-graph-fetch-external-format_config-group__item">
|
690
|
+
<QueryBuilderGraphFetchExternalConfig
|
691
|
+
graphFetchState={graphFetchState}
|
692
|
+
serializationState={serializationState}
|
693
|
+
serializationTreeData={serializationState.treeData}
|
694
|
+
bindings={compatibleBindings}
|
695
|
+
isReadOnly={false}
|
696
|
+
/>
|
697
|
+
</div>
|
698
|
+
</div>
|
699
|
+
</div>
|
700
|
+
</ResizablePanel>
|
701
|
+
)}
|
702
|
+
</ResizablePanelGroup>
|
394
703
|
</div>
|
395
704
|
</div>
|
396
705
|
);
|
@@ -400,10 +709,9 @@ export const QueryBuilderGraphFetchTreeExplorer = observer(
|
|
400
709
|
const QueryBuilderGraphFetchTreePanel = observer(
|
401
710
|
(props: {
|
402
711
|
graphFetchTreeState: QueryBuilderGraphFetchTreeState;
|
403
|
-
|
404
|
-
pureSerializationState: GraphFetchPureSerializationState;
|
712
|
+
serializationState: GraphFetchSerializationState;
|
405
713
|
}) => {
|
406
|
-
const { graphFetchTreeState,
|
714
|
+
const { graphFetchTreeState, serializationState } = props;
|
407
715
|
const treeData = graphFetchTreeState.treeData;
|
408
716
|
|
409
717
|
// Deep/Graph Fetch Tree
|
@@ -415,8 +723,18 @@ const QueryBuilderGraphFetchTreePanel = observer(
|
|
415
723
|
const handleDrop = useCallback(
|
416
724
|
(item: QueryBuilderExplorerTreeDragSource): void => {
|
417
725
|
graphFetchTreeState.addProperty(item.node, { refreshTreeData: true });
|
726
|
+
// If serializationState is GraphFetchExternalFormatSerializationState, we should add this node to
|
727
|
+
// the external format serialization tree as well
|
728
|
+
if (
|
729
|
+
serializationState instanceof
|
730
|
+
GraphFetchExternalFormatSerializationState
|
731
|
+
) {
|
732
|
+
serializationState.addProperty(deepClone(item.node), {
|
733
|
+
refreshTreeData: true,
|
734
|
+
});
|
735
|
+
}
|
418
736
|
},
|
419
|
-
[graphFetchTreeState],
|
737
|
+
[graphFetchTreeState, serializationState],
|
420
738
|
);
|
421
739
|
const [{ isDragOver }, dropTargetConnector] = useDrop<
|
422
740
|
QueryBuilderExplorerTreeDragSource,
|
@@ -458,7 +776,7 @@ const QueryBuilderGraphFetchTreePanel = observer(
|
|
458
776
|
{treeData && !isGraphFetchTreeDataEmpty(treeData) && (
|
459
777
|
<QueryBuilderGraphFetchTreeExplorer
|
460
778
|
graphFetchState={graphFetchTreeState}
|
461
|
-
|
779
|
+
serializationState={serializationState}
|
462
780
|
treeData={treeData}
|
463
781
|
isReadOnly={false}
|
464
782
|
updateTreeData={updateTreeData}
|
@@ -478,11 +796,14 @@ export const QueryBuilderGraphFetchPanel = observer(
|
|
478
796
|
graphFetchTreeState.queryBuilderState.textEditorState.openModal(
|
479
797
|
QueryBuilderTextEditorMode.TEXT,
|
480
798
|
);
|
481
|
-
if (
|
799
|
+
if (
|
800
|
+
serializationState instanceof GraphFetchPureSerializationState ||
|
801
|
+
serializationState instanceof GraphFetchExternalFormatSerializationState
|
802
|
+
) {
|
482
803
|
return (
|
483
804
|
<QueryBuilderGraphFetchTreePanel
|
484
805
|
graphFetchTreeState={graphFetchTreeState}
|
485
|
-
|
806
|
+
serializationState={serializationState}
|
486
807
|
/>
|
487
808
|
);
|
488
809
|
}
|
@@ -48,6 +48,7 @@ import {
|
|
48
48
|
import type { LambdaFunctionBuilderOption } from '../../QueryBuilderValueSpecificationBuilderHelper.js';
|
49
49
|
import { appendGraphFetch } from './QueryBuilderGraphFetchTreeValueSpecificationBuilder.js';
|
50
50
|
import {
|
51
|
+
deepClone,
|
51
52
|
guaranteeNonNullable,
|
52
53
|
hashArray,
|
53
54
|
type Hashable,
|
@@ -190,6 +191,7 @@ export class GraphFetchExternalFormatSerializationState extends GraphFetchSerial
|
|
190
191
|
targetBinding: observable,
|
191
192
|
treeData: observable.ref,
|
192
193
|
serializationContentType: computed,
|
194
|
+
setGraphFetchTree: action,
|
193
195
|
});
|
194
196
|
this.targetBinding = targetBinding;
|
195
197
|
this.treeData = treeData;
|
@@ -203,6 +205,30 @@ export class GraphFetchExternalFormatSerializationState extends GraphFetchSerial
|
|
203
205
|
this.treeData = val;
|
204
206
|
}
|
205
207
|
|
208
|
+
addProperty(
|
209
|
+
node: QueryBuilderExplorerTreePropertyNodeData,
|
210
|
+
options?: {
|
211
|
+
refreshTreeData?: boolean;
|
212
|
+
},
|
213
|
+
): void {
|
214
|
+
if (!this.treeData) {
|
215
|
+
this.queryBuilderGraphFetchTreeState.queryBuilderState.applicationStore.notificationService.notifyWarning(
|
216
|
+
`Can't add property: graph-fetch tree has not been properly initialized`,
|
217
|
+
);
|
218
|
+
return;
|
219
|
+
}
|
220
|
+
addQueryBuilderPropertyNode(
|
221
|
+
this.treeData,
|
222
|
+
this.queryBuilderGraphFetchTreeState.queryBuilderState.explorerState
|
223
|
+
.nonNullableTreeData,
|
224
|
+
node,
|
225
|
+
this.queryBuilderGraphFetchTreeState.queryBuilderState,
|
226
|
+
);
|
227
|
+
if (options?.refreshTreeData) {
|
228
|
+
this.setGraphFetchTree({ ...this.treeData });
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
206
232
|
override getLabel(): string {
|
207
233
|
return SERIALIZATION_TYPE.EXTERNAL_FORMAT;
|
208
234
|
}
|
@@ -409,6 +435,14 @@ export class QueryBuilderGraphFetchTreeState
|
|
409
435
|
|
410
436
|
fetchProperty(node: QueryBuilderExplorerTreePropertyNodeData): void {
|
411
437
|
this.addProperty(node, { refreshTreeData: true });
|
438
|
+
if (
|
439
|
+
this.serializationState instanceof
|
440
|
+
GraphFetchExternalFormatSerializationState
|
441
|
+
) {
|
442
|
+
this.serializationState.addProperty(deepClone(node), {
|
443
|
+
refreshTreeData: true,
|
444
|
+
});
|
445
|
+
}
|
412
446
|
}
|
413
447
|
|
414
448
|
fetchProperties(nodes: QueryBuilderExplorerTreePropertyNodeData[]): void {
|
@@ -175,8 +175,8 @@ export const appendGraphFetch = (
|
|
175
175
|
`Can't build graph-fetch tree expression: preceding expression is not defined`,
|
176
176
|
);
|
177
177
|
|
178
|
-
const
|
179
|
-
if (
|
178
|
+
const serializationState = graphFetchTreeState.serializationState;
|
179
|
+
if (serializationState instanceof GraphFetchPureSerializationState) {
|
180
180
|
// build graph-fetch tree
|
181
181
|
if (
|
182
182
|
graphFetchTreeState.treeData &&
|
@@ -201,9 +201,9 @@ export const appendGraphFetch = (
|
|
201
201
|
graphFetchInstance,
|
202
202
|
];
|
203
203
|
serializeFunction.parametersValues = [graphFetchFunc, graphFetchInstance];
|
204
|
-
if (
|
204
|
+
if (serializationState.config) {
|
205
205
|
const configFunction = buildPureSerializationConfig(
|
206
|
-
|
206
|
+
serializationState.config as unknown as Record<PropertyKey, boolean>,
|
207
207
|
graphFetchTreeState.queryBuilderState.graphManagerState.graph,
|
208
208
|
);
|
209
209
|
serializeFunction.parametersValues.push(configFunction);
|
@@ -211,18 +211,18 @@ export const appendGraphFetch = (
|
|
211
211
|
lambdaFunction.expressionSequence[0] = serializeFunction;
|
212
212
|
}
|
213
213
|
} else if (
|
214
|
-
|
214
|
+
serializationState instanceof GraphFetchExternalFormatSerializationState
|
215
215
|
) {
|
216
216
|
const externalizeFunction = new SimpleFunctionExpression(
|
217
217
|
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXTERNALIZE),
|
218
218
|
);
|
219
219
|
const mainGraphTree = graphFetchTreeState.treeData;
|
220
|
-
const
|
220
|
+
const externalizeGraphFetchTreeData = serializationState.treeData;
|
221
221
|
if (
|
222
222
|
mainGraphTree &&
|
223
|
-
|
223
|
+
externalizeGraphFetchTreeData &&
|
224
224
|
!isGraphFetchTreeDataEmpty(mainGraphTree) &&
|
225
|
-
!isGraphFetchTreeDataEmpty(
|
225
|
+
!isGraphFetchTreeDataEmpty(externalizeGraphFetchTreeData)
|
226
226
|
) {
|
227
227
|
// 0th param
|
228
228
|
const graphFetchInstance = new GraphFetchTreeInstanceValue();
|
@@ -244,12 +244,12 @@ export const appendGraphFetch = (
|
|
244
244
|
const bindingInstance = new InstanceValue(Multiplicity.ONE, undefined);
|
245
245
|
bindingInstance.values = [
|
246
246
|
PackageableElementExplicitReference.create(
|
247
|
-
|
247
|
+
serializationState.targetBinding,
|
248
248
|
),
|
249
249
|
];
|
250
250
|
// 2nd parameter
|
251
251
|
const xtGraphFetchInstance = new GraphFetchTreeInstanceValue();
|
252
|
-
xtGraphFetchInstance.values = [
|
252
|
+
xtGraphFetchInstance.values = [externalizeGraphFetchTreeData.tree];
|
253
253
|
// build externalize
|
254
254
|
externalizeFunction.parametersValues = [
|
255
255
|
graphFetchFunc,
|
@@ -260,7 +260,7 @@ export const appendGraphFetch = (
|
|
260
260
|
}
|
261
261
|
} else {
|
262
262
|
throw new UnsupportedOperationError(
|
263
|
-
`Unsupported serialization state ${
|
263
|
+
`Unsupported serialization state ${serializationState.getLabel()}`,
|
264
264
|
);
|
265
265
|
}
|
266
266
|
// build result set modifier: i.e. preview limit
|