@finos/legend-application-query 8.1.2 → 9.0.0

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 (125) hide show
  1. package/lib/application/LegendQuery.d.ts.map +1 -1
  2. package/lib/application/LegendQuery.js +7 -9
  3. package/lib/application/LegendQuery.js.map +1 -1
  4. package/lib/application/LegendQueryApplicationConfig.d.ts +4 -0
  5. package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
  6. package/lib/application/LegendQueryApplicationConfig.js +4 -0
  7. package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
  8. package/lib/components/{QuerySetupStoreProvider.d.ts → CloneQueryServiceSetup.d.ts} +2 -7
  9. package/lib/components/CloneQueryServiceSetup.d.ts.map +1 -0
  10. package/lib/components/CloneQueryServiceSetup.js +137 -0
  11. package/lib/components/CloneQueryServiceSetup.js.map +1 -0
  12. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts +24 -0
  13. package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -0
  14. package/lib/components/Core_LegendQueryApplicationPlugin.js +144 -0
  15. package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -0
  16. package/lib/components/CreateMappingQuerySetup.d.ts +18 -0
  17. package/lib/components/CreateMappingQuerySetup.d.ts.map +1 -0
  18. package/lib/components/CreateMappingQuerySetup.js +160 -0
  19. package/lib/components/CreateMappingQuerySetup.js.map +1 -0
  20. package/lib/components/EditExistingQuerySetup.d.ts +18 -0
  21. package/lib/components/EditExistingQuerySetup.d.ts.map +1 -0
  22. package/lib/components/EditExistingQuerySetup.js +107 -0
  23. package/lib/components/EditExistingQuerySetup.js.map +1 -0
  24. package/lib/components/LegendQueryApplication.d.ts.map +1 -1
  25. package/lib/components/LegendQueryApplication.js +4 -2
  26. package/lib/components/LegendQueryApplication.js.map +1 -1
  27. package/lib/components/LoadProjectServiceQuerySetup.d.ts +18 -0
  28. package/lib/components/LoadProjectServiceQuerySetup.d.ts.map +1 -0
  29. package/lib/components/LoadProjectServiceQuerySetup.js +63 -0
  30. package/lib/components/LoadProjectServiceQuerySetup.js.map +1 -0
  31. package/lib/components/QueryEditor.d.ts.map +1 -1
  32. package/lib/components/QueryEditor.js +31 -33
  33. package/lib/components/QueryEditor.js.map +1 -1
  34. package/lib/components/QueryProductionizerSetup.d.ts +18 -0
  35. package/lib/components/QueryProductionizerSetup.d.ts.map +1 -0
  36. package/lib/components/QueryProductionizerSetup.js +85 -0
  37. package/lib/components/QueryProductionizerSetup.js.map +1 -0
  38. package/lib/components/QuerySetup.d.ts +20 -5
  39. package/lib/components/QuerySetup.d.ts.map +1 -1
  40. package/lib/components/QuerySetup.js +69 -473
  41. package/lib/components/QuerySetup.js.map +1 -1
  42. package/lib/components/UpdateExistingServiceQuerySetup.d.ts +18 -0
  43. package/lib/components/UpdateExistingServiceQuerySetup.d.ts.map +1 -0
  44. package/lib/components/UpdateExistingServiceQuerySetup.js +69 -0
  45. package/lib/components/UpdateExistingServiceQuerySetup.js.map +1 -0
  46. package/lib/index.css +2 -2
  47. package/lib/index.css.map +1 -1
  48. package/lib/index.d.ts +2 -3
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +2 -3
  51. package/lib/index.js.map +1 -1
  52. package/lib/package.json +5 -8
  53. package/lib/stores/CloneServiceQuerySetupStore.d.ts +41 -0
  54. package/lib/stores/CloneServiceQuerySetupStore.d.ts.map +1 -0
  55. package/lib/stores/CloneServiceQuerySetupStore.js +98 -0
  56. package/lib/stores/CloneServiceQuerySetupStore.js.map +1 -0
  57. package/lib/stores/CreateMappingQuerySetupStore.d.ts +40 -0
  58. package/lib/stores/CreateMappingQuerySetupStore.d.ts.map +1 -0
  59. package/lib/stores/CreateMappingQuerySetupStore.js +97 -0
  60. package/lib/stores/CreateMappingQuerySetupStore.js.map +1 -0
  61. package/lib/stores/EditExistingQuerySetupStore.d.ts +33 -0
  62. package/lib/stores/EditExistingQuerySetupStore.d.ts.map +1 -0
  63. package/lib/stores/EditExistingQuerySetupStore.js +85 -0
  64. package/lib/stores/EditExistingQuerySetupStore.js.map +1 -0
  65. package/lib/stores/LegendQueryApplicationPlugin.d.ts +21 -16
  66. package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
  67. package/lib/stores/LegendQueryApplicationPlugin.js +4 -0
  68. package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
  69. package/lib/stores/LegendQueryRouter.d.ts +28 -1
  70. package/lib/stores/LegendQueryRouter.d.ts.map +1 -1
  71. package/lib/stores/LegendQueryRouter.js +33 -3
  72. package/lib/stores/LegendQueryRouter.js.map +1 -1
  73. package/lib/stores/LoadProjectServiceQuerySetupStore.d.ts +27 -0
  74. package/lib/stores/LoadProjectServiceQuerySetupStore.d.ts.map +1 -0
  75. package/lib/stores/LoadProjectServiceQuerySetupStore.js +61 -0
  76. package/lib/stores/LoadProjectServiceQuerySetupStore.js.map +1 -0
  77. package/lib/stores/QueryEditorStore.d.ts +6 -2
  78. package/lib/stores/QueryEditorStore.d.ts.map +1 -1
  79. package/lib/stores/QueryEditorStore.js +35 -17
  80. package/lib/stores/QueryEditorStore.js.map +1 -1
  81. package/lib/stores/QueryEditorStoreTestUtils.d.ts.map +1 -1
  82. package/lib/stores/QueryEditorStoreTestUtils.js +3 -0
  83. package/lib/stores/QueryEditorStoreTestUtils.js.map +1 -1
  84. package/lib/stores/QueryProductionizerSetupStore.d.ts +32 -0
  85. package/lib/stores/QueryProductionizerSetupStore.d.ts.map +1 -0
  86. package/lib/stores/QueryProductionizerSetupStore.js +101 -0
  87. package/lib/stores/QueryProductionizerSetupStore.js.map +1 -0
  88. package/lib/stores/QuerySetupStore.d.ts +22 -85
  89. package/lib/stores/QuerySetupStore.d.ts.map +1 -1
  90. package/lib/stores/QuerySetupStore.js +78 -408
  91. package/lib/stores/QuerySetupStore.js.map +1 -1
  92. package/lib/stores/UpdateExistingServiceQuerySetupStore.d.ts +28 -0
  93. package/lib/stores/UpdateExistingServiceQuerySetupStore.d.ts.map +1 -0
  94. package/lib/stores/UpdateExistingServiceQuerySetupStore.js +73 -0
  95. package/lib/stores/UpdateExistingServiceQuerySetupStore.js.map +1 -0
  96. package/package.json +13 -16
  97. package/src/application/LegendQuery.tsx +7 -8
  98. package/src/application/LegendQueryApplicationConfig.ts +14 -0
  99. package/src/components/CloneQueryServiceSetup.tsx +312 -0
  100. package/src/components/Core_LegendQueryApplicationPlugin.tsx +184 -0
  101. package/src/components/CreateMappingQuerySetup.tsx +352 -0
  102. package/src/components/EditExistingQuerySetup.tsx +280 -0
  103. package/src/components/LegendQueryApplication.tsx +14 -2
  104. package/src/components/LoadProjectServiceQuerySetup.tsx +131 -0
  105. package/src/components/QueryEditor.tsx +127 -81
  106. package/src/components/QueryProductionizerSetup.tsx +206 -0
  107. package/src/components/QuerySetup.tsx +285 -1183
  108. package/src/components/UpdateExistingServiceQuerySetup.tsx +153 -0
  109. package/src/index.ts +3 -2
  110. package/src/stores/CloneServiceQuerySetupStore.ts +151 -0
  111. package/src/stores/CreateMappingQuerySetupStore.ts +155 -0
  112. package/src/stores/EditExistingQuerySetupStore.ts +111 -0
  113. package/src/stores/LegendQueryApplicationPlugin.ts +27 -27
  114. package/src/stores/LegendQueryRouter.ts +95 -12
  115. package/src/stores/LoadProjectServiceQuerySetupStore.ts +87 -0
  116. package/src/stores/QueryEditorStore.ts +90 -24
  117. package/src/stores/QueryEditorStoreTestUtils.ts +3 -0
  118. package/src/stores/QueryProductionizerSetupStore.ts +143 -0
  119. package/src/stores/QuerySetupStore.ts +111 -604
  120. package/src/stores/UpdateExistingServiceQuerySetupStore.ts +118 -0
  121. package/tsconfig.json +13 -1
  122. package/lib/components/QuerySetupStoreProvider.d.ts.map +0 -1
  123. package/lib/components/QuerySetupStoreProvider.js +0 -34
  124. package/lib/components/QuerySetupStoreProvider.js.map +0 -1
  125. package/src/components/QuerySetupStoreProvider.tsx +0 -56
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Copyright (c) 2020-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
+ ArrowLeftIcon,
19
+ CustomSelectorInput,
20
+ SearchIcon,
21
+ type SelectComponent,
22
+ } from '@finos/legend-art';
23
+ import { debounce, guaranteeType } from '@finos/legend-shared';
24
+ import { flowResult } from 'mobx';
25
+ import { observer, useLocalObservable } from 'mobx-react-lite';
26
+ import { useContext, useEffect, useMemo, useRef, useState } from 'react';
27
+ import { generateQuerySetupRoute } from '../stores/LegendQueryRouter.js';
28
+ import { useDepotServerClient } from '@finos/legend-server-depot';
29
+ import { useLegendQueryApplicationStore } from './LegendQueryBaseStoreProvider.js';
30
+ import { UpdateExistingServiceQuerySetupStore } from '../stores/UpdateExistingServiceQuerySetupStore.js';
31
+ import { BaseQuerySetup, BaseQuerySetupStoreContext } from './QuerySetup.js';
32
+ import {
33
+ buildServiceOption,
34
+ formatServiceOptionLabel,
35
+ type ServiceOption,
36
+ } from '@finos/legend-query-builder';
37
+
38
+ const UpdateExistingServiceQuerySetupStoreProvider: React.FC<{
39
+ children: React.ReactNode;
40
+ }> = ({ children }) => {
41
+ const applicationStore = useLegendQueryApplicationStore();
42
+ const depotServerClient = useDepotServerClient();
43
+ const store = useLocalObservable(
44
+ () =>
45
+ new UpdateExistingServiceQuerySetupStore(
46
+ applicationStore,
47
+ depotServerClient,
48
+ ),
49
+ );
50
+ return (
51
+ <BaseQuerySetupStoreContext.Provider value={store}>
52
+ {children}
53
+ </BaseQuerySetupStoreContext.Provider>
54
+ );
55
+ };
56
+
57
+ const useUpdateExistingServiceQuerySetupStore =
58
+ (): UpdateExistingServiceQuerySetupStore =>
59
+ guaranteeType(
60
+ useContext(BaseQuerySetupStoreContext),
61
+ UpdateExistingServiceQuerySetupStore,
62
+ `Can't find query setup store in context`,
63
+ );
64
+
65
+ const UpdateExistingServiceQuerySetupContent = observer(() => {
66
+ const applicationStore = useLegendQueryApplicationStore();
67
+ const setupStore = useUpdateExistingServiceQuerySetupStore();
68
+ const serviceSearchRef = useRef<SelectComponent>(null);
69
+ const [searchText, setSearchText] = useState('');
70
+
71
+ const back = (): void => {
72
+ applicationStore.navigator.goToLocation(generateQuerySetupRoute());
73
+ };
74
+
75
+ const serviceOptions = setupStore.services.map(buildServiceOption);
76
+ const onServiceOptionChange = (option: ServiceOption): void => {
77
+ setupStore
78
+ .loadServiceUpdater(option.value)
79
+ .catch(applicationStore.alertUnhandledError);
80
+ };
81
+
82
+ // search text
83
+ const debouncedLoadServices = useMemo(
84
+ () =>
85
+ debounce((input: string): void => {
86
+ flowResult(setupStore.loadServices(input)).catch(
87
+ applicationStore.alertUnhandledError,
88
+ );
89
+ }, 500),
90
+ [applicationStore, setupStore],
91
+ );
92
+ const onSearchTextChange = (value: string): void => {
93
+ if (value !== searchText) {
94
+ setSearchText(value);
95
+ debouncedLoadServices.cancel();
96
+ debouncedLoadServices(value);
97
+ }
98
+ };
99
+
100
+ useEffect(() => {
101
+ flowResult(setupStore.loadServices('')).catch(
102
+ applicationStore.alertUnhandledError,
103
+ );
104
+ }, [setupStore, applicationStore]);
105
+
106
+ useEffect(() => {
107
+ serviceSearchRef.current?.focus();
108
+ }, []);
109
+
110
+ return (
111
+ <div className="query-setup__wizard query-setup__existing-service-query">
112
+ <div className="query-setup__wizard__header query-setup__existing-service-query__header">
113
+ <button
114
+ className="query-setup__wizard__header__btn"
115
+ onClick={back}
116
+ title="Back to Main Menu"
117
+ >
118
+ <ArrowLeftIcon />
119
+ </button>
120
+ <div className="query-setup__wizard__header__title">
121
+ Updating an existing service query...
122
+ </div>
123
+ </div>
124
+ <div className="query-setup__wizard__content">
125
+ <div className="query-setup__wizard__group query-setup__wizard__group--inline query-setup__existing-service-query__search-bar">
126
+ <div className="query-setup__wizard__group__title">
127
+ <SearchIcon />
128
+ </div>
129
+ <CustomSelectorInput
130
+ ref={serviceSearchRef}
131
+ className="query-setup__wizard__selector"
132
+ options={serviceOptions}
133
+ isLoading={setupStore.loadServicesState.isInProgress}
134
+ onInputChange={onSearchTextChange}
135
+ inputValue={searchText}
136
+ onChange={onServiceOptionChange}
137
+ placeholder="Search for service..."
138
+ darkMode={true}
139
+ formatOptionLabel={formatServiceOptionLabel}
140
+ />
141
+ </div>
142
+ </div>
143
+ </div>
144
+ );
145
+ });
146
+
147
+ export const UpdateExistingServiceQuerySetup: React.FC = () => (
148
+ <UpdateExistingServiceQuerySetupStoreProvider>
149
+ <BaseQuerySetup>
150
+ <UpdateExistingServiceQuerySetupContent />
151
+ </BaseQuerySetup>
152
+ </UpdateExistingServiceQuerySetupStoreProvider>
153
+ );
package/src/index.ts CHANGED
@@ -22,16 +22,17 @@ export {
22
22
  QueryEditorStoreContext,
23
23
  useQueryEditorStore,
24
24
  } from './components/QueryEditorStoreProvider.js';
