@finos/legend-application-query 13.4.12 → 13.4.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts +5 -0
  2. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -1
  3. package/lib/components/Core_LegendQueryApplicationPlugin.js +201 -4
  4. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -1
  5. package/lib/components/QueryEditor.d.ts +8 -0
  6. package/lib/components/QueryEditor.d.ts.map +1 -1
  7. package/lib/components/QueryEditor.js +25 -140
  8. package/lib/components/QueryEditor.js.map +1 -1
  9. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts.map +1 -1
  10. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js +2 -0
  11. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js.map +1 -1
  12. package/lib/components/data-space/DataSpaceQuerySetup.d.ts.map +1 -1
  13. package/lib/components/data-space/DataSpaceQuerySetup.js +7 -6
  14. package/lib/components/data-space/DataSpaceQuerySetup.js.map +1 -1
  15. package/lib/index.css +2 -2
  16. package/lib/index.css.map +1 -1
  17. package/lib/index.d.ts +1 -2
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +1 -2
  20. package/lib/index.js.map +1 -1
  21. package/lib/package.json +1 -1
  22. package/lib/stores/LegendQueryApplicationPlugin.d.ts +4 -12
  23. package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
  24. package/lib/stores/LegendQueryApplicationPlugin.js +1 -0
  25. package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
  26. package/lib/stores/QueryEditorStore.d.ts +7 -1
  27. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  28. package/lib/stores/QueryEditorStore.js +18 -4
  29. package/lib/stores/QueryEditorStore.js.map +1 -1
  30. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js +1 -1
  31. package/lib/stores/__test-utils__/LegendQueryApplicationTestUtils.js.map +1 -1
  32. package/lib/stores/data-space/DataSpaceQueryCreatorStore.d.ts.map +1 -1
  33. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js +2 -2
  34. package/lib/stores/data-space/DataSpaceQueryCreatorStore.js.map +1 -1
  35. package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts +2 -1
  36. package/lib/stores/data-space/DataSpaceQuerySetupState.d.ts.map +1 -1
  37. package/lib/stores/data-space/DataSpaceQuerySetupState.js +6 -3
  38. package/lib/stores/data-space/DataSpaceQuerySetupState.js.map +1 -1
  39. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  40. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +2 -2
  41. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  42. package/package.json +6 -6
  43. package/src/components/Core_LegendQueryApplicationPlugin.tsx +406 -1
  44. package/src/components/QueryEditor.tsx +111 -507
  45. package/src/components/__test-utils__/QueryEditorComponentTestUtils.tsx +2 -0
  46. package/src/components/data-space/DataSpaceQuerySetup.tsx +52 -53
  47. package/src/index.ts +2 -2
  48. package/src/stores/{LegendQueryApplicationPlugin.ts → LegendQueryApplicationPlugin.tsx} +11 -18
  49. package/src/stores/QueryEditorStore.ts +23 -0
  50. package/src/stores/__test-utils__/LegendQueryApplicationTestUtils.ts +1 -1
  51. package/src/stores/data-space/DataSpaceQueryCreatorStore.ts +2 -0
  52. package/src/stores/data-space/DataSpaceQuerySetupState.ts +8 -0
  53. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +2 -0
  54. package/tsconfig.json +2 -4
  55. package/lib/__lib__/LegendQueryTesting.d.ts +0 -19
  56. package/lib/__lib__/LegendQueryTesting.d.ts.map +0 -1
  57. package/lib/__lib__/LegendQueryTesting.js +0 -20
  58. package/lib/__lib__/LegendQueryTesting.js.map +0 -1
  59. package/lib/application/LegendQueryDocumentation.d.ts +0 -19
  60. package/lib/application/LegendQueryDocumentation.d.ts.map +0 -1
  61. package/lib/application/LegendQueryDocumentation.js +0 -20
  62. package/lib/application/LegendQueryDocumentation.js.map +0 -1
  63. package/src/__lib__/LegendQueryTesting.ts +0 -19
  64. package/src/application/LegendQueryDocumentation.ts +0 -19
@@ -23,10 +23,20 @@ import packageJson from '../../package.json' assert { type: 'json' };
23
23
  import type { QuerySetupLandingPageStore } from '../stores/QuerySetupStore.js';
