@finos/legend-application-repl 0.0.20 → 0.0.21

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 (116) hide show
  1. package/lib/application/LegendREPLGridClient.d.ts +0 -2
  2. package/lib/application/LegendREPLGridClient.d.ts.map +1 -1
  3. package/lib/application/LegendREPLGridClient.js +6 -33
  4. package/lib/application/LegendREPLGridClient.js.map +1 -1
  5. package/lib/components/AgGrid.d.ts +3 -2
  6. package/lib/components/AgGrid.d.ts.map +1 -1
  7. package/lib/components/AgGrid.js +1 -1
  8. package/lib/components/AgGrid.js.map +1 -1
  9. package/lib/components/LegendREPLGridClientApplication.d.ts +7 -0
  10. package/lib/components/LegendREPLGridClientApplication.d.ts.map +1 -1
  11. package/lib/components/LegendREPLGridClientApplication.js +12 -5
  12. package/lib/components/LegendREPLGridClientApplication.js.map +1 -1
  13. package/lib/components/REPLGridClient.d.ts +11 -2
  14. package/lib/components/REPLGridClient.d.ts.map +1 -1
  15. package/lib/components/REPLGridClient.js +107 -30
  16. package/lib/components/REPLGridClient.js.map +1 -1
  17. package/lib/components/dataCube/DataCubeGridEditor.d.ts +22 -0
  18. package/lib/components/dataCube/DataCubeGridEditor.d.ts.map +1 -0
  19. package/lib/components/dataCube/DataCubeGridEditor.js +37 -0
  20. package/lib/components/dataCube/DataCubeGridEditor.js.map +1 -0
  21. package/lib/components/dataCube/DataCubeQueryTextEditor.d.ts +22 -0
  22. package/lib/components/dataCube/DataCubeQueryTextEditor.d.ts.map +1 -0
  23. package/lib/components/{REPLQueryEditor.js → dataCube/DataCubeQueryTextEditor.js} +26 -44
  24. package/lib/components/dataCube/DataCubeQueryTextEditor.js.map +1 -0
  25. package/lib/components/grid/GridUtils.d.ts +4 -2
  26. package/lib/components/grid/GridUtils.d.ts.map +1 -1
  27. package/lib/components/grid/GridUtils.js +37 -2
  28. package/lib/components/grid/GridUtils.js.map +1 -1
  29. package/lib/components/grid/ServerSideDataSource.d.ts.map +1 -1
  30. package/lib/components/grid/ServerSideDataSource.js +8 -5
  31. package/lib/components/grid/ServerSideDataSource.js.map +1 -1
  32. package/lib/components/grid/TDSLambdaBuilder.d.ts.map +1 -1
  33. package/lib/components/grid/TDSLambdaBuilder.js +1 -1
  34. package/lib/components/grid/TDSLambdaBuilder.js.map +1 -1
  35. package/lib/components/grid/TDSQuery.d.ts +25 -0
  36. package/lib/components/grid/TDSQuery.d.ts.map +1 -0
  37. package/lib/components/grid/TDSQuery.js +32 -0
  38. package/lib/components/grid/TDSQuery.js.map +1 -0
  39. package/lib/components/grid/TDSRequest.d.ts +15 -2
  40. package/lib/components/grid/TDSRequest.d.ts.map +1 -1
  41. package/lib/components/grid/TDSRequest.js +52 -0
  42. package/lib/components/grid/TDSRequest.js.map +1 -1
  43. package/lib/grid.css +1 -1
  44. package/lib/index.css +2 -2
  45. package/lib/index.css.map +1 -1
  46. package/lib/package.json +12 -12
  47. package/lib/repl.css +2 -2
  48. package/lib/repl.css.map +1 -1
  49. package/lib/server/REPLServerClient.d.ts +3 -0
  50. package/lib/server/REPLServerClient.d.ts.map +1 -1
  51. package/lib/server/REPLServerClient.js +2 -0
  52. package/lib/server/REPLServerClient.js.map +1 -1
  53. package/lib/stores/REPLGridClientStore.d.ts +2 -13
  54. package/lib/stores/REPLGridClientStore.d.ts.map +1 -1
  55. package/lib/stores/REPLGridClientStore.js +6 -144
  56. package/lib/stores/REPLGridClientStore.js.map +1 -1
  57. package/lib/stores/dataCube/DataCubeConfigState.d.ts +32 -0
  58. package/lib/stores/dataCube/DataCubeConfigState.d.ts.map +1 -0
  59. package/lib/stores/dataCube/DataCubeConfigState.js +62 -0
  60. package/lib/stores/dataCube/DataCubeConfigState.js.map +1 -0
  61. package/lib/stores/{REPLGridState.d.ts → dataCube/DataCubeGridState.d.ts} +11 -12
  62. package/lib/stores/dataCube/DataCubeGridState.d.ts.map +1 -0
  63. package/lib/stores/dataCube/DataCubeGridState.js +108 -0
  64. package/lib/stores/dataCube/DataCubeGridState.js.map +1 -0
  65. package/lib/stores/dataCube/DataCubePanelState.d.ts +23 -0
  66. package/lib/stores/dataCube/DataCubePanelState.d.ts.map +1 -0
  67. package/lib/stores/dataCube/DataCubePanelState.js +22 -0
  68. package/lib/stores/dataCube/DataCubePanelState.js.map +1 -0
  69. package/lib/stores/dataCube/DataCubePropertiesPanelState.d.ts +34 -0
  70. package/lib/stores/dataCube/DataCubePropertiesPanelState.d.ts.map +1 -0
  71. package/lib/stores/dataCube/DataCubePropertiesPanelState.js +57 -0
  72. package/lib/stores/dataCube/DataCubePropertiesPanelState.js.map +1 -0
  73. package/lib/{components/REPLQueryEditor.d.ts → stores/dataCube/DataCubeQueryEditorState.d.ts} +2 -5
  74. package/lib/stores/dataCube/DataCubeQueryEditorState.d.ts.map +1 -0
  75. package/lib/stores/dataCube/DataCubeQueryEditorState.js +49 -0
  76. package/lib/stores/dataCube/DataCubeQueryEditorState.js.map +1 -0
  77. package/lib/stores/dataCube/DataCubeQueryTextEditorState.d.ts +25 -0
  78. package/lib/stores/dataCube/DataCubeQueryTextEditorState.d.ts.map +1 -0
  79. package/lib/stores/dataCube/DataCubeQueryTextEditorState.js +35 -0
  80. package/lib/stores/dataCube/DataCubeQueryTextEditorState.js.map +1 -0
  81. package/lib/stores/dataCube/DataCubeState.d.ts +41 -0
  82. package/lib/stores/dataCube/DataCubeState.d.ts.map +1 -0
  83. package/lib/stores/dataCube/DataCubeState.js +208 -0
  84. package/lib/stores/dataCube/DataCubeState.js.map +1 -0
  85. package/lib/stores/dataCube/HPivotAndSortPanelState.d.ts +40 -0
  86. package/lib/stores/dataCube/HPivotAndSortPanelState.d.ts.map +1 -0
  87. package/lib/stores/dataCube/HPivotAndSortPanelState.js +130 -0
  88. package/lib/stores/dataCube/HPivotAndSortPanelState.js.map +1 -0
  89. package/package.json +18 -18
  90. package/src/application/LegendREPLGridClient.tsx +5 -55
  91. package/src/components/AgGrid.tsx +2 -6
  92. package/src/components/LegendREPLGridClientApplication.tsx +18 -1
  93. package/src/components/REPLGridClient.tsx +445 -111
  94. package/src/components/dataCube/DataCubeGridEditor.tsx +69 -0
  95. package/src/components/{REPLQueryEditor.tsx → dataCube/DataCubeQueryTextEditor.tsx} +87 -58
  96. package/src/components/grid/GridUtils.ts +47 -3
  97. package/src/components/grid/ServerSideDataSource.ts +17 -4
  98. package/src/components/grid/TDSLambdaBuilder.ts +5 -1
  99. package/src/components/grid/TDSQuery.ts +37 -0
  100. package/src/components/grid/TDSRequest.ts +80 -2
  101. package/src/server/REPLServerClient.ts +17 -0
  102. package/src/stores/REPLGridClientStore.ts +6 -248
  103. package/src/stores/dataCube/DataCubeConfigState.ts +79 -0
  104. package/src/stores/{REPLGridState.ts → dataCube/DataCubeGridState.ts} +65 -30
  105. package/src/stores/dataCube/DataCubePanelState.ts +28 -0
  106. package/src/stores/dataCube/DataCubePropertiesPanelState.ts +65 -0
  107. package/src/stores/dataCube/DataCubeQueryEditorState.ts +66 -0
  108. package/src/stores/dataCube/DataCubeQueryTextEditorState.ts +41 -0
  109. package/src/stores/dataCube/DataCubeState.ts +333 -0
  110. package/src/stores/dataCube/HPivotAndSortPanelState.ts +170 -0
  111. package/tsconfig.json +11 -2
  112. package/lib/components/REPLQueryEditor.d.ts.map +0 -1
  113. package/lib/components/REPLQueryEditor.js.map +0 -1
  114. package/lib/stores/REPLGridState.d.ts.map +0 -1
  115. package/lib/stores/REPLGridState.js +0 -86
  116. package/lib/stores/REPLGridState.js.map +0 -1
