@finos/legend-data-cube 0.1.11 → 0.1.13

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 (175) hide show
  1. package/lib/components/DataCubePlaceholder.d.ts.map +1 -1
  2. package/lib/components/DataCubePlaceholder.js +2 -1
  3. package/lib/components/DataCubePlaceholder.js.map +1 -1
  4. package/lib/components/core/DataCubePureCodeEditorUtils.d.ts +2 -1
  5. package/lib/components/core/DataCubePureCodeEditorUtils.d.ts.map +1 -1
  6. package/lib/components/core/DataCubePureCodeEditorUtils.js.map +1 -1
  7. package/lib/components/view/editor/DataCubeEditor.d.ts.map +1 -1
  8. package/lib/components/view/editor/DataCubeEditor.js +4 -2
  9. package/lib/components/view/editor/DataCubeEditor.js.map +1 -1
  10. package/lib/components/view/editor/DataCubeEditorColumnsPanel.d.ts.map +1 -1
  11. package/lib/components/view/editor/DataCubeEditorColumnsPanel.js +3 -3
  12. package/lib/components/view/editor/DataCubeEditorColumnsPanel.js.map +1 -1
  13. package/lib/components/view/editor/DataCubeEditorColumnsSelector.d.ts +47 -0
  14. package/lib/components/view/editor/DataCubeEditorColumnsSelector.d.ts.map +1 -0
  15. package/lib/components/view/editor/{DataCubeEditorColumnSelector.js → DataCubeEditorColumnsSelector.js} +70 -55
  16. package/lib/components/view/editor/DataCubeEditorColumnsSelector.js.map +1 -0
  17. package/lib/components/view/editor/DataCubeEditorDimensionsPanel.d.ts +3 -13
  18. package/lib/components/view/editor/DataCubeEditorDimensionsPanel.d.ts.map +1 -1
  19. package/lib/components/view/editor/DataCubeEditorDimensionsPanel.js +707 -264
  20. package/lib/components/view/editor/DataCubeEditorDimensionsPanel.js.map +1 -1
  21. package/lib/components/view/editor/DataCubeEditorHorizontalPivotsPanel.js +2 -2
  22. package/lib/components/view/editor/DataCubeEditorHorizontalPivotsPanel.js.map +1 -1
  23. package/lib/components/view/editor/DataCubeEditorSortsPanel.js +2 -2
  24. package/lib/components/view/editor/DataCubeEditorSortsPanel.js.map +1 -1
  25. package/lib/components/view/editor/DataCubeEditorVerticalPivotsPanel.js +2 -2
  26. package/lib/components/view/editor/DataCubeEditorVerticalPivotsPanel.js.map +1 -1
  27. package/lib/components/view/{grid/DataCubeGridShared.d.ts → extend/DataCubeCodeEditor.d.ts} +7 -3
  28. package/lib/components/view/extend/DataCubeCodeEditor.d.ts.map +1 -0
  29. package/lib/components/view/extend/DataCubeCodeEditor.js +114 -0
  30. package/lib/components/view/extend/DataCubeCodeEditor.js.map +1 -0
  31. package/lib/components/view/extend/DataCubeCodeEditorState.d.ts +43 -0
  32. package/lib/components/view/extend/DataCubeCodeEditorState.d.ts.map +1 -0
  33. package/lib/components/view/extend/DataCubeCodeEditorState.js +37 -0
  34. package/lib/components/view/extend/DataCubeCodeEditorState.js.map +1 -0
  35. package/lib/components/view/extend/DataCubeColumnEditor.d.ts.map +1 -1
  36. package/lib/components/view/extend/DataCubeColumnEditor.js +5 -84
  37. package/lib/components/view/extend/DataCubeColumnEditor.js.map +1 -1
  38. package/lib/components/view/grid/DataCubeGrid.d.ts +2 -1
  39. package/lib/components/view/grid/DataCubeGrid.d.ts.map +1 -1
  40. package/lib/components/view/grid/DataCubeGrid.js +29 -19
  41. package/lib/components/view/grid/DataCubeGrid.js.map +1 -1
  42. package/lib/components/view/grid/DataCubeMultidimensionalGrid.d.ts +1 -1
  43. package/lib/components/view/grid/DataCubeMultidimensionalGrid.d.ts.map +1 -1
  44. package/lib/components/view/grid/DataCubeMultidimensionalGrid.js +2 -1
  45. package/lib/components/view/grid/DataCubeMultidimensionalGrid.js.map +1 -1
  46. package/lib/index.css +2 -2
  47. package/lib/index.css.map +1 -1
  48. package/lib/index.d.ts +3 -0
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +3 -0
  51. package/lib/index.js.map +1 -1
  52. package/lib/package.json +1 -1
  53. package/lib/stores/DataCubeAPI.d.ts.map +1 -1
  54. package/lib/stores/DataCubeAPI.js +3 -1
  55. package/lib/stores/DataCubeAPI.js.map +1 -1
  56. package/lib/stores/core/DataCubeEngine.d.ts +1 -1
  57. package/lib/stores/core/DataCubeEngine.d.ts.map +1 -1
  58. package/lib/stores/core/DataCubeQueryEngine.d.ts +5 -0
  59. package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
  60. package/lib/stores/core/DataCubeQueryEngine.js +6 -0
  61. package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
  62. package/lib/stores/core/DataCubeSnapshot.d.ts +1 -1
  63. package/lib/stores/core/DataCubeSnapshot.d.ts.map +1 -1
  64. package/lib/stores/core/model/AdhocQueryDataCubeSource.d.ts +2 -0
  65. package/lib/stores/core/model/AdhocQueryDataCubeSource.d.ts.map +1 -1
  66. package/lib/stores/core/model/AdhocQueryDataCubeSource.js +3 -0
  67. package/lib/stores/core/model/AdhocQueryDataCubeSource.js.map +1 -1
  68. package/lib/stores/core/model/DataCubeConfiguration.d.ts +11 -0
  69. package/lib/stores/core/model/DataCubeConfiguration.d.ts.map +1 -1
  70. package/lib/stores/core/model/DataCubeConfiguration.js +19 -1
  71. package/lib/stores/core/model/DataCubeConfiguration.js.map +1 -1
  72. package/lib/stores/services/DataCubeSettingService.d.ts.map +1 -1
  73. package/lib/stores/services/DataCubeSettingService.js +10 -6
  74. package/lib/stores/services/DataCubeSettingService.js.map +1 -1
  75. package/lib/stores/view/DataCubeInfoState.d.ts +2 -0
  76. package/lib/stores/view/DataCubeInfoState.d.ts.map +1 -1
  77. package/lib/stores/view/DataCubeInfoState.js +3 -0
  78. package/lib/stores/view/DataCubeInfoState.js.map +1 -1
  79. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.d.ts +8 -8
  80. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.d.ts.map +1 -1
  81. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.js +6 -6
  82. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.js.map +1 -1
  83. package/lib/stores/view/editor/{DataCubeEditorColumnSelectorState.d.ts → DataCubeEditorColumnsSelectorState.d.ts} +6 -6
  84. package/lib/stores/view/editor/DataCubeEditorColumnsSelectorState.d.ts.map +1 -0
  85. package/lib/stores/view/editor/{DataCubeEditorColumnSelectorState.js → DataCubeEditorColumnsSelectorState.js} +4 -4
  86. package/lib/stores/view/editor/DataCubeEditorColumnsSelectorState.js.map +1 -0
  87. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.d.ts +29 -6
  88. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.d.ts.map +1 -1
  89. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js +102 -39
  90. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js.map +1 -1
  91. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts +5 -5
  92. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts.map +1 -1
  93. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.js +7 -6
  94. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.js.map +1 -1
  95. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts +2 -1
  96. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
  97. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js +5 -0
  98. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
  99. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.d.ts +5 -5
  100. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
  101. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.js +6 -6
  102. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.js.map +1 -1
  103. package/lib/stores/view/editor/DataCubeEditorState.d.ts +3 -0
  104. package/lib/stores/view/editor/DataCubeEditorState.d.ts.map +1 -1
  105. package/lib/stores/view/editor/DataCubeEditorState.js +6 -0
  106. package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
  107. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.d.ts +5 -5
  108. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.d.ts.map +1 -1
  109. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.js +6 -6
  110. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.js.map +1 -1
  111. package/lib/stores/view/extend/DataCubeColumnEditorState.d.ts +7 -14
  112. package/lib/stores/view/extend/DataCubeColumnEditorState.d.ts.map +1 -1
  113. package/lib/stores/view/extend/DataCubeColumnEditorState.js +14 -22
  114. package/lib/stores/view/extend/DataCubeColumnEditorState.js.map +1 -1
  115. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts +2 -1
  116. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  117. package/lib/stores/view/grid/DataCubeGridClientEngine.js +7 -0
  118. package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
  119. package/lib/stores/view/grid/DataCubeGridClientExportEngine.js +1 -1
  120. package/lib/stores/view/grid/DataCubeGridClientExportEngine.js.map +1 -1
  121. package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts +2 -0
  122. package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  123. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js +9 -16
  124. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js.map +1 -1
  125. package/lib/stores/view/grid/DataCubeGridState.d.ts +2 -2
  126. package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
  127. package/lib/stores/view/grid/DataCubeGridState.js +19 -6
  128. package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
  129. package/package.json +5 -5
  130. package/src/components/DataCubePlaceholder.tsx +2 -0
  131. package/src/components/core/DataCubePureCodeEditorUtils.tsx +2 -1
  132. package/src/components/view/editor/DataCubeEditor.tsx +8 -3
  133. package/src/components/view/editor/DataCubeEditorColumnsPanel.tsx +6 -8
  134. package/src/components/view/editor/{DataCubeEditorColumnSelector.tsx → DataCubeEditorColumnsSelector.tsx} +108 -83
  135. package/src/components/view/editor/DataCubeEditorDimensionsPanel.tsx +1259 -503
  136. package/src/components/view/editor/DataCubeEditorHorizontalPivotsPanel.tsx +5 -5
  137. package/src/components/view/editor/DataCubeEditorSortsPanel.tsx +10 -10
  138. package/src/components/view/editor/DataCubeEditorVerticalPivotsPanel.tsx +2 -2
  139. package/src/components/view/extend/DataCubeCodeEditor.tsx +175 -0
  140. package/src/components/view/extend/DataCubeCodeEditorState.tsx +72 -0
  141. package/src/components/view/extend/DataCubeColumnEditor.tsx +5 -133
  142. package/src/components/view/grid/DataCubeGrid.tsx +70 -53
  143. package/src/components/view/grid/DataCubeMultidimensionalGrid.tsx +3 -1
  144. package/src/index.tsx +3 -0
  145. package/src/stores/DataCubeAPI.ts +3 -1
  146. package/src/stores/core/DataCubeEngine.tsx +1 -1
  147. package/src/stores/core/DataCubeQueryEngine.ts +6 -0
  148. package/src/stores/core/DataCubeSnapshot.ts +1 -1
  149. package/src/stores/core/model/AdhocQueryDataCubeSource.ts +3 -0
  150. package/src/stores/core/model/DataCubeConfiguration.ts +31 -0
  151. package/src/stores/services/DataCubeSettingService.tsx +10 -6
  152. package/src/stores/view/DataCubeInfoState.ts +4 -0
  153. package/src/stores/view/editor/DataCubeEditorColumnsPanelState.ts +13 -13
  154. package/src/stores/view/editor/{DataCubeEditorColumnSelectorState.ts → DataCubeEditorColumnsSelectorState.ts} +6 -6
  155. package/src/stores/view/editor/DataCubeEditorDimensionsPanelState.ts +162 -58
  156. package/src/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.ts +12 -11
  157. package/src/stores/view/editor/DataCubeEditorMutableConfiguration.ts +8 -0
  158. package/src/stores/view/editor/DataCubeEditorSortsPanelState.ts +10 -10
  159. package/src/stores/view/editor/DataCubeEditorState.tsx +6 -0
  160. package/src/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.ts +11 -11
  161. package/src/stores/view/extend/DataCubeColumnEditorState.tsx +16 -26
  162. package/src/stores/view/grid/DataCubeGridClientEngine.ts +8 -0
  163. package/src/stores/view/grid/DataCubeGridClientExportEngine.ts +1 -1
  164. package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +26 -1
  165. package/src/stores/view/grid/DataCubeGridState.ts +23 -6
  166. package/tsconfig.json +4 -3
  167. package/lib/components/view/editor/DataCubeEditorColumnSelector.d.ts +0 -38
  168. package/lib/components/view/editor/DataCubeEditorColumnSelector.d.ts.map +0 -1
  169. package/lib/components/view/editor/DataCubeEditorColumnSelector.js.map +0 -1
  170. package/lib/components/view/grid/DataCubeGridShared.d.ts.map +0 -1
  171. package/lib/components/view/grid/DataCubeGridShared.js +0 -25
  172. package/lib/components/view/grid/DataCubeGridShared.js.map +0 -1
  173. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.d.ts.map +0 -1
  174. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.js.map +0 -1
  175. package/src/components/view/grid/DataCubeGridShared.tsx +0 -42
@@ -18,9 +18,9 @@ import { DataCubeIcon } from '@finos/legend-art';
18
18
  import { observer } from 'mobx-react-lite';
19
19
  import type { DataCubeViewState } from '../../../stores/view/DataCubeViewState.js';
20
20
  import {
21
- DataCubeColumnSelectorSortDirectionDropdown,
22
- DataCubeEditorColumnSelector,
23
- } from './DataCubeEditorColumnSelector.js';
21
+ DataCubeEditorColumnsSelectorSortDirectionDropdown,
22
+ DataCubeEditorColumnsSelector,
23
+ } from './DataCubeEditorColumnsSelector.js';
24
24
  import { useEffect } from 'react';
25
25
 
26
26
  export const DataCubeEditorHorizontalPivotsPanel = observer(
@@ -41,10 +41,10 @@ export const DataCubeEditorHorizontalPivotsPanel = observer(
41
41
  </div>
42
42
  </div>
43
43
  <div className="flex h-[calc(100%_-_24px)] w-full">
44
- <DataCubeEditorColumnSelector
44
+ <DataCubeEditorColumnsSelector
45
45
  selector={panel.selector}
46
46
  columnActionRenderer={(p) => (
47
- <DataCubeColumnSelectorSortDirectionDropdown {...p} />
47
+ <DataCubeEditorColumnsSelectorSortDirectionDropdown {...p} />
48
48
  )}
49
49
  />
50
50
  </div>
@@ -17,20 +17,20 @@
17
17
  import { observer } from 'mobx-react-lite';
18
18
  import { DataCubeIcon } from '@finos/legend-art';
19
19
  import {
20
- DataCubeColumnSelectorSortDirectionDropdown,
21
- DataCubeEditorColumnSelector,
22
- } from './DataCubeEditorColumnSelector.js';
20
+ DataCubeEditorColumnsSelectorSortDirectionDropdown,
21
+ DataCubeEditorColumnsSelector,
22
+ } from './DataCubeEditorColumnsSelector.js';
23
23
  import type {
24
- DataCubeEditorColumnSelectorState,
25
- DataCubeEditorSortColumnState,
26
- } from '../../../stores/view/editor/DataCubeEditorColumnSelectorState.js';
24
+ DataCubeEditorColumnsSelectorState,
25
+ DataCubeEditorColumnsSelectorSortColumnState,
26
+ } from '../../../stores/view/editor/DataCubeEditorColumnsSelectorState.js';
27
27
  import { PIVOT_COLUMN_NAME_VALUE_SEPARATOR } from '../../../stores/core/DataCubeQueryEngine.js';
28
28
  import type { DataCubeViewState } from '../../../stores/view/DataCubeViewState.js';
29
29
 
30
30
  const SortColumnLabel = observer(
31
31
  (props: {
32
- selector: DataCubeEditorColumnSelectorState<DataCubeEditorSortColumnState>;
33
- column: DataCubeEditorSortColumnState;
32
+ selector: DataCubeEditorColumnsSelectorState<DataCubeEditorColumnsSelectorSortColumnState>;
33
+ column: DataCubeEditorColumnsSelectorSortColumnState;
34
34
  }) => {
35
35
  const { column } = props;
36
36
 
@@ -58,11 +58,11 @@ export const DataCubeEditorSortsPanel = observer(
58
58
  </div>
59
59
  </div>
60
60
  <div className="flex h-[calc(100%_-_24px)] w-full">
61
- <DataCubeEditorColumnSelector
61
+ <DataCubeEditorColumnsSelector
62
62
  selector={panel.selector}
63
63
  columnLabelRenderer={(p) => <SortColumnLabel {...p} />}
64
64
  columnActionRenderer={(p) => (
65
- <DataCubeColumnSelectorSortDirectionDropdown {...p} />
65
+ <DataCubeEditorColumnsSelectorSortDirectionDropdown {...p} />
66
66
  )}
67
67
  />
68
68
  </div>
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { DataCubeIcon } from '@finos/legend-art';
18
18
  import { observer } from 'mobx-react-lite';
19
- import { DataCubeEditorColumnSelector } from './DataCubeEditorColumnSelector.js';
19
+ import { DataCubeEditorColumnsSelector } from './DataCubeEditorColumnsSelector.js';
20
20
  import type { DataCubeViewState } from '../../../stores/view/DataCubeViewState.js';
21
21
 
22
22
  export const DataCubeEditorVerticalPivotsPanel = observer(
@@ -35,7 +35,7 @@ export const DataCubeEditorVerticalPivotsPanel = observer(
35
35
  </div>
36
36
  </div>
37
37
  <div className="flex h-[calc(100%_-_24px)] w-full">
38
- <DataCubeEditorColumnSelector selector={panel.selector} />
38
+ <DataCubeEditorColumnsSelector selector={panel.selector} />
39
39
  </div>
40
40
  </div>
41
41
  );
@@ -0,0 +1,175 @@
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 { cn } from '@finos/legend-art';
18
+ import {
19
+ getBaseCodeEditorOptions,
20
+ CODE_EDITOR_LANGUAGE,
21
+ CODE_EDITOR_THEME,
22
+ PURE_CODE_EDITOR_WORD_SEPARATORS,
23
+ } from '@finos/legend-code-editor';
24
+ import {
25
+ debounce,
26
+ guaranteeNonNullable,
27
+ isNonNullable,
28
+ } from '@finos/legend-shared';
29
+ import { observer } from 'mobx-react-lite';
30
+ import { useRef, useState, useMemo, useEffect } from 'react';
31
+ import {
32
+ MONACO_EDITOR_OVERFLOW_WIDGETS_ROOT_ID,
33
+ getCodeSuggestions,
34
+ } from '../../core/DataCubePureCodeEditorUtils.js';
35
+ import {
36
+ editor as monacoEditorAPI,
37
+ languages as monacoLanguagesAPI,
38
+ type IDisposable,
39
+ } from 'monaco-editor';
40
+ import type { DataCubeCodeEditorState } from './DataCubeCodeEditorState.js';
41
+ import { runInAction } from 'mobx';
42
+
43
+ export const DataCubeCodeEditor = observer(
44
+ (props: { state: DataCubeCodeEditorState }) => {
45
+ const { state } = props;
46
+
47
+ const editorRef = useRef<HTMLDivElement>(null);
48
+ const [editor, setEditor] = useState<
49
+ monacoEditorAPI.IStandaloneCodeEditor | undefined
50
+ >();
51
+
52
+ const suggestionsProvider = useRef<IDisposable | undefined>(undefined);
53
+
54
+ const debouncedCheckReturnType = useMemo(
55
+ () =>
56
+ debounce((): void => {
57
+ state.getReturnType().catch((error) => {
58
+ state.alertHandler(error);
59
+ });
60
+ }, 500),
61
+ [state],
62
+ );
63
+
64
+ useEffect(() => {
65
+ if (!editor && editorRef.current) {
66
+ const element = editorRef.current;
67
+ const widgetRoot = document.getElementById(
68
+ MONACO_EDITOR_OVERFLOW_WIDGETS_ROOT_ID,
69
+ );
70
+ const newEditor = monacoEditorAPI.create(element, {
71
+ ...getBaseCodeEditorOptions(),
72
+ fontSize: 12,
73
+ language: CODE_EDITOR_LANGUAGE.PURE,
74
+ theme: CODE_EDITOR_THEME.GITHUB_LIGHT,
75
+ wordSeparators: PURE_CODE_EDITOR_WORD_SEPARATORS,
76
+ // Make sure the widgets (tooltips, menus) are not clipped by the container bounds
77
+ // and fix the problem where widgets are rendered with position=fixed not working well with parent
78
+ // containers (i.e. the draggable window) which has been transformed
79
+ // See https://dev.to/salilnaik/the-uncanny-relationship-between-position-fixed-and-transform-property-32f6
80
+ // See https://github.com/microsoft/monaco-editor/issues/2793#issuecomment-999337740
81
+ fixedOverflowWidgets: true,
82
+ ...(isNonNullable(widgetRoot)
83
+ ? { overflowWidgetsDomNode: widgetRoot }
84
+ : {}),
85
+ });
86
+
87
+ // NOTE: since engine suggestions are computed based on the current text content
88
+ // we put it in this block to simplify the flow and really to "bend" monaco-editor
89
+ // suggestion provider to our needs. But we also need to make sure this suggestion
90
+ // provider is scoped to the current editor only by checking the editor model
91
+ suggestionsProvider.current?.dispose();
92
+ suggestionsProvider.current =
93
+ monacoLanguagesAPI.registerCompletionItemProvider(
94
+ CODE_EDITOR_LANGUAGE.PURE,
95
+ {
96
+ // NOTE: this is a hack to fetch suggestions from engine for every keystroke
97
+ triggerCharacters: [...PURE_CODE_EDITOR_WORD_SEPARATORS, '$'],
98
+ provideCompletionItems: async (model, position, context) => {
99
+ let suggestions: monacoLanguagesAPI.CompletionItem[] = [];
100
+
101
+ if (model.uri === state.editorModelUri) {
102
+ suggestions = suggestions.concat(
103
+ await getCodeSuggestions(
104
+ position,
105
+ model,
106
+ state.codePrefix,
107
+ state.engine,
108
+ guaranteeNonNullable(state.model),
109
+ state.queryLambda,
110
+ ),
111
+ );
112
+ }
113
+
114
+ return { suggestions };
115
+ },
116
+ },
117
+ );
118
+
119
+ newEditor.setModel(state.editorModel);
120
+ newEditor.onDidChangeModelContent(() => {
121
+ state.currentlyEditing = true;
122
+ const currentVal = newEditor.getValue();
123
+ if (currentVal !== state.code) {
124
+ runInAction(() => {
125
+ state.code = currentVal;
126
+ });
127
+ // clear error on content change/typing
128
+ state.clearError();
129
+ state.setReturnType(undefined);
130
+ debouncedCheckReturnType.cancel();
131
+ debouncedCheckReturnType();
132
+ }
133
+ });
134
+ // focus on the editor initially and set the cursor to the end
135
+ // since we're trying to create a new column
136
+ newEditor.focus();
137
+ newEditor.setPosition({
138
+ lineNumber: 1,
139
+ column: state.code.length + 1,
140
+ });
141
+ state.setEditor(newEditor);
142
+ setEditor(newEditor);
143
+ }
144
+ }, [state, editor, debouncedCheckReturnType]);
145
+
146
+ // clean up
147
+ useEffect(
148
+ () => (): void => {
149
+ if (editor) {
150
+ editor.dispose();
151
+
152
+ suggestionsProvider.current?.dispose();
153
+ }
154
+ },
155
+ [editor],
156
+ );
157
+
158
+ useEffect(() => {
159
+ state.editor?.updateOptions({
160
+ readOnly: state.finalizationState.isInProgress,
161
+ });
162
+ }, [state, state.finalizationState.isInProgress]);
163
+
164
+ return (
165
+ <div
166
+ className={cn('relative h-full w-full border border-neutral-200', {
167
+ 'border-red-500': state.hasErrors,
168
+ })}
169
+ >
170
+ <div className="absolute left-0 top-0 h-full w-full overflow-hidden" />
171
+ <div ref={editorRef} style={{ height: '100%', width: '100%' }} />
172
+ </div>
173
+ );
174
+ },
175
+ );
@@ -0,0 +1,72 @@
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
+ import type { EngineError, V1_Lambda } from '@finos/legend-graph';
17
+ import { ActionState, uuid, type PlainObject } from '@finos/legend-shared';
18
+ import { editor as monacoEditorAPI, Uri } from 'monaco-editor';
19
+ import type { DataCubeEngine } from '../../../stores/core/DataCubeEngine.js';
20
+ import type { DataCubeSource } from '../../../stores/core/model/DataCubeSource.js';
21
+ import { clearMarkers, CODE_EDITOR_LANGUAGE } from '@finos/legend-code-editor';
22
+
23
+ export abstract class DataCubeCodeEditorState {
24
+ protected readonly uuid = uuid();
25
+
26
+ editorModel: monacoEditorAPI.ITextModel;
27
+ editor?: monacoEditorAPI.IStandaloneCodeEditor | undefined;
28
+ editorModelUri: Uri;
29
+
30
+ code = '';
31
+ codePrefix: string;
32
+ returnType?: string | undefined;
33
+
34
+ finalizationState = ActionState.create();
35
+ codeError?: EngineError | undefined;
36
+ model: DataCubeSource | PlainObject | undefined;
37
+ engine: DataCubeEngine;
38
+
39
+ currentlyEditing?: boolean;
40
+
41
+ constructor(engine: DataCubeEngine) {
42
+ this.engine = engine;
43
+ this.codePrefix = '';
44
+ this.editorModelUri = Uri.file(`/${this.uuid}.pure`);
45
+ this.editorModel = monacoEditorAPI.createModel(
46
+ '',
47
+ CODE_EDITOR_LANGUAGE.PURE,
48
+ this.editorModelUri,
49
+ );
50
+ }
51
+
52
+ get hasErrors(): boolean {
53
+ return Boolean(this.codeError);
54
+ }
55
+
56
+ clearError() {
57
+ this.codeError = undefined;
58
+ clearMarkers(this.uuid);
59
+ }
60
+
61
+ setReturnType(value: string | undefined) {
62
+ this.returnType = value;
63
+ }
64
+
65
+ setEditor(editor: monacoEditorAPI.IStandaloneCodeEditor) {
66
+ this.editor = editor;
67
+ }
68
+
69
+ abstract alertHandler: (error: Error) => void;
70
+ abstract getReturnType(): Promise<string | boolean | undefined>;
71
+ abstract queryLambda: () => V1_Lambda;
72
+ }
@@ -19,22 +19,6 @@ import {
19
19
  DataCubeExistingColumnEditorState,
20
20
  type DataCubeColumnBaseEditorState,
21
21
  } from '../../../stores/view/extend/DataCubeColumnEditorState.js';
22
- import {
23
- editor as monacoEditorAPI,
24
- languages as monacoLanguagesAPI,
25
- type IDisposable,
26
- } from 'monaco-editor';
27
- import { useEffect, useMemo, useRef, useState } from 'react';
28
- import {
29
- CODE_EDITOR_THEME,
30
- PURE_CODE_EDITOR_WORD_SEPARATORS,
31
- CODE_EDITOR_LANGUAGE,
32
- getBaseCodeEditorOptions,
33
- } from '@finos/legend-code-editor';
34
- import {
35
- getCodeSuggestions,
36
- MONACO_EDITOR_OVERFLOW_WIDGETS_ROOT_ID,
37
- } from '../../core/DataCubePureCodeEditorUtils.js';
38
22
  import {
39
23
  FormButton,
40
24
  FormDocumentation,
@@ -43,14 +27,16 @@ import {
43
27
  FormDropdownMenuTrigger,
44
28
  FormTextInput,
45
29
  } from '../../core/DataCubeFormUtils.js';
46
- import { debounce, isNonNullable } from '@finos/legend-shared';
47
- import { cn, DataCubeIcon, useDropdownMenu } from '@finos/legend-art';
30
+ import { DataCubeIcon, useDropdownMenu } from '@finos/legend-art';
48
31
  import {
49
32
  DataCubeColumnDataType,
50
33
  DataCubeColumnKind,
51
34
  } from '../../../stores/core/DataCubeQueryEngine.js';
52
35
  import { DataCubeDocumentationKey } from '../../../__lib__/DataCubeDocumentation.js';
53
36
  import { useDataCube } from '../../DataCubeProvider.js';
37
+ import { useMemo, useRef } from 'react';
38
+ import { debounce } from '@finos/legend-shared';
39
+ import { DataCubeCodeEditor } from './DataCubeCodeEditor.js';
54
40
 
55
41
  enum DataCubeExtendedColumnKind {
56
42
  LEAF_LEVEL_MEASURE = 'Leaf Level Measure',
@@ -84,11 +70,6 @@ export const DataCubeColumnCreator = observer(
84
70
  typeDropPropsOpen,
85
71
  ] = useDropdownMenu();
86
72
 
87
- const suggestionsProvider = useRef<IDisposable | undefined>(undefined);
88
- const editorRef = useRef<HTMLDivElement>(null);
89
- const [editor, setEditor] = useState<
90
- monacoEditorAPI.IStandaloneCodeEditor | undefined
91
- >();
92
73
  const debouncedCheckReturnType = useMemo(
93
74
  () =>
94
75
  debounce((): void => {
@@ -99,103 +80,6 @@ export const DataCubeColumnCreator = observer(
99
80
  [state, dataCube],
100
81
  );
101
82
 
102
- useEffect(() => {
103
- if (!editor && editorRef.current) {
104
- const element = editorRef.current;
105
- const widgetRoot = document.getElementById(
106
- MONACO_EDITOR_OVERFLOW_WIDGETS_ROOT_ID,
107
- );
108
- const newEditor = monacoEditorAPI.create(element, {
109
- ...getBaseCodeEditorOptions(),
110
- fontSize: 12,
111
- language: CODE_EDITOR_LANGUAGE.PURE,
112
- theme: CODE_EDITOR_THEME.GITHUB_LIGHT,
113
- wordSeparators: PURE_CODE_EDITOR_WORD_SEPARATORS,
114
- // Make sure the widgets (tooltips, menus) are not clipped by the container bounds
115
- // and fix the problem where widgets are rendered with position=fixed not working well with parent
116
- // containers (i.e. the draggable window) which has been transformed
117
- // See https://dev.to/salilnaik/the-uncanny-relationship-between-position-fixed-and-transform-property-32f6
118
- // See https://github.com/microsoft/monaco-editor/issues/2793#issuecomment-999337740
119
- fixedOverflowWidgets: true,
120
- ...(isNonNullable(widgetRoot)
121
- ? { overflowWidgetsDomNode: widgetRoot }
122
- : {}),
123
- });
124
-
125
- // NOTE: since engine suggestions are computed based on the current text content
126
- // we put it in this block to simplify the flow and really to "bend" monaco-editor
127
- // suggestion provider to our needs. But we also need to make sure this suggestion
128
- // provider is scoped to the current editor only by checking the editor model
129
- suggestionsProvider.current?.dispose();
130
- suggestionsProvider.current =
131
- monacoLanguagesAPI.registerCompletionItemProvider(
132
- CODE_EDITOR_LANGUAGE.PURE,
133
- {
134
- // NOTE: this is a hack to fetch suggestions from engine for every keystroke
135
- triggerCharacters: [...PURE_CODE_EDITOR_WORD_SEPARATORS, '$'],
136
- provideCompletionItems: async (model, position, context) => {
137
- let suggestions: monacoLanguagesAPI.CompletionItem[] = [];
138
-
139
- if (model.uri === state.editorModelUri) {
140
- suggestions = suggestions.concat(
141
- await getCodeSuggestions(
142
- position,
143
- model,
144
- state.codePrefix,
145
- view.engine,
146
- view.source,
147
- () => state.buildExtendBaseQuery(),
148
- ),
149
- );
150
- }
151
-
152
- return { suggestions };
153
- },
154
- },
155
- );
156
-
157
- newEditor.setModel(state.editorModel);
158
- newEditor.onDidChangeModelContent(() => {
159
- const currentVal = newEditor.getValue();
160
- if (currentVal !== state.code) {
161
- state.code = currentVal;
162
- // clear error on content change/typing
163
- state.clearError();
164
- state.setReturnType(undefined);
165
- debouncedCheckReturnType.cancel();
166
- debouncedCheckReturnType();
167
- }
168
- });
169
- // focus on the editor initially and set the cursor to the end
170
- // since we're trying to create a new column
171
- newEditor.focus();
172
- newEditor.setPosition({
173
- lineNumber: 1,
174
- column: state.code.length + 1,
175
- });
176
- state.setEditor(newEditor);
177
- setEditor(newEditor);
178
- }
179
- }, [state, editor, debouncedCheckReturnType, view]);
180
-
181
- // clean up
182
- useEffect(
183
- () => (): void => {
184
- if (editor) {
185
- editor.dispose();
186
-
187
- suggestionsProvider.current?.dispose();
188
- }
189
- },
190
- [editor],
191
- );
192
-
193
- useEffect(() => {
194
- state.editor?.updateOptions({
195
- readOnly: state.finalizationState.isInProgress,
196
- });
197
- }, [state, state.finalizationState.isInProgress]);
198
-
199
83
  return (
200
84
  <>
201
85
  <div className="h-[calc(100%_-_40px)] w-full px-2 pt-2">
@@ -329,19 +213,7 @@ export const DataCubeColumnCreator = observer(
329
213
  </div>
330
214
  </div>
331
215
  <div className="h-[calc(100%_-_96px)] w-full p-2 pt-1">
332
- <div
333
- className={cn(
334
- 'relative h-full w-full border border-neutral-200',
335
- {
336
- 'border-red-500': Boolean(state.codeError),
337
- },
338
- )}
339
- >
340
- <div
341
- className="absolute left-0 top-0 h-full w-full overflow-hidden"
342
- ref={editorRef}
343
- />
344
- </div>
216
+ <DataCubeCodeEditor state={state} />
345
217
  </div>
346
218
  </div>
347
219
  </div>