24
24
  import {
25
25
  ArrowCircleUpIcon,
26
+ Button,
27
+ CaretDownIcon,
26
28
  DroidIcon,
29
+ DropdownMenu,
30
+ InfoCircleIcon,
27
31
  ManageSearchIcon,
32
+ MenuContent,
33
+ MenuContentItem,
34
+ MenuContentItemIcon,
35
+ MenuContentItemLabel,
28
36
  PlusIcon,
29
37
  RobotIcon,
38
+ SaveAsIcon,
39
+ SaveCurrIcon,
30
40
  SquareIcon,
31
41
  } from '@finos/legend-art';
32
42
  import {
@@ -34,6 +44,7 @@ import {
34
44
  generateCreateMappingQuerySetupRoute,
35
45
  generateEditExistingQuerySetupRoute,
36
46
  generateLoadProjectServiceQuerySetup,
47
+ generateMappingQueryCreatorRoute,
37
48
  generateQueryProductionizerSetupRoute,
38
49
  generateUpdateExistingServiceQuerySetup,
39
50
  LEGEND_QUERY_ROUTE_PATTERN,
@@ -50,7 +61,31 @@ import {
50
61
  configureCodeEditorComponent,
51
62
  setupPureLanguageService,
52
63
  } from '@finos/legend-lego/code-editor';
53
- import { generateDataSpaceQuerySetupRoute } from '../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
64
+ import {
65
+ generateDataSpaceQueryCreatorRoute,
66
+ generateDataSpaceQuerySetupRoute,
67
+ } from '../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
68
+ import type {
69
+ QueryBuilderHeaderActionConfiguration,
70
+ QueryBuilderMenuActionConfiguration,
71
+ } from '@finos/legend-query-builder';
72
+ import {
73
+ ExistingQueryEditorStore,
74
+ QueryBuilderActionConfig_QueryApplication,
75
+ createViewProjectHandler,
76
+ createViewSDLCProjectHandler,
77
+ } from '../stores/QueryEditorStore.js';
78
+ import {
79
+ DataSpaceQueryBuilderState,
80
+ generateDataSpaceTemplateQueryPromotionRoute,
81
+ } from '@finos/legend-extension-dsl-data-space/application';
82
+ import { RuntimePointer } from '@finos/legend-graph';
83
+ import { LegendQueryTelemetryHelper } from '../__lib__/LegendQueryTelemetryHelper.js';
84
+ import { StoreProjectData } from '@finos/legend-server-depot';
85
+ import { buildUrl } from '@finos/legend-shared';
86
+ import { parseProjectIdentifier } from '@finos/legend-storage';
87
+ import { QueryEditorExistingQueryHeader } from './QueryEditor.js';
88
+ import { DataSpaceTemplateQueryCreatorStore } from '../stores/data-space/DataSpaceTemplateQueryCreatorStore.js';
54
89
 
55
90
  export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlugin {
56
91
  static NAME = packageJson.extensions.applicationQueryPlugin;
@@ -203,4 +238,374 @@ export class Core_LegendQueryApplicationPlugin extends LegendQueryApplicationPlu
203
238
  },
204
239
  ];
205
240
  }
