@finos/legend-application-repl 0.0.31 → 0.0.32

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 (170) hide show
  1. package/lib/components/LegendREPLFrameworkProvider.js +1 -1
  2. package/lib/components/LegendREPLFrameworkProvider.js.map +1 -1
  3. package/lib/components/REPLStoreProvider.d.ts +1 -1
  4. package/lib/components/REPLStoreProvider.d.ts.map +1 -1
  5. package/lib/components/REPLStoreProvider.js +1 -1
  6. package/lib/components/REPLStoreProvider.js.map +1 -1
  7. package/lib/components/REPLWindow.d.ts +33 -0
  8. package/lib/components/REPLWindow.d.ts.map +1 -0
  9. package/lib/components/REPLWindow.js +117 -0
  10. package/lib/components/REPLWindow.js.map +1 -0
  11. package/lib/components/dataCube/DataCube.js +1 -1
  12. package/lib/components/dataCube/DataCube.js.map +1 -1
  13. package/lib/components/dataCube/editor/DataCubeEditor.d.ts.map +1 -1
  14. package/lib/components/dataCube/editor/DataCubeEditor.js +12 -91
  15. package/lib/components/dataCube/editor/DataCubeEditor.js.map +1 -1
  16. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.d.ts.map +1 -1
  17. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js +3 -2
  18. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js.map +1 -1
  19. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
  20. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.js +161 -87
  21. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
  22. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js +1 -1
  23. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js.map +1 -1
  24. package/lib/components/dataCube/editor/DataCubeEditorColumnsSelector.d.ts.map +1 -1
  25. package/lib/components/dataCube/editor/DataCubeEditorColumnsSelector.js +0 -1
  26. package/lib/components/dataCube/editor/DataCubeEditorColumnsSelector.js.map +1 -1
  27. package/lib/components/dataCube/editor/DataCubeEditorDeveloperPanel.d.ts.map +1 -1
  28. package/lib/components/dataCube/editor/DataCubeEditorDeveloperPanel.js +3 -2
  29. package/lib/components/dataCube/editor/DataCubeEditorDeveloperPanel.js.map +1 -1
  30. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.d.ts.map +1 -1
  31. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.js +3 -2
  32. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.js.map +1 -1
  33. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.d.ts.map +1 -1
  34. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.js +3 -2
  35. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.js.map +1 -1
  36. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.d.ts.map +1 -1
  37. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.js +96 -55
  38. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.js.map +1 -1
  39. package/lib/components/dataCube/editor/DataCubeEditorHPivotsPanel.d.ts.map +1 -1
  40. package/lib/components/dataCube/editor/DataCubeEditorHPivotsPanel.js +3 -2
  41. package/lib/components/dataCube/editor/DataCubeEditorHPivotsPanel.js.map +1 -1
  42. package/lib/components/dataCube/editor/DataCubeEditorShared.d.ts +1 -0
  43. package/lib/components/dataCube/editor/DataCubeEditorShared.d.ts.map +1 -1
  44. package/lib/components/dataCube/editor/DataCubeEditorShared.js +44 -27
  45. package/lib/components/dataCube/editor/DataCubeEditorShared.js.map +1 -1
  46. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.js +1 -1
  47. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.js.map +1 -1
  48. package/lib/components/dataCube/editor/DataCubeEditorVPivotsPanel.d.ts.map +1 -1
  49. package/lib/components/dataCube/editor/DataCubeEditorVPivotsPanel.js +3 -2
  50. package/lib/components/dataCube/editor/DataCubeEditorVPivotsPanel.js.map +1 -1
  51. package/lib/components/dataCube/grid/DataCubeGrid.d.ts +3 -0
  52. package/lib/components/dataCube/grid/DataCubeGrid.d.ts.map +1 -1
  53. package/lib/components/dataCube/grid/DataCubeGrid.js +186 -75
  54. package/lib/components/dataCube/grid/DataCubeGrid.js.map +1 -1
  55. package/lib/components/dataCube/grid/DataCubeGridShared.d.ts +1 -1
  56. package/lib/components/dataCube/grid/DataCubeGridShared.d.ts.map +1 -1
  57. package/lib/components/dataCube/grid/DataCubeGridShared.js +1 -1
  58. package/lib/components/dataCube/grid/DataCubeGridShared.js.map +1 -1
  59. package/lib/components/dataCube/grid/menu/DataCubeGridMenu.d.ts.map +1 -1
  60. package/lib/components/dataCube/grid/menu/DataCubeGridMenu.js +60 -29
  61. package/lib/components/dataCube/grid/menu/DataCubeGridMenu.js.map +1 -1
  62. package/lib/components/dataCube/grid/menu/DataCubeGridSortsMenu.d.ts.map +1 -1
  63. package/lib/components/dataCube/grid/menu/DataCubeGridSortsMenu.js +10 -10
  64. package/lib/components/dataCube/grid/menu/DataCubeGridSortsMenu.js.map +1 -1
  65. package/lib/index.css +2 -2
  66. package/lib/index.css.map +1 -1
  67. package/lib/package.json +14 -14
  68. package/lib/stores/{dataCube/REPLStore.d.ts → REPLStore.d.ts} +5 -3
  69. package/lib/stores/REPLStore.d.ts.map +1 -0
  70. package/lib/stores/{dataCube/REPLStore.js → REPLStore.js} +5 -2
  71. package/lib/stores/REPLStore.js.map +1 -0
  72. package/lib/stores/dataCube/{core/DataCubeEngine.d.ts → DataCubeInfrastructure.d.ts} +20 -4
  73. package/lib/stores/dataCube/DataCubeInfrastructure.d.ts.map +1 -0
  74. package/lib/stores/dataCube/{core/DataCubeEngine.js → DataCubeInfrastructure.js} +31 -3
  75. package/lib/stores/dataCube/DataCubeInfrastructure.js.map +1 -0
  76. package/lib/stores/dataCube/DataCubeState.d.ts +4 -4
  77. package/lib/stores/dataCube/DataCubeState.d.ts.map +1 -1
  78. package/lib/stores/dataCube/DataCubeState.js +7 -8
  79. package/lib/stores/dataCube/DataCubeState.js.map +1 -1
  80. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts +42 -38
  81. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts.map +1 -1
  82. package/lib/stores/dataCube/core/DataCubeConfiguration.js +84 -78
  83. package/lib/stores/dataCube/core/DataCubeConfiguration.js.map +1 -1
  84. package/lib/stores/dataCube/core/DataCubeConfigurationBuilder.d.ts.map +1 -1
  85. package/lib/stores/dataCube/core/DataCubeConfigurationBuilder.js +2 -1
  86. package/lib/stores/dataCube/core/DataCubeConfigurationBuilder.js.map +1 -1
  87. package/lib/stores/dataCube/core/DataCubeCoreState.d.ts +1 -1
  88. package/lib/stores/dataCube/core/DataCubeCoreState.d.ts.map +1 -1
  89. package/lib/stores/dataCube/core/DataCubeCoreState.js +1 -1
  90. package/lib/stores/dataCube/core/DataCubeCoreState.js.map +1 -1
  91. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js +6 -6
  92. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js.map +1 -1
  93. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts +46 -29
  94. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts.map +1 -1
  95. package/lib/stores/dataCube/core/DataCubeQueryEngine.js +68 -50
  96. package/lib/stores/dataCube/core/DataCubeQueryEngine.js.map +1 -1
  97. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  98. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js +5 -5
  99. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  100. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.d.ts +1 -3
  101. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.d.ts.map +1 -1
  102. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.js +2 -3
  103. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.js.map +1 -1
  104. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.d.ts +3 -0
  105. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.d.ts.map +1 -1
  106. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js +9 -0
  107. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js.map +1 -1
  108. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts +8 -7
  109. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts.map +1 -1
  110. package/lib/stores/dataCube/editor/DataCubeEditorState.js +21 -17
  111. package/lib/stores/dataCube/editor/DataCubeEditorState.js.map +1 -1
  112. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.d.ts +43 -38
  113. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.d.ts.map +1 -1
  114. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.js +209 -128
  115. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.js.map +1 -1
  116. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts +32 -0
  117. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  118. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js +34 -1
  119. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js.map +1 -1
  120. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.d.ts +4 -1
  121. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.d.ts.map +1 -1
  122. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.js +327 -36
  123. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.js.map +1 -1
  124. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts +16 -2
  125. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts.map +1 -1
  126. package/lib/stores/dataCube/grid/DataCubeGridState.js +51 -21
  127. package/lib/stores/dataCube/grid/DataCubeGridState.js.map +1 -1
  128. package/package.json +20 -20
  129. package/src/components/LegendREPLFrameworkProvider.tsx +1 -1
  130. package/src/components/REPLStoreProvider.tsx +1 -1
  131. package/src/components/REPLWindow.tsx +179 -0
  132. package/src/components/dataCube/DataCube.tsx +1 -1
  133. package/src/components/dataCube/editor/DataCubeEditor.tsx +79 -190
  134. package/src/components/dataCube/editor/DataCubeEditorCodePanel.tsx +3 -1
  135. package/src/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.tsx +480 -279
  136. package/src/components/dataCube/editor/DataCubeEditorColumnsPanel.tsx +1 -1
  137. package/src/components/dataCube/editor/DataCubeEditorColumnsSelector.tsx +0 -1
  138. package/src/components/dataCube/editor/DataCubeEditorDeveloperPanel.tsx +3 -1
  139. package/src/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.tsx +3 -1
  140. package/src/components/dataCube/editor/DataCubeEditorFilterPanel.tsx +3 -1
  141. package/src/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.tsx +235 -174
  142. package/src/components/dataCube/editor/DataCubeEditorHPivotsPanel.tsx +3 -1
  143. package/src/components/dataCube/editor/DataCubeEditorShared.tsx +69 -33
  144. package/src/components/dataCube/editor/DataCubeEditorSortsPanel.tsx +1 -1
  145. package/src/components/dataCube/editor/DataCubeEditorVPivotsPanel.tsx +3 -1
  146. package/src/components/dataCube/grid/DataCubeGrid.tsx +310 -149
  147. package/src/components/dataCube/grid/DataCubeGridShared.tsx +5 -1
  148. package/src/components/dataCube/grid/menu/DataCubeGridMenu.tsx +76 -29
  149. package/src/components/dataCube/grid/menu/DataCubeGridSortsMenu.tsx +10 -11
  150. package/src/stores/{dataCube/REPLStore.ts → REPLStore.ts} +6 -3
  151. package/src/stores/dataCube/{core/DataCubeEngine.ts → DataCubeInfrastructure.ts} +40 -3
  152. package/src/stores/dataCube/DataCubeState.ts +9 -9
  153. package/src/stores/dataCube/core/DataCubeConfiguration.ts +106 -86
  154. package/src/stores/dataCube/core/DataCubeConfigurationBuilder.ts +5 -1
  155. package/src/stores/dataCube/core/DataCubeCoreState.ts +4 -1
  156. package/src/stores/dataCube/core/DataCubeQueryBuilder.ts +11 -11
  157. package/src/stores/dataCube/core/DataCubeQueryEngine.ts +70 -49
  158. package/src/stores/dataCube/core/DataCubeQuerySnapshotBuilder.ts +6 -7
  159. package/src/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.ts +6 -5
  160. package/src/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.ts +14 -0
  161. package/src/stores/dataCube/editor/DataCubeEditorState.ts +26 -19
  162. package/src/stores/dataCube/editor/DataCubeMutableConfiguration.ts +247 -139
  163. package/src/stores/dataCube/grid/DataCubeGridClientEngine.ts +55 -1
  164. package/src/stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.tsx +491 -43
  165. package/src/stores/dataCube/grid/DataCubeGridState.ts +73 -20
  166. package/tsconfig.json +3 -2
  167. package/lib/stores/dataCube/REPLStore.d.ts.map +0 -1
  168. package/lib/stores/dataCube/REPLStore.js.map +0 -1
  169. package/lib/stores/dataCube/core/DataCubeEngine.d.ts.map +0 -1
  170. package/lib/stores/dataCube/core/DataCubeEngine.js.map +0 -1
