@finos/legend-extension-dsl-data-space 8.0.1 → 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 (60) hide show
  1. package/lib/components/DataSpaceViewer.d.ts.map +1 -1
  2. package/lib/components/DataSpaceViewer.js +12 -5
  3. package/lib/components/DataSpaceViewer.js.map +1 -1
  4. package/lib/components/query/DSL_DataSpace_LegendQueryApplicationPlugin.d.ts +2 -4
  5. package/lib/components/query/DSL_DataSpace_LegendQueryApplicationPlugin.d.ts.map +1 -1
  6. package/lib/components/query/DSL_DataSpace_LegendQueryApplicationPlugin.js +24 -35
  7. package/lib/components/query/DSL_DataSpace_LegendQueryApplicationPlugin.js.map +1 -1
  8. package/lib/components/query/DataSpaceAdvancedSearchModal.d.ts +24 -0
  9. package/lib/components/query/DataSpaceAdvancedSearchModal.d.ts.map +1 -0
  10. package/lib/components/query/DataSpaceAdvancedSearchModal.js +82 -0
  11. package/lib/components/query/DataSpaceAdvancedSearchModal.js.map +1 -0
  12. package/lib/components/query/DataSpaceQueryBuilder.d.ts +7 -0
  13. package/lib/components/query/DataSpaceQueryBuilder.d.ts.map +1 -1
  14. package/lib/components/query/DataSpaceQueryBuilder.js +7 -5
  15. package/lib/components/query/DataSpaceQueryBuilder.js.map +1 -1
  16. package/lib/components/query/DataSpaceQuerySetup.d.ts +3 -4
  17. package/lib/components/query/DataSpaceQuerySetup.d.ts.map +1 -1
  18. package/lib/components/query/DataSpaceQuerySetup.js +45 -56
  19. package/lib/components/query/DataSpaceQuerySetup.js.map +1 -1
  20. package/lib/index.css +2 -2
  21. package/lib/index.css.map +1 -1
  22. package/lib/package.json +4 -4
  23. package/lib/stores/DataSpaceViewerState.d.ts +9 -5
  24. package/lib/stores/DataSpaceViewerState.d.ts.map +1 -1
  25. package/lib/stores/DataSpaceViewerState.js +8 -4
  26. package/lib/stores/DataSpaceViewerState.js.map +1 -1
  27. package/lib/stores/query/DSL_DataSpace_LegendQueryRouter.d.ts +5 -1
  28. package/lib/stores/query/DSL_DataSpace_LegendQueryRouter.d.ts.map +1 -1
  29. package/lib/stores/query/DSL_DataSpace_LegendQueryRouter.js +10 -5
  30. package/lib/stores/query/DSL_DataSpace_LegendQueryRouter.js.map +1 -1
  31. package/lib/stores/query/{DataSpaceQuerySetupState.d.ts → DataSpaceAdvancedSearchState.d.ts} +16 -7
  32. package/lib/stores/query/DataSpaceAdvancedSearchState.d.ts.map +1 -0
  33. package/lib/stores/query/{DataSpaceQuerySetupState.js → DataSpaceAdvancedSearchState.js} +28 -16
  34. package/lib/stores/query/DataSpaceAdvancedSearchState.js.map +1 -0
  35. package/lib/stores/query/DataSpaceQueryBuilderState.d.ts +9 -2
  36. package/lib/stores/query/DataSpaceQueryBuilderState.d.ts.map +1 -1
  37. package/lib/stores/query/DataSpaceQueryBuilderState.js +32 -2
  38. package/lib/stores/query/DataSpaceQueryBuilderState.js.map +1 -1
  39. package/lib/stores/query/DataSpaceQueryCreatorStore.d.ts.map +1 -1
  40. package/lib/stores/query/DataSpaceQueryCreatorStore.js +6 -6
  41. package/lib/stores/query/DataSpaceQueryCreatorStore.js.map +1 -1
  42. package/lib/stores/query/DataSpaceQuerySetupStore.d.ts +50 -0
  43. package/lib/stores/query/DataSpaceQuerySetupStore.d.ts.map +1 -0
  44. package/lib/stores/query/DataSpaceQuerySetupStore.js +112 -0
  45. package/lib/stores/query/DataSpaceQuerySetupStore.js.map +1 -0
  46. package/package.json +15 -15
  47. package/src/components/DataSpaceViewer.tsx +53 -24
  48. package/src/components/query/DSL_DataSpace_LegendQueryApplicationPlugin.tsx +35 -69
  49. package/src/components/query/DataSpaceAdvancedSearchModal.tsx +248 -0
  50. package/src/components/query/DataSpaceQueryBuilder.tsx +57 -37
  51. package/src/components/query/DataSpaceQuerySetup.tsx +124 -186
  52. package/src/stores/DataSpaceViewerState.ts +28 -15
  53. package/src/stores/query/DSL_DataSpace_LegendQueryRouter.ts +34 -20
  54. package/src/stores/query/{DataSpaceQuerySetupState.ts → DataSpaceAdvancedSearchState.ts} +63 -37
  55. package/src/stores/query/DataSpaceQueryBuilderState.ts +61 -2
  56. package/src/stores/query/DataSpaceQueryCreatorStore.ts +11 -4
  57. package/src/stores/query/DataSpaceQuerySetupStore.ts +207 -0
  58. package/tsconfig.json +3 -1
  59. package/lib/stores/query/DataSpaceQuerySetupState.d.ts.map +0 -1
  60. package/lib/stores/query/DataSpaceQuerySetupState.js.map +0 -1