25
- export { useQuerySetupStore } from './components/QuerySetupStoreProvider.js';
26
25
  export { QueryEditor } from './components/QueryEditor.js';
27
26
 
28
27
  export { LegendQueryPluginManager } from './application/LegendQueryPluginManager.js';
29
28
 
30
29
  export * from './stores/LegendQueryApplicationPlugin.js';
31
30
  export * from './stores/LegendQueryRouter.js';
32
- export { QuerySetupState, QuerySetupStore } from './stores/QuerySetupStore.js';
31
+ export { BaseQuerySetupStore } from './stores/QuerySetupStore.js';
33
32
  export { LegendQueryApplicationConfig } from './application/LegendQueryApplicationConfig.js';
34
33
  export {
34
+ createViewProjectHandler,
35
+ createViewSDLCProjectHandler,
35
36
  QueryEditorStore,
36
37
  ExistingQueryEditorStore,
37
38
  type QueryExportConfiguration,
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Copyright (c) 2020-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
+ getQueryBuilderGraphManagerExtension,
19
+ type ServiceExecutionAnalysisResult,
20
+ } from '@finos/legend-query-builder';
21
+ import {
22
+ type DepotServerClient,
23
+ ProjectData,
24
+ } from '@finos/legend-server-depot';
25
+ import {
26
+ ActionState,
27
+ assertErrorThrown,
28
+ LogEvent,
29
+ type PlainObject,
30
+ type GeneratorFn,
31
+ } from '@finos/legend-shared';
32
+ import type { Entity } from '@finos/legend-storage';
33
+ import { action, flow, flowResult, makeObservable, observable } from 'mobx';
34
+ import { LEGEND_QUERY_APP_EVENT } from '../LegendQueryAppEvent.js';
35
+ import type { LegendQueryApplicationStore } from './LegendQueryBaseStore.js';
36
+ import { BaseQuerySetupStore } from './QuerySetupStore.js';
37
+ import type { Service } from '@finos/legend-graph';
38
+
39
+ export interface ServiceExecutionOption {
40
+ service: Service;
41
+ key?: string | undefined;
42
+ }
43
+
44
+ export class CloneServiceQuerySetupStore extends BaseQuerySetupStore {
45
+ projects: ProjectData[] = [];
46
+ loadProjectsState = ActionState.create();
47
+ loadServiceExecutionsState = ActionState.create();
48
+ currentProject?: ProjectData | undefined;
49
+ currentVersionId?: string | undefined;
50
+ currentServiceExecutionOption?: ServiceExecutionOption | undefined;
51
+ serviceExecutionOptions: ServiceExecutionOption[] = [];
52
+
53
+ constructor(
54
+ applicationStore: LegendQueryApplicationStore,
55
+ depotServerClient: DepotServerClient,
56
+ ) {
57
+ super(applicationStore, depotServerClient);
58
+
59
+ makeObservable(this, {
60
+ serviceExecutionOptions: observable,
61
+ projects: observable,
62
+ currentProject: observable,
63
+ currentVersionId: observable,
64
+ currentServiceExecutionOption: observable,
65
+ setCurrentProject: action,
66
+ setCurrentVersionId: action,
67
+ setCurrentServiceExecutionOption: action,
68
+ setServiceExecutionOptions: action,
69
+ loadProjects: flow,
70
+ loadServiceExecutionOptions: flow,
71
+ });
72
+ }
73
+
74
+ setCurrentProject(val: ProjectData | undefined): void {
75
+ this.currentProject = val;
76
+ }
77
+
78
+ setCurrentVersionId(val: string | undefined): void {
79
+ this.currentVersionId = val;
80
+ }
81
+
82
+ setCurrentServiceExecutionOption(
83
+ val: ServiceExecutionOption | undefined,
84
+ ): void {
85
+ this.currentServiceExecutionOption = val;
86
+ }
87
+
88
+ setServiceExecutionOptions(val: ServiceExecutionOption[]): void {
89
+ this.serviceExecutionOptions = val;
90
+ }
91
+
92
+ *loadProjects(): GeneratorFn<void> {
93
+ this.loadProjectsState.inProgress();
94
+ try {
95
+ this.projects = (
96
+ (yield this.depotServerClient.getProjects()) as PlainObject<ProjectData>[]
97
+ ).map((v) => ProjectData.serialization.fromJson(v));
98
+ this.loadProjectsState.pass();
99
+ } catch (error) {
100
+ assertErrorThrown(error);
101
+ this.applicationStore.notifyError(error);
102
+ this.loadProjectsState.fail();
103
+ }
104
+ }
105
+
106
+ *loadServiceExecutionOptions(
107
+ project: ProjectData,
108
+ versionId: string,
109
+ ): GeneratorFn<void> {
110
+ this.loadServiceExecutionsState.inProgress();
111
+ try {
112
+ // fetch entities and dependencies
113
+ const entities = (yield this.depotServerClient.getEntities(
114
+ project,
115
+ versionId,
116
+ )) as Entity[];
117
+ const dependencyEntitiesIndex = (yield flowResult(
118
+ this.depotServerClient.getIndexedDependencyEntities(project, versionId),
119
+ )) as Map<string, Entity[]>;
120
+
121
+ const serviceExecutionAnalysisResults = (yield flowResult(
122
+ getQueryBuilderGraphManagerExtension(
123
+ this.graphManagerState.graphManager,
124
+ ).surveyServiceExecution(entities, dependencyEntitiesIndex),
125
+ )) as ServiceExecutionAnalysisResult[];
126
+
127
+ this.setServiceExecutionOptions(
128
+ serviceExecutionAnalysisResults.flatMap((result) => {
129
+ if (result.executionKeys?.length) {
130
+ return result.executionKeys.map((key) => ({
131
+ service: result.service,
132
+ key,
133
+ }));
134
+ }
135
+ return {
136
+ service: result.service,
137
+ };
138
+ }),
139
+ );
140
+ this.loadServiceExecutionsState.pass();
141
+ } catch (error) {
142
+ assertErrorThrown(error);
143
+ this.applicationStore.log.error(
144
+ LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
145
+ error,
146
+ );
147
+ this.applicationStore.notifyError(error);
148
+ this.loadServiceExecutionsState.fail();
149
+ }
150
+ }
151
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Copyright (c) 2020-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 type { Mapping, PackageableRuntime } from '@finos/legend-graph';
18
+ import {
19
+ getQueryBuilderGraphManagerExtension,
20
+ type MappingRuntimeCompatibilityAnalysisResult,
21
+ } from '@finos/legend-query-builder';
22
+ import {
23
+ type DepotServerClient,
24
+ ProjectData,
25
+ } from '@finos/legend-server-depot';
26
+ import {
27
+ ActionState,
28
+ assertErrorThrown,
29
+ LogEvent,
30
+ type PlainObject,
31
+ type GeneratorFn,
32
+ } from '@finos/legend-shared';
33
+ import type { Entity } from '@finos/legend-storage';
34
+ import {
35
+ action,
36
+ computed,
37
+ flow,
38
+ flowResult,
39
+ makeObservable,
40
+ observable,
41
+ } from 'mobx';
42
+ import { LEGEND_QUERY_APP_EVENT } from '../LegendQueryAppEvent.js';
43
+ import type { LegendQueryApplicationStore } from './LegendQueryBaseStore.js';
44
+ import { BaseQuerySetupStore } from './QuerySetupStore.js';
45
+
46
+ export class CreateMappingQuerySetupStore extends BaseQuerySetupStore {
47
+ readonly loadProjectsState = ActionState.create();
48
+ readonly surveyMappingRuntimeCompatibilityState = ActionState.create();
49
+
50
+ projects: ProjectData[] = [];
51
+ currentProject?: ProjectData | undefined;
52
+ currentVersionId?: string | undefined;
53
+ currentMapping?: Mapping | undefined;
54
+ currentRuntime?: PackageableRuntime | undefined;
55
+ mappingRuntimeCompatibilitySurveyResult: MappingRuntimeCompatibilityAnalysisResult[] =
56
+ [];
57
+
58
+ constructor(
59
+ applicationStore: LegendQueryApplicationStore,
60
+ depotServerClient: DepotServerClient,
61
+ ) {
62
+ super(applicationStore, depotServerClient);
63
+
64
+ makeObservable(this, {
65
+ projects: observable,
66
+ currentProject: observable,
67
+ currentVersionId: observable,
68
+ currentMapping: observable,
69
+ currentRuntime: observable,
70
+ mappingRuntimeCompatibilitySurveyResult: observable,
71
+ compatibleRuntimes: computed,
72
+ setCurrentProject: action,
73
+ setCurrentVersionId: action,
74
+ setCurrentMapping: action,
75
+ setCurrentRuntime: action,
76
+ loadProjects: flow,
77
+ surveyMappingRuntimeCompatibility: flow,
78
+ });
79
+ }
80
+
81
+ setCurrentProject(val: ProjectData | undefined): void {
82
+ this.currentProject = val;
83
+ }
84
+
85
+ setCurrentVersionId(val: string | undefined): void {
86
+ this.currentVersionId = val;
87
+ }
88
+
89
+ setCurrentMapping(val: Mapping | undefined): void {
90
+ this.currentMapping = val;
91
+ }
92
+
93
+ setCurrentRuntime(val: PackageableRuntime | undefined): void {
94
+ this.currentRuntime = val;
95
+ }
96
+
97
+ get compatibleRuntimes(): PackageableRuntime[] {
98
+ const currentMapping = this.currentMapping;
99
+ if (!currentMapping) {
100
+ return [];
101
+ }
102
+ return (
103
+ this.mappingRuntimeCompatibilitySurveyResult.find(
104
+ (result) => result.mapping === currentMapping,
105
+ )?.runtimes ?? []
106
+ );
107
+ }
108
+
109
+ *loadProjects(): GeneratorFn<void> {
110
+ this.loadProjectsState.inProgress();
111
+ try {
112
+ this.projects = (
113
+ (yield this.depotServerClient.getProjects()) as PlainObject<ProjectData>[]
114
+ ).map((v) => ProjectData.serialization.fromJson(v));
115
+ this.loadProjectsState.pass();
116
+ } catch (error) {
117
+ assertErrorThrown(error);
118
+ this.applicationStore.notifyError(error);
119
+ this.loadProjectsState.fail();
120
+ }
121
+ }
122
+
123
+ *surveyMappingRuntimeCompatibility(
124
+ project: ProjectData,
125
+ versionId: string,
126
+ ): GeneratorFn<void> {
127
+ this.surveyMappingRuntimeCompatibilityState.inProgress();
128
+ try {
129
+ // fetch entities and dependencies
130
+ const entities = (yield this.depotServerClient.getEntities(
131
+ project,
132
+ versionId,
133
+ )) as Entity[];
134
+ const dependencyEntitiesIndex = (yield flowResult(
135
+ this.depotServerClient.getIndexedDependencyEntities(project, versionId),
136
+ )) as Map<string, Entity[]>;
137
+
138
+ this.mappingRuntimeCompatibilitySurveyResult = (yield flowResult(
139
+ getQueryBuilderGraphManagerExtension(
140
+ this.graphManagerState.graphManager,
141
+ ).surveyMappingRuntimeCompatibility(entities, dependencyEntitiesIndex),
142
+ )) as MappingRuntimeCompatibilityAnalysisResult[];
143
+
144
+ this.surveyMappingRuntimeCompatibilityState.pass();
145
+ } catch (error) {
146
+ assertErrorThrown(error);
147
+ this.applicationStore.log.error(
148
+ LogEvent.create(LEGEND_QUERY_APP_EVENT.GENERIC_FAILURE),
149
+ error,
150
+ );
151
+ this.applicationStore.notifyError(error);
152
+ this.surveyMappingRuntimeCompatibilityState.fail();
153
+ }
154
+ }
155
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copyright (c) 2020-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
+ DEFAULT_TYPEAHEAD_SEARCH_LIMIT,
19
+ DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH,
20
+ } from '@finos/legend-application';
21
+ import {
22
+ QuerySearchSpecification,
23
+ type LightQuery,
24
+ type QueryInfo,
25
+ } from '@finos/legend-graph';
26
+ import type { DepotServerClient } from '@finos/legend-server-depot';
27
+ import {
28
+ ActionState,
29
+ assertErrorThrown,
30
+ type GeneratorFn,
31
+ } from '@finos/legend-shared';
32
+ import { action, flow, makeObservable, observable } from 'mobx';
33
+ import type { LegendQueryApplicationStore } from './LegendQueryBaseStore.js';
34
+ import { BaseQuerySetupStore } from './QuerySetupStore.js';
35
+
36
+ export class EditExistingQuerySetupStore extends BaseQuerySetupStore {
37
+ readonly loadQueriesState = ActionState.create();
38
+ readonly loadQueryState = ActionState.create();
39
+
40
+ queries: LightQuery[] = [];
41
+ currentQuery?: LightQuery | undefined;
42
+ currentQueryInfo?: QueryInfo | undefined;
43
+ showCurrentUserQueriesOnly = false;
44
+
45
+ constructor(
46
+ applicationStore: LegendQueryApplicationStore,
47
+ depotServerClient: DepotServerClient,
48
+ ) {
49
+ super(applicationStore, depotServerClient);
50
+
51
+ makeObservable(this, {
52
+ queries: observable,
53
+ currentQuery: observable,
54
+ currentQueryInfo: observable,
55
+ showCurrentUserQueriesOnly: observable,
56
+ setShowCurrentUserQueriesOnly: action,
57
+ setCurrentQuery: flow,
58
+ loadQueries: flow,
59
+ });
60
+ }
61
+
62
+ setShowCurrentUserQueriesOnly(val: boolean): void {
63
+ this.showCurrentUserQueriesOnly = val;
64
+ }
65
+
66
+ *setCurrentQuery(queryId: string | undefined): GeneratorFn<void> {
67
+ if (queryId) {
68
+ try {
69
+ this.loadQueryState.inProgress();
70
+ this.currentQuery =
71
+ (yield this.graphManagerState.graphManager.getLightQuery(
72
+ queryId,
73
+ )) as LightQuery;
74
+ this.currentQueryInfo =
75
+ (yield this.graphManagerState.graphManager.getQueryInfo(
76
+ queryId,
77
+ )) as QueryInfo;
78
+ } catch (error) {
79
+ assertErrorThrown(error);
80
+ this.applicationStore.notifyError(error);
81
+ } finally {
82
+ this.loadQueryState.reset();
83
+ }
84
+ } else {
85
+ this.currentQuery = undefined;
86
+ }
87
+ }
88
+
89
+ *loadQueries(searchText: string): GeneratorFn<void> {
90
+ const isValidSearchString =
91
+ searchText.length >= DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH;
92
+ this.loadQueriesState.inProgress();
93
+ try {
94
+ const searchSpecification = new QuerySearchSpecification();
95
+ searchSpecification.searchTerm = isValidSearchString
96
+ ? searchText
97
+ : undefined;
98
+ searchSpecification.limit = DEFAULT_TYPEAHEAD_SEARCH_LIMIT;
99
+ searchSpecification.showCurrentUserQueriesOnly =
100
+ this.showCurrentUserQueriesOnly;
101
+ this.queries = (yield this.graphManagerState.graphManager.searchQueries(
102
+ searchSpecification,
103
+ )) as LightQuery[];
104
+ this.loadQueriesState.pass();
105
+ } catch (error) {
106
+ assertErrorThrown(error);
107
+ this.applicationStore.notifyError(error);
108
+ this.loadQueriesState.fail();
109
+ }
110
+ }
111
+ }
@@ -19,25 +19,35 @@ import type { Query } from '@finos/legend-graph';
19
19
  import type { QueryBuilderState } from '@finos/legend-query-builder';
20
20
  import type React from 'react';
21
21
  import type { LegendQueryPluginManager } from '../application/LegendQueryPluginManager.js';
22
- import type {
23
- ExistingQueryEditorStore,
24
- QueryEditorStore,
25
- } from './QueryEditorStore.js';
26
- import type { QuerySetupState, QuerySetupStore } from './QuerySetupStore.js';
22
+ import type { ExistingQueryEditorStore } from './QueryEditorStore.js';
23
+ import type { QuerySetupLandingPageStore } from './QuerySetupStore.js';
27
24
 
28
- export type QuerySetupOptionRendererConfiguration = {
25
+ export enum QuerySetupActionTag {
26
+ PRODUCTIONIZATION = 'Productionization',
27
+ }
28
+
29
+ export type QuerySetupActionConfiguration = {
29
30
  key: string;
30
- renderer: (setupStore: QuerySetupStore) => React.ReactNode | undefined;
31
+ isCreateAction: boolean;
32
+ isAdvanced: boolean;
33
+ /**
34
+ * NOTE: we could potentially support multiple tags, but for simplicity
35
+ * we will only limit this to one
36
+ *
37
+ * If no tag is provided, the action will be classified into the default group
38
+ */
39
+ tag?: string;
40
+ // NOTE: we could have an advanced option for rendering, i.e. specifying the
41
+ // component for the button, this gives a lot of flexibility and could facilitate
42
+ // powerful interaction like click to open modal dialog, etc., but this allows
43
+ // too much customization, so we will not have that for now
44
+ //
45
+ label: string;
46
+ icon: React.ReactNode;
47
+ className?: string | undefined;
48
+ action: (setupStore: QuerySetupLandingPageStore) => Promise<void>;
31
49
  };
32
50
 
33
- export type QuerySetupRenderer = (
34
- setupState: QuerySetupState,
35
- ) => React.ReactNode | undefined;
36
-
37
- export type QueryEditorHeaderLabeler = (
38
- editorStore: QueryEditorStore,
39
- ) => React.ReactNode | undefined;
40
-
41
51
  export type ExistingQueryEditorStateBuilder = (
42
52
  query: Query,
43
53
  editorStore: ExistingQueryEditorStore,
@@ -63,19 +73,9 @@ export abstract class LegendQueryApplicationPlugin extends LegendApplicationPlug
63
73
  }
64
74
 
65
75
  /**
66
- * Get the list of renderer configurations for the query setup option.
67
- */
68
- getExtraQuerySetupOptionRendererConfigurations?(): QuerySetupOptionRendererConfiguration[];
69
-
70
- /**
71
- * Get the list of renderers for query setup.
72
- */
73
- getExtraQuerySetupRenderers?(): QuerySetupRenderer[];
74
-
75
- /**
76
- * Get the list of query editor header labelers.
76
+ * Get the list of actions (configurations) for query setup.
77
77
  */
78
- getExtraQueryEditorHeaderLabelers?(): QueryEditorHeaderLabeler[];
78
+ getExtraQuerySetupActionConfigurations?(): QuerySetupActionConfiguration[];
79
79
 
80
80
  /**
81
81
  * Get the list of existing query editor state builders.