@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
@@ -26,146 +26,88 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const prop_types_1 = __importDefault(require("prop-types"));
30
- const react_1 = __importDefault(require("react"));
31
- const R = react_1.default.createElement;
29
+ const react_1 = __importStar(require("react"));
32
30
  const lodash_1 = __importDefault(require("lodash"));
33
31
  const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
34
- const update_1 = __importDefault(require("@mwater/react-library/lib/update"));
35
32
  const Widget_1 = __importDefault(require("./Widget"));
36
33
  const DropdownWidgetComponent_1 = __importDefault(require("./DropdownWidgetComponent"));
37
34
  const ModalPopupComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalPopupComponent"));
38
- // Table of contents widget that displays the h1, h2, etc entries from all text fields in one widget
39
- // design is:
40
- // header: text of header. Defaults to "Contents"
41
- // borderWeight: border weight. Defaults to 0=None. 1=light, 2=medium, 3=heavy
42
- // numbering: true/false for prepending numbering to entries (e.g. 3.4.1)
35
+ const immer_1 = __importDefault(require("immer"));
36
+ /**
37
+ * Table of contents widget that displays the h1, h2, etc entries from all text fields in one widget
38
+ */
43
39
  class TOCWidget extends Widget_1.default {
44
- // Creates a React element that is a view of the widget
45
- // options:
46
- // schema: schema to use
47
- // dataSource: data source to use
48
- // widgetDataSource: Gives data to the widget in a way that allows client-server separation and secure sharing. See definition in WidgetDataSource.
49
- // design: widget design
50
- // scope: scope of the widget (when the widget self-selects a particular scope)
51
- // filters: array of filters to apply. Each is { table: table id, jsonql: jsonql condition with {alias} for tableAlias. Use injectAlias to correct
52
- // onScopeChange: called with scope of widget
53
- // onDesignChange: called with new design. null/undefined for readonly
54
- // width: width in pixels on screen
55
- // height: height in pixels on screen
56
- // tocEntries: entries in the table of contents
57
- // onScrollToTOCEntry: called with (widgetId, tocEntryId) to scroll to TOC entry
40
+ /** Creates a React element that is a view of the widget */
58
41
  createViewElement(options) {
59
- return R(TOCWidgetComponent, {
60
- design: options.design,
61
- onDesignChange: options.onDesignChange,
62
- width: options.width,
63
- height: options.height,
64
- tocEntries: options.tocEntries,
65
- onScrollToTOCEntry: options.onScrollToTOCEntry
66
- });
42
+ return react_1.default.createElement(TOCWidgetComponent, { design: options.design, onDesignChange: options.onDesignChange ?? undefined, width: options.width, height: options.height, tocEntries: options.tocEntries, onScrollToTOCEntry: options.onScrollToTOCEntry, translate: options.translate });
67
43
  }
68
44
  // Determine if widget is auto-height, which means that a vertical height is not required.
69
45
  isAutoHeight() {
70
46
  return true;
71
47
  }
48
+ getTranslatableStrings(design, schema) {
49
+ const strings = [];
50
+ if (design.header) {
51
+ strings.push(design.header);
52
+ }
53
+ return strings;
54
+ }
72
55
  }
73
56
  exports.default = TOCWidget;