@@ -22,16 +22,34 @@ import { RowGroupingModule } from '@ag-grid-enterprise/row-grouping';
22
22
  import { ClipboardModule } from '@ag-grid-enterprise/clipboard';
23
23
  import { MenuModule } from '@ag-grid-enterprise/menu';
24
24
  import { AgGridReact } from '@ag-grid-community/react';
25
- import { useEffect, useState } from 'react';
25
+ import { useEffect } from 'react';
26
26
  import { useREPLStore } from '../../REPLStoreProvider.js';
27
- import { DataCubeIcon, Switch, cn } from '@finos/legend-art';
27
+ import { DataCubeIcon, Switch, cn, Global, css } from '@finos/legend-art';
28
28
  import {
29
- INTERNAL__GRID_CLIENT_HEADER_HEIGHT,
30
- INTERNAL__GRID_CLIENT_ROW_HEIGHT,
29
+ generateBackgroundColorUtilityClassName,
30
+ generateFontCaseUtilityClassName,
31
+ generateFontFamilyUtilityClassName,
32
+ generateFontSizeUtilityClassName,
33
+ generateFontUnderlineUtilityClassName,
34
+ generateTextAlignUtilityClassName,
35
+ generateTextColorUtilityClassName,
36
+ INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME,
31
37
  } from '../../../stores/dataCube/grid/DataCubeGridClientEngine.js';
