@finos/legend-application-query 13.8.4 → 13.8.6

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.
Files changed (38) hide show
  1. package/lib/components/QueryEditor.d.ts.map +1 -1
  2. package/lib/components/QueryEditor.js +2 -15
  3. package/lib/components/QueryEditor.js.map +1 -1
  4. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts +13 -0
  5. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.d.ts.map +1 -1
  6. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js +84 -3
  7. package/lib/components/__test-utils__/QueryEditorComponentTestUtils.js.map +1 -1
  8. package/lib/components/data-space/DataSpaceTemplateQueryCreator.d.ts.map +1 -1
  9. package/lib/components/data-space/DataSpaceTemplateQueryCreator.js +17 -4
  10. package/lib/components/data-space/DataSpaceTemplateQueryCreator.js.map +1 -1
  11. package/lib/components/utils/QueryParameterUtils.d.ts +19 -0
  12. package/lib/components/utils/QueryParameterUtils.d.ts.map +1 -0
  13. package/lib/components/utils/QueryParameterUtils.js +57 -0
  14. package/lib/components/utils/QueryParameterUtils.js.map +1 -0
  15. package/lib/index.css +1 -1
  16. package/lib/light-mode.css +2 -2
  17. package/lib/light-mode.css.map +1 -1
  18. package/lib/package.json +1 -1
  19. package/lib/stores/QueryEditorStore.d.ts +2 -0
  20. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  21. package/lib/stores/QueryEditorStore.js +9 -26
  22. package/lib/stores/QueryEditorStore.js.map +1 -1
  23. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts +3 -1
  24. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.d.ts.map +1 -1
  25. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js +23 -3
  26. package/lib/stores/data-space/DataSpaceTemplateQueryCreatorStore.js.map +1 -1
  27. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.d.ts.map +1 -1
  28. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js +19 -5
  29. package/lib/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.js.map +1 -1
  30. package/package.json +8 -8
  31. package/src/components/QueryEditor.tsx +2 -20
  32. package/src/components/__test-utils__/QueryEditorComponentTestUtils.tsx +205 -1
  33. package/src/components/data-space/DataSpaceTemplateQueryCreator.tsx +28 -1
  34. package/src/components/utils/QueryParameterUtils.ts +77 -0
  35. package/src/stores/QueryEditorStore.ts +11 -36
  36. package/src/stores/data-space/DataSpaceTemplateQueryCreatorStore.ts +44 -1
  37. package/src/stores/data-space/query-builder/LegendQueryDataSpaceQueryBuilderState.ts +28 -14
  38. package/tsconfig.json +1 -0
@@ -21,6 +21,7 @@ import {
21
21
  type AbstractPreset,
22
22
  filterByType,
23
23
  guaranteeNonNullable,
24
+ guaranteeType,
24
25
  } from '@finos/legend-shared';
25
26
  import { createMock, createSpy } from '@finos/legend-shared/test';
