@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,13 +1,21 @@
1
1
  import React from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
3
  import { JsonQLFilter } from "..";
4
+ import { HoverOverItem } from "./maps";
4
5
  export interface HoverContentProps {
5
6
  /** Schema to use */
6
7
  schema: Schema;
7
8
  dataSource: DataSource;
8
- /** Design of the marker layer */
9
- design: any;
10
9
  filters?: JsonQLFilter[];
10
+ /** Table that hover over is for */
11
+ table: string;
12
+ /** Hover over items */
13
+ items: HoverOverItem[];
14
+ /** Locale to use */
15
+ locale: string;
16
+ /** Translate function to use */
17
+ translate: (input: string) => string;
11
18
  }
12
- declare const HoverContent: React.FC<HoverContentProps>;
19
+ /** Component that displays hover over content */
20
+ declare const HoverContent: (props: HoverContentProps) => React.JSX.Element;
13
21
  export default HoverContent;
@@ -28,17 +28,20 @@ const expressions_1 = require("@mwater/expressions");
28
28
  const lodash_1 = require("lodash");
29
29
  const valueFormatter_1 = require("../valueFormatter");
30
30
  const valueFormatter_2 = require("../valueFormatter");
31
- const HoverContent = props => {
31
+ /** Component that displays hover over content */
32
+ const HoverContent = (props) => {
32
33
  const [values, setValues] = (0, react_1.useState)({});
34
+ const [error, setError] = (0, react_1.useState)(null);
33
35
  const exprUtils = new expressions_1.ExprUtils(props.schema);
34
36
  (0, react_1.useEffect)(() => {
35
- const items = props.design.hoverOver?.items ?? [];
37
+ let mounted = true;
38
+ const items = props.items;
36
39
  if (items.length > 0) {
37
40
  const exprCompiler = new expressions_1.ExprCompiler(props.schema);
38
41
  const query = {
39
42
  type: "query",
40
43
  selects: [],
41
- from: exprCompiler.compileTable(props.design.table, "main"),
44
+ from: exprCompiler.compileTable(props.table, "main"),
42
45
  limit: 1
43
46
  };
44
47
  items.forEach((item) => {
@@ -62,21 +65,34 @@ const HoverContent = props => {
62
65
  }
63
66
  }
64
67
  props.dataSource.performQuery(query, (error, data) => {
68
+ if (!mounted) {
69
+ return;
70
+ }
71
+ if (error) {
72
+ setError(props.translate("Error loading hover data"));
73
+ return;
74
+ }
65
75
  setValues(data?.[0] ?? {});
66
76
  });
67
77
  }
78
+ return () => {
79
+ mounted = false;
80
+ };
68
81
  }, []);
69
- return (react_1.default.createElement("div", { className: "_mviz-map-hover-content" }, props.design.hoverOver?.items.map((item) => {
82
+ if (error) {
83
+ return react_1.default.createElement("div", { className: "text-danger" }, error);
84
+ }
85
+ return (react_1.default.createElement("div", { className: "_mviz-map-hover-content" }, props.items.map((item) => {
70
86
  let value = values[item.id];
71
- if (value !== null && item.value) {
87
+ if (value != null && item.value) {
72
88
  // Get expression type
73
89
  const exprType = exprUtils.getExprType(item.value);
74
90
  // Format if can format
75
91
  if (exprType && (0, valueFormatter_1.canFormatType)(exprType)) {
76
- value = (0, valueFormatter_2.formatValue)(exprType, value, undefined);
92
+ value = (0, valueFormatter_2.formatValue)(exprType, value, item.format, props.locale);
77
93
  }
78
94
  else {
79
- value = exprUtils.stringifyExprLiteral(item.value, value);
95
+ value = exprUtils.stringifyExprLiteral(item.value, value, props.locale);
80
96
  }
81
97
  }
82
98
  else {
@@ -84,9 +100,9 @@ const HoverContent = props => {
84
100
  }
85
101
  return (react_1.default.createElement(react_1.default.Fragment, null,
86
102
  react_1.default.createElement("span", null,
87
- item.label,
103
+ props.translate(item.label),
88
104
  ":"),
89
- react_1.default.createElement("span", { className: "text-muted" }, values[item.id] === null ? "n/a" : values[item.id] ?? "■■■■")));
105
+ react_1.default.createElement("span", { className: "text-muted" }, values[item.id] === null ? "n/a" : value)));
90
106
  })));
91
107
  };
92
108
  exports.default = HoverContent;
@@ -4,6 +4,7 @@ import { OnGridClickResults, OnGridHoverResults } from "./maps";
4
4
  import { ReactNode } from "react";
5
5
  import { JsonQLQuery } from "@mwater/jsonql";
6
6
  import { LayerSpecification } from "maplibre-gl";
7
+ import { MapLayerDataSource } from "./MapLayerDataSource";
7
8
  export interface JsonQLCssLayerDefinition {
8
9
  layers: Array<{
9
10
  /** Layer id */
@@ -28,11 +29,15 @@ export interface OnGridClickOptions<LayerDesign> {
28
29
  /** data source to use */
29
30
  dataSource: DataSource;
30
31
  /** layer data source */
31
- layerDataSource: any;
32
+ layerDataSource: MapLayerDataSource;
32
33
  /** current scope data if layer is scoping */
33
34
  scopeData: any;
34
35
  /** compiled filters to apply to the popup */
35
36
  filters: JsonQLFilter[];
37
+ /** Locale to use */
38
+ locale: string;
39
+ /** Translate function to use */
40
+ translate: (input: string) => string;
36
41
  }
37
42
  export interface OnGridHoverOptions<LayerDesign> {
38
43
  /** design of layer */
@@ -42,11 +47,15 @@ export interface OnGridHoverOptions<LayerDesign> {
42
47
  /** data source to use */
43
48
  dataSource: DataSource;
44
49
  /** layer data source */
45
- layerDataSource: any;
50
+ layerDataSource: MapLayerDataSource;
46
51
  /** current scope data if layer is scoping */
47
52
  scopeData: any;
48
53
  /** compiled filters to apply to the popup */
49
54
  filters: JsonQLFilter[];
55
+ /** Locale to use */
56
+ locale: string;
57
+ /** Translate function to use */
58
+ translate: (input: string) => string;
50
59
  }
51
60
  /** Definition of a vector tile layer */
52
61
  export interface VectorTileDef {
@@ -137,7 +146,7 @@ export default class Layer<LayerDesign> {
137
146
  /** Get max zoom level */
138
147
  getMaxZoom(design: LayerDesign): number | null | undefined;
139
148
  /** Get the legend to be optionally displayed on the map. Returns a React element */
140
- getLegend(design: LayerDesign, schema: Schema, name: string, dataSource: DataSource, locale: string, filters: JsonQLFilter[]): ReactNode;
149
+ getLegend(options: LegendOptions<LayerDesign>): ReactNode;
141
150
  /** Get a list of table ids that can be filtered on */
142
151
  getFilterableTables(design: LayerDesign, schema: Schema): string[];
143
152
  /** True if layer can be edited */
@@ -161,4 +170,16 @@ export default class Layer<LayerDesign> {
161
170
  w: number;
162
171
  s: number;
163
172
  } | null) => void): void;
173
+ /** Get strings to be translated */
174
+ getTranslatableStrings(design: LayerDesign, schema: Schema): string[];
175
+ }
176
+ export interface LegendOptions<LayerDesign> {
177
+ design: LayerDesign;
178
+ schema: Schema;
179
+ name: string;
180
+ dataSource: DataSource;
181
+ locale: string;
182
+ filters: JsonQLFilter[];
183
+ /** Translate function to use */
184
+ translate: (input: string) => string;
164
185
  }
package/lib/maps/Layer.js CHANGED
@@ -72,7 +72,7 @@ class Layer {
72
72
  return null;
73
73
  }
74
74
  /** Get the legend to be optionally displayed on the map. Returns a React element */
75
- getLegend(design, schema, name, dataSource, locale, filters) {
75
+ getLegend(options) {
76
76
  return null;
77
77
  }
78
78
  /** Get a list of table ids that can be filtered on */
@@ -178,5 +178,9 @@ class Layer {
178
178
  }
179
179
  });
180
180
  }
181
+ /** Get strings to be translated */
182
+ getTranslatableStrings(design, schema) {
183
+ return [];
184
+ }
181
185
  }
182
186
  exports.default = Layer;
@@ -17,29 +17,21 @@ class LayerFactory {
17
17
  switch (type) {
18
18
  case "MWaterServer":
19
19
  return new MWaterServerLayer_1.default();
20
- break;
21
20
  case "Markers":
22
21
  return new MarkersLayer_1.default();
23
- break;
24
22
  case "Buffer":
25
23
  return new BufferLayer_1.default();
26
- break;
27
24
  // Uses a legacy type name
28
25
  case "AdminChoropleth":
29
26
  return new ChoroplethLayer_1.default();
30
- break;
31
27
  case "Cluster":
32
28
  return new ClusterLayer_1.default();
33
- break;
34
29
  case "TileUrl":
35
30
  return new TileUrlLayer_1.default();
36
- break;
37
31
  case "SwitchableTileUrl":
38
32
  return new SwitchableTileUrlLayer_1.default();
39
- break;
40
33
  case "Grid":
41
34
  return new GridLayer_1.default();
42
- break;
43
35
  }
44
36
  throw new Error(`Unknown type ${type}`);
45
37
  }
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const react_1 = __importDefault(require("react"));
7
7
  const lodash_1 = __importDefault(require("lodash"));
8
- const R = react_1.default.createElement;
9
8
  const AxisBuilder_1 = __importDefault(require("../axes/AxisBuilder"));
10
9
  const LegendGroup_1 = __importDefault(require("./LegendGroup"));
11
10
  // wraps the legends for a layer
@@ -4,4 +4,5 @@ import { MapDesign } from "./MapDesign";
4
4
  export declare function LayerSwitcherComponent(props: {
5
5
  design: MapDesign;
6
6
  onDesignChange: (design: MapDesign) => void;
7
+ translate: (input: string) => string;
7
8
  }): React.JSX.Element;
@@ -65,7 +65,7 @@ function LayerSwitcherComponent(props) {
65
65
  return (react_1.default.createElement("div", { key: index, style: { fontSize: 12, whiteSpace: "nowrap", cursor: "pointer" }, onClick: handleClick },
66
66
  react_1.default.createElement("i", { className: lv.visible ? "fa fa-fw fa-check-square text-primary" : "fa fa-fw fa-square text-muted" }),
67
67
  "\u00A0",
68
- lv.name));
68
+ props.translate(lv.name)));
69
69
  }
70
70
  return (react_1.default.createElement("div", { style: { textAlign: "right" }, ref: useClickOutside(() => {
71
71
  setDropdownOpen(false);
@@ -123,7 +123,9 @@ class LeafletMapComponent extends react_1.Component {
123
123
  if (pad) {
124
124
  lBounds = lBounds.pad(pad);
125
125
  }
126
- this.map.fitBounds(lBounds, { animate: true });
126
+ if (lBounds.getEast() !== Infinity && lBounds.getWest() !== -Infinity && lBounds.getNorth() !== Infinity && lBounds.getSouth() !== -Infinity) {
127
+ this.map.fitBounds(lBounds, { animate: true });
128
+ }
127
129
  }
128
130
  else {
129
131
  // Fit world doesn't work sometimes. Make sure that entire left-right is included
@@ -10,5 +10,6 @@ export default function LegendComponent(props: {
10
10
  /** array of filters to apply. Each is { table: table id, jsonql: jsonql condition with {alias} for tableAlias. Use injectAlias to correct */
11
11
  filters: JsonQLFilter[];
12
12
  locale: string;
13
+ translate: (input: string) => string;
13
14
  onHide: () => void;
14
15
  }): React.JSX.Element | null;
@@ -37,7 +37,15 @@ function LegendComponent(props) {
37
37
  // }
38
38
  return {
39
39
  key: layerView.id,
40
- legend: layer.getLegend(design, props.schema, layerView.name, props.dataSource, props.locale, props.filters)
40
+ legend: layer.getLegend({
41
+ design,
42
+ schema: props.schema,
43
+ name: layerView.name,
44
+ dataSource: props.dataSource,
45
+ locale: props.locale,
46
+ filters: props.filters,
47
+ translate: props.translate
48
+ })
41
49
  };
42
50
  }));
43
51
  if (legendItems.length === 0) {
@@ -1,4 +1,4 @@
1
- import Layer from "./Layer";
1
+ import Layer, { LegendOptions } from "./Layer";
2
2
  import React from "react";
3
3
  import { Schema } from "@mwater/expressions";
4
4
  export default class MWaterServerLayer extends Layer<any> {
@@ -10,7 +10,7 @@ export default class MWaterServerLayer extends Layer<any> {
10
10
  } | null;
11
11
  getMinZoom(design: any): any;
12
12
  getMaxZoom(design: any): any;
13
- getLegend(design: any, schema: Schema): React.CElement<any, LoadingLegend>;
13
+ getLegend(options: LegendOptions<any>): React.CElement<any, LoadingLegend>;
14
14
  getFilterableTables(design: any, schema: Schema): any[];
15
15
  isEditable(): boolean;
16
16
  cleanDesign(design: any, schema: Schema): any;
@@ -45,11 +45,11 @@ class MWaterServerLayer extends Layer_1.default {
45
45
  }
46
46
  // Get the legend to be optionally displayed on the map. Returns
47
47
  // a React element
48
- getLegend(design, schema) {
48
+ getLegend(options) {
49
49
  // Create loading legend component
50
50
  // TODO hardcoded
51
51
  const apiUrl = "https://api.mwater.co/v3/";
52
- return react_1.default.createElement(LoadingLegend, { url: `${apiUrl}maps/legend?type=${design.type}` });
52
+ return react_1.default.createElement(LoadingLegend, { url: `${apiUrl}maps/legend?type=${options.design.type}` });
53
53
  }
54
54
  // Get a list of table ids that can be filtered on
55
55
  getFilterableTables(design, schema) {
@@ -65,16 +65,16 @@ class MapComponent extends react_1.default.Component {
65
65
  key: "undo",
66
66
  className: `btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`,
67
67
  onClick: this.handleUndo
68
- }, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, T ` Undo`)),
68
+ }, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, " ", T `Undo`)),
69
69
  " ",
70
70
  R("a", {
71
71
  key: "redo",
72
72
  className: `btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`,
73
73
  onClick: this.handleRedo
74
- }, R("span", { className: "fas fa-caret-right" }), R("span", { className: "hide-600px" }, T ` Redo`))
74
+ }, R("span", { className: "fas fa-caret-right" }), R("span", { className: "hide-600px" }, " ", T `Redo`))
75
75
  ]
76
76
  : undefined, this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
77
- ? R("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters }, R("span", { className: "fa fa-filter" }), R("span", { className: "hide-600px" }, T ` Show Quickfilters`))
77
+ ? R("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters }, R("span", { className: "fa fa-filter" }), R("span", { className: "hide-600px" }, " ", T `Show Quickfilters`))
78
78
  : undefined, this.props.extraTitleButtonsElem, R("a", { key: "toggleDesign", className: "btn btn-link btn-sm", onClick: this.handleToggleDesignPanel, alt: T `Toggle design panel` }, this.getDesign().hideDesignPanel ?
79
79
  R("span", { className: "fas fa-angle-double-left" })
80
80
  : R("span", { className: "fas fa-angle-double-right" })));
@@ -19,6 +19,8 @@ export interface MapDesign {
19
19
  attribution?: string;
20
20
  /** true to automatically zoom to bounds of data */
21
21
  autoBounds?: boolean;
22
+ /** True to animate zoom to bounds of data. Default is true */
23
+ animateAutoBounds?: boolean;
22
24
  /** maximum allowed zoom level */
23
25
  maxZoom?: number | null;
24
26
  /** array of global filters. See below. */
@@ -17,12 +17,13 @@ export interface MapDesignerComponentProps {
17
17
  enableQuickfilters?: boolean;
18
18
  }
19
19
  export default class MapDesignerComponent extends React.Component<MapDesignerComponentProps> {
20
- handleAttributionChange: (text: any) => void;
21
- handleAutoBoundsChange: (value: any) => void;
20
+ handleAttributionChange: (text: string | undefined) => void;
21
+ handleAutoBoundsChange: (value: boolean) => void;
22
+ handleAnimateAutoBoundsChange: (value: boolean) => void;
22
23
  handleShowLayerSwitcherChange: (value: any) => void;
23
24
  handleConvertToClusterMap: () => void;
24
25
  handleConvertToMarkersMap: () => void;
25
26
  handleInitialLegendDisplayChange: (value: any) => void;
26
- renderOptionsTab(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
27
+ renderOptionsTab(): React.JSX.Element;
27
28
  render(): React.JSX.Element;
28
29
  }
@@ -30,7 +30,6 @@ const lodash_1 = __importDefault(require("lodash"));
30
30
  const react_1 = __importDefault(require("react"));
31
31
  const R = react_1.default.createElement;
32
32
  const TabbedComponent_1 = __importDefault(require("@mwater/react-library/lib/TabbedComponent"));
33
- const NumberInputComponent_1 = __importDefault(require("@mwater/react-library/lib/NumberInputComponent"));
34
33
  const CheckboxComponent_1 = __importDefault(require("../CheckboxComponent"));
35
34
  const react_onclickout_1 = __importDefault(require("react-onclickout"));
36
35
  const MapLayersDesignerComponent_1 = __importDefault(require("./MapLayersDesignerComponent"));
@@ -51,6 +50,10 @@ class MapDesignerComponent extends react_1.default.Component {
51
50
  const design = { ...this.props.design, autoBounds: value };
52
51
  return this.props.onDesignChange(design);
53
52
  };
53
+ handleAnimateAutoBoundsChange = (value) => {
54
+ const design = { ...this.props.design, animateAutoBounds: value };
55
+ return this.props.onDesignChange(design);
56
+ };
54
57
  handleShowLayerSwitcherChange = (value) => {
55
58
  const design = { ...this.props.design, showLayerSwitcher: value };
56
59
  return this.props.onDesignChange(design);
@@ -66,35 +69,32 @@ class MapDesignerComponent extends react_1.default.Component {
66
69
  return this.props.onDesignChange(design);
67
70
  };
68
71
  renderOptionsTab() {
69
- return R("div", null, R(BaseLayerDesignerComponent_1.default, {
70
- design: this.props.design,
71
- onDesignChange: this.props.onDesignChange
72
- }), R(CheckboxComponent_1.default, {
73
- checked: this.props.design.autoBounds,
74
- onChange: this.handleAutoBoundsChange
75
- }, R("span", { className: "text-muted" }, T `Automatic zoom `, R(PopoverHelpComponent_1.default, { placement: "left" }, T `Automatically zoom to the complete data whenever the map is loaded or the filters change`))), R(CheckboxComponent_1.default, {
76
- checked: this.props.design.showLayerSwitcher,
77
- onChange: this.handleShowLayerSwitcherChange
78
- }, R("span", { className: "text-muted" }, T `Show Layer Switcher `, R(PopoverHelpComponent_1.default, { placement: "left" }, T `Show a control in the map allowing switching layers`))), R(ui.FormGroup, { label: T `Initial Legend Display`, labelMuted: true }, R(ui.Select, {
79
- value: this.props.design.initialLegendDisplay || "open",
80
- onChange: this.handleInitialLegendDisplayChange,
81
- options: [
82
- { value: "open", label: T `Open` },
83
- { value: "closed", label: T `Closed` },
84
- { value: "closedIfSmall", label: T `Open if wide enough` }
85
- ],
86
- style: { width: "auto" }
87
- })), MapUtils.canConvertToClusterMap(this.props.design)
88
- ? R("div", { key: "tocluster" }, R("a", { onClick: this.handleConvertToClusterMap, className: "btn btn-link btn-sm" }, T `Convert to cluster map`))
89
- : undefined, MapUtils.canConvertToMarkersMap(this.props.design)
90
- ? R("div", { key: "toMarker" }, R("a", { onClick: this.handleConvertToMarkersMap, className: "btn btn-link btn-sm" }, T `Convert to markers map`))
91
- : undefined, R(AttributionComponent, {
92
- text: this.props.design.attribution,
93
- onTextChange: this.handleAttributionChange
94
- }), R("br"), R(AdvancedOptionsComponent, {
95
- design: this.props.design,
96
- onDesignChange: this.props.onDesignChange
97
- }));
72
+ return (react_1.default.createElement("div", null,
73
+ react_1.default.createElement(BaseLayerDesignerComponent_1.default, { design: this.props.design, onDesignChange: this.props.onDesignChange }),
74
+ react_1.default.createElement(CheckboxComponent_1.default, { checked: this.props.design.autoBounds, onChange: this.handleAutoBoundsChange },
75
+ react_1.default.createElement("span", { className: "text-muted" },
76
+ T `Automatic zoom`,
77
+ " ",
78
+ react_1.default.createElement(PopoverHelpComponent_1.default, { placement: "left" }, T `Automatically zoom to the complete data whenever the map is loaded or the filters change`))),
79
+ this.props.design.autoBounds && (react_1.default.createElement(CheckboxComponent_1.default, { checked: this.props.design.animateAutoBounds ?? true, onChange: this.handleAnimateAutoBoundsChange },
80
+ react_1.default.createElement("span", { className: "text-muted" }, T `Animate automatic zoom`))),
81
+ react_1.default.createElement(CheckboxComponent_1.default, { checked: this.props.design.showLayerSwitcher, onChange: this.handleShowLayerSwitcherChange },
82
+ react_1.default.createElement("span", { className: "text-muted" },
83
+ T `Show Layer Switcher `,
84
+ react_1.default.createElement(PopoverHelpComponent_1.default, { placement: "left" }, T `Show a control in the map allowing switching layers`))),
85
+ react_1.default.createElement(ui.FormGroup, { label: T `Initial Legend Display`, labelMuted: true },
86
+ react_1.default.createElement(ui.Select, { value: this.props.design.initialLegendDisplay || "open", onChange: this.handleInitialLegendDisplayChange, options: [
87
+ { value: "open", label: T `Open|adjective` },
88
+ { value: "closed", label: T `Closed` },
89
+ { value: "closedIfSmall", label: T `Open if wide enough` }
90
+ ], style: { width: "auto" } })),
91
+ MapUtils.canConvertToClusterMap(this.props.design) ? (react_1.default.createElement("div", { key: "tocluster" },
92
+ react_1.default.createElement("a", { onClick: this.handleConvertToClusterMap, className: "btn btn-link btn-sm" }, T `Convert to cluster map`))) : undefined,
93
+ MapUtils.canConvertToMarkersMap(this.props.design) ? (react_1.default.createElement("div", { key: "toMarker" },
94
+ react_1.default.createElement("a", { onClick: this.handleConvertToMarkersMap, className: "btn btn-link btn-sm" }, T `Convert to markers map`))) : undefined,
95
+ react_1.default.createElement(AttributionComponent, { text: this.props.design.attribution, onTextChange: this.handleAttributionChange }),
96
+ react_1.default.createElement("br", null),
97
+ react_1.default.createElement(AdvancedOptionsComponent, { design: this.props.design, onDesignChange: this.props.onDesignChange })));
98
98
  }
99
99
  render() {
100
100
  const filterableTables = MapUtils.getFilterableTables(this.props.design, this.props.schema);
@@ -102,47 +102,42 @@ class MapDesignerComponent extends react_1.default.Component {
102
102
  const tabs = [
103
103
  {
104
104
  id: "layers",
105
- label: [R("i", { className: "fa fa-bars" }), T ` Layers`],
106
- elem: R(MapLayersDesignerComponent_1.default, {
107
- schema: this.props.schema,
108
- dataSource: this.props.dataSource,
109
- design: this.props.design,
110
- onDesignChange: this.props.onDesignChange,
111
- allowEditingLayers: true,
112
- filters: lodash_1.default.compact(filters)
113
- })
105
+ label: react_1.default.createElement(react_1.default.Fragment, null,
106
+ react_1.default.createElement("i", { className: "fa fa-bars" }),
107
+ " ",
108
+ T `Layers`),
109
+ elem: react_1.default.createElement(MapLayersDesignerComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, design: this.props.design, onDesignChange: this.props.onDesignChange, allowEditingLayers: true, filters: lodash_1.default.compact(filters) })
114
110
  },
115
111
  {
116
112
  id: "filters",
117
- label: [R("i", { className: "fa fa-filter" }), T ` Filters`],
118
- elem: R(MapFiltersDesignerComponent_1.default, {
119
- schema: this.props.schema,
120
- dataSource: this.props.dataSource,
121
- design: this.props.design,
122
- onDesignChange: this.props.onDesignChange
123
- })
113
+ label: react_1.default.createElement(react_1.default.Fragment, null,
114
+ react_1.default.createElement("i", { className: "fa fa-filter" }),
115
+ " ",
116
+ T `Filters`),
117
+ elem: react_1.default.createElement(MapFiltersDesignerComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, design: this.props.design, onDesignChange: this.props.onDesignChange })
124
118
  },
125
119
  {
126
120
  id: "options",
127
- label: [R("i", { className: "fa fa-cog" }), T ` Options`],
121
+ label: react_1.default.createElement(react_1.default.Fragment, null,
122
+ react_1.default.createElement("i", { className: "fa fa-cog" }),
123
+ " ",
124
+ T `Options`),
128
125
  elem: this.renderOptionsTab()
129
126
  }
130
127
  ];
131
128
  if (this.props.enableQuickfilters) {
132
129
  tabs.splice(2, 0, {
133
130
  id: "quickfilters",
134
- label: [R("i", { className: "fa fa-bolt" }), " ", T `Quickfilters`],
135
- elem: R("div", { style: { marginBottom: 200 } }, R(QuickfiltersDesignComponent_1.default, {
136
- design: this.props.design.quickfilters || [],
137
- onDesignChange: (qfDesign) => {
138
- this.props.onDesignChange((0, immer_1.default)(this.props.design, (draft) => {
139
- draft.quickfilters = qfDesign;
140
- }));
141
- },
142
- schema: this.props.schema,
143
- dataSource: this.props.dataSource,
144
- tables: filterableTables
145
- }))
131
+ label: react_1.default.createElement(react_1.default.Fragment, null,
132
+ react_1.default.createElement("i", { className: "fa fa-bolt" }),
133
+ " ",
134
+ T `Quickfilters`),
135
+ elem: react_1.default.createElement("div", { style: { marginBottom: 200 } },
136
+ react_1.default.createElement(QuickfiltersDesignComponent_1.default, { design: this.props.design.quickfilters || [], onDesignChange: (qfDesign) => {
137
+ this.props.onDesignChange((0, immer_1.default)(this.props.design, (draft) => {
138
+ draft.quickfilters = qfDesign;
139
+ }));
140
+ }, schema: this.props.schema, dataSource: this.props.dataSource, tables: filterableTables }))
146
141
  });
147
142
  }
148
143
  const activeTables = MapUtils.getFilterableTables(this.props.design, this.props.schema);
@@ -168,19 +163,18 @@ class AttributionComponent extends react_1.default.Component {
168
163
  return this.setState({ editing: false });
169
164
  };
170
165
  renderEditor() {
171
- return R(react_onclickout_1.default, { onClickOut: this.handleClickOut }, R("input", { onChange: this.handleTextChange, value: this.props.text, className: "form-control" }));
166
+ return (react_1.default.createElement(react_onclickout_1.default, { onClickOut: this.handleClickOut },
167
+ react_1.default.createElement("input", { onChange: this.handleTextChange, value: this.props.text, className: "form-control" })));
172
168
  }
173
169
  handleTextClick = () => {
174
170
  return this.setState({ editing: true });
175
171
  };
176
172
  render() {
177
- let elem = R("div", { style: { marginLeft: 5 } }, this.state.editing
178
- ? this.renderEditor()
179
- : this.props.text
180
- ? R("span", { onClick: this.handleTextClick, style: { cursor: "pointer" } }, this.props.text)
181
- : R("a", { onClick: this.handleTextClick, className: "btn btn-link btn-sm" }, T `+ Add attribution`));
173
+ let elem = (react_1.default.createElement("div", { style: { marginLeft: 5 } }, this.state.editing ? (this.renderEditor()) : this.props.text ? (react_1.default.createElement("span", { onClick: this.handleTextClick, style: { cursor: "pointer" } }, this.props.text)) : (react_1.default.createElement("a", { onClick: this.handleTextClick, className: "btn btn-link btn-sm" }, T `+ Add attribution`))));
182
174
  if (this.props.text || this.state.editing) {
183
- elem = R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Attribution`), elem);
175
+ elem = (react_1.default.createElement("div", { className: "mb-3" },
176
+ react_1.default.createElement("label", { className: "text-muted" }, T `Attribution`),
177
+ elem));
184
178
  }
185
179
  return elem;
186
180
  }
@@ -195,14 +189,14 @@ class AdvancedOptionsComponent extends react_1.default.Component {
195
189
  }
196
190
  render() {
197
191
  if (!this.state.expanded) {
198
- return R("div", null, R("a", { className: "btn btn-link btn-sm", onClick: () => this.setState({ expanded: true }) }, T `Advanced options...`));
192
+ return (react_1.default.createElement("div", null,
193
+ react_1.default.createElement("a", { className: "btn btn-link btn-sm", onClick: () => this.setState({ expanded: true }) }, T `Advanced options...`)));
199
194
  }
200
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Advanced`), R("div", null, R("span", { className: "text-muted" }, T `Maximum Zoom Level: `), " ", R(NumberInputComponent_1.default, {
201
- small: true,
202
- style: { display: "inline-block" },
203
- placeholder: T `None`,
204
- value: this.props.design.maxZoom,
205
- onChange: (v) => this.props.onDesignChange(lodash_1.default.extend({}, this.props.design, { maxZoom: v }))
206
- })));
195
+ return (react_1.default.createElement("div", { className: "mb-3" },
196
+ react_1.default.createElement("label", { className: "text-muted" }, T `Advanced`),
197
+ react_1.default.createElement("div", null,
198
+ react_1.default.createElement("span", { className: "text-muted" }, T `Maximum Zoom Level: `),
199
+ " ",
200
+ react_1.default.createElement(ui.NumberInput, { decimal: false, size: "sm", style: { display: "inline-block" }, placeholder: T `None`, value: this.props.design.maxZoom, onChange: (v) => this.props.onDesignChange(lodash_1.default.extend({}, this.props.design, { maxZoom: v })) }))));
207
201
  }
208
202
  }
@@ -111,8 +111,8 @@ class MapLayerViewDesignerComponent extends react_1.default.Component {
111
111
  }
112
112
  renderLayerEditToggle() {
113
113
  return R("div", { key: "edit", style: { marginBottom: this.state.editing ? 10 : undefined } }, R("a", { className: "link-plain", onClick: this.handleToggleEditing, style: { fontSize: 12 } }, this.state.editing
114
- ? [R("i", { className: "fa fa-caret-up" }), T ` Close`]
115
- : [R("i", { className: "fa fa-cog" }), T ` Customize...`]));
114
+ ? [R("i", { className: "fa fa-caret-up" }), " ", T `Close`]
115
+ : [R("i", { className: "fa fa-cog" }), " ", T `Customize...`]));
116
116
  }
117
117
  handleOpacityChange = (newValue) => {
118
118
  return this.update({ opacity: newValue / 100 });
@@ -19,3 +19,7 @@ export declare function getCompiledFilters(design: MapDesign, schema: Schema, fi
19
19
  table: string;
20
20
  jsonql: JsonQLExpr;
21
21
  }[];
22
+ /**
23
+ * Get a list of translatable strings in the map design
24
+ */
25
+ export declare function getTranslatableStrings(design: MapDesign, schema: Schema): string[];
@@ -10,6 +10,7 @@ exports.convertToClusterMap = convertToClusterMap;
10
10
  exports.convertToMarkersMap = convertToMarkersMap;
11
11
  exports.getFilterableTables = getFilterableTables;
12
12
  exports.getCompiledFilters = getCompiledFilters;
13
+ exports.getTranslatableStrings = getTranslatableStrings;
13
14
  const lodash_1 = __importDefault(require("lodash"));
14
15
  const expressions_1 = require("@mwater/expressions");
15
16
  const LayerFactory_1 = __importDefault(require("./LayerFactory"));
@@ -116,3 +117,21 @@ function getCompiledFilters(design, schema, filterableTables) {
116
117
  }
117
118
  return compiledFilters;
118
119
  }
120
+ /**
121
+ * Get a list of translatable strings in the map design
122
+ */
123
+ function getTranslatableStrings(design, schema) {
124
+ const strings = [];
125
+ // Iterate through each layer view in the design
126
+ for (const layerView of design.layerViews) {
127
+ // Name of the layer is translatable
128
+ strings.push(layerView.name);
129
+ // Create the layer using the LayerFactory
130
+ const layer = LayerFactory_1.default.createLayer(layerView.type);
131
+ // Get the translatable strings from the layer design
132
+ const layerStrings = layer.getTranslatableStrings(layerView.design, schema);
133
+ strings.push(...layerStrings);
134
+ }
135
+ // Remove duplicates
136
+ return lodash_1.default.uniq(strings);
137
+ }