@finos/legend-application-repl 0.0.48 → 0.0.50

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 (336) hide show
  1. package/lib/components/dataCube/DataCube.d.ts.map +1 -1
  2. package/lib/components/dataCube/DataCube.js +14 -11
  3. package/lib/components/dataCube/DataCube.js.map +1 -1
  4. package/lib/components/dataCube/editor/DataCubeEditor.d.ts +4 -1
  5. package/lib/components/dataCube/editor/DataCubeEditor.d.ts.map +1 -1
  6. package/lib/components/dataCube/editor/DataCubeEditor.js +6 -7
  7. package/lib/components/dataCube/editor/DataCubeEditor.js.map +1 -1
  8. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.d.ts +4 -1
  9. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.d.ts.map +1 -1
  10. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js +2 -12
  11. package/lib/components/dataCube/editor/DataCubeEditorCodePanel.js.map +1 -1
  12. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.d.ts +4 -1
  13. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
  14. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.js +57 -51
  15. package/lib/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
  16. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.d.ts +4 -1
  17. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.d.ts.map +1 -1
  18. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js +3 -4
  19. package/lib/components/dataCube/editor/DataCubeEditorColumnsPanel.js.map +1 -1
  20. package/lib/components/dataCube/editor/DataCubeEditorColumnsSelector.js +1 -1
  21. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.d.ts +4 -1
  22. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.d.ts.map +1 -1
  23. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.js +3 -4
  24. package/lib/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.js.map +1 -1
  25. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.d.ts +4 -1
  26. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.d.ts.map +1 -1
  27. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.js +289 -10
  28. package/lib/components/dataCube/editor/DataCubeEditorFilterPanel.js.map +1 -1
  29. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.d.ts +4 -1
  30. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.d.ts.map +1 -1
  31. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.js +30 -30
  32. package/lib/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.js.map +1 -1
  33. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.d.ts +4 -1
  34. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.d.ts.map +1 -1
  35. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.js +3 -4
  36. package/lib/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.js.map +1 -1
  37. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.d.ts +4 -1
  38. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.d.ts.map +1 -1
  39. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.js +19 -20
  40. package/lib/components/dataCube/editor/DataCubeEditorSortsPanel.js.map +1 -1
  41. package/lib/components/dataCube/editor/DataCubeEditorVerticalPivotsPanel.d.ts +4 -1
  42. package/lib/components/dataCube/editor/DataCubeEditorVerticalPivotsPanel.d.ts.map +1 -1
  43. package/lib/components/dataCube/editor/DataCubeEditorVerticalPivotsPanel.js +3 -4
  44. package/lib/components/dataCube/editor/DataCubeEditorVerticalPivotsPanel.js.map +1 -1
  45. package/lib/components/dataCube/grid/DataCubeGrid.d.ts +7 -2
  46. package/lib/components/dataCube/grid/DataCubeGrid.d.ts.map +1 -1
  47. package/lib/components/dataCube/grid/DataCubeGrid.js +53 -54
  48. package/lib/components/dataCube/grid/DataCubeGrid.js.map +1 -1
  49. package/lib/components/repl/Form.d.ts +4 -2
  50. package/lib/components/repl/Form.d.ts.map +1 -1
  51. package/lib/components/repl/Form.js +55 -19
  52. package/lib/components/repl/Form.js.map +1 -1
  53. package/lib/index.css +2 -2
  54. package/lib/index.css.map +1 -1
  55. package/lib/package.json +4 -3
  56. package/lib/stores/dataCube/DataCubeEngine.d.ts +30 -0
  57. package/lib/stores/dataCube/DataCubeEngine.d.ts.map +1 -1
  58. package/lib/stores/dataCube/DataCubeEngine.js +60 -1
  59. package/lib/stores/dataCube/DataCubeEngine.js.map +1 -1
  60. package/lib/stores/dataCube/DataCubeState.d.ts +2 -2
  61. package/lib/stores/dataCube/DataCubeState.d.ts.map +1 -1
  62. package/lib/stores/dataCube/DataCubeState.js +11 -5
  63. package/lib/stores/dataCube/DataCubeState.js.map +1 -1
  64. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts +0 -1
  65. package/lib/stores/dataCube/core/DataCubeConfiguration.d.ts.map +1 -1
  66. package/lib/stores/dataCube/core/DataCubeConfiguration.js +0 -2
  67. package/lib/stores/dataCube/core/DataCubeConfiguration.js.map +1 -1
  68. package/lib/stores/dataCube/core/DataCubeQueryBuilder.d.ts +8 -17
  69. package/lib/stores/dataCube/core/DataCubeQueryBuilder.d.ts.map +1 -1
  70. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js +16 -230
  71. package/lib/stores/dataCube/core/DataCubeQueryBuilder.js.map +1 -1
  72. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.d.ts +44 -0
  73. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.d.ts.map +1 -0
  74. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.js +221 -0
  75. package/lib/stores/dataCube/core/DataCubeQueryBuilderUtils.js.map +1 -0
  76. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts +41 -20
  77. package/lib/stores/dataCube/core/DataCubeQueryEngine.d.ts.map +1 -1
  78. package/lib/stores/dataCube/core/DataCubeQueryEngine.js +70 -46
  79. package/lib/stores/dataCube/core/DataCubeQueryEngine.js.map +1 -1
  80. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.d.ts +7 -5
  81. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.d.ts.map +1 -1
  82. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.js +1 -1
  83. package/lib/stores/dataCube/core/DataCubeQuerySnapshot.js.map +1 -1
  84. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.d.ts +4 -4
  85. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  86. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js +18 -135
  87. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  88. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilderUtils.d.ts +31 -0
  89. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -0
  90. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilderUtils.js +142 -0
  91. package/lib/stores/dataCube/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -0
  92. package/lib/stores/dataCube/core/DataCubeQuerySnapshotManager.d.ts +16 -1
  93. package/lib/stores/dataCube/core/DataCubeQuerySnapshotManager.d.ts.map +1 -1
  94. package/lib/stores/dataCube/core/DataCubeQuerySnapshotManager.js +25 -3
  95. package/lib/stores/dataCube/core/DataCubeQuerySnapshotManager.js.map +1 -1
  96. package/lib/stores/dataCube/core/{DataCubeCoreState.d.ts → DataCubeStaticContentDisplayState.d.ts} +3 -4
  97. package/lib/stores/dataCube/core/DataCubeStaticContentDisplayState.d.ts.map +1 -0
  98. package/lib/stores/dataCube/core/{DataCubeCoreState.js → DataCubeStaticContentDisplayState.js} +3 -6
  99. package/lib/stores/dataCube/core/DataCubeStaticContentDisplayState.js.map +1 -0
  100. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterEditorState.d.ts +36 -0
  101. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterEditorState.d.ts.map +1 -0
  102. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterEditorState.js +153 -0
  103. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterEditorState.js.map +1 -0
  104. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation.d.ts +32 -0
  105. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation.d.ts.map +1 -0
  106. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation.js +64 -0
  107. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation.js.map +1 -0
  108. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Contain.d.ts +34 -0
  109. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Contain.d.ts.map +1 -0
  110. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Contain.js +59 -0
  111. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Contain.js.map +1 -0
  112. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.d.ts +34 -0
  113. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.d.ts.map +1 -0
  114. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.js +64 -0
  115. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.js.map +1 -0
  116. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWith.d.ts +34 -0
  117. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWith.d.ts.map +1 -0
  118. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWith.js +59 -0
  119. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWith.js.map +1 -0
  120. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.d.ts +34 -0
  121. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.d.ts.map +1 -0
  122. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.js +64 -0
  123. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.js.map +1 -0
  124. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Equal.d.ts +34 -0
  125. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Equal.d.ts.map +1 -0
  126. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Equal.js +126 -0
  127. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Equal.js.map +1 -0
  128. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.d.ts +34 -0
  129. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.d.ts.map +1 -0
  130. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.js +64 -0
  131. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.js.map +1 -0
  132. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.d.ts +34 -0
  133. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.d.ts.map +1 -0
  134. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.js +64 -0
  135. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.js.map +1 -0
  136. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualColumn.d.ts +34 -0
  137. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualColumn.d.ts.map +1 -0
  138. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualColumn.js +60 -0
  139. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualColumn.js.map +1 -0
  140. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThan.d.ts +34 -0
  141. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThan.d.ts.map +1 -0
  142. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThan.js +59 -0
  143. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThan.js.map +1 -0
  144. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.d.ts +34 -0
  145. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.d.ts.map +1 -0
  146. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.js +60 -0
  147. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.js.map +1 -0
  148. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.d.ts +34 -0
  149. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.d.ts.map +1 -0
  150. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.js +59 -0
  151. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.js.map +1 -0
  152. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.d.ts +34 -0
  153. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.d.ts.map +1 -0
  154. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.js +60 -0
  155. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.js.map +1 -0
  156. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNotNull.d.ts +31 -0
  157. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNotNull.d.ts.map +1 -0
  158. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNotNull.js +54 -0
  159. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNotNull.js.map +1 -0
  160. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNull.d.ts +31 -0
  161. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNull.d.ts.map +1 -0
  162. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNull.js +54 -0
  163. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNull.js.map +1 -0
  164. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThan.d.ts +34 -0
  165. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThan.d.ts.map +1 -0
  166. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThan.js +59 -0
  167. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThan.js.map +1 -0
  168. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanColumn.d.ts +34 -0
  169. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanColumn.d.ts.map +1 -0
  170. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanColumn.js +60 -0
  171. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanColumn.js.map +1 -0
  172. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.d.ts +34 -0
  173. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.d.ts.map +1 -0
  174. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.js +59 -0
  175. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.js.map +1 -0
  176. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.d.ts +34 -0
  177. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.d.ts.map +1 -0
  178. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.js +60 -0
  179. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.js.map +1 -0
  180. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotContain.d.ts +34 -0
  181. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotContain.d.ts.map +1 -0
  182. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotContain.js +59 -0
  183. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotContain.js.map +1 -0
  184. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEndWith.d.ts +34 -0
  185. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEndWith.d.ts.map +1 -0
  186. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEndWith.js +59 -0
  187. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEndWith.js.map +1 -0
  188. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqual.d.ts +34 -0
  189. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqual.d.ts.map +1 -0
  190. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqual.js +59 -0
  191. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqual.js.map +1 -0
  192. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.d.ts +34 -0
  193. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.d.ts.map +1 -0
  194. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.js +64 -0
  195. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.js.map +1 -0
  196. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.d.ts +34 -0
  197. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.d.ts.map +1 -0
  198. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.js +64 -0
  199. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.js.map +1 -0
  200. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.d.ts +34 -0
  201. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.d.ts.map +1 -0
  202. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.js +60 -0
  203. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.js.map +1 -0
  204. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotStartWith.d.ts +34 -0
  205. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotStartWith.d.ts.map +1 -0
  206. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotStartWith.js +59 -0
  207. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotStartWith.js.map +1 -0
  208. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWith.d.ts +34 -0
  209. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWith.d.ts.map +1 -0
  210. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWith.js +59 -0
  211. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWith.js.map +1 -0
  212. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.d.ts +34 -0
  213. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.d.ts.map +1 -0
  214. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.js +64 -0
  215. package/lib/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.js.map +1 -0
  216. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js +2 -2
  217. package/lib/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.js.map +1 -1
  218. package/lib/stores/dataCube/editor/DataCubeEditorFilterPanelState.d.ts +58 -0
  219. package/lib/stores/dataCube/editor/DataCubeEditorFilterPanelState.d.ts.map +1 -0
  220. package/lib/stores/dataCube/editor/DataCubeEditorFilterPanelState.js +205 -0
  221. package/lib/stores/dataCube/editor/DataCubeEditorFilterPanelState.js.map +1 -0
  222. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.d.ts +4 -4
  223. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
  224. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.js +2 -2
  225. package/lib/stores/dataCube/editor/DataCubeEditorSortsPanelState.js.map +1 -1
  226. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts +5 -4
  227. package/lib/stores/dataCube/editor/DataCubeEditorState.d.ts.map +1 -1
  228. package/lib/stores/dataCube/editor/DataCubeEditorState.js +9 -7
  229. package/lib/stores/dataCube/editor/DataCubeEditorState.js.map +1 -1
  230. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.d.ts +5 -4
  231. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.d.ts.map +1 -1
  232. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.js +6 -5
  233. package/lib/stores/dataCube/editor/DataCubeMutableConfiguration.js.map +1 -1
  234. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts +2 -8
  235. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  236. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js +3 -10
  237. package/lib/stores/dataCube/grid/DataCubeGridClientEngine.js.map +1 -1
  238. package/lib/stores/dataCube/grid/DataCubeGridClientExportEngine.js +1 -1
  239. package/lib/stores/dataCube/grid/DataCubeGridClientExportEngine.js.map +1 -1
  240. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  241. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.js +22 -44
  242. package/lib/stores/dataCube/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  243. package/lib/stores/dataCube/grid/DataCubeGridControllerState.d.ts +17 -7
  244. package/lib/stores/dataCube/grid/DataCubeGridControllerState.d.ts.map +1 -1
  245. package/lib/stores/dataCube/grid/DataCubeGridControllerState.js +59 -6
  246. package/lib/stores/dataCube/grid/DataCubeGridControllerState.js.map +1 -1
  247. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  248. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.js +157 -53
  249. package/lib/stores/dataCube/grid/DataCubeGridMenuBuilder.js.map +1 -1
  250. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.d.ts +2 -1
  251. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  252. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.js +7 -7
  253. package/lib/stores/dataCube/grid/DataCubeGridQueryBuilder.js.map +1 -1
  254. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.d.ts.map +1 -1
  255. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.js +13 -6
  256. package/lib/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
  257. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts +2 -3
  258. package/lib/stores/dataCube/grid/DataCubeGridState.d.ts.map +1 -1
  259. package/lib/stores/dataCube/grid/DataCubeGridState.js +10 -6
  260. package/lib/stores/dataCube/grid/DataCubeGridState.js.map +1 -1
  261. package/package.json +10 -9
  262. package/src/components/dataCube/DataCube.tsx +20 -13
  263. package/src/components/dataCube/editor/DataCubeEditor.tsx +15 -15
  264. package/src/components/dataCube/editor/DataCubeEditorCodePanel.tsx +72 -80
  265. package/src/components/dataCube/editor/DataCubeEditorColumnPropertiesPanel.tsx +1020 -950
  266. package/src/components/dataCube/editor/DataCubeEditorColumnsPanel.tsx +46 -44
  267. package/src/components/dataCube/editor/DataCubeEditorColumnsSelector.tsx +1 -1
  268. package/src/components/dataCube/editor/DataCubeEditorExtendedColumnsPanel.tsx +20 -18
  269. package/src/components/dataCube/editor/DataCubeEditorFilterPanel.tsx +862 -19
  270. package/src/components/dataCube/editor/DataCubeEditorGeneralPropertiesPanel.tsx +687 -667
  271. package/src/components/dataCube/editor/DataCubeEditorHorizontalPivotsPanel.tsx +20 -18
  272. package/src/components/dataCube/editor/DataCubeEditorSortsPanel.tsx +71 -62
  273. package/src/components/dataCube/editor/DataCubeEditorVerticalPivotsPanel.tsx +19 -17
  274. package/src/components/dataCube/grid/DataCubeGrid.tsx +144 -140
  275. package/src/components/repl/Form.tsx +145 -98
  276. package/src/stores/dataCube/DataCubeEngine.ts +69 -1
  277. package/src/stores/dataCube/DataCubeState.ts +13 -9
  278. package/src/stores/dataCube/core/DataCubeConfiguration.ts +1 -3
  279. package/src/stores/dataCube/core/DataCubeQueryBuilder.ts +43 -355
  280. package/src/stores/dataCube/core/DataCubeQueryBuilderUtils.ts +354 -0
  281. package/src/stores/dataCube/core/DataCubeQueryEngine.ts +46 -21
  282. package/src/stores/dataCube/core/DataCubeQuerySnapshot.ts +8 -12
  283. package/src/stores/dataCube/core/DataCubeQuerySnapshotBuilder.ts +25 -194
  284. package/src/stores/dataCube/core/DataCubeQuerySnapshotBuilderUtils.ts +211 -0
  285. package/src/stores/dataCube/core/DataCubeQuerySnapshotManager.ts +50 -1
  286. package/src/stores/dataCube/core/{DataCubeCoreState.ts → DataCubeStaticContentDisplayState.ts} +2 -6
  287. package/src/stores/dataCube/core/filter/DataCubeQueryFilterEditorState.ts +229 -0
  288. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation.ts +105 -0
  289. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Contain.tsx +87 -0
  290. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx +93 -0
  291. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWith.tsx +87 -0
  292. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx +93 -0
  293. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__Equal.tsx +159 -0
  294. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx +93 -0
  295. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx +93 -0
  296. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx +89 -0
  297. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx +87 -0
  298. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx +89 -0
  299. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx +87 -0
  300. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx +89 -0
  301. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx +83 -0
  302. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__IsNull.tsx +80 -0
  303. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThan.tsx +87 -0
  304. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx +89 -0
  305. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx +87 -0
  306. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx +89 -0
  307. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotContain.tsx +90 -0
  308. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx +90 -0
  309. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx +90 -0
  310. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx +96 -0
  311. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx +96 -0
  312. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx +92 -0
  313. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx +90 -0
  314. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWith.tsx +87 -0
  315. package/src/stores/dataCube/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx +93 -0
  316. package/src/stores/dataCube/editor/DataCubeEditorColumnPropertiesPanelState.ts +2 -2
  317. package/src/stores/dataCube/editor/DataCubeEditorFilterPanelState.ts +295 -0
  318. package/src/stores/dataCube/editor/DataCubeEditorSortsPanelState.ts +5 -9
  319. package/src/stores/dataCube/editor/DataCubeEditorState.tsx +9 -8
  320. package/src/stores/dataCube/editor/DataCubeMutableConfiguration.ts +10 -10
  321. package/src/stores/dataCube/grid/DataCubeGridClientEngine.ts +22 -23
  322. package/src/stores/dataCube/grid/DataCubeGridClientExportEngine.ts +1 -1
  323. package/src/stores/dataCube/grid/DataCubeGridConfigurationBuilder.tsx +22 -47
  324. package/src/stores/dataCube/grid/DataCubeGridControllerState.ts +91 -10
  325. package/src/stores/dataCube/grid/DataCubeGridMenuBuilder.tsx +218 -53
  326. package/src/stores/dataCube/grid/DataCubeGridQueryBuilder.ts +66 -61
  327. package/src/stores/dataCube/grid/DataCubeGridQuerySnapshotBuilder.ts +20 -10
  328. package/src/stores/dataCube/grid/DataCubeGridState.ts +10 -6
  329. package/tsconfig.json +33 -2
  330. package/lib/stores/dataCube/core/DataCubeCoreState.d.ts.map +0 -1
  331. package/lib/stores/dataCube/core/DataCubeCoreState.js.map +0 -1
  332. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.d.ts +0 -30
  333. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.d.ts.map +0 -1
  334. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.js +0 -41
  335. package/lib/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.js.map +0 -1
  336. package/src/stores/dataCube/core/DataCubeQuerySnapshotSubscriber.ts +0 -62
@@ -14,30 +14,873 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { DataCubeIcon } from '@finos/legend-art';
17
+ import {
18
+ BasePopover,
19
+ cn,
20
+ DataCubeIcon,
21
+ DateCalendar,
22
+ DatePicker,
23
+ DatePickerField,
24
+ useDropdownMenu,
25
+ useForkRef,
26
+ } from '@finos/legend-art';
18
27
  import { observer } from 'mobx-react-lite';
19
- import { useREPLStore } from '../../REPLStoreProvider.js';
20
- import { useEffect } from 'react';
21
- import { FormBadge_WIP } from '../../repl/Form.js';
28
+ import {
29
+ DataCubeOperationAdvancedValueType,
30
+ DataCubeQueryFilterGroupOperator,
31
+ getDataType,
32
+ type DataCubeOperationValue,
33
+ } from '../../../stores/dataCube/core/DataCubeQueryEngine.js';
34
+ import {
35
+ DataCubeFilterEditorConditionGroupTreeNode,
36
+ DataCubeFilterEditorConditionTreeNode,
37
+ type DataCubeFilterEditorTreeNode,
38
+ } from '../../../stores/dataCube/core/filter/DataCubeQueryFilterEditorState.js';
39
+ import {
40
+ FormDropdownMenu,
41
+ FormDropdownMenuItem,
42
+ FormDropdownMenuTrigger,
43
+ } from '../../repl/Form.js';
44
+ import type { DataCubeState } from '../../../stores/dataCube/DataCubeState.js';
45
+ import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
46
+ import { DATE_FORMAT, PRIMITIVE_TYPE } from '@finos/legend-graph';
47
+ import {
48
+ formatDate,
49
+ getNullableFirstEntry,
50
+ guaranteeIsNumber,
51
+ parseISO,
52
+ } from '@finos/legend-shared';
53
+ import { evaluate } from 'mathjs';
22
54
 
23
- export const DataCubeEditorFilterPanel = observer(() => {
24
- const repl = useREPLStore();
25
- const panel = repl.dataCube.editor.sorts;
55
+ const FILTER_TREE_OFFSET = 10;
56
+ const FILTER_TREE_INDENTATION_SPACE = 36;
57
+ const FILTER_TREE_HORIZONTAL_GUTTER_LINE_PADDING = 8;
58
+ const FILTER_TREE_VERTICAL_GUTTER_LINE_OFFSET = 6;
59
+ const FILTER_TREE_CONTROLLER_OFFSET = 60;
60
+ const FILTER_TREE_GROUP_HIGHLIGHT_PADDING = 2;
26
61
 
27
- useEffect(() => {}, [panel]); // TODO: @akphi - remove this dummy useEffect
62
+ const DataCubeEditorFilterConditionNodeTextValueEditor = observer(
63
+ forwardRef<
64
+ HTMLInputElement,
65
+ {
66
+ value: string;
67
+ updateValue: (value: string) => void;
68
+ }
69
+ >(function DataCubeEditorFilterConditionNodeValueEditor(props, ref) {
70
+ const { value, updateValue } = props;
71
+ const inputRef = useRef<HTMLInputElement>(null);
72
+ const handleRef = useForkRef(inputRef, ref);
28
73
 
29
- return (
30
- <div className="h-full w-full select-none p-2">
31
- <div className="flex h-6">
32
- <div className="flex h-6 items-center text-xl font-medium">
33
- <DataCubeIcon.TableFilter />
34
- </div>
35
- <div className="ml-1 flex h-6 items-center text-xl font-medium">
36
- Filter
37
- <FormBadge_WIP />
74
+ return (
75
+ <input
76
+ ref={handleRef}
77
+ className="h-5 w-full flex-shrink-0 border border-neutral-400 px-1 text-sm disabled:border-neutral-300 disabled:bg-neutral-50 disabled:text-neutral-300"
78
+ value={value}
79
+ onKeyDown={(event) => {
80
+ if (event.code === 'Escape') {
81
+ inputRef.current?.select();
82
+ }
83
+ }}
84
+ onChange={(event) => updateValue(event.target.value)}
85
+ />
86
+ );
87
+ }),
88
+ );
89
+
90
+ const EVLUATION_ERROR_LABEL = '#ERR';
91
+ const DataCubeEditorFilterConditionNodeNumberValueEditor = observer(
92
+ forwardRef<
93
+ HTMLInputElement,
94
+ {
95
+ value: number;
96
+ updateValue: (value: number) => void;
97
+ defaultValue?: number | undefined;
98
+ step?: number | undefined;
99
+ }
100
+ >(function DataCubeEditorFilterConditionNodeValueEditor(props, ref) {
101
+ const { value, updateValue, defaultValue = 0, step = 1 } = props;
102
+ const [inputValue, setInputValue] = useState<string>(value.toString());
103
+ const inputRef = useRef<HTMLInputElement>(null);
104
+ const handleRef = useForkRef(inputRef, ref);
105
+
106
+ const calculateExpression = (): void => {
107
+ const numericValue = Number(inputValue);
108
+ if (inputValue === '') {
109
+ // Explicitly check this case since `Number()` parses empty string as `0`
110
+ setInputValue(defaultValue.toString());
111
+ updateValue(defaultValue);
112
+ } else if (isNaN(numericValue)) {
113
+ if (inputValue === EVLUATION_ERROR_LABEL) {
114
+ setInputValue(value.toString());
115
+ return;
116
+ }
117
+ // If the value is not a number, try to evaluate it as an expression
118
+ try {
119
+ const calculatedValue = guaranteeIsNumber(evaluate(inputValue));
120
+ setInputValue(calculatedValue.toString());
121
+ updateValue(calculatedValue);
122
+ } catch {
123
+ setInputValue(EVLUATION_ERROR_LABEL);
124
+ updateValue(defaultValue);
125
+ }
126
+ }
127
+ };
128
+
129
+ useEffect(() => {
130
+ setInputValue(value.toString());
131
+ }, [value]);
132
+
133
+ return (
134
+ <div className="relative h-5 w-full flex-shrink-0">
135
+ <input
136
+ ref={handleRef}
137
+ inputMode="numeric"
138
+ spellCheck={false}
139
+ type="text" // NOTE: we leave this as text so that we can support expression evaluation
140
+ className="h-full w-full border border-neutral-400 px-1 pr-5 text-sm disabled:border-neutral-300 disabled:bg-neutral-50 disabled:text-neutral-300"
141
+ value={inputValue}
142
+ onKeyDown={(event) => {
143
+ if (event.code === 'Enter') {
144
+ calculateExpression();
145
+ inputRef.current?.focus();
146
+ } else if (event.code === 'Escape') {
147
+ inputRef.current?.select();
148
+ } else if (event.code === 'ArrowUp') {
149
+ event.preventDefault();
150
+ const newValue = value + step;
151
+ setInputValue(newValue.toString());
152
+ updateValue(newValue);
153
+ } else if (event.code === 'ArrowDown') {
154
+ event.preventDefault();
155
+ const newValue = value - step;
156
+ setInputValue(newValue.toString());
157
+ updateValue(newValue);
158
+ }
159
+ }}
160
+ onChange={(event) => {
161
+ const newInputValue = event.target.value;
162
+ setInputValue(newInputValue);
163
+ const numericValue = Number(newInputValue);
164
+ if (
165
+ isNaN(numericValue) ||
166
+ !newInputValue // Explicitly check this case since `Number()` parses empty string as `0`
167
+ ) {
168
+ return;
169
+ }
170
+ updateValue(numericValue);
171
+ }}
172
+ onBlur={() => calculateExpression()}
173
+ />
174
+ <div className="absolute right-0 top-0 flex h-5 w-5 items-center justify-center">
175
+ <button
176
+ className="text-lg text-neutral-500 hover:text-neutral-600"
177
+ title="Evaluate Expression (Enter)"
178
+ onClick={calculateExpression}
179
+ tabIndex={-1}
180
+ >
181
+ <DataCubeIcon.Calculate />
182
+ </button>
38
183
  </div>
39
184
  </div>
40
- <div className="flex h-[calc(100%_-_24px)] w-full"></div>
185
+ );
186
+ }),
187
+ );
188
+
189
+ // NOTE: this has to be declared here instead of defined inline in slot configuration of DatePicker
190
+ // else, with each re-render, a new function will be created and the ref might be lost
191
+ const CustomDateFieldPicker = forwardRef<HTMLInputElement>(
192
+ function CustomDateFieldPicker(p, r) {
193
+ return (
194
+ <DatePickerField
195
+ {...p}
196
+ ref={r}
197
+ className="h-5 w-full flex-shrink-0 border border-neutral-400 px-1 pr-5 text-sm disabled:border-neutral-300 disabled:bg-neutral-50 disabled:text-neutral-300"
198
+ />
199
+ );
200
+ },
201
+ );
202
+
203
+ const CustomDateFieldPickerOpenCalendarButton = observer(
204
+ (props: { value: string; updateValue: (value: string) => void }) => {
205
+ const { value, updateValue } = props;
206
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
207
+
208
+ return (
209
+ <>
210
+ <button
211
+ className="absolute right-0 top-0 flex h-5 w-5 items-center justify-center"
212
+ title="Open Date Picker..."
213
+ onClick={(event) => {
214
+ setAnchorEl(event.currentTarget);
215
+ }}
216
+ tabIndex={-1}
217
+ >
218
+ <DataCubeIcon.Calendar className="text-lg text-neutral-500 hover:text-neutral-600" />
219
+ </button>
220
+ <BasePopover
221
+ open={Boolean(anchorEl)}
222
+ anchorEl={anchorEl}
223
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
224
+ transformOrigin={{ vertical: 'top', horizontal: 'center' }}
225
+ onClose={() => setAnchorEl(null)}
226
+ classes={{
227
+ root: 'data-cube-editor-date-calendar mt-0.5',
228
+ paper: 'shadow-md rounded-none border border-neutral-300',
229
+ }}
230
+ >
231
+ <DateCalendar
232
+ autoFocus={true}
233
+ value={parseISO(value)}
234
+ onChange={(newValue: Date) => {
235
+ updateValue(formatDate(newValue, DATE_FORMAT));
236
+ setAnchorEl(null);
237
+ }}
238
+ />
239
+ </BasePopover>
240
+ </>
241
+ );
242
+ },
243
+ );
244
+
245
+ const DataCubeEditorFilterConditionNodeDateValueEditor = observer(
246
+ forwardRef<
247
+ HTMLInputElement,
248
+ {
249
+ value: string;
250
+ updateValue: (value: string) => void;
251
+ }
252
+ >(function DataCubeEditorFilterConditionNodeValueEditor(props, ref) {
253
+ const { value, updateValue } = props;
254
+
255
+ return (
256
+ <DatePicker
257
+ ref={ref}
258
+ value={parseISO(value)}
259
+ format={DATE_FORMAT}
260
+ slots={{
261
+ field: CustomDateFieldPicker,
262
+ openPickerButton: () => (
263
+ <CustomDateFieldPickerOpenCalendarButton
264
+ value={value}
265
+ updateValue={updateValue}
266
+ />
267
+ ),
268
+ }}
269
+ onChange={(newValue: Date | null) => {
270
+ if (newValue) {
271
+ updateValue(formatDate(newValue, DATE_FORMAT));
272
+ }
273
+ }}
274
+ />
275
+ );
276
+ }),
277
+ );
278
+
279
+ const DataCubeEditorFilterConditionNodeColumnSelector = observer(
280
+ forwardRef<
281
+ HTMLButtonElement,
282
+ {
283
+ value: string;
284
+ updateValue: (value: string) => void;
285
+ dataCube: DataCubeState;
286
+ }
287
+ >(function DataCubeEditorFilterConditionNodeColumnSelector(props, ref) {
288
+ const { value, updateValue, dataCube } = props;
289
+ const panel = dataCube.editor.filter;
290
+ const matchingColumn = panel.columns.find(
291
+ (column) => column.name === value,
292
+ );
293
+ const [
294
+ openColumnsDropdown,
295
+ closeColumnsDropdown,
296
+ columnsDropdownProps,
297
+ columnsDropdownPropsOpen,
298
+ ] = useDropdownMenu();
299
+
300
+ return (
301
+ <>
302
+ <FormDropdownMenuTrigger
303
+ ref={ref}
304
+ className="relative mr-1 w-32"
305
+ onClick={openColumnsDropdown}
306
+ open={columnsDropdownPropsOpen}
307
+ >
308
+ {value}
309
+ </FormDropdownMenuTrigger>
310
+ <FormDropdownMenu className="w-32" {...columnsDropdownProps}>
311
+ {panel.columns
312
+ .filter(
313
+ (column) =>
314
+ matchingColumn &&
315
+ getDataType(matchingColumn.type) === getDataType(column.type),
316
+ )
317
+ .map((column) => (
318
+ <FormDropdownMenuItem
319
+ key={column.name}
320
+ onClick={() => {
321
+ updateValue(column.name);
322
+ closeColumnsDropdown();
323
+ }}
324
+ autoFocus={value === column.name}
325
+ >
326
+ {column.name}
327
+ </FormDropdownMenuItem>
328
+ ))}
329
+ </FormDropdownMenu>
330
+ </>
331
+ );
332
+ }),
333
+ );
334
+
335
+ const DataCubeEditorFilterConditionNodeValueEditor = observer(
336
+ forwardRef<
337
+ HTMLElement,
338
+ {
339
+ value: DataCubeOperationValue;
340
+ updateValue: (value: unknown) => void;
341
+ dataCube: DataCubeState;
342
+ }
343
+ >(function DataCubeEditorFilterConditionNodeValueEditor(props, ref) {
344
+ const { value, updateValue, dataCube } = props;
345
+ // WIP: support collection/column
346
+ switch (value.type) {
347
+ case PRIMITIVE_TYPE.STRING:
348
+ return (
349
+ <DataCubeEditorFilterConditionNodeTextValueEditor
350
+ ref={ref as React.MutableRefObject<HTMLInputElement>}
351
+ value={value.value as string}
352
+ updateValue={(val) => updateValue(val)}
353
+ />
354
+ );
355
+ case PRIMITIVE_TYPE.NUMBER:
356
+ case PRIMITIVE_TYPE.DECIMAL:
357
+ case PRIMITIVE_TYPE.FLOAT:
358
+ case PRIMITIVE_TYPE.INTEGER:
359
+ return (
360
+ <DataCubeEditorFilterConditionNodeNumberValueEditor
361
+ ref={ref as React.MutableRefObject<HTMLInputElement>}
362
+ value={value.value as number}
363
+ updateValue={(val) => updateValue(val)}
364
+ />
365
+ );
366
+ case PRIMITIVE_TYPE.DATE:
367
+ case PRIMITIVE_TYPE.STRICTDATE:
368
+ case PRIMITIVE_TYPE.DATETIME:
369
+ return (
370
+ <DataCubeEditorFilterConditionNodeDateValueEditor
371
+ ref={ref as React.MutableRefObject<HTMLInputElement>}
372
+ value={value.value as string}
373
+ updateValue={(val) => updateValue(val)}
374
+ />
375
+ );
376
+ case DataCubeOperationAdvancedValueType.COLUMN:
377
+ return (
378
+ <DataCubeEditorFilterConditionNodeColumnSelector
379
+ ref={ref as React.MutableRefObject<HTMLButtonElement>}
380
+ value={value.value as string}
381
+ updateValue={(val) => updateValue(val)}
382
+ dataCube={dataCube}
383
+ />
384
+ );
385
+ default:
386
+ return null;
387
+ }
388
+ }),
389
+ );
390
+
391
+ function DataCubeEditorFilterNotLabel() {
392
+ return (
393
+ <div className="relative flex pl-2.5">
394
+ <div className="pointer-events-none absolute -left-2 h-0 w-0 border-[9px] border-neutral-600 border-b-transparent border-l-transparent border-t-transparent" />
395
+ <div
396
+ className="mr-1 flex h-[18px] w-10 flex-shrink-0 items-center bg-neutral-600 pl-2 text-sm font-medium text-white"
397
+ title="Filter is inverted: select all but what matches."
398
+ >
399
+ NOT
400
+ </div>
41
401
  </div>
42
402
  );
43
- });
403
+ }
404
+
405
+ const DataCubeEditorFilterConditionNodeController = observer(
406
+ (props: {
407
+ className?: string | undefined;
408
+ node: DataCubeFilterEditorTreeNode;
409
+ dataCube: DataCubeState;
410
+ }) => {
411
+ const { className, node, dataCube } = props;
412
+ const panel = dataCube.editor.filter;
413
+
414
+ return (
415
+ <div
416
+ className={cn(
417
+ 'flex h-3.5 w-14 flex-shrink-0 bg-neutral-100',
418
+ className,
419
+ )}
420
+ >
421
+ <button
422
+ className="flex h-3.5 w-3.5 items-center justify-center rounded-bl-sm rounded-tl-sm border border-neutral-400 hover:bg-neutral-200"
423
+ onClick={() => panel.addFilterNode(node)}
424
+ title="Insert a new column filter, just after this filter."
425
+ >
426
+ <DataCubeIcon.FilterAddOperator className="stroke-[2.5] text-sm" />
427
+ </button>
428
+ <button
429
+ className="flex h-3.5 w-3.5 items-center justify-center border border-l-0 border-neutral-400 hover:bg-neutral-200"
430
+ onClick={() => panel.removeFilterNode(node)}
431
+ title="Remove this filter"
432
+ >
433
+ <DataCubeIcon.FilterRemoveOperator className="stroke-[2.5] text-sm" />
434
+ </button>
435
+ <button
436
+ className="flex h-3.5 w-3.5 items-center justify-center border border-l-0 border-neutral-400 hover:bg-neutral-200"
437
+ onClick={() => panel.layerFilterNode(node)}
438
+ title="Put this filter in its own sub-group (and combine it with other filters)."
439
+ >
440
+ <DataCubeIcon.FilterGroupOperator className="stroke-[2.5] text-sm" />
441
+ </button>
442
+ <button
443
+ className={cn(
444
+ 'flex h-3.5 w-3.5 items-center justify-center rounded-br-sm rounded-tr-sm border border-l-0 border-neutral-400 hover:bg-neutral-200',
445
+ {
446
+ 'bg-neutral-600': node.not,
447
+ 'border-neutral-600': node.not,
448
+ 'text-white': node.not,
449
+ 'hover:bg-neutral-600': node.not,
450
+ },
451
+ )}
452
+ onClick={() => node.setNot(!node.not)}
453
+ title={
454
+ node.not
455
+ ? 'Turn off the NOT operator on this filter to select only what matches.'
456
+ : 'Turn on the NOT operator on this filter to select all but what matches.'
457
+ }
458
+ >
459
+ <DataCubeIcon.FilterNotOperator className="stroke-[3] text-xs" />
460
+ </button>
461
+ </div>
462
+ );
463
+ },
464
+ );
465
+
466
+ const DataCubeEditorFilterConditionNodeDisplay = observer(
467
+ (props: {
468
+ node: DataCubeFilterEditorConditionTreeNode;
469
+ level: number;
470
+ dataCube: DataCubeState;
471
+ }) => {
472
+ const { node, level, dataCube } = props;
473
+ const panel = dataCube.editor.filter;
474
+ const parentNode = node.parent;
475
+ const nodeIdx = parentNode ? parentNode.children.indexOf(node) : undefined;
476
+ const valueEditorRef = useRef<HTMLElement>(null);
477
+ const [
478
+ openColumnsDropdown,
479
+ closeColumnsDropdown,
480
+ columnsDropdownProps,
481
+ columnsDropdownPropsOpen,
482
+ ] = useDropdownMenu();
483
+ const [
484
+ openOperatorsDropdown,
485
+ closeOperatorsDropdown,
486
+ operatorsDropdownProps,
487
+ operatorsDropdownPropsOpen,
488
+ ] = useDropdownMenu();
489
+ const focusOnValueEditor = useCallback(
490
+ () => valueEditorRef.current?.focus(),
491
+ [],
492
+ );
493
+
494
+ return (
495
+ <div className="group flex h-6 items-center">
496
+ <div
497
+ className={cn(
498
+ 'z-1 absolute h-6 w-full bg-opacity-50 group-hover:bg-sky-100 group-hover:bg-opacity-50',
499
+ {
500
+ 'bg-sky-50': node === panel.selectedNode,
501
+ 'border-[0.5px] border-l-2 border-sky-200 border-l-sky-600':
502
+ node === panel.selectedNode,
503
+ },
504
+ )}
505
+ onClick={() => panel.setSelectedNode(node)}
506
+ />
507
+ <div
508
+ style={{
509
+ paddingLeft: `${level * FILTER_TREE_INDENTATION_SPACE + FILTER_TREE_OFFSET + (level - 1) * FILTER_TREE_CONTROLLER_OFFSET}px`,
510
+ }}
511
+ className="relative h-6 flex-shrink-0"
512
+ onClick={() => panel.setSelectedNode(node)}
513
+ >
514
+ {parentNode && (
515
+ <div
516
+ className="absolute top-0 flex h-6 items-center justify-end"
517
+ style={{
518
+ width: `${FILTER_TREE_INDENTATION_SPACE - FILTER_TREE_HORIZONTAL_GUTTER_LINE_PADDING - FILTER_TREE_VERTICAL_GUTTER_LINE_OFFSET}px`,
519
+ right: `${FILTER_TREE_HORIZONTAL_GUTTER_LINE_PADDING}px`,
520
+ }}
521
+ >
522
+ <div
523
+ className={cn('h-[1px] w-full flex-1 bg-neutral-200', {
524
+ 'bg-sky-600': parentNode === panel.selectedGroupNode,
525
+ })}
526
+ />
527
+ {nodeIdx !== undefined && nodeIdx > 0 && (
528
+ <div
529
+ className={cn(
530
+ 'flex h-6 items-center justify-center pl-1 text-xs text-neutral-600',
531
+ {
532
+ 'text-sky-600': parentNode === panel.selectedGroupNode,
533
+ },
534
+ )}
535
+ >
536
+ {parentNode.operation === DataCubeQueryFilterGroupOperator.AND
537
+ ? 'and'
538
+ : 'or'}
539
+ </div>
540
+ )}
541
+ </div>
542
+ )}
543
+ </div>
544
+ <DataCubeEditorFilterConditionNodeController
545
+ className="relative mr-1"
546
+ node={node}
547
+ dataCube={dataCube}
548
+ />
549
+ {node.not && <DataCubeEditorFilterNotLabel />}
550
+ <FormDropdownMenuTrigger
551
+ className="relative mr-1 w-32"
552
+ onClick={openColumnsDropdown}
553
+ open={columnsDropdownPropsOpen}
554
+ >
555
+ {node.column.name}
556
+ </FormDropdownMenuTrigger>
557
+ <FormDropdownMenu
558
+ className="w-32"
559
+ {...columnsDropdownProps}
560
+ onClosed={focusOnValueEditor}
561
+ >
562
+ {panel.columns.map((column) => (
563
+ <FormDropdownMenuItem
564
+ key={column.name}
565
+ onClick={() => {
566
+ if (column !== node.column) {
567
+ const newOp = node.operation.isCompatibleWithColumn(column)
568
+ ? node.operation
569
+ : getNullableFirstEntry(
570
+ panel.dataCube.engine.filterOperations.filter((op) =>
571
+ op.isCompatibleWithColumn(column),
572
+ ),
573
+ );
574
+ if (newOp) {
575
+ node.setColumn(column);
576
+ node.setOperation(newOp);
577
+ node.setValue(newOp.generateDefaultValue(column));
578
+ }
579
+ }
580
+ closeColumnsDropdown();
581
+ }}
582
+ autoFocus={node.column.name === column.name}
583
+ >
584
+ {column.name}
585
+ </FormDropdownMenuItem>
586
+ ))}
587
+ </FormDropdownMenu>
588
+ <FormDropdownMenuTrigger
589
+ className="relative mr-1 w-24"
590
+ onClick={openOperatorsDropdown}
591
+ open={operatorsDropdownPropsOpen}
592
+ >
593
+ {node.operation.label}
594
+ </FormDropdownMenuTrigger>
595
+ <FormDropdownMenu
596
+ className="w-24"
597
+ {...operatorsDropdownProps}
598
+ onClosed={focusOnValueEditor}
599
+ >
600
+ {panel.dataCube.engine.filterOperations
601
+ .filter((op) => op.isCompatibleWithColumn(node.column))
602
+ .map((op) => (
603
+ <FormDropdownMenuItem
604
+ key={op.operator}
605
+ onClick={() => {
606
+ if (op !== node.operation) {
607
+ if (op.isCompatibleWithColumn(node.column)) {
608
+ node.setOperation(op);
609
+ node.setValue(op.generateDefaultValue(node.column));
610
+ }
611
+ }
612
+ closeOperatorsDropdown();
613
+ }}
614
+ autoFocus={node.operation.operator === op.operator}
615
+ >
616
+ {op.label}
617
+ </FormDropdownMenuItem>
618
+ ))}
619
+ </FormDropdownMenu>
620
+ <div className="relative w-32 flex-shrink-0">
621
+ {node.value && (
622
+ <DataCubeEditorFilterConditionNodeValueEditor
623
+ ref={valueEditorRef}
624
+ value={node.value}
625
+ updateValue={(val) => node.updateValue(val)}
626
+ dataCube={dataCube}
627
+ />
628
+ )}
629
+ </div>
630
+ </div>
631
+ );
632
+ },
633
+ );
634
+
635
+ const DataCubeEditorFilterGroupNodeDisplay = observer(
636
+ (props: {
637
+ node: DataCubeFilterEditorConditionGroupTreeNode;
638
+ level: number;
639
+ dataCube: DataCubeState;
640
+ }) => {
641
+ const { node, level, dataCube } = props;
642
+ const panel = dataCube.editor.filter;
643
+ const parentNode = node.parent;
644
+ const nodeIdx = parentNode ? parentNode.children.indexOf(node) : undefined;
645
+ const [
646
+ openOperatorsDropdown,
647
+ closeOperatorsDropdown,
648
+ operatorsDropdownProps,
649
+ operatorsDropdownPropsOpen,
650
+ ] = useDropdownMenu();
651
+
652
+ return (
653
+ <div className="group flex h-6 items-center">
654
+ <div
655
+ className={cn(
656
+ 'z-1 absolute h-6 w-full bg-opacity-50 group-hover:bg-sky-100 group-hover:bg-opacity-50',
657
+ {
658
+ 'bg-sky-50': node === panel.selectedNode,
659
+ 'border-[0.5px] border-l-2 border-sky-200 border-l-sky-600':
660
+ node === panel.selectedNode,
661
+ },
662
+ )}
663
+ onClick={() => panel.setSelectedNode(node)}
664
+ />
665
+ <div
666
+ style={{
667
+ paddingLeft: `${level * FILTER_TREE_INDENTATION_SPACE + FILTER_TREE_OFFSET + (level !== 0 ? (level - 1) * FILTER_TREE_CONTROLLER_OFFSET : 0)}px`,
668
+ }}
669
+ className="relative h-6 flex-shrink-0"
670
+ onClick={() => panel.setSelectedNode(node)}
671
+ >
672
+ {level !== 0 && parentNode && (
673
+ <div
674
+ className="absolute top-0 flex h-6 items-center justify-end"
675
+ style={{
676
+ width: `${FILTER_TREE_INDENTATION_SPACE - FILTER_TREE_HORIZONTAL_GUTTER_LINE_PADDING - FILTER_TREE_VERTICAL_GUTTER_LINE_OFFSET}px`,
677
+ right: `${FILTER_TREE_HORIZONTAL_GUTTER_LINE_PADDING}px`,
678
+ }}
679
+ >
680
+ <div
681
+ className={cn('h-[1px] w-full flex-1 bg-neutral-200', {
682
+ 'bg-sky-600': parentNode === panel.selectedGroupNode,
683
+ })}
684
+ />
685
+ {nodeIdx !== undefined && nodeIdx > 0 && (
686
+ <div
687
+ className={cn(
688
+ 'flex h-6 items-center justify-center pl-1 text-xs text-neutral-600',
689
+ {
690
+ 'text-sky-600': parentNode === panel.selectedGroupNode,
691
+ },
692
+ )}
693
+ >
694
+ {parentNode.operation === DataCubeQueryFilterGroupOperator.AND
695
+ ? 'and'
696
+ : 'or'}
697
+ </div>
698
+ )}
699
+ </div>
700
+ )}
701
+ </div>
702
+ {level !== 0 && (
703
+ <>
704
+ <DataCubeEditorFilterConditionNodeController
705
+ className="relative mr-1"
706
+ node={node}
707
+ dataCube={dataCube}
708
+ />
709
+ {node.not && <DataCubeEditorFilterNotLabel />}
710
+ </>
711
+ )}
712
+ <FormDropdownMenuTrigger
713
+ className="relative w-14"
714
+ onClick={openOperatorsDropdown}
715
+ open={operatorsDropdownPropsOpen}
716
+ >
717
+ {node.operation === DataCubeQueryFilterGroupOperator.AND
718
+ ? 'All of'
719
+ : 'Any of'}
720
+ </FormDropdownMenuTrigger>
721
+ <FormDropdownMenu className="w-14" {...operatorsDropdownProps}>
722
+ <FormDropdownMenuItem
723
+ onClick={() => {
724
+ node.setOperation(DataCubeQueryFilterGroupOperator.AND);
725
+ closeOperatorsDropdown();
726
+ }}
727
+ autoFocus={node.operation === DataCubeQueryFilterGroupOperator.AND}
728
+ >
729
+ All of
730
+ </FormDropdownMenuItem>
731
+ <FormDropdownMenuItem
732
+ onClick={() => {
733
+ node.setOperation(DataCubeQueryFilterGroupOperator.OR);
734
+ closeOperatorsDropdown();
735
+ }}
736
+ autoFocus={node.operation === DataCubeQueryFilterGroupOperator.OR}
737
+ >
738
+ Any of
739
+ </FormDropdownMenuItem>
740
+ </FormDropdownMenu>
741
+ </div>
742
+ );
743
+ },
744
+ );
745
+
746
+ // NOTE: This particular rendering of the filter tree leans on tree data structure used to organize the nodes
747
+ // and thus, though simpler to implement, makes it harder to implement certain features which favors flat
748
+ // structure like list, such as drag and drop, multi-select, etc.
749
+ // If those needs come up we could shift the implementation or look out for a library that already works well
750
+ // out of the box such as:
751
+ // See https://mui.com/x/react-tree-view/
752
+ // See https://github.com/lukasbach/react-complex-tree
753
+ const DataCubeEditorFilterGroupDisplay = observer(
754
+ (props: {
755
+ node: DataCubeFilterEditorConditionGroupTreeNode;
756
+ level: number;
757
+ dataCube: DataCubeState;
758
+ }) => {
759
+ const { node, level, dataCube } = props;
760
+ const panel = dataCube.editor.filter;
761
+
762
+ return (
763
+ <div className="relative w-full">
764
+ <div
765
+ className={cn('pointer-events-none absolute h-full', {
766
+ 'border-[0.5px] border-sky-200 bg-sky-50':
767
+ node === panel.selectedGroupNode,
768
+ })}
769
+ style={{
770
+ marginLeft: `${level * FILTER_TREE_INDENTATION_SPACE + FILTER_TREE_OFFSET + level * FILTER_TREE_CONTROLLER_OFFSET - FILTER_TREE_GROUP_HIGHLIGHT_PADDING}px`,
771
+ width: `calc(100% - ${level * FILTER_TREE_INDENTATION_SPACE + FILTER_TREE_OFFSET + level * FILTER_TREE_CONTROLLER_OFFSET - 2 * FILTER_TREE_GROUP_HIGHLIGHT_PADDING}px)`,
772
+ }}
773
+ />
774
+ <DataCubeEditorFilterGroupNodeDisplay
775
+ node={node}
776
+ level={level}
777
+ dataCube={dataCube}
778
+ />
779
+ <div className="relative">
780
+ <div
781
+ className={cn(
782
+ 'pointer-events-none absolute z-10 h-[calc(100%_-_12px)] w-0 border-l border-neutral-200',
783
+ {
784
+ 'border-sky-600': node === panel.selectedGroupNode,
785
+ },
786
+ )}
787
+ style={{
788
+ marginLeft: `${level * FILTER_TREE_INDENTATION_SPACE + FILTER_TREE_OFFSET + FILTER_TREE_VERTICAL_GUTTER_LINE_OFFSET + level * FILTER_TREE_CONTROLLER_OFFSET}px`,
789
+ }}
790
+ />
791
+ {node.children.map((childNode) => {
792
+ if (childNode instanceof DataCubeFilterEditorConditionTreeNode) {
793
+ return (
794
+ <DataCubeEditorFilterConditionNodeDisplay
795
+ key={childNode.uuid}
796
+ level={level + 1}
797
+ node={childNode}
798
+ dataCube={dataCube}
799
+ />
800
+ );
801
+ } else if (
802
+ childNode instanceof DataCubeFilterEditorConditionGroupTreeNode
803
+ ) {
804
+ return (
805
+ <DataCubeEditorFilterGroupDisplay
806
+ key={childNode.uuid}
807
+ level={level + 1}
808
+ node={childNode}
809
+ dataCube={dataCube}
810
+ />
811
+ );
812
+ }
813
+ return null;
814
+ })}
815
+ </div>
816
+ </div>
817
+ );
818
+ },
819
+ );
820
+
821
+ export const DataCubeEditorFilterPanel = observer(
822
+ (props: { dataCube: DataCubeState }) => {
823
+ const { dataCube } = props;
824
+ const panel = dataCube.editor.filter;
825
+
826
+ useEffect(() => {
827
+ panel.setSelectedNode(undefined);
828
+ }, [panel]);
829
+
830
+ return (
831
+ <div className="h-full w-full select-none p-2">
832
+ <div className="flex h-6">
833
+ <div className="flex h-6 items-center text-xl font-medium">
834
+ <DataCubeIcon.TableFilter />
835
+ </div>
836
+ <div className="ml-1 flex h-6 items-center text-xl font-medium">
837
+ Filter
838
+ </div>
839
+ </div>
840
+ <div className="flex h-[calc(100%_-_24px)] w-full">
841
+ <div className="flex h-full w-full pt-1">
842
+ <div
843
+ className="relative flex h-full w-full overflow-auto rounded-sm border border-neutral-200"
844
+ onClick={() => panel.setSelectedNode(undefined)}
845
+ >
846
+ {!panel.tree.root && (
847
+ <div className="h-full w-full p-3">
848
+ <div>
849
+ No filter is specified. Click the button below to start.
850
+ </div>
851
+ <button
852
+ className="w-30 mt-2 h-6 border border-neutral-400 bg-neutral-300 px-2 hover:brightness-95"
853
+ onClick={() => {
854
+ panel.initializeTree();
855
+ }}
856
+ >
857
+ Create New Filter
858
+ </button>
859
+ </div>
860
+ )}
861
+ {panel.tree.root && (
862
+ <div
863
+ className="flex flex-col py-1"
864
+ // prevent click event of filter tree from propagating to the
865
+ // container which when clicked, will clear node selection
866
+ onClick={(event) => event.stopPropagation()}
867
+ >
868
+ <DataCubeEditorFilterGroupDisplay
869
+ node={panel.tree.root}
870
+ level={0}
871
+ dataCube={dataCube}
872
+ />
873
+ <div
874
+ // add a padding so there will always be a clickable area to clear node selection
875
+ className="min-h-6 w-full flex-1"
876
+ onClick={() => panel.setSelectedNode(undefined)}
877
+ />
878
+ </div>
879
+ )}
880
+ </div>
881
+ </div>
882
+ </div>
883
+ </div>
884
+ );
885
+ },
886
+ );