@finos/legend-application-data-cube 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +1 -1
  2. package/lib/__lib__/LegendDataCubeNavigation.d.ts +9 -5
  3. package/lib/__lib__/LegendDataCubeNavigation.d.ts.map +1 -1
  4. package/lib/__lib__/LegendDataCubeNavigation.js +9 -5
  5. package/lib/__lib__/LegendDataCubeNavigation.js.map +1 -1
  6. package/lib/__lib__/LegendDataCubeUserData.d.ts +2 -2
  7. package/lib/__lib__/LegendDataCubeUserData.d.ts.map +1 -1
  8. package/lib/__lib__/LegendDataCubeUserData.js +2 -2
  9. package/lib/__lib__/LegendDataCubeUserData.js.map +1 -1
  10. package/lib/application/LegendDataCubeApplicationConfig.d.ts +4 -0
  11. package/lib/application/LegendDataCubeApplicationConfig.d.ts.map +1 -1
  12. package/lib/application/LegendDataCubeApplicationConfig.js +5 -0
  13. package/lib/application/LegendDataCubeApplicationConfig.js.map +1 -1
  14. package/lib/components/LegendDataCubeBlockingWindow.d.ts +29 -0
  15. package/lib/components/LegendDataCubeBlockingWindow.d.ts.map +1 -0
  16. package/lib/components/LegendDataCubeBlockingWindow.js +75 -0
  17. package/lib/components/LegendDataCubeBlockingWindow.js.map +1 -0
  18. package/lib/components/LegendDataCubeWebApplication.js +2 -2
  19. package/lib/components/LegendDataCubeWebApplication.js.map +1 -1
  20. package/lib/components/builder/LegendDataCubeBuilder.d.ts +20 -0
  21. package/lib/components/builder/LegendDataCubeBuilder.d.ts.map +1 -0
  22. package/lib/components/builder/LegendDataCubeBuilder.js +162 -0
  23. package/lib/components/builder/LegendDataCubeBuilder.js.map +1 -0
  24. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.d.ts +19 -0
  25. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.d.ts.map +1 -0
  26. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js +34 -0
  27. package/lib/components/builder/LegendDataCubeBuilderStoreProvider.js.map +1 -0
  28. package/lib/components/{query-builder/LegendDataCubeQuerySaver.d.ts → builder/LegendDataCubeCreator.d.ts} +2 -2
  29. package/lib/components/builder/LegendDataCubeCreator.d.ts.map +1 -0
  30. package/lib/components/{query-builder/LegendDataCubeNewQueryBuilder.js → builder/LegendDataCubeCreator.js} +10 -10
  31. package/lib/components/builder/LegendDataCubeCreator.js.map +1 -0
  32. package/lib/components/builder/LegendDataCubeDeleteConfirmation.d.ts +19 -0
  33. package/lib/components/builder/LegendDataCubeDeleteConfirmation.d.ts.map +1 -0
  34. package/lib/components/builder/LegendDataCubeDeleteConfirmation.js +43 -0
  35. package/lib/components/builder/LegendDataCubeDeleteConfirmation.js.map +1 -0
  36. package/lib/components/{query-builder/LegendDataCubeQueryLoader.d.ts → builder/LegendDataCubeLoader.d.ts} +2 -2
  37. package/lib/components/builder/LegendDataCubeLoader.d.ts.map +1 -0
  38. package/lib/components/builder/LegendDataCubeLoader.js +113 -0
  39. package/lib/components/builder/LegendDataCubeLoader.js.map +1 -0
  40. package/lib/components/{query-builder/LegendDataCubeNewQueryBuilder.d.ts → builder/LegendDataCubeSaver.d.ts} +2 -2
  41. package/lib/components/builder/LegendDataCubeSaver.d.ts.map +1 -0
  42. package/lib/components/builder/LegendDataCubeSaver.js +73 -0
  43. package/lib/components/builder/LegendDataCubeSaver.js.map +1 -0
  44. package/lib/components/{query-builder/LegendDataCubeQueryBuilder.d.ts → builder/LegendDataCubeSourceViewer.d.ts} +4 -2
  45. package/lib/components/builder/LegendDataCubeSourceViewer.d.ts.map +1 -0
  46. package/lib/components/builder/LegendDataCubeSourceViewer.js +46 -0
  47. package/lib/components/builder/LegendDataCubeSourceViewer.js.map +1 -0
  48. package/lib/components/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilder.d.ts +1 -1
  49. package/lib/components/builder/source/AdhocQueryDataCubeSourceBuilder.d.ts.map +1 -0
  50. package/lib/components/builder/source/AdhocQueryDataCubeSourceBuilder.js.map +1 -0
  51. package/lib/components/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilder.d.ts +1 -1
  52. package/lib/components/builder/source/LegendQueryDataCubeSourceBuilder.d.ts.map +1 -0
  53. package/lib/components/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilder.js +13 -13
  54. package/lib/components/builder/source/LegendQueryDataCubeSourceBuilder.js.map +1 -0
  55. package/lib/index.css +1 -1
  56. package/lib/package.json +1 -1
  57. package/lib/stores/LegendDataCubeCacheManager.d.ts.map +1 -1
  58. package/lib/stores/LegendDataCubeCacheManager.js +11 -12
  59. package/lib/stores/LegendDataCubeCacheManager.js.map +1 -1
  60. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts +1 -1
  61. package/lib/stores/LegendDataCubeDataCubeEngine.d.ts.map +1 -1
  62. package/lib/stores/LegendDataCubeDataCubeEngine.js +5 -11
  63. package/lib/stores/LegendDataCubeDataCubeEngine.js.map +1 -1
  64. package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts +80 -0
  65. package/lib/stores/builder/LegendDataCubeBuilderStore.d.ts.map +1 -0
  66. package/lib/stores/builder/LegendDataCubeBuilderStore.js +353 -0
  67. package/lib/stores/builder/LegendDataCubeBuilderStore.js.map +1 -0
  68. package/lib/stores/{query-builder/LegendDataCubeNewQueryState.d.ts → builder/LegendDataCubeCreatorState.d.ts} +5 -5
  69. package/lib/stores/builder/LegendDataCubeCreatorState.d.ts.map +1 -0
  70. package/lib/stores/{query-builder/LegendDataCubeNewQueryState.js → builder/LegendDataCubeCreatorState.js} +17 -17
  71. package/lib/stores/builder/LegendDataCubeCreatorState.js.map +1 -0
  72. package/lib/stores/{query-builder/LegendDataCubeQueryLoaderState.d.ts → builder/LegendDataCubeLoaderState.d.ts} +20 -20
  73. package/lib/stores/builder/LegendDataCubeLoaderState.d.ts.map +1 -0
  74. package/lib/stores/builder/LegendDataCubeLoaderState.js +187 -0
  75. package/lib/stores/builder/LegendDataCubeLoaderState.js.map +1 -0
  76. package/lib/stores/builder/source/AdhocQueryDataCubeSourceBuilderState.d.ts.map +1 -0
  77. package/lib/stores/builder/source/AdhocQueryDataCubeSourceBuilderState.js.map +1 -0
  78. package/lib/stores/builder/source/LegendDataCubeSourceBuilderState.d.ts.map +1 -0
  79. package/lib/stores/{query-builder/source-builder → builder/source}/LegendDataCubeSourceBuilderState.js +1 -1
  80. package/lib/stores/builder/source/LegendDataCubeSourceBuilderState.js.map +1 -0
  81. package/lib/stores/builder/source/LegendQueryDataCubeSourceBuilderState.d.ts.map +1 -0
  82. package/lib/stores/builder/source/LegendQueryDataCubeSourceBuilderState.js.map +1 -0
  83. package/package.json +5 -5
  84. package/src/__lib__/LegendDataCubeNavigation.ts +15 -7
  85. package/src/__lib__/LegendDataCubeUserData.ts +2 -2
  86. package/src/application/LegendDataCubeApplicationConfig.ts +12 -0
  87. package/src/components/LegendDataCubeBlockingWindow.tsx +120 -0
  88. package/src/components/LegendDataCubeWebApplication.tsx +3 -3
  89. package/src/components/builder/LegendDataCubeBuilder.tsx +331 -0
  90. package/src/components/{query-builder/LegendDataCubeQueryBuilderStoreProvider.tsx → builder/LegendDataCubeBuilderStoreProvider.tsx} +19 -16
  91. package/src/components/{query-builder/LegendDataCubeNewQueryBuilder.tsx → builder/LegendDataCubeCreator.tsx} +9 -9
  92. package/src/components/builder/LegendDataCubeDeleteConfirmation.tsx +87 -0
  93. package/src/components/{query-builder/LegendDataCubeQueryLoader.tsx → builder/LegendDataCubeLoader.tsx} +122 -59
  94. package/src/components/builder/LegendDataCubeSaver.tsx +184 -0
  95. package/src/components/builder/LegendDataCubeSourceViewer.tsx +108 -0
  96. package/src/components/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilder.tsx +1 -1
  97. package/src/components/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilder.tsx +16 -15
  98. package/src/stores/LegendDataCubeCacheManager.ts +11 -12
  99. package/src/stores/LegendDataCubeDataCubeEngine.ts +4 -14
  100. package/src/stores/builder/LegendDataCubeBuilderStore.tsx +516 -0
  101. package/src/stores/{query-builder/LegendDataCubeNewQueryState.tsx → builder/LegendDataCubeCreatorState.tsx} +23 -21
  102. package/src/stores/builder/LegendDataCubeLoaderState.tsx +248 -0
  103. package/src/stores/{query-builder/source-builder → builder/source}/LegendDataCubeSourceBuilderState.ts +1 -1
  104. package/tsconfig.json +16 -13
  105. package/lib/components/query-builder/LegendDataCubeNewQueryBuilder.d.ts.map +0 -1
  106. package/lib/components/query-builder/LegendDataCubeNewQueryBuilder.js.map +0 -1
  107. package/lib/components/query-builder/LegendDataCubeQueryBuilder.d.ts.map +0 -1
  108. package/lib/components/query-builder/LegendDataCubeQueryBuilder.js +0 -93
  109. package/lib/components/query-builder/LegendDataCubeQueryBuilder.js.map +0 -1
  110. package/lib/components/query-builder/LegendDataCubeQueryBuilderStoreProvider.d.ts +0 -19
  111. package/lib/components/query-builder/LegendDataCubeQueryBuilderStoreProvider.d.ts.map +0 -1
  112. package/lib/components/query-builder/LegendDataCubeQueryBuilderStoreProvider.js +0 -33
  113. package/lib/components/query-builder/LegendDataCubeQueryBuilderStoreProvider.js.map +0 -1
  114. package/lib/components/query-builder/LegendDataCubeQueryLoader.d.ts.map +0 -1
  115. package/lib/components/query-builder/LegendDataCubeQueryLoader.js +0 -97
  116. package/lib/components/query-builder/LegendDataCubeQueryLoader.js.map +0 -1
  117. package/lib/components/query-builder/LegendDataCubeQuerySaver.d.ts.map +0 -1
  118. package/lib/components/query-builder/LegendDataCubeQuerySaver.js +0 -51
  119. package/lib/components/query-builder/LegendDataCubeQuerySaver.js.map +0 -1
  120. package/lib/components/query-builder/source-builder/AdhocQueryDataCubeSourceBuilder.d.ts.map +0 -1
  121. package/lib/components/query-builder/source-builder/AdhocQueryDataCubeSourceBuilder.js.map +0 -1
  122. package/lib/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.d.ts.map +0 -1
  123. package/lib/components/query-builder/source-builder/LegendQueryDataCubeSourceBuilder.js.map +0 -1
  124. package/lib/stores/query-builder/LegendDataCubeNewQueryState.d.ts.map +0 -1
  125. package/lib/stores/query-builder/LegendDataCubeNewQueryState.js.map +0 -1
  126. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.d.ts +0 -58
  127. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.d.ts.map +0 -1
  128. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.js +0 -228
  129. package/lib/stores/query-builder/LegendDataCubeQueryBuilderStore.js.map +0 -1
  130. package/lib/stores/query-builder/LegendDataCubeQueryLoaderState.d.ts.map +0 -1
  131. package/lib/stores/query-builder/LegendDataCubeQueryLoaderState.js +0 -198
  132. package/lib/stores/query-builder/LegendDataCubeQueryLoaderState.js.map +0 -1
  133. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.d.ts.map +0 -1
  134. package/lib/stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.js.map +0 -1
  135. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.d.ts.map +0 -1
  136. package/lib/stores/query-builder/source-builder/LegendDataCubeSourceBuilderState.js.map +0 -1
  137. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.d.ts.map +0 -1
  138. package/lib/stores/query-builder/source-builder/LegendQueryDataCubeSourceBuilderState.js.map +0 -1
  139. package/src/components/query-builder/LegendDataCubeQueryBuilder.tsx +0 -164
  140. package/src/components/query-builder/LegendDataCubeQuerySaver.tsx +0 -116
  141. package/src/stores/query-builder/LegendDataCubeQueryBuilderStore.tsx +0 -323
  142. package/src/stores/query-builder/LegendDataCubeQueryLoaderState.tsx +0 -260
  143. /package/lib/components/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilder.js +0 -0
  144. /package/lib/stores/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilderState.d.ts +0 -0
  145. /package/lib/stores/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilderState.js +0 -0
  146. /package/lib/stores/{query-builder/source-builder → builder/source}/LegendDataCubeSourceBuilderState.d.ts +0 -0
  147. /package/lib/stores/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilderState.d.ts +0 -0
  148. /package/lib/stores/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilderState.js +0 -0
  149. /package/src/stores/{query-builder/source-builder → builder/source}/AdhocQueryDataCubeSourceBuilderState.ts +0 -0
  150. /package/src/stores/{query-builder/source-builder → builder/source}/LegendQueryDataCubeSourceBuilderState.ts +0 -0
