@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.
- package/lib/ColorComponent.d.ts +10 -11
- package/lib/ColorComponent.js +78 -29
- package/lib/ColorSchemeFactory.d.ts +13 -2
- package/lib/ColorSchemeFactory.js +7 -5
- package/lib/CustomColorsContext.d.ts +6 -0
- package/lib/CustomColorsContext.js +6 -0
- package/lib/FiltersDesignerComponent.d.ts +1 -4
- package/lib/FiltersDesignerComponent.js +2 -3
- package/lib/GlobalFilter.d.ts +13 -0
- package/lib/GlobalFilter.js +2 -0
- package/lib/LocaleContextInjector.d.ts +5 -11
- package/lib/LocaleContextInjector.js +4 -12
- package/lib/MWaterAddRelatedFormComponent.js +3 -3
- package/lib/MWaterAddRelatedIndicatorComponent.d.ts +1 -4
- package/lib/MWaterAddRelatedIndicatorComponent.js +6 -6
- package/lib/MWaterCompleteTableSelectComponent.d.ts +7 -25
- package/lib/MWaterCompleteTableSelectComponent.js +36 -36
- package/lib/MWaterContextComponent.d.ts +19 -9
- package/lib/MWaterContextComponent.js +38 -22
- package/lib/MWaterCustomTablesetListComponent.js +9 -3
- package/lib/MWaterGlobalFiltersComponent.d.ts +6 -5
- package/lib/MWaterGlobalFiltersComponent.js +4 -4
- package/lib/MWaterLoaderComponent.d.ts +15 -3
- package/lib/MWaterLoaderComponent.js +11 -2
- package/lib/MWaterTableSelectComponent.d.ts +1 -4
- package/lib/MWaterTableSelectComponent.js +10 -12
- package/lib/UIComponents.d.ts +2 -2
- package/lib/UIComponents.js +4 -12
- package/lib/axes/Axis.d.ts +20 -25
- package/lib/axes/AxisBuilder.d.ts +7 -4
- package/lib/axes/AxisBuilder.js +12 -8
- package/lib/axes/AxisComponent.d.ts +6 -9
- package/lib/axes/AxisComponent.js +1 -2
- package/lib/axes/ColorPaletteCollectionComponent.d.ts +5 -12
- package/lib/axes/ColorPaletteCollectionComponent.js +67 -36
- package/lib/dashboards/DashboardComponent.d.ts +4 -17
- package/lib/dashboards/DashboardComponent.js +20 -67
- package/lib/dashboards/DashboardDesign.d.ts +5 -20
- package/lib/dashboards/DashboardUpgrader.js +36 -1
- package/lib/dashboards/DashboardViewComponent.d.ts +5 -34
- package/lib/dashboards/DashboardViewComponent.js +112 -136
- package/lib/dashboards/FontStyleEditor.d.ts +8 -0
- package/lib/dashboards/FontStyleEditor.js +130 -0
- package/lib/dashboards/LayoutOptionsComponent.d.ts +0 -1
- package/lib/dashboards/LayoutOptionsComponent.js +209 -39
- package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -2
- package/lib/dashboards/ServerDashboardDataSource.js +52 -33
- package/lib/dashboards/SettingsModalComponent.d.ts +4 -15
- package/lib/dashboards/SettingsModalComponent.js +24 -38
- package/lib/dashboards/WidgetComponent.d.ts +3 -3
- package/lib/dashboards/WidgetComponent.js +3 -6
- package/lib/dashboards/WidgetDataSourcePrioritizer.d.ts +20 -0
- package/lib/dashboards/WidgetDataSourcePrioritizer.js +72 -0
- package/lib/dashboards/layoutOptions.d.ts +83 -0
- package/lib/dashboards/layoutOptions.js +436 -10
- package/lib/datagrids/DatagridComponent.d.ts +2 -9
- package/lib/datagrids/DatagridDataSource.d.ts +3 -3
- package/lib/datagrids/DatagridDataSource.js +0 -14
- package/lib/datagrids/DatagridDesign.d.ts +7 -6
- package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -93
- package/lib/datagrids/DatagridDesignerComponent.js +8 -6
- package/lib/datagrids/DatagridViewComponent.js +1 -1
- package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -20
- package/lib/datagrids/FindReplaceModalComponent.js +27 -13
- package/lib/datagrids/ServerDatagridDataSource.d.ts +8 -7
- package/lib/datagrids/ServerDatagridDataSource.js +88 -36
- package/lib/demo.js +4 -4
- package/lib/index.css +5 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +0 -1
- package/lib/layouts/LayoutManager.d.ts +33 -29
- package/lib/layouts/LayoutManager.js +2 -8
- package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +26 -56
- package/lib/layouts/blocks/BlocksDisplayComponent.js +122 -205
- package/lib/layouts/blocks/BlocksLayoutManager.d.ts +6 -22
- package/lib/layouts/blocks/BlocksLayoutManager.js +5 -14
- package/lib/layouts/blocks/HorizontalBlockComponent.d.ts +5 -4
- package/lib/layouts/blocks/HorizontalBlockComponent.js +5 -5
- package/lib/layouts/grid/GridLayoutManager.d.ts +2 -1
- package/lib/mWaterLoader.d.ts +2 -0
- package/lib/mWaterLoader.js +2 -1
- package/lib/maps/AddLayerComponent.d.ts +6 -8
- package/lib/maps/AddLayerComponent.js +6 -6
- package/lib/maps/BingLayer.js +10 -20
- package/lib/maps/BufferLayer.js +5 -2
- package/lib/maps/ChoroplethLayer.js +2 -1
- package/lib/maps/ClusterLayer.js +3 -1
- package/lib/maps/DirectMapDataSource.d.ts +5 -2
- package/lib/maps/DirectMapDataSource.js +2 -1
- package/lib/maps/EditPopupComponent.js +2 -1
- package/lib/maps/GridLayer.js +5 -3
- package/lib/maps/GridLayerDesigner.js +0 -1
- package/lib/maps/LayerSwitcherComponent.js +1 -1
- package/lib/maps/MapComponent.d.ts +3 -11
- package/lib/maps/MapComponent.js +3 -3
- package/lib/maps/MapDesign.d.ts +2 -13
- package/lib/maps/MapFiltersDesignerComponent.d.ts +0 -4
- package/lib/maps/MapFiltersDesignerComponent.js +4 -5
- package/lib/maps/MarkersLayer.js +30 -25
- package/lib/maps/RasterMapViewComponent.d.ts +3 -13
- package/lib/maps/RasterMapViewComponent.js +3 -3
- package/lib/maps/RegionSelectComponent.d.ts +2 -1
- package/lib/maps/ServerMapDataSource.d.ts +3 -4
- package/lib/maps/ServerMapDataSource.js +5 -5
- package/lib/maps/VectorMapViewComponent.js +2 -1
- package/lib/maps/mapSymbols.js +2 -0
- package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/lib/maps/vectorMaps.d.ts +1 -0
- package/lib/maps/vectorMaps.js +70 -56
- package/lib/quickfilter/QuickfilterCompiler.d.ts +1 -1
- package/lib/quickfilter/QuickfiltersComponent.d.ts +1 -4
- package/lib/quickfilter/QuickfiltersComponent.js +3 -3
- package/lib/richtext/DropdownPaletteItem.d.ts +32 -0
- package/lib/richtext/DropdownPaletteItem.js +82 -0
- package/lib/richtext/FontColorPaletteItem.d.ts +1 -5
- package/lib/richtext/FontColorPaletteItem.js +32 -27
- package/lib/richtext/ItemsHtmlConverter.js +12 -3
- package/lib/richtext/RichTextComponent.d.ts +26 -52
- package/lib/richtext/RichTextComponent.js +166 -128
- package/lib/valueFormatter.js +6 -1
- package/lib/wellknown.d.ts +5 -0
- package/lib/wellknown.js +288 -0
- package/lib/widgets/DropdownWidgetComponent.d.ts +8 -25
- package/lib/widgets/DropdownWidgetComponent.js +48 -25
- package/lib/widgets/IFrameWidgetComponent.d.ts +3 -11
- package/lib/widgets/ImageWidgetComponent.d.ts +8 -27
- package/lib/widgets/MapWidget.d.ts +4 -7
- package/lib/widgets/MapWidget.js +2 -1
- package/lib/widgets/MarkdownWidget.d.ts +2 -7
- package/lib/widgets/TOCWidget.d.ts +2 -9
- package/lib/widgets/TOCWidget.js +2 -1
- package/lib/widgets/Widget.d.ts +2 -0
- package/lib/widgets/WidgetDataSource.d.ts +3 -1
- package/lib/widgets/charts/Chart.d.ts +0 -1
- package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartViewComponent.js +11 -3
- package/lib/widgets/charts/ChartWidget.d.ts +1 -74
- package/lib/widgets/charts/ChartWidget.js +4 -183
- package/lib/widgets/charts/ChartWidgetComponent.d.ts +51 -0
- package/lib/widgets/charts/ChartWidgetComponent.js +167 -0
- package/lib/widgets/charts/calendar/CalendarChartViewComponent.d.ts +1 -4
- package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +4 -4
- package/lib/widgets/charts/imagemosaic/ImagePopupComponent.d.ts +2 -7
- package/lib/widgets/charts/layered/LayeredChart.d.ts +5 -10
- package/lib/widgets/charts/layered/LayeredChart.js +6 -7
- package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +4 -2
- package/lib/widgets/charts/layered/LayeredChartCompiler.js +46 -32
- package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +4 -0
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +5 -31
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +21 -3
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +1 -7
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -1
- package/lib/widgets/charts/layered/LayeredChartViewComponent.d.ts +1 -4
- package/lib/widgets/charts/layered/LayeredChartViewComponent.js +89 -38
- package/lib/widgets/charts/pivot/IntersectionDesignerComponent.d.ts +5 -105
- package/lib/widgets/charts/pivot/IntersectionDesignerComponent.js +122 -166
- package/lib/widgets/charts/pivot/PivotChart.d.ts +6 -0
- package/lib/widgets/charts/pivot/PivotChart.js +47 -17
- package/lib/widgets/charts/pivot/PivotChartDesign.d.ts +11 -0
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +11 -7
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +1 -1
- package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +2 -2
- package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +20 -36
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +0 -1
- package/lib/widgets/charts/pivot/PivotChartQueryBuilder.d.ts +23 -2
- package/lib/widgets/charts/pivot/PivotChartQueryBuilder.js +215 -181
- package/lib/widgets/charts/pivot/PivotChartUtils.d.ts +2 -2
- package/lib/widgets/charts/pivot/PivotChartViewComponent.d.ts +9 -47
- package/lib/widgets/charts/pivot/PivotChartViewComponent.js +20 -60
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +55 -58
- package/lib/widgets/charts/table/TableChart.js +8 -4
- package/lib/widgets/charts/table/TableChartDesignerComponent.js +3 -3
- package/lib/widgets/charts/table/TableChartViewComponent.js +30 -16
- package/lib/widgets/text/ExprInsertModalComponent.d.ts +2 -13
- package/lib/widgets/text/ExprUpdateModalComponent.d.ts +2 -13
- package/lib/widgets/text/TextComponent.d.ts +5 -12
- package/lib/widgets/text/TextComponent.js +19 -39
- package/lib/widgets/text/TextWidget.d.ts +2 -1
- package/lib/widgets/text/TextWidget.js +5 -1
- package/lib/widgets/text/TextWidgetComponent.d.ts +15 -3
- package/lib/widgets/text/TextWidgetComponent.js +76 -19
- package/lib/widgets/text/TextWidgetDesign.d.ts +16 -2
- package/lib/widgets/text/TextWidgetDesign.js +6 -0
- package/package.json +4 -4
- package/src/ColorComponent.tsx +177 -0
- package/src/ColorSchemeFactory.ts +12 -6
- package/src/CustomColorsContext.tsx +8 -0
- package/src/FiltersDesignerComponent.ts +3 -4
- package/src/GlobalFilter.ts +17 -0
- package/src/LocaleContextInjector.tsx +14 -13
- package/src/MWaterAddRelatedFormComponent.ts +3 -3
- package/src/MWaterAddRelatedIndicatorComponent.ts +6 -6
- package/src/MWaterCompleteTableSelectComponent.tsx +36 -36
- package/src/MWaterContextComponent.tsx +42 -33
- package/src/MWaterCustomTablesetListComponent.tsx +21 -3
- package/src/MWaterGlobalFiltersComponent.ts +8 -8
- package/src/MWaterLoaderComponent.ts +14 -4
- package/src/MWaterTableSelectComponent.tsx +11 -12
- package/src/{UIComponents.ts → UIComponents.tsx} +7 -15
- package/src/axes/Axis.ts +24 -25
- package/src/axes/AxisBuilder.ts +16 -13
- package/src/axes/AxisComponent.ts +3 -4
- package/src/axes/{ColorPaletteCollectionComponent.ts → ColorPaletteCollectionComponent.tsx} +87 -61
- package/src/dashboards/DashboardComponent.tsx +73 -147
- package/src/dashboards/DashboardDesign.ts +5 -25
- package/src/dashboards/DashboardUpgrader.ts +41 -1
- package/src/dashboards/DashboardViewComponent.tsx +313 -0
- package/src/dashboards/FontStyleEditor.tsx +166 -0
- package/src/dashboards/LayoutOptionsComponent.tsx +377 -71
- package/src/dashboards/ServerDashboardDataSource.ts +52 -33
- package/src/dashboards/SettingsModalComponent.tsx +170 -0
- package/src/dashboards/WidgetComponent.tsx +6 -12
- package/src/dashboards/WidgetDataSourcePrioritizer.ts +82 -0
- package/src/dashboards/layoutOptions.tsx +581 -0
- package/src/datagrids/DatagridDataSource.ts +6 -12
- package/src/datagrids/DatagridDesign.ts +8 -3
- package/src/datagrids/DatagridDesignerComponent.tsx +22 -18
- package/src/datagrids/DatagridViewComponent.ts +3 -3
- package/src/datagrids/ExprCellComponent.ts +0 -1
- package/src/datagrids/FindReplaceModalComponent.ts +39 -22
- package/src/datagrids/ServerDatagridDataSource.ts +107 -45
- package/src/demo.ts +4 -4
- package/src/index.css +5 -0
- package/src/index.ts +2 -1
- package/src/layouts/LayoutManager.ts +44 -42
- package/src/layouts/blocks/BlocksDisplayComponent.tsx +498 -0
- package/src/layouts/blocks/BlocksLayoutManager.ts +6 -15
- package/src/layouts/blocks/HorizontalBlockComponent.ts +9 -8
- package/src/mWaterLoader.ts +4 -1
- package/src/maps/AddLayerComponent.ts +9 -9
- package/src/maps/BingLayer.ts +16 -26
- package/src/maps/BufferLayer.ts +5 -2
- package/src/maps/ChoroplethLayer.ts +2 -1
- package/src/maps/ClusterLayer.ts +3 -1
- package/src/maps/DirectMapDataSource.ts +12 -3
- package/src/maps/EditPopupComponent.ts +2 -1
- package/src/maps/GridLayer.ts +5 -3
- package/src/maps/GridLayerDesigner.tsx +0 -1
- package/src/maps/LayerSwitcherComponent.tsx +1 -1
- package/src/maps/MapComponent.ts +3 -3
- package/src/maps/MapDesign.ts +2 -17
- package/src/maps/{MapFiltersDesignerComponent.ts → MapFiltersDesignerComponent.tsx} +25 -25
- package/src/maps/MarkersLayer.ts +38 -41
- package/src/maps/RasterMapViewComponent.ts +3 -3
- package/src/maps/ServerMapDataSource.ts +8 -8
- package/src/maps/VectorMapViewComponent.tsx +2 -2
- package/src/maps/mapSymbols.ts +2 -0
- package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/src/maps/vectorMaps.tsx +88 -74
- package/src/quickfilter/QuickfilterCompiler.ts +1 -1
- package/src/quickfilter/QuickfiltersComponent.ts +3 -3
- package/src/richtext/DropdownPaletteItem.tsx +144 -0
- package/src/richtext/FontColorPaletteItem.tsx +160 -0
- package/src/richtext/ItemsHtmlConverter.ts +15 -5
- package/src/richtext/RichTextComponent.tsx +274 -232
- package/src/valueFormatter.ts +5 -1
- package/src/wellknown.ts +286 -0
- package/src/widgets/DropdownWidgetComponent.tsx +75 -0
- package/src/widgets/MapWidget.ts +5 -2
- package/src/widgets/TOCWidget.ts +2 -1
- package/src/widgets/Widget.ts +3 -0
- package/src/widgets/WidgetDataSource.ts +3 -1
- package/src/widgets/charts/Chart.ts +1 -1
- package/src/widgets/charts/ChartViewComponent.ts +16 -3
- package/src/widgets/charts/ChartWidget.ts +3 -275
- package/src/widgets/charts/ChartWidgetComponent.tsx +281 -0
- package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +4 -4
- package/src/widgets/charts/layered/LayeredChart.ts +4 -6
- package/src/widgets/charts/layered/LayeredChartCompiler.ts +80 -63
- package/src/widgets/charts/layered/LayeredChartDesign.ts +7 -1
- package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +43 -10
- package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +6 -6
- package/src/widgets/charts/layered/LayeredChartViewComponent.ts +140 -88
- package/src/widgets/charts/pivot/IntersectionDesignerComponent.tsx +305 -221
- package/src/widgets/charts/pivot/PivotChart.ts +56 -18
- package/src/widgets/charts/pivot/PivotChartDesign.ts +12 -0
- package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +4 -3
- package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +39 -76
- package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +0 -1
- package/src/widgets/charts/pivot/PivotChartQueryBuilder.ts +230 -189
- package/src/widgets/charts/pivot/PivotChartUtils.ts +4 -4
- package/src/widgets/charts/pivot/{PivotChartViewComponent.ts → PivotChartViewComponent.tsx} +86 -89
- package/src/widgets/charts/table/TableChart.ts +8 -4
- package/src/widgets/charts/table/TableChartDesignerComponent.ts +4 -4
- package/src/widgets/charts/table/TableChartViewComponent.ts +32 -19
- package/src/widgets/text/TextComponent.tsx +47 -49
- package/src/widgets/text/TextWidget.ts +8 -3
- package/src/widgets/text/TextWidgetComponent.tsx +249 -0
- package/src/widgets/text/TextWidgetDesign.ts +26 -2
- package/src/ColorComponent.ts +0 -117
- package/src/dashboards/DashboardViewComponent.ts +0 -304
- package/src/dashboards/SettingsModalComponent.ts +0 -169
- package/src/dashboards/layoutOptions.ts +0 -40
- package/src/layout-styles.css +0 -263
- package/src/layouts/blocks/BlocksDisplayComponent.ts +0 -461
- package/src/layouts/grid/GridLayoutComponent.ts +0 -67
- package/src/layouts/grid/GridLayoutManager.ts +0 -185
- package/src/layouts/grid/LegoLayoutEngine.ts +0 -142
- package/src/layouts/grid/PaletteItemComponent.ts +0 -28
- package/src/layouts/grid/README.md +0 -14
- package/src/layouts/grid/WidgetContainerComponent.ts +0 -420
- package/src/richtext/FontColorPaletteItem.ts +0 -172
- package/src/richtext/FontSizePaletteItem.ts +0 -110
- package/src/widgets/DropdownWidgetComponent.ts +0 -78
- 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
|
+
}
|