241
+ getExtraQueryBuilderExportMenuActionConfigurations?(): QueryBuilderMenuActionConfiguration[] {
242
+ return [
243
+ {
244
+ key: 'promote-as-template-query',
245
+ title: 'Promote Curated Template query...',
246
+ label: 'Curated Template Query',
247
+ onClick: (queryBuilderState): void => {
248
+ if (
249
+ queryBuilderState.workflowState.actionConfig instanceof
250
+ QueryBuilderActionConfig_QueryApplication
251
+ ) {
252
+ const editorStore =
253
+ queryBuilderState.workflowState.actionConfig.editorStore;
254
+ const proceedCuratedTemplateQueryPromotion =
255
+ async (): Promise<void> => {
256
+ if (
257
+ !(
258
+ editorStore instanceof ExistingQueryEditorStore &&
259
+ queryBuilderState instanceof DataSpaceQueryBuilderState
260
+ )
261
+ ) {
262
+ return;
263
+ }
264
+ // fetch project data
265
+ const project = StoreProjectData.serialization.fromJson(
266
+ await editorStore.depotServerClient.getProject(
267
+ editorStore.lightQuery.groupId,
268
+ editorStore.lightQuery.artifactId,
269
+ ),
270
+ );
271
+
272
+ // find the matching SDLC instance
273
+ const projectIDPrefix = parseProjectIdentifier(
274
+ project.projectId,
275
+ ).prefix;
276
+ const matchingSDLCEntry =
277
+ editorStore.applicationStore.config.studioInstances.find(
278
+ (entry) => entry.sdlcProjectIDPrefix === projectIDPrefix,
279
+ );
280
+ if (matchingSDLCEntry) {
281
+ editorStore.applicationStore.navigationService.navigator.visitAddress(
282
+ buildUrl([
283
+ editorStore.applicationStore.config.studioApplicationUrl,
284
+ generateDataSpaceTemplateQueryPromotionRoute(
285
+ editorStore.lightQuery.groupId,
286
+ editorStore.lightQuery.artifactId,
287
+ editorStore.lightQuery.versionId,
288
+ queryBuilderState.dataSpace.path,
289
+ editorStore.lightQuery.id,
290
+ ),
291
+ ]),
292
+ );
293
+ } else {
294
+ editorStore.applicationStore.notificationService.notifyWarning(
295
+ `Can't find the corresponding SDLC instance to productionize the query`,
296
+ );
297
+ }
298
+ };
299
+
300
+ queryBuilderState.changeDetectionState.alertUnsavedChanges(() => {
301
+ proceedCuratedTemplateQueryPromotion().catch(
302
+ editorStore.applicationStore.alertUnhandledError,
303
+ );
304
+ });
305
+ }
306
+ },
307
+ icon: <ArrowCircleUpIcon />,
308
+ },
309
+ ];
310
+ }
311
+
312
+ getExtraQueryBuilderHelpMenuActionConfigurations?(): QueryBuilderMenuActionConfiguration[] {
313
+ return [
314
+ {
315
+ key: 'about-query-info',
316
+ title: 'Get Query Info',
317
+ label: 'About Query Info',
318
+ onClick: (queryBuilderState): void => {
319
+ if (
320
+ queryBuilderState.workflowState.actionConfig instanceof
321
+ QueryBuilderActionConfig_QueryApplication
322
+ ) {
323
+ const editorStore =
324
+ queryBuilderState.workflowState.actionConfig.editorStore;
325
+ if (editorStore instanceof ExistingQueryEditorStore) {
326
+ editorStore.updateState.setShowQueryInfo(true);
327
+ }
328
+ }
329
+ },
330
+ icon: <InfoCircleIcon />,
331
+ },
332
+ {
333
+ key: 'about-query-project',
334
+ title: 'Go to Project',
335
+ label: 'Go to Project',
336
+ onClick: (queryBuilderState): void => {
337
+ if (
338
+ queryBuilderState.workflowState.actionConfig instanceof
339
+ QueryBuilderActionConfig_QueryApplication
340
+ ) {
341
+ const editorStore =
342
+ queryBuilderState.workflowState.actionConfig.editorStore;
343
+ LegendQueryTelemetryHelper.logEvent_QueryViewProjectLaunched(
344
+ editorStore.applicationStore.telemetryService,
345
+ );
346
+ const { groupId, artifactId, versionId } =
347
+ editorStore.getProjectInfo();
348
+ createViewProjectHandler(editorStore.applicationStore)(
349
+ groupId,
350
+ artifactId,
351
+ versionId,
352
+ undefined,
353
+ );
354
+ }
355
+ },
356
+ icon: <InfoCircleIcon />,
357
+ },
358
+ {
359
+ key: 'about-query-sdlc-project',
360
+ title: 'Go to SDLC Project',
361
+ label: 'Go to SDLC Project',
362
+ onClick: (queryBuilderState): void => {
363
+ if (
364
+ queryBuilderState.workflowState.actionConfig instanceof
365
+ QueryBuilderActionConfig_QueryApplication
366
+ ) {
367
+ const editorStore =
368
+ queryBuilderState.workflowState.actionConfig.editorStore;
369
+ LegendQueryTelemetryHelper.logEvent_QueryViewSdlcProjectLaunched(
370
+ editorStore.applicationStore.telemetryService,
371
+ );
372
+ const { groupId, artifactId } = editorStore.getProjectInfo();
373
+ createViewSDLCProjectHandler(
374
+ editorStore.applicationStore,
375
+ editorStore.depotServerClient,
376
+ )(groupId, artifactId, undefined).catch(
377
+ editorStore.applicationStore.alertUnhandledError,
378
+ );
379
+ }
380
+ },
381
+ icon: <InfoCircleIcon />,
382
+ },
383
+ ];
384
+ }
385
+
386
+ getExtraQueryBuilderHeaderActionConfigurations?(): QueryBuilderHeaderActionConfiguration[] {
387
+ return [
388
+ {
389
+ key: 'load-query',
390
+ category: 0,
391
+ renderer: (queryBuilderState): React.ReactNode => {
392
+ if (
393
+ queryBuilderState.workflowState.actionConfig instanceof
394
+ QueryBuilderActionConfig_QueryApplication
395
+ ) {
396
+ const editorStore =
397
+ queryBuilderState.workflowState.actionConfig.editorStore;
398
+ const openQueryLoader = (): void => {
399
+ editorStore.queryLoaderState.setQueryLoaderDialogOpen(true);
400
+ };
401
+ return (
402
+ <Button
403
+ className="query-editor__header__action btn--dark"
404
+ disabled={editorStore.isPerformingBlockingAction}
405
+ onClick={openQueryLoader}
406
+ title="Load query..."
407
+ >
408
+ <ManageSearchIcon className="query-editor__header__action__icon--load" />
409
+ <div className="query-editor__header__action__label">
410
+ Load Query
411
+ </div>
412
+ </Button>
413
+ );
414
+ }
415
+ return undefined;
416
+ },
417
+ },
418
+ {
419
+ key: 'new-query',
420
+ category: 0,
421
+ renderer: (queryBuilderState): React.ReactNode => {
422
+ if (
423
+ queryBuilderState.workflowState.actionConfig instanceof
424
+ QueryBuilderActionConfig_QueryApplication
425
+ ) {
426
+ const editorStore =
427
+ queryBuilderState.workflowState.actionConfig.editorStore;
428
+ const isExistingQuery =
429
+ editorStore instanceof ExistingQueryEditorStore;
430
+ const handleNewQuery = (): void => {
431
+ if (editorStore instanceof ExistingQueryEditorStore) {
432
+ const query = editorStore.query;
433
+ if (query) {
434
+ if (queryBuilderState instanceof DataSpaceQueryBuilderState) {
435
+ editorStore.applicationStore.navigationService.navigator.goToLocation(
436
+ generateDataSpaceQueryCreatorRoute(
437
+ query.groupId,
438
+ query.artifactId,
439
+ query.versionId,
440
+ queryBuilderState.dataSpace.path,
441
+ queryBuilderState.executionContext.name,
442
+ undefined,
443
+ undefined,
444
+ ),
445
+ );
446
+ } else {
447
+ const mapping =
448
+ editorStore.queryBuilderState?.executionContextState
449
+ .mapping;
450
+ const runtime =
451
+ editorStore.queryBuilderState?.executionContextState
452
+ .runtimeValue;
453
+ if (mapping && runtime instanceof RuntimePointer) {
454
+ editorStore.applicationStore.navigationService.navigator.goToLocation(
455
+ generateMappingQueryCreatorRoute(
456
+ query.groupId,
457
+ query.artifactId,
458
+ query.versionId,
459
+ mapping.path,
460
+ runtime.packageableRuntime.value.path,
461
+ ),
462
+ );
463
+ }
464
+ }
465
+ }
466
+ }
467
+ };
468
+ return (
469
+ <>
470
+ {isExistingQuery && (
471
+ <Button
472
+ className="query-editor__header__action btn--dark"
473
+ disabled={editorStore.isPerformingBlockingAction}
474
+ onClick={handleNewQuery}
475
+ title="New query"
476
+ >
477
+ <SaveCurrIcon />
478
+ <div className="query-editor__header__action__label">
479
+ New Query
480
+ </div>
481
+ </Button>
482
+ )}
483
+ </>
484
+ );
485
+ }
486
+ return undefined;
487
+ },
488
+ },
489
+ {
490
+ key: 'save-combo',
491
+ category: 0,
492
+ renderer: (queryBuilderState): React.ReactNode => {
493
+ if (
494
+ queryBuilderState.workflowState.actionConfig instanceof
495
+ QueryBuilderActionConfig_QueryApplication
496
+ ) {
497
+ const editorStore =
498
+ queryBuilderState.workflowState.actionConfig.editorStore;
499
+ const isExistingQuery =
500
+ editorStore instanceof ExistingQueryEditorStore;
501
+ const openSaveQueryModal = (): void => {
502
+ if (editorStore instanceof ExistingQueryEditorStore) {
503
+ editorStore.updateState.showSaveModal();
504
+ }
505
+ };
506
+ const handleQuerySaveAs = (): void => {
507
+ editorStore.queryCreatorState.open(
508
+ editorStore instanceof ExistingQueryEditorStore
509
+ ? editorStore.query
510
+ : undefined,
511
+ );
512
+ };
513
+ return (
514
+ <div className="query-editor__header__action-combo btn__dropdown-combo">
515
+ <Button
516
+ className="query-editor__header__action query-editor__header__action-combo__main-btn btn--dak"
517
+ disabled={
518
+ !isExistingQuery ||
519
+ editorStore.isPerformingBlockingAction ||
520
+ !queryBuilderState.canBuildQuery
521
+ }
522
+ onClick={openSaveQueryModal}
523
+ title="Save query"
524
+ >
525
+ <SaveCurrIcon />
526
+ <div className="query-editor__header__action__label">
527
+ Save
528
+ </div>
529
+ </Button>
530
+ <DropdownMenu
531
+ className="query-editor__header__action-combo__dropdown-btn"
532
+ disabled={editorStore.isViewProjectActionDisabled}
533
+ title="query__editor__save-dropdown"
534
+ content={
535
+ <MenuContent>
536
+ <MenuContentItem
537
+ className="btn__dropdown-combo__option"
538
+ onClick={handleQuerySaveAs}
539
+ title="query__editor__save-dropdown__save-as"
540
+ disabled={
541
+ editorStore.isPerformingBlockingAction ||
542
+ !queryBuilderState.canBuildQuery
543
+ }
544
+ >
545
+ <MenuContentItemIcon>
546
+ <SaveAsIcon />
547
+ </MenuContentItemIcon>
548
+ <MenuContentItemLabel>
549
+ Save As New Query
550
+ </MenuContentItemLabel>
551
+ </MenuContentItem>
552
+ </MenuContent>
553
+ }
554
+ >
555
+ <CaretDownIcon />
556
+ </DropdownMenu>
557
+ </div>
558
+ );
559
+ }
560
+ return undefined;
561
+ },
562
+ },
563
+ ];
564
+ }
565
+
566
+ getExtraQueryBuilderHeaderTitleConfigurations?(): QueryBuilderHeaderActionConfiguration {
567
+ return {
568
+ key: 'query-title',
569
+ category: 0,
570
+ renderer: (queryBuilderState): React.ReactNode => {
571
+ if (
572
+ queryBuilderState.workflowState.actionConfig instanceof
573
+ QueryBuilderActionConfig_QueryApplication
574
+ ) {
575
+ const editorStore =
576
+ queryBuilderState.workflowState.actionConfig.editorStore;
577
+ const renderQueryTitle = (): React.ReactNode => {
578
+ if (editorStore instanceof ExistingQueryEditorStore) {
579
+ return (
580
+ <QueryEditorExistingQueryHeader
581
+ queryBuilderState={queryBuilderState}
582
+ existingEditorStore={editorStore}
583
+ />
584
+ );
585
+ } else if (
586
+ editorStore instanceof DataSpaceTemplateQueryCreatorStore
587
+ ) {
588
+ return (
589
+ <div className="query-editor__dataspace__header">
590
+ <div className="query-editor__header__content__main query-editor__header__content__title__text query-editor__dataspace__header__title__text">
591
+ {editorStore.templateQueryTitle}
592
+ </div>
593
+ <div className="query-editor__dataspace__header__title__tag">
594
+ template
595
+ </div>
596
+ </div>
597
+ );
598
+ }
599
+ return undefined;
600
+ };
601
+ return (
602
+ <div className="query-editor__header__content">
603
+ {renderQueryTitle()}
604
+ </div>
605
+ );
606
+ }
607
+ return undefined;
608
+ },
609
+ };
610
+ }
206
611
  }