26
27
  import {
@@ -40,6 +41,7 @@ import {
40
41
  QueryDataProductModelAccessExecutionContextInfo,
41
42
  QueryDataProductNativeExecutionContextInfo,
42
43
  ModelAccessPointGroup,
44
+ V1_PureGraphManager,
43
45
  } from '@finos/legend-graph';
44
46
  import { DepotServerClient } from '@finos/legend-server-depot';
45
47
  import {
@@ -67,19 +69,34 @@ import {
67
69
  import { LegendQueryFrameworkProvider } from '../LegendQueryFrameworkProvider.js';
68
70
  import { TEST__BrowserEnvironmentProvider } from '@finos/legend-application/test';
69
71
  import { Core_LegendQueryApplicationPlugin } from '../Core_LegendQueryApplicationPlugin.js';
70
- import { Route, Routes } from '@finos/legend-application/browser';
72
+ import {
73
+ Route,
74
+ Routes,
75
+ generateExtensionUrlPattern,
76
+ } from '@finos/legend-application/browser';
71
77
  import {
72
78
  generateExistingQueryEditorRoute,
73
79
  LEGEND_QUERY_ROUTE_PATTERN,
74
80
  } from '../../__lib__/LegendQueryNavigation.js';
81
+ import {
82
+ generateDataSpaceTemplateQueryCreatorRoute,
83
+ LEGACY_DATA_SPACE_QUERY_ROUTE_PATTERN,
84
+ } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
85
+ import { DataSpaceTemplateQueryCreator } from '../data-space/DataSpaceTemplateQueryCreator.js';
75
86
  import {
76
87
  type V1_DataSpaceAnalysisResult,
77
88
  DSL_DataSpace_getGraphManagerExtension,
78
89
  } from '@finos/legend-extension-dsl-data-space/graph';
79
90
  import { LegendQueryDataProductQueryBuilderState } from '../../stores/data-product/query-builder/LegendQueryDataProductQueryBuilderState.js';
80
91
  import { DataProductSelectorState } from '../../stores/data-space/DataProductSelectorState.js';
92
+ import { DataSpaceTemplateQueryCreatorStore } from '../../stores/data-space/DataSpaceTemplateQueryCreatorStore.js';
81
93
 
82
94
  const TEST_QUERY_ID = 'test-query-id';
95
+ const TEST_GROUP_ID = 'test-group';
96
+ const TEST_ARTIFACT_ID = 'test-artifact';
97
+ const TEST_VERSION_ID = 'test-version';
98
+ const TEST_TEMPLATE_QUERY_ID = 'templateQuery';
99
+ const TEST_DATA_SPACE_PATH = 'domain::COVIDDatapace';
83
100
  export const TEST_QUERY_NAME = 'MyTestQuery';
84
101
 
85
102
  export const TEST__provideMockedQueryEditorStore = (customization?: {
@@ -123,6 +140,52 @@ export const TEST__provideMockedQueryEditorStore = (customization?: {
123
140
  return value;
124
141
  };
125
142
 
143
+ export const TEST__provideMockedDataSpaceTemplateQueryCreatorStore =
144
+ (customization?: {
145
+ mock?: DataSpaceTemplateQueryCreatorStore;
146
+ applicationStore?: LegendQueryApplicationStore;
147
+ graphManagerState?: GraphManagerState;
148
+ pluginManager?: LegendQueryPluginManager;
149
+ extraPlugins?: AbstractPlugin[];
150
+ extraPresets?: AbstractPreset[];
151
+ }): DataSpaceTemplateQueryCreatorStore => {
152
+ const pluginManager =
153
+ customization?.pluginManager ?? LegendQueryPluginManager.create();
154
+ pluginManager
155
+ .usePlugins([
156
+ new Core_LegendQueryApplicationPlugin(),
157
+ ...(customization?.extraPlugins ?? []),
158
+ ])
159
+ .usePresets([...(customization?.extraPresets ?? [])])
160
+ .install();
161
+ const applicationStore =
162
+ customization?.applicationStore ??
163
+ new ApplicationStore(
164
+ TEST__getTestLegendQueryApplicationConfig(),
165
+ pluginManager,
166
+ );
167
+ const depotServerClient = new DepotServerClient({
168
+ serverUrl: applicationStore.config.depotServerUrl,
169
+ });
170
+ depotServerClient.setTracerService(applicationStore.tracerService);
171
+ const value =
172
+ customization?.mock ??
173
+ new DataSpaceTemplateQueryCreatorStore(
174
+ applicationStore,
175
+ depotServerClient,
176
+ TEST_GROUP_ID,
177
+ TEST_ARTIFACT_ID,
178
+ TEST_VERSION_ID,
179
+ TEST_DATA_SPACE_PATH,
180
+ TEST_TEMPLATE_QUERY_ID,
181
+ { fips: 'value' },
182
+ );
183
+ const MOCK__QueryEditorStoreProvider = require('../QueryEditorStoreProvider.js'); // eslint-disable-line @typescript-eslint/no-require-imports,@typescript-eslint/no-unsafe-assignment
184
+ MOCK__QueryEditorStoreProvider.useQueryEditorStore = createMock();
185
+ MOCK__QueryEditorStoreProvider.useQueryEditorStore.mockReturnValue(value);
186
+ return value;
187
+ };
188
+
126
189
  export const TEST__setUpQueryEditor = async (
127
190
  MOCK__editorStore: ExistingQueryEditorStore,
128
191
  entities: PlainObject<Entity>[],
@@ -432,6 +495,147 @@ export const TEST__setUpDataSpaceExistingQueryEditor = async (
432
495
  };
433
496
  };
434
497
 
498
+ export const TEST__setUpDataSpaceTemplateQueryEditor = async (
499
+ MOCK__editorStore: DataSpaceTemplateQueryCreatorStore,
500
+ V1_dataspaceAnalyticsResult: PlainObject<V1_DataSpaceAnalysisResult>,
501
+ dataSpacePath: string,
502
+ executionContext: string,
503
+ lambda: RawLambda,
504
+ entities: PlainObject<Entity>[],
505
+ ): Promise<{
506
+ renderResult: RenderResult;
507
+ queryBuilderState: QueryBuilderState;
508
+ }> => {
509
+ const projectData = {
510
+ id: 'test-id',
511
+ groupId: MOCK__editorStore.groupId,
512
+ artifactId: MOCK__editorStore.artifactId,
513
+ projectId: 'test-project-id',
514
+ versions: [MOCK__editorStore.versionId],
515
+ latestVersion: MOCK__editorStore.versionId,
516
+ };
517
+
518
+ const graphManagerState = MOCK__editorStore.graphManagerState;
519
+
520
+ await graphManagerState.graphManager.initialize({
521
+ env: 'test',
522
+ tabSize: 2,
523
+ clientConfig: {},
524
+ });
525
+
526
+ await graphManagerState.initializeSystem();
527
+
528
+ createSpy(
529
+ MOCK__editorStore.depotServerClient,
530
+ 'getProject',
531
+ ).mockResolvedValue(projectData);
532
+ createSpy(
533
+ MOCK__editorStore.depotServerClient,
534
+ 'getEntities',
535
+ ).mockResolvedValue(entities);
536
+ createSpy(
537
+ MOCK__editorStore.depotServerClient,
538
+ 'getIndexedDependencyEntities',
539
+ ).mockResolvedValue(new Map<string, EntitiesWithOrigin>());
540
+ createSpy(
541
+ MOCK__editorStore.depotServerClient,
542
+ 'getEntitiesByClassifier',
543
+ ).mockResolvedValue([]);
544
+ createSpy(
545
+ MOCK__editorStore.depotServerClient,
546
+ 'getGenerationContentByPath',
547
+ ).mockResolvedValue(JSON.stringify(V1_dataspaceAnalyticsResult));
548
+ createSpy(
549
+ MOCK__editorStore.depotServerClient,
550
+ 'getGenerationFilesByType',
551
+ ).mockResolvedValue([]);
552
+ createSpy(
553
+ graphManagerState.graphManager,
554
+ 'pureCodeToLambda',
555
+ ).mockResolvedValue(new RawLambda(lambda.parameters, lambda.body));
556
+ createSpy(
557
+ graphManagerState.graphManager,
558
+ 'lambdaToPureCode',
559
+ ).mockResolvedValue('');
560
+ createSpy(graphManagerState.graphManager, 'surveyDatasets').mockResolvedValue(
561
+ [],
562
+ );
563
+ createSpy(
564
+ graphManagerState.graphManager,
565
+ 'checkDatasetEntitlements',
566
+ ).mockResolvedValue([]);
567
+
568
+ // Mock engine's transformCodeToValueSpecifications to handle preset URL string parameter values.
569
+ const pureGraphManager = guaranteeType(
570
+ graphManagerState.graphManager,
571
+ V1_PureGraphManager,
572
+ );
573
+ createSpy(
574
+ pureGraphManager.engine,
575
+ 'transformCodeToValueSpecifications',
576
+ ).mockImplementation(async (input: Record<string, { value: string }>) => {
577
+ const result = new Map<string, PlainObject>();
578
+ for (const [key, entry] of Object.entries(input)) {
579
+ const match = /^'(?<content>.*)'$/.exec(entry.value);
580
+ if (match?.groups) {
581
+ result.set(key, { _type: 'string', value: match.groups.content });
582
+ }
583
+ }
584
+ return result;
585
+ });
586
+
587
+ const graphManagerExtension = DSL_DataSpace_getGraphManagerExtension(
588
+ graphManagerState.graphManager,
589
+ );
590
+ const dataspaceAnalyticsResult =
591
+ await graphManagerExtension.buildDataSpaceAnalytics(
592
+ V1_dataspaceAnalyticsResult,
593
+ graphManagerState.graphManager.pluginManager.getPureProtocolProcessorPlugins(),
594
+ );
595
+ createSpy(graphManagerExtension, 'analyzeDataSpace').mockResolvedValue(
596
+ dataspaceAnalyticsResult,
597
+ );
598
+
599
+ MOCK__editorStore.buildGraph = createMock();
600
+ graphManagerState.graphManager.initialize = createMock();
601
+
602
+ const templateRoute = generateDataSpaceTemplateQueryCreatorRoute(
603
+ MOCK__editorStore.groupId,
604
+ MOCK__editorStore.artifactId,
605
+ MOCK__editorStore.versionId,
606
+ MOCK__editorStore.dataSpacePath,
607
+ MOCK__editorStore.templateQueryId,
608
+ );
609
+
610
+ const renderResult = render(
611
+ <ApplicationStoreProvider store={MOCK__editorStore.applicationStore}>
612
+ <TEST__BrowserEnvironmentProvider initialEntries={[templateRoute]}>
613
+ <LegendQueryFrameworkProvider>
614
+ <Routes>
615
+ <Route
616
+ path={generateExtensionUrlPattern(
617
+ LEGACY_DATA_SPACE_QUERY_ROUTE_PATTERN.TEMPLATE_QUERY,
618
+ )}
619
+ element={<DataSpaceTemplateQueryCreator />}
620
+ />
621
+ </Routes>
622
+ </LegendQueryFrameworkProvider>
623
+ </TEST__BrowserEnvironmentProvider>
624
+ </ApplicationStoreProvider>,
625
+ );
626
+ await waitFor(() =>
627
+ renderResult.getByTestId(QUERY_BUILDER_TEST_ID.QUERY_BUILDER),
628
+ );
629
+
630
+ return {
631
+ renderResult,
632
+ queryBuilderState: guaranteeNonNullable(
633
+ MOCK__editorStore.queryBuilderState,
634
+ `Query builder state should have been initialized`,
635
+ ),
636
+ };
637
+ };
638
+
435
639
  export const TEST__setUpDataProductExistingQueryEditor = async (
436
640
  MOCK__editorStore: ExistingQueryEditorStore,
437
641
  dataProductPath: string,
@@ -25,17 +25,22 @@ import { DataSpaceTemplateQueryCreatorStore } from '../../stores/data-space/Data
25
25
  import { QueryEditorStoreContext } from '../QueryEditorStoreProvider.js';
26
26
  import {
27
27
  DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN,
28
+ generateDataSpaceTemplateQueryCreatorRoute,
28
29
  type DataSpaceTemplateQueryCreatorPathParams,
29
30
  } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
30
31
  import { QueryEditor } from '../QueryEditor.js';
31
32
  import { guaranteeNonNullable } from '@finos/legend-shared';
33
+ import { useApplicationStore } from '@finos/legend-application';
34
+ import { extractQueryParams } from '../utils/QueryParameterUtils.js';
35
+ import { useEffect } from 'react';
32
36
 
33
37
  const DataSpaceTemplateQueryCreatorStoreProvider: React.FC<{
34
38
  children: React.ReactNode;
35
39
  gav: string;
36
40
  dataSpacePath: string;
37
41
  templateQueryId: string;
38
- }> = ({ children, gav, dataSpacePath, templateQueryId }) => {
42
+ params: Record<string, string> | undefined;
43
+ }> = ({ children, gav, dataSpacePath, templateQueryId, params }) => {
39
44
  const { groupId, artifactId, versionId } = parseGAVCoordinates(gav);
40
45
  const applicationStore = useLegendQueryApplicationStore();
41
46
  const baseStore = useLegendQueryBaseStore();
@@ -49,6 +54,7 @@ const DataSpaceTemplateQueryCreatorStoreProvider: React.FC<{
49
54
  versionId,
50
55
  dataSpacePath,
51
56
  templateQueryId,
57
+ params,
52
58
  ),
53
59
  );
54
60
  return (
@@ -59,6 +65,7 @@ const DataSpaceTemplateQueryCreatorStoreProvider: React.FC<{
59
65
  };
60
66
 
61
67
  export const DataSpaceTemplateQueryCreator = observer(() => {
68
+ const applicationStore = useApplicationStore();
62
69
  const parameters = useParams<DataSpaceTemplateQueryCreatorPathParams>();
63
70
  const gav = guaranteeNonNullable(
64
71
  parameters[DATA_SPACE_TEMPLATE_QUERY_CREATOR_ROUTE_PATTERN_TOKEN.GAV],
@@ -74,11 +81,31 @@ export const DataSpaceTemplateQueryCreator = observer(() => {
74
81
  ],
75
82
  );
76
83
 
84
+ const queryParams =
85
+ applicationStore.navigationService.navigator.getCurrentLocationParameters();
86
+ const processed = extractQueryParams(queryParams);
87
+
88
+ useEffect(() => {
89
+ // clear params
90
+ if (processed && Object.keys(processed).length) {
91
+ const { groupId, artifactId, versionId } = parseGAVCoordinates(gav);
92
+ applicationStore.navigationService.navigator.updateCurrentLocation(
93
+ generateDataSpaceTemplateQueryCreatorRoute(
94
+ groupId,
95
+ artifactId,
96
+ versionId,
97
+ dataSpacePath,
98
+ templateQueryId,
99
+ ),
100
+ );
101
+ }
102
+ }, [applicationStore, gav, dataSpacePath, templateQueryId, processed]);
77
103
  return (
78
104
  <DataSpaceTemplateQueryCreatorStoreProvider
79
105
  gav={gav}
80
106
  dataSpacePath={dataSpacePath}
81
107
  templateQueryId={templateQueryId}
108
+ params={processed}
82
109
  >
83
110
  <QueryEditor />
84
111
  </DataSpaceTemplateQueryCreatorStoreProvider>
@@ -0,0 +1,77 @@
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
+ import {
18
+ type GraphManagerState,
19
+ type QueryParameterValue,
20
+ type RawLambda,
21
+ buildLambdaVariableExpressions,
22
+ PrimitiveType,
23
+ VariableExpression,
24
+ } from '@finos/legend-graph';
25
+ import { filterByType, returnUndefOnError } from '@finos/legend-shared';
26
+
27
+ const QUERY_PARAM_SUFFIX = 'p:';
28
+
29
+ export const extractQueryParams = (
30
+ urlQuery: Record<string, string | undefined>,
31
+ ): Record<string, string> | undefined => {
32
+ const queryParamEntries = Array.from(Object.entries(urlQuery));
33
+ if (queryParamEntries.length) {
34
+ const paramValues: Record<string, string> = {};
35
+ queryParamEntries.forEach(([key, queryValue]) => {
36
+ if (queryValue && key.startsWith(QUERY_PARAM_SUFFIX)) {
37
+ paramValues[key.slice(QUERY_PARAM_SUFFIX.length)] = queryValue;
38
+ }
39
+ });
40
+ return Object.values(paramValues).length === 0 ? undefined : paramValues;
41
+ }
42
+
43
+ return undefined;
44
+ };
45
+
46
+ export const processQueryParameters = (
47
+ query: RawLambda,
48
+ savedQueryParams: QueryParameterValue[] | undefined,
49
+ urlParams: Record<string, string> | undefined,
50
+ graphManagerState: GraphManagerState,
51
+ ): Map<string, string> | undefined => {
52
+ const resolvedStringParams = new Map<string, string>();
53
+ savedQueryParams?.forEach((e) => {
54
+ resolvedStringParams.set(e.name, e.content);
55
+ });
56
+ // here we overwrite any params coming from the url
57
+ if (urlParams && Object.values(urlParams).length > 0) {
58
+ const compiledParams = returnUndefOnError(() =>
59
+ buildLambdaVariableExpressions(query, graphManagerState),
60
+ )?.filter(filterByType(VariableExpression));
61
+ Object.entries(urlParams).forEach(([key, value]) => {
62
+ const cP = compiledParams?.find((e) => e.name === key);
63
+ if (cP?.genericType?.value.rawType === PrimitiveType.STRING) {
64
+ resolvedStringParams.set(key, `'${value}'`);
65
+ } else if (
66
+ cP?.genericType?.value.rawType === PrimitiveType.DATE ||
67
+ cP?.genericType?.value.rawType === PrimitiveType.STRICTDATE ||
68
+ cP?.genericType?.value.rawType === PrimitiveType.DATETIME
69
+ ) {
70
+ resolvedStringParams.set(key, `%${value}`);
71
+ } else {
72
+ resolvedStringParams.set(key, value);
73
+ }
74
+ });
75
+ }
76
+ return resolvedStringParams.size > 0 ? resolvedStringParams : undefined;
77
+ };
@@ -68,9 +68,6 @@ import {
68
68
  cloneQueryStereotype,
69
69
  cloneQueryTaggedValue,
70
70
  QueryProjectCoordinates,
71
- buildLambdaVariableExpressions,
72
- VariableExpression,
73
- PrimitiveType,
74
71
  CORE_PURE_PATH,
75
72
  isValidFullPath,
76
73
  QUERY_PROFILE_PATH,
@@ -157,6 +154,7 @@ import {
157
154
  LakehouseContractServerClient,
158
155
  LakehouseEnvironmentType,
159
156
  } from '@finos/legend-server-lakehouse';
157
+ import { processQueryParameters } from '../components/utils/QueryParameterUtils.js';
160
158
 
161
159
  export interface QueryPersistConfiguration {
162
160
  defaultName?: string | undefined;
@@ -470,6 +468,11 @@ export abstract class QueryEditorStore {
470
468
  }
471
469
 
472
470
  abstract getProjectInfo(): ProjectGAVCoordinates | undefined;
471
+
472
+ getEditorRoute(): string | undefined {
473
+ return undefined;
474
+ }
475
+
473
476
  /**
474
477
  * Set up the editor state before building the graph
475
478
  */
@@ -1754,38 +1757,6 @@ const resolveExecutionContext = (
1754
1757
  return matchingExecContexts[0];
1755
1758
  };
1756
1759
 
1757
- const processQueryParams = (
1758
- query: RawLambda,
1759
- savedQueryParams: QueryParameterValue[] | undefined,
1760
- urlParams: Record<string, string> | undefined,
1761
- graphManagerState: GraphManagerState,
1762
- ): Map<string, string> | undefined => {
1763
- const resolvedStringParams = new Map<string, string>();
1764
- savedQueryParams?.forEach((e) => {
1765
- resolvedStringParams.set(e.name, e.content);
1766
- });
1767
- // here we overwrite any params coming from the url
1768
- if (urlParams && Object.values(urlParams).length > 0) {
1769
- const compiledParams = returnUndefOnError(() =>
1770
- buildLambdaVariableExpressions(query, graphManagerState),
1771
- )?.filter(filterByType(VariableExpression));
1772
- Object.entries(urlParams).forEach(([key, value]) => {
1773
- const cP = compiledParams?.find((e) => e.name === key);
1774
- if (cP?.genericType?.value.rawType === PrimitiveType.STRING) {
1775
- resolvedStringParams.set(key, `'${value}'`);
1776
- } else if (
1777
- cP?.genericType?.value.rawType === PrimitiveType.DATE ||
1778
- cP?.genericType?.value.rawType === PrimitiveType.DATETIME
1779
- ) {
1780
- resolvedStringParams.set(key, `%${value}`);
1781
- } else {
1782
- resolvedStringParams.set(key, value);
1783
- }
1784
- });
1785
- }
1786
- return resolvedStringParams.size > 0 ? resolvedStringParams : undefined;
1787
- };
1788
-
1789
1760
  export class ExistingQueryEditorStore extends QueryEditorStore {
1790
1761
  private queryId: string;
1791
1762
  private _lightQuery?: LightQuery | undefined;
@@ -1823,6 +1794,10 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
1823
1794
  return guaranteeNonNullable(this._lightQuery, `Query has not been loaded`);
1824
1795
  }
1825
1796
 
1797
+ override getEditorRoute(): string {
1798
+ return generateExistingQueryEditorRoute(this.queryId);
1799
+ }
1800
+
1826
1801
  override get isPerformingBlockingAction(): boolean {
1827
1802
  return (
1828
1803
  super.isPerformingBlockingAction ||
@@ -2178,7 +2153,7 @@ export class ExistingQueryEditorStore extends QueryEditorStore {
2178
2153
  // leverage initialization of query builder state to ensure we handle unsupported queries
2179
2154
  let defaultParameters: Map<string, ValueSpecification> | undefined =
2180
2155
  undefined;
2181
- const processedQueryParamValues = processQueryParams(
2156
+ const processedQueryParamValues = processQueryParameters(
2182
2157
  existingQueryLambda,
2183
2158
  query.defaultParameterValues,
2184
2159
  this.urlQueryParamValues,
@@ -18,12 +18,15 @@ import {
18
18
  type Query,
19
19
  type QuerySearchSpecification,
20
20
  type RawLambda,
21
+ type ValueSpecification,
21
22
  QueryProjectCoordinates,
22
23
  extractElementNameFromPath,
23
24
  } from '@finos/legend-graph';
24
25
  import { type DepotServerClient } from '@finos/legend-server-depot';
25
26
  import {
27
+ assertErrorThrown,
26
28
  IllegalStateError,
29
+ LogEvent,
27
30
  uuid,
28
31
  type GeneratorFn,
29
32
  } from '@finos/legend-shared';
@@ -41,6 +44,7 @@ import {
41
44
  QueryEditorStore,
42
45
  } from '../QueryEditorStore.js';
43
46
  import type { LegendQueryApplicationStore } from '../LegendQueryBaseStore.js';
47
+ import { generateDataSpaceTemplateQueryCreatorRoute } from '../../__lib__/DSL_DataSpace_LegendQueryNavigation.js';
44
48
  import {
45
49
  DataSpacePackageableElementExecutable,
46
50
  getDataSpace,
@@ -54,6 +58,8 @@ import {
54
58
  } from '@finos/legend-extension-dsl-data-space/application';
55
59
  import { LegendQueryDataSpaceQueryBuilderState } from './query-builder/LegendQueryDataSpaceQueryBuilderState.js';
56
60
  import { DataProductSelectorState } from './DataProductSelectorState.js';
61
+ import { processQueryParameters } from '../../components/utils/QueryParameterUtils.js';
62
+ import { LEGEND_QUERY_APP_EVENT } from '../../__lib__/LegendQueryEvent.js';
57
63
 
58
64
  export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
59
65
  readonly groupId: string;
@@ -62,6 +68,7 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
62
68
  readonly dataSpacePath: string;
63
69
  readonly templateQueryId: string;
64
70
  templateQueryTitle?: string;
71
+ urlQueryParamValues: Record<string, string> | undefined;
65
72
 
66
73
  constructor(
67
74
  applicationStore: LegendQueryApplicationStore,
@@ -71,6 +78,7 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
71
78
  versionId: string,
72
79
  dataSpacePath: string,
73
80
  templateQueryId: string,
81
+ urlQueryParamValues: Record<string, string> | undefined,
74
82
  ) {
75
83
  super(applicationStore, depotServerClient);
76
84
 
@@ -79,6 +87,7 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
79
87
  this.versionId = versionId;
80
88
  this.dataSpacePath = dataSpacePath;
81
89
  this.templateQueryId = templateQueryId;
90
+ this.urlQueryParamValues = urlQueryParamValues;
82
91
  }
83
92
 
84
93
  getProjectInfo(): ProjectGAVCoordinates {
@@ -89,6 +98,16 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
89
98
  };
90
99
  }
91
100
 
101
+ override getEditorRoute(): string {
102
+ return generateDataSpaceTemplateQueryCreatorRoute(
103
+ this.groupId,
104
+ this.artifactId,
105
+ this.versionId,
106
+ this.dataSpacePath,
107
+ this.templateQueryId,
108
+ );
109
+ }
110
+
92
111
  override *buildGraph(): GeneratorFn<void> {
93
112
  // do nothing
94
113
  }
@@ -212,7 +231,31 @@ export class DataSpaceTemplateQueryCreatorStore extends QueryEditorStore {
212
231
  );
213
232
  queryBuilderState.setExecutionContext(executionContext);
214
233
  await queryBuilderState.propagateExecutionContextChange(true);
215
- queryBuilderState.initializeWithQuery(query);
234
+
235
+ let defaultParameters: Map<string, ValueSpecification> | undefined =
236
+ undefined;
237
+ const processedQueryParamValues = processQueryParameters(
238
+ query,
239
+ undefined,
240
+ this.urlQueryParamValues,
241
+ this.graphManagerState,
242
+ );
243
+ if (processedQueryParamValues?.size) {
244
+ try {
245
+ defaultParameters =
246
+ await this.graphManagerState.graphManager.pureCodeToValueSpecifications(
247
+ processedQueryParamValues,
248
+ this.graphManagerState.graph,
249
+ );
250
+ } catch (error) {
251
+ assertErrorThrown(error);
252
+ this.applicationStore.logService.error(
253
+ LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
254
+ `Error resolving preset query param values: ${error.message}`,
255
+ );
256
+ }
257
+ }
258
+ queryBuilderState.initializeWithQuery(query, defaultParameters);
216
259
  return queryBuilderState;
217
260
  }
218
261
 
@@ -54,6 +54,7 @@ import {
54
54
  } from '@finos/legend-query-builder';
55
55
  import { renderLegendQueryDataSpaceQueryBuilderSetupPanelContent } from '../../../components/data-space/LegendQueryDataSpaceQueryBuilder.js';
56
56
  import type { LegendQueryApplicationStore } from '../../LegendQueryBaseStore.js';
57
+ import { QueryBuilderActionConfig_QueryApplication } from '../../QueryEditorStore.js';
57
58
  import {
58
59
  createViewProjectHandler,
59
60
  createViewSDLCProjectHandler,
@@ -162,23 +163,36 @@ export class LegendQueryDataSpaceQueryBuilderState extends DataSpaceQueryBuilder
162
163
  }
163
164
 
164
165
  override copyDataSpaceLinkToClipboard(): void {
165
- const dataSpace = this.dataSpace;
166
- const executionContext = this.executionContext;
167
- const runtimePath =
168
- this.executionContextState.runtimeValue instanceof RuntimePointer
169
- ? this.executionContextState.runtimeValue.packageableRuntime.value.path
166
+ const editorStore =
167
+ this.workflowState.actionConfig instanceof
168
+ QueryBuilderActionConfig_QueryApplication
169
+ ? this.workflowState.actionConfig.editorStore
170
170
  : undefined;
171
+ const editorRoute = editorStore?.getEditorRoute();
172
+ let routePath: string;
173
+ if (editorRoute) {
174
+ routePath = editorRoute;
175
+ } else {
176
+ const dataSpace = this.dataSpace;
177
+ const executionContext = this.executionContext;
178
+ const runtimePath =
179
+ this.executionContextState.runtimeValue instanceof RuntimePointer
180
+ ? this.executionContextState.runtimeValue.packageableRuntime.value
181
+ .path
182
+ : undefined;
183
+ routePath = generateDataSpaceQueryCreatorRoute(
184
+ this.project.groupId,
185
+ this.project.artifactId,
186
+ this.project.versionId,
187
+ dataSpace.path,
188
+ executionContext.name,
189
+ runtimePath,
190
+ this.class?.path,
191
+ );
192
+ }
171
193
  const route =
172
194
  this.applicationStore.navigationService.navigator.generateAddress(
173
- generateDataSpaceQueryCreatorRoute(
174
- this.project.groupId,
175
- this.project.artifactId,
176
- this.project.versionId,
177
- dataSpace.path,
178
- executionContext.name,
179
- runtimePath,
180
- this.class?.path,
181
- ),
195
+ routePath,
182
196
  );
183
197
 
184
198
  navigator.clipboard
package/tsconfig.json CHANGED
@@ -66,6 +66,7 @@
66
66
  "./src/application/LegendQueryPluginManager.ts",
67
67
  "./src/components/data-product/QueryDataProductUtil.ts",
68
68
  "./src/components/data-space/QueryDataSpaceUtil.ts",
69
+ "./src/components/utils/QueryParameterUtils.ts",
69
70
  "./src/stores/CloneServiceQuerySetupStore.ts",
70
71
  "./src/stores/CreateMappingQuerySetupStore.ts",
71
72
  "./src/stores/EditExistingQuerySetupStore.ts",