32
38
  import { RangeSelectionModule } from '@ag-grid-enterprise/range-selection';
33
- import { buildGridMenu } from './menu/DataCubeGridMenu.js';
34
- import { DEFAULT_ROW_BUFFER } from '../../../stores/dataCube/core/DataCubeQueryEngine.js';
39
+ import {
40
+ DataCubeFont,
41
+ DataCubeFontCase,
42
+ DataCubeFontFormatUnderlineVariant,
43
+ DataCubeFontTextAlignment,
44
+ DEFAULT_ROW_BACKGROUND_COLOR,
45
+ DEFAULT_ROW_HIGHLIGHT_BACKGROUND_COLOR,
46
+ } from '../../../stores/dataCube/core/DataCubeQueryEngine.js';
47
+ import { isNonNullable } from '@finos/legend-shared';
48
+ import type {
49
+ DataCubeConfiguration,
50
+ DataCubeConfigurationColorKey,
51
+ } from '../../../stores/dataCube/core/DataCubeConfiguration.js';
52
+ import { generateBaseGridOptions } from '../../../stores/dataCube/grid/DataCubeGridQuerySnapshotAnalyzer.js';
35
53
 
36
54
  // NOTE: This is a workaround to prevent ag-grid license key check from flooding the console screen
37
55
  // with its stack trace in Chrome.
@@ -43,11 +61,292 @@ console.error = (message?: unknown, ...agrs: unknown[]): void => {
43
61
  console.log(`%c ${message}`, 'color: silver'); // eslint-disable-line no-console
44
62
  };