@@ -35,6 +35,10 @@ import {
35
35
  InfoCircleIcon,
36
36
  ExternalLinkIcon,
37
37
  useResizeDetector,
38
+ DropdownMenu,
39
+ MenuContent,
40
+ MenuContentItem,
41
+ CaretDownIcon,
38
42
  } from '@finos/legend-art';
39
43
  import {
40
44
  type Diagram,
@@ -51,6 +55,7 @@ import {
51
55
  } from '../stores/DataSpaceViewerState.js';
52
56
  import type { DataSpaceExecutionContextAnalysisResult } from '../graphManager/action/analytics/DataSpaceAnalysis.js';
53
57
  import { generateGAVCoordinates } from '@finos/legend-storage';
58
+ import { useApplicationStore } from '@finos/legend-application';
54
59
 
55
60
  interface DataSpaceViewerActivityConfig {
56
61
  mode: DATA_SPACE_VIEWER_ACTIVITY_MODE;
@@ -313,14 +318,14 @@ const DataSpaceInfo = observer(
313
318
  const { dataSpaceViewerState } = props;
314
319
  const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
315
320
  const viewProject = (): void =>
316
- dataSpaceViewerState.viewProject?.(
321
+ dataSpaceViewerState.viewProject(
317
322
  dataSpaceViewerState.groupId,
318
323
  dataSpaceViewerState.artifactId,
319
324
  dataSpaceViewerState.versionId,
320
325
  undefined,
321
326
  );
322
327
  const viewDataSpaceInProject = (): void =>
323
- dataSpaceViewerState.viewProject?.(
328
+ dataSpaceViewerState.viewProject(
324
329
  dataSpaceViewerState.groupId,
325
330
  dataSpaceViewerState.artifactId,
326
331
  dataSpaceViewerState.versionId,
@@ -475,6 +480,7 @@ const DataSpaceSupportInfoViewerInner = observer(
475
480
  export const DataSpaceViewer = observer(
476
481
  (props: { dataSpaceViewerState: DataSpaceViewerState }) => {
477
482
  const { dataSpaceViewerState } = props;
483
+ const applicationStore = useApplicationStore();
478
484
  const analysisResult = dataSpaceViewerState.dataSpaceAnalysisResult;
479
485
  const changeActivity =
480
486
  (activity: DATA_SPACE_VIEWER_ACTIVITY_MODE): (() => void) =>
@@ -520,38 +526,61 @@ export const DataSpaceViewer = observer(
520
526
  ];
521
527
 
522
528
  const viewProject = (): void =>
523
- dataSpaceViewerState.viewProject?.(
529
+ dataSpaceViewerState.viewProject(
524
530
  dataSpaceViewerState.groupId,
525
531
  dataSpaceViewerState.artifactId,
526
532
  dataSpaceViewerState.versionId,
527
533
  analysisResult.path,
528
534
  );
535
+ const viewSDLCProject = (): void => {
536
+ dataSpaceViewerState
537
+ .viewSDLCProject(
538
+ dataSpaceViewerState.groupId,
539
+ dataSpaceViewerState.artifactId,
540
+ analysisResult.path,
541
+ )
542
+ .catch(applicationStore.alertUnhandledError);
543
+ };
529
544
 
530
545
  return (
531
546
  <div className="data-space__viewer">
532
547
  <div className="data-space__viewer__header">
533
- <button
534
- className="data-space__viewer__title"
535
- tabIndex={-1}
536
- title={`View Project (${generateGAVCoordinates(
537
- dataSpaceViewerState.groupId,
538
- dataSpaceViewerState.artifactId,
539
- dataSpaceViewerState.versionId,
540
- )})`}
541
- onClick={viewProject}
542
- >
543
- <div
544
- className="data-space__viewer__title__label"
545
- title={`${analysisResult.title ?? analysisResult.name} - ${
546
- analysisResult.path
547
- }`}
548
+ <div className="data-space__viewer__title">
549
+ <button
550
+ className="data-space__viewer__title__btn"
551
+ tabIndex={-1}
552
+ title={`View Project (${generateGAVCoordinates(
553
+ dataSpaceViewerState.groupId,
554
+ dataSpaceViewerState.artifactId,
555
+ dataSpaceViewerState.versionId,
556
+ )})`}
557
+ onClick={viewProject}
548
558
  >
549
- {analysisResult.title ?? analysisResult.name}
550
- </div>
551
- <div className="data-space__viewer__title__link">
552
- <ExternalLinkSquareIcon />
553
- </div>
554
- </button>
559
+ <div
560
+ className="data-space__viewer__title__label"
561
+ title={`${analysisResult.title ?? analysisResult.name} - ${
562
+ analysisResult.path
563
+ }`}
564
+ >
565
+ {analysisResult.title ?? analysisResult.name}
566
+ </div>
567
+ <div className="data-space__viewer__title__link">
568
+ <ExternalLinkSquareIcon />
569
+ </div>
570
+ </button>
571
+ <DropdownMenu
572
+ className="data-space__viewer__title__dropdown-trigger"
573
+ content={
574
+ <MenuContent>
575
+ <MenuContentItem onClick={viewSDLCProject}>
576
+ View SDLC project
577
+ </MenuContentItem>
578
+ </MenuContent>
579
+ }
580
+ >
581
+ <CaretDownIcon title="Show more options..." />
582
+ </DropdownMenu>
583
+ </div>
555
584
  <div
556
585
  className={clsx('data-space__viewer__description', {
557
586
  'data-space__viewer__description--empty':
@@ -16,38 +16,29 @@
16
16
 
17
17
  import packageJson from '../../../package.json';
18
18
  import {
19
- type QueryEditorStore,
20
- type QueryEditorHeaderLabeler,
21
- type QuerySetupOptionRendererConfiguration,
22
- type QuerySetupRenderer,
23
- type QuerySetupState,
24
- type QuerySetupStore,
19
+ type QuerySetupActionConfiguration,
25
20
  type ExistingQueryEditorStateBuilder,
26
21
  type ExistingQueryEditorStore,
27
22
  LegendQueryApplicationPlugin,
28
23
  generateExistingQueryEditorRoute,
29
24
  LegendQueryEventService,
30
25
  LEGEND_QUERY_APP_EVENT,
26
+ createViewProjectHandler,
27
+ createViewSDLCProjectHandler,
31
28
  } from '@finos/legend-application-query';
32
29
  import { SquareIcon } from '@finos/legend-art';
33
- import { DataSpaceQuerySetupState } from '../../stores/query/DataSpaceQuerySetupState.js';
34
- import { DataspaceQuerySetup } from './DataSpaceQuerySetup.js';
35
30
  import {
36
31
  ActionAlertActionType,
37
32
  ActionAlertType,
38
33
  type ApplicationPageEntry,
39
34
  } from '@finos/legend-application';
40
- import { CREATE_QUERY_FROM_DATA_SPACE_ROUTE_PATTERN } from '../../stores/query/DSL_DataSpace_LegendQueryRouter.js';
41
- import { DataSpaceQueryCreator } from './DataSpaceQueryCreator.js';
42
- import {
43
- createQueryDataSpaceTaggedValue,
44
- DataSpaceQueryCreatorStore,
45
- } from '../../stores/query/DataSpaceQueryCreatorStore.js';
46
35
  import {
47
- Query,
48
- extractElementNameFromPath,
49
- isValidFullPath,
50
- } from '@finos/legend-graph';
36
+ DATA_SPACE_QUERY_ROUTE_PATTERN,
37
+ generateDataSpaceQuerySetupRoute,
38
+ } from '../../stores/query/DSL_DataSpace_LegendQueryRouter.js';
39
+ import { DataSpaceQueryCreator } from './DataSpaceQueryCreator.js';
40
+ import { createQueryDataSpaceTaggedValue } from '../../stores/query/DataSpaceQueryCreatorStore.js';
41
+ import { Query, isValidFullPath } from '@finos/legend-graph';
51
42
  import {
52
43
  QUERY_PROFILE_PATH,
53
44
  QUERY_PROFILE_TAG_DATA_SPACE,
@@ -57,6 +48,7 @@ import type { DataSpaceInfo } from '../../stores/query/DataSpaceInfo.js';
57
48
  import { getOwnDataSpace } from '../../graphManager/DSL_DataSpace_GraphManagerHelper.js';
58
49
  import { assertErrorThrown, LogEvent, uuid } from '@finos/legend-shared';
59
50
  import type { QueryBuilderState } from '@finos/legend-query-builder';
51
+ import { DataSpaceQuerySetup } from './DataSpaceQuerySetup.js';
60
52
 
61
53
  export class DSL_DataSpace_LegendQueryApplicationPlugin extends LegendQueryApplicationPlugin {
62
54
  constructor() {
@@ -65,68 +57,37 @@ export class DSL_DataSpace_LegendQueryApplicationPlugin extends LegendQueryAppli
65
57
 
66
58
  override getExtraApplicationPageEntries(): ApplicationPageEntry[] {
67
59
  return [
60
+ // data space query editor setup
61
+ {
62
+ key: 'data-space-query-setup-application-page',
63
+ urlPatterns: [DATA_SPACE_QUERY_ROUTE_PATTERN.SETUP],
64
+ renderer: DataSpaceQuerySetup,
65
+ },
68
66
  // data space query editor
69
67
  {
70
68
  key: 'data-space-query-editor-application-page',
71
- urlPatterns: [CREATE_QUERY_FROM_DATA_SPACE_ROUTE_PATTERN],
69
+ urlPatterns: [DATA_SPACE_QUERY_ROUTE_PATTERN.CREATE],
72
70
  renderer: DataSpaceQueryCreator,
73
71
  },
74
72
  ];
75
73
  }
76
74
 
77
- override getExtraQuerySetupOptionRendererConfigurations(): QuerySetupOptionRendererConfiguration[] {
75
+ override getExtraQuerySetupActionConfigurations(): QuerySetupActionConfiguration[] {
78
76
  return [
79
77
  {
80
- key: 'data-space-query-option',
81
- renderer: (
82
- setupStore: QuerySetupStore,
83
- ): React.ReactNode | undefined => {
84
- const createQuery = (): void =>
85
- setupStore.setSetupState(new DataSpaceQuerySetupState(setupStore));
86
- return (
87
- <button
88
- className="query-setup__landing-page__option query-setup__landing-page__option--data-space"
89
- onClick={createQuery}
90
- >
91
- <div className="query-setup__landing-page__option__icon">
92
- <SquareIcon className="query-setup__landing-page__icon--data-space" />
93
- </div>
94
- <div className="query-setup__landing-page__option__label">
95
- Create query from data space
96
- </div>
97
- </button>
78
+ key: 'create-query-from-data-space',
79
+ isAdvanced: false,
80
+ isCreateAction: true,
81
+ action: async (setupStore) => {
82
+ setupStore.applicationStore.navigator.goToLocation(
83
+ generateDataSpaceQuerySetupRoute(),
98
84
  );
99
85
  },
100
- },
101
- ];
102
- }
103
-
104
- override getExtraQuerySetupRenderers(): QuerySetupRenderer[] {
105
- return [
106
- (querySetupState: QuerySetupState): React.ReactNode | undefined => {
107
- if (querySetupState instanceof DataSpaceQuerySetupState) {
108
- return <DataspaceQuerySetup querySetupState={querySetupState} />;
109
- }
110
- return undefined;
111
- },
112
- ];
113
- }
114
-
115
- override getExtraQueryEditorHeaderLabelers(): QueryEditorHeaderLabeler[] {
116
- return [
117
- (editorStore: QueryEditorStore): React.ReactNode | undefined => {
118
- if (editorStore instanceof DataSpaceQueryCreatorStore) {
119
- return (
120
- <div className="query-editor__header__label">
121
- <SquareIcon className="query-editor__header__label__icon icon--data-space" />
122
- {extractElementNameFromPath(editorStore.dataSpacePath)}
123
- <div className="query-editor__header__label__tag">
124
- {editorStore.executionContext}
125
- </div>
126
- </div>
127
- );
128
- }
129
- return undefined;
86
+ label: 'Create query from data space',
87
+ className: 'query-setup__landing-page__action--data-space',
88
+ icon: (
89
+ <SquareIcon className="query-setup__landing-page__icon--data-space" />
90
+ ),
130
91
  },
131
92
  ];
132
93
  }
@@ -168,6 +129,11 @@ export class DSL_DataSpace_LegendQueryApplicationPlugin extends LegendQueryAppli
168
129
  query.groupId,
169
130
  query.artifactId,
170
131
  query.versionId,
132
+ createViewProjectHandler(editorStore.applicationStore),
133
+ createViewSDLCProjectHandler(
134
+ editorStore.applicationStore,
135
+ editorStore.depotServerClient,
136
+ ),
171
137
  (dataSpaceInfo: DataSpaceInfo) => {
172
138
  if (dataSpaceInfo.defaultExecutionContext) {
173
139
  const persistQuery = async (): Promise<void> => {
@@ -205,7 +171,7 @@ export class DSL_DataSpace_LegendQueryApplicationPlugin extends LegendQueryAppli
205
171
  LegendQueryEventService.create(
206
172
  editorStore.applicationStore.eventService,
207
173
  ).notify_QueryCreated({ queryId: newQuery.id });
208
- editorStore.applicationStore.navigator.reloadToLocation(
174
+ editorStore.applicationStore.navigator.goToLocation(
209
175
  generateExistingQueryEditorRoute(newQuery.id),
210
176
  );
211
177
  } else {
@@ -0,0 +1,248 @@
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 { useApplicationStore } from '@finos/legend-application';
18
+ import {
19
+ type SelectComponent,
20
+ BoltIcon,
21
+ clsx,
22
+ BlankPanelContent,
23
+ TimesCircleIcon,
24
+ PanelLoadingIndicator,
25
+ CustomSelectorInput,
26
+ SearchIcon,
27
+ Dialog,
28
+ TimesIcon,
29
+ ArrowRightIcon,
30
+ } from '@finos/legend-art';
31
+ import { generateGAVCoordinates } from '@finos/legend-storage';
32
+ import { debounce } from '@finos/legend-shared';
33
+ import { flowResult } from 'mobx';
34
+ import { observer } from 'mobx-react-lite';
35
+ import { useEffect, useMemo, useRef, useState } from 'react';
36
+ import { DataSpaceViewer } from '../DataSpaceViewer.js';
37
+ import type { DataSpaceInfo } from '../../stores/query/DataSpaceInfo.js';
38
+ import type { DataSpaceAdvancedSearchState } from '../../stores/query/DataSpaceAdvancedSearchState.js';
39
+
40
+ type DataSpaceOption = { label: string; value: DataSpaceInfo };
41
+ const buildDataSpaceOption = (value: DataSpaceInfo): DataSpaceOption => ({
42
+ label: value.title ?? value.name,
43
+ value,
44
+ });
45
+
46
+ export const DataSpaceAdvancedSearchModal = observer(
47
+ (props: {
48
+ searchState: DataSpaceAdvancedSearchState;
49
+ onClose: () => void;
50
+ }) => {
51
+ const { searchState, onClose } = props;
52
+ const applicationStore = useApplicationStore();
53
+ const dataSpaceSearchRef = useRef<SelectComponent>(null);
54
+ const [searchText, setSearchText] = useState('');
55
+ const handleEnter = (): void => dataSpaceSearchRef.current?.focus();
56
+ const proceedToCreateQuery = (): void => {
57
+ flowResult(searchState.proceedToCreateQuery()).catch(
58
+ applicationStore.alertUnhandledError,
59
+ );
60
+ };
61
+
62
+ const toggleGetSnapshot = (): void => {
63
+ searchState.setToGetSnapShot(!searchState.toGetSnapShot);
64
+ flowResult(searchState.loadDataSpaces(searchText)).catch(
65
+ applicationStore.alertUnhandledError,
66
+ );
67
+ };
68
+
69
+ // data space
70
+ const dataSpaceOptions = searchState.dataSpaces.map(buildDataSpaceOption);
71
+ const selectedDataSpaceOption = searchState.currentDataSpace
72
+ ? buildDataSpaceOption(searchState.currentDataSpace)
73
+ : null;
74
+ const onDataSpaceOptionChange = (option: DataSpaceOption | null): void => {
75
+ searchState.setCurrentDataSpace(option?.value);
76
+ searchState.setDataSpaceViewerState(undefined);
77
+ };
78
+ const formatDataSpaceOptionLabel = (
79
+ option: DataSpaceOption,
80
+ ): React.ReactNode => (
81
+ <div
82
+ className="data-space-advanced-search__dialog__option"
83
+ title={`${option.label} - ${
84
+ option.value.path
85
+ } - ${generateGAVCoordinates(
86
+ option.value.groupId,
87
+ option.value.artifactId,
88
+ option.value.versionId,
89
+ )}`}
90
+ >
91
+ <div className="data-space-advanced-search__dialog__option__label">
92
+ {option.label}
93
+ </div>
94
+ <div className="data-space-advanced-search__dialog__option__path">
95
+ {option.value.path}
96
+ </div>
97
+ <div className="data-space-advanced-search__dialog__option__gav">
98
+ {generateGAVCoordinates(
99
+ option.value.groupId,
100
+ option.value.artifactId,
101
+ option.value.versionId,
102
+ )}
103
+ </div>
104
+ </div>
105
+ );
106
+
107
+ // search text
108
+ const debouncedLoadDataSpaces = useMemo(
109
+ () =>
110
+ debounce((input: string): void => {
111
+ flowResult(searchState.loadDataSpaces(input)).catch(
112
+ applicationStore.alertUnhandledError,
113
+ );
114
+ }, 500),
115
+ [applicationStore, searchState],
116
+ );
117
+ const onSearchTextChange = (value: string): void => {
118
+ if (value !== searchText) {
119
+ setSearchText(value);
120
+ debouncedLoadDataSpaces.cancel();
121
+ debouncedLoadDataSpaces(value);
122
+ }
123
+ };
124
+
125
+ useEffect(() => {
126
+ searchState.loadDataSpaces('');
127
+ flowResult(searchState.loadDataSpaces('')).catch(
128
+ applicationStore.alertUnhandledError,
129
+ );
130
+ }, [searchState, applicationStore]);
131
+
132
+ useEffect(() => {
133
+ if (searchState.currentDataSpace) {
134
+ flowResult(
135
+ searchState.loadDataSpace(searchState.currentDataSpace),
136
+ ).catch(applicationStore.alertUnhandledError);
137
+ }
138
+ }, [searchState, applicationStore, searchState.currentDataSpace]);
139
+
140
+ return (
141
+ <Dialog
142
+ open={true}
143
+ onClose={onClose}
144
+ classes={{
145
+ root: 'editor-modal__root-container',
146
+ container: 'editor-modal__container',
147
+ paper:
148
+ 'editor-modal__content data-space-advanced-search__dialog__container__content',
149
+ }}
150
+ TransitionProps={{
151
+ onEnter: handleEnter,
152
+ }}
153
+ >
154
+ <div className="modal modal--dark editor-modal data-space-advanced-search__dialog">
155
+ <div className="data-space-advanced-search__dialog__header modal__header">
156
+ <div className="modal__title">Search for data space</div>
157
+ <div className="modal__header__actions">
158
+ <button
159
+ className="modal__header__action"
160
+ title="Close"
161
+ onClick={onClose}
162
+ >
163
+ <TimesIcon />
164
+ </button>
165
+ </div>
166
+ </div>
167
+ <div className="data-space-advanced-search__dialog__content">
168
+ <div className="data-space-advanced-search__dialog__input">
169
+ <div className="data-space-advanced-search__dialog__input__icon">
170
+ <SearchIcon />
171
+ </div>
172
+ <CustomSelectorInput
173
+ ref={dataSpaceSearchRef}
174
+ className="data-space-advanced-search__dialog__input__selector"
175
+ options={dataSpaceOptions}
176
+ isLoading={searchState.loadDataSpacesState.isInProgress}
177
+ onInputChange={onSearchTextChange}
178
+ inputValue={searchText}
179
+ onChange={onDataSpaceOptionChange}
180
+ value={selectedDataSpaceOption}
181
+ placeholder="Search for data space by name..."
182
+ isClearable={true}
183
+ escapeClearsValue={true}
184
+ darkMode={true}
185
+ formatOptionLabel={formatDataSpaceOptionLabel}
186
+ />
187
+ <button
188
+ className={clsx(
189
+ 'data-space-advanced-search__dialog__input__use-snapshot-btn',
190
+ {
191
+ 'data-space-advanced-search__dialog__input__use-snapshot-btn--active':
192
+ searchState.toGetSnapShot,
193
+ },
194
+ )}
195
+ tabIndex={-1}
196
+ title={`[${
197
+ searchState.toGetSnapShot ? 'on' : 'off'
198
+ }] Toggle show data spaces from snapshot releases instead of latest releases`}
199
+ onClick={toggleGetSnapshot}
200
+ >
201
+ <BoltIcon />
202
+ </button>
203
+ <button
204
+ className="data-space-advanced-search__dialog__input__proceed-btn"
205
+ tabIndex={-1}
206
+ title="Proceed to create query"
207
+ onClick={proceedToCreateQuery}
208
+ >
209
+ <ArrowRightIcon />
210
+ </button>
211
+ </div>
212
+ <div className="data-space-advanced-search__dialog__view">
213
+ <PanelLoadingIndicator
214
+ isLoading={searchState.loadDataSpaceState.isInProgress}
215
+ />
216
+ {searchState.dataSpaceViewerState && (
217
+ <DataSpaceViewer
218
+ dataSpaceViewerState={searchState.dataSpaceViewerState}
219
+ />
220
+ )}
221
+ {!searchState.dataSpaceViewerState && (
222
+ <>
223
+ {searchState.loadDataSpaceState.isInProgress && (
224
+ <BlankPanelContent>
225
+ {searchState.loadDataSpaceState.message}
226
+ </BlankPanelContent>
227
+ )}
228
+ {searchState.loadDataSpaceState.hasFailed && (
229
+ <BlankPanelContent>
230
+ <div className="data-space-advanced-search__dialog__view--failed">
231
+ <div className="data-space-advanced-search__dialog__view--failed__icon">
232
+ <TimesCircleIcon />
233
+ </div>
234
+ <div className="data-space-advanced-search__dialog__view--failed__text">
235
+ Can&apos;t load data space
236
+ </div>
237
+ </div>
238
+ </BlankPanelContent>
239
+ )}
240
+ </>
241
+ )}
242
+ </div>
243
+ </div>
244
+ </div>
245
+ </Dialog>
246
+ );
247
+ },
248
+ );
@@ -26,6 +26,7 @@ import {
26
26
  MenuContentItemIcon,
27
27
  CheckIcon,
28
28
  MenuContentItemLabel,
29
+ SearchIcon,
29
30
  } from '@finos/legend-art';
30
31
  import { observer } from 'mobx-react-lite';
31
32
  import { useApplicationStore } from '@finos/legend-application';
@@ -49,15 +50,44 @@ import { debounce, guaranteeType } from '@finos/legend-shared';
49
50
  import { flowResult } from 'mobx';
50
51
  import type { DataSpaceExecutionContext } from '../../graph/metamodel/pure/model/packageableElements/dataSpace/DSL_DataSpace_DataSpace.js';
51
52
  import { DataSpaceIcon } from '../DSL_DataSpace_Icon.js';
53
+ import { DataSpaceAdvancedSearchModal } from './DataSpaceAdvancedSearchModal.js';
52
54
 
53
- type DataSpaceOption = {
55
+ export type DataSpaceOption = {
54
56
  label: string;
55
57
  value: DataSpaceInfo;
56
58
  };
57
- const buildDataSpaceOption = (value: DataSpaceInfo): DataSpaceOption => ({
59
+ export const buildDataSpaceOption = (
60
+ value: DataSpaceInfo,
61
+ ): DataSpaceOption => ({
58
62
  label: value.title ?? value.name,
59
63
  value,
60
64
  });
65
+ export const formatDataSpaceOptionLabel = (
66
+ option: DataSpaceOption,
67
+ ): React.ReactNode => (
68
+ <div
69
+ className="query-builder__setup__data-space__option"
70
+ title={`${option.label} - ${option.value.path} - ${generateGAVCoordinates(
71
+ option.value.groupId,
72
+ option.value.artifactId,
73
+ option.value.versionId,
74
+ )}`}
75
+ >
76
+ <div className="query-builder__setup__data-space__option__label">
77
+ {option.label}
78
+ </div>
79
+ <div className="query-builder__setup__data-space__option__path">
80
+ {option.value.path}
81
+ </div>
82
+ <div className="query-builder__setup__data-space__option__gav">
83
+ {generateGAVCoordinates(
84
+ option.value.groupId,
85
+ option.value.artifactId,
86
+ option.value.versionId,
87
+ )}
88
+ </div>
89
+ </div>
90
+ );
61
91
 
62
92
  type ExecutionContextOption = {
63
93
  label: string;
@@ -105,34 +135,6 @@ const DataSpaceQueryBuilderSetupPanelContent = observer(
105
135
  const onDataSpaceOptionChange = (option: DataSpaceOption): void => {
106
136
  queryBuilderState.onDataSpaceChange(option.value);
107
137
  };
108
- const formatDataSpaceOptionLabel = (
109
- option: DataSpaceOption,
110
- ): React.ReactNode => (
111
- <div
112
- className="query-builder__setup__data-space__option"
113
- title={`${option.label} - ${
114
- option.value.path
115
- } - ${generateGAVCoordinates(
116
- option.value.groupId,
117
- option.value.artifactId,
118
- option.value.versionId,
119
- )}`}
120
- >
121
- <div className="query-builder__setup__data-space__option__label">
122
- {option.label}
123
- </div>
124
- <div className="query-builder__setup__data-space__option__path">
125
- {option.value.path}
126
- </div>
127
- <div className="query-builder__setup__data-space__option__gav">
128
- {generateGAVCoordinates(
129
- option.value.groupId,
130
- option.value.artifactId,
131
- option.value.versionId,
132
- )}
133
- </div>
134
- </div>
135
- );
136
138
 
137
139
  // data space search text
138
140
  const debouncedLoadDataSpaces = useMemo(
@@ -151,6 +153,8 @@ const DataSpaceQueryBuilderSetupPanelContent = observer(
151
153
  debouncedLoadDataSpaces(value);
152
154
  }
153
155
  };
156
+ const openDataSpaceAdvancedSearch = (): void =>
157
+ queryBuilderState.showAdvancedSearchPanel();
154
158
 
155
159
  // execution context
156
160
  const executionContextOptions =
@@ -219,7 +223,8 @@ const DataSpaceQueryBuilderSetupPanelContent = observer(
219
223
  data space execution context
220
224
  </div>
221
225
  <DropdownMenu
222
- className="query-builder__setup__config-group__header__dropdown"
226
+ className="query-builder__setup__config-group__header__dropdown-trigger"
227
+ title="Show Settings..."
223
228
  content={
224
229
  <MenuContent>
225
230
  <MenuContentItem
@@ -245,12 +250,7 @@ const DataSpaceQueryBuilderSetupPanelContent = observer(
245
250
  transformOrigin: { vertical: 'top', horizontal: 'right' },
246
251
  }}
247
252
  >
248
- <button
249
- className="query-builder__setup__config-group__header__dropdown-trigger"
250
- title="Show Settings..."
251
- >
252
- <MoreHorizontalIcon />
253
- </button>
253
+ <MoreHorizontalIcon />
254
254
  </DropdownMenu>
255
255
  </div>
256
256
  <div className="query-builder__setup__config-group__content">
@@ -274,6 +274,26 @@ const DataSpaceQueryBuilderSetupPanelContent = observer(
274
274
  darkMode={!applicationStore.TEMPORARY__isLightThemeEnabled}
275
275
  formatOptionLabel={formatDataSpaceOptionLabel}
276
276
  />
277
+ {queryBuilderState.isAdvancedDataSpaceSearchEnabled && (
278
+ <>
279
+ <button
280
+ tabIndex={-1}
281
+ className="query-builder__setup__data-space-searcher__btn btn--dark"
282
+ onClick={openDataSpaceAdvancedSearch}
283
+ title="Open advanced search for data space..."
284
+ >
285
+ <SearchIcon />
286
+ </button>
287
+ {queryBuilderState.advancedSearchState && (
288
+ <DataSpaceAdvancedSearchModal
289
+ searchState={queryBuilderState.advancedSearchState}
290
+ onClose={() =>
291
+ queryBuilderState.hideAdvancedSearchPanel()
292
+ }
293
+ />
294
+ )}
295
+ </>
296
+ )}
277
297
  </div>
278
298
  <div className="query-builder__setup__config-group__item">
279
299
  <div