@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
@@ -60,8 +60,8 @@ class ColorComponent extends react_1.default.Component {
60
60
  const rect = this.colorWellRef.getBoundingClientRect();
61
61
  const popupPosition = {
62
62
  position: "fixed",
63
- top: `${rect.bottom + window.scrollY}px`,
64
- left: `${rect.left + window.scrollX}px`,
63
+ top: `${rect.bottom}px`,
64
+ left: `${rect.left}px`,
65
65
  zIndex: 1070,
66
66
  backgroundColor: "white",
67
67
  border: "solid 1px #DDD",
@@ -8,7 +8,7 @@ export interface GlobalFiltersElementFactoryProps {
8
8
  dataSource: DataSource;
9
9
  filterableTables: string[];
10
10
  globalFilters?: GlobalFilter[];
11
- onChange: (globalFilters: GlobalFilter[]) => void;
11
+ onChange?: (globalFilters: GlobalFilter[]) => void;
12
12
  /** If true, return null element if not applicable to filterableTables */
13
13
  nullIfIrrelevant?: boolean;
14
14
  }
@@ -8,10 +8,10 @@ export interface MWaterGlobalFiltersComponentProps {
8
8
  dataSource: DataSource;
9
9
  filterableTables: string[];
10
10
  globalFilters?: GlobalFilter[];
11
- onChange: (globalFilters: GlobalFilter[]) => void;
11
+ onChange?: (globalFilters: GlobalFilter[]) => void;
12
12
  }
13
13
  export default class MWaterGlobalFiltersComponent extends React.Component<MWaterGlobalFiltersComponentProps> {
14
14
  handleRegionsChange: (regions: any) => void;
15
15
  handleManagedByChange: (managedBy: any) => void;
16
- render(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
16
+ render(): React.JSX.Element;
17
17
  }
@@ -28,12 +28,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const lodash_1 = __importDefault(require("lodash"));
30
30
  const react_1 = __importDefault(require("react"));
31
- const R = react_1.default.createElement;
32
31
  const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
33
32
  const expressions_ui_1 = require("@mwater/expressions-ui");
34
33
  // Control to edit the global filters (_managed_by and admin_region)
35
34
  class MWaterGlobalFiltersComponent extends react_1.default.Component {
36
35
  handleRegionsChange = (regions) => {
36
+ if (!this.props.onChange) {
37
+ return;
38
+ }
37
39
  // Remove existing filter
38
40
  const globalFilters = lodash_1.default.filter(this.props.globalFilters || [], (gf) => !(gf.op === "within any" && gf.columnId === "admin_region"));
39
41
  // Add new filter if present
@@ -48,6 +50,9 @@ class MWaterGlobalFiltersComponent extends react_1.default.Component {
48
50
  this.props.onChange(globalFilters);
49
51
  };
50
52
  handleManagedByChange = (managedBy) => {
53
+ if (!this.props.onChange) {
54
+ return;
55
+ }
51
56
  // Remove existing filter
52
57
  const globalFilters = lodash_1.default.filter(this.props.globalFilters || [], (gf) => !(gf.op === "within" && gf.columnId === "_managed_by"));
53
58
  // Add new filter if present
@@ -79,25 +84,11 @@ class MWaterGlobalFiltersComponent extends react_1.default.Component {
79
84
  else {
80
85
  adminRegions = null;
81
86
  }
82
- return R("div", null, R(ui.FormGroup, { label: T `Only sites managed by`, labelMuted: true }, R(expressions_ui_1.IdLiteralComponent, {
83
- value: managedBy,
84
- onChange: this.handleManagedByChange,
85
- idTable: "groups",
86
- schema: this.props.schema,
87
- dataSource: this.props.dataSource,
88
- placeholder: T `All Organizations`,
89
- multi: false,
90
- filter: { type: "field", tableAlias: "main", column: "canManageEntities" }
91
- })), R(ui.FormGroup, { label: T `Only sites located in`, labelMuted: true }, R(expressions_ui_1.IdLiteralComponent, {
92
- value: adminRegions,
93
- onChange: this.handleRegionsChange,
94
- idTable: "admin_regions",
95
- schema: this.props.schema,
96
- dataSource: this.props.dataSource,
97
- placeholder: T `All Regions`,
98
- multi: true,
99
- orderBy: [{ expr: { type: "field", tableAlias: "main", column: "level" }, direction: "asc" }]
100
- })));
87
+ return (react_1.default.createElement("div", null,
88
+ react_1.default.createElement(ui.FormGroup, { label: T `Only sites managed by`, labelMuted: true },
89
+ react_1.default.createElement(expressions_ui_1.IdLiteralComponent, { value: managedBy, onChange: this.props.onChange ? this.handleManagedByChange : undefined, idTable: "groups", schema: this.props.schema, dataSource: this.props.dataSource, placeholder: T `All Organizations`, multi: false, filter: { type: "field", tableAlias: "main", column: "canManageEntities" } })),
90
+ react_1.default.createElement(ui.FormGroup, { label: T `Only sites located in`, labelMuted: true },
91
+ react_1.default.createElement(expressions_ui_1.IdLiteralComponent, { value: adminRegions, onChange: this.props.onChange ? this.handleRegionsChange : undefined, idTable: "admin_regions", schema: this.props.schema, dataSource: this.props.dataSource, placeholder: T `All Regions`, multi: true, orderBy: [{ expr: { type: "field", tableAlias: "main", column: "level" }, direction: "asc" }] }))));
101
92
  }
102
93
  }
103
94
  exports.default = MWaterGlobalFiltersComponent;
@@ -1,8 +1,7 @@
1
- import React, { ReactElement } from "react";
1
+ import React, { ReactElement, ReactNode } from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
3
  import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent";
4
- import LoadingComponent from "@mwater/react-library/lib/LoadingComponent";
5
- import MWaterContextComponent, { AddLayerElementFactory } from "./MWaterContextComponent";
4
+ import { AddLayerElementFactory } from "./MWaterContextComponent";
6
5
  export interface MWaterLoaderComponentProps {
7
6
  apiUrl: string;
8
7
  client?: string;
@@ -24,7 +23,7 @@ export interface MWaterLoaderComponentProps {
24
23
  dataSource: DataSource;
25
24
  }) => ReactElement<any> | null;
26
25
  /** Custom error formatter that returns React node or string, gets passed the error response from server */
27
- errorFormatter?: (data: any, defaultError: string) => string;
26
+ errorFormatter?: (data: any, defaultError: ReactNode) => ReactNode;
28
27
  /** Origin of usage. e.g. "dashboards:43445364..." */
29
28
  origin?: string;
30
29
  }
@@ -43,13 +42,5 @@ export default class MWaterLoaderComponent extends AsyncLoadComponent<MWaterLoad
43
42
  constructor(props: MWaterLoaderComponentProps);
44
43
  isLoadNeeded(newProps: MWaterLoaderComponentProps, oldProps: MWaterLoaderComponentProps): boolean;
45
44
  load(props: MWaterLoaderComponentProps, prevProps: MWaterLoaderComponentProps, callback: any): void;
46
- render(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | React.CElement<import("@mwater/react-library/lib/LoadingComponent").LoadingComponentProps, LoadingComponent> | React.CElement<{
47
- apiUrl: string;
48
- client?: string;
49
- user?: string;
50
- schema: Schema;
51
- extraTables?: string[];
52
- onExtraTablesChange?: (extraTables: string[]) => void;
53
- addLayerElementFactory?: AddLayerElementFactory;
54
- }, MWaterContextComponent> | null;
45
+ render(): React.JSX.Element | null;
55
46
  }
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const lodash_1 = __importDefault(require("lodash"));
7
7
  const react_1 = __importDefault(require("react"));
8
- const R = react_1.default.createElement;
9
8
  const AsyncLoadComponent_1 = __importDefault(require("@mwater/react-library/lib/AsyncLoadComponent"));
10
9
  const LoadingComponent_1 = __importDefault(require("@mwater/react-library/lib/LoadingComponent"));
11
10
  const mWaterLoader_1 = __importDefault(require("./mWaterLoader"));
@@ -69,18 +68,10 @@ class MWaterLoaderComponent extends AsyncLoadComponent_1.default {
69
68
  return this.props.children(this.state.error);
70
69
  }
71
70
  // Inject context
72
- return R(MWaterContextComponent_1.default, {
73
- apiUrl: this.props.apiUrl,
74
- client: this.props.client,
75
- user: this.props.user,
76
- schema: this.state.schema,
77
- extraTables: this.props.extraTables,
78
- onExtraTablesChange: this.props.onExtraTablesChange,
79
- addLayerElementFactory: this.props.addLayerElementFactory
80
- }, this.props.children(this.state.error, {
71
+ return (react_1.default.createElement(MWaterContextComponent_1.default, { apiUrl: this.props.apiUrl, client: this.props.client, user: this.props.user, schema: this.state.schema, extraTables: this.props.extraTables, onExtraTablesChange: this.props.onExtraTablesChange, addLayerElementFactory: this.props.addLayerElementFactory }, this.props.children(this.state.error, {
81
72
  schema: this.state.schema,
82
73
  dataSource: this.state.dataSource
83
- }));
74
+ })));
84
75
  }
85
76
  }
86
77
  exports.default = MWaterLoaderComponent;
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ export interface TranslationsTabComponentProps {
3
+ /** Base locale of the design (e.g. "en") */
4
+ locale: string;
5
+ /** Other locales the design is translated into */
6
+ otherLocales: string[];
7
+ /** Translation mappings per locale. Maps locale to { originalString: translatedString } */
8
+ translations: {
9
+ [locale: string]: {
10
+ [key: string]: string;
11
+ };
12
+ };
13
+ /** All strings that need translation */
14
+ translatableStrings: string[];
15
+ /** Called when base locale changes */
16
+ onLocaleChange: (locale: string) => void;
17
+ /** Called when other locales change */
18
+ onOtherLocalesChange: (locales: string[]) => void;
19
+ /** Called when translations change */
20
+ onTranslationsChange: (translations: {
21
+ [locale: string]: {
22
+ [key: string]: string;
23
+ };
24
+ }) => void;
25
+ /** Custom filename for download. Defaults to "Translations.xlsx" */
26
+ downloadFilename?: string;
27
+ /** Custom description for base language section */
28
+ baseLanguageDescription?: string;
29
+ }
30
+ /**
31
+ * Reusable translations tab component for managing localization of designs
32
+ * (dashboards, maps, etc.) that have locale, otherLocales, and translations properties.
33
+ */
34
+ export declare function TranslationsTabComponent(props: TranslationsTabComponentProps): React.JSX.Element;
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.TranslationsTabComponent = TranslationsTabComponent;
30
+ const lodash_1 = __importDefault(require("lodash"));
31
+ const react_1 = __importStar(require("react"));
32
+ const languages_1 = require("./languages");
33
+ const react_select_1 = __importDefault(require("react-select"));
34
+ const file_saver_1 = __importDefault(require("file-saver"));
35
+ const localizeUtils = __importStar(require("ez-localize/lib/utils"));
36
+ const autotranslate_1 = require("./autotranslate");
37
+ const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
38
+ /**
39
+ * Reusable translations tab component for managing localization of designs
40
+ * (dashboards, maps, etc.) that have locale, otherLocales, and translations properties.
41
+ */
42
+ function TranslationsTabComponent(props) {
43
+ const { locale, otherLocales, translations, translatableStrings, onLocaleChange, onOtherLocalesChange, onTranslationsChange, downloadFilename = "Translations.xlsx", baseLanguageDescription = T `This is the base language.` } = props;
44
+ const fileInputRef = (0, react_1.useRef)(null);
45
+ const localeOptions = (0, react_1.useMemo)(() => {
46
+ return lodash_1.default.sortBy(lodash_1.default.map(languages_1.languages, (language) => ({
47
+ value: language.code,
48
+ label: `${language.en} (${language.name})`
49
+ })), 'label');
50
+ }, []);
51
+ // Get available languages that aren't already selected
52
+ const availableLocaleOptions = (0, react_1.useMemo)(() => {
53
+ const selectedLocales = new Set([locale, ...otherLocales]);
54
+ return localeOptions.filter(opt => !selectedLocales.has(opt.value));
55
+ }, [localeOptions, locale, otherLocales]);
56
+ // Calculate percentage of strings translated for each locale
57
+ const translationPercentages = (0, react_1.useMemo)(() => {
58
+ const percentages = {};
59
+ const totalStrings = translatableStrings.length;
60
+ for (const loc of otherLocales) {
61
+ const translatedCount = translatableStrings.filter(str => translations?.[loc]?.[str] != null).length;
62
+ // Round down to nearest percent
63
+ percentages[loc] = (totalStrings > 0) ? Math.floor((translatedCount / totalStrings) * 100) : 0;
64
+ }
65
+ return percentages;
66
+ }, [translations, otherLocales, translatableStrings]);
67
+ const handleAddLocale = (selectedLocale) => {
68
+ const newOtherLocales = [...otherLocales, selectedLocale.value];
69
+ onOtherLocalesChange(newOtherLocales);
70
+ // Note: We don't initialize translations here because calling both callbacks
71
+ // in sequence would cause a race condition where the second overwrites the first.
72
+ // The code handles undefined translations via optional chaining.
73
+ };
74
+ const handleRemoveLocale = (localeToRemove) => {
75
+ const newOtherLocales = otherLocales.filter(loc => loc !== localeToRemove);
76
+ onOtherLocalesChange(newOtherLocales);
77
+ // Note: We don't remove translations here for the same reason as above.
78
+ // Orphaned translations are harmless and will be cleaned up on next save.
79
+ };
80
+ // Convert translations to LocalizedString format
81
+ const getLocalizedStrings = () => {
82
+ const localizedStrings = [];
83
+ for (const str of translatableStrings) {
84
+ const localizedString = { _base: locale };
85
+ localizedString[locale] = str;
86
+ // Only add translations for other locales if they exist
87
+ for (const otherLocale of otherLocales) {
88
+ if (translations?.[otherLocale]?.[str]) {
89
+ localizedString[otherLocale] = translations[otherLocale][str];
90
+ }
91
+ }
92
+ localizedStrings.push(localizedString);
93
+ }
94
+ return localizedStrings;
95
+ };
96
+ // Convert LocalizedString format back to translations
97
+ const updateFromLocalizedStrings = (localizedStrings) => {
98
+ const newTranslations = {};
99
+ // Initialize translations object
100
+ for (const loc of otherLocales) {
101
+ newTranslations[loc] = {};
102
+ }
103
+ // Add all translations
104
+ for (const str of localizedStrings) {
105
+ for (const loc of otherLocales) {
106
+ if (str[loc]) {
107
+ newTranslations[loc][str[str._base]] = str[loc];
108
+ }
109
+ }
110
+ }
111
+ return newTranslations;
112
+ };
113
+ const handleDownload = () => {
114
+ // Get strings in LocalizedString format
115
+ const strings = getLocalizedStrings();
116
+ // Create xlsx base64 using all locales (primary + other)
117
+ const locales = [{ code: locale, name: locale }]
118
+ .concat(otherLocales.map(code => ({ code, name: code })));
119
+ const base64 = localizeUtils.exportXlsx(locales, strings);
120
+ // Download
121
+ file_saver_1.default.saveAs(b64toBlob(base64, "application/octet-stream"), downloadFilename);
122
+ };
123
+ const handleUpload = () => {
124
+ fileInputRef.current?.click();
125
+ };
126
+ const handleUploadChange = (evt) => {
127
+ const reader = new FileReader();
128
+ reader.onload = (file) => {
129
+ if (!file.target?.result) {
130
+ return;
131
+ }
132
+ const base64 = file.target.result.split(",")[1];
133
+ try {
134
+ // Create locales array for import
135
+ const locales = [{ code: locale, name: locale }]
136
+ .concat(otherLocales.map(code => ({ code, name: code })));
137
+ // Import updates
138
+ const updates = localizeUtils.importXlsx(locales, base64);
139
+ // If nothing localized
140
+ if (updates.length === 0) {
141
+ alert(T `No translation data found in file`);
142
+ return;
143
+ }
144
+ // Convert back to translations format and update
145
+ const newTranslations = updateFromLocalizedStrings(updates);
146
+ onTranslationsChange(newTranslations);
147
+ alert(T `${updates.length} translations applied`);
148
+ }
149
+ catch (error) {
150
+ console.error("Invalid xlsx file:", error);
151
+ alert(T `Invalid xlsx file`);
152
+ }
153
+ };
154
+ if (evt.target.files?.[0]) {
155
+ reader.readAsDataURL(evt.target.files[0]);
156
+ }
157
+ };
158
+ const handleTranslationsChangeForLocale = (loc, newLocaleTranslations) => {
159
+ const newTranslations = { ...translations };
160
+ newTranslations[loc] = newLocaleTranslations;
161
+ onTranslationsChange(newTranslations);
162
+ };
163
+ return (react_1.default.createElement(react_1.default.Fragment, null,
164
+ react_1.default.createElement(bootstrap_1.FormGroup, { label: T `Base Language`, labelMuted: true, help: baseLanguageDescription },
165
+ react_1.default.createElement(react_select_1.default, { value: lodash_1.default.findWhere(localeOptions, { value: locale }) || null, options: localeOptions, onChange: (selected) => onLocaleChange(selected.value) })),
166
+ react_1.default.createElement(bootstrap_1.FormGroup, { label: T `Additional Languages`, labelMuted: true, help: T `Add languages to translate into` },
167
+ react_1.default.createElement("table", null,
168
+ react_1.default.createElement("tbody", null, otherLocales.map(loc => {
169
+ const localeOption = lodash_1.default.findWhere(localeOptions, { value: loc });
170
+ if (!localeOption) {
171
+ return null;
172
+ }
173
+ return (react_1.default.createElement("tr", { key: loc },
174
+ react_1.default.createElement("td", { style: { paddingRight: 10 } }, localeOption.label),
175
+ react_1.default.createElement("td", { className: translationPercentages[loc] === 100 ? "text-success" : "text-warning", style: { textAlign: "right" } }, T `${translationPercentages[loc]}% translated`),
176
+ react_1.default.createElement("td", null, translationPercentages[loc] < 100 && (react_1.default.createElement(AutoTranslateLink, { locale: loc, baseLocale: locale, strings: translatableStrings, existingTranslations: translations?.[loc] || {}, onTranslationsChange: (newLocaleTranslations) => handleTranslationsChangeForLocale(loc, newLocaleTranslations) }))),
177
+ react_1.default.createElement("td", null,
178
+ react_1.default.createElement("button", { type: "button", className: "btn btn-sm btn-link", onClick: () => handleRemoveLocale(loc) },
179
+ react_1.default.createElement("i", { className: "fa fa-times" })))));
180
+ }))),
181
+ availableLocaleOptions.length > 0 && (react_1.default.createElement("div", { className: "mt-3" },
182
+ react_1.default.createElement(react_select_1.default, { value: null, options: availableLocaleOptions, onChange: handleAddLocale, placeholder: T `Add language...` })))),
183
+ otherLocales.length > 0 && (react_1.default.createElement(react_1.default.Fragment, null,
184
+ react_1.default.createElement(bootstrap_1.FormGroup, { label: T `Manage Translations`, labelMuted: true, help: T `Download and re-upload an Excel spreadsheet of text to translate:` },
185
+ react_1.default.createElement("p", null, T `Download and re-upload an Excel spreadsheet of text to translate:`),
186
+ react_1.default.createElement("div", null,
187
+ react_1.default.createElement("button", { type: "button", className: "btn btn-secondary", onClick: handleDownload },
188
+ react_1.default.createElement("i", { className: "fas fa-download me-2" }),
189
+ T `Download XLSX`)),
190
+ react_1.default.createElement("div", { className: "text-muted mt-2" }, T `This creates a spreadsheet that can be sent to a translator. Please do not change the first column or first row of the spreadsheet.`),
191
+ react_1.default.createElement("br", null),
192
+ react_1.default.createElement("p", null, T `Once translation is complete, upload the file back using the button below:`),
193
+ react_1.default.createElement("div", null,
194
+ react_1.default.createElement("button", { type: "button", className: "btn btn-secondary", onClick: handleUpload },
195
+ react_1.default.createElement("i", { className: "fas fa-upload me-2" }),
196
+ T `Upload Translated XLSX`)),
197
+ react_1.default.createElement("input", { type: "file", ref: fileInputRef, style: { display: "none" }, onChange: handleUploadChange, accept: ".xlsx" }))))));
198
+ }
199
+ /**
200
+ * Button that auto-translates untranslated strings using the translation service
201
+ */
202
+ function AutoTranslateLink(props) {
203
+ const { locale, baseLocale, strings, existingTranslations, onTranslationsChange } = props;
204
+ const [isTranslating, setIsTranslating] = (0, react_1.useState)(false);
205
+ const untranslatedStrings = (0, react_1.useMemo)(() => {
206
+ return strings.filter(str => !existingTranslations[str]);
207
+ }, [strings, existingTranslations]);
208
+ const handleClick = async () => {
209
+ if (isTranslating) {
210
+ return;
211
+ }
212
+ setIsTranslating(true);
213
+ try {
214
+ const translatedStrings = await (0, autotranslate_1.translateStrings)(untranslatedStrings, baseLocale, locale);
215
+ const newTranslations = { ...existingTranslations };
216
+ for (let i = 0; i < untranslatedStrings.length; i++) {
217
+ newTranslations[untranslatedStrings[i]] = translatedStrings[i];
218
+ }
219
+ onTranslationsChange(newTranslations);
220
+ }
221
+ catch (error) {
222
+ console.error("Error translating strings:", error);
223
+ alert(T `Error translating strings`);
224
+ }
225
+ finally {
226
+ setIsTranslating(false);
227
+ }
228
+ };
229
+ if (untranslatedStrings.length === 0) {
230
+ return null;
231
+ }
232
+ if (!(0, autotranslate_1.canAutoTranslate)(locale)) {
233
+ return null;
234
+ }
235
+ return (react_1.default.createElement("button", { type: "button", className: "btn btn-sm btn-link", onClick: handleClick, disabled: isTranslating, style: { marginLeft: 5, padding: "0 5px" } }, isTranslating ? (react_1.default.createElement("span", null,
236
+ react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
237
+ " ",
238
+ T `Translating...`)) : (T `Autotranslate`)));
239
+ }
240
+ /**
241
+ * Helper function for base64 to blob conversion
242
+ */
243
+ function b64toBlob(b64Data, contentType = "", sliceSize = 512) {
244
+ const byteCharacters = atob(b64Data);
245
+ const byteArrays = [];
246
+ for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
247
+ const slice = byteCharacters.slice(offset, offset + sliceSize);
248
+ const byteNumbers = new Array(slice.length);
249
+ for (let i = 0; i < slice.length; i++) {
250
+ byteNumbers[i] = slice.charCodeAt(i);
251
+ }
252
+ const byteArray = new Uint8Array(byteNumbers);
253
+ byteArrays.push(byteArray);
254
+ }
255
+ return new Blob(byteArrays, { type: contentType });
256
+ }
@@ -1,7 +1,8 @@
1
1
  export default class UndoStack {
2
2
  undoStack: any[];
3
3
  redoStack: any[];
4
- constructor(undoStack?: any, redoStack?: any);
4
+ maxDepth?: number;
5
+ constructor(undoStack?: any, redoStack?: any, maxDepth?: number);
5
6
  push(value: any): UndoStack;
6
7
  canUndo(): boolean;
7
8
  canRedo(): boolean;
package/lib/UndoStack.js CHANGED
@@ -8,20 +8,26 @@ const lodash_1 = __importDefault(require("lodash"));
8
8
  class UndoStack {
9
9
  undoStack;
10
10
  redoStack;
11
- constructor(undoStack, redoStack) {
11
+ maxDepth;
12
+ constructor(undoStack, redoStack, maxDepth) {
12
13
  this.undoStack = undoStack || [];
13
14
  this.redoStack = redoStack || [];
15
+ this.maxDepth = maxDepth;
14
16
  }
15
17
  // Add a value to the stack
16
18
  push(value) {
17
19
  // No trivial pushes
18
- if (lodash_1.default.isEqual(this.getValue(), value)) {
20
+ if (JSON.stringify(this.getValue()) === JSON.stringify(value)) {
19
21
  return this;
20
22
  }
21
- const undoStack = this.undoStack.slice();
23
+ let undoStack = this.undoStack.slice();
22
24
  undoStack.push(value);
25
+ // Limit stack depth if maxDepth is set
26
+ if (this.maxDepth && undoStack.length > this.maxDepth) {
27
+ undoStack = undoStack.slice(undoStack.length - this.maxDepth);
28
+ }
23
29
  const redoStack = [];
24
- return new UndoStack(undoStack, redoStack);
30
+ return new UndoStack(undoStack, redoStack, this.maxDepth);
25
31
  }
26
32
  canUndo() {
27
33
  return this.undoStack.length > 1;
@@ -34,14 +40,14 @@ class UndoStack {
34
40
  const redoStack = this.redoStack.slice();
35
41
  redoStack.push(lodash_1.default.last(this.undoStack));
36
42
  const undoStack = lodash_1.default.initial(this.undoStack);
37
- return new UndoStack(undoStack, redoStack);
43
+ return new UndoStack(undoStack, redoStack, this.maxDepth);
38
44
  }
39
45
  redo() {
40
46
  // Put last redo on to undoStack
41
47
  const undoStack = this.undoStack.slice();
42
48
  undoStack.push(lodash_1.default.last(this.redoStack));
43
49
  const redoStack = lodash_1.default.initial(this.redoStack);
44
- return new UndoStack(undoStack, redoStack);
50
+ return new UndoStack(undoStack, redoStack, this.maxDepth);
45
51
  }
46
52
  // Get the current value
47
53
  getValue() {
@@ -197,30 +197,30 @@ class DashboardComponent extends react_1.default.Component {
197
197
  react_1.default.createElement("span", { className: "fal fa-globe" }),
198
198
  " ",
199
199
  this.state.locale),
200
- react_1.default.createElement("ul", { className: "dropdown-menu dropdown-menu-end" }, [this.props.design.locale || "en", ...this.props.design.otherLocales].map(locale => react_1.default.createElement("li", { key: locale },
200
+ react_1.default.createElement("ul", { className: "dropdown-menu dropdown-menu-end" }, [...new Set([this.props.design.locale || "en", ...this.props.design.otherLocales])].map(locale => react_1.default.createElement("li", { key: locale },
201
201
  react_1.default.createElement("a", { className: "dropdown-item", onClick: () => this.setState({ locale: locale }) }, __1.languages.find(l => l.code === locale)?.name || locale)))))
202
202
  : undefined,
203
203
  react_1.default.createElement("a", { key: "print", className: "btn btn-link btn-sm", onClick: this.handlePrint },
204
204
  react_1.default.createElement("span", { className: "fas fa-print" }),
205
- react_1.default.createElement("span", { className: "hide-600px" },
205
+ react_1.default.createElement("span", { className: "hide-800px" },
206
206
  " ",
207
207
  T `Print`)),
208
208
  react_1.default.createElement("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData },
209
209
  react_1.default.createElement("span", { className: "fas fa-sync" }),
210
- react_1.default.createElement("span", { className: "hide-600px" },
210
+ react_1.default.createElement("span", { className: "hide-800px" },
211
211
  " ",
212
212
  T `Refresh`)),
213
213
  this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
214
214
  ? react_1.default.createElement("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters },
215
215
  react_1.default.createElement("span", { className: "fa fa-filter" }),
216
- react_1.default.createElement("span", { className: "hide-600px" },
216
+ react_1.default.createElement("span", { className: "hide-800px" },
217
217
  " ",
218
218
  T `Show Quickfilters`))
219
219
  : undefined,
220
220
  this.state.editing
221
221
  ? react_1.default.createElement("a", { key: "settings", className: "btn btn-link btn-sm", onClick: this.handleSettings },
222
222
  react_1.default.createElement("span", { className: "fas fa-cog" }),
223
- react_1.default.createElement("span", { className: "hide-600px" },
223
+ react_1.default.createElement("span", { className: "hide-800px" },
224
224
  " ",
225
225
  T `Settings`))
226
226
  : undefined,
@@ -271,6 +271,7 @@ class DashboardComponent extends react_1.default.Component {
271
271
  react_1.default.createElement("div", { style: {
272
272
  display: "grid",
273
273
  gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
274
+ gridTemplateColumns: "minmax(0, 1fr)",
274
275
  height: "100%"
275
276
  } },
276
277
  !this.props.hideTitleBar ? this.renderTitleBar() : undefined,
@@ -34,6 +34,6 @@ export interface DashboardDesign {
34
34
  };
35
35
  /** true to enable implicit filtering (see ImplicitFilterBuilder). Defaults to true for older dashboards. */
36
36
  implicitFiltersEnabled?: boolean;
37
- /** array of global filters. See below. */
37
+ /** Array of global filters */
38
38
  globalFilters?: GlobalFilter[];
39
39
  }
@@ -66,7 +66,6 @@ declare class ServerWidgetLayerDataSource implements MapLayerDataSource {
66
66
  options: ServerWidgetLayerDataSourceOptions;
67
67
  constructor(options: ServerWidgetLayerDataSourceOptions);
68
68
  getTileUrl(design: any, filters: JsonQLFilter[]): any;
69
- getUtfGridUrl(design: any, filters: JsonQLFilter[]): string | null;
70
69
  /** Get the url for vector tile source with an expiry time. Only for layers of type "VectorTile"
71
70
  * @param createdAfter ISO 8601 timestamp requiring that tile source on server is created after specified datetime
72
71
  */
@@ -231,21 +231,6 @@ class ServerWidgetLayerDataSource {
231
231
  }
232
232
  return this.createUrl(filters, "png");
233
233
  }
234
- // Get the url for the interactivity tiles with the specified filters applied
235
- // Called with (design, filters) where design is the layer design and filters are filters to apply. Returns URL
236
- getUtfGridUrl(design, filters) {
237
- // Handle special cases
238
- if (this.options.layerView.type === "MWaterServer") {
239
- return this.createLegacyUrl(this.options.layerView.design, "grid.json", filters);
240
- }
241
- // Create layer
242
- const layer = LayerFactory_1.default.createLayer(this.options.layerView.type);
243
- // If layer has tiles url directly available
244
- if (layer.getLayerDefinitionType() === "TileUrl") {
245
- return layer.getUtfGridUrl(this.options.layerView.design, filters);
246
- }
247
- return this.createUrl(filters, "grid.json");
248
- }
249
234
  /** Get the url for vector tile source with an expiry time. Only for layers of type "VectorTile"
250
235
  * @param createdAfter ISO 8601 timestamp requiring that tile source on server is created after specified datetime
251
236
  */
@@ -298,22 +283,12 @@ class ServerWidgetLayerDataSource {
298
283
  query.cacheExpiry = cacheExpiry;
299
284
  }
300
285
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?` + querystring_1.default.stringify(query);
301
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
302
- // Used to speed queries
303
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
304
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/");
305
- }
306
286
  return url;
307
287
  }
308
288
  // Create query string
309
289
  createLegacyUrl(design, extension, filters) {
310
290
  let where;
311
291
  let url = `${this.options.apiUrl}maps/tiles/{z}/{x}/{y}.${extension}?type=${design.type}&radius=1000`;
312
- // Add subdomains: {s} will be substituted with "a", "b" or "c" in leaflet for api.mwater.co only.
313
- // Used to speed queries
314
- if (url.match(/^https:\/\/api\.mwater\.co\//)) {
315
- url = url.replace(/^https:\/\/api\.mwater\.co\//, "https://{s}-api.mwater.co/");
316
- }
317
292
  if (this.options.client) {
318
293
  url += `&client=${this.options.client}`;
319
294
  }