@@ -15,7 +15,13 @@
15
15
  */
16
16
 
17
17
  import { observer } from 'mobx-react-lite';
18
- import { cn, DataCubeIcon, useDropdownMenu } from '@finos/legend-art';
18
+ import {
19
+ cn,
20
+ DataCubeIcon,
21
+ DropdownMenu,
22
+ DropdownMenuItem,
23
+ useDropdownMenu,
24
+ } from '@finos/legend-art';
19
25
  import {
20
26
  debounce,
21
27
  formatDistanceToNow,
@@ -30,29 +36,30 @@ import {
30
36
  FormDropdownMenuTrigger,
31
37
  FormTextInput,
32
38
  } from '@finos/legend-data-cube';
33
- import { useLegendDataCubeQueryBuilderStore } from './LegendDataCubeQueryBuilderStoreProvider.js';
39
+ import { useLegendDataCubeBuilderStore } from './LegendDataCubeBuilderStoreProvider.js';
34
40
  import {
35
- DATA_CUBE_QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT,
36
- DataCubeQuerySortByType,
37
- } from '../../stores/query-builder/LegendDataCubeQueryLoaderState.js';
41
+ DATA_CUBE_LOADER_TYPEAHEAD_SEARCH_LIMIT,
42
+ DataCubeSortByType,
43
+ } from '../../stores/builder/LegendDataCubeLoaderState.js';
44
+ import { useApplicationStore } from '@finos/legend-application';
38
45
 