45
63
 
64
+ function textColorStyle(
65
+ key: DataCubeConfigurationColorKey,
66
+ configuration: DataCubeConfiguration,
67
+ ) {
68
+ return `${Array.from(
69
+ new Set([
70
+ configuration[`${key}ForegroundColor`],
71
+ ...configuration.columns
72
+ .map((column) => column[`${key}ForegroundColor`])
73
+ .filter(isNonNullable),
74
+ ]).values(),
75
+ )
76
+ .map(
77
+ (color) =>
78
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateTextColorUtilityClassName(color, key)}{color:${color};}`,
79
+ )
80
+ .join('\n')}`;
81
+ }
82
+
83
+ function backgroundColorStyle(
84
+ key: DataCubeConfigurationColorKey,
85
+ configuration: DataCubeConfiguration,
86
+ ) {
87
+ return `${Array.from(
88
+ new Set([
89
+ configuration[`${key}BackgroundColor`],
90
+ ...configuration.columns
91
+ .map((column) => column[`${key}BackgroundColor`])
92
+ .filter(isNonNullable),
93
+ ]).values(),
94
+ )
95
+ .map(
96
+ (color) =>
97
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateBackgroundColorUtilityClassName(color, key)}{background-color:${color};}`,
98
+ )
99
+ .join('\n')};`;
100
+ }
101
+
102
+ export const DataCubeGridStyleController = observer(() => {
103
+ const replStore = useREPLStore();
104
+ const dataCube = replStore.dataCube;
105
+ const grid = dataCube.grid;
106
+ const configuration = grid.queryConfiguration;
107
+
108
+ return (
109
+ <Global
110
+ styles={css`
111
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} {
112
+ --ag-odd-row-background-color: ${grid.queryConfiguration
113
+ .alternateRowsStandardMode && !grid.queryConfiguration.alternateRows
114
+ ? DEFAULT_ROW_HIGHLIGHT_BACKGROUND_COLOR
115
+ : DEFAULT_ROW_BACKGROUND_COLOR};
116
+ --ag-cell-horizontal-border: ${grid.queryConfiguration
117
+ .showVerticalGridLines
118
+ ? `1px solid
119
+ ${grid.queryConfiguration.gridLineColor}`
120
+ : 'none'};
121
+ --ag-row-border-color: ${grid.queryConfiguration
122
+ .showHorizontalGridLines
123
+ ? grid.queryConfiguration.gridLineColor
124
+ : 'transparent'};
125
+ }
126
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT}
127
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.HIGHLIGHT_ROW} {
128
+ background-color: ${grid.queryConfiguration.alternateRows
129
+ ? grid.queryConfiguration.alternateRowsColor
130
+ : DEFAULT_ROW_BACKGROUND_COLOR};
131
+ }
132
+ ${[
133
+ DataCubeFont.ARIAL,
134
+ DataCubeFont.ROBOTO,
135
+ DataCubeFont.ROBOTO_CONDENSED,
136
+ ]
137
+ .map(
138
+ (fontFamily) =>
139
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontFamilyUtilityClassName(fontFamily)}{font-family:${fontFamily},sans-serif;}`,
140
+ )
141
+ .join('\n')}
142
+ ${[
143
+ DataCubeFont.GEORGIA,
144
+ DataCubeFont.ROBOTO_SERIF,
145
+ DataCubeFont.TIMES_NEW_ROMAN,
146
+ ]
147
+ .map(
148
+ (fontFamily) =>
149
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontFamilyUtilityClassName(fontFamily)}{font-family:${fontFamily},serif;}`,
150
+ )
151
+ .join('\n')}
152
+ ${[
153
+ DataCubeFont.JERBRAINS_MONO,
154
+ DataCubeFont.ROBOTO_MONO,
155
+ DataCubeFont.UBUNTU_MONO,
156
+ ]
157
+ .map(
158
+ (fontFamily) =>
159
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontFamilyUtilityClassName(fontFamily)}{font-family:${fontFamily},monospace;}`,
160
+ )
161
+ .join('\n')}
162
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.FONT_BOLD} {
163
+ font-weight: 700;
164
+ }
165
+ ${[
166
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 32, 36,
167
+ 48, 72,
168
+ ]
169
+ .map(
170
+ (fontSize) =>
171
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontSizeUtilityClassName(fontSize)}{font-size:${fontSize}px;}`,
172
+ )
173
+ .join('\n')}
174
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT}
175
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.FONT_ITALIC} {
176
+ font-style: italic;
177
+ }
178
+ ${[
179
+ DataCubeFontFormatUnderlineVariant.SOLID,
180
+ DataCubeFontFormatUnderlineVariant.DASHED,
181
+ DataCubeFontFormatUnderlineVariant.DOTTED,
182
+ DataCubeFontFormatUnderlineVariant.DOUBLE,
183
+ DataCubeFontFormatUnderlineVariant.WAVY,
184
+ ]
185
+ .map(
186
+ (variant) =>
187
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontUnderlineUtilityClassName(variant)}{text-decoration:underline ${variant};}`,
188
+ )
189
+ .join('\n')}
190
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.FONT_STRIKETHROUGH} {
191
+ text-decoration: line-through;
192
+ }
193
+ ${[
194
+ DataCubeFontCase.LOWERCASE,
195
+ DataCubeFontCase.UPPERCASE,
196
+ DataCubeFontCase.CAPITALIZE,
197
+ ]
198
+ .map(
199
+ (fontCase) =>
200
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateFontCaseUtilityClassName(fontCase)}{text-transform:${fontCase};}`,
201
+ )
202
+ .join('\n')}
203
+ ${[
204
+ DataCubeFontTextAlignment.LEFT,
205
+ DataCubeFontTextAlignment.CENTER,
206
+ DataCubeFontTextAlignment.RIGHT,
207
+ ]
208
+ .map(
209
+ (alignment) =>
210
+ `.${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT} .${generateTextAlignUtilityClassName(alignment)}{text-align:${alignment};}`,
211
+ )
212
+ .join('\n')};
213
+ ${backgroundColorStyle('normal', configuration)}
214
+ ${backgroundColorStyle('zero', configuration)}
215
+ ${backgroundColorStyle('negative', configuration)}
216
+ ${backgroundColorStyle('error', configuration)}
217
+ ${textColorStyle('normal', configuration)}
218
+ ${textColorStyle('zero', configuration)}
219
+ ${textColorStyle('negative', configuration)}
220
+ ${textColorStyle('error', configuration)}
221
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT}
222
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.BLUR} {
223
+ filter: blur(3px);
224
+ }
225
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.ROOT}
226
+ .${INTERNAL__GRID_CLIENT_UTILITY_CSS_CLASS_NAME.BLUR}:hover {
227
+ filter: none;
228
+ }
229
+ `}
230
+ />
231
+ );
232
+ });
233
+
234
+ const DataCubeGridStatusBar = observer(() => {
235
+ const replStore = useREPLStore();
236
+ const dataCube = replStore.dataCube;
237
+ const grid = dataCube.grid;
238
+ const scrollHintText = grid.scrollHintText;
239
+
240
+ return (
241
+ <div className="relative flex h-5 w-full select-none justify-between border-b border-neutral-200 bg-neutral-100">
242
+ {Boolean(scrollHintText) && (
243
+ <div className="absolute -top-9 right-4 flex items-center rounded-sm border border-neutral-300 bg-neutral-100 p-1 pr-2 text-neutral-500 shadow-sm">
244
+ <DataCubeIcon.TableScroll className="text-lg" />
245
+ <div className="ml-1 font-mono text-sm">{scrollHintText}</div>
246
+ </div>
247
+ )}
248
+ <div />
249
+ <div className="flex h-full items-center">
250
+ <div className="flex h-full items-center px-2 font-mono text-sm text-neutral-500">
251
+ {grid.clientDataSource.rowCount
252
+ ? `Rows: ${grid.clientDataSource.rowCount}`
253
+ : ''}
254
+ </div>
255
+ {grid.datasourceConfiguration.limit !== undefined &&
256
+ grid.queryConfiguration.showWarningForTruncatedResult && (
257
+ // TODO: if we want to properly warn if the data has been truncated due to row limit,
258
+ // this would require us to fetch n+1 rows when limit=n
259
+ // This is feature is not difficult to implement, but it would be implemented most cleanly
260
+ // when we change the query execution engine to return the total number of rows,
261
+ // so for now, we simply just warn about truncation whenever a limit != -1 is specified
262
+ <>
263
+ <div className="h-3 w-[1px] bg-neutral-200" />
264
+ <div className="flex h-full items-center px-2 text-orange-500">
265
+ <DataCubeIcon.Warning className="stroke-[3px]" />
266
+ <div className="ml-1 text-sm font-semibold">{`Results truncated to fit within row limit (${grid.datasourceConfiguration.limit})`}</div>
267
+ </div>
268
+ </>
269
+ )}
270
+ <div className="h-3 w-[1px] bg-neutral-200" />
271
+ <button
272
+ className="flex h-full items-center p-2"
273
+ onClick={(): void =>
274
+ grid.setPaginationEnabled(!grid.isPaginationEnabled)
275
+ }
276
+ >
277
+ <Switch
278
+ checked={grid.isPaginationEnabled}
279
+ classes={{
280
+ root: 'p-0 w-6 h-5 flex items-center',
281
+ input: 'w-2',
282
+ checked: '!translate-x-2 ease-in-out duration-100 transition',
283
+ thumb: cn('w-2 h-2', {
284
+ 'bg-sky-600': grid.isPaginationEnabled,
285
+ 'bg-neutral-500': !grid.isPaginationEnabled,
286
+ }),
287
+ switchBase:
288
+ 'p-0.5 mt-1 translate-x-0 ease-in-out duration-100 transition',
289
+ track: cn('h-3 w-5 border', {
290
+ '!bg-sky-100 border-sky-600': grid.isPaginationEnabled,
291
+ '!bg-neutral-100 border-neutral-500': !grid.isPaginationEnabled,
292
+ }),
293
+ }}
294
+ disableRipple={true}
295
+ disableFocusRipple={true}
296
+ />
297
+ <div
298
+ className={cn('text-sm', {
299
+ 'text-sky-600': grid.isPaginationEnabled,
300
+ 'text-neutral-500': !grid.isPaginationEnabled,
301
+ })}
302
+ >
303
+ Pagination
304
+ </div>
305
+ </button>
306
+ </div>
307
+ </div>
308
+ );
309
+ });
310
+
311
+ const DataCubeGridClient = observer(() => {
312
+ const replStore = useREPLStore();
313
+ const dataCube = replStore.dataCube;
314
+ const grid = dataCube.grid;
315
+
316
+ return (
317
+ <div className="relative h-[calc(100%_-_20px)] w-full">
318
+ <AgGridReact
319
+ className="data-cube-grid ag-theme-balham"
320
+ rowModelType="serverSide"
321
+ serverSideDatasource={grid.clientDataSource}
322
+ context={{
323
+ dataCube,
324
+ }}
325
+ onGridReady={(params): void => {
326
+ grid.configureClient(params.api);
327
+ // restore original error logging
328
+ console.error = __INTERNAL__original_console_error; // eslint-disable-line no-console
329
+ }}
330
+ modules={[
331
+ // community
332
+ ClientSideRowModelModule,
333
+ // enterprise
334
+ ServerSideRowModelModule,
335
+ RowGroupingModule,
336
+ MenuModule,
337
+ ClipboardModule,
338
+ RangeSelectionModule,
339
+ ]}
340
+ {...generateBaseGridOptions(dataCube)}
341
+ />
342
+ </div>
343
+ );
344
+ });
345
+
46
346
  export const DataCubeGrid = observer(() => {
47
347
  const replStore = useREPLStore();
48
348
  const dataCube = replStore.dataCube;
49
349
  const grid = dataCube.grid;
50
- const [scrollHintText, setScrollHintText] = useState('');
51
350
 
52
351
  useEffect(() => {
53
352
  if (grid.clientLicenseKey) {
@@ -56,148 +355,10 @@ export const DataCubeGrid = observer(() => {
56
355
  }, [grid.clientLicenseKey]);
57
356
 
58
357
  return (
59
- <div className="data-cube-grid flex-1">
60
- <div className="h-[calc(100%_-_20px)] w-full">
61
- <AgGridReact
62
- // -------------------------------------- ROW GROUPING --------------------------------------
63
- rowGroupPanelShow="always"
64
- suppressScrollOnNewData={true}
65
- groupDisplayType="custom" // keeps the column set stable even when row grouping is used
66
- suppressRowGroupHidesColumns={true} // keeps the column set stable even when row grouping is used
67
- // Keeps the columns stable even when aggregation is used
68
- suppressAggFuncInHeader={true}
69
- // -------------------------------------- PIVOT --------------------------------------
70
- // pivotPanelShow="always"
71
- // pivotMode={true}
72
- // -------------------------------------- SORT --------------------------------------
73
- // Force multi-sorting since this is what the query supports anyway
74
- alwaysMultiSort={true}
75
- // -------------------------------------- DISPLAY & INTERACTION --------------------------------------
76
- className="ag-theme-balham"
77
- rowHeight={INTERNAL__GRID_CLIENT_ROW_HEIGHT}
78
- headerHeight={INTERNAL__GRID_CLIENT_HEADER_HEIGHT}
79
- suppressBrowserResizeObserver={true}
80
- reactiveCustomComponents={true} // TODO: remove on v32 as this would be default to `true` then
81
- noRowsOverlayComponent={() => (
82
- <div className="flex items-center border-[1.5px] border-neutral-300 p-2 font-medium text-neutral-400">
83
- <div>
84
- <DataCubeIcon.WarningCircle className="mr-1 stroke-2 text-lg" />
85
- </div>
86
- 0 rows
87
- </div>
88
- )}
89
- loadingOverlayComponent={() => (
90
- <div className="flex items-center border-[1.5px] border-neutral-300 p-2 font-medium text-neutral-400">
91
- <div>
92
- <DataCubeIcon.Loader className="mr-1 animate-spin stroke-2 text-lg" />
93
- </div>
94
- Loading...
95
- </div>
96
- )}
97
- preventDefaultOnContextMenu={true}
98
- columnMenu="new" // ensure context menu works on header
99
- getContextMenuItems={buildGridMenu}
100
- getMainMenuItems={buildGridMenu}
101
- enableRangeSelection={true}
102
- // Show cursor position when scrolling
103
- onBodyScroll={(event) => {
104
- const rowCount = event.api.getDisplayedRowCount();
105
- const range = event.api.getVerticalPixelRange();
106
- const start = Math.max(
107
- 1,
108
- Math.ceil(range.top / INTERNAL__GRID_CLIENT_ROW_HEIGHT) + 1,
109
- );
110
- const end = Math.min(
111
- rowCount,
112
- Math.floor(range.bottom / INTERNAL__GRID_CLIENT_ROW_HEIGHT),
113
- );
114
- setScrollHintText(`${start}-${end}/${rowCount}`);
115
- event.api.hidePopupMenu(); // hide context-menu while scrolling
116
- }}
117
- onBodyScrollEnd={() => setScrollHintText('')}
118
- // -------------------------------------- SERVER SIDE ROW MODEL --------------------------------------
119
- rowModelType="serverSide"
120
- serverSideDatasource={grid.clientDataSource}
121
- // -------------------------------------- PERFORMANCE --------------------------------------
122
- // NOTE: since we shrink the spacing, more rows can be shown, as such, setting higher row
123
- // buffer will improve scrolling performance, but compromise initial load and various
124
- // actions performance
125
- rowBuffer={DEFAULT_ROW_BUFFER}
126
- animateRows={false} // improve performance
127
- // -------------------------------------- SETUP --------------------------------------
128
- modules={[
129
- // community
130
- ClientSideRowModelModule,
131
- // enterprise
132
- ServerSideRowModelModule,
133
- RowGroupingModule,
134
- MenuModule,
135
- ClipboardModule,
136
- RangeSelectionModule,
137
- ]}
138
- onGridReady={(params): void => {
139
- grid.configureClient(params.api);
140
- // restore original error logging
141
- console.error = __INTERNAL__original_console_error; // eslint-disable-line no-console
142
- }}
143
- context={{
144
- dataCube,
145
- }}
146
- />
147
- </div>
148
- <div className="relative flex h-5 w-full justify-between border-b border-b-neutral-200 bg-neutral-100">
149
- {Boolean(scrollHintText) && (
150
- <div className="absolute -top-8 right-4 flex items-center rounded-sm border border-neutral-300 bg-neutral-100 p-1 pr-2 text-neutral-500 shadow-sm">
151
- <DataCubeIcon.TableScroll className="text-lg" />
152
- <div className="ml-1 font-mono text-sm">{scrollHintText}</div>
153
- </div>
154
- )}
155
- <div />
156
- <div className="flex items-center">
157
- <div className="select-none p-2 font-mono text-sm text-neutral-500">
158
- {grid.clientDataSource.rowCount
159
- ? `(${grid.clientDataSource.rowCount} rows)`
160
- : ''}
161
- </div>
162
- <div className="h-3 w-[1px] bg-neutral-200" />
163
- <button
164
- className="flex h-full items-center p-2"
165
- onClick={(): void =>
166
- grid.setPaginationEnabled(!grid.isPaginationEnabled)
167
- }
168
- >
169
- <Switch
170
- checked={grid.isPaginationEnabled}
171
- classes={{
172
- root: 'p-0 w-6 h-5 flex items-center',
173
- input: 'w-2',
174
- checked: '!translate-x-2 ease-in-out duration-100 transition',
175
- thumb: cn('w-2 h-2', {
176
- 'bg-sky-600': grid.isPaginationEnabled,
177
- 'bg-neutral-500': !grid.isPaginationEnabled,
178
- }),
179
- switchBase:
180
- 'p-0.5 mt-1 translate-x-0 ease-in-out duration-100 transition',
181
- track: cn('h-3 w-5 border', {
182
- '!bg-sky-100 border-sky-600': grid.isPaginationEnabled,
183
- '!bg-neutral-100 border-neutral-500':
184
- !grid.isPaginationEnabled,
185
- }),
186
- }}
187
- disableRipple={true}
188
- disableFocusRipple={true}
189
- />
190
- <div
191
- className={cn('text-sm', {
192
- 'text-sky-600': grid.isPaginationEnabled,
193
- 'text-neutral-500': !grid.isPaginationEnabled,
194
- })}
195
- >
196
- Pagination
197
- </div>
198
- </button>
199
- </div>
200
- </div>
358
+ <div className="flex-1">
359
+ <DataCubeGridStyleController />
360
+ <DataCubeGridClient />
361
+ <DataCubeGridStatusBar />
201
362
  </div>
202
363
  );
203
364
  });
@@ -20,7 +20,11 @@ import {
20
20
  } from '@ag-grid-community/react';
21
21
  import { WIP_Badge } from '../editor/DataCubeEditorShared.js';
22
22
 
23
- export function WIP_GridMenuItem({ name, subMenu }: CustomMenuItemProps) {
23
+ export function WIP_GridMenuItem({
24
+ name,
25
+ subMenu,
26
+ checked,
27
+ }: CustomMenuItemProps) {
24
28
  useGridMenuItem({
25
29
  configureDefaults: () => true,
26
30
  });
@@ -22,6 +22,11 @@ import type {
22
22
  import type { DataCubeState } from '../../../../stores/dataCube/DataCubeState.js';
23
23
  import { buildGridSortsMenu } from './DataCubeGridSortsMenu.js';
24
24
  import { WIP_GridMenuItem } from '../DataCubeGridShared.js';
25
+ import {
26
+ DataCubeColumnPinPlacement,
27
+ DEFAULT_COLUMN_MIN_WIDTH,
28
+ } from '../../../../stores/dataCube/core/DataCubeQueryEngine.js';
29
+ import { isNonNullable } from '@finos/legend-shared';
25
30
 
26
31
  export function buildGridMenu(
27
32
  params:
@@ -32,6 +37,9 @@ export function buildGridMenu(
32
37
  const dataCube = context.dataCube;
33
38
  const editor = dataCube.editor;
34
39
  const column = params.column ?? undefined;
40
+ const columnConfiguration = editor.columnProperties.getColumnConfiguration(
41
+ column?.getColId(),
42
+ );
35
43
  const value: unknown = 'value' in params ? params.value : undefined;
36
44
 
37
45
  const result: (string | MenuItemDef)[] = [
@@ -308,55 +316,94 @@ export function buildGridMenu(
308
316
  'separator',
309
317
  {
310
318
  name: 'Resize',
311
- menuItem: WIP_GridMenuItem,
312
- cssClasses: ['!opacity-100'],
313
- disabled: true,
314
319
  subMenu: [
315
320
  {
316
- name: `Size to Fit Content`,
317
- menuItem: WIP_GridMenuItem,
318
- cssClasses: ['!opacity-100'],
319
- disabled: true,
321
+ name: `Auto-size to Fit Content`,
322
+ action: () =>
323
+ params.api.autoSizeColumns(
324
+ [column?.getColId()].filter(isNonNullable),
325
+ ),
326
+ disabled: !column,
327
+ },
328
+ {
329
+ name: `Minimize Column`,
330
+ action: () => {
331
+ if (column) {
332
+ params.api.setColumnWidths([
333
+ {
334
+ key: column.getColId(),
335
+ newWidth:
336
+ columnConfiguration?.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,
337
+ },
338
+ ]);
339
+ }
340
+ },
341
+ disabled: !column,
320
342
  },
343
+ 'separator',
321
344
  {
322
- name: `Autosize`,
323
- menuItem: WIP_GridMenuItem,
324
- cssClasses: ['!opacity-100'],
325
- disabled: true,
345
+ name: `Auto-size All Columns`,
346
+ action: () => params.api.autoSizeAllColumns(),
326
347
  },
327
- 'separator',
328
348
  {
329
- name: `Autosize All Columns`,
330
- menuItem: WIP_GridMenuItem,
331
- cssClasses: ['!opacity-100'],
332
- disabled: true,
349
+ name: `Minimize All Columns`,
350
+ action: () => {
351
+ params.api.setColumnWidths(
352
+ dataCube.editor.columnProperties.columns.map((col) => ({
353
+ key: col.name,
354
+ newWidth:
355
+ columnConfiguration?.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,
356
+ })),
357
+ );
358
+ },
359
+ },
360
+ {
361
+ name: `Size Grid to Fit Screen`,
362
+ action: () => params.api.sizeColumnsToFit(),
333
363
  },
334
364
  ],
335
365
  },
336
366
  {
337
367
  name: 'Pin',
338
- menuItem: WIP_GridMenuItem,
339
- cssClasses: ['!opacity-100'],
340
- disabled: true,
341
368
  subMenu: [
342
369
  {
343
370
  name: `Pin Left`,
344
- menuItem: WIP_GridMenuItem,
345
- cssClasses: ['!opacity-100'],
346
- disabled: true,
371
+ disabled: !column || column.isPinnedLeft(),
372
+ checked: Boolean(column?.isPinnedLeft()),
373
+ action: () => {
374
+ columnConfiguration?.setPinned(DataCubeColumnPinPlacement.LEFT);
375
+ editor.applyChanges();
376
+ },
347
377
  },
348
378
  {
349
379
  name: `Pin Right`,
350
- menuItem: WIP_GridMenuItem,
351
- cssClasses: ['!opacity-100'],
352
- disabled: true,
380
+ disabled: !column || column.isPinnedRight(),
381
+ checked: Boolean(column?.isPinnedRight()),
382
+ action: () => {
383
+ columnConfiguration?.setPinned(DataCubeColumnPinPlacement.RIGHT);
384
+ editor.applyChanges();
385
+ },
386
+ },
387
+ {
388
+ name: `Unpin`,
389
+ disabled: !column?.isPinned(),
390
+ action: () => {
391
+ columnConfiguration?.setPinned(undefined);
392
+ editor.applyChanges();
393
+ },
353
394
  },
354
395
  'separator',
355
396
  {
356
- name: `Remove Pinning`,
357
- menuItem: WIP_GridMenuItem,
358
- cssClasses: ['!opacity-100'],
359
- disabled: true,
397
+ name: `Remove All Pinnings`,
398
+ disabled: editor.columnProperties.columns.every(
399
+ (col) => col.pinned === undefined,
400
+ ),
401
+ action: () => {
402
+ editor.columnProperties.columns.forEach((col) =>
403
+ col.setPinned(undefined),
404
+ );
405
+ editor.applyChanges();
406
+ },
360
407
  },
361
408
  ],
362
409
  },