@@ -15,35 +15,419 @@
15
15
  */
16
16
 
17
17
  import { observer } from 'mobx-react-lite';
18
- import {
19
- useREPLGridClientStore,
20
- withEditorStore,
21
- } from './REPLGridClientStoreProvider.js';
22
- import { AgGridComponent } from './AgGrid.js';
23
- import { useEffect } from 'react';
18
+ import { useREPLGridClientStore } from './REPLGridClientStoreProvider.js';
19
+ import { useEffect, useRef } from 'react';
24
20
  import { flowResult } from 'mobx';
25
- import { getTDSRowData } from '../components/grid/GridUtils.js';
26
- import { ServerSideDataSource } from '../components/grid/ServerSideDataSource.js';
27
21
  import { LEGEND_APPLICATION_COLOR_THEME } from '@finos/legend-application';
28
22
  import {
29
- CODE_EDITOR_LANGUAGE,
30
- CODE_EDITOR_THEME,
31
- CodeEditor,
32
- } from '@finos/legend-lego/code-editor';
33
- import {
23
+ BasePopover,
34
24
  CheckSquareIcon,
35
- PanelLoadingIndicator,
36
- PlayIcon,
25
+ Modal,
26
+ ModalBody,
27
+ ModalFooter,
28
+ ModalFooterButton,
29
+ ModalHeader,
30
+ ModalHeaderActions,
31
+ ModalTitle,
32
+ PlusIcon,
33
+ SearchIcon,
37
34
  SquareIcon,
35
+ TimesIcon,
38
36
  clsx,
37
+ ChevronLeftIcon,
38
+ ChevronRightIcon,
39
+ CustomSelectorInput,
39
40
  } from '@finos/legend-art';
40
41
  import { LEGEND_APPLICATION_REPL_SETTING_KEY } from '../Const.js';
42
+ import { useParams } from '@finos/legend-application/browser';
43
+ import {
44
+ LEGEND_REPL_GRID_CLIENT_PATTERN_TOKEN,
45
+ type REPLQueryEditorPathParams,
46
+ } from './LegendREPLGridClientApplication.js';
47
+ import type { REPLGridClientStore } from '../stores/REPLGridClientStore.js';
48
+ import { DataCubeQueryTextEditor } from './dataCube/DataCubeQueryTextEditor.js';
49
+ import { DataCubeGridEditor } from './dataCube/DataCubeGridEditor.js';
50
+ import { PIVOT_PANEL_TABS } from '../stores/dataCube/DataCubePropertiesPanelState.js';
51
+ import { TDS_SORT_ORDER } from './grid/TDSRequest.js';
41
52
 
42
- import { QueryEditor } from './REPLQueryEditor.js';
53
+ type SortOption = {
54
+ label: string;
55
+ value: TDS_SORT_ORDER;
56
+ };
43
57
 
44
- export const Editor = withEditorStore(
45
- observer(() => {
58
+ const HPivotAndSortEditor = observer(
59
+ (props: { editorStore: REPLGridClientStore }) => {
60
+ const { editorStore } = props;
61
+ const hPivotAndSortColumnState =
62
+ editorStore.dataCubeState.propertiesPanelState.hpivotAndSortPanelState;
63
+ const onAvailabeSortColumnsSearchTextChange: React.ChangeEventHandler<
64
+ HTMLInputElement
65
+ > = (event) => {
66
+ hPivotAndSortColumnState.setAvailableSortColumnsSearchText(
67
+ event.target.value,
68
+ );
69
+ };
70
+ const onSelectedSortColumnsSearchTextChange: React.ChangeEventHandler<
71
+ HTMLInputElement
72
+ > = (event) => {
73
+ hPivotAndSortColumnState.setSelectedSortColumnsSearchText(
74
+ event.target.value,
75
+ );
76
+ };
77
+ const clearAvailableSortColumnsSearchText = (): void => {
78
+ hPivotAndSortColumnState.setAvailableSortColumnsSearchText('');
79
+ };
80
+ const clearSelectedSortColumnsSearchText = (): void => {
81
+ hPivotAndSortColumnState.setSelectedSortColumnsSearchText('');
82
+ };
83
+ const sortOptions = Array.from(Object.values(TDS_SORT_ORDER)).map(
84
+ (val) => ({
85
+ label: val,
86
+ value: val,
87
+ }),
88
+ );
89
+ const onAvailableColumnsSortOptionsChanged = (
90
+ columnName: string,
91
+ ): ((option: SortOption) => void) =>
92
+ function AvailableColumnSortOption(option: SortOption): void {
93
+ const column = hPivotAndSortColumnState.availableSortColumns.find(
94
+ (col) => col.column === columnName,
95
+ );
96
+ if (column) {
97
+ column.setOrder(option.value);
98
+ }
99
+ };
100
+
101
+ const onSelectedColumnsSortOptionsChanged = (
102
+ columnName: string,
103
+ ): ((option: SortOption) => void) =>
104
+ function SelectedColumnSortOption(option: SortOption): void {
105
+ const column = hPivotAndSortColumnState.selectedSortColumns.find(
106
+ (col) => col.column === columnName,
107
+ );
108
+ if (column) {
109
+ column.setOrder(option.value);
110
+ }
111
+ };
112
+
113
+ return (
114
+ <div className="repl__hpivot__sort__editor">
115
+ <div className="repl__hpivot__sort__column__editor">
116
+ <div className="repl__hpivot__sort__column__editor__header">
117
+ Sorts
118
+ </div>
119
+ <div className="repl__hpivot__sort__column__editor__content">
120
+ <div className="repl__hpivot__sort__column__editor__available__columns">
121
+ <div className="repl__hpivot__sort__column__editor__description">
122
+ Available sort columns:
123
+ </div>
124
+ <div className="repl__hpivot__sort__column__editor__container">
125
+ <div className="query-builder-property-search-panel__header">
126
+ <div className="query-builder-property-search-panel__input__container">
127
+ <input
128
+ className={clsx(
129
+ 'query-builder-property-search-panel__input',
130
+ {
131
+ 'query-builder-property-search-panel__input--searching':
132
+ hPivotAndSortColumnState.availableSortColumnsSearchText,
133
+ },
134
+ )}
135
+ spellCheck={false}
136
+ onChange={onAvailabeSortColumnsSearchTextChange}
137
+ value={
138
+ hPivotAndSortColumnState.availableSortColumnsSearchText
139
+ }
140
+ placeholder="Search"
141
+ />
142
+ {!hPivotAndSortColumnState.availableSortColumnsSearchText ? (
143
+ <>
144
+ <div className="query-builder-property-search-panel__input__search__icon">
145
+ <SearchIcon />
146
+ </div>
147
+ </>
148
+ ) : (
149
+ <button
150
+ className="query-builder-property-search-panel__input__clear-btn"
151
+ tabIndex={-1}
152
+ onClick={clearAvailableSortColumnsSearchText}
153
+ title="Clear"
154
+ >
155
+ <TimesIcon />
156
+ </button>
157
+ )}
158
+ </div>
159
+ </div>
160
+ <div className="repl__hpivot__sort__column__editor__available__columns__content">
161
+ <div
162
+ className="repl__hpivot__sort__column__editor__available__columns__root"
163
+ onDoubleClick={(): void =>
164
+ hPivotAndSortColumnState.addAllAvailableSortColumns()
165
+ }
166
+ >
167
+ <PlusIcon />
168
+ <div className="repl__hpivot__sort__column__editor__available__columns__root__label">
169
+ All
170
+ </div>
171
+ </div>
172
+ {hPivotAndSortColumnState.availableSortColumnsSearchResults.map(
173
+ (col) => (
174
+ <div
175
+ className="repl__hpivot__sort__column__editor__available__columns__children"
176
+ key={col.column}
177
+ >
178
+ <div
179
+ className="repl__hpivot__sort__column__editor__available__columns__children__name"
180
+ onDoubleClick={(): void =>
181
+ hPivotAndSortColumnState.addAvailableSortColumn(
182
+ col.column,
183
+ )
184
+ }
185
+ >
186
+ {col.column}
187
+ </div>
188
+ <CustomSelectorInput
189
+ className="repl__hpivot__sort__column__editor__available__columns__children__order"
190
+ options={sortOptions}
191
+ onChange={onAvailableColumnsSortOptionsChanged(
192
+ col.column,
193
+ )}
194
+ value={{ label: col.order, value: col.order }}
195
+ isClearable={false}
196
+ darkMode={
197
+ !editorStore.applicationStore.layoutService
198
+ .TEMPORARY__isLightColorThemeEnabled
199
+ }
200
+ />
201
+ </div>
202
+ ),
203
+ )}
204
+ </div>
205
+ </div>
206
+ </div>
207
+ <div className="repl__hpivot__sort__column__editor__actions">
208
+ <div className="repl__hpivot__sort__column__editor__action">
209
+ <button
210
+ tabIndex={-1}
211
+ // onClick={clearSearch}
212
+ title="Add"
213
+ >
214
+ Add
215
+ <ChevronRightIcon />
216
+ </button>
217
+ </div>
218
+ <div className="repl__hpivot__sort__column__editor__action">
219
+ <button
220
+ tabIndex={-1}
221
+ // onClick={clearSearch}
222
+ title="Remove"
223
+ >
224
+ <ChevronLeftIcon />
225
+ Remove
226
+ </button>
227
+ </div>
228
+ </div>
229
+ <div className="repl__hpivot__sort__column__editor__selected__columns">
230
+ <div className="repl__hpivot__sort__column__editor__description">
231
+ Selected sort columns:
232
+ </div>
233
+ <div className="repl__hpivot__sort__column__editor__container">
234
+ <div className="query-builder-property-search-panel__header">
235
+ <div className="query-builder-property-search-panel__input__container">
236
+ <input
237
+ className={clsx(
238
+ 'query-builder-property-search-panel__input',
239
+ {
240
+ 'query-builder-property-search-panel__input--searching':
241
+ hPivotAndSortColumnState.selectedSortColumnsSearchText,
242
+ },
243
+ )}
244
+ spellCheck={false}
245
+ onChange={onSelectedSortColumnsSearchTextChange}
246
+ value={
247
+ hPivotAndSortColumnState.selectedSortColumnsSearchText
248
+ }
249
+ placeholder="Search"
250
+ />
251
+ {!hPivotAndSortColumnState.selectedSortColumnsSearchText ? (
252
+ <>
253
+ <div className="query-builder-property-search-panel__input__search__icon">
254
+ <SearchIcon />
255
+ </div>
256
+ </>
257
+ ) : (
258
+ <button
259
+ className="query-builder-property-search-panel__input__clear-btn"
260
+ tabIndex={-1}
261
+ onClick={clearSelectedSortColumnsSearchText}
262
+ title="Clear"
263
+ >
264
+ <TimesIcon />
265
+ </button>
266
+ )}
267
+ </div>
268
+ </div>
269
+ <div className="repl__hpivot__sort__column__editor__available__columns__content">
270
+ <div
271
+ className="repl__hpivot__sort__column__editor__available__columns__root"
272
+ onDoubleClick={(): void =>
273
+ hPivotAndSortColumnState.addAllSelectedSortColumns()
274
+ }
275
+ >
276
+ <PlusIcon />
277
+ <div className="repl__hpivot__sort__column__editor__available__columns__root__label">
278
+ All
279
+ </div>
280
+ </div>
281
+ {hPivotAndSortColumnState.selectedSortColumnsSearchResults.map(
282
+ (col) => (
283
+ <div
284
+ className="repl__hpivot__sort__column__editor__available__columns__children"
285
+ key={col.column}
286
+ >
287
+ <div
288
+ className="repl__hpivot__sort__column__editor__available__columns__children__name"
289
+ onDoubleClick={(): void =>
290
+ hPivotAndSortColumnState.addSelectedSortColumn(
291
+ col.column,
292
+ )
293
+ }
294
+ >
295
+ {col.column}
296
+ </div>
297
+ <CustomSelectorInput
298
+ className="repl__hpivot__sort__column__editor__available__columns__children__order"
299
+ options={sortOptions}
300
+ onChange={onSelectedColumnsSortOptionsChanged(
301
+ col.column,
302
+ )}
303
+ value={{ label: col.order, value: col.order }}
304
+ isClearable={false}
305
+ darkMode={
306
+ !editorStore.applicationStore.layoutService
307
+ .TEMPORARY__isLightColorThemeEnabled
308
+ }
309
+ />
310
+ </div>
311
+ ),
312
+ )}
313
+ </div>
314
+ </div>
315
+ </div>
316
+ </div>
317
+ </div>
318
+ </div>
319
+ );
320
+ },
321
+ );
322
+
323
+ const PivotPanelEditor = observer(
324
+ (props: {
325
+ triggerElement: HTMLElement | null;
326
+ editorStore: REPLGridClientStore;
327
+ }) => {
328
+ const { triggerElement, editorStore } = props;
329
+ const dataCubeState = editorStore.dataCubeState;
330
+ const applicationStore = editorStore.applicationStore;
331
+ const closeEditor = (): void => {
332
+ dataCubeState.configState.closePanel();
333
+ };
334
+ const selectedTab =
335
+ dataCubeState.propertiesPanelState.selectedPivotPanelTab;
336
+ const tabOptions = [
337
+ PIVOT_PANEL_TABS.COLUMNS_AND_PIVOTS,
338
+ PIVOT_PANEL_TABS.HPIVOTS_AND_SORTS,
339
+ PIVOT_PANEL_TABS.GENERAL_PROPERTIES,
340
+ PIVOT_PANEL_TABS.COLUMN_PROPERTIES,
341
+ PIVOT_PANEL_TABS.DEVELOPER_OPTIONS,
342
+ PIVOT_PANEL_TABS.PIVOT_LAYOUT,
343
+ ];
344
+ const setSelectedTab = (tab: PIVOT_PANEL_TABS): void => {
345
+ dataCubeState.propertiesPanelState.setSelectedPivotPanelTab(tab);
346
+ };
347
+ const onClickOk = (): void => {
348
+ dataCubeState.propertiesPanelState.applyChanges();
349
+ dataCubeState.configState.closePanel();
350
+ };
351
+
352
+ return (
353
+ <BasePopover
354
+ open={dataCubeState.configState.isPivotPanelOpened}
355
+ onClose={closeEditor}
356
+ anchorEl={triggerElement}
357
+ anchorOrigin={{
358
+ vertical: 'center',
359
+ horizontal: 'center',
360
+ }}
361
+ transformOrigin={{
362
+ vertical: 'center',
363
+ horizontal: 'center',
364
+ }}
365
+ >
366
+ <Modal
367
+ darkMode={
368
+ !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled
369
+ }
370
+ className="editor-modal embedded-runtime-editor"
371
+ >
372
+ <ModalHeader>
373
+ <ModalTitle title="cube properties" />
374
+ <ModalHeaderActions>
375
+ <button
376
+ className="modal__header__action"
377
+ tabIndex={-1}
378
+ onClick={closeEditor}
379
+ >
380
+ <TimesIcon />
381
+ </button>
382
+ </ModalHeaderActions>
383
+ </ModalHeader>
384
+ <ModalBody>
385
+ <div style={{ height: '100%', width: '100%' }}>
386
+ <div className="panel__header uml-element-editor__tabs__header ">
387
+ <div className="uml-element-editor__tabs">
388
+ {tabOptions.map((tab) => (
389
+ <div
390
+ key={tab}
391
+ onClick={(): void => setSelectedTab(tab)}
392
+ className={clsx('uml-element-editor__tab', {
393
+ 'uml-element-editor__tab--active': tab === selectedTab,
394
+ })}
395
+ >
396
+ {tab}
397
+ </div>
398
+ ))}
399
+ </div>
400
+ </div>
401
+ {selectedTab === PIVOT_PANEL_TABS.HPIVOTS_AND_SORTS && (
402
+ <HPivotAndSortEditor editorStore={editorStore} />
403
+ )}
404
+ </div>
405
+ </ModalBody>
406
+ <ModalFooter className="repl__modal__footer">
407
+ <div className="search-modal__actions">
408
+ <ModalFooterButton text="Ok" onClick={onClickOk} />
409
+ <ModalFooterButton text="Close" onClick={closeEditor} />
410
+ <ModalFooterButton
411
+ text="Apply"
412
+ onClick={(): void =>
413
+ dataCubeState.propertiesPanelState.applyChanges()
414
+ }
415
+ />
416
+ </div>
417
+ </ModalFooter>
418
+ </Modal>
419
+ </BasePopover>
420
+ );
421
+ },
422
+ );
423
+
424
+ export const GenericEditor = observer(
425
+ (props: { queryId?: string | undefined }) => {
426
+ const { queryId } = props;
46
427
  const editorStore = useREPLGridClientStore();
428
+ const dataCubeState = editorStore.dataCubeState;
429
+ const pivotPanelButtonRef = useRef<HTMLDivElement>(null);
430
+
47
431
  const selectDarkTheme = (): void => {
48
432
  editorStore.applicationStore.layoutService.setColorTheme(
49
433
  LEGEND_APPLICATION_COLOR_THEME.DEFAULT_DARK,
@@ -60,47 +444,55 @@ export const Editor = withEditorStore(
60
444
  editorStore.applicationStore.layoutService
61
445
  .TEMPORARY__isLightColorThemeEnabled;
62
446
 
63
- const executeLambda = (): void => {
64
- flowResult(editorStore.executeLambda()).catch(
447
+ const saveQuery = (): void => {
448
+ flowResult(dataCubeState.saveQuery()).catch(
65
449
  editorStore.applicationStore.alertUnhandledError,
66
450
  );
67
451
  };
68
452
 
69
453
  const togglePagination = (): void => {
70
- editorStore.replGridState.setIsPaginationEnabled(
71
- !editorStore.replGridState.isPaginationEnabled,
454
+ dataCubeState.configState.setIsPaginationEnabled(
455
+ !dataCubeState.configState.isPaginationEnabled,
72
456
  );
73
457
  editorStore.applicationStore.settingService.persistValue(
74
458
  LEGEND_APPLICATION_REPL_SETTING_KEY.PAGINATION,
75
- editorStore.replGridState.isPaginationEnabled,
459
+ dataCubeState.configState.isPaginationEnabled,
76
460
  );
77
461
  };
78
462
 
79
463
  useEffect(() => {
80
- flowResult(editorStore.getInitialREPLGridServerResult()).catch(
464
+ flowResult(dataCubeState.getInitialREPLGridServerResult(queryId)).catch(
81
465
  editorStore.applicationStore.alertUnhandledError,
82
466
  );
83
- }, [editorStore]);
467
+ }, [dataCubeState, editorStore, queryId]);
84
468
 
85
469
  return (
86
470
  <div className="repl">
87
471
  <div className="repl__header">
88
472
  <div className="repl__header__content">
89
- <div className="repl__header__content__title">REPL Grid</div>
473
+ <div className="repl__header__content__title">Legend DataCube</div>
90
474
  <div className="repl__header__actions">
475
+ <div
476
+ className="repl__header__action__pagination"
477
+ onClick={(): void => saveQuery()}
478
+ >
479
+ <div className="repl__header__action__pagination__label">
480
+ Save Query
481
+ </div>
482
+ </div>
91
483
  <div className="repl__header__action__pagination">
92
484
  <button
93
485
  className={clsx(
94
486
  'repl__header__action__pagination__toggler__btn',
95
487
  {
96
488
  'repl__header__action__pagination__toggler__btn--toggled':
97
- editorStore.replGridState.isPaginationEnabled,
489
+ dataCubeState.configState.isPaginationEnabled,
98
490
  },
99
491
  )}
100
492
  onClick={togglePagination}
101
493
  tabIndex={-1}
102
494
  >
103
- {editorStore.replGridState.isPaginationEnabled ? (
495
+ {dataCubeState.configState.isPaginationEnabled ? (
104
496
  <CheckSquareIcon />
105
497
  ) : (
106
498
  <SquareIcon />
@@ -134,93 +526,35 @@ export const Editor = withEditorStore(
134
526
  </div>
135
527
  </div>
136
528
  <div className="repl__content">
137
- <div className="repl__content__query">
138
- <div className="repl__query">
139
- <div className="repl__query__editor">
140
- <div className="repl__query__header">
141
- <div className="repl__query__label">Curent Query</div>
142
- <div className="repl__query__execute-btn btn__dropdown-combo btn__dropdown-combo--primary">
143
- <button
144
- className="btn__dropdown-combo__label"
145
- onClick={executeLambda}
146
- tabIndex={-1}
147
- >
148
- <PlayIcon className="btn__dropdown-combo__label__icon" />
149
- <div className="btn__dropdown-combo__label__title">
150
- Run Query
151
- </div>
152
- </button>
153
- </div>
154
- </div>
155
- <div className="repl__query__content">
156
- <QueryEditor />
157
- </div>
158
- </div>
159
- </div>
160
- {editorStore.replGridState.currentSubQuery !== undefined && (
161
- <div className="repl__query">
162
- <div className="repl__query__editor">
163
- <div className="repl__query__header">
164
- <div className="repl__query__label__sub__query">
165
- Current Row Group Sub Query
166
- </div>
167
- <div className="repl__query__label__sub__query__read--only">
168
- Read Only
169
- </div>
170
- </div>
171
- <div className="repl__query__content">
172
- <CodeEditor
173
- lightTheme={
174
- isLightTheme
175
- ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_HC_LIGHT
176
- : CODE_EDITOR_THEME.BUILT_IN__VSCODE_HC_BLACK
177
- }
178
- language={CODE_EDITOR_LANGUAGE.PURE}
179
- isReadOnly={true}
180
- inputValue={editorStore.replGridState.currentSubQuery}
181
- hideActionBar={true}
182
- hidePadding={true}
183
- />
184
- </div>
185
- </div>
186
- </div>
187
- )}
529
+ <DataCubeQueryTextEditor editorStore={editorStore} />
530
+ <DataCubeGridEditor editorStore={editorStore} />
531
+ </div>
532
+ <div className="repl__footer">
533
+ <div
534
+ className="repl__footer__pivot"
535
+ ref={pivotPanelButtonRef}
536
+ onClick={(): void => dataCubeState.configState.openPanel()}
537
+ >
538
+ Pivot
188
539
  </div>
189
- <div className="repl__query__label">Result</div>
190
- <PanelLoadingIndicator
191
- isLoading={editorStore.executeAction.isInProgress}
192
- />
193
- {editorStore.executeAction.hasCompleted && (
194
- <AgGridComponent
195
- className={
196
- editorStore.applicationStore.layoutService
197
- .TEMPORARY__isLightColorThemeEnabled
198
- ? 'ag-theme-balham'
199
- : 'ag-theme-balham-dark'
200
- }
201
- gridOptions={
202
- editorStore.replGridState.initialResult
203
- ? {
204
- serverSideDatasource: new ServerSideDataSource(
205
- getTDSRowData(
206
- editorStore.replGridState.initialResult.result,
207
- ),
208
- editorStore.replGridState.initialResult.builder.columns,
209
- editorStore,
210
- ),
211
- }
212
- : {}
213
- }
214
- licenseKey={editorStore.replGridState.licenseKey ?? ''}
215
- rowData={editorStore.replGridState.rowData}
216
- columnDefs={editorStore.replGridState.columnDefs}
217
- suppressServerSideInfiniteScroll={
218
- !editorStore.replGridState.isPaginationEnabled
219
- }
540
+ <div className="repl__footer__filter">Filter</div>
541
+ <div className="repl__footer__mode">Modes</div>
542
+ {dataCubeState.configState.isPivotPanelOpened && (
543
+ <PivotPanelEditor
544
+ editorStore={editorStore}
545
+ triggerElement={pivotPanelButtonRef.current}
220
546
  />
221
547
  )}
222
548
  </div>
223
549
  </div>
224
550
  );
225
- }),
551
+ },
226
552
  );
553
+
554
+ export const Editor = observer(() => <GenericEditor />);
555
+
556
+ export const REPLQueryEditor = observer(() => {
557
+ const params = useParams<REPLQueryEditorPathParams>();
558
+ const queryId = params[LEGEND_REPL_GRID_CLIENT_PATTERN_TOKEN.QUERY_ID];
559
+ return <GenericEditor queryId={queryId} />;
560
+ });
@@ -0,0 +1,69 @@
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 { AgGridComponent } from '../AgGrid.js';
19
+ import { getTDSRowData } from '../../components/grid/GridUtils.js';
20
+ import { ServerSideDataSource } from '../../components/grid/ServerSideDataSource.js';
21
+ import { PanelLoadingIndicator } from '@finos/legend-art';
22
+ import type { REPLGridClientStore } from '../../stores/REPLGridClientStore.js';
23
+
24
+ export const DataCubeGridEditor = observer(
25
+ (props: { editorStore: REPLGridClientStore }) => {
26
+ const { editorStore } = props;
27
+ const dataCubeState = editorStore.dataCubeState;
28
+
29
+ return (
30
+ <>
31
+ <div className="repl__query__label">Result</div>
32
+ <PanelLoadingIndicator
33
+ isLoading={dataCubeState.executeAction.isInProgress}
34
+ />
35
+ {dataCubeState.executeAction.hasCompleted && (
36
+ <AgGridComponent
37
+ onGridReady={(params): void => {
38
+ dataCubeState.configState.setGridApi(params.api);
39
+ }}
40
+ className={
41
+ editorStore.applicationStore.layoutService
42
+ .TEMPORARY__isLightColorThemeEnabled
43
+ ? 'ag-theme-balham'
44
+ : 'ag-theme-balham-dark'
45
+ }
46
+ gridOptions={
47
+ dataCubeState.gridState.initialResult
48
+ ? {
49
+ serverSideDatasource: new ServerSideDataSource(
50
+ getTDSRowData(
51
+ dataCubeState.gridState.initialResult.result,
52
+ ),
53
+ dataCubeState.gridState.initialResult.builder.columns,
54
+ editorStore,
55
+ ),
56
+ suppressServerSideInfiniteScroll:
57
+ !dataCubeState.configState.isPaginationEnabled,
58
+ }
59
+ : {}
60
+ }
61
+ licenseKey={dataCubeState.configState.licenseKey ?? ''}
62
+ rowData={dataCubeState.gridState.rowData}
63
+ columnDefs={dataCubeState.gridState.columnDefs}
64
+ />
65
+ )}
66
+ </>
67
+ );
68
+ },
69
+ );