39
- const LegendDataCubeQuerySearcher = observer(() => {
40
- const store = useLegendDataCubeQueryBuilderStore();
46
+ const LegendDataCubeSearcher = observer(() => {
47
+ const store = useLegendDataCubeBuilderStore();
41
48
  const state = store.loader;
42
49
 
43
50
  const searchInputRef = useRef<HTMLInputElement>(null);
44
- const searchResults = state.queries;
51
+ const searchResults = state.searchResults;
45
52
 
46
53
  useEffect(() => {
47
54
  searchInputRef.current?.focus();
48
55
  }, [state]);
49
56
 
50
57
  // search text
51
- const debouncedLoadQueries = useMemo(
58
+ const debouncedLoader = useMemo(
52
59
  () =>
53
60
  debounce((input: string) => {
54
61
  state
55
- .searchQueries(input)
62
+ .searchDataCubes(input)
56
63
  .catch((error) => store.alertService.alertUnhandledError(error));
57
64
  }, 500),
58
65
  [store, state],
@@ -62,21 +69,21 @@ const LegendDataCubeQuerySearcher = observer(() => {
62
69
  ) => {
63
70
  if (event.target.value !== state.searchText) {
64
71
  state.setSearchText(event.target.value);
65
- debouncedLoadQueries.cancel();
66
- debouncedLoadQueries(event.target.value);
72
+ debouncedLoader.cancel();
73
+ debouncedLoader(event.target.value);
67
74
  }
68
75
  };
69
76
  const clearSearches = () => {
70
77
  state.setSearchText('');
71
- debouncedLoadQueries.cancel();
72
- debouncedLoadQueries('');
78
+ debouncedLoader.cancel();
79
+ debouncedLoader('');
73
80
  };
74
81
 
75
82
  // filter and sort
76
- const toggleShowCurrentUserQueriesOnly = () => {
77
- state.setShowCurrentUserQueriesOnly(!state.showCurrentUserQueriesOnly);
78
- debouncedLoadQueries.cancel();
79
- debouncedLoadQueries(state.searchText);
83
+ const toggleShowCurrentUserResultsOnly = () => {
84
+ state.setShowCurrentUserResultsOnly(!state.showCurrentUserResultsOnly);
85
+ debouncedLoader.cancel();
86
+ debouncedLoader(state.searchText);
80
87
  };
81
88
 
82
89
  const [
@@ -85,15 +92,15 @@ const LegendDataCubeQuerySearcher = observer(() => {
85
92
  sortDropdownProps,
86
93
  sortDropdownPropsOpen,
87
94
  ] = useDropdownMenu();
88
- const applySort = (value: DataCubeQuerySortByType) => {
95
+ const applySort = (value: DataCubeSortByType) => {
89
96
  state.setSortBy(value);
90
- debouncedLoadQueries.cancel();
91
- debouncedLoadQueries(state.searchText);
97
+ debouncedLoader.cancel();
98
+ debouncedLoader(state.searchText);
92
99
  };
93
100
 
94
101
  useEffect(() => {
95
102
  state
96
- .searchQueries('')
103
+ .searchDataCubes('')
97
104
  .catch((error) => store.alertService.alertUnhandledError(error));
98
105
  }, [store, state]);
99
106
 
@@ -108,7 +115,7 @@ const LegendDataCubeQuerySearcher = observer(() => {
108
115
  })}
109
116
  onChange={onSearchTextChange}
110
117
  value={state.searchText}
111
- placeholder="Search for queries by name or ID"
118
+ placeholder="Search for DataCube(s) by name or ID"
112
119
  />
113
120
  <div className="absolute flex aspect-square h-full items-center justify-center">
114
121
  <DataCubeIcon.Search className="text-lg text-neutral-600" />
@@ -132,8 +139,8 @@ const LegendDataCubeQuerySearcher = observer(() => {
132
139
  <div className="flex h-6 w-[calc(100%_-_40px)] overflow-x-auto">
133
140
  <FormCheckbox
134
141
  label="Mine Only"
135
- checked={state.showCurrentUserQueriesOnly}
136
- onChange={toggleShowCurrentUserQueriesOnly}
142
+ checked={state.showCurrentUserResultsOnly}
143
+ onChange={toggleShowCurrentUserResultsOnly}
137
144
  />
138
145
  </div>
139
146
  </div>
@@ -148,7 +155,7 @@ const LegendDataCubeQuerySearcher = observer(() => {
148
155
  Sort by: {state.sortBy}
149
156
  </FormDropdownMenuTrigger>
150
157
  <FormDropdownMenu className="w-32" {...sortDropdownProps}>
151
- {Object.values(DataCubeQuerySortByType).map((option) => (
158
+ {Object.values(DataCubeSortByType).map((option) => (
152
159
  <FormDropdownMenuItem
153
160
  key={option}
154
161
  onClick={() => {
@@ -170,15 +177,15 @@ const LegendDataCubeQuerySearcher = observer(() => {
170
177
  {state.searchState.hasCompleted && (
171
178
  <>
172
179
  <div className="mb-1 flex h-5 w-full items-center px-1.5 text-sm text-neutral-600">
173
- {state.showingDefaultQueries ? (
180
+ {state.showingDefaultResults ? (
174
181
  `Refine your search to get better matches`
175
182
  ) : searchResults.length >=
176
- DATA_CUBE_QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (
183
+ DATA_CUBE_LOADER_TYPEAHEAD_SEARCH_LIMIT ? (
177
184
  <>
178
- {`Found ${DATA_CUBE_QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`}{' '}
185
+ {`Found ${DATA_CUBE_LOADER_TYPEAHEAD_SEARCH_LIMIT}+ matches`}{' '}
179
186
  <DataCubeIcon.AlertInfo
180
187
  className="ml-1 text-lg"
181
- title="Some queries are not listed, refine your search to get better matches"
188
+ title="Some DataCubes are not listed, refine your search to get better matches"
182
189
  />
183
190
  </>
184
191
  ) : (
@@ -186,25 +193,25 @@ const LegendDataCubeQuerySearcher = observer(() => {
186
193
  )}
187
194
  </div>
188
195
  {searchResults
189
- .slice(0, DATA_CUBE_QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT)
190
- .map((query, idx) => (
196
+ .slice(0, DATA_CUBE_LOADER_TYPEAHEAD_SEARCH_LIMIT)
197
+ .map((result, idx) => (
191
198
  <div
192
199
  className="mx-1.5 mb-0.5 flex h-[42px] w-[calc(100%_-_12px)] cursor-pointer border border-neutral-200 bg-neutral-100 hover:bg-neutral-200"
193
- key={query.id}
194
- title="Click to choose query"
195
- onClick={() => state.setSelectedQuery(query)}
200
+ key={result.id}
201
+ title="Click to choose DataCube"
202
+ onClick={() => state.setSelectedResult(result)}
196
203
  >
197
204
  <div className="w-[calc(100%_-_16px)]">
198
205
  <div className="h-6 w-4/5 overflow-hidden text-ellipsis whitespace-nowrap px-1.5 leading-6">
199
- {query.name}
206
+ {result.name}
200
207
  </div>
201
208
  <div className="flex h-[18px] items-start justify-between px-1.5">
202
209
  <div className="flex">
203
210
  <DataCubeIcon.ClockEdit className="text-sm text-neutral-500" />
204
211
  <div className="ml-1 text-sm text-neutral-500">
205
- {query.lastUpdatedAt
212
+ {result.lastUpdatedAt
206
213
  ? formatDistanceToNow(
207
- new Date(query.lastUpdatedAt),
214
+ new Date(result.lastUpdatedAt),
208
215
  {
209
216
  includeSeconds: true,
210
217
  addSuffix: true,
@@ -216,7 +223,7 @@ const LegendDataCubeQuerySearcher = observer(() => {
216
223
  <div className="flex">
217
224
  <DataCubeIcon.User className="text-sm text-neutral-500" />
218
225
  <div className="ml-1 text-sm text-neutral-500">
219
- {query.owner}
226
+ {result.owner}
220
227
  </div>
221
228
  </div>
222
229
  </div>
@@ -240,52 +247,108 @@ const LegendDataCubeQuerySearcher = observer(() => {
240
247
  );
241
248
  });
242
249
 
243
- export const LegendDataCubeQueryLoader = observer(() => {
244
- const store = useLegendDataCubeQueryBuilderStore();
250
+ export const LegendDataCubeLoader = observer(() => {
251
+ const store = useLegendDataCubeBuilderStore();
252
+ const application = useApplicationStore();
245
253
  const state = store.loader;
246
- const query = state.selectedQuery;
254
+ const selectedResult = state.selectedResult;
255
+ const [openManageDropdown, closeManageDropdown, manageDropdownProps] =
256
+ useDropdownMenu();
247
257
 
248
258
  return (
249
259
  <>
250
260
  <div className="h-[calc(100%_-_40px)] w-full px-2 pt-2">
251
261
  <div className="h-full w-full overflow-auto border border-neutral-300 bg-white">
252
- {!query ? (
253
- <LegendDataCubeQuerySearcher />
262
+ {!selectedResult ? (
263
+ <LegendDataCubeSearcher />
254
264
  ) : (
255
265
  <div className="h-full w-full p-1.5">
256
- <div className="mb-0.5 flex h-[42px] w-full border border-neutral-200 bg-neutral-100">
266
+ <div className="relative mb-0.5 flex h-[42px] w-full border border-neutral-200 bg-neutral-100">
257
267
  <div className="w-full">
258
268
  <div className="h-6 w-4/5 overflow-hidden text-ellipsis whitespace-nowrap px-1.5 leading-6">
259
- {query.name}
269
+ {selectedResult.name}
260
270
  </div>
271
+ <button
272
+ className="absolute right-0.5 top-0.5 flex aspect-square w-5 items-center justify-center text-neutral-500"
273
+ title="Copy ID to clipboard"
274
+ onClick={() => {
275
+ application.clipboardService
276
+ .copyTextToClipboard(selectedResult.id)
277
+ .catch((error) =>
278
+ store.alertService.alertUnhandledError(error),
279
+ );
280
+ }}
281
+ >
282
+ <DataCubeIcon.Clipboard />
283
+ </button>
261
284
  <div className="flex h-[18px] items-start justify-between px-1.5">
262
285
  <div className="flex">
263
286
  <DataCubeIcon.ClockEdit className="text-sm text-neutral-500" />
264
287
  <div className="ml-1 text-sm text-neutral-500">
265
- {query.lastUpdatedAt
266
- ? formatDistanceToNow(new Date(query.lastUpdatedAt), {
267
- includeSeconds: true,
268
- addSuffix: true,
269
- })
288
+ {selectedResult.lastUpdatedAt
289
+ ? formatDistanceToNow(
290
+ new Date(selectedResult.lastUpdatedAt),
291
+ {
292
+ includeSeconds: true,
293
+ addSuffix: true,
294
+ },
295
+ )
270
296
  : '(unknown)'}
271
297
  </div>
272
298
  </div>
273
299
  <div className="flex">
274
300
  <DataCubeIcon.User className="text-sm text-neutral-500" />
275
301
  <div className="ml-1 text-sm text-neutral-500">
276
- {query.owner}
302
+ {selectedResult.owner}
277
303
  </div>
278
304
  </div>
279
305
  </div>
280
306
  </div>
281
307
  </div>
282
308
 
283
- <FormButton
284
- className="mt-1.5"
285
- onClick={() => state.setSelectedQuery(undefined)}
286
- >
287
- Select Another Query
288
- </FormButton>
309
+ <div className="mt-1.5 flex justify-between">
310
+ <FormButton
311
+ className="flex items-center pl-1"
312
+ onClick={() => state.setSelectedResult(undefined)}
313
+ >
314
+ <DataCubeIcon.ChevronLeft className="mr-0.5" />
315
+ Go Back
316
+ </FormButton>
317
+
318
+ {store.canCurrentUserManageDataCube(selectedResult) && (
319
+ <>
320
+ <FormButton
321
+ className="flex w-[138px] items-center justify-start px-0"
322
+ onClick={openManageDropdown}
323
+ >
324
+ <div className="px-2.5">Manage DataCube</div>
325
+ <div className="flex h-4 w-4 items-center justify-center border-l border-neutral-400">
326
+ <DataCubeIcon.CaretDown className="text-sm" />
327
+ </div>
328
+ </FormButton>
329
+ <DropdownMenu
330
+ {...manageDropdownProps}
331
+ menuProps={{
332
+ classes: {
333
+ paper: 'rounded-none mt-[1px]',
334
+ list: 'w-[138px] p-0 rounded-none border border-neutral-400 bg-white max-h-40 overflow-y-auto py-0.5',
335
+ },
336
+ }}
337
+ >
338
+ <DropdownMenuItem
339
+ className="flex h-[22px] w-full items-center px-2.5 text-base hover:bg-neutral-100 focus:bg-neutral-100"
340
+ onClick={() => {
341
+ store.setDataCubeToDelete(selectedResult);
342
+ store.deleteConfirmationDisplay.open();
343
+ closeManageDropdown();
344
+ }}
345
+ >
346
+ Delete...
347
+ </DropdownMenuItem>
348
+ </DropdownMenu>
349
+ </>
350
+ )}
351
+ </div>
289
352
  </div>
290
353
  )}
291
354
  </div>
@@ -294,7 +357,7 @@ export const LegendDataCubeQueryLoader = observer(() => {
294
357
  <FormButton onClick={() => state.display.close()}>Cancel</FormButton>
295
358
  <FormButton
296
359
  className="ml-2"
297
- disabled={!query || state.finalizeState.isInProgress}
360
+ disabled={!selectedResult || state.finalizeState.isInProgress}
298
361
  onClick={() => {
299
362
  state
300
363
  .finalize()
@@ -0,0 +1,184 @@
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
+ DataCubeSpecification,
19
+ DEFAULT_REPORT_NAME,
20
+ FormBadge_Advanced,
21
+ FormButton,
22
+ FormCheckbox,
23
+ FormTextInput,
24
+ } from '@finos/legend-data-cube';
25
+ import { observer } from 'mobx-react-lite';
26
+ import { useEffect, useState } from 'react';
27
+ import { useLegendDataCubeBuilderStore } from './LegendDataCubeBuilderStoreProvider.js';
28
+ import { guaranteeNonNullable, returnUndefOnError } from '@finos/legend-shared';
29
+
30
+ export const LegendDataCubeSaver = observer(() => {
31
+ const [name, setName] = useState(DEFAULT_REPORT_NAME);
32
+ const [syncName, setSyncName] = useState(false);
33
+ const [autoEnableCache, setAutoEnableCache] = useState(false);
34
+ const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);
35
+ const store = useLegendDataCubeBuilderStore();
36
+ const builder = guaranteeNonNullable(store.builder);
37
+
38
+ useEffect(() => {
39
+ const persistentDataCube = builder.persistentDataCube;
40
+ const latestSpecification = persistentDataCube
41
+ ? returnUndefOnError(() =>
42
+ DataCubeSpecification.serialization.fromJson(
43
+ persistentDataCube.content,
44
+ ),
45
+ )
46
+ : undefined;
47
+
48
+ setName(
49
+ persistentDataCube?.name ??
50
+ builder.initialSpecification.configuration?.name ??
51
+ DEFAULT_REPORT_NAME,
52
+ );
53
+ setSyncName(false);
54
+ setAutoEnableCache(latestSpecification?.options?.autoEnableCache ?? false);
55
+ }, [builder]);
56
+
57
+ return (
58
+ <>
59
+ <div className="h-[calc(100%_-_40px)] w-full px-2 pt-2">
60
+ <div className="h-full w-full overflow-auto border border-neutral-300 bg-white">
61
+ <div className="h-full w-full select-none p-2">
62
+ <div className="flex h-5 w-full items-center">
63
+ <div className="flex h-full w-20 flex-shrink-0 items-center text-sm">
64
+ Name:
65
+ </div>
66
+ <FormTextInput
67
+ className="w-80"
68
+ value={name}
69
+ onChange={(event) => {
70
+ setName(event.target.value);
71
+ }}
72
+ autoFocus={true}
73
+ />
74
+ </div>
75
+ <div className="mt-2 flex h-5 w-full items-center">
76
+ <div className="flex h-full w-20 flex-shrink-0" />
77
+ <FormCheckbox
78
+ label="Ensure report name is in sync with DataCube name"
79
+ checked={syncName}
80
+ onChange={() => setSyncName(!syncName)}
81
+ />
82
+ </div>
83
+ {showAdvancedSettings && (
84
+ <>
85
+ <div className="my-2 h-[1px] w-full bg-neutral-200" />
86
+ <div className="mt-2 flex h-5 w-full items-center">
87
+ <div className="flex h-full w-20 flex-shrink-0 items-center text-sm">
88
+ Caching:
89
+ </div>
90
+ <FormCheckbox
91
+ label="Auto-enable caching"
92
+ checked={autoEnableCache}
93
+ onChange={() => setAutoEnableCache(!autoEnableCache)}
94
+ />
95
+ <FormBadge_Advanced />
96
+ </div>
97
+ </>
98
+ )}
99
+ </div>
100
+ </div>
101
+ </div>
102
+ <div className="flex h-10 items-center justify-between px-2">
103
+ <div className="flex h-full items-center pl-1">
104
+ <FormCheckbox
105
+ label="Show advanced settings?"
106
+ checked={showAdvancedSettings}
107
+ onChange={() => setShowAdvancedSettings(!showAdvancedSettings)}
108
+ />
109
+ <FormBadge_Advanced />
110
+ </div>
111
+ <div className="flex">
112
+ <FormButton onClick={() => store.saverDisplay.close()}>
113
+ Cancel
114
+ </FormButton>
115
+ {builder.persistentDataCube ? (
116
+ // updating existing DataCube
117
+ <>
118
+ <FormButton
119
+ className="ml-2"
120
+ disabled={
121
+ !builder.dataCube ||
122
+ store.saveState.isInProgress ||
123
+ !store.canCurrentUserManageDataCube(
124
+ builder.persistentDataCube,
125
+ )
126
+ }
127
+ onClick={() => {
128
+ store
129
+ .saveDataCube(name, {
130
+ syncName,
131
+ autoEnableCache,
132
+ saveAsNew: false,
133
+ })
134
+ .catch((error) =>
135
+ store.alertService.alertUnhandledError(error),
136
+ );
137
+ }}
138
+ >
139
+ Save
140
+ </FormButton>
141
+ <FormButton
142
+ className="ml-2"
143
+ disabled={!builder.dataCube || store.saveState.isInProgress}
144
+ onClick={() => {
145
+ store
146
+ .saveDataCube(name, {
147
+ syncName,
148
+ autoEnableCache,
149
+ saveAsNew: true,
150
+ })
151
+ .catch((error) =>
152
+ store.alertService.alertUnhandledError(error),
153
+ );
154
+ }}
155
+ >
156
+ Save As
157
+ </FormButton>
158
+ </>
159
+ ) : (
160
+ // creating new DataCube
161
+ <>
162
+ <FormButton
163
+ className="ml-2"
164
+ disabled={!builder.dataCube || store.saveState.isInProgress}
165
+ onClick={() => {
166
+ store
167
+ .createNewDataCube(name, {
168
+ syncName,
169
+ autoEnableCache,
170
+ })
171
+ .catch((error) =>
172
+ store.alertService.alertUnhandledError(error),
173
+ );
174
+ }}
175
+ >
176
+ Save
177
+ </FormButton>
178
+ </>
179
+ )}
180
+ </div>
181
+ </div>
182
+ </>
183
+ );
184
+ });
@@ -0,0 +1,108 @@
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 { observer } from 'mobx-react-lite';
18
+ import { useLegendDataCubeBuilderStore } from './LegendDataCubeBuilderStoreProvider.js';
19
+ import { LegendQueryDataCubeSource } from '../../stores/model/LegendQueryDataCubeSource.js';
20
+ import { useLegendDataCubeApplicationStore } from '../LegendDataCubeFrameworkProvider.js';
21
+ import { EXTERNAL_APPLICATION_NAVIGATION__generateQueryViewUrl } from '../../__lib__/LegendDataCubeNavigation.js';
22
+ import { DataCubeIcon } from '@finos/legend-art';
23
+
24
+ export const LegendDataCubeSourceViewer = observer(() => {
25
+ const store = useLegendDataCubeBuilderStore();
26
+ const source = store.builder?.source;
27
+ const application = useLegendDataCubeApplicationStore();
28
+
29
+ if (!source) {
30
+ return null;
31
+ }
32
+ if (source instanceof LegendQueryDataCubeSource) {
33
+ const link = application.config.queryApplicationUrl
34
+ ? EXTERNAL_APPLICATION_NAVIGATION__generateQueryViewUrl(
35
+ application.config.queryApplicationUrl,
36
+ source.info.id,
37
+ )
38
+ : undefined;
39
+ return (
40
+ <div className="h-full w-full px-2 pt-2">
41
+ <div className="h-[calc(100%_-_8px)] w-full border border-neutral-300 bg-white">
42
+ <div className="h-full w-full select-none p-2">
43
+ <div className="flex h-6">
44
+ <div className="flex h-6 items-center text-xl font-medium">
45
+ <DataCubeIcon.Table />
46
+ </div>
47
+ <div className="ml-1 flex h-6 items-center text-xl font-medium">
48
+ Legend Query
49
+ </div>
50
+ </div>
51
+ {link && (
52
+ <div className="mt-2 flex h-6 w-full">
53
+ <div className="flex h-full w-[calc(100%_-_20px)] items-center border border-r-0 border-neutral-400 px-1.5 font-bold text-sky-500 underline">
54
+ <a
55
+ href={link}
56
+ target="_blank"
57
+ rel="noopener noreferrer"
58
+ className="overflow-hidden overflow-ellipsis whitespace-nowrap"
59
+ >
60
+ {link}
61
+ </a>
62
+ </div>
63
+ <button
64
+ className="flex aspect-square h-full w-6 items-center justify-center border border-neutral-400 bg-neutral-300 hover:brightness-95"
65
+ onClick={() => {
66
+ store.application.clipboardService
67
+ .copyTextToClipboard(link)
68
+ .catch((error) =>
69
+ store.alertService.alertUnhandledError(error),
70
+ );
71
+ }}
72
+ title="Copy Link"
73
+ >
74
+ <DataCubeIcon.Clipboard />
75
+ </button>
76
+ </div>
77
+ )}
78
+ {!link && (
79
+ <div className="mt-2 flex h-6 w-full">
80
+ <div className="flex h-full w-[calc(100%_-_20px)] items-center border border-r-0 border-neutral-400 bg-neutral-200 px-1.5">
81
+ <div className="overflow-hidden overflow-ellipsis whitespace-nowrap">
82
+ {source.info.id}
83
+ </div>
84
+ </div>
85
+ <button
86
+ className="flex aspect-square h-full w-6 items-center justify-center border border-neutral-400 bg-neutral-300 hover:brightness-95"
87
+ onClick={() => {
88
+ application.clipboardService
89
+ .copyTextToClipboard(source.info.id)
90
+ .catch((error) =>
91
+ store.alertService.alertUnhandledError(error),
92
+ );
93
+ }}
94
+ title="Copy ID"
95
+ >
96
+ <DataCubeIcon.Clipboard />
97
+ </button>
98
+ </div>
99
+ )}
100
+ </div>
101
+ </div>
102
+ </div>
103
+ );
104
+ }
105
+ return (
106
+ <div className="h-full w-full px-2 pt-2">{`Can't display source`}</div>
107
+ );
108
+ });
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import { observer } from 'mobx-react-lite';
18
- import type { AdhocQueryDataCubeSourceBuilderState } from '../../../stores/query-builder/source-builder/AdhocQueryDataCubeSourceBuilderState.js';
18
+ import type { AdhocQueryDataCubeSourceBuilderState } from '../../../stores/builder/source/AdhocQueryDataCubeSourceBuilderState.js';
19
19
  import { FormBadge_WIP } from '@finos/legend-data-cube';
20
20
 
21
21
  export const AdhocQueryDataCubeSourceBuilder = observer(