@mwater/visualization 5.5.0 → 5.6.1

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 (275) hide show
  1. package/lib/ColorComponent.js +2 -2
  2. package/lib/MWaterContextComponent.d.ts +1 -1
  3. package/lib/MWaterGlobalFiltersComponent.d.ts +2 -2
  4. package/lib/MWaterGlobalFiltersComponent.js +11 -20
  5. package/lib/MWaterLoaderComponent.d.ts +4 -13
  6. package/lib/MWaterLoaderComponent.js +2 -11
  7. package/lib/TranslationsTabComponent.d.ts +34 -0
  8. package/lib/TranslationsTabComponent.js +256 -0
  9. package/lib/UndoStack.d.ts +2 -1
  10. package/lib/UndoStack.js +12 -6
  11. package/lib/dashboards/DashboardComponent.js +6 -5
  12. package/lib/dashboards/DashboardDesign.d.ts +1 -1
  13. package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
  14. package/lib/dashboards/ServerDashboardDataSource.js +0 -25
  15. package/lib/dashboards/SettingsModalComponent.js +9 -233
  16. package/lib/datagrids/DatagridComponent.js +27 -2
  17. package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -3
  18. package/lib/datagrids/DatagridDesignerComponent.js +108 -120
  19. package/lib/datagrids/DatagridViewComponent.js +33 -6
  20. package/lib/datagrids/OrderBysDesignerComponent.d.ts +7 -7
  21. package/lib/datagrids/OrderBysDesignerComponent.js +19 -28
  22. package/lib/index.css +45 -2
  23. package/lib/index.d.ts +5 -5
  24. package/lib/index.js +2 -3
  25. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +8 -1
  26. package/lib/layouts/blocks/BlocksDisplayComponent.js +46 -4
  27. package/lib/maps/BufferLayer.d.ts +0 -13
  28. package/lib/maps/BufferLayer.js +24 -237
  29. package/lib/maps/BufferLayerDesign.d.ts +1 -1
  30. package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
  31. package/lib/maps/BufferLayerDesignerComponent.js +2 -7
  32. package/lib/maps/ChoroplethLayer.d.ts +1 -16
  33. package/lib/maps/ChoroplethLayer.js +25 -358
  34. package/lib/maps/ChoroplethLayerDesign.d.ts +5 -2
  35. package/lib/maps/ChoroplethLayerDesigner.d.ts +10 -32
  36. package/lib/maps/ChoroplethLayerDesigner.js +58 -89
  37. package/lib/maps/ClusterLayer.d.ts +0 -9
  38. package/lib/maps/ClusterLayer.js +0 -250
  39. package/lib/maps/DirectMapDataSource.js +1 -48
  40. package/lib/maps/EditHoverOver.d.ts +4 -3
  41. package/lib/maps/EditHoverOver.js +3 -3
  42. package/lib/maps/GridLayer.d.ts +0 -15
  43. package/lib/maps/GridLayer.js +0 -212
  44. package/lib/maps/HoverContent.js +1 -1
  45. package/lib/maps/Layer.d.ts +1 -26
  46. package/lib/maps/Layer.js +0 -13
  47. package/lib/maps/LeafletMapComponent.js +10 -19
  48. package/lib/maps/MapComponent.d.ts +19 -35
  49. package/lib/maps/MapComponent.js +135 -77
  50. package/lib/maps/MapControlComponent.d.ts +4 -5
  51. package/lib/maps/MapControlComponent.js +5 -12
  52. package/lib/maps/MapDesign.d.ts +8 -0
  53. package/lib/maps/MapDesignerComponent.d.ts +2 -0
  54. package/lib/maps/MapDesignerComponent.js +7 -2
  55. package/lib/maps/MapLayerDataSource.d.ts +0 -4
  56. package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
  57. package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
  58. package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
  59. package/lib/maps/MapLayersDesignerComponent.js +2 -1
  60. package/lib/maps/MapTranslationsTab.d.ts +15 -0
  61. package/lib/maps/MapTranslationsTab.js +47 -0
  62. package/lib/maps/MapUtils.d.ts +11 -0
  63. package/lib/maps/MapUtils.js +57 -1
  64. package/lib/maps/MapViewComponent.d.ts +1 -1
  65. package/lib/maps/MapViewComponent.js +1 -8
  66. package/lib/maps/MarkersLayer.d.ts +1 -14
  67. package/lib/maps/MarkersLayer.js +89 -254
  68. package/lib/maps/MarkersLayerDesign.d.ts +5 -1
  69. package/lib/maps/MarkersLayerDesignerComponent.d.ts +32 -57
  70. package/lib/maps/MarkersLayerDesignerComponent.js +158 -134
  71. package/lib/maps/ServerMapDataSource.d.ts +0 -1
  72. package/lib/maps/ServerMapDataSource.js +0 -25
  73. package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
  74. package/lib/maps/SwitchableTileUrlLayer.js +0 -9
  75. package/lib/maps/TileUrlLayer.d.ts +0 -1
  76. package/lib/maps/TileUrlLayer.js +0 -5
  77. package/lib/maps/VectorMapViewComponent.js +13 -10
  78. package/lib/maps/symbols/font-awesome/asterisk.png +0 -0
  79. package/lib/maps/symbols/font-awesome/ban.png +0 -0
  80. package/lib/maps/symbols/font-awesome/beer.png +0 -0
  81. package/lib/maps/symbols/font-awesome/bell.png +0 -0
  82. package/lib/maps/symbols/font-awesome/bolt.png +0 -0
  83. package/lib/maps/symbols/font-awesome/building.png +0 -0
  84. package/lib/maps/symbols/font-awesome/bullseye.png +0 -0
  85. package/lib/maps/symbols/font-awesome/bus.png +0 -0
  86. package/lib/maps/symbols/font-awesome/caret-up.png +0 -0
  87. package/lib/maps/symbols/font-awesome/certificate.png +0 -0
  88. package/lib/maps/symbols/font-awesome/check-circle.png +0 -0
  89. package/lib/maps/symbols/font-awesome/check.png +0 -0
  90. package/lib/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  91. package/lib/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  92. package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
  93. package/lib/maps/symbols/font-awesome/cloud.png +0 -0
  94. package/lib/maps/symbols/font-awesome/comment.png +0 -0
  95. package/lib/maps/symbols/font-awesome/crosshairs.png +0 -0
  96. package/lib/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  97. package/lib/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  98. package/lib/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  99. package/lib/maps/symbols/font-awesome/female.png +0 -0
  100. package/lib/maps/symbols/font-awesome/file.png +0 -0
  101. package/lib/maps/symbols/font-awesome/flag.png +0 -0
  102. package/lib/maps/symbols/font-awesome/flask.png +0 -0
  103. package/lib/maps/symbols/font-awesome/h-square.png +0 -0
  104. package/lib/maps/symbols/font-awesome/home.png +0 -0
  105. package/lib/maps/symbols/font-awesome/info-circle.png +0 -0
  106. package/lib/maps/symbols/font-awesome/male.png +0 -0
  107. package/lib/maps/symbols/font-awesome/medkit.png +0 -0
  108. package/lib/maps/symbols/font-awesome/mobile.png +0 -0
  109. package/lib/maps/symbols/font-awesome/plus-circle.png +0 -0
  110. package/lib/maps/symbols/font-awesome/plus-square.png +0 -0
  111. package/lib/maps/symbols/font-awesome/plus.png +0 -0
  112. package/lib/maps/symbols/font-awesome/square.png +0 -0
  113. package/lib/maps/symbols/font-awesome/star.png +0 -0
  114. package/lib/maps/symbols/font-awesome/thumbs-down.png +0 -0
  115. package/lib/maps/symbols/font-awesome/thumbs-up.png +0 -0
  116. package/lib/maps/symbols/font-awesome/ticket.png +0 -0
  117. package/lib/maps/symbols/font-awesome/times-circle.png +0 -0
  118. package/lib/maps/symbols/font-awesome/times.png +0 -0
  119. package/lib/maps/symbols/font-awesome/tint.png +0 -0
  120. package/lib/maps/symbols/font-awesome/tree.png +0 -0
  121. package/lib/maps/symbols/font-awesome/university.png +0 -0
  122. package/lib/maps/symbols/font-awesome/usd.png +0 -0
  123. package/lib/maps/symbols/font-awesome/user.png +0 -0
  124. package/lib/maps/symbols/font-awesome/users.png +0 -0
  125. package/lib/maps/symbols/font-awesome/wheelchair.png +0 -0
  126. package/lib/maps/symbols/sdf-ize.sh +93 -0
  127. package/lib/maps/vectorMaps.d.ts +6 -6
  128. package/lib/maps/vectorMaps.js +33 -45
  129. package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +4 -2
  130. package/lib/mwater_table_selection/IndicatorsListComponent.js +103 -34
  131. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.d.ts +18 -0
  132. package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.js +80 -0
  133. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +26 -0
  134. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +237 -51
  135. package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +2 -2
  136. package/lib/mwater_table_selection/MWaterTableSelectComponent.js +9 -4
  137. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.d.ts +19 -0
  138. package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.js +111 -0
  139. package/lib/quickfilter/QuickfiltersComponent.d.ts +3 -102
  140. package/lib/quickfilter/QuickfiltersComponent.js +53 -110
  141. package/lib/quickfilter/TextLiteralComponent.d.ts +23 -47
  142. package/lib/quickfilter/TextLiteralComponent.js +85 -82
  143. package/lib/widgets/MapWidget.js +6 -3
  144. package/lib/widgets/text/ExprItemEditorComponent.d.ts +3 -8
  145. package/lib/widgets/text/ExprItemEditorComponent.js +36 -33
  146. package/lib/widgets/text/ExprUpdateModalComponent.d.ts +1 -0
  147. package/package.json +3 -4
  148. package/src/ColorComponent.tsx +2 -2
  149. package/src/MWaterContextComponent.tsx +1 -1
  150. package/src/{MWaterGlobalFiltersComponent.ts → MWaterGlobalFiltersComponent.tsx} +32 -33
  151. package/src/{MWaterLoaderComponent.ts → MWaterLoaderComponent.tsx} +17 -18
  152. package/src/TranslationsTabComponent.tsx +429 -0
  153. package/src/UndoStack.ts +14 -6
  154. package/src/dashboards/DashboardComponent.tsx +6 -5
  155. package/src/dashboards/DashboardDesign.ts +1 -1
  156. package/src/dashboards/ServerDashboardDataSource.ts +0 -31
  157. package/src/dashboards/SettingsModalComponent.tsx +27 -383
  158. package/src/datagrids/DatagridComponent.tsx +36 -2
  159. package/src/datagrids/DatagridDesignerComponent.tsx +241 -229
  160. package/src/datagrids/DatagridViewComponent.tsx +44 -7
  161. package/src/datagrids/OrderBysDesignerComponent.tsx +61 -70
  162. package/src/index.css +45 -2
  163. package/src/index.ts +5 -11
  164. package/src/layouts/blocks/BlocksDisplayComponent.tsx +60 -5
  165. package/src/maps/BufferLayer.ts +30 -263
  166. package/src/maps/BufferLayerDesign.ts +1 -1
  167. package/src/maps/BufferLayerDesignerComponent.tsx +2 -7
  168. package/src/maps/ChoroplethLayer.ts +30 -394
  169. package/src/maps/ChoroplethLayerDesign.ts +5 -2
  170. package/src/maps/ChoroplethLayerDesigner.tsx +169 -165
  171. package/src/maps/ClusterLayer.ts +0 -274
  172. package/src/maps/DirectMapDataSource.ts +2 -61
  173. package/src/maps/EditHoverOver.tsx +9 -5
  174. package/src/maps/GridLayer.ts +0 -224
  175. package/src/maps/HoverContent.tsx +1 -1
  176. package/src/maps/Layer.ts +1 -35
  177. package/src/maps/LeafletMapComponent.tsx +10 -19
  178. package/src/maps/MapComponent.tsx +448 -0
  179. package/src/maps/MapControlComponent.tsx +41 -0
  180. package/src/maps/MapDesign.ts +6 -0
  181. package/src/maps/MapDesignerComponent.tsx +18 -1
  182. package/src/maps/MapLayerDataSource.ts +0 -5
  183. package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
  184. package/src/maps/MapLayersDesignerComponent.ts +4 -1
  185. package/src/maps/MapTranslationsTab.tsx +53 -0
  186. package/src/maps/MapUtils.ts +61 -1
  187. package/src/maps/MapViewComponent.tsx +2 -8
  188. package/src/maps/MarkersLayer.ts +101 -275
  189. package/src/maps/MarkersLayerDesign.ts +7 -1
  190. package/src/maps/MarkersLayerDesignerComponent.tsx +436 -0
  191. package/src/maps/ServerMapDataSource.ts +0 -31
  192. package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
  193. package/src/maps/TileUrlLayer.tsx +0 -6
  194. package/src/maps/VectorMapViewComponent.tsx +15 -15
  195. package/src/maps/symbols/font-awesome/asterisk.png +0 -0
  196. package/src/maps/symbols/font-awesome/ban.png +0 -0
  197. package/src/maps/symbols/font-awesome/beer.png +0 -0
  198. package/src/maps/symbols/font-awesome/bell.png +0 -0
  199. package/src/maps/symbols/font-awesome/bolt.png +0 -0
  200. package/src/maps/symbols/font-awesome/building.png +0 -0
  201. package/src/maps/symbols/font-awesome/bullseye.png +0 -0
  202. package/src/maps/symbols/font-awesome/bus.png +0 -0
  203. package/src/maps/symbols/font-awesome/caret-up.png +0 -0
  204. package/src/maps/symbols/font-awesome/certificate.png +0 -0
  205. package/src/maps/symbols/font-awesome/check-circle.png +0 -0
  206. package/src/maps/symbols/font-awesome/check.png +0 -0
  207. package/src/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
  208. package/src/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
  209. package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
  210. package/src/maps/symbols/font-awesome/cloud.png +0 -0
  211. package/src/maps/symbols/font-awesome/comment.png +0 -0
  212. package/src/maps/symbols/font-awesome/crosshairs.png +0 -0
  213. package/src/maps/symbols/font-awesome/dot-circle-o.png +0 -0
  214. package/src/maps/symbols/font-awesome/exclamation-circle.png +0 -0
  215. package/src/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
  216. package/src/maps/symbols/font-awesome/female.png +0 -0
  217. package/src/maps/symbols/font-awesome/file.png +0 -0
  218. package/src/maps/symbols/font-awesome/flag.png +0 -0
  219. package/src/maps/symbols/font-awesome/flask.png +0 -0
  220. package/src/maps/symbols/font-awesome/h-square.png +0 -0
  221. package/src/maps/symbols/font-awesome/home.png +0 -0
  222. package/src/maps/symbols/font-awesome/info-circle.png +0 -0
  223. package/src/maps/symbols/font-awesome/male.png +0 -0
  224. package/src/maps/symbols/font-awesome/medkit.png +0 -0
  225. package/src/maps/symbols/font-awesome/mobile.png +0 -0
  226. package/src/maps/symbols/font-awesome/plus-circle.png +0 -0
  227. package/src/maps/symbols/font-awesome/plus-square.png +0 -0
  228. package/src/maps/symbols/font-awesome/plus.png +0 -0
  229. package/src/maps/symbols/font-awesome/square.png +0 -0
  230. package/src/maps/symbols/font-awesome/star.png +0 -0
  231. package/src/maps/symbols/font-awesome/thumbs-down.png +0 -0
  232. package/src/maps/symbols/font-awesome/thumbs-up.png +0 -0
  233. package/src/maps/symbols/font-awesome/ticket.png +0 -0
  234. package/src/maps/symbols/font-awesome/times-circle.png +0 -0
  235. package/src/maps/symbols/font-awesome/times.png +0 -0
  236. package/src/maps/symbols/font-awesome/tint.png +0 -0
  237. package/src/maps/symbols/font-awesome/tree.png +0 -0
  238. package/src/maps/symbols/font-awesome/university.png +0 -0
  239. package/src/maps/symbols/font-awesome/usd.png +0 -0
  240. package/src/maps/symbols/font-awesome/user.png +0 -0
  241. package/src/maps/symbols/font-awesome/users.png +0 -0
  242. package/src/maps/symbols/font-awesome/wheelchair.png +0 -0
  243. package/src/maps/symbols/sdf-ize.sh +93 -0
  244. package/src/maps/vectorMaps.tsx +32 -53
  245. package/src/mwater_table_selection/IndicatorsListComponent.tsx +165 -37
  246. package/src/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.tsx +111 -0
  247. package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +373 -37
  248. package/src/mwater_table_selection/MWaterTableSelectComponent.tsx +12 -8
  249. package/src/mwater_table_selection/MWaterWorkflowsSelectComponent.tsx +159 -0
  250. package/src/quickfilter/{QuickfiltersComponent.ts → QuickfiltersComponent.tsx} +165 -158
  251. package/src/quickfilter/TextLiteralComponent.tsx +197 -0
  252. package/src/widgets/MapWidget.tsx +11 -1
  253. package/src/widgets/text/ExprItemEditorComponent.tsx +83 -77
  254. package/src/widgets/text/ExprUpdateModalComponent.tsx +1 -0
  255. package/test/UndoStackTests.ts +52 -1
  256. package/.storybook/config.js +0 -7
  257. package/.storybook/head.html +0 -3
  258. package/.storybook/webpack.config.js +0 -15
  259. package/src/maps/BingLayer.ts +0 -146
  260. package/src/maps/MapComponent.ts +0 -312
  261. package/src/maps/MapControlComponent.ts +0 -46
  262. package/src/maps/MarkersLayerDesignerComponent.ts +0 -374
  263. package/src/maps/RasterMapViewComponent.ts +0 -345
  264. package/src/quickfilter/TextLiteralComponent.ts +0 -165
  265. package/stories/UpdateableComponent.js +0 -29
  266. package/stories/consoles.js +0 -202
  267. package/stories/dashboards.js +0 -217
  268. package/stories/datagridDesign.js +0 -114
  269. package/stories/datagrids.js +0 -69
  270. package/stories/dates.js +0 -80
  271. package/stories/exprcomponent.js +0 -43
  272. package/stories/index.js +0 -18
  273. package/stories/leaflet.js +0 -59
  274. package/stories/maps.js +0 -24
  275. package/stories/pivotChart.js +0 -235
@@ -82,6 +82,11 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
82
82
  const [rows, setRows] = useState<any[]>([])
83
83
  const [entirelyLoaded, setEntirelyLoaded] = useState(false)
84
84
  const loadStateRef = useRef<LoadState | null>(null)
85
+
86
+ // Track which design key the current rows were loaded with to avoid rendering stale data
87
+ // with a mismatched column structure (e.g. after column reorder)
88
+ const [loadedDesignKey, setLoadedDesignKey] = useState<string | null>(null)
89
+ const currentDesignKey = getDatagridReloadKey(props.design)
85
90
 
86
91
  // Get row header width based on selection and showRowNumbers
87
92
  const rowHeaderWidth = props.selectedRows
@@ -154,7 +159,7 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
154
159
 
155
160
  /** Render row headers with optional selection checkboxes */
156
161
  const renderRowHeader = useCallback((options: RenderRowHeaderProps) => {
157
- const rowHeaderStyle = {
162
+ const rowHeaderStyle: React.CSSProperties = {
158
163
  width: options.width,
159
164
  height: options.height,
160
165
  display: "flex",
@@ -165,9 +170,20 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
165
170
  padding: "0 8px"
166
171
  }
167
172
 
168
- const rowId = options.row < rows.length ? rows[options.row].id : null
173
+ // If design key doesn't match, rows are stale - show loading state
174
+ if (loadedDesignKey !== currentDesignKey || options.row >= rows.length) {
175
+ return (
176
+ <div style={rowHeaderStyle}>
177
+ {props.design.showRowNumbers ? (
178
+ <div style={{ flex: 1, textAlign: "right" }}>{options.row + 1}</div>
179
+ ) : null}
180
+ </div>
181
+ )
182
+ }
183
+
184
+ const rowId = rows[options.row].id
169
185
  const isSelected = rowId != null && props.selectedRows ? props.selectedRows.isSelected(rowId) : false
170
- const isSubtable = options.row < rows.length ? rows[options.row].subtable >= 0 : false
186
+ const isSubtable = rows[options.row].subtable >= 0
171
187
 
172
188
  return (
173
189
  <div style={rowHeaderStyle}>
@@ -185,7 +201,7 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
185
201
  ) : null}
186
202
  </div>
187
203
  )
188
- }, [rows, props.selectedRows, props.onSelectedRowsChange, props.design.showRowNumbers, handleRowSelect])
204
+ }, [rows, props.selectedRows, props.onSelectedRowsChange, props.design.showRowNumbers, handleRowSelect, loadedDesignKey, currentDesignKey])
189
205
 
190
206
  const loadMoreRows = useStableCallback((callback?: () => void) => {
191
207
  const loadState: LoadState = {
@@ -217,6 +233,7 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
217
233
  loadStateRef.current = null
218
234
  setRows(prev => [...prev, ...newRows])
219
235
  setEntirelyLoaded(newRows.length < (props.pageSize || 100))
236
+ setLoadedDesignKey(getDatagridReloadKey(loadState.design))
220
237
  callback?.()
221
238
  }
222
239
  }
@@ -224,9 +241,9 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
224
241
  })
225
242
 
226
243
  function reload() {
227
- console.log("reload")
228
244
  setRows([])
229
245
  setEntirelyLoaded(false)
246
+ setLoadedDesignKey(null)
230
247
  }
231
248
 
232
249
  // Reset rows when design, filters or refreshKey changes
@@ -342,6 +359,11 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
342
359
  })
343
360
 
344
361
  const handleCopy = useStableCallback((rowIndex: number, colIndex: number) => {
362
+ // If design key doesn't match, rows are stale - don't copy
363
+ if (loadedDesignKey !== currentDesignKey || rowIndex >= rows.length) {
364
+ return
365
+ }
366
+
345
367
  const row = rows[rowIndex]
346
368
  const col = props.design.columns[colIndex]
347
369
  const value = row[`c${colIndex}`]
@@ -370,6 +392,13 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
370
392
  })
371
393
 
372
394
  const renderCell = useStableCallback((options: RenderCellProps) => {
395
+ // If rows were loaded with a different design key, show loading state to avoid
396
+ // rendering stale data with mismatched column structure (e.g. after column reorder)
397
+ if (loadedDesignKey !== currentDesignKey) {
398
+ _.defer(() => loadMoreRows())
399
+ return <div style={{ padding: 8 }}><i className="fa fa-spinner fa-spin text-muted" /></div>
400
+ }
401
+
373
402
  if (options.row >= rows.length) {
374
403
  _.defer(() => loadMoreRows())
375
404
  return <div style={{ padding: 8 }}><i className="fa fa-spinner fa-spin text-muted" /></div>
@@ -437,7 +466,9 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
437
466
  fontWeight: "bold",
438
467
  height: "100%",
439
468
  display: "flex",
440
- alignItems: "center"
469
+ alignItems: "center",
470
+ overflow: "hidden",
471
+ width: options.width
441
472
  }}>
442
473
  {column.label || exprUtils.summarizeExpr(column.expr, props.design.locale)}
443
474
  </div>
@@ -445,7 +476,8 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
445
476
  })
446
477
 
447
478
  const renderCellEditor = useStableCallback((options: RenderCellEditorProps) => {
448
- if (options.row >= rows.length) {
479
+ // If design key doesn't match, rows are stale - don't render editor
480
+ if (loadedDesignKey !== currentDesignKey || options.row >= rows.length) {
449
481
  return <div />
450
482
  }
451
483
 
@@ -477,6 +509,11 @@ const DatagridViewComponent = forwardRef<DatagridViewComponentRef, DatagridViewC
477
509
  return false
478
510
  }
479
511
 
512
+ // If design key doesn't match, rows are stale - don't allow edit
513
+ if (loadedDesignKey !== currentDesignKey || options.row >= rows.length) {
514
+ return false
515
+ }
516
+
480
517
  const rowId = rows[options.row].id
481
518
  if (rowId == null) {
482
519
  return false
@@ -1,11 +1,9 @@
1
- import PropTypes from "prop-types"
2
1
  import _ from "lodash"
3
2
  import React from "react"
4
- const R = React.createElement
5
-
6
- import { DataSource, ExprUtils, Schema } from "@mwater/expressions"
3
+ import { DataSource, Schema } from "@mwater/expressions"
7
4
  import { ExprComponent } from "@mwater/expressions-ui"
8
- import { Checkbox } from "@mwater/react-library/lib/bootstrap"
5
+ import { Toggle } from "@mwater/react-library/lib/bootstrap"
6
+ import { DatagridDesignOrderBy } from "./DatagridDesign"
9
7
 
10
8
  export interface OrderBysDesignerComponentProps {
11
9
  /** schema to use */
@@ -13,10 +11,9 @@ export interface OrderBysDesignerComponentProps {
13
11
  /** dataSource to use */
14
12
  dataSource: DataSource
15
13
  table: string
16
- /** Columns list See README.md of this folder */
17
- orderBys: any
14
+ orderBys: DatagridDesignOrderBy[]
18
15
  /** Called when columns changes */
19
- onChange: any
16
+ onChange: (orderBys: DatagridDesignOrderBy[]) => void
20
17
  }
21
18
 
22
19
  // Edits an orderBys which is a list of expressions and directions. See README.md
@@ -42,40 +39,38 @@ export default class OrderBysDesignerComponent extends React.Component<OrderBysD
42
39
  }
43
40
 
44
41
  render() {
45
- return R(
46
- "div",
47
- null,
48
- _.map(this.props.orderBys, (orderBy, index) => {
49
- return R(OrderByDesignerComponent, {
50
- key: index,
51
- schema: this.props.schema,
52
- table: this.props.table,
53
- dataSource: this.props.dataSource,
54
- orderBy,
55
- onChange: this.handleChange.bind(null, index),
56
- onRemove: this.handleRemove.bind(null, index)
57
- })
58
- }),
42
+ return (
43
+ <div>
44
+ {_.map(this.props.orderBys, (orderBy, index) => {
45
+ return <OrderByDesignerComponent
46
+ key={index}
47
+ schema={this.props.schema}
48
+ table={this.props.table}
49
+ dataSource={this.props.dataSource}
50
+ orderBy={orderBy}
51
+ onChange={this.handleChange.bind(null, index)}
52
+ onRemove={this.handleRemove.bind(null, index)}
53
+ />
54
+ })}
59
55
 
60
- R(
61
- "button",
62
- {
63
- key: "add",
64
- type: "button",
65
- className: "btn btn-link",
66
- onClick: this.handleAdd
67
- },
68
- R("span", { className: "fas fa-plus" }),
69
- " " + T`Add Ordering`
70
- )
56
+ <button
57
+ key="add"
58
+ type="button"
59
+ className="btn btn-link"
60
+ onClick={this.handleAdd}
61
+ >
62
+ <span className="fas fa-plus" />
63
+ {" " + T`Add Ordering`}
64
+ </button>
65
+ </div>
71
66
  )
72
67
  }
73
68
  }
74
69
 
75
70
  interface OrderByDesignerComponentProps {
76
- orderBy: any
77
- onChange: any
78
- onRemove: any
71
+ orderBy: DatagridDesignOrderBy
72
+ onChange: (orderBy: DatagridDesignOrderBy) => void
73
+ onRemove: () => void
79
74
  schema: Schema
80
75
  dataSource: DataSource
81
76
  table?: string
@@ -86,43 +81,39 @@ class OrderByDesignerComponent extends React.Component<OrderByDesignerComponentP
86
81
  return this.props.onChange(_.extend({}, this.props.orderBy, { expr }))
87
82
  }
88
83
 
89
- handleDirectionChange = (value: any) => {
90
- return this.props.onChange(_.extend({}, this.props.orderBy, { direction: value ? "desc" : "asc" }))
84
+ handleDirectionChange = (direction: string) => {
85
+ return this.props.onChange(_.extend({}, this.props.orderBy, { direction }))
91
86
  }
92
87
 
93
88
  render() {
94
- return R(
95
- "div",
96
- { className: "row" },
97
- R(
98
- "div",
99
- { className: "col-7" },
100
- R(ExprComponent, {
101
- schema: this.props.schema,
102
- dataSource: this.props.dataSource,
103
- table: this.props.table,
104
- types: ["text", "number", "boolean", "date", "datetime"],
105
- aggrStatuses: ["individual", "literal", "aggregate"],
106
- value: this.props.orderBy.expr,
107
- onChange: this.handleExprChange
108
- })
109
- ),
110
- R(
111
- "div",
112
- { className: "col-3" },
113
- <Checkbox inline value={this.props.orderBy.direction === "desc"} onChange={this.handleDirectionChange}>
114
- {T`Reverse`}
115
- </Checkbox>
116
- ),
117
- R(
118
- "div",
119
- { className: "col-1" },
120
- R(
121
- "button",
122
- { className: "btn btn-sm btn-link", type: "button", onClick: this.props.onRemove },
123
- R("span", { className: "fas fa-times" })
124
- )
125
- )
89
+ return (
90
+ <div style={{ display: "flex", alignItems: "center", gap: "8px", marginBottom: "8px" }}>
91
+ <div style={{ flex: 1 }}>
92
+ <ExprComponent
93
+ schema={this.props.schema}
94
+ dataSource={this.props.dataSource}
95
+ table={this.props.table}
96
+ types={["text", "number", "boolean", "date", "datetime"]}
97
+ aggrStatuses={["individual", "literal", "aggregate"]}
98
+ value={this.props.orderBy.expr}
99
+ onChange={this.handleExprChange}
100
+ />
101
+ </div>
102
+ <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
103
+ <Toggle
104
+ size="xs"
105
+ value={this.props.orderBy.direction}
106
+ onChange={this.handleDirectionChange}
107
+ options={[
108
+ { value: "asc", label: T`Ascending` },
109
+ { value: "desc", label: T`Descending` }
110
+ ]}
111
+ />
112
+ <button className="btn btn-sm btn-link" type="button" onClick={this.props.onRemove}>
113
+ <span className="fas fa-times" />
114
+ </button>
115
+ </div>
116
+ </div>
126
117
  )
127
118
  }
128
119
  }
package/src/index.css CHANGED
@@ -55,6 +55,12 @@ Lato, Lora, Inter, Merriweather, Roboto
55
55
  }
56
56
  }
57
57
 
58
+ @media only screen and (max-width: 800px) {
59
+ .hide-800px {
60
+ display: none;
61
+ }
62
+ }
63
+
58
64
  /* Dashed thresholds */
59
65
  .bb-grid line {
60
66
  stroke-dasharray: 3;
@@ -133,6 +139,20 @@ Lato, Lora, Inter, Merriweather, Roboto
133
139
  visibility: visible;
134
140
  }
135
141
 
142
+ /* Use these to make a grandchild that displays only when parent is hovered */
143
+ .hover-display-parent > * > .hover-display-grandchild {
144
+ visibility: hidden;
145
+ }
146
+
147
+ .hover-display-parent:hover > * > .hover-display-grandchild {
148
+ visibility: visible;
149
+ }
150
+
151
+ /* Use these to set a faint background on hover */
152
+ .hover-grey:hover {
153
+ background-color: #f8f8f8;
154
+ }
155
+
136
156
  .bb-title {
137
157
  font: 14px sans-serif;
138
158
  font-weight: bold;
@@ -342,6 +362,29 @@ Lato, Lora, Inter, Merriweather, Roboto
342
362
  background-color: #363b3e;
343
363
  padding: 5px;
344
364
  padding-top: 6px;
365
+ transform: translateX(-100%);
366
+ animation: slideIn 0.3s ease-in-out;
367
+ }
368
+
369
+ @keyframes slideIn {
370
+ from {
371
+ transform: translateX(-100%);
372
+ }
373
+ to {
374
+ transform: translateX(0);
375
+ }
376
+ }
377
+
378
+ .mwater-visualization-palette-container {
379
+ position: absolute;
380
+ top: 0;
381
+ left: 0;
382
+ height: 100%;
383
+ z-index: 1000;
384
+ }
385
+
386
+ .mwater-visualization-palette-container:not(.hidden) .mwater-visualization-palette {
387
+ transform: translateX(0);
345
388
  }
346
389
 
347
390
  .mwater-visualization-palette-item {
@@ -543,11 +586,11 @@ Lato, Lora, Inter, Merriweather, Roboto
543
586
  background-color: rgba(0, 0, 0, 0.075);
544
587
  }
545
588
 
546
- ._mviz-move:hover {
589
+ .mwater-visualization-cursor-hover:hover {
547
590
  cursor: move;
548
591
  }
549
592
 
550
- ._mviz-map-hover-content {
593
+ .mwater-visualization-map-hover-content {
551
594
  display: grid;
552
595
  grid-template-columns: 1fr 2fr;
553
596
  grid-auto-rows: min-content;
package/src/index.ts CHANGED
@@ -1,10 +1,5 @@
1
- export {
2
- default as LeafletMapComponent,
3
- MapBounds,
4
- TileLayer,
5
- GeoJsonLayer,
6
- MapLayer
7
- } from "./maps/LeafletMapComponent"
1
+ export { default as LeafletMapComponent } from "./maps/LeafletMapComponent"
2
+ export type { MapBounds, TileLayer, GeoJsonLayer, MapLayer } from "./maps/LeafletMapComponent"
8
3
 
9
4
  export { default as DateRangeComponent } from "./DateRangeComponent"
10
5
 
@@ -18,7 +13,7 @@ export { default as DashboardComponent } from "./dashboards/DashboardComponent"
18
13
  export { default as DashboardDataSource } from "./dashboards/DashboardDataSource"
19
14
  export { default as DirectDashboardDataSource } from "./dashboards/DirectDashboardDataSource"
20
15
  export * from "./dashboards/DashboardDesign"
21
- export { MapDesign, MapLayerView } from "./maps/MapDesign"
16
+ export type { MapDesign, MapLayerView } from "./maps/MapDesign"
22
17
 
23
18
  export { default as compressJson } from "./compressJson"
24
19
 
@@ -32,7 +27,7 @@ export { default as Widget } from "./widgets/Widget"
32
27
  export { default as DatagridUtils } from "./datagrids/DatagridUtils"
33
28
 
34
29
  export * from "./maps/MapViewComponent"
35
- export { MapScope } from "./maps/MapUtils"
30
+ export type { MapScope } from "./maps/MapUtils"
36
31
 
37
32
  export { languages } from "./languages"
38
33
 
@@ -41,7 +36,7 @@ export { default as MWaterContextComponent } from "./MWaterContextComponent"
41
36
 
42
37
  export { default as mWaterLoader } from "./mWaterLoader"
43
38
 
44
- export { WidgetDataSource } from "./widgets/WidgetDataSource"
39
+ export type { WidgetDataSource } from "./widgets/WidgetDataSource"
45
40
  export { default as DirectWidgetDataSource } from "./widgets/DirectWidgetDataSource"
46
41
 
47
42
  import "leaflet/dist/leaflet.css"
@@ -55,7 +50,6 @@ export { setMapTilerApiKey } from "./maps/vectorMaps"
55
50
 
56
51
  export { default as UndoStack } from "./UndoStack"
57
52
  export { default as DashboardViewComponent } from "./dashboards/DashboardViewComponent"
58
- export let BingLayer = require("./maps/BingLayer")
59
53
  export let UtfGridLayer = require("./maps/UtfGridLayer")
60
54
  export { default as LayerFactory } from "./maps/LayerFactory"
61
55
  export { default as MapDesignerComponent } from "./maps/MapDesignerComponent"
@@ -38,11 +38,39 @@ export interface BlocksDisplayComponentProps {
38
38
  cantPasteMessage?: string
39
39
  }
40
40
 
41
+ interface BlocksDisplayComponentState {
42
+ isPaletteVisible: boolean
43
+ isManuallyHidden: boolean
44
+ }
45
+
41
46
  /**
42
47
  Renders the complete layout of the blocks and also optionally a palette to the left
43
48
  that can be used to drag new items into the layout. Palette is only displayed if onItemsChange is not null
44
49
  */
45
- class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps> {
50
+ class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps, BlocksDisplayComponentState> {
51
+ state: BlocksDisplayComponentState = {
52
+ isPaletteVisible: false,
53
+ isManuallyHidden: false
54
+ }
55
+
56
+ componentDidUpdate(prevProps: BlocksDisplayComponentProps) {
57
+ // If editing state changes (onItemsChange becomes available/unavailable)
58
+ if (prevProps.onItemsChange !== this.props.onItemsChange) {
59
+ if (this.props.onItemsChange && !this.state.isManuallyHidden) {
60
+ this.setState({ isPaletteVisible: true })
61
+ } else if (!this.props.onItemsChange) {
62
+ this.setState({ isPaletteVisible: false, isManuallyHidden: false })
63
+ }
64
+ }
65
+ }
66
+
67
+ handlePaletteToggle = () => {
68
+ this.setState(prevState => ({
69
+ isPaletteVisible: !prevState.isPaletteVisible,
70
+ isManuallyHidden: !prevState.isManuallyHidden
71
+ }))
72
+ }
73
+
46
74
  handleBlockDrop = (sourceBlock: LayoutBlock, targetBlock: LayoutBlock, side: "top" | "left" | "right" | "bottom") => {
47
75
  // Remove source from items
48
76
  let items = blockUtils.removeBlock(this.props.items, sourceBlock)!
@@ -219,8 +247,32 @@ class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps
219
247
 
220
248
  renderPalette() {
221
249
  return (
222
- <div key="palette" style={{ width: 141, height: "100%", position: "absolute", top: 0, left: 0 }}>
250
+ <div key="palette" style={{
251
+ width: 141,
252
+ height: "100%",
253
+ position: "absolute",
254
+ top: 0,
255
+ left: 0,
256
+ transition: "transform 0.3s ease-in-out",
257
+ transform: this.state.isPaletteVisible ? "translateX(0)" : "translateX(-100%)"
258
+ }}>
223
259
  <div className="mwater-visualization-palette" style={{ height: "100%" }}>
260
+ <div
261
+ style={{
262
+ position: "absolute",
263
+ right: -14,
264
+ top: 0,
265
+ background: "#363b3e",
266
+ color: "white",
267
+ padding: "5px 3px 5px 5px",
268
+ cursor: "pointer",
269
+ borderRadius: "0 3px 3px 0",
270
+ zIndex: 1001
271
+ }}
272
+ onClick={this.handlePaletteToggle}
273
+ >
274
+ <i className={`fa fa-chevron-${this.state.isPaletteVisible ? 'left' : 'right'}`} />
275
+ </div>
224
276
  <PaletteItemComponent
225
277
  createItem={this.createBlockItem({ type: "widget", widgetType: "Text", design: { style: "title" } })}
226
278
  title={<i className="fa fa-font" />}
@@ -345,16 +397,19 @@ class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps
345
397
  style={{ width: "100%", height: "100%", overflow: "hidden", position: "relative" }}
346
398
  layoutOptions={layoutOptions}
347
399
  >
348
- {this.renderPalette()}
400
+ <div className="mwater-visualization-palette-container">
401
+ {this.renderPalette()}
402
+ </div>
349
403
  <div
350
404
  style={{
351
405
  position: "absolute",
352
- left: 141,
406
+ left: this.state.isPaletteVisible ? 141 : 0,
353
407
  top: 0,
354
408
  bottom: 0,
355
409
  right: 0,
356
410
  overflowX: "auto",
357
- overflowY: "scroll"
411
+ overflowY: "scroll",
412
+ transition: "left 0.3s ease-in-out"
358
413
  }}
359
414
  className={`mwater-visualization-block-parent-outer mwater-visualization-block-editing`}
360
415
  >