@mwater/visualization 5.4.1 → 5.4.3

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 (273) 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 +12 -20
  21. package/lib/dashboards/DashboardComponent.js +109 -69
  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/languages.js +6 -1
  47. package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
  48. package/lib/mWaterLoader.d.ts +1 -1
  49. package/lib/maps/BufferLayer.d.ts +7 -5
  50. package/lib/maps/BufferLayer.js +69 -48
  51. package/lib/maps/BufferLayerDesign.d.ts +21 -14
  52. package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
  53. package/lib/maps/BufferLayerDesignerComponent.js +68 -102
  54. package/lib/maps/ChoroplethLayer.d.ts +5 -4
  55. package/lib/maps/ChoroplethLayer.js +32 -9
  56. package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
  57. package/lib/maps/ChoroplethLayerDesigner.js +4 -2
  58. package/lib/maps/ClusterLayer.d.ts +3 -4
  59. package/lib/maps/ClusterLayer.js +2 -1
  60. package/lib/maps/DetailLevelSelectComponent.js +1 -1
  61. package/lib/maps/DirectMapDataSource.js +2 -1
  62. package/lib/maps/EditPopupComponent.js +5 -3
  63. package/lib/maps/GridLayer.d.ts +3 -4
  64. package/lib/maps/GridLayer.js +2 -1
  65. package/lib/maps/GridLayerDesigner.js +5 -3
  66. package/lib/maps/HoverContent.d.ts +11 -3
  67. package/lib/maps/HoverContent.js +25 -9
  68. package/lib/maps/Layer.d.ts +24 -3
  69. package/lib/maps/Layer.js +5 -1
  70. package/lib/maps/LayerFactory.js +0 -8
  71. package/lib/maps/LayerLegendComponent.js +0 -1
  72. package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
  73. package/lib/maps/LayerSwitcherComponent.js +1 -1
  74. package/lib/maps/LeafletMapComponent.js +3 -1
  75. package/lib/maps/LegendComponent.d.ts +1 -0
  76. package/lib/maps/LegendComponent.js +9 -1
  77. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  78. package/lib/maps/MWaterServerLayer.js +2 -2
  79. package/lib/maps/MapComponent.js +3 -3
  80. package/lib/maps/MapDesign.d.ts +2 -0
  81. package/lib/maps/MapDesignerComponent.d.ts +4 -3
  82. package/lib/maps/MapDesignerComponent.js +68 -74
  83. package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
  84. package/lib/maps/MapUtils.d.ts +4 -0
  85. package/lib/maps/MapUtils.js +19 -0
  86. package/lib/maps/MapViewComponent.d.ts +8 -3
  87. package/lib/maps/MarkersLayer.d.ts +5 -4
  88. package/lib/maps/MarkersLayer.js +33 -7
  89. package/lib/maps/MarkersLayerDesign.d.ts +19 -16
  90. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
  91. package/lib/maps/PopupFilterJoinsUtils.js +0 -6
  92. package/lib/maps/RasterMapViewComponent.d.ts +3 -31
  93. package/lib/maps/RasterMapViewComponent.js +7 -2
  94. package/lib/maps/ServerMapDataSource.js +2 -1
  95. package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
  96. package/lib/maps/SwitchableTileUrlLayer.js +2 -1
  97. package/lib/maps/TileUrlLayer.d.ts +4 -5
  98. package/lib/maps/TileUrlLayer.js +2 -1
  99. package/lib/maps/VectorMapViewComponent.d.ts +5 -37
  100. package/lib/maps/VectorMapViewComponent.js +19 -8
  101. package/lib/maps/maps.d.ts +3 -0
  102. package/lib/quickfilter/Quickfilter.d.ts +2 -0
  103. package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
  104. package/lib/quickfilter/QuickfiltersComponent.js +9 -7
  105. package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +5 -30
  106. package/lib/quickfilter/QuickfiltersDesignComponent.js +56 -63
  107. package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
  108. package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
  109. package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
  110. package/lib/richtext/ExprItemsTranslator.js +149 -0
  111. package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
  112. package/lib/richtext/ItemsHtmlConverter.js +31 -15
  113. package/lib/wellknown.js +12 -9
  114. package/lib/widgets/IFrameWidget.d.ts +4 -4
  115. package/lib/widgets/ImageWidget.d.ts +7 -4
  116. package/lib/widgets/ImageWidget.js +9 -1
  117. package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
  118. package/lib/widgets/ImageWidgetComponent.js +1 -1
  119. package/lib/widgets/MapWidget.d.ts +5 -48
  120. package/lib/widgets/MapWidget.js +26 -63
  121. package/lib/widgets/MarkdownWidget.d.ts +3 -0
  122. package/lib/widgets/MarkdownWidget.js +3 -0
  123. package/lib/widgets/TOCWidget.d.ts +15 -27
  124. package/lib/widgets/TOCWidget.js +107 -183
  125. package/lib/widgets/Widget.d.ts +18 -7
  126. package/lib/widgets/Widget.js +4 -0
  127. package/lib/widgets/WidgetScopesViewComponent.js +1 -1
  128. package/lib/widgets/charts/Chart.d.ts +10 -1
  129. package/lib/widgets/charts/Chart.js +22 -11
  130. package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
  131. package/lib/widgets/charts/ChartViewComponent.js +6 -3
  132. package/lib/widgets/charts/ChartWidget.d.ts +2 -0
  133. package/lib/widgets/charts/ChartWidget.js +9 -1
  134. package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
  135. package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
  136. package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
  137. package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
  138. package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
  139. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
  140. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
  141. package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
  142. package/lib/widgets/charts/layered/LayeredChart.js +63 -3
  143. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
  144. package/lib/widgets/charts/layered/LayeredChartCompiler.js +1 -1
  145. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
  146. package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
  147. package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
  148. package/lib/widgets/charts/pivot/PivotChart.js +63 -0
  149. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
  150. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
  151. package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
  152. package/lib/widgets/charts/table/TableChart.d.ts +1 -0
  153. package/lib/widgets/charts/table/TableChart.js +15 -0
  154. package/lib/widgets/text/TextComponent.d.ts +11 -4
  155. package/lib/widgets/text/TextComponent.js +11 -8
  156. package/lib/widgets/text/TextWidget.d.ts +6 -3
  157. package/lib/widgets/text/TextWidget.js +7 -1
  158. package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
  159. package/lib/widgets/text/TextWidgetComponent.js +7 -1
  160. package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
  161. package/lib/widgets/text/TextWidgetDesign.js +1 -1
  162. package/package.json +7 -8
  163. package/src/ColorComponent.tsx +1 -2
  164. package/src/IdSelection.ts +62 -0
  165. package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
  166. package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
  167. package/src/MWaterLoaderComponent.ts +28 -26
  168. package/src/MWaterResponsesFilterComponent.ts +5 -2
  169. package/src/MWaterTableSelectComponent.tsx +5 -9
  170. package/src/autotranslate.ts +141 -0
  171. package/src/axes/AxisBuilder.ts +3 -3
  172. package/src/axes/AxisColorEditorComponent.tsx +5 -0
  173. package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
  174. package/src/axes/CategoryMapComponent.ts +4 -4
  175. package/src/axes/RangesComponent.ts +3 -2
  176. package/src/dashboards/DashboardComponent.tsx +189 -125
  177. package/src/dashboards/DashboardDesign.ts +9 -2
  178. package/src/dashboards/DashboardUtils.ts +39 -0
  179. package/src/dashboards/DashboardViewComponent.tsx +22 -3
  180. package/src/dashboards/ServerDashboardDataSource.ts +2 -1
  181. package/src/dashboards/SettingsModalComponent.tsx +450 -35
  182. package/src/dashboards/WidgetComponent.tsx +12 -6
  183. package/src/datagrids/CellEditor.tsx +354 -0
  184. package/src/datagrids/DatagridComponent.tsx +646 -0
  185. package/src/datagrids/DatagridViewComponent.tsx +539 -0
  186. package/src/datagrids/DirectDatagridDataSource.ts +2 -3
  187. package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
  188. package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
  189. package/src/index.css +1 -1
  190. package/src/index.ts +0 -1
  191. package/src/languages.ts +6 -1
  192. package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
  193. package/src/mWaterLoader.ts +1 -1
  194. package/src/maps/BufferLayer.ts +83 -60
  195. package/src/maps/BufferLayerDesign.ts +20 -14
  196. package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
  197. package/src/maps/ChoroplethLayer.ts +40 -19
  198. package/src/maps/ChoroplethLayerDesign.ts +4 -2
  199. package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
  200. package/src/maps/ClusterLayer.ts +4 -10
  201. package/src/maps/DetailLevelSelectComponent.ts +1 -1
  202. package/src/maps/DirectMapDataSource.ts +2 -1
  203. package/src/maps/EditPopupComponent.ts +7 -3
  204. package/src/maps/GridLayer.ts +4 -10
  205. package/src/maps/GridLayerDesigner.tsx +5 -3
  206. package/src/maps/HoverContent.tsx +40 -16
  207. package/src/maps/Layer.ts +28 -10
  208. package/src/maps/LayerFactory.ts +0 -8
  209. package/src/maps/LayerLegendComponent.ts +2 -4
  210. package/src/maps/LayerSwitcherComponent.tsx +6 -2
  211. package/src/maps/LeafletMapComponent.tsx +3 -1
  212. package/src/maps/LegendComponent.tsx +10 -1
  213. package/src/maps/MWaterServerLayer.ts +3 -3
  214. package/src/maps/MapComponent.ts +3 -3
  215. package/src/maps/MapDesign.ts +3 -0
  216. package/src/maps/MapDesignerComponent.tsx +165 -162
  217. package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
  218. package/src/maps/MapUtils.ts +24 -0
  219. package/src/maps/MapViewComponent.tsx +11 -3
  220. package/src/maps/MarkersLayer.ts +44 -18
  221. package/src/maps/MarkersLayerDesign.ts +19 -16
  222. package/src/maps/PopupFilterJoinsUtils.ts +6 -2
  223. package/src/maps/RasterMapViewComponent.ts +9 -45
  224. package/src/maps/ServerMapDataSource.ts +2 -2
  225. package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
  226. package/src/maps/TileUrlLayer.tsx +4 -10
  227. package/src/maps/VectorMapViewComponent.tsx +28 -55
  228. package/src/maps/maps.ts +3 -0
  229. package/src/quickfilter/Quickfilter.ts +3 -0
  230. package/src/quickfilter/QuickfiltersComponent.ts +13 -7
  231. package/src/quickfilter/QuickfiltersDesignComponent.tsx +127 -128
  232. package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
  233. package/src/richtext/ExprItemsTranslator.ts +176 -0
  234. package/src/richtext/ItemsHtmlConverter.ts +33 -18
  235. package/src/wellknown.ts +33 -30
  236. package/src/widgets/ImageWidget.ts +10 -1
  237. package/src/widgets/ImageWidgetComponent.ts +3 -2
  238. package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
  239. package/src/widgets/MarkdownWidget.ts +3 -0
  240. package/src/widgets/TOCWidget.tsx +281 -0
  241. package/src/widgets/Widget.ts +25 -5
  242. package/src/widgets/WidgetScopesViewComponent.ts +2 -1
  243. package/src/widgets/charts/Chart.ts +31 -12
  244. package/src/widgets/charts/ChartViewComponent.ts +13 -3
  245. package/src/widgets/charts/ChartWidget.ts +11 -1
  246. package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
  247. package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
  248. package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
  249. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
  250. package/src/widgets/charts/layered/LayeredChart.ts +71 -3
  251. package/src/widgets/charts/layered/LayeredChartCompiler.ts +2 -2
  252. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
  253. package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
  254. package/src/widgets/charts/pivot/PivotChart.ts +73 -0
  255. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
  256. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
  257. package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
  258. package/src/widgets/charts/table/TableChart.ts +17 -0
  259. package/src/widgets/text/TextComponent.tsx +22 -12
  260. package/src/widgets/text/TextWidget.ts +9 -2
  261. package/src/widgets/text/TextWidgetComponent.tsx +16 -1
  262. package/src/widgets/text/TextWidgetDesign.ts +4 -7
  263. package/test/IdSelectionTests.ts +54 -0
  264. package/test/LayeredChartCompilerTests.ts +0 -2
  265. package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
  266. package/test/wellknownTests.ts +144 -0
  267. package/src/datagrids/DatagridComponent.ts +0 -478
  268. package/src/datagrids/DatagridViewComponent.ts +0 -464
  269. package/src/datagrids/EditExprCellComponent.tsx +0 -305
  270. package/src/datagrids/README.md +0 -3
  271. package/src/maps/BufferLayerDesignerComponent.ts +0 -311
  272. package/src/widgets/TOCWidget.ts +0 -326
  273. package/test/LegoLayoutEngineTests.ts +0 -69
@@ -28,7 +28,6 @@ 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 UndoStack_1 = __importDefault(require("../UndoStack"));
33
32
  const DashboardUtils = __importStar(require("./DashboardUtils"));
34
33
  const DashboardViewComponent_1 = __importDefault(require("./DashboardViewComponent"));
@@ -39,6 +38,7 @@ const LayoutManager_1 = __importDefault(require("../layouts/LayoutManager"));
39
38
  const LayoutOptionsComponent_1 = require("./LayoutOptionsComponent");
40
39
  const ModalWindowComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalWindowComponent"));
41
40
  const layoutOptions_1 = require("./layoutOptions");
41
+ const __1 = require("..");
42
42
  const expressions_ui_1 = require("@mwater/expressions-ui");
43
43
  /** Dashboard component that includes an action bar at the top
44
44
  * Manages undo stack and quickfilter value
@@ -50,6 +50,15 @@ class DashboardComponent extends react_1.default.Component {
50
50
  constructor(props) {
51
51
  super(props);
52
52
  const layoutOptions = (0, layoutOptions_1.getLayoutOptions)(props.design);
53
+ // Prefer the T.en locale if available when loading the dashboard
54
+ let initialLocale = props.design.locale || "en";
55
+ const otherLocales = props.design.otherLocales || [];
56
+ if (props.preferredLocale && otherLocales.includes(props.preferredLocale)) {
57
+ initialLocale = props.preferredLocale;
58
+ }
59
+ else if (otherLocales.includes(T.locale)) {
60
+ initialLocale = T.locale;
61
+ }
53
62
  this.state = {
54
63
  undoStack: new UndoStack_1.default().push(props.design),
55
64
  quickfiltersValues: props.quickfiltersValues || null,
@@ -57,7 +66,8 @@ class DashboardComponent extends react_1.default.Component {
57
66
  props.onDesignChange != null,
58
67
  layoutOptionsOpen: false,
59
68
  hideQuickfilters: layoutOptions.hideQuickfiltersWidth != null && layoutOptions.hideQuickfiltersWidth > document.body.clientWidth,
60
- refreshKey: 1
69
+ refreshKey: 1,
70
+ locale: initialLocale
61
71
  };
62
72
  if (props.onEditModeChange) {
63
73
  props.onEditModeChange(this.state.editing);
@@ -141,58 +151,108 @@ class DashboardComponent extends react_1.default.Component {
141
151
  compiledFilters = compiledFilters.concat(this.props.filters || []);
142
152
  return compiledFilters;
143
153
  }
154
+ /** Translate function to use for display. Do not use when editing. */
155
+ translate = (input) => {
156
+ const designLocale = this.props.design.locale ?? "en";
157
+ const displayLocale = this.state.editing ? designLocale : (this.state.locale ?? designLocale ?? "en");
158
+ if (designLocale === displayLocale) {
159
+ return input;
160
+ }
161
+ return this.props.design.translations?.[displayLocale]?.[input] ?? input;
162
+ };
144
163
  renderEditingSwitch() {
145
- return R("a", {
146
- key: "edit",
147
- className: `btn btn-primary btn-sm ${this.state.editing ? "active" : ""}`,
148
- onClick: this.handleToggleEditing
149
- }, R("span", { className: "fas fa-pencil-alt" }), this.state.editing ? T ` Editing` : T ` Edit`);
164
+ return (react_1.default.createElement("a", { key: "edit", className: `btn btn-primary btn-sm ${this.state.editing ? "active" : ""}`, onClick: this.handleToggleEditing },
165
+ react_1.default.createElement("span", { className: "fas fa-pencil-alt" }),
166
+ " ",
167
+ this.state.editing ? T `Editing` : T `Edit`));
150
168
  }
151
169
  renderStyle() {
152
- return R("button", { type: "button", key: "style", className: "btn btn-link btn-sm", onClick: this.handleOpenLayoutOptions }, R("span", { className: "fa fa-mobile" }), R("span", { className: "hide-600px" }, T ` Layout `));
170
+ return (react_1.default.createElement("button", { type: "button", key: "style", className: "btn btn-link btn-sm", onClick: this.handleOpenLayoutOptions },
171
+ react_1.default.createElement("span", { className: "fa fa-mobile" }),
172
+ react_1.default.createElement("span", { className: "hide-600px" },
173
+ " ",
174
+ T `Layout`)));
153
175
  }
154
176
  renderActionLinks() {
155
- return R("div", null, this.state.editing
156
- ? [
157
- R("a", {
158
- key: "undo",
159
- className: `btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`,
160
- onClick: this.handleUndo
161
- }, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, T ` Undo`)),
162
- " ",
163
- R("a", {
164
- key: "redo",
165
- className: `btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`,
166
- onClick: this.handleRedo
167
- }, R("span", { className: "fas fa-caret-right" }), R("span", { className: "hide-600px" }, T ` Redo`))
168
- ]
169
- : undefined, R("a", { key: "print", className: "btn btn-link btn-sm", onClick: this.handlePrint }, R("span", { className: "fas fa-print" }), R("span", { className: "hide-600px" }, T ` Print`)), R("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData }, R("span", { className: "fas fa-sync" }), R("span", { className: "hide-600px" }, T ` Refresh`)), this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
170
- ? 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`))
171
- : undefined,
172
- // R 'a', key: "export", className: "btn btn-link btn-sm", onClick: @handleSaveDesignFile,
173
- // R('span', className: "glyphicon glyphicon-download-alt")
174
- // " Export"
175
- this.state.editing
176
- ? R("a", { key: "settings", className: "btn btn-link btn-sm", onClick: this.handleSettings }, R("span", { className: "fas fa-cog" }), R("span", { className: "hide-600px" }, T ` Settings`))
177
- : undefined, this.state.editing ? this.renderStyle() : undefined, this.props.extraTitleButtonsElem, this.props.onDesignChange != null ? this.renderEditingSwitch() : undefined);
177
+ return (react_1.default.createElement("div", null,
178
+ this.state.editing
179
+ ? [
180
+ react_1.default.createElement("a", { key: "undo", className: `btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`, onClick: this.handleUndo },
181
+ react_1.default.createElement("span", { className: "fas fa-caret-left" }),
182
+ react_1.default.createElement("span", { className: "hide-600px" },
183
+ " ",
184
+ T `Undo`)),
185
+ " ",
186
+ react_1.default.createElement("a", { key: "redo", className: `btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`, onClick: this.handleRedo },
187
+ react_1.default.createElement("span", { className: "fas fa-caret-right" }),
188
+ react_1.default.createElement("span", { className: "hide-600px" },
189
+ " ",
190
+ T `Redo`))
191
+ ]
192
+ : undefined,
193
+ !this.state.editing && this.props.design.otherLocales && this.props.design.otherLocales.length > 0
194
+ ? react_1.default.createElement("div", { key: "translations", className: "dropdown d-inline-block" },
195
+ react_1.default.createElement("a", { className: "btn btn-link btn-sm dropdown-toggle", "data-bs-toggle": "dropdown" },
196
+ react_1.default.createElement("span", { className: "fal fa-globe" }),
197
+ " ",
198
+ this.state.locale),
199
+ 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("a", { className: "dropdown-item", onClick: () => this.setState({ locale: locale }) }, __1.languages.find(l => l.code === locale)?.name || locale)))))
201
+ : undefined,
202
+ react_1.default.createElement("a", { key: "print", className: "btn btn-link btn-sm", onClick: this.handlePrint },
203
+ react_1.default.createElement("span", { className: "fas fa-print" }),
204
+ react_1.default.createElement("span", { className: "hide-600px" },
205
+ " ",
206
+ T `Print`)),
207
+ react_1.default.createElement("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData },
208
+ react_1.default.createElement("span", { className: "fas fa-sync" }),
209
+ react_1.default.createElement("span", { className: "hide-600px" },
210
+ " ",
211
+ T `Refresh`)),
212
+ this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
213
+ ? react_1.default.createElement("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters },
214
+ react_1.default.createElement("span", { className: "fa fa-filter" }),
215
+ react_1.default.createElement("span", { className: "hide-600px" },
216
+ " ",
217
+ T `Show Quickfilters`))
218
+ : undefined,
219
+ this.state.editing
220
+ ? react_1.default.createElement("a", { key: "settings", className: "btn btn-link btn-sm", onClick: this.handleSettings },
221
+ react_1.default.createElement("span", { className: "fas fa-cog" }),
222
+ react_1.default.createElement("span", { className: "hide-600px" },
223
+ " ",
224
+ T `Settings`))
225
+ : undefined,
226
+ this.state.editing ? this.renderStyle() : undefined,
227
+ this.props.extraTitleButtonsElem,
228
+ this.props.onDesignChange != null ? this.renderEditingSwitch() : undefined));
178
229
  }
179
230
  renderTitleBar() {
180
- return R("div", { style: { height: 40, padding: 4 } }, R("div", { style: { float: "right" } }, this.renderActionLinks()), this.props.titleElem);
231
+ return (react_1.default.createElement("div", { style: { height: 40, padding: 4 } },
232
+ react_1.default.createElement("div", { style: { float: "right" } }, this.renderActionLinks()),
233
+ this.props.titleElem));
181
234
  }
182
235
  renderQuickfilter() {
183
- return R(QuickfiltersComponent_1.default, {
184
- design: this.props.design.quickfilters || [],
185
- schema: this.props.schema,
186
- dataSource: this.props.dataSource,
187
- quickfiltersDataSource: this.props.dashboardDataSource.getQuickfiltersDataSource(),
188
- values: this.state.quickfiltersValues || undefined,
189
- onValuesChange: (values) => this.setState({ quickfiltersValues: values }),
190
- locks: this.props.quickfilterLocks,
191
- filters: this.getCompiledFilters(),
192
- hideTopBorder: this.props.hideTitleBar,
236
+ return react_1.default.createElement(QuickfiltersComponent_1.default, { design: this.props.design.quickfilters || [], schema: this.props.schema, dataSource: this.props.dataSource, quickfiltersDataSource: this.props.dashboardDataSource.getQuickfiltersDataSource(), values: this.state.quickfiltersValues || undefined, onValuesChange: (values) => this.setState({ quickfiltersValues: values }), locks: this.props.quickfilterLocks, filters: this.getCompiledFilters(), hideTopBorder: this.props.hideTitleBar,
193
237
  // Don't hide if title bar is hidden as it can't be shown again
194
- onHide: () => !this.props.hideTitleBar ? this.setState({ hideQuickfilters: true }) : undefined
195
- });
238
+ onHide: () => this.setState({ hideQuickfilters: true }), translate: this.translate });
239
+ }
240
+ renderFloatingShowQuickfiltersButton() {
241
+ // Only show if:
242
+ // 1. Quick filters exist
243
+ // 2. Quick filters are hidden
244
+ // 3. Title bar is hidden (since otherwise button is in title bar)
245
+ if (!this.props.design.quickfilters?.length || !this.state.hideQuickfilters || !this.props.hideTitleBar) {
246
+ return null;
247
+ }
248
+ return (react_1.default.createElement("div", { style: {
249
+ position: "absolute",
250
+ top: 5,
251
+ right: 20,
252
+ zIndex: 1000
253
+ } },
254
+ react_1.default.createElement("button", { className: "btn btn-link btn-sm", onClick: () => this.setState({ hideQuickfilters: false }) },
255
+ react_1.default.createElement("i", { className: "fa fa-angle-double-down" }))));
196
256
  }
197
257
  refDashboardView = (el) => {
198
258
  this.dashboardView = el;
@@ -201,33 +261,12 @@ class DashboardComponent extends react_1.default.Component {
201
261
  let filters = this.props.filters || [];
202
262
  // Compile quickfilters
203
263
  filters = filters.concat(new QuickfilterCompiler_1.default(this.props.schema).compile(this.props.design.quickfilters || [], this.state.quickfiltersValues, this.props.quickfilterLocks));
204
- const dashboardView = R(DashboardViewComponent_1.default, {
205
- schema: this.props.schema,
206
- dataSource: this.props.dataSource,
207
- dashboardDataSource: this.props.dashboardDataSource,
208
- ref: this.refDashboardView,
209
- design: this.props.design,
210
- onDesignChange: this.state.editing ? this.props.onDesignChange : undefined,
211
- filters,
212
- onRowClick: this.props.onRowClick,
213
- namedStrings: this.props.namedStrings,
214
- hideScopes: this.state.hideQuickfilters,
215
- refreshKey: this.state.refreshKey
216
- });
217
- const readonlyDashboardView = R(DashboardViewComponent_1.default, {
218
- schema: this.props.schema,
219
- dataSource: this.props.dataSource,
220
- dashboardDataSource: this.props.dashboardDataSource,
221
- ref: this.refDashboardView,
222
- design: this.props.design,
223
- filters,
224
- onRowClick: this.props.onRowClick,
225
- namedStrings: this.props.namedStrings,
226
- hideScopes: this.state.hideQuickfilters
227
- });
264
+ const displayLocale = this.state.editing ? this.props.design.locale || "en" : this.state.locale;
265
+ const dashboardView = react_1.default.createElement(DashboardViewComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, dashboardDataSource: this.props.dashboardDataSource, ref: this.refDashboardView, design: this.props.design, onDesignChange: this.state.editing ? this.props.onDesignChange : undefined, filters: filters, onRowClick: this.props.onRowClick, namedStrings: this.props.namedStrings, hideScopes: this.state.hideQuickfilters, refreshKey: this.state.refreshKey, locale: displayLocale });
266
+ const readonlyDashboardView = react_1.default.createElement(DashboardViewComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, dashboardDataSource: this.props.dashboardDataSource, ref: this.refDashboardView, design: this.props.design, filters: filters, onRowClick: this.props.onRowClick, namedStrings: this.props.namedStrings, hideScopes: this.state.hideQuickfilters, locale: displayLocale });
228
267
  // Pass active tables down to table select components so they can present a shorter list
229
268
  return react_1.default.createElement(expressions_ui_1.ActiveTablesContext.Provider, { value: DashboardUtils.getFilterableTables(this.props.design, this.props.schema) },
230
- react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: this.props.design.locale ?? "en" },
269
+ react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: displayLocale },
231
270
  react_1.default.createElement("div", { style: {
232
271
  display: "grid",
233
272
  gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
@@ -236,6 +275,7 @@ class DashboardComponent extends react_1.default.Component {
236
275
  !this.props.hideTitleBar ? this.renderTitleBar() : undefined,
237
276
  react_1.default.createElement("div", null, !this.state.hideQuickfilters ? this.renderQuickfilter() : undefined),
238
277
  dashboardView,
278
+ this.renderFloatingShowQuickfiltersButton(),
239
279
  this.props.onDesignChange != null && (react_1.default.createElement(SettingsModalComponent_1.default, { onDesignChange: this.handleDesignChange, schema: this.props.schema, dataSource: this.props.dataSource, ref: (c) => {
240
280
  this.settings = c;
241
281
  } })),
@@ -2,13 +2,14 @@ import { Quickfilter } from "../quickfilter/Quickfilter";
2
2
  import { Expr } from "@mwater/expressions";
3
3
  import { BlocksLayoutOptions, DashboardTheme } from "./layoutOptions";
4
4
  import { GlobalFilter } from "../GlobalFilter";
5
+ import { LayoutBlock } from "../layouts/blocks/blockUtils";
5
6
  /** Dashboard design
6
7
  * Each understands enough of the dashboard design to create widgets.
7
8
  * Widget refers to the widget itself, where *item* refers also to the layout and id that it has in the dashboard.
8
9
  */
9
10
  export interface DashboardDesign {
10
11
  /** dashboard items. Format depends on layout of dashboard. See layouts/.../README.md */
11
- items: any;
12
+ items: LayoutBlock;
12
13
  /** array of quick filters (user-selectable filters). See quickfilter/README.md */
13
14
  quickfilters?: Quickfilter[];
14
15
  /** layout engine to use (`blocks` is new default) */
@@ -21,8 +22,16 @@ export interface DashboardDesign {
21
22
  filters?: {
22
23
  [tableId: string]: Expr;
23
24
  };
24
- /** optional locale (e.g. "fr") to use for display */
25
+ /** optional locale (e.g. "fr") to use for display. Defaults to "en" */
25
26
  locale?: string;
27
+ /** Other locales that the dashboard is available in. */
28
+ otherLocales?: string[];
29
+ /** Translation map for dashboard. Maps locale to translation map. Does not include default locale. */
30
+ translations?: {
31
+ [locale: string]: {
32
+ [key: string]: string;
33
+ };
34
+ };
26
35
  /** true to enable implicit filtering (see ImplicitFilterBuilder). Defaults to true for older dashboards. */
27
36
  implicitFiltersEnabled?: boolean;
28
37
  /** array of global filters. See below. */
@@ -1,7 +1,12 @@
1
1
  import { Schema } from "@mwater/expressions";
2
2
  import { JsonQLFilter } from "..";
3
+ import LayoutManager from "../layouts/LayoutManager";
3
4
  import { DashboardDesign } from "./DashboardDesign";
4
5
  /** Gets filterable tables for a dashboard */
5
6
  export declare function getFilterableTables(design: DashboardDesign, schema: Schema): string[];
7
+ /** Gets all translatable strings from a dashboard */
8
+ export declare function getTranslatableStringsFromDashboard(design: DashboardDesign, schema: Schema): string[];
9
+ /** Gets translatable strings from a layout manager and items */
10
+ export declare function getTranslatableStringsFromLayoutManager(layoutManager: LayoutManager, items: any, schema: Schema): string[];
6
11
  /** Get filters from props filters combined with dashboard filters */
7
12
  export declare function getCompiledFilters(design: DashboardDesign, schema: Schema, filterableTables: string[]): JsonQLFilter[];
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getFilterableTables = getFilterableTables;
7
+ exports.getTranslatableStringsFromDashboard = getTranslatableStringsFromDashboard;
8
+ exports.getTranslatableStringsFromLayoutManager = getTranslatableStringsFromLayoutManager;
7
9
  exports.getCompiledFilters = getCompiledFilters;
8
10
  const lodash_1 = __importDefault(require("lodash"));
9
11
  const expressions_1 = require("@mwater/expressions");
@@ -24,6 +26,34 @@ function getFilterableTables(design, schema) {
24
26
  filterableTables = lodash_1.default.filter(lodash_1.default.uniq(filterableTables), (table) => schema.getTable(table));
25
27
  return filterableTables;
26
28
  }
29
+ /** Gets all translatable strings from a dashboard */
30
+ function getTranslatableStringsFromDashboard(design, schema) {
31
+ const layoutManager = LayoutManager_1.default.createLayoutManager(design.layout);
32
+ // Get translatable strings from layout manager
33
+ let strings = getTranslatableStringsFromLayoutManager(layoutManager, design.items, schema);
34
+ // Get translatable strings from quickfilters
35
+ if (design.quickfilters) {
36
+ for (let quickfilter of design.quickfilters) {
37
+ if (quickfilter.label) {
38
+ strings.push(quickfilter.label);
39
+ }
40
+ }
41
+ }
42
+ // Remove duplicates
43
+ return lodash_1.default.uniq(strings);
44
+ }
45
+ /** Gets translatable strings from a layout manager and items */
46
+ function getTranslatableStringsFromLayoutManager(layoutManager, items, schema) {
47
+ let strings = [];
48
+ for (let widgetItem of layoutManager.getAllWidgets(items)) {
49
+ // Create widget
50
+ const widget = WidgetFactory_1.default.createWidget(widgetItem.type);
51
+ // Get translatable strings
52
+ strings = strings.concat(widget.getTranslatableStrings(widgetItem.design, schema));
53
+ }
54
+ // Remove duplicates
55
+ return lodash_1.default.uniq(strings);
56
+ }
27
57
  /** Get filters from props filters combined with dashboard filters */
28
58
  function getCompiledFilters(design, schema, filterableTables) {
29
59
  let expr, jsonql, table;
@@ -30,6 +30,8 @@ export interface DashboardViewComponentProps {
30
30
  printMode?: boolean;
31
31
  /** Change to force a refresh */
32
32
  refreshKey?: any;
33
+ /** Locale to use for display. Defaults to dashboard design locale. */
34
+ locale?: string;
33
35
  }
34
36
  export interface DashboardViewComponentHandle {
35
37
  print: () => Promise<void>;
@@ -154,6 +154,17 @@ const DashboardViewComponent = react_1.default.forwardRef((props, ref) => {
154
154
  const renderScopes = () => {
155
155
  return (react_1.default.createElement(WidgetScopesViewComponent_1.default, { scopes: widgetScoper.getScopes(), onRemoveScope: handleRemoveScope }));
156
156
  };
157
+ /** Locale that the dashboard design is in */
158
+ const designLocale = props.design.locale ?? "en";
159
+ /** Locale to display the dashboard in. If editing, always use design locale. */
160
+ const displayLocale = props.onDesignChange != null ? designLocale : (props.locale ?? designLocale ?? "en");
161
+ /** Translate function to use for display. Do not use when editing. */
162
+ const translate = (0, react_1.useCallback)((input) => {
163
+ if (designLocale === displayLocale) {
164
+ return input;
165
+ }
166
+ return props.design.translations?.[displayLocale]?.[input] ?? input;
167
+ }, [props.design.translations, designLocale, displayLocale]);
157
168
  const compRef = (widgetId, comp) => {
158
169
  return (widgetComps.current[widgetId] = comp);
159
170
  };
@@ -180,9 +191,11 @@ const DashboardViewComponent = react_1.default.forwardRef((props, ref) => {
180
191
  const implicitFilterBuilder = new ImplicitFilterBuilder_1.default(props.schema);
181
192
  filters = implicitFilterBuilder.extendFilters(filterableTables, filters);
182
193
  }
183
- const widgetElem = (react_1.default.createElement(WidgetComponent_1.WidgetComponent, { key: options.id, id: options.id, type: options.type, schema: props.schema, dataSource: props.dataSource, widgetDataSource: widgetDataSource, design: options.design, scope: widgetScoper.getScope(options.id), filters: filters, onScopeChange: handleScopeChange.bind(null, options.id), onDesignChange: options.onDesignChange, width: options.width, height: options.height, onRowClick: props.onRowClick, namedStrings: props.namedStrings, tocEntries: tocEntries, onScrollToTOCEntry: handleScrollToTOCEntry,
194
+ const widgetElem = (react_1.default.createElement(WidgetComponent_1.WidgetComponent, { key: options.id, type: options.type, schema: props.schema, dataSource: props.dataSource, widgetDataSource: widgetDataSource, design: options.design, scope: widgetScoper.getScope(options.id), filters: filters, onScopeChange: handleScopeChange.bind(null, options.id), onDesignChange: options.onDesignChange, width: options.width, height: options.height, onRowClick: props.onRowClick, namedStrings: props.namedStrings, tocEntries: tocEntries, onScrollToTOCEntry: handleScrollToTOCEntry,
184
195
  // Keep references to widget elements
185
- widgetRef: compRef.bind(null, options.id), refreshKey: props.refreshKey }));
196
+ widgetRef: compRef.bind(null, options.id), refreshKey: props.refreshKey,
197
+ // Use locale from props, design, or default to en
198
+ locale: displayLocale, translate: translate }));
186
199
  return widgetElem;
187
200
  };
188
201
  const style = {
@@ -195,7 +208,7 @@ const DashboardViewComponent = react_1.default.forwardRef((props, ref) => {
195
208
  style.overflowX = "auto";
196
209
  }
197
210
  // Render widget container
198
- return (react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: props.design.locale ?? "en" },
211
+ return (react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: displayLocale },
199
212
  react_1.default.createElement("div", { style: style },
200
213
  !props.hideScopes ? renderScopes() : undefined,
201
214
  layoutManager.renderLayout({
@@ -273,7 +273,8 @@ class ServerWidgetLayerDataSource {
273
273
  throw new Error("Error getting tiles token");
274
274
  }
275
275
  const { token, expires } = await response.json();
276
- return { url: this.options.apiUrl + `vector_tiles/tiles/{z}/{x}/{y}?token=${token}`, expires };
276
+ // Client isn't necessary, but allows tracking of usage easier
277
+ return { url: this.options.apiUrl + `vector_tiles/tiles/{z}/{x}/{y}?token=${token}&client=${this.options.client ?? ""}`, expires };
277
278
  }
278
279
  // Gets widget data source for a popup widget
279
280
  getPopupWidgetDataSource(design, widgetId) {
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
3
  import { DashboardDesign } from "./DashboardDesign";
4
4
  export interface SettingsModalComponentProps {
5
- onDesignChange: any;
5
+ onDesignChange: (design: DashboardDesign) => void;
6
6
  schema: Schema;
7
7
  dataSource: DataSource;
8
8
  }