@mwater/visualization 5.4.1 → 5.4.2

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 (269) hide show
  1. package/lib/ColorComponent.js +2 -1
  2. package/lib/IdSelection.d.ts +16 -0
  3. package/lib/IdSelection.js +59 -0
  4. package/lib/MWaterAddRelatedIndicatorComponent.js +2 -2
  5. package/lib/MWaterCompleteTableSelectComponent.d.ts +3 -8
  6. package/lib/MWaterCompleteTableSelectComponent.js +36 -42
  7. package/lib/MWaterLoaderComponent.d.ts +11 -10
  8. package/lib/MWaterLoaderComponent.js +1 -1
  9. package/lib/MWaterResponsesFilterComponent.js +1 -1
  10. package/lib/MWaterTableSelectComponent.d.ts +0 -1
  11. package/lib/MWaterTableSelectComponent.js +4 -6
  12. package/lib/autotranslate.d.ts +20 -0
  13. package/lib/autotranslate.js +122 -0
  14. package/lib/axes/AxisBuilder.js +3 -3
  15. package/lib/axes/AxisColorEditorComponent.js +4 -0
  16. package/lib/axes/AxisComponent.d.ts +8 -12
  17. package/lib/axes/AxisComponent.js +32 -80
  18. package/lib/axes/CategoryMapComponent.js +4 -4
  19. package/lib/axes/RangesComponent.js +2 -2
  20. package/lib/dashboards/DashboardComponent.d.ts +6 -0
  21. package/lib/dashboards/DashboardComponent.js +44 -12
  22. package/lib/dashboards/DashboardDesign.d.ts +11 -2
  23. package/lib/dashboards/DashboardUtils.d.ts +5 -0
  24. package/lib/dashboards/DashboardUtils.js +30 -0
  25. package/lib/dashboards/DashboardViewComponent.d.ts +2 -0
  26. package/lib/dashboards/DashboardViewComponent.js +16 -3
  27. package/lib/dashboards/ServerDashboardDataSource.js +2 -1
  28. package/lib/dashboards/SettingsModalComponent.d.ts +1 -1
  29. package/lib/dashboards/SettingsModalComponent.js +256 -19
  30. package/lib/dashboards/WidgetComponent.d.ts +6 -3
  31. package/lib/dashboards/WidgetComponent.js +3 -1
  32. package/lib/datagrids/CellEditor.d.ts +19 -0
  33. package/lib/datagrids/CellEditor.js +223 -0
  34. package/lib/datagrids/DatagridComponent.d.ts +18 -87
  35. package/lib/datagrids/DatagridComponent.js +304 -222
  36. package/lib/datagrids/DatagridViewComponent.d.ts +15 -53
  37. package/lib/datagrids/DatagridViewComponent.js +256 -257
  38. package/lib/datagrids/DirectDatagridDataSource.js +2 -3
  39. package/lib/datagrids/ExprCellComponent.d.ts +8 -15
  40. package/lib/datagrids/ExprCellComponent.js +11 -15
  41. package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -6
  42. package/lib/datagrids/FindReplaceModalComponent.js +38 -75
  43. package/lib/index.css +1 -1
  44. package/lib/index.d.ts +0 -1
  45. package/lib/index.js +0 -1
  46. package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
  47. package/lib/mWaterLoader.d.ts +1 -1
  48. package/lib/maps/BufferLayer.d.ts +7 -5
  49. package/lib/maps/BufferLayer.js +69 -48
  50. package/lib/maps/BufferLayerDesign.d.ts +21 -14
  51. package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
  52. package/lib/maps/BufferLayerDesignerComponent.js +68 -102
  53. package/lib/maps/ChoroplethLayer.d.ts +5 -4
  54. package/lib/maps/ChoroplethLayer.js +32 -9
  55. package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
  56. package/lib/maps/ChoroplethLayerDesigner.js +4 -2
  57. package/lib/maps/ClusterLayer.d.ts +3 -4
  58. package/lib/maps/ClusterLayer.js +2 -1
  59. package/lib/maps/DetailLevelSelectComponent.js +1 -1
  60. package/lib/maps/DirectMapDataSource.js +2 -1
  61. package/lib/maps/EditPopupComponent.js +5 -3
  62. package/lib/maps/GridLayer.d.ts +3 -4
  63. package/lib/maps/GridLayer.js +2 -1
  64. package/lib/maps/GridLayerDesigner.js +5 -3
  65. package/lib/maps/HoverContent.d.ts +11 -3
  66. package/lib/maps/HoverContent.js +25 -9
  67. package/lib/maps/Layer.d.ts +24 -3
  68. package/lib/maps/Layer.js +5 -1
  69. package/lib/maps/LayerFactory.js +0 -8
  70. package/lib/maps/LayerLegendComponent.js +0 -1
  71. package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
  72. package/lib/maps/LayerSwitcherComponent.js +1 -1
  73. package/lib/maps/LeafletMapComponent.js +3 -1
  74. package/lib/maps/LegendComponent.d.ts +1 -0
  75. package/lib/maps/LegendComponent.js +9 -1
  76. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  77. package/lib/maps/MWaterServerLayer.js +2 -2
  78. package/lib/maps/MapComponent.js +3 -3
  79. package/lib/maps/MapDesign.d.ts +2 -0
  80. package/lib/maps/MapDesignerComponent.d.ts +4 -3
  81. package/lib/maps/MapDesignerComponent.js +68 -74
  82. package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
  83. package/lib/maps/MapUtils.d.ts +4 -0
  84. package/lib/maps/MapUtils.js +19 -0
  85. package/lib/maps/MapViewComponent.d.ts +8 -3
  86. package/lib/maps/MarkersLayer.d.ts +5 -4
  87. package/lib/maps/MarkersLayer.js +33 -7
  88. package/lib/maps/MarkersLayerDesign.d.ts +19 -16
  89. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
  90. package/lib/maps/PopupFilterJoinsUtils.js +0 -6
  91. package/lib/maps/RasterMapViewComponent.d.ts +3 -31
  92. package/lib/maps/RasterMapViewComponent.js +7 -2
  93. package/lib/maps/ServerMapDataSource.js +2 -1
  94. package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
  95. package/lib/maps/SwitchableTileUrlLayer.js +2 -1
  96. package/lib/maps/TileUrlLayer.d.ts +4 -5
  97. package/lib/maps/TileUrlLayer.js +2 -1
  98. package/lib/maps/VectorMapViewComponent.d.ts +5 -37
  99. package/lib/maps/VectorMapViewComponent.js +19 -8
  100. package/lib/maps/maps.d.ts +3 -0
  101. package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
  102. package/lib/quickfilter/QuickfiltersComponent.js +9 -7
  103. package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +1 -1
  104. package/lib/quickfilter/QuickfiltersDesignComponent.js +19 -35
  105. package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
  106. package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
  107. package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
  108. package/lib/richtext/ExprItemsTranslator.js +149 -0
  109. package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
  110. package/lib/richtext/ItemsHtmlConverter.js +31 -15
  111. package/lib/wellknown.js +12 -9
  112. package/lib/widgets/IFrameWidget.d.ts +4 -4
  113. package/lib/widgets/ImageWidget.d.ts +7 -4
  114. package/lib/widgets/ImageWidget.js +9 -1
  115. package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
  116. package/lib/widgets/ImageWidgetComponent.js +1 -1
  117. package/lib/widgets/MapWidget.d.ts +5 -48
  118. package/lib/widgets/MapWidget.js +26 -63
  119. package/lib/widgets/MarkdownWidget.d.ts +3 -0
  120. package/lib/widgets/MarkdownWidget.js +3 -0
  121. package/lib/widgets/TOCWidget.d.ts +15 -27
  122. package/lib/widgets/TOCWidget.js +107 -183
  123. package/lib/widgets/Widget.d.ts +18 -7
  124. package/lib/widgets/Widget.js +4 -0
  125. package/lib/widgets/WidgetScopesViewComponent.js +1 -1
  126. package/lib/widgets/charts/Chart.d.ts +10 -1
  127. package/lib/widgets/charts/Chart.js +22 -11
  128. package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
  129. package/lib/widgets/charts/ChartViewComponent.js +6 -3
  130. package/lib/widgets/charts/ChartWidget.d.ts +2 -0
  131. package/lib/widgets/charts/ChartWidget.js +9 -1
  132. package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
  133. package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
  134. package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
  135. package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
  136. package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
  137. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
  138. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
  139. package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
  140. package/lib/widgets/charts/layered/LayeredChart.js +63 -3
  141. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
  142. package/lib/widgets/charts/layered/LayeredChartCompiler.js +1 -1
  143. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
  144. package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
  145. package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
  146. package/lib/widgets/charts/pivot/PivotChart.js +63 -0
  147. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
  148. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
  149. package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
  150. package/lib/widgets/charts/table/TableChart.d.ts +1 -0
  151. package/lib/widgets/charts/table/TableChart.js +15 -0
  152. package/lib/widgets/text/TextComponent.d.ts +11 -4
  153. package/lib/widgets/text/TextComponent.js +11 -8
  154. package/lib/widgets/text/TextWidget.d.ts +6 -3
  155. package/lib/widgets/text/TextWidget.js +7 -1
  156. package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
  157. package/lib/widgets/text/TextWidgetComponent.js +7 -1
  158. package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
  159. package/lib/widgets/text/TextWidgetDesign.js +1 -1
  160. package/package.json +7 -8
  161. package/src/ColorComponent.tsx +1 -2
  162. package/src/IdSelection.ts +62 -0
  163. package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
  164. package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
  165. package/src/MWaterLoaderComponent.ts +28 -26
  166. package/src/MWaterResponsesFilterComponent.ts +5 -2
  167. package/src/MWaterTableSelectComponent.tsx +5 -9
  168. package/src/autotranslate.ts +141 -0
  169. package/src/axes/AxisBuilder.ts +3 -3
  170. package/src/axes/AxisColorEditorComponent.tsx +5 -0
  171. package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
  172. package/src/axes/CategoryMapComponent.ts +4 -4
  173. package/src/axes/RangesComponent.ts +3 -2
  174. package/src/dashboards/DashboardComponent.tsx +79 -14
  175. package/src/dashboards/DashboardDesign.ts +9 -2
  176. package/src/dashboards/DashboardUtils.ts +39 -0
  177. package/src/dashboards/DashboardViewComponent.tsx +22 -3
  178. package/src/dashboards/ServerDashboardDataSource.ts +2 -1
  179. package/src/dashboards/SettingsModalComponent.tsx +450 -35
  180. package/src/dashboards/WidgetComponent.tsx +12 -6
  181. package/src/datagrids/CellEditor.tsx +354 -0
  182. package/src/datagrids/DatagridComponent.tsx +646 -0
  183. package/src/datagrids/DatagridViewComponent.tsx +539 -0
  184. package/src/datagrids/DirectDatagridDataSource.ts +2 -3
  185. package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
  186. package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
  187. package/src/index.css +1 -1
  188. package/src/index.ts +0 -1
  189. package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
  190. package/src/mWaterLoader.ts +1 -1
  191. package/src/maps/BufferLayer.ts +83 -60
  192. package/src/maps/BufferLayerDesign.ts +20 -14
  193. package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
  194. package/src/maps/ChoroplethLayer.ts +40 -19
  195. package/src/maps/ChoroplethLayerDesign.ts +4 -2
  196. package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
  197. package/src/maps/ClusterLayer.ts +4 -10
  198. package/src/maps/DetailLevelSelectComponent.ts +1 -1
  199. package/src/maps/DirectMapDataSource.ts +2 -1
  200. package/src/maps/EditPopupComponent.ts +7 -3
  201. package/src/maps/GridLayer.ts +4 -10
  202. package/src/maps/GridLayerDesigner.tsx +5 -3
  203. package/src/maps/HoverContent.tsx +40 -16
  204. package/src/maps/Layer.ts +28 -10
  205. package/src/maps/LayerFactory.ts +0 -8
  206. package/src/maps/LayerLegendComponent.ts +2 -4
  207. package/src/maps/LayerSwitcherComponent.tsx +6 -2
  208. package/src/maps/LeafletMapComponent.tsx +3 -1
  209. package/src/maps/LegendComponent.tsx +10 -1
  210. package/src/maps/MWaterServerLayer.ts +3 -3
  211. package/src/maps/MapComponent.ts +3 -3
  212. package/src/maps/MapDesign.ts +3 -0
  213. package/src/maps/MapDesignerComponent.tsx +165 -162
  214. package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
  215. package/src/maps/MapUtils.ts +24 -0
  216. package/src/maps/MapViewComponent.tsx +11 -3
  217. package/src/maps/MarkersLayer.ts +44 -18
  218. package/src/maps/MarkersLayerDesign.ts +19 -16
  219. package/src/maps/PopupFilterJoinsUtils.ts +6 -2
  220. package/src/maps/RasterMapViewComponent.ts +9 -45
  221. package/src/maps/ServerMapDataSource.ts +2 -2
  222. package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
  223. package/src/maps/TileUrlLayer.tsx +4 -10
  224. package/src/maps/VectorMapViewComponent.tsx +28 -55
  225. package/src/maps/maps.ts +3 -0
  226. package/src/quickfilter/QuickfiltersComponent.ts +13 -7
  227. package/src/quickfilter/QuickfiltersDesignComponent.tsx +56 -74
  228. package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
  229. package/src/richtext/ExprItemsTranslator.ts +176 -0
  230. package/src/richtext/ItemsHtmlConverter.ts +33 -18
  231. package/src/wellknown.ts +33 -30
  232. package/src/widgets/ImageWidget.ts +10 -1
  233. package/src/widgets/ImageWidgetComponent.ts +3 -2
  234. package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
  235. package/src/widgets/MarkdownWidget.ts +3 -0
  236. package/src/widgets/TOCWidget.tsx +281 -0
  237. package/src/widgets/Widget.ts +25 -5
  238. package/src/widgets/WidgetScopesViewComponent.ts +2 -1
  239. package/src/widgets/charts/Chart.ts +31 -12
  240. package/src/widgets/charts/ChartViewComponent.ts +13 -3
  241. package/src/widgets/charts/ChartWidget.ts +11 -1
  242. package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
  243. package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
  244. package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
  245. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
  246. package/src/widgets/charts/layered/LayeredChart.ts +71 -3
  247. package/src/widgets/charts/layered/LayeredChartCompiler.ts +2 -2
  248. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
  249. package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
  250. package/src/widgets/charts/pivot/PivotChart.ts +73 -0
  251. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
  252. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
  253. package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
  254. package/src/widgets/charts/table/TableChart.ts +17 -0
  255. package/src/widgets/text/TextComponent.tsx +22 -12
  256. package/src/widgets/text/TextWidget.ts +9 -2
  257. package/src/widgets/text/TextWidgetComponent.tsx +16 -1
  258. package/src/widgets/text/TextWidgetDesign.ts +4 -7
  259. package/test/IdSelectionTests.ts +54 -0
  260. package/test/LayeredChartCompilerTests.ts +0 -2
  261. package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
  262. package/test/wellknownTests.ts +144 -0
  263. package/src/datagrids/DatagridComponent.ts +0 -478
  264. package/src/datagrids/DatagridViewComponent.ts +0 -464
  265. package/src/datagrids/EditExprCellComponent.tsx +0 -305
  266. package/src/datagrids/README.md +0 -3
  267. package/src/maps/BufferLayerDesignerComponent.ts +0 -311
  268. package/src/widgets/TOCWidget.ts +0 -326
  269. package/test/LegoLayoutEngineTests.ts +0 -69
@@ -1,464 +0,0 @@
1
- import _ from "lodash"
2
- import React from "react"
3
- const R = React.createElement
4
- import { Table, Column, Cell } from "fixed-data-table-2"
5
- import { DataSource, Expr, ExprUtils, Schema } from "@mwater/expressions"
6
- import ExprCellComponent from "./ExprCellComponent"
7
- import EditExprCellComponent from "./EditExprCellComponent"
8
- import DatagridDataSource from "./DatagridDataSource"
9
- import { DatagridDesign, JsonQLFilter } from ".."
10
- import produce from "immer"
11
-
12
- export interface DatagridViewComponentProps {
13
- /** Width of control */
14
- width: number
15
-
16
- /** Height of control */
17
- height: number
18
-
19
- pageSize?: number
20
-
21
- schema: Schema
22
- dataSource: DataSource
23
- datagridDataSource: DatagridDataSource
24
-
25
- design: DatagridDesign
26
- onDesignChange?: (design: DatagridDesign) => void
27
-
28
- filters?: JsonQLFilter[]
29
-
30
- /** Check if a cell is editable by testing if underlying expression is editable */
31
- canEditExpr?: (tableId: string, rowId: any, expr: Expr) => Promise<boolean>
32
-
33
- /** Update cell values by updating set of expressions and values */
34
- updateExprValues?: (tableId: string, rowUpdates: RowUpdate[]) => Promise<void>
35
-
36
- /** Called when row is double-clicked with (tableId, rowId, rowIndex) */
37
- onRowDoubleClick?: (tableId: string, rowId: any, rowIndex: number) => void
38
-
39
- /** Called when a row is clicked with (tableId, rowId, rowIndex) */
40
- onRowClick?: (tableId: string, rowId: any, rowIndex: number) => void
41
-
42
- /** Change to force a refresh */
43
- refreshKey?: any
44
- }
45
-
46
- /** Update to one row expression value */
47
- export interface RowUpdate {
48
- primaryKey: string
49
- expr: Expr
50
- value: any
51
- }
52
-
53
- export interface DatagridViewComponentState {
54
- rows: any[]
55
- entirelyLoaded: boolean
56
-
57
- /** set to { rowIndex: 0, 1, 2, columnIndex: 0, 1, 2..., rowId: id of row } if editing a cell */
58
- editingCell: { rowIndex: number; columnIndex: number; rowId: any } | null
59
-
60
- savingCell: boolean
61
- }
62
-
63
- interface LoadState {
64
- design: DatagridDesign
65
- offset: number
66
- limit: number
67
- filters?: JsonQLFilter[]
68
- }
69
-
70
- /** Datagrid table itself without decorations such as edit button etc.
71
- * See README.md for description of datagrid format
72
- * Design should be cleaned already before being passed in (see DatagridUtils)
73
- */
74
- export default class DatagridViewComponent extends React.Component<
75
- DatagridViewComponentProps,
76
- DatagridViewComponentState
77
- > {
78
- static defaultProps = { pageSize: 100 }
79
-
80
- loadState: LoadState | null
81
- editCellComp: EditExprCellComponent | null
82
-
83
- constructor(props: DatagridViewComponentProps) {
84
- super(props)
85
-
86
- this.state = {
87
- rows: [],
88
- entirelyLoaded: false,
89
- editingCell: null, // set to { rowIndex: 0, 1, 2, columnIndex: 0, 1, 2... } if editing a cell
90
- savingCell: false // True when saving a cell's contents
91
- }
92
- }
93
-
94
- componentWillReceiveProps(nextProps: DatagridViewComponentProps) {
95
- // If design or filters changed, delete all rows
96
- // TODO won't this reload on column resize?
97
- if (!_.isEqual(nextProps.design, this.props.design) || !_.isEqual(nextProps.filters, this.props.filters) || nextProps.refreshKey !== this.props.refreshKey) {
98
- this.setState({ rows: [], entirelyLoaded: false })
99
- }
100
- }
101
-
102
- // Loads more rows because the placeholder last row has been rendered
103
- loadMoreRows() {
104
- // Get the current load state (the values that determine what to load and if the loaded results can still be used or are stale)
105
- const loadState: LoadState = {
106
- design: this.props.design,
107
- offset: this.state.rows.length,
108
- limit: this.props.pageSize!,
109
- filters: this.props.filters
110
- }
111
-
112
- // If already loading what we want, return
113
- if (_.isEqual(loadState, this.loadState)) {
114
- return
115
- }
116
-
117
- // Record what we're loading
118
- this.loadState = loadState
119
-
120
- // Perform the actual load
121
- this.props.datagridDataSource.getRows(
122
- loadState.design,
123
- loadState.offset,
124
- loadState.limit,
125
- loadState.filters,
126
- (error: any, newRows: any) => {
127
- if (error) {
128
- console.error(error)
129
- alert(T`Error loading data`)
130
- return
131
- }
132
-
133
- // Check that the required load state has not changed
134
- if (_.isEqual(loadState, this.loadState)) {
135
- // Load is complete
136
- this.loadState = null
137
-
138
- // Add rows, setting entirelyLoaded based on whether fewer than requested were returned
139
- const rows = this.state.rows.concat(newRows)
140
- return this.setState({ rows, entirelyLoaded: newRows.length < this.props.pageSize! })
141
- }
142
- }
143
- )
144
- }
145
-
146
- // Reloads all data
147
- reload = () => {
148
- return this.setState({ rows: [], entirelyLoaded: false })
149
- }
150
-
151
- deleteRow(rowIndex: any, callback: any) {
152
- const newRows = this.state.rows.slice()
153
- _.pullAt(newRows, rowIndex)
154
- this.setState({ rows: newRows })
155
- callback()
156
- }
157
-
158
- /** Reload a single row by index and id. Note that the row might be in a different
159
- * ordinal position within the datagrid, or might have vanished from view if the change
160
- * caused the row to be excluded by the filter. Always replace
161
- * it where it was, unless it has disappeared from view in which case the row
162
- * is removed.
163
- */
164
- reloadRow(rowIndex: number, rowId: any, callback: () => void) {
165
- // Create new filters that only include one row
166
- const filters = produce(this.props.filters || [], draft => {
167
- draft.push({
168
- table: this.props.design.table!,
169
- jsonql: {
170
- type: "op",
171
- op: "=",
172
- exprs: [
173
- { type: "field", tableAlias: "{alias}", column: this.props.schema.getTable(this.props.design.table!)?.primaryKey! },
174
- { type: "literal", value: rowId }
175
- ]
176
- }
177
- })
178
- })
179
-
180
- this.props.datagridDataSource.getRows(
181
- this.props.design,
182
- 0,
183
- 1,
184
- filters,
185
- (error, rows) => {
186
- if (error) {
187
- console.error(error)
188
- alert(T`Error loading data`)
189
- callback()
190
- return
191
- }
192
-
193
- const newRows = produce(this.state.rows, draft => {
194
- if (rows![0]) {
195
- draft[rowIndex] = rows![0]
196
- }
197
- else {
198
- // If row missing, remove it from list
199
- draft.splice(rowIndex, 1)
200
- }
201
- })
202
-
203
- this.setState({ rows: newRows })
204
- callback()
205
- }
206
- )
207
- }
208
-
209
- handleColumnResize = (newColumnWidth: any, columnKey: any) => {
210
- // Find index of column
211
- const columnIndex = _.findIndex(this.props.design.columns, { id: columnKey })
212
-
213
- // Set new width
214
- let column = this.props.design.columns[columnIndex]
215
- column = _.extend({}, column, { width: newColumnWidth })
216
-
217
- // Re-add to list
218
- const columns = this.props.design.columns.slice()
219
- columns[columnIndex] = column
220
-
221
- this.props.onDesignChange!(_.extend({}, this.props.design, { columns }))
222
- }
223
-
224
- handleCellClick = (rowIndex: any, columnIndex: any) => {
225
- // Ignore if already editing
226
- if (this.state.editingCell?.rowIndex === rowIndex && this.state.editingCell?.columnIndex === columnIndex) {
227
- return
228
- }
229
-
230
- // Ignore if saving
231
- if (this.state.savingCell) {
232
- return
233
- }
234
-
235
- // Save editing if editing and return
236
- if (this.state.editingCell) {
237
- this.handleSaveEdit()
238
- return
239
- }
240
-
241
- // Check if can edit
242
- if (!this.props.canEditExpr) {
243
- return
244
- }
245
-
246
- // Get column
247
- const column = this.props.design.columns[columnIndex]
248
-
249
- // Get expression type
250
- const exprType = new ExprUtils(this.props.schema).getExprType(column.expr)!
251
-
252
- // If cannot edit type, return
253
- if (!["text", "number", "enum", "date", "datetime"].includes(exprType)) {
254
- return
255
- }
256
-
257
- // Get row id
258
- const rowId = this.state.rows[rowIndex].id
259
- if (rowId == null) {
260
- // No row id means aggregated table. Cannot edti
261
- return
262
- }
263
-
264
- this.props.canEditExpr(this.props.design.table!, rowId, column.expr)
265
- .then(canEdit => {
266
- if (canEdit) {
267
- // Start editing
268
- this.setState({ editingCell: { rowIndex, columnIndex, rowId } })
269
- }
270
- }).catch(error => {
271
- console.error(error)
272
- })
273
- }
274
-
275
- // Called to save
276
- handleSaveEdit = () => {
277
- // Ignore if not changed
278
- if (!this.editCellComp || !this.editCellComp.hasChanged()) {
279
- this.setState({ editingCell: null, savingCell: false })
280
- return
281
- }
282
-
283
- const rowId = this.state.editingCell!.rowId
284
- const { expr } = this.props.design.columns[this.state.editingCell!.columnIndex]
285
- const value = this.editCellComp.getValue()
286
-
287
- this.setState({ savingCell: true }, () => {
288
- this.props.updateExprValues!(this.props.design.table!, [{ primaryKey: rowId, expr, value }])
289
- .then(() => {
290
- // Reload row
291
- this.reloadRow(this.state.editingCell!.rowIndex, rowId, () => {
292
- this.setState({ editingCell: null, savingCell: false })
293
- })
294
- }).catch(error => {
295
- alert(T`Error saving data`)
296
- console.error(error)
297
- })
298
- })
299
- }
300
-
301
- handleCancelEdit = () => {
302
- this.setState({ editingCell: null, savingCell: false })
303
- }
304
-
305
- // Called with current ref edit. Save
306
- refEditCell = (comp: EditExprCellComponent | null) => {
307
- this.editCellComp = comp
308
- }
309
-
310
- handleRowDoubleClick = (ev: any, rowIndex: any) => {
311
- if (this.props.onRowDoubleClick != null && this.state.rows[rowIndex]?.id) {
312
- this.props.onRowDoubleClick(this.props.design.table!, this.state.rows[rowIndex].id, rowIndex)
313
- }
314
- }
315
-
316
- handleRowClick = (ev: any, rowIndex: any) => {
317
- if (this.props.onRowClick != null && this.state.rows[rowIndex].id) {
318
- this.props.onRowClick(this.props.design.table!, this.state.rows[rowIndex].id, rowIndex)
319
- }
320
- }
321
-
322
- // Render a single cell. exprType is passed in for performance purposes and is calculated once per column
323
- renderCell = (column: any, columnIndex: any, exprType: any, cellProps: any) => {
324
- // If rendering placeholder row
325
- if (cellProps.rowIndex >= this.state.rows.length) {
326
- // Load next tick as cannot update while rendering
327
- _.defer(() => {
328
- this.loadMoreRows()
329
- })
330
- return R(Cell, cellProps, R("i", { className: "fa fa-spinner fa-spin" }))
331
- }
332
-
333
- // Special case for row number
334
- if (columnIndex === -1) {
335
- return R(
336
- Cell,
337
- {
338
- width: cellProps.width,
339
- height: cellProps.height,
340
- style: {
341
- whiteSpace: "nowrap",
342
- textAlign: "right"
343
- }
344
- },
345
- cellProps.rowIndex + 1
346
- )
347
- }
348
-
349
- // Get value (columns are c0, c1, c2, etc.)
350
- const value = this.state.rows[cellProps.rowIndex][`c${columnIndex}`]
351
-
352
- // Render special if editing
353
- if (
354
- this.state.editingCell?.rowIndex === cellProps.rowIndex &&
355
- this.state.editingCell?.columnIndex === columnIndex
356
- ) {
357
- // Special if saving
358
- if (this.state.savingCell) {
359
- return R(Cell, cellProps, R("i", { className: "fa fa-spinner fa-spin" }))
360
- }
361
-
362
- return R(EditExprCellComponent, {
363
- ref: this.refEditCell,
364
- schema: this.props.schema,
365
- dataSource: this.props.dataSource,
366
- locale: this.props.design.locale,
367
- width: cellProps.width,
368
- height: cellProps.height,
369
- value,
370
- expr: column.expr,
371
- onSave: this.handleSaveEdit,
372
- onCancel: this.handleCancelEdit
373
- })
374
- }
375
-
376
- if (column.type === "expr") {
377
- // Muted if from main and are displaying subtable
378
- const muted = !column.subtable && this.state.rows[cellProps.rowIndex].subtable >= 0
379
-
380
- return R(ExprCellComponent, {
381
- schema: this.props.schema,
382
- dataSource: this.props.dataSource,
383
- locale: this.props.design.locale,
384
- width: cellProps.width,
385
- height: cellProps.height,
386
- value,
387
- expr: column.expr,
388
- format: column.format,
389
- exprType,
390
- muted,
391
- onClick: this.handleCellClick.bind(null, cellProps.rowIndex, columnIndex)
392
- })
393
- }
394
-
395
- return null
396
- }
397
-
398
- // Render a single column
399
- renderColumn(column: any, columnIndex: any) {
400
- const exprUtils = new ExprUtils(this.props.schema)
401
-
402
- // Get expression type
403
- const exprType = exprUtils.getExprType(column.expr)
404
-
405
- return R(Column, {
406
- key: column.id,
407
- header: R(
408
- Cell,
409
- { style: { whiteSpace: "nowrap" } },
410
- column.label || exprUtils.summarizeExpr(column.expr, this.props.design.locale)
411
- ),
412
- width: column.width,
413
- allowCellsRecycling: true,
414
- cell: this.renderCell.bind(null, column, columnIndex, exprType),
415
- columnKey: column.id,
416
- isResizable: this.props.onDesignChange != null
417
- })
418
- }
419
-
420
- // Render all columns
421
- renderColumns() {
422
- const columns = _.map(this.props.design.columns, (column, columnIndex) => this.renderColumn(column, columnIndex))
423
-
424
- if (this.props.design.showRowNumbers) {
425
- columns.unshift(
426
- this.renderColumn(
427
- {
428
- label: "#",
429
- width: 50
430
- },
431
- -1
432
- )
433
- )
434
- }
435
-
436
- return columns
437
- }
438
-
439
- render() {
440
- let rowsCount = this.state.rows.length
441
-
442
- // Add loading row if not entirely loaded
443
- if (!this.state.entirelyLoaded) {
444
- rowsCount += 1
445
- }
446
-
447
- return R(
448
- Table,
449
- {
450
- rowsCount,
451
- rowHeight: 40,
452
- headerHeight: 40,
453
- width: this.props.width,
454
- height: this.props.height,
455
- onRowDoubleClick: this.handleRowDoubleClick,
456
- onRowClick: this.handleRowClick,
457
- isColumnResizing: false,
458
- onColumnResizeEndCallback: this.handleColumnResize,
459
- touchScrollEnabled: true
460
- },
461
- this.renderColumns()
462
- )
463
- }
464
- }