@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.
- package/lib/application/LegendQuery.d.ts.map +1 -1
- package/lib/application/LegendQuery.js +7 -9
- package/lib/application/LegendQuery.js.map +1 -1
- package/lib/application/LegendQueryApplicationConfig.d.ts +4 -0
- package/lib/application/LegendQueryApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendQueryApplicationConfig.js +4 -0
- package/lib/application/LegendQueryApplicationConfig.js.map +1 -1
- package/lib/components/{QuerySetupStoreProvider.d.ts → CloneQueryServiceSetup.d.ts} +2 -7
- package/lib/components/CloneQueryServiceSetup.d.ts.map +1 -0
- package/lib/components/CloneQueryServiceSetup.js +137 -0
- package/lib/components/CloneQueryServiceSetup.js.map +1 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.d.ts +24 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.d.ts.map +1 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.js +144 -0
- package/lib/components/Core_LegendQueryApplicationPlugin.js.map +1 -0
- package/lib/components/CreateMappingQuerySetup.d.ts +18 -0
- package/lib/components/CreateMappingQuerySetup.d.ts.map +1 -0
- package/lib/components/CreateMappingQuerySetup.js +160 -0
- package/lib/components/CreateMappingQuerySetup.js.map +1 -0
- package/lib/components/EditExistingQuerySetup.d.ts +18 -0
- package/lib/components/EditExistingQuerySetup.d.ts.map +1 -0
- package/lib/components/EditExistingQuerySetup.js +107 -0
- package/lib/components/EditExistingQuerySetup.js.map +1 -0
- package/lib/components/LegendQueryApplication.d.ts.map +1 -1
- package/lib/components/LegendQueryApplication.js +4 -2
- package/lib/components/LegendQueryApplication.js.map +1 -1
- package/lib/components/LoadProjectServiceQuerySetup.d.ts +18 -0
- package/lib/components/LoadProjectServiceQuerySetup.d.ts.map +1 -0
- package/lib/components/LoadProjectServiceQuerySetup.js +63 -0
- package/lib/components/LoadProjectServiceQuerySetup.js.map +1 -0
- package/lib/components/QueryEditor.d.ts.map +1 -1
- package/lib/components/QueryEditor.js +31 -33
- package/lib/components/QueryEditor.js.map +1 -1
- package/lib/components/QueryProductionizerSetup.d.ts +18 -0
- package/lib/components/QueryProductionizerSetup.d.ts.map +1 -0
- package/lib/components/QueryProductionizerSetup.js +85 -0
- package/lib/components/QueryProductionizerSetup.js.map +1 -0
- package/lib/components/QuerySetup.d.ts +20 -5
- package/lib/components/QuerySetup.d.ts.map +1 -1
- package/lib/components/QuerySetup.js +69 -473
- package/lib/components/QuerySetup.js.map +1 -1
- package/lib/components/UpdateExistingServiceQuerySetup.d.ts +18 -0
- package/lib/components/UpdateExistingServiceQuerySetup.d.ts.map +1 -0
- package/lib/components/UpdateExistingServiceQuerySetup.js +69 -0
- package/lib/components/UpdateExistingServiceQuerySetup.js.map +1 -0
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +2 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -3
- package/lib/index.js.map +1 -1
- package/lib/package.json +5 -8
- package/lib/stores/CloneServiceQuerySetupStore.d.ts +41 -0
- package/lib/stores/CloneServiceQuerySetupStore.d.ts.map +1 -0
- package/lib/stores/CloneServiceQuerySetupStore.js +98 -0
- package/lib/stores/CloneServiceQuerySetupStore.js.map +1 -0
- package/lib/stores/CreateMappingQuerySetupStore.d.ts +40 -0
- package/lib/stores/CreateMappingQuerySetupStore.d.ts.map +1 -0
- package/lib/stores/CreateMappingQuerySetupStore.js +97 -0
- package/lib/stores/CreateMappingQuerySetupStore.js.map +1 -0
- package/lib/stores/EditExistingQuerySetupStore.d.ts +33 -0
- package/lib/stores/EditExistingQuerySetupStore.d.ts.map +1 -0
- package/lib/stores/EditExistingQuerySetupStore.js +85 -0
- package/lib/stores/EditExistingQuerySetupStore.js.map +1 -0
- package/lib/stores/LegendQueryApplicationPlugin.d.ts +21 -16
- package/lib/stores/LegendQueryApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/LegendQueryApplicationPlugin.js +4 -0
- package/lib/stores/LegendQueryApplicationPlugin.js.map +1 -1
- package/lib/stores/LegendQueryRouter.d.ts +28 -1
- package/lib/stores/LegendQueryRouter.d.ts.map +1 -1
- package/lib/stores/LegendQueryRouter.js +33 -3
- package/lib/stores/LegendQueryRouter.js.map +1 -1
- package/lib/stores/LoadProjectServiceQuerySetupStore.d.ts +27 -0
- package/lib/stores/LoadProjectServiceQuerySetupStore.d.ts.map +1 -0
- package/lib/stores/LoadProjectServiceQuerySetupStore.js +61 -0
- package/lib/stores/LoadProjectServiceQuerySetupStore.js.map +1 -0
- package/lib/stores/QueryEditorStore.d.ts +6 -2
- package/lib/stores/QueryEditorStore.d.ts.map +1 -1
- package/lib/stores/QueryEditorStore.js +35 -17
- package/lib/stores/QueryEditorStore.js.map +1 -1
- package/lib/stores/QueryEditorStoreTestUtils.d.ts.map +1 -1
- package/lib/stores/QueryEditorStoreTestUtils.js +3 -0
- package/lib/stores/QueryEditorStoreTestUtils.js.map +1 -1
- package/lib/stores/QueryProductionizerSetupStore.d.ts +32 -0
- package/lib/stores/QueryProductionizerSetupStore.d.ts.map +1 -0
- package/lib/stores/QueryProductionizerSetupStore.js +101 -0
- package/lib/stores/QueryProductionizerSetupStore.js.map +1 -0
- package/lib/stores/QuerySetupStore.d.ts +22 -85
- package/lib/stores/QuerySetupStore.d.ts.map +1 -1
- package/lib/stores/QuerySetupStore.js +78 -408
- package/lib/stores/QuerySetupStore.js.map +1 -1
- package/lib/stores/UpdateExistingServiceQuerySetupStore.d.ts +28 -0
- package/lib/stores/UpdateExistingServiceQuerySetupStore.d.ts.map +1 -0
- package/lib/stores/UpdateExistingServiceQuerySetupStore.js +73 -0
- package/lib/stores/UpdateExistingServiceQuerySetupStore.js.map +1 -0
- package/package.json +13 -16
- package/src/application/LegendQuery.tsx +7 -8
- package/src/application/LegendQueryApplicationConfig.ts +14 -0
- package/src/components/CloneQueryServiceSetup.tsx +312 -0
- package/src/components/Core_LegendQueryApplicationPlugin.tsx +184 -0
- package/src/components/CreateMappingQuerySetup.tsx +352 -0
- package/src/components/EditExistingQuerySetup.tsx +280 -0
- package/src/components/LegendQueryApplication.tsx +14 -2
- package/src/components/LoadProjectServiceQuerySetup.tsx +131 -0
- package/src/components/QueryEditor.tsx +127 -81
- package/src/components/QueryProductionizerSetup.tsx +206 -0
- package/src/components/QuerySetup.tsx +285 -1183
- package/src/components/UpdateExistingServiceQuerySetup.tsx +153 -0
- package/src/index.ts +3 -2
- package/src/stores/CloneServiceQuerySetupStore.ts +151 -0
- package/src/stores/CreateMappingQuerySetupStore.ts +155 -0
- package/src/stores/EditExistingQuerySetupStore.ts +111 -0
- package/src/stores/LegendQueryApplicationPlugin.ts +27 -27
- package/src/stores/LegendQueryRouter.ts +95 -12
- package/src/stores/LoadProjectServiceQuerySetupStore.ts +87 -0
- package/src/stores/QueryEditorStore.ts +90 -24
- package/src/stores/QueryEditorStoreTestUtils.ts +3 -0
- package/src/stores/QueryProductionizerSetupStore.ts +143 -0
- package/src/stores/QuerySetupStore.ts +111 -604
- package/src/stores/UpdateExistingServiceQuerySetupStore.ts +118 -0
- package/tsconfig.json +13 -1
- package/lib/components/QuerySetupStoreProvider.d.ts.map +0 -1
- package/lib/components/QuerySetupStoreProvider.js +0 -34
- package/lib/components/QuerySetupStoreProvider.js.map +0 -1
- package/src/components/QuerySetupStoreProvider.tsx +0 -56
@@ -0,0 +1,131 @@
|
|
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 { ArrowLeftIcon, CustomSelectorInput } from '@finos/legend-art';
|
18
|
+
import { guaranteeType } from '@finos/legend-shared';
|
19
|
+
import { flowResult } from 'mobx';
|
20
|
+
import { observer, useLocalObservable } from 'mobx-react-lite';
|
21
|
+
import { useContext, useEffect } from 'react';
|
22
|
+
import { generateQuerySetupRoute } from '../stores/LegendQueryRouter.js';
|
23
|
+
import { useDepotServerClient } from '@finos/legend-server-depot';
|
24
|
+
import { useLegendQueryApplicationStore } from './LegendQueryBaseStoreProvider.js';
|
25
|
+
import { LoadProjectServiceQuerySetupStore } from '../stores/LoadProjectServiceQuerySetupStore.js';
|
26
|
+
import {
|
27
|
+
BaseQuerySetup,
|
28
|
+
BaseQuerySetupStoreContext,
|
29
|
+
buildProjectOption,
|
30
|
+
type ProjectOption,
|
31
|
+
} from './QuerySetup.js';
|
32
|
+
import {} from '@finos/legend-query-builder';
|
33
|
+
import { useApplicationStore } from '@finos/legend-application';
|
34
|
+
|
35
|
+
const LoadProjectServiceQuerySetupStoreProvider: React.FC<{
|
36
|
+
children: React.ReactNode;
|
37
|
+
}> = ({ children }) => {
|
38
|
+
const applicationStore = useLegendQueryApplicationStore();
|
39
|
+
const depotServerClient = useDepotServerClient();
|
40
|
+
const store = useLocalObservable(
|
41
|
+
() =>
|
42
|
+
new LoadProjectServiceQuerySetupStore(
|
43
|
+
applicationStore,
|
44
|
+
depotServerClient,
|
45
|
+
),
|
46
|
+
);
|
47
|
+
return (
|
48
|
+
<BaseQuerySetupStoreContext.Provider value={store}>
|
49
|
+
{children}
|
50
|
+
</BaseQuerySetupStoreContext.Provider>
|
51
|
+
);
|
52
|
+
};
|
53
|
+
|
54
|
+
const useLoadProjectServiceQuerySetupStore =
|
55
|
+
(): LoadProjectServiceQuerySetupStore =>
|
56
|
+
guaranteeType(
|
57
|
+
useContext(BaseQuerySetupStoreContext),
|
58
|
+
LoadProjectServiceQuerySetupStore,
|
59
|
+
`Can't find query setup store in context`,
|
60
|
+
);
|
61
|
+
|
62
|
+
const LoadProjectServiceQuerySetupContent = observer(() => {
|
63
|
+
const applicationStore = useApplicationStore();
|
64
|
+
const setupStore = useLoadProjectServiceQuerySetupStore();
|
65
|
+
|
66
|
+
const back = (): void => {
|
67
|
+
applicationStore.navigator.goToLocation(generateQuerySetupRoute());
|
68
|
+
};
|
69
|
+
|
70
|
+
// project
|
71
|
+
const projectOptions = setupStore.projects.map(buildProjectOption);
|
72
|
+
const projectSelectorPlaceholder = setupStore.loadProjectsState.isInProgress
|
73
|
+
? 'Loading projects'
|
74
|
+
: setupStore.loadProjectsState.hasFailed
|
75
|
+
? 'Error fetching projects'
|
76
|
+
: setupStore.projects.length
|
77
|
+
? 'Choose a project'
|
78
|
+
: 'You have no projects, please create or acquire access for at least one';
|
79
|
+
const onProjectOptionChange = (option: ProjectOption): void => {
|
80
|
+
setupStore
|
81
|
+
.loadProjectServiceUpdater(option.value)
|
82
|
+
.catch(applicationStore.alertUnhandledError);
|
83
|
+
};
|
84
|
+
|
85
|
+
useEffect(() => {
|
86
|
+
flowResult(setupStore.loadProjects()).catch(
|
87
|
+
applicationStore.alertUnhandledError,
|
88
|
+
);
|
89
|
+
}, [setupStore, applicationStore]);
|
90
|
+
|
91
|
+
return (
|
92
|
+
<div className="query-setup__wizard query-setup__existing-service-query">
|
93
|
+
<div className="query-setup__wizard__header query-setup__service-query__header">
|
94
|
+
<button
|
95
|
+
className="query-setup__wizard__header__btn"
|
96
|
+
onClick={back}
|
97
|
+
title="Back to Main Menu"
|
98
|
+
>
|
99
|
+
<ArrowLeftIcon />
|
100
|
+
</button>
|
101
|
+
<div className="query-setup__wizard__header__title">
|
102
|
+
Load service query from a project...
|
103
|
+
</div>
|
104
|
+
</div>
|
105
|
+
<div className="query-setup__wizard__content">
|
106
|
+
<div className="query-setup__wizard__group query-setup__wizard__group--inline query-setup__existing-service-query__search-bar">
|
107
|
+
<CustomSelectorInput
|
108
|
+
className="query-setup__wizard__selector"
|
109
|
+
options={projectOptions}
|
110
|
+
disabled={
|
111
|
+
setupStore.loadProjectsState.isInProgress ||
|
112
|
+
!projectOptions.length
|
113
|
+
}
|
114
|
+
isLoading={setupStore.loadProjectsState.isInProgress}
|
115
|
+
onChange={onProjectOptionChange}
|
116
|
+
placeholder={projectSelectorPlaceholder}
|
117
|
+
darkMode={true}
|
118
|
+
/>
|
119
|
+
</div>
|
120
|
+
</div>
|
121
|
+
</div>
|
122
|
+
);
|
123
|
+
});
|
124
|
+
|
125
|
+
export const LoadProjectServiceQuerySetup: React.FC = () => (
|
126
|
+
<LoadProjectServiceQuerySetupStoreProvider>
|
127
|
+
<BaseQuerySetup>
|
128
|
+
<LoadProjectServiceQuerySetupContent />
|
129
|
+
</BaseQuerySetup>
|
130
|
+
</LoadProjectServiceQuerySetupStoreProvider>
|
131
|
+
);
|
@@ -17,10 +17,8 @@
|
|
17
17
|
import {
|
18
18
|
type SelectComponent,
|
19
19
|
Dialog,
|
20
|
-
ArrowLeftIcon,
|
21
20
|
ExternalLinkSquareIcon,
|
22
21
|
PanelLoadingIndicator,
|
23
|
-
RobotIcon,
|
24
22
|
SaveIcon,
|
25
23
|
BlankPanelContent,
|
26
24
|
clsx,
|
@@ -31,6 +29,15 @@ import {
|
|
31
29
|
CheckSquareIcon,
|
32
30
|
SquareIcon,
|
33
31
|
ManageSearchIcon,
|
32
|
+
DropdownMenu,
|
33
|
+
MenuContent,
|
34
|
+
MenuContentItem,
|
35
|
+
CaretDownIcon,
|
36
|
+
MenuIcon,
|
37
|
+
MenuContentDivider,
|
38
|
+
MenuContentItemIcon,
|
39
|
+
CheckIcon,
|
40
|
+
MenuContentItemLabel,
|
34
41
|
} from '@finos/legend-art';
|
35
42
|
import { debounce, getQueryParameters } from '@finos/legend-shared';
|
36
43
|
import { observer } from 'mobx-react-lite';
|
@@ -40,18 +47,17 @@ import {
|
|
40
47
|
type ExistingQueryEditorPathParams,
|
41
48
|
type ServiceQueryCreatorPathParams,
|
42
49
|
type ServiceQueryCreatorQueryParams,
|
43
|
-
LEGEND_QUERY_ROUTE_PATTERN,
|
44
50
|
LEGEND_QUERY_QUERY_PARAM_TOKEN,
|
45
51
|
LEGEND_QUERY_PATH_PARAM_TOKEN,
|
46
|
-
EXTERNAL_APPLICATION_NAVIGATION__generateStudioProjectViewUrl,
|
47
52
|
generateExistingQueryEditorRoute,
|
53
|
+
generateQuerySetupRoute,
|
48
54
|
} from '../stores/LegendQueryRouter.js';
|
49
55
|
import {
|
50
56
|
type QueryEditorStore,
|
51
|
-
MappingQueryCreatorStore,
|
52
57
|
ExistingQueryEditorStore,
|
53
58
|
QueryExportState,
|
54
|
-
|
59
|
+
createViewProjectHandler,
|
60
|
+
createViewSDLCProjectHandler,
|
55
61
|
} from '../stores/QueryEditorStore.js';
|
56
62
|
import { useApplicationStore, useParams } from '@finos/legend-application';
|
57
63
|
import {
|
@@ -60,14 +66,12 @@ import {
|
|
60
66
|
ServiceQueryCreatorStoreProvider,
|
61
67
|
useQueryEditorStore,
|
62
68
|
} from './QueryEditorStoreProvider.js';
|
63
|
-
import {
|
64
|
-
type RawLambda,
|
65
|
-
extractElementNameFromPath,
|
66
|
-
} from '@finos/legend-graph';
|
69
|
+
import type { RawLambda } from '@finos/legend-graph';
|
67
70
|
import { flowResult } from 'mobx';
|
68
71
|
import { useLegendQueryApplicationStore } from './LegendQueryBaseStoreProvider.js';
|
69
72
|
import {
|
70
73
|
QueryBuilder,
|
74
|
+
QueryBuilderNavigationBlocker,
|
71
75
|
type QueryBuilderState,
|
72
76
|
} from '@finos/legend-query-builder';
|
73
77
|
|
@@ -156,46 +160,6 @@ const QueryExport = observer(() => {
|
|
156
160
|
);
|
157
161
|
});
|
158
162
|
|
159
|
-
const renderQueryEditorHeaderLabel = (
|
160
|
-
editorStore: QueryEditorStore,
|
161
|
-
): React.ReactNode => {
|
162
|
-
if (editorStore instanceof ExistingQueryEditorStore) {
|
163
|
-
return (
|
164
|
-
<div className="query-editor__header__label query-editor__header__label--existing-query">
|
165
|
-
{editorStore.query.name}
|
166
|
-
</div>
|
167
|
-
);
|
168
|
-
} else if (editorStore instanceof MappingQueryCreatorStore) {
|
169
|
-
return (
|
170
|
-
<div className="query-editor__header__label query-editor__header__label--create-query">
|
171
|
-
New Query
|
172
|
-
</div>
|
173
|
-
);
|
174
|
-
} else if (editorStore instanceof ServiceQueryCreatorStore) {
|
175
|
-
return (
|
176
|
-
<div className="query-editor__header__label query-editor__header__label--service-query">
|
177
|
-
<RobotIcon className="query-editor__header__label__icon" />
|
178
|
-
{extractElementNameFromPath(editorStore.servicePath)}
|
179
|
-
{editorStore.executionKey && (
|
180
|
-
<div className="query-editor__header__label__tag">
|
181
|
-
{editorStore.executionKey}
|
182
|
-
</div>
|
183
|
-
)}
|
184
|
-
</div>
|
185
|
-
);
|
186
|
-
}
|
187
|
-
const extraQueryEditorHeaderLabelers = editorStore.pluginManager
|
188
|
-
.getApplicationPlugins()
|
189
|
-
.flatMap((plugin) => plugin.getExtraQueryEditorHeaderLabelers?.() ?? []);
|
190
|
-
for (const labeler of extraQueryEditorHeaderLabelers) {
|
191
|
-
const label = labeler(editorStore);
|
192
|
-
if (label) {
|
193
|
-
return label;
|
194
|
-
}
|
195
|
-
}
|
196
|
-
return null;
|
197
|
-
};
|
198
|
-
|
199
163
|
const QueryLoader = observer(
|
200
164
|
(props: {
|
201
165
|
editorStore: QueryEditorStore;
|
@@ -253,8 +217,9 @@ const QueryLoader = observer(
|
|
253
217
|
if (selectedQueryID) {
|
254
218
|
queryBuilderState.changeDetectionState.alertUnsavedChanges(() => {
|
255
219
|
editorStore.queryLoaderState.setIsQueryLoaderOpen(false);
|
256
|
-
applicationStore.navigator.
|
220
|
+
applicationStore.navigator.goToLocation(
|
257
221
|
generateExistingQueryEditorRoute(selectedQueryID),
|
222
|
+
{ ignoreBlocking: true },
|
258
223
|
);
|
259
224
|
});
|
260
225
|
}
|
@@ -418,16 +383,22 @@ const QueryEditorHeaderContent = observer(
|
|
418
383
|
const openQueryLoader = (): void => {
|
419
384
|
editorStore.queryLoaderState.setIsQueryLoaderOpen(true);
|
420
385
|
};
|
421
|
-
const
|
386
|
+
const viewProject = (): void => {
|
422
387
|
const { groupId, artifactId, versionId } = editorStore.getProjectInfo();
|
423
|
-
applicationStore
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
388
|
+
createViewProjectHandler(applicationStore)(
|
389
|
+
groupId,
|
390
|
+
artifactId,
|
391
|
+
versionId,
|
392
|
+
undefined,
|
393
|
+
);
|
394
|
+
};
|
395
|
+
const viewSDLCProject = (): void => {
|
396
|
+
const { groupId, artifactId } = editorStore.getProjectInfo();
|
397
|
+
createViewSDLCProjectHandler(
|
398
|
+
applicationStore,
|
399
|
+
editorStore.depotServerClient,
|
400
|
+
)(groupId, artifactId, undefined).catch(
|
401
|
+
applicationStore.alertUnhandledError,
|
431
402
|
);
|
432
403
|
};
|
433
404
|
const toggleLightDarkMode = (): void =>
|
@@ -451,9 +422,7 @@ const QueryEditorHeaderContent = observer(
|
|
451
422
|
|
452
423
|
return (
|
453
424
|
<div className="query-editor__header__content">
|
454
|
-
<div className="query-editor__header__content__main"
|
455
|
-
{renderQueryEditorHeaderLabel(editorStore)}
|
456
|
-
</div>
|
425
|
+
<div className="query-editor__header__content__main" />
|
457
426
|
<div className="query-editor__header__actions">
|
458
427
|
{editorStore instanceof ExistingQueryEditorStore &&
|
459
428
|
applicationStore.pluginManager
|
@@ -482,14 +451,33 @@ const QueryEditorHeaderContent = observer(
|
|
482
451
|
queryBuilderState={queryBuilderState}
|
483
452
|
/>
|
484
453
|
)}
|
485
|
-
<
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
454
|
+
<div className="query-editor__header__action query-editor__header__action__view-project">
|
455
|
+
<button
|
456
|
+
className="query-editor__header__action__view-project__btn btn--dark"
|
457
|
+
disabled={editorStore.isViewProjectActionDisabled}
|
458
|
+
tabIndex={-1}
|
459
|
+
title="View project"
|
460
|
+
onClick={viewProject}
|
461
|
+
>
|
462
|
+
<ExternalLinkSquareIcon />
|
463
|
+
</button>
|
464
|
+
<DropdownMenu
|
465
|
+
className="query-editor__header__action__view-project__dropdown-trigger btn--dark"
|
466
|
+
disabled={editorStore.isViewProjectActionDisabled}
|
467
|
+
content={
|
468
|
+
<MenuContent>
|
469
|
+
<MenuContentItem
|
470
|
+
disabled={editorStore.isViewProjectActionDisabled}
|
471
|
+
onClick={viewSDLCProject}
|
472
|
+
>
|
473
|
+
View SDLC project
|
474
|
+
</MenuContentItem>
|
475
|
+
</MenuContent>
|
476
|
+
}
|
477
|
+
>
|
478
|
+
<CaretDownIcon />
|
479
|
+
</DropdownMenu>
|
480
|
+
</div>
|
493
481
|
{applicationStore.config.options.TEMPORARY__enableThemeSwitcher && (
|
494
482
|
<button
|
495
483
|
className="query-editor__header__action btn--dark"
|
@@ -507,6 +495,7 @@ const QueryEditorHeaderContent = observer(
|
|
507
495
|
<button
|
508
496
|
className="query-editor__header__action btn--dark"
|
509
497
|
tabIndex={-1}
|
498
|
+
disabled={editorStore.isSaveActionDisabled}
|
510
499
|
onClick={saveQuery}
|
511
500
|
title="Save query"
|
512
501
|
>
|
@@ -523,8 +512,27 @@ export const QueryEditor = observer(() => {
|
|
523
512
|
const applicationStore = useApplicationStore();
|
524
513
|
const editorStore = useQueryEditorStore();
|
525
514
|
const isLoadingEditor = !editorStore.initState.hasCompleted;
|
526
|
-
|
527
|
-
|
515
|
+
|
516
|
+
// documentation
|
517
|
+
const appDocUrl = applicationStore.documentationService.url;
|
518
|
+
const goToDocumentation = (): void => {
|
519
|
+
if (appDocUrl) {
|
520
|
+
applicationStore.navigator.visitAddress(appDocUrl);
|
521
|
+
}
|
522
|
+
};
|
523
|
+
// go to setup page
|
524
|
+
const goToQuerySetup = (): void =>
|
525
|
+
applicationStore.navigator.visitAddress(
|
526
|
+
applicationStore.navigator.generateAddress(generateQuerySetupRoute()),
|
527
|
+
);
|
528
|
+
// settings
|
529
|
+
// NOTE: this is temporary until we find a better home for these settings in query builder
|
530
|
+
const engineConfig =
|
531
|
+
editorStore.graphManagerState.graphManager.TEMPORARY__getEngineConfig();
|
532
|
+
const toggleEngineClientRequestPayloadCompression = (): void =>
|
533
|
+
engineConfig.setUseClientRequestPayloadCompression(
|
534
|
+
!engineConfig.useClientRequestPayloadCompression,
|
535
|
+
);
|
528
536
|
|
529
537
|
useEffect(() => {
|
530
538
|
flowResult(editorStore.initialize()).catch(
|
@@ -550,13 +558,46 @@ export const QueryEditor = observer(() => {
|
|
550
558
|
])}
|
551
559
|
>
|
552
560
|
<div className="query-editor__header">
|
553
|
-
<
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
561
|
+
<div className="query-editor__header__menu">
|
562
|
+
<DropdownMenu
|
563
|
+
className="query-editor__header__menu-item"
|
564
|
+
menuProps={{
|
565
|
+
anchorOrigin: { vertical: 'top', horizontal: 'right' },
|
566
|
+
transformOrigin: { vertical: 'top', horizontal: 'left' },
|
567
|
+
elevation: 7,
|
568
|
+
}}
|
569
|
+
content={
|
570
|
+
<MenuContent>
|
571
|
+
{/* <MenuContentItem onClick={openHelp}>Help...</MenuContentItem> */}
|
572
|
+
<MenuContentItem
|
573
|
+
disabled={!appDocUrl}
|
574
|
+
onClick={goToDocumentation}
|
575
|
+
>
|
576
|
+
See Documentation
|
577
|
+
</MenuContentItem>
|
578
|
+
<MenuContentItem onClick={goToQuerySetup}>
|
579
|
+
Back to query setup
|
580
|
+
</MenuContentItem>
|
581
|
+
<MenuContentDivider />
|
582
|
+
<MenuContentItem disabled={true}>Settings</MenuContentItem>
|
583
|
+
<MenuContentItem
|
584
|
+
onClick={toggleEngineClientRequestPayloadCompression}
|
585
|
+
>
|
586
|
+
<MenuContentItemIcon>
|
587
|
+
{engineConfig.useClientRequestPayloadCompression ? (
|
588
|
+
<CheckIcon />
|
589
|
+
) : null}
|
590
|
+
</MenuContentItemIcon>
|
591
|
+
<MenuContentItemLabel>
|
592
|
+
Compress request payload
|
593
|
+
</MenuContentItemLabel>
|
594
|
+
</MenuContentItem>
|
595
|
+
</MenuContent>
|
596
|
+
}
|
597
|
+
>
|
598
|
+
<MenuIcon />
|
599
|
+
</DropdownMenu>
|
600
|
+
</div>
|
560
601
|
{!isLoadingEditor && editorStore.queryBuilderState && (
|
561
602
|
<QueryEditorHeaderContent
|
562
603
|
queryBuilderState={editorStore.queryBuilderState}
|
@@ -566,7 +607,12 @@ export const QueryEditor = observer(() => {
|
|
566
607
|
<div className="query-editor__content">
|
567
608
|
<PanelLoadingIndicator isLoading={isLoadingEditor} />
|
568
609
|
{!isLoadingEditor && editorStore.queryBuilderState && (
|
569
|
-
|
610
|
+
<>
|
611
|
+
<QueryBuilderNavigationBlocker
|
612
|
+
queryBuilderState={editorStore.queryBuilderState}
|
613
|
+
/>
|
614
|
+
<QueryBuilder queryBuilderState={editorStore.queryBuilderState} />
|
615
|
+
</>
|
570
616
|
)}
|
571
617
|
{(isLoadingEditor || !editorStore.queryBuilderState) && (
|
572
618
|
<BlankPanelContent>
|
@@ -0,0 +1,206 @@
|
|
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
|
+
ArrowRightIcon,
|
20
|
+
BlankPanelContent,
|
21
|
+
clsx,
|
22
|
+
CustomSelectorInput,
|
23
|
+
PanelLoadingIndicator,
|
24
|
+
SearchIcon,
|
25
|
+
type SelectComponent,
|
26
|
+
} from '@finos/legend-art';
|
27
|
+
import { debounce, guaranteeType } from '@finos/legend-shared';
|
28
|
+
import { flowResult } from 'mobx';
|
29
|
+
import { observer, useLocalObservable } from 'mobx-react-lite';
|
30
|
+
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
31
|
+
import { useDepotServerClient } from '@finos/legend-server-depot';
|
32
|
+
import {
|
33
|
+
EDITOR_LANGUAGE,
|
34
|
+
TextInputEditor,
|
35
|
+
useApplicationStore,
|
36
|
+
} from '@finos/legend-application';
|
37
|
+
import { useLegendQueryApplicationStore } from './LegendQueryBaseStoreProvider.js';
|
38
|
+
import { QueryProductionizerSetupStore } from '../stores/QueryProductionizerSetupStore.js';
|
39
|
+
import { BaseQuerySetup, BaseQuerySetupStoreContext } from './QuerySetup.js';
|
40
|
+
import {
|
41
|
+
buildQueryOption,
|
42
|
+
type QueryOption,
|
43
|
+
} from '@finos/legend-query-builder';
|
44
|
+
import { generateQuerySetupRoute } from '../stores/LegendQueryRouter.js';
|
45
|
+
|
46
|
+
const QueryProductionizerSetupStoreProvider: React.FC<{
|
47
|
+
children: React.ReactNode;
|
48
|
+
}> = ({ children }) => {
|
49
|
+
const applicationStore = useLegendQueryApplicationStore();
|
50
|
+
const depotServerClient = useDepotServerClient();
|
51
|
+
const store = useLocalObservable(
|
52
|
+
() =>
|
53
|
+
new QueryProductionizerSetupStore(applicationStore, depotServerClient),
|
54
|
+
);
|
55
|
+
return (
|
56
|
+
<BaseQuerySetupStoreContext.Provider value={store}>
|
57
|
+
{children}
|
58
|
+
</BaseQuerySetupStoreContext.Provider>
|
59
|
+
);
|
60
|
+
};
|
61
|
+
|
62
|
+
const useQueryProductionizerSetupStore = (): QueryProductionizerSetupStore =>
|
63
|
+
guaranteeType(
|
64
|
+
useContext(BaseQuerySetupStoreContext),
|
65
|
+
QueryProductionizerSetupStore,
|
66
|
+
`Can't find query setup store in context`,
|
67
|
+
);
|
68
|
+
|
69
|
+
const QueryProductionizerSetupContent = observer(() => {
|
70
|
+
const applicationStore = useApplicationStore();
|
71
|
+
const setupStore = useQueryProductionizerSetupStore();
|
72
|
+
const querySearchRef = useRef<SelectComponent>(null);
|
73
|
+
const [searchText, setSearchText] = useState('');
|
74
|
+
|
75
|
+
// actions
|
76
|
+
const back = (): void => {
|
77
|
+
applicationStore.navigator.goToLocation(generateQuerySetupRoute());
|
78
|
+
};
|
79
|
+
const next = (): void => {
|
80
|
+
if (setupStore.currentQuery) {
|
81
|
+
setupStore
|
82
|
+
.loadQueryProductionizer()
|
83
|
+
.catch(applicationStore.alertUnhandledError);
|
84
|
+
}
|
85
|
+
};
|
86
|
+
const canProceed = setupStore.currentQuery;
|
87
|
+
|
88
|
+
// query
|
89
|
+
const queryOptions = setupStore.queries.map(buildQueryOption);
|
90
|
+
const selectedQueryOption = setupStore.currentQuery
|
91
|
+
? buildQueryOption(setupStore.currentQuery)
|
92
|
+
: null;
|
93
|
+
const onQueryOptionChange = (option: QueryOption | null): void => {
|
94
|
+
if (option?.value !== setupStore.currentQuery) {
|
95
|
+
setupStore.setCurrentQuery(option?.value.id);
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
// search text
|
100
|
+
const debouncedLoadQueries = useMemo(
|
101
|
+
() =>
|
102
|
+
debounce((input: string): void => {
|
103
|
+
flowResult(setupStore.loadQueries(input)).catch(
|
104
|
+
applicationStore.alertUnhandledError,
|
105
|
+
);
|
106
|
+
}, 500),
|
107
|
+
[applicationStore, setupStore],
|
108
|
+
);
|
109
|
+
const onSearchTextChange = (value: string): void => {
|
110
|
+
if (value !== searchText) {
|
111
|
+
setSearchText(value);
|
112
|
+
debouncedLoadQueries.cancel();
|
113
|
+
debouncedLoadQueries(value);
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
useEffect(() => {
|
118
|
+
flowResult(setupStore.loadQueries('')).catch(
|
119
|
+
applicationStore.alertUnhandledError,
|
120
|
+
);
|
121
|
+
}, [setupStore, applicationStore]);
|
122
|
+
|
123
|
+
useEffect(() => {
|
124
|
+
querySearchRef.current?.focus();
|
125
|
+
}, []);
|
126
|
+
|
127
|
+
return (
|
128
|
+
<div className="query-setup__wizard query-setup__productionize-query">
|
129
|
+
<div className="query-setup__wizard__header query-setup__productionize-query__header">
|
130
|
+
<button
|
131
|
+
className="query-setup__wizard__header__btn"
|
132
|
+
onClick={back}
|
133
|
+
title="Back to Main Menu"
|
134
|
+
>
|
135
|
+
<ArrowLeftIcon />
|
136
|
+
</button>
|
137
|
+
<div className="query-setup__wizard__header__title">
|
138
|
+
Productionizing an existing query...
|
139
|
+
</div>
|
140
|
+
<button
|
141
|
+
className={clsx('query-setup__wizard__header__btn', {
|
142
|
+
'query-setup__wizard__header__btn--ready': canProceed,
|
143
|
+
})}
|
144
|
+
onClick={next}
|
145
|
+
disabled={!canProceed}
|
146
|
+
title="Productionize query"
|
147
|
+
>
|
148
|
+
<ArrowRightIcon />
|
149
|
+
</button>
|
150
|
+
</div>
|
151
|
+
<div className="query-setup__wizard__content">
|
152
|
+
<div className="query-setup__wizard__group query-setup__wizard__group--inline">
|
153
|
+
<div className="query-setup__wizard__group__title">
|
154
|
+
<SearchIcon />
|
155
|
+
</div>
|
156
|
+
<CustomSelectorInput
|
157
|
+
ref={querySearchRef}
|
158
|
+
className="query-setup__wizard__selector"
|
159
|
+
options={queryOptions}
|
160
|
+
isLoading={setupStore.loadQueriesState.isInProgress}
|
161
|
+
onInputChange={onSearchTextChange}
|
162
|
+
inputValue={searchText}
|
163
|
+
onChange={onQueryOptionChange}
|
164
|
+
value={selectedQueryOption}
|
165
|
+
placeholder="Search for query by name..."
|
166
|
+
isClearable={true}
|
167
|
+
escapeClearsValue={true}
|
168
|
+
darkMode={true}
|
169
|
+
/>
|
170
|
+
</div>
|
171
|
+
<div className="query-setup__productionize-query__preview">
|
172
|
+
<PanelLoadingIndicator
|
173
|
+
isLoading={setupStore.loadQueryState.isInProgress}
|
174
|
+
/>
|
175
|
+
{setupStore.currentQuery && (
|
176
|
+
<>
|
177
|
+
{!setupStore.currentQueryInfo && (
|
178
|
+
<BlankPanelContent>{`Can't preview query`}</BlankPanelContent>
|
179
|
+
)}
|
180
|
+
{setupStore.currentQueryInfo && (
|
181
|
+
<TextInputEditor
|
182
|
+
inputValue={setupStore.currentQueryInfo.content}
|
183
|
+
isReadOnly={true}
|
184
|
+
language={EDITOR_LANGUAGE.PURE}
|
185
|
+
showMiniMap={false}
|
186
|
+
hideGutter={true}
|
187
|
+
/>
|
188
|
+
)}
|
189
|
+
</>
|
190
|
+
)}
|
191
|
+
{!setupStore.currentQuery && (
|
192
|
+
<BlankPanelContent>No query to preview</BlankPanelContent>
|
193
|
+
)}
|
194
|
+
</div>
|
195
|
+
</div>
|
196
|
+
</div>
|
197
|
+
);
|
198
|
+
});
|
199
|
+
|
200
|
+
export const QueryProductionizerSetup: React.FC = () => (
|
201
|
+
<QueryProductionizerSetupStoreProvider>
|
202
|
+
<BaseQuerySetup>
|
203
|
+
<QueryProductionizerSetupContent />
|
204
|
+
</BaseQuerySetup>
|
205
|
+
</QueryProductionizerSetupStoreProvider>
|
206
|
+
);
|