74
- class TOCWidgetComponent extends react_1.default.Component {
75
- static propTypes = {
76
- design: prop_types_1.default.object.isRequired, // See Map Design.md
77
- onDesignChange: prop_types_1.default.func, // Called with new design. null/undefined for readonly
78
- width: prop_types_1.default.number,
79
- height: prop_types_1.default.number,
80
- tocEntries: prop_types_1.default.arrayOf(prop_types_1.default.shape({
81
- id: prop_types_1.default.any,
82
- widgetId: prop_types_1.default.string.isRequired,
83
- level: prop_types_1.default.number.isRequired,
84
- text: prop_types_1.default.string.isRequired
85
- })),
86
- onScrollToTOCEntry: prop_types_1.default.func
87
- };
88
- constructor(props) {
89
- super(props);
90
- this.state = {
91
- editing: false // true if editing
92
- };
93
- }
94
- handleStartEditing = () => {
95
- return this.setState({ editing: true });
57
+ function TOCWidgetComponent(props) {
58
+ const { design, onDesignChange, width, height, tocEntries, onScrollToTOCEntry, translate } = props;
59
+ const [editing, setEditing] = (0, react_1.useState)(false);
60
+ const handleStartEditing = () => {
61
+ setEditing(true);
96
62
  };
97
- handleEndEditing = () => {
98
- return this.setState({ editing: false });
63
+ const handleEndEditing = () => {
64
+ setEditing(false);
99
65
  };
100
- renderEditor() {
101
- if (!this.state.editing) {
66
+ const renderEditor = () => {
67
+ if (!editing) {
102
68
  return null;
103
69
  }
104
70
  // Create editor
105
- const editor = R(TOCWidgetDesignerComponent, {
106
- design: this.props.design,
107
- onDesignChange: this.props.onDesignChange
108
- });
109
- return R(ModalPopupComponent_1.default, {
110
- showCloseX: true,
111
- header: T `Table of Contents Options`,
112
- onClose: this.handleEndEditing
113
- }, editor);
114
- }
115
- renderContent() {
116
- return R(TOCWidgetViewComponent, {
117
- design: this.props.design,
118
- onDesignChange: this.props.onDesignChange,
119
- width: this.props.width,
120
- height: this.props.height,
121
- tocEntries: this.props.tocEntries,
122
- onScrollToTOCEntry: this.props.onScrollToTOCEntry
123
- });
124
- }
125
- render() {
126
- const dropdownItems = [];
127
- if (this.props.onDesignChange != null) {
128
- dropdownItems.push({ label: T `Edit`, icon: "pencil", onClick: this.handleStartEditing });
129
- }
130
- // Wrap in a simple widget
131
- return R("div", { onDoubleClick: this.handleStartEditing }, this.props.onDesignChange != null ? this.renderEditor() : undefined, R(DropdownWidgetComponent_1.default, {
132
- width: this.props.width,
133
- height: this.props.height,
134
- dropdownItems
135
- }, this.renderContent()));
71
+ const editor = react_1.default.createElement(TOCWidgetDesignerComponent, { design: design, onDesignChange: onDesignChange });
72
+ return react_1.default.createElement(ModalPopupComponent_1.default, { showCloseX: true, header: T `Table of Contents Options`, onClose: handleEndEditing }, editor);
73
+ };
74
+ const renderContent = () => {
75
+ return react_1.default.createElement(TOCWidgetViewComponent, { design: design, onDesignChange: onDesignChange, width: width, height: height, tocEntries: tocEntries, onScrollToTOCEntry: onScrollToTOCEntry, translate: translate });
76
+ };
77
+ const dropdownItems = [];
78
+ if (onDesignChange != null) {
79
+ dropdownItems.push({ label: T `Edit`, icon: "pencil", onClick: handleStartEditing });
136
80
  }
81
+ // Wrap in a simple widget
82
+ return react_1.default.createElement("div", { onDoubleClick: handleStartEditing },
83
+ onDesignChange != null ? renderEditor() : undefined,
84
+ react_1.default.createElement(DropdownWidgetComponent_1.default, { width: width, height: height, dropdownItems: dropdownItems }, renderContent()));
137
85
  }
138
86
  // Displays the contents of the widget
139
- class TOCWidgetViewComponent extends react_1.default.Component {
140
- static propTypes = {
141
- design: prop_types_1.default.object.isRequired, // Design of chart
142
- onDesignChange: prop_types_1.default.func, // Called with new design. null/undefined for readonly
143
- width: prop_types_1.default.number,
144
- height: prop_types_1.default.number,
145
- tocEntries: prop_types_1.default.arrayOf(prop_types_1.default.shape({
146
- id: prop_types_1.default.any,
147
- widgetId: prop_types_1.default.string.isRequired,
148
- level: prop_types_1.default.number.isRequired,
149
- text: prop_types_1.default.string.isRequired
150
- })),
151
- onScrollToTOCEntry: prop_types_1.default.func
87
+ function TOCWidgetViewComponent(props) {
88
+ const { design, onDesignChange, width, height, tocEntries, onScrollToTOCEntry, translate } = props;
89
+ const handleEntryClick = (tocEntry) => {
90
+ return onScrollToTOCEntry?.(tocEntry.widgetId, tocEntry.id);
152
91
  };
153
- handleEntryClick = (tocEntry) => {
154
- return this.props.onScrollToTOCEntry?.(tocEntry.widgetId, tocEntry.id);
155
- };
156
- renderTOCEntry(tocEntry, index) {
92
+ const renderTOCEntry = (tocEntry, index) => {
157
93
  // Find indentation number (e.g "1.3.2") by counting # backwards that are same level with no level lower
158
94
  let level;
159
95
  let indentation = "";
160
- if (this.props.design.numbering) {
161
- let asc, end;
162
- for (level = 1, end = tocEntry.level, asc = 1 <= end; asc ? level <= end : level >= end; asc ? level++ : level--) {
96
+ if (design.numbering) {
97
+ // For each level up to the current entry's level
98
+ for (let level = 1; level <= tocEntry.level; level++) {
163
99
  let value = 0;
164
- for (let i2 = 0, end1 = index, asc1 = 0 <= end1; asc1 ? i2 <= end1 : i2 >= end1; asc1 ? i2++ : i2--) {
165
- if (this.props.tocEntries[i2].level === level) {
166
- value += 1;
100
+ // Count entries at this level up to current index
101
+ for (let i = 0; i <= index; i++) {
102
+ const entry = tocEntries?.[i];
103
+ if (!entry) {
104
+ continue;
105
+ }
106
+ if (entry.level === level) {
107
+ value++;
167
108
  }
168
- else if (this.props.tocEntries[i2].level < level) {
109
+ else if (entry.level < level) {
110
+ // Reset counter when we hit a higher level
169
111
  value = 0;
170
112
  }
171
113
  }
@@ -173,82 +115,64 @@ class TOCWidgetViewComponent extends react_1.default.Component {
173
115
  }
174
116
  indentation += " ";
175
117
  }
176
- return R("div", { key: index, style: { paddingLeft: tocEntry.level * 8 - 8 } }, R("a", { className: "link-plain", onClick: this.handleEntryClick.bind(null, tocEntry) }, indentation, R("span", null, tocEntry.text)));
177
- }
178
- render() {
179
- // Get border
180
- const border = (() => {
181
- switch (this.props.design.borderWeight) {
182
- case 0:
183
- return "none";
184
- case 1:
185
- return "solid 1px #f4f4f4";
186
- case 2:
187
- return "solid 1px #ccc";
188
- case 3:
189
- return "solid 1px #888";
190
- }
191
- })();
192
- return R("div", {
193
- style: {
194
- width: this.props.width,
195
- height: this.props.height,
196
- border,
197
- padding: 5,
198
- margin: 1
199
- }
200
- },
201
- // Render header
202
- R("div", { style: { fontWeight: "bold" } }, this.props.design.header), lodash_1.default.map(this.props.tocEntries, (tocEntry, i) => {
203
- return this.renderTOCEntry(tocEntry, i);
204
- }),
205
- // Add placeholder if none and editable
206
- this.props.onDesignChange && (this.props.tocEntries || []).length === 0
207
- ? R("div", { className: "text-muted" }, T `Table of Contents will appear here as text blocks with headings are added to the dashboard`)
118
+ return react_1.default.createElement("div", { key: index, style: { paddingLeft: tocEntry.level * 8 - 8 } },
119
+ react_1.default.createElement("a", { className: "link-plain", onClick: () => handleEntryClick(tocEntry) },
120
+ indentation,
121
+ react_1.default.createElement("span", null, translate(tocEntry.text))));
122
+ };
123
+ // Get border
124
+ const border = (() => {
125
+ switch (design.borderWeight) {
126
+ case 0:
127
+ return "none";
128
+ case 1:
129
+ return "solid 1px #f4f4f4";
130
+ case 2:
131
+ return "solid 1px #ccc";
132
+ case 3:
133
+ return "solid 1px #888";
134
+ }
135
+ })();
136
+ return react_1.default.createElement("div", { style: {
137
+ width,
138
+ height,
139
+ border,
140
+ padding: 5,
141
+ margin: 1
142
+ } },
143
+ react_1.default.createElement("div", { style: { fontWeight: "bold" } }, design.header ? props.translate(design.header) : ""),
144
+ lodash_1.default.map(tocEntries || [], (tocEntry, i) => {
145
+ return renderTOCEntry(tocEntry, i);
146
+ }),
147
+ onDesignChange && (tocEntries || []).length === 0
148
+ ? react_1.default.createElement("div", { className: "text-muted" }, T `Table of Contents will appear here as text blocks with headings are added to the dashboard`)
208
149
  : undefined);
209
- }
210
150
  }
211
151
  // Designer for TOC widget options
212
- class TOCWidgetDesignerComponent extends react_1.default.Component {
213
- constructor(...args) {
214
- super(...args);
215
- this.update = this.update.bind(this);
216
- }
217
- static propTypes = {
218
- design: prop_types_1.default.object.isRequired,
219
- onDesignChange: prop_types_1.default.func.isRequired
220
- };
152
+ function TOCWidgetDesignerComponent(props) {
153
+ const { design, onDesignChange } = props;
221
154
  // Updates design with the specified changes
222
- update() {
223
- return (0, update_1.default)(this.props.design, this.props.onDesignChange, arguments);
224
- }
225
- handleMarkdownChange = (ev) => {
226
- const design = lodash_1.default.extend({}, this.props.design, { markdown: ev.target.value });
227
- return this.props.onDesignChange(design);
155
+ const handleUpdate = (field) => (value) => {
156
+ onDesignChange((0, immer_1.default)(design, draft => {
157
+ draft[field] = value;
158
+ }));
228
159
  };
229
- render() {
230
- return R("div", null, R(ui.FormGroup, { label: T `Header` }, R(ui.TextInput, { value: this.props.design.header || "", onChange: this.update("header"), placeholder: T `None` })), R(ui.FormGroup, { label: T `Border` }, R(BorderComponent, { value: this.props.design.borderWeight || 0, onChange: this.update("borderWeight") })), R(ui.FormGroup, { label: T `Numbering` }, R(ui.Radio, {
231
- inline: true,
232
- value: this.props.design.numbering || false,
233
- radioValue: true,
234
- onChange: this.update("numbering")
235
- }, T `On`), R(ui.Radio, {
236
- inline: true,
237
- value: this.props.design.numbering || false,
238
- radioValue: false,
239
- onChange: this.update("numbering")
240
- }, T `Off`)));
241
- }
160
+ return react_1.default.createElement("div", null,
161
+ react_1.default.createElement(ui.FormGroup, { label: T `Header` },
162
+ react_1.default.createElement(ui.TextInput, { value: design.header || "", onChange: handleUpdate("header"), placeholder: T `None` })),
163
+ react_1.default.createElement(ui.FormGroup, { label: T `Border` },
164
+ react_1.default.createElement(BorderComponent, { value: design.borderWeight || 0, onChange: handleUpdate("borderWeight") })),
165
+ react_1.default.createElement(ui.FormGroup, { label: T `Numbering` },
166
+ react_1.default.createElement(ui.Radio, { inline: true, value: design.numbering || false, radioValue: true, onChange: handleUpdate("numbering") }, T `On`),
167
+ react_1.default.createElement(ui.Radio, { inline: true, value: design.numbering || false, radioValue: false, onChange: handleUpdate("numbering") }, T `Off`)));
242
168
  }
243
169
  // Allows setting border heaviness
244
- class BorderComponent extends react_1.default.Component {
245
- static propTypes = {
246
- value: prop_types_1.default.number,
247
- defaultValue: prop_types_1.default.number,
248
- onChange: prop_types_1.default.func.isRequired
249
- };
250
- render() {
251
- const value = this.props.value != null ? this.props.value : this.props.defaultValue;
252
- return R("div", null, R(ui.Radio, { inline: true, value, radioValue: 0, onChange: this.props.onChange }, T `None`), R(ui.Radio, { inline: true, value, radioValue: 1, onChange: this.props.onChange }, T `Light`), R(ui.Radio, { inline: true, value, radioValue: 2, onChange: this.props.onChange }, T `Medium`), R(ui.Radio, { inline: true, value, radioValue: 3, onChange: this.props.onChange }, T `Heavy`));
253
- }
170
+ function BorderComponent(props) {
171
+ const { value, defaultValue, onChange } = props;
172
+ const currentValue = value != null ? value : defaultValue;
173
+ return react_1.default.createElement("div", null,
174
+ react_1.default.createElement(ui.Radio, { inline: true, value: currentValue, radioValue: 0, onChange: onChange }, T `None`),
175
+ react_1.default.createElement(ui.Radio, { inline: true, value: currentValue, radioValue: 1, onChange: onChange }, T `Light`),
176
+ react_1.default.createElement(ui.Radio, { inline: true, value: currentValue, radioValue: 2, onChange: onChange }, T `Medium`),
177
+ react_1.default.createElement(ui.Radio, { inline: true, value: currentValue, radioValue: 3, onChange: onChange }, T `Heavy`));
254
178
  }
@@ -9,18 +9,16 @@ export interface CreateViewElementOptions {
9
9
  dataSource: DataSource;
10
10
  /** Gives data to the widget in a way that allows client-server separation and secure sharing. See definition in WidgetDataSource. **/
11
11
  widgetDataSource: WidgetDataSource;
12
- /** widget design **/
13
- design: object;
12
+ /** widget design */
13
+ design: any;
14
14
  /** scope of the widget (when the widget self-selects a particular scope) **/
15
15
  scope?: WidgetScope | null;
16
16
  /** array of filters to apply.**/
17
17
  filters: JsonQLFilter[];
18
18
  /** called with scope of widget **/
19
- onScopeChange: (scope: WidgetScope | null) => void;
19
+ onScopeChange?: (scope: WidgetScope | null) => void;
20
20
  /** called with new design. null/undefined for readonly **/
21
- onDesignChange?: {
22
- (design: object): void;
23
- } | null;
21
+ onDesignChange?: ((design: any) => void) | null;
24
22
  /** width in pixels on screen **/
25
23
  width?: number;
26
24
  /** height in pixels on screen **/
@@ -34,13 +32,24 @@ export interface CreateViewElementOptions {
34
32
  [key: string]: string;
35
33
  };
36
34
  /** Entries in the table of content */
37
- tocEntries?: string[];
35
+ tocEntries?: TOCEntry[];
38
36
  /** the widget callback ref */
39
37
  widgetRef?: (widget: any) => void;
40
38
  /** called with (widgetId, tocEntryId) to scroll to TOC entry */
41
39
  onScrollToTOCEntry?: (widgetId: string, tocEntryId: string) => void;
42
40
  /** A key that changes when the widget should be refreshed */
43
41
  refreshKey?: any;
42
+ /** Locale to use for display */
43
+ locale: string;
44
+ /** Translate function to use for display. Returns same string when editing. */
45
+ translate: (input: string) => string;
46
+ }
47
+ /** An entry in the table of contents */
48
+ export interface TOCEntry {
49
+ id: any;
50
+ widgetId: string;
51
+ level: number;
52
+ text: string;
44
53
  }
45
54
  export default class Widget {
46
55
  /** Creates a React element that is a view of the widget */
@@ -60,4 +69,6 @@ export default class Widget {
60
69
  text: string;
61
70
  level: number;
62
71
  }[];
72
+ /** Gets any strings that should be translated */
73
+ getTranslatableStrings(design: any, schema: Schema): string[];
63
74
  }
@@ -29,5 +29,9 @@ class Widget {
29
29
  getTOCEntries(design, namedStrings) {
30
30
  return [];
31
31
  }
32
+ /** Gets any strings that should be translated */
33
+ getTranslatableStrings(design, schema) {
34
+ return [];
35
+ }
32
36
  }
33
37
  exports.default = Widget;
@@ -30,7 +30,7 @@ class WidgetScopesViewComponent extends react_1.default.Component {
30
30
  if (lodash_1.default.compact(lodash_1.default.values(scopes)).length === 0) {
31
31
  return null;
32
32
  }
33
- return R("div", { className: "alert alert-info" }, R("span", { className: "fas fa-filter" }), T ` Filters: `, lodash_1.default.map(lodash_1.default.keys(scopes), (id) => this.renderScope(id, scopes[id])));
33
+ return R("div", { className: "alert alert-info" }, R("span", { className: "fas fa-filter" }), " ", T `Filters: `, lodash_1.default.map(lodash_1.default.keys(scopes), (id) => this.renderScope(id, scopes[id])));
34
34
  }
35
35
  }
36
36
  exports.default = WidgetScopesViewComponent;
@@ -8,7 +8,7 @@ export interface ChartCreateViewElementOptions {
8
8
  schema: Schema;
9
9
  /** data source to use. Only used when designing, for display uses data **/
10
10
  dataSource: DataSource;
11
- /** Chart design **/
11
+ /** Chart design. Should already be translated. */
12
12
  design: any;
13
13
  /** called with new design. null/undefined for readonly **/
14
14
  onDesignChange?: {
@@ -28,6 +28,8 @@ export interface ChartCreateViewElementOptions {
28
28
  height?: number;
29
29
  /** Called with (tableId, rowId) when item is clicked **/
30
30
  onRowClick?: (tableId: string, rowId: any) => void;
31
+ /** Locale to use for display */
32
+ locale: string;
31
33
  }
32
34
  export default class Chart {
33
35
  cleanDesign(design: any, schema: Schema): void;
@@ -45,6 +47,9 @@ export default class Chart {
45
47
  onDesignChange: (design: any) => void;
46
48
  }): ReactNode;
47
49
  getData(design: any, schema: Schema, dataSource: DataSource, filters: any, callback: any): void;
50
+ /** Create a view element for the chart.
51
+ * Chart design should already be translated. This is handled by ChartViewComponent.
52
+ */
48
53
  createViewElement(options: ChartCreateViewElementOptions): ReactNode;
49
54
  createDropdownItems(design: any, schema: Schema, widgetDataSource: WidgetDataSource, filters: any): {
50
55
  label: ReactNode;
@@ -53,4 +58,8 @@ export default class Chart {
53
58
  createDataTable(design: any, schema: Schema, dataSource: DataSource, data: any, locale: any): any[][];
54
59
  getFilterableTables(design: any, schema: Schema): string[];
55
60
  getPlaceholderIcon(): string;
61
+ /** Get a list of translatable strings in the design. No need to override in subclasses. Design should already be cleaned. */
62
+ getTranslatableStrings(design: any, schema: Schema): string[];
63
+ /** Translates the design. Override in subclasses. Design is already cleaned. */
64
+ translateDesign(design: any, translate: (input: string) => string): any;
56
65
  }
@@ -44,17 +44,9 @@ class Chart {
44
44
  getData(design, schema, dataSource, filters, callback) {
45
45
  throw new Error("Not implemented");
46
46
  }
47
- // Create a view element for the chart
48
- // Options include:
49
- // schema: schema to use
50
- // dataSource: dataSource to use
51
- // design: design of the chart
52
- // onDesignChange: when design changes
53
- // data: results from queries
54
- // width, height: size of the chart view
55
- // scope: current scope of the view element
56
- // onScopeChange: called when scope changes with new scope
57
- // onRowClick: Called with (tableId, rowId) when item is clicked
47
+ /** Create a view element for the chart.
48
+ * Chart design should already be translated. This is handled by ChartViewComponent.
49
+ */
58
50
  createViewElement(options) {
59
51
  throw new Error("Not implemented");
60
52
  }
@@ -79,5 +71,24 @@ class Chart {
79
71
  getPlaceholderIcon() {
80
72
  return "";
81
73
  }
74
+ /** Get a list of translatable strings in the design. No need to override in subclasses. Design should already be cleaned. */
75
+ getTranslatableStrings(design, schema) {
76
+ const strings = new Set();
77
+ // Create collector function that just saves strings and returns them unchanged
78
+ const collectStrings = (str) => {
79
+ // Only collect non-empty strings
80
+ if (str) {
81
+ strings.add(str);
82
+ }
83
+ return str;
84
+ };
85
+ // Use existing translation function but with collector
86
+ this.translateDesign(design, collectStrings);
87
+ return Array.from(strings);
88
+ }
89
+ /** Translates the design. Override in subclasses. Design is already cleaned. */
90
+ translateDesign(design, translate) {
91
+ return design;
92
+ }
82
93
  }
83
94
  exports.default = Chart;
@@ -26,6 +26,10 @@ export interface ChartViewComponentProps {
26
26
  onRowClick?: (tableId: string, rowId: any) => void;
27
27
  /** A key that changes when the widget should be refreshed */
28
28
  refreshKey?: any;
29
+ /** Locale to use for display */
30
+ locale: string;
31
+ /** Translate function to use for display */
32
+ translate: (input: string) => string;
29
33
  }
30
34
  interface ChartViewComponentState {
31
35
  cacheExpiry?: any;
@@ -108,11 +108,13 @@ class ChartViewComponent extends react_1.default.Component {
108
108
  if (this.state.dataError) {
109
109
  return this.renderError();
110
110
  }
111
- return R("div", { style }, this.state.validDesign
111
+ // Translate design if needed
112
+ const translatedDesign = this.props.onDesignChange || !this.props.translate || !this.state.validDesign ? this.state.validDesign : this.props.chart.translateDesign(this.state.validDesign, this.props.translate);
113
+ return R("div", { style }, translatedDesign
112
114
  ? this.props.chart.createViewElement({
113
115
  schema: this.props.schema,
114
116
  dataSource: this.props.dataSource,
115
- design: this.state.validDesign,
117
+ design: translatedDesign,
116
118
  onDesignChange: this.props.onDesignChange,
117
119
  data: this.state.data,
118
120
  scope: this.props.scope,
@@ -120,7 +122,8 @@ class ChartViewComponent extends react_1.default.Component {
120
122
  width: this.props.width,
121
123
  height: this.props.height,
122
124
  onRowClick: this.props.onRowClick,
123
- filters: this.props.filters
125
+ filters: this.props.filters,
126
+ locale: this.props.locale,
124
127
  })
125
128
  : undefined, this.state.dataLoading ? this.renderSpinner() : undefined);
126
129
  }
@@ -11,4 +11,6 @@ export default class ChartWidget extends Widget {
11
11
  getData(design: any, schema: Schema, dataSource: DataSource, filters: any, callback: any): void;
12
12
  getFilterableTables(design: any, schema: Schema): string[];
13
13
  isAutoHeight(): boolean;
14
+ /** Get a list of translatable strings in the design */
15
+ getTranslatableStrings(design: any, schema: Schema): string[];
14
16
  }
@@ -41,7 +41,9 @@ class ChartWidget extends Widget_1.default {
41
41
  width: options.width,
42
42
  height: options.height,
43
43
  onRowClick: options.onRowClick,
44
- refreshKey: options.refreshKey
44
+ refreshKey: options.refreshKey,
45
+ locale: options.locale,
46
+ translate: options.translate
45
47
  });
46
48
  }
47
49
  // Get the data that the widget needs. This will be called on the server, typically.
@@ -65,5 +67,11 @@ class ChartWidget extends Widget_1.default {
65
67
  isAutoHeight() {
66
68
  return this.chart.isAutoHeight();
67
69
  }
70
+ /** Get a list of translatable strings in the design */
71
+ getTranslatableStrings(design, schema) {
72
+ // Clean design first
73
+ const cleanDesign = this.chart.cleanDesign(design, schema);
74
+ return this.chart.getTranslatableStrings(cleanDesign, schema);
75
+ }
68
76
  }
69
77
  exports.default = ChartWidget;
@@ -33,6 +33,10 @@ export interface ChartWidgetComponentProps {
33
33
  connectResizeHandle?: any;
34
34
  /** A key that changes when the widget should be refreshed */
35
35
  refreshKey?: any;
36
+ /** Locale to use for display */
37
+ locale: string;
38
+ /** Translate function to use for display */
39
+ translate: (input: string) => string;
36
40
  }
37
41
  export declare class ChartWidgetComponent extends React.PureComponent<ChartWidgetComponentProps, {
38
42
  editDesign: any;
@@ -87,7 +87,7 @@ class ChartWidgetComponent extends react_1.default.PureComponent {
87
87
  this.setState({ editDesign: design });
88
88
  };
89
89
  renderChart(design, onDesignChange, width, height) {
90
- return react_1.default.createElement(ChartViewComponent_1.default, { chart: this.props.chart, design: design, onDesignChange: onDesignChange, schema: this.props.schema, dataSource: this.props.dataSource, widgetDataSource: this.props.widgetDataSource, scope: this.props.scope, filters: this.props.filters, width: width, height: height, onScopeChange: this.props.onScopeChange, onRowClick: this.props.onRowClick, refreshKey: this.props.refreshKey });
90
+ return react_1.default.createElement(ChartViewComponent_1.default, { chart: this.props.chart, design: design, onDesignChange: onDesignChange, schema: this.props.schema, dataSource: this.props.dataSource, widgetDataSource: this.props.widgetDataSource, scope: this.props.scope, filters: this.props.filters, width: width, height: height, onScopeChange: this.props.onScopeChange, onRowClick: this.props.onRowClick, refreshKey: this.props.refreshKey, locale: this.props.locale, translate: this.props.translate });
91
91
  }
92
92
  renderEditor() {
93
93
  if (!this.state.editDesign) {
@@ -149,7 +149,7 @@ class ChartWidgetComponent extends react_1.default.PureComponent {
149
149
  // Create dropdown items
150
150
  const dropdownItems = this.props.chart.createDropdownItems(design, this.props.schema, this.props.widgetDataSource, this.props.filters);
151
151
  if (!designError) {
152
- dropdownItems.push({ label: T `Export Data`, icon: "save-file", onClick: this.handleSaveCsvFile });
152
+ dropdownItems.push({ label: T `Export Data`, onClick: this.handleSaveCsvFile });
153
153
  }
154
154
  if (this.props.onDesignChange != null) {
155
155
  dropdownItems.unshift({
@@ -36,4 +36,5 @@ export default class CalendarChart extends Chart {
36
36
  createDataTable(design: any, schema: Schema, dataSource: DataSource, data: any): string[][];
37
37
  getFilterableTables(design: any, schema: Schema): any[];
38
38
  getPlaceholderIcon(): string;
39
+ translateDesign(design: CalendarChartDesign, translate: (input: string) => string): CalendarChartDesign;
39
40
  }
@@ -171,5 +171,31 @@ class CalendarChart extends Chart_1.default {
171
171
  getPlaceholderIcon() {
172
172
  return "fa-calendar";
173
173
  }
174
+ translateDesign(design, translate) {
175
+ return (0, immer_1.default)(design, draft => {
176
+ // Translate title text
177
+ if (draft.titleText) {
178
+ draft.titleText = translate(draft.titleText);
179
+ }
180
+ // Translate axis category labels
181
+ if (draft.dateAxis?.categoryLabels) {
182
+ for (const key in draft.dateAxis.categoryLabels) {
183
+ draft.dateAxis.categoryLabels[key] = translate(draft.dateAxis.categoryLabels[key]);
184
+ }
185
+ }
186
+ if (draft.valueAxis?.categoryLabels) {
187
+ for (const key in draft.valueAxis.categoryLabels) {
188
+ draft.valueAxis.categoryLabels[key] = translate(draft.valueAxis.categoryLabels[key]);
189
+ }
190
+ }
191
+ // Translate null labels
192
+ if (draft.dateAxis?.nullLabel) {
193
+ draft.dateAxis.nullLabel = translate(draft.dateAxis.nullLabel);
194
+ }
195
+ if (draft.valueAxis?.nullLabel) {
196
+ draft.valueAxis.nullLabel = translate(draft.valueAxis.nullLabel);
197
+ }
198
+ });
199
+ }
174
200
  }
175
201
  exports.default = CalendarChart;