@mwater/visualization 5.1.0 → 5.3.0

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 (305) hide show
  1. package/lib/ColorComponent.d.ts +10 -11
  2. package/lib/ColorComponent.js +78 -29
  3. package/lib/ColorSchemeFactory.d.ts +13 -2
  4. package/lib/ColorSchemeFactory.js +7 -5
  5. package/lib/CustomColorsContext.d.ts +6 -0
  6. package/lib/CustomColorsContext.js +6 -0
  7. package/lib/FiltersDesignerComponent.d.ts +1 -4
  8. package/lib/FiltersDesignerComponent.js +2 -3
  9. package/lib/GlobalFilter.d.ts +13 -0
  10. package/lib/GlobalFilter.js +2 -0
  11. package/lib/LocaleContextInjector.d.ts +5 -11
  12. package/lib/LocaleContextInjector.js +4 -12
  13. package/lib/MWaterAddRelatedFormComponent.js +3 -3
  14. package/lib/MWaterAddRelatedIndicatorComponent.d.ts +1 -4
  15. package/lib/MWaterAddRelatedIndicatorComponent.js +6 -6
  16. package/lib/MWaterCompleteTableSelectComponent.d.ts +7 -25
  17. package/lib/MWaterCompleteTableSelectComponent.js +36 -36
  18. package/lib/MWaterContextComponent.d.ts +19 -9
  19. package/lib/MWaterContextComponent.js +38 -22
  20. package/lib/MWaterCustomTablesetListComponent.js +9 -3
  21. package/lib/MWaterGlobalFiltersComponent.d.ts +6 -5
  22. package/lib/MWaterGlobalFiltersComponent.js +4 -4
  23. package/lib/MWaterLoaderComponent.d.ts +15 -3
  24. package/lib/MWaterLoaderComponent.js +11 -2
  25. package/lib/MWaterTableSelectComponent.d.ts +1 -4
  26. package/lib/MWaterTableSelectComponent.js +10 -12
  27. package/lib/UIComponents.d.ts +2 -2
  28. package/lib/UIComponents.js +4 -12
  29. package/lib/axes/Axis.d.ts +20 -25
  30. package/lib/axes/AxisBuilder.d.ts +7 -4
  31. package/lib/axes/AxisBuilder.js +12 -8
  32. package/lib/axes/AxisComponent.d.ts +6 -9
  33. package/lib/axes/AxisComponent.js +1 -2
  34. package/lib/axes/ColorPaletteCollectionComponent.d.ts +5 -12
  35. package/lib/axes/ColorPaletteCollectionComponent.js +67 -36
  36. package/lib/dashboards/DashboardComponent.d.ts +4 -17
  37. package/lib/dashboards/DashboardComponent.js +20 -67
  38. package/lib/dashboards/DashboardDesign.d.ts +5 -20
  39. package/lib/dashboards/DashboardUpgrader.js +36 -1
  40. package/lib/dashboards/DashboardViewComponent.d.ts +5 -34
  41. package/lib/dashboards/DashboardViewComponent.js +112 -136
  42. package/lib/dashboards/FontStyleEditor.d.ts +8 -0
  43. package/lib/dashboards/FontStyleEditor.js +130 -0
  44. package/lib/dashboards/LayoutOptionsComponent.d.ts +0 -1
  45. package/lib/dashboards/LayoutOptionsComponent.js +209 -39
  46. package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -2
  47. package/lib/dashboards/ServerDashboardDataSource.js +52 -33
  48. package/lib/dashboards/SettingsModalComponent.d.ts +4 -15
  49. package/lib/dashboards/SettingsModalComponent.js +24 -38
  50. package/lib/dashboards/WidgetComponent.d.ts +3 -3
  51. package/lib/dashboards/WidgetComponent.js +3 -6
  52. package/lib/dashboards/WidgetDataSourcePrioritizer.d.ts +20 -0
  53. package/lib/dashboards/WidgetDataSourcePrioritizer.js +72 -0
  54. package/lib/dashboards/layoutOptions.d.ts +83 -0
  55. package/lib/dashboards/layoutOptions.js +436 -10
  56. package/lib/datagrids/DatagridComponent.d.ts +2 -9
  57. package/lib/datagrids/DatagridDataSource.d.ts +3 -3
  58. package/lib/datagrids/DatagridDataSource.js +0 -14
  59. package/lib/datagrids/DatagridDesign.d.ts +7 -6
  60. package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -93
  61. package/lib/datagrids/DatagridDesignerComponent.js +8 -6
  62. package/lib/datagrids/DatagridViewComponent.js +1 -1
  63. package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -20
  64. package/lib/datagrids/FindReplaceModalComponent.js +27 -13
  65. package/lib/datagrids/ServerDatagridDataSource.d.ts +8 -7
  66. package/lib/datagrids/ServerDatagridDataSource.js +88 -36
  67. package/lib/demo.js +4 -4
  68. package/lib/index.css +5 -0
  69. package/lib/index.d.ts +2 -1
  70. package/lib/index.js +0 -1
  71. package/lib/layouts/LayoutManager.d.ts +33 -29
  72. package/lib/layouts/LayoutManager.js +2 -8
  73. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +26 -56
  74. package/lib/layouts/blocks/BlocksDisplayComponent.js +122 -205
  75. package/lib/layouts/blocks/BlocksLayoutManager.d.ts +6 -22
  76. package/lib/layouts/blocks/BlocksLayoutManager.js +5 -14
  77. package/lib/layouts/blocks/HorizontalBlockComponent.d.ts +5 -4
  78. package/lib/layouts/blocks/HorizontalBlockComponent.js +5 -5
  79. package/lib/layouts/grid/GridLayoutManager.d.ts +2 -1
  80. package/lib/mWaterLoader.d.ts +2 -0
  81. package/lib/mWaterLoader.js +2 -1
  82. package/lib/maps/AddLayerComponent.d.ts +6 -8
  83. package/lib/maps/AddLayerComponent.js +6 -6
  84. package/lib/maps/BingLayer.js +10 -20
  85. package/lib/maps/BufferLayer.js +5 -2
  86. package/lib/maps/ChoroplethLayer.js +2 -1
  87. package/lib/maps/ClusterLayer.js +3 -1
  88. package/lib/maps/DirectMapDataSource.d.ts +5 -2
  89. package/lib/maps/DirectMapDataSource.js +2 -1
  90. package/lib/maps/EditPopupComponent.js +2 -1
  91. package/lib/maps/GridLayer.js +5 -3
  92. package/lib/maps/GridLayerDesigner.js +0 -1
  93. package/lib/maps/LayerSwitcherComponent.js +1 -1
  94. package/lib/maps/MapComponent.d.ts +3 -11
  95. package/lib/maps/MapComponent.js +3 -3
  96. package/lib/maps/MapDesign.d.ts +2 -13
  97. package/lib/maps/MapFiltersDesignerComponent.d.ts +0 -4
  98. package/lib/maps/MapFiltersDesignerComponent.js +4 -5
  99. package/lib/maps/MarkersLayer.js +30 -25
  100. package/lib/maps/RasterMapViewComponent.d.ts +3 -13
  101. package/lib/maps/RasterMapViewComponent.js +3 -3
  102. package/lib/maps/RegionSelectComponent.d.ts +2 -1
  103. package/lib/maps/ServerMapDataSource.d.ts +3 -4
  104. package/lib/maps/ServerMapDataSource.js +5 -5
  105. package/lib/maps/VectorMapViewComponent.js +2 -1
  106. package/lib/maps/mapSymbols.js +2 -0
  107. package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
  108. package/lib/maps/vectorMaps.d.ts +1 -0
  109. package/lib/maps/vectorMaps.js +70 -56
  110. package/lib/quickfilter/QuickfilterCompiler.d.ts +1 -1
  111. package/lib/quickfilter/QuickfiltersComponent.d.ts +1 -4
  112. package/lib/quickfilter/QuickfiltersComponent.js +3 -3
  113. package/lib/richtext/DropdownPaletteItem.d.ts +32 -0
  114. package/lib/richtext/DropdownPaletteItem.js +82 -0
  115. package/lib/richtext/FontColorPaletteItem.d.ts +1 -5
  116. package/lib/richtext/FontColorPaletteItem.js +32 -27
  117. package/lib/richtext/ItemsHtmlConverter.js +12 -3
  118. package/lib/richtext/RichTextComponent.d.ts +26 -52
  119. package/lib/richtext/RichTextComponent.js +166 -128
  120. package/lib/valueFormatter.js +6 -1
  121. package/lib/wellknown.d.ts +5 -0
  122. package/lib/wellknown.js +288 -0
  123. package/lib/widgets/DropdownWidgetComponent.d.ts +8 -25
  124. package/lib/widgets/DropdownWidgetComponent.js +48 -25
  125. package/lib/widgets/IFrameWidgetComponent.d.ts +3 -11
  126. package/lib/widgets/ImageWidgetComponent.d.ts +8 -27
  127. package/lib/widgets/MapWidget.d.ts +4 -7
  128. package/lib/widgets/MapWidget.js +2 -1
  129. package/lib/widgets/MarkdownWidget.d.ts +2 -7
  130. package/lib/widgets/TOCWidget.d.ts +2 -9
  131. package/lib/widgets/TOCWidget.js +2 -1
  132. package/lib/widgets/Widget.d.ts +2 -0
  133. package/lib/widgets/WidgetDataSource.d.ts +3 -1
  134. package/lib/widgets/charts/Chart.d.ts +0 -1
  135. package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
  136. package/lib/widgets/charts/ChartViewComponent.js +11 -3
  137. package/lib/widgets/charts/ChartWidget.d.ts +1 -74
  138. package/lib/widgets/charts/ChartWidget.js +4 -183
  139. package/lib/widgets/charts/ChartWidgetComponent.d.ts +51 -0
  140. package/lib/widgets/charts/ChartWidgetComponent.js +167 -0
  141. package/lib/widgets/charts/calendar/CalendarChartViewComponent.d.ts +1 -4
  142. package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +4 -4
  143. package/lib/widgets/charts/imagemosaic/ImagePopupComponent.d.ts +2 -7
  144. package/lib/widgets/charts/layered/LayeredChart.d.ts +5 -10
  145. package/lib/widgets/charts/layered/LayeredChart.js +6 -7
  146. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +4 -2
  147. package/lib/widgets/charts/layered/LayeredChartCompiler.js +46 -32
  148. package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +4 -0
  149. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +5 -31
  150. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +21 -3
  151. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +1 -7
  152. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -1
  153. package/lib/widgets/charts/layered/LayeredChartViewComponent.d.ts +1 -4
  154. package/lib/widgets/charts/layered/LayeredChartViewComponent.js +89 -38
  155. package/lib/widgets/charts/pivot/IntersectionDesignerComponent.d.ts +5 -105
  156. package/lib/widgets/charts/pivot/IntersectionDesignerComponent.js +122 -166
  157. package/lib/widgets/charts/pivot/PivotChart.d.ts +6 -0
  158. package/lib/widgets/charts/pivot/PivotChart.js +47 -17
  159. package/lib/widgets/charts/pivot/PivotChartDesign.d.ts +11 -0
  160. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +11 -7
  161. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +1 -1
  162. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +2 -2
  163. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +20 -36
  164. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +0 -1
  165. package/lib/widgets/charts/pivot/PivotChartQueryBuilder.d.ts +23 -2
  166. package/lib/widgets/charts/pivot/PivotChartQueryBuilder.js +215 -181
  167. package/lib/widgets/charts/pivot/PivotChartUtils.d.ts +2 -2
  168. package/lib/widgets/charts/pivot/PivotChartViewComponent.d.ts +9 -47
  169. package/lib/widgets/charts/pivot/PivotChartViewComponent.js +20 -60
  170. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +55 -58
  171. package/lib/widgets/charts/table/TableChart.js +8 -4
  172. package/lib/widgets/charts/table/TableChartDesignerComponent.js +3 -3
  173. package/lib/widgets/charts/table/TableChartViewComponent.js +30 -16
  174. package/lib/widgets/text/ExprInsertModalComponent.d.ts +2 -13
  175. package/lib/widgets/text/ExprUpdateModalComponent.d.ts +2 -13
  176. package/lib/widgets/text/TextComponent.d.ts +5 -12
  177. package/lib/widgets/text/TextComponent.js +19 -39
  178. package/lib/widgets/text/TextWidget.d.ts +2 -1
  179. package/lib/widgets/text/TextWidget.js +5 -1
  180. package/lib/widgets/text/TextWidgetComponent.d.ts +15 -3
  181. package/lib/widgets/text/TextWidgetComponent.js +76 -19
  182. package/lib/widgets/text/TextWidgetDesign.d.ts +16 -2
  183. package/lib/widgets/text/TextWidgetDesign.js +6 -0
  184. package/package.json +4 -4
  185. package/src/ColorComponent.tsx +177 -0
  186. package/src/ColorSchemeFactory.ts +12 -6
  187. package/src/CustomColorsContext.tsx +8 -0
  188. package/src/FiltersDesignerComponent.ts +3 -4
  189. package/src/GlobalFilter.ts +17 -0
  190. package/src/LocaleContextInjector.tsx +14 -13
  191. package/src/MWaterAddRelatedFormComponent.ts +3 -3
  192. package/src/MWaterAddRelatedIndicatorComponent.ts +6 -6
  193. package/src/MWaterCompleteTableSelectComponent.tsx +36 -36
  194. package/src/MWaterContextComponent.tsx +42 -33
  195. package/src/MWaterCustomTablesetListComponent.tsx +21 -3
  196. package/src/MWaterGlobalFiltersComponent.ts +8 -8
  197. package/src/MWaterLoaderComponent.ts +14 -4
  198. package/src/MWaterTableSelectComponent.tsx +11 -12
  199. package/src/{UIComponents.ts → UIComponents.tsx} +7 -15
  200. package/src/axes/Axis.ts +24 -25
  201. package/src/axes/AxisBuilder.ts +16 -13
  202. package/src/axes/AxisComponent.ts +3 -4
  203. package/src/axes/{ColorPaletteCollectionComponent.ts → ColorPaletteCollectionComponent.tsx} +87 -61
  204. package/src/dashboards/DashboardComponent.tsx +73 -147
  205. package/src/dashboards/DashboardDesign.ts +5 -25
  206. package/src/dashboards/DashboardUpgrader.ts +41 -1
  207. package/src/dashboards/DashboardViewComponent.tsx +313 -0
  208. package/src/dashboards/FontStyleEditor.tsx +166 -0
  209. package/src/dashboards/LayoutOptionsComponent.tsx +377 -71
  210. package/src/dashboards/ServerDashboardDataSource.ts +52 -33
  211. package/src/dashboards/SettingsModalComponent.tsx +170 -0
  212. package/src/dashboards/WidgetComponent.tsx +6 -12
  213. package/src/dashboards/WidgetDataSourcePrioritizer.ts +82 -0
  214. package/src/dashboards/layoutOptions.tsx +581 -0
  215. package/src/datagrids/DatagridDataSource.ts +6 -12
  216. package/src/datagrids/DatagridDesign.ts +8 -3
  217. package/src/datagrids/DatagridDesignerComponent.tsx +22 -18
  218. package/src/datagrids/DatagridViewComponent.ts +3 -3
  219. package/src/datagrids/ExprCellComponent.ts +0 -1
  220. package/src/datagrids/FindReplaceModalComponent.ts +39 -22
  221. package/src/datagrids/ServerDatagridDataSource.ts +107 -45
  222. package/src/demo.ts +4 -4
  223. package/src/index.css +5 -0
  224. package/src/index.ts +2 -1
  225. package/src/layouts/LayoutManager.ts +44 -42
  226. package/src/layouts/blocks/BlocksDisplayComponent.tsx +498 -0
  227. package/src/layouts/blocks/BlocksLayoutManager.ts +6 -15
  228. package/src/layouts/blocks/HorizontalBlockComponent.ts +9 -8
  229. package/src/mWaterLoader.ts +4 -1
  230. package/src/maps/AddLayerComponent.ts +9 -9
  231. package/src/maps/BingLayer.ts +16 -26
  232. package/src/maps/BufferLayer.ts +5 -2
  233. package/src/maps/ChoroplethLayer.ts +2 -1
  234. package/src/maps/ClusterLayer.ts +3 -1
  235. package/src/maps/DirectMapDataSource.ts +12 -3
  236. package/src/maps/EditPopupComponent.ts +2 -1
  237. package/src/maps/GridLayer.ts +5 -3
  238. package/src/maps/GridLayerDesigner.tsx +0 -1
  239. package/src/maps/LayerSwitcherComponent.tsx +1 -1
  240. package/src/maps/MapComponent.ts +3 -3
  241. package/src/maps/MapDesign.ts +2 -17
  242. package/src/maps/{MapFiltersDesignerComponent.ts → MapFiltersDesignerComponent.tsx} +25 -25
  243. package/src/maps/MarkersLayer.ts +38 -41
  244. package/src/maps/RasterMapViewComponent.ts +3 -3
  245. package/src/maps/ServerMapDataSource.ts +8 -8
  246. package/src/maps/VectorMapViewComponent.tsx +2 -2
  247. package/src/maps/mapSymbols.ts +2 -0
  248. package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
  249. package/src/maps/vectorMaps.tsx +88 -74
  250. package/src/quickfilter/QuickfilterCompiler.ts +1 -1
  251. package/src/quickfilter/QuickfiltersComponent.ts +3 -3
  252. package/src/richtext/DropdownPaletteItem.tsx +144 -0
  253. package/src/richtext/FontColorPaletteItem.tsx +160 -0
  254. package/src/richtext/ItemsHtmlConverter.ts +15 -5
  255. package/src/richtext/RichTextComponent.tsx +274 -232
  256. package/src/valueFormatter.ts +5 -1
  257. package/src/wellknown.ts +286 -0
  258. package/src/widgets/DropdownWidgetComponent.tsx +75 -0
  259. package/src/widgets/MapWidget.ts +5 -2
  260. package/src/widgets/TOCWidget.ts +2 -1
  261. package/src/widgets/Widget.ts +3 -0
  262. package/src/widgets/WidgetDataSource.ts +3 -1
  263. package/src/widgets/charts/Chart.ts +1 -1
  264. package/src/widgets/charts/ChartViewComponent.ts +16 -3
  265. package/src/widgets/charts/ChartWidget.ts +3 -275
  266. package/src/widgets/charts/ChartWidgetComponent.tsx +281 -0
  267. package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +4 -4
  268. package/src/widgets/charts/layered/LayeredChart.ts +4 -6
  269. package/src/widgets/charts/layered/LayeredChartCompiler.ts +80 -63
  270. package/src/widgets/charts/layered/LayeredChartDesign.ts +7 -1
  271. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +43 -10
  272. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +6 -6
  273. package/src/widgets/charts/layered/LayeredChartViewComponent.ts +140 -88
  274. package/src/widgets/charts/pivot/IntersectionDesignerComponent.tsx +305 -221
  275. package/src/widgets/charts/pivot/PivotChart.ts +56 -18
  276. package/src/widgets/charts/pivot/PivotChartDesign.ts +12 -0
  277. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +4 -3
  278. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +39 -76
  279. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +0 -1
  280. package/src/widgets/charts/pivot/PivotChartQueryBuilder.ts +230 -189
  281. package/src/widgets/charts/pivot/PivotChartUtils.ts +4 -4
  282. package/src/widgets/charts/pivot/{PivotChartViewComponent.ts → PivotChartViewComponent.tsx} +86 -89
  283. package/src/widgets/charts/table/TableChart.ts +8 -4
  284. package/src/widgets/charts/table/TableChartDesignerComponent.ts +4 -4
  285. package/src/widgets/charts/table/TableChartViewComponent.ts +32 -19
  286. package/src/widgets/text/TextComponent.tsx +47 -49
  287. package/src/widgets/text/TextWidget.ts +8 -3
  288. package/src/widgets/text/TextWidgetComponent.tsx +249 -0
  289. package/src/widgets/text/TextWidgetDesign.ts +26 -2
  290. package/src/ColorComponent.ts +0 -117
  291. package/src/dashboards/DashboardViewComponent.ts +0 -304
  292. package/src/dashboards/SettingsModalComponent.ts +0 -169
  293. package/src/dashboards/layoutOptions.ts +0 -40
  294. package/src/layout-styles.css +0 -263
  295. package/src/layouts/blocks/BlocksDisplayComponent.ts +0 -461
  296. package/src/layouts/grid/GridLayoutComponent.ts +0 -67
  297. package/src/layouts/grid/GridLayoutManager.ts +0 -185
  298. package/src/layouts/grid/LegoLayoutEngine.ts +0 -142
  299. package/src/layouts/grid/PaletteItemComponent.ts +0 -28
  300. package/src/layouts/grid/README.md +0 -14
  301. package/src/layouts/grid/WidgetContainerComponent.ts +0 -420
  302. package/src/richtext/FontColorPaletteItem.ts +0 -172
  303. package/src/richtext/FontSizePaletteItem.ts +0 -110
  304. package/src/widgets/DropdownWidgetComponent.ts +0 -78
  305. package/src/widgets/text/TextWidgetComponent.ts +0 -120
@@ -0,0 +1,313 @@
1
+ import _ from "lodash"
2
+ import React, { CSSProperties, useEffect, useImperativeHandle, useRef, useMemo, useState } from "react"
3
+
4
+ import ImplicitFilterBuilder from "../ImplicitFilterBuilder"
5
+ import * as DashboardUtils from "./DashboardUtils"
6
+ import { DataSource, Schema } from "@mwater/expressions"
7
+ import WidgetFactory from "../widgets/WidgetFactory"
8
+ import WidgetScoper from "../widgets/WidgetScoper"
9
+ import ReactElementPrinter from "@mwater/react-library/lib/ReactElementPrinter"
10
+ import LayoutManager, { RenderWidgetOptions } from "../layouts/LayoutManager"
11
+ import WidgetScopesViewComponent from "../widgets/WidgetScopesViewComponent"
12
+ import { getLayoutOptions } from "./layoutOptions"
13
+ import { WidgetComponent } from "./WidgetComponent"
14
+ import { DashboardDataSource, DashboardDesign, JsonQLFilter } from ".."
15
+ import { setPrintingModeEnabled } from "../maps/vectorMaps"
16
+ import { WidgetDataSourcePrioritizer } from "./WidgetDataSourcePrioritizer"
17
+ import { LocaleContext } from "@mwater/expressions-ui/lib/contexts"
18
+
19
+ export interface DashboardViewComponentProps {
20
+ /** schema to use */
21
+ schema: Schema
22
+
23
+ /** data source to use. Only used when designing, for display uses dashboardDataSource */
24
+ dataSource: DataSource
25
+
26
+ /** dashboard data source */
27
+ dashboardDataSource: DashboardDataSource
28
+
29
+ design: DashboardDesign
30
+
31
+ /** Leave unset for readonly */
32
+ onDesignChange?: (design: DashboardDesign) => void
33
+
34
+ /** Called with (tableId, rowId) when item is clicked */
35
+ onRowClick?: (tableId: string, rowId: any) => void
36
+
37
+ /** Optional lookup of string name to value. Used for {{branding}} and other replacement strings in text widget */
38
+ namedStrings?: { [key: string]: string }
39
+
40
+ /** Filters to add to the dashboard (includes extra filters and any quickfilters from the dashboard component. Does not include dashboard level filters) */
41
+ filters?: JsonQLFilter[]
42
+
43
+ /** Entry to scroll to initially when dashboard is loaded */
44
+ initialTOCEntryScroll?: { widgetId: string; entryId: any }
45
+
46
+ /** True to hide scope display */
47
+ hideScopes?: boolean
48
+
49
+ /** True to render in print mode (prevents odd clipping issue) */
50
+ printMode?: boolean
51
+
52
+ /** Change to force a refresh */
53
+ refreshKey?: any
54
+ }
55
+
56
+ export interface DashboardViewComponentHandle {
57
+ print: () => Promise<void>
58
+ }
59
+
60
+ /**
61
+ * Displays a dashboard, handling removing of widgets. No title bar or other decorations.
62
+ * Handles scoping and stores the state of scope
63
+ */
64
+ const DashboardViewComponent = React.forwardRef<DashboardViewComponentHandle, DashboardViewComponentProps>((props, ref) => {
65
+ const [widgetScoper, setWidgetScoper] = useState(new WidgetScoper())
66
+ const widgetComps = useRef<{ [widgetId: string]: any }>({})
67
+ const [forceUpdate, setForceUpdate] = useState(0)
68
+
69
+ const widgetDataSourcePrioritizer = useMemo(() => {
70
+ return new WidgetDataSourcePrioritizer(props.dashboardDataSource, 10)
71
+ }, [props.dashboardDataSource])
72
+
73
+ useEffect(() => {
74
+ return () => {
75
+ // Clear queue on component unmount
76
+ widgetDataSourcePrioritizer.cancel()
77
+ }
78
+ }, [widgetDataSourcePrioritizer])
79
+
80
+ useEffect(() => {
81
+ if (props.initialTOCEntryScroll) {
82
+ // Getting heights of widgets properly requires a 0 length timeout
83
+ setTimeout(() => {
84
+ handleScrollToTOCEntry(
85
+ props.initialTOCEntryScroll!.widgetId,
86
+ props.initialTOCEntryScroll!.entryId
87
+ )
88
+ }, 0)
89
+ }
90
+
91
+ // Add listener to localstorage to update clipboard display
92
+ window.addEventListener("storage", handleStorageChange)
93
+
94
+ return () => {
95
+ // Remove listener
96
+ window.removeEventListener("storage", handleStorageChange)
97
+ }
98
+ }, [props.initialTOCEntryScroll])
99
+
100
+ const handleStorageChange = () => {
101
+ setForceUpdate(forceUpdate + 1)
102
+ }
103
+
104
+ const handleScopeChange = (id: any, scope: any) => {
105
+ setWidgetScoper(widgetScoper.applyScope(id, scope))
106
+ }
107
+
108
+ const handleRemoveScope = (id: any) => {
109
+ setWidgetScoper(widgetScoper.applyScope(id, null))
110
+ }
111
+
112
+ const handleItemsChange = (items: any) => {
113
+ const design = _.extend({}, props.design, { items }) as DashboardDesign
114
+ props.onDesignChange!(design)
115
+ }
116
+
117
+ const handleClipboardChange = (block: any) => {
118
+ try {
119
+ // If empty, just set it
120
+ if (!block) {
121
+ window.localStorage.removeItem("DashboardViewComponent.clipboard")
122
+ setForceUpdate(forceUpdate + 1)
123
+ return
124
+ }
125
+
126
+ // Determine which tables are used (just peek for any uses of the table name. Not ideal, but easy)
127
+ const tables = _.pluck(
128
+ _.filter(props.schema.getTables(), (table) => JSON.stringify(block).includes(JSON.stringify(table.id))),
129
+ "id"
130
+ )
131
+
132
+ // Store in clipboard
133
+ window.localStorage.setItem("DashboardViewComponent.clipboard", JSON.stringify({ block, tables }))
134
+ setForceUpdate(forceUpdate + 1)
135
+ } catch (err) {
136
+ return alert("Clipboard not available")
137
+ }
138
+ }
139
+
140
+ const getClipboardContents = () => {
141
+ try {
142
+ return JSON.parse(window.localStorage.getItem("DashboardViewComponent.clipboard") || "null")
143
+ } catch (err) {
144
+ return null
145
+ }
146
+ }
147
+
148
+ const print = async () => {
149
+ // Temporarily enable print mode for vector maps
150
+ try {
151
+ setPrintingModeEnabled(true)
152
+
153
+ // Create element at 1080 wide (use as standard printing width)
154
+ const elem = (
155
+ <div style={{ width: 1080 }}>
156
+ <DashboardViewComponent {...props} onDesignChange={undefined} printMode={true} />
157
+ </div>
158
+ )
159
+
160
+ const printer = new ReactElementPrinter()
161
+ await printer.print(elem, { delay: 5000 })
162
+ } finally {
163
+ setPrintingModeEnabled(false)
164
+ }
165
+ }
166
+
167
+ useImperativeHandle(ref, () => ({
168
+ print
169
+ }))
170
+
171
+ const getCompiledFilters = () => {
172
+ let compiledFilters = DashboardUtils.getCompiledFilters(
173
+ props.design,
174
+ props.schema,
175
+ DashboardUtils.getFilterableTables(props.design, props.schema)
176
+ )
177
+ compiledFilters = compiledFilters.concat(props.filters || [])
178
+ return compiledFilters
179
+ }
180
+
181
+ const getTOCEntries = (layoutManager: any) => {
182
+ const entries = []
183
+
184
+ for (let { id, type, design } of layoutManager.getAllWidgets(props.design.items)) {
185
+ const widget = WidgetFactory.createWidget(type)
186
+ // Add widgetId to each one
187
+ for (let entry of widget.getTOCEntries(design, props.namedStrings)) {
188
+ entries.push(_.extend({}, entry, { widgetId: id }))
189
+ }
190
+ }
191
+
192
+ return entries
193
+ }
194
+
195
+ const handleScrollToTOCEntry = (widgetId: any, entryId: any) => {
196
+ const widgetComp = widgetComps.current[widgetId]
197
+ if (!widgetComp) {
198
+ return
199
+ }
200
+
201
+ // Call scrollToTOCEntry if present
202
+ return widgetComp.scrollToTOCEntry?.(entryId)
203
+ }
204
+
205
+ const renderScopes = () => {
206
+ return (
207
+ <WidgetScopesViewComponent
208
+ scopes={widgetScoper.getScopes()}
209
+ onRemoveScope={handleRemoveScope}
210
+ />
211
+ )
212
+ }
213
+
214
+ const compRef = (widgetId: any, comp: any) => {
215
+ return (widgetComps.current[widgetId] = comp)
216
+ }
217
+
218
+ let cantPasteMessage = ""
219
+ const layoutManager = LayoutManager.createLayoutManager(props.design.layout)
220
+
221
+ const compiledFilters = getCompiledFilters()
222
+
223
+ // Get filterable tables
224
+ const filterableTables = DashboardUtils.getFilterableTables(props.design, props.schema)
225
+
226
+ // Determine toc entries
227
+ const tocEntries = getTOCEntries(layoutManager)
228
+
229
+ // Get clipboard contents
230
+ const clipboardContents = getClipboardContents()
231
+
232
+ // Check if can't paste because of missing table
233
+ if (clipboardContents && !_.all(clipboardContents.tables, (table: string) => props.schema.getTable(table))) {
234
+ cantPasteMessage = "Dashboard is missing one or more data sources needed for the copied item."
235
+ }
236
+
237
+ const renderWidget = (options: RenderWidgetOptions) => {
238
+ const widgetDataSource = widgetDataSourcePrioritizer.getWidgetDataSource(
239
+ options.type,
240
+ options.id,
241
+ options.priority ?? 0
242
+ )
243
+
244
+ // Get filters (passed in plus dashboard widget scoper filters)
245
+ let filters = compiledFilters.concat(widgetScoper.getFilters(options.id))
246
+
247
+ // Extend the filters to include implicit filters (filter children in 1-n relationships)
248
+ if (props.design.implicitFiltersEnabled || props.design.implicitFiltersEnabled == null) {
249
+ // Default is true
250
+ const implicitFilterBuilder = new ImplicitFilterBuilder(props.schema)
251
+ filters = implicitFilterBuilder.extendFilters(filterableTables, filters)
252
+ }
253
+
254
+ const widgetElem = (
255
+ <WidgetComponent
256
+ key={options.id}
257
+ id={options.id}
258
+ type={options.type}
259
+ schema={props.schema}
260
+ dataSource={props.dataSource}
261
+ widgetDataSource={widgetDataSource}
262
+ design={options.design}
263
+ scope={widgetScoper.getScope(options.id)}
264
+ filters={filters}
265
+ onScopeChange={handleScopeChange.bind(null, options.id)}
266
+ onDesignChange={options.onDesignChange}
267
+ width={options.width}
268
+ height={options.height}
269
+ onRowClick={props.onRowClick}
270
+ namedStrings={props.namedStrings}
271
+ tocEntries={tocEntries}
272
+ onScrollToTOCEntry={handleScrollToTOCEntry}
273
+ // Keep references to widget elements
274
+ widgetRef={compRef.bind(null, options.id)}
275
+ refreshKey={props.refreshKey}
276
+ />
277
+ )
278
+
279
+ return widgetElem
280
+ }
281
+
282
+ const style: CSSProperties = {
283
+ height: "100%",
284
+ position: "relative"
285
+ }
286
+
287
+ if (!props.printMode) {
288
+ // Prevent this block from taking up too much space. Scrolling handled by layout manager.
289
+ // Setting overflow-x stops the inner div from becoming too tall
290
+ style.overflowX = "auto"
291
+ }
292
+
293
+ // Render widget container
294
+ return (
295
+ <LocaleContext.Provider value={props.design.locale ?? "en"}>
296
+ <div style={style}>
297
+ {!props.hideScopes ? renderScopes() : undefined}
298
+
299
+ {layoutManager.renderLayout({
300
+ items: props.design.items,
301
+ onItemsChange: props.onDesignChange != null ? handleItemsChange : undefined,
302
+ layoutOptions: getLayoutOptions(props.design),
303
+ renderWidget,
304
+ clipboard: clipboardContents?.block,
305
+ onClipboardChange: handleClipboardChange,
306
+ cantPasteMessage
307
+ })}
308
+ </div>
309
+ </LocaleContext.Provider>
310
+ )
311
+ })
312
+
313
+ export default DashboardViewComponent
@@ -0,0 +1,166 @@
1
+ import React, { useState } from "react"
2
+ import ActionCancelModalComponent from "@mwater/react-library/lib/ActionCancelModalComponent"
3
+ import { expandFontFamily, FontStyle } from "./layoutOptions"
4
+ import { default as ReactSelect } from "react-select"
5
+ import { Select, FormGroup } from "@mwater/react-library/lib/bootstrap"
6
+ import ColorComponent from "../ColorComponent"
7
+
8
+ interface FontStyleEditorProps {
9
+ value: FontStyle
10
+ onChange: (value: FontStyle) => void
11
+ }
12
+
13
+ export const FontStyleEditor = ({ value, onChange }: FontStyleEditorProps) => {
14
+ const [isModalOpen, setIsModalOpen] = useState(false)
15
+
16
+ const handleOpenModal = () => setIsModalOpen(true)
17
+ const handleCloseModal = () => setIsModalOpen(false)
18
+
19
+ const handleSave = (newValue: FontStyle) => {
20
+ onChange(newValue)
21
+ handleCloseModal()
22
+ }
23
+
24
+ return <>
25
+ <div style={{ display: 'flex', alignItems: 'center', cursor: 'pointer', border: 'solid 1px #DDD', padding: '4px', borderRadius: '6px', justifyContent: 'space-between' }} onClick={handleOpenModal}>
26
+ <div style={{
27
+ fontFamily: expandFontFamily(value.family),
28
+ fontSize: `${value.size}px`,
29
+ fontWeight: value.weight,
30
+ color: value.color
31
+ }}>
32
+ Sample
33
+ </div>
34
+ <div style={{ fontSize: '10px', color: '#888', marginTop: '2px' }}>
35
+ {value.family}, {value.size}px
36
+ </div>
37
+ </div>
38
+ {isModalOpen && (
39
+ <FontEditorModal
40
+ initialValue={value}
41
+ onSave={handleSave}
42
+ onCancel={handleCloseModal}
43
+ />
44
+ )}
45
+ </>
46
+ }
47
+
48
+ interface FontEditorModalProps {
49
+ initialValue: FontStyle
50
+ onSave: (value: FontStyle) => void
51
+ onCancel: () => void
52
+ }
53
+
54
+ const FontEditorModal: React.FC<FontEditorModalProps> = ({ initialValue, onSave, onCancel }) => {
55
+ const [currentValue, setCurrentValue] = useState<FontStyle>(initialValue)
56
+
57
+ const handleChange = (field: keyof FontStyle, value: string | number) => {
58
+ if (field == "family") {
59
+ setCurrentValue(prev => ({ ...prev, [field]: value as string, weight: "400" }))
60
+ }
61
+ else {
62
+ setCurrentValue(prev => ({ ...prev, [field]: value }))
63
+ }
64
+ }
65
+
66
+ // Generate font size options from 5 to 48
67
+ const fontSizeOptions = Array.from({ length: 44 }, (_, i) => i + 5).map(size => ({
68
+ value: size,
69
+ label: `${size}px`
70
+ }))
71
+
72
+ // If the font is variable, then the font weight options are much wider
73
+ const fontWeightOptions: string[] = []
74
+ if (currentValue.family === "Roboto") {
75
+ fontWeightOptions.push("100", "300", "400", "500", "700", "900")
76
+ }
77
+ else if (currentValue.family === "Lora") {
78
+ fontWeightOptions.push("400", "500", "600", "700")
79
+ }
80
+ else if (currentValue.family === "Inter") {
81
+ fontWeightOptions.push("100", "200", "300", "400", "500", "600", "700", "800", "900")
82
+ }
83
+ else if (currentValue.family === "Merriweather") {
84
+ fontWeightOptions.push("300", "400", "700", "900")
85
+ }
86
+ else if (currentValue.family === "Lato") {
87
+ fontWeightOptions.push("100", "300", "400", "700", "900")
88
+ }
89
+ else {
90
+ fontWeightOptions.push("400", "700")
91
+ }
92
+
93
+ return (
94
+ <ActionCancelModalComponent
95
+ title="Edit Font"
96
+ onAction={() => onSave(currentValue)}
97
+ onCancel={onCancel}
98
+ >
99
+ <div style={{
100
+ border: '1px solid #ccc',
101
+ padding: '10px',
102
+ marginBottom: '15px',
103
+ borderRadius: '4px'
104
+ }}>
105
+ <div style={{
106
+ marginBottom: '10px',
107
+ fontSize: '14px',
108
+ fontWeight: 'bold'
109
+ }}>
110
+ Sample Text:
111
+ </div>
112
+ <div style={{
113
+ fontFamily: expandFontFamily(currentValue.family),
114
+ fontSize: `${currentValue.size}px`,
115
+ fontWeight: currentValue.weight,
116
+ color: currentValue.color
117
+ }}>
118
+ The quick brown fox jumps over the lazy dog.
119
+ </div>
120
+ </div>
121
+ <FormGroup label="Font Family">
122
+ <ReactSelect
123
+ value={{ value: currentValue.family, label: currentValue.family }}
124
+ onChange={(option) => handleChange('family', option?.value || '')}
125
+ options={[
126
+ { value: 'Helvetica Neue', label: 'Helvetica Neue' },
127
+ { value: 'Georgia', label: 'Georgia' },
128
+ { value: 'Inter', label: 'Inter' },
129
+ { value: 'Lato', label: 'Lato' },
130
+ { value: 'Lora', label: 'Lora' },
131
+ { value: 'Lucida Grande', label: 'Lucida Grande' },
132
+ { value: 'Merriweather', label: 'Merriweather' },
133
+ { value: 'Roboto', label: 'Roboto' },
134
+ ]}
135
+ formatOptionLabel={(option) => (
136
+ <span style={{ fontFamily: expandFontFamily(option.value) }}>{option.label}</span>
137
+ )}
138
+ isClearable={false}
139
+ menuPortalTarget={document.body}
140
+ styles={{ menuPortal: (style) => ({ ...style, zIndex: 2000 }) }}
141
+ />
142
+ </FormGroup>
143
+ <FormGroup label="Font Size:" horizontal>
144
+ <Select
145
+ value={currentValue.size}
146
+ onChange={(value) => handleChange('size', value || 12)}
147
+ options={fontSizeOptions}
148
+ />
149
+ </FormGroup>
150
+ <FormGroup label="Font Weight:" horizontal>
151
+ <Select
152
+ value={currentValue.weight}
153
+ onChange={(value) => handleChange('weight', value as string)}
154
+ options={fontWeightOptions.map(weight => ({ value: weight, label: weight }))}
155
+ />
156
+ </FormGroup>
157
+ <FormGroup label="Font Color:" horizontal>
158
+ <ColorComponent
159
+ color={currentValue.color}
160
+ onChange={(value) => handleChange('color', value!)}
161
+ disableReset
162
+ />
163
+ </FormGroup>
164
+ </ActionCancelModalComponent>
165
+ )
166
+ }