@mwater/visualization 5.2.0 → 5.3.1
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/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 +5 -16
- package/lib/MWaterCompleteTableSelectComponent.js +36 -36
- package/lib/MWaterContextComponent.d.ts +4 -6
- package/lib/MWaterContextComponent.js +4 -13
- package/lib/MWaterLoaderComponent.d.ts +5 -3
- package/lib/MWaterLoaderComponent.js +2 -1
- 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/AxisBuilder.d.ts +7 -4
- package/lib/axes/AxisBuilder.js +3 -1
- package/lib/axes/AxisComponent.d.ts +2 -5
- 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 -12
- package/lib/dashboards/DashboardComponent.js +18 -38
- package/lib/dashboards/DashboardDesign.d.ts +3 -3
- package/lib/dashboards/DashboardUpgrader.js +36 -1
- package/lib/dashboards/DashboardViewComponent.d.ts +5 -34
- package/lib/dashboards/DashboardViewComponent.js +109 -132
- 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 +211 -42
- package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -2
- package/lib/dashboards/ServerDashboardDataSource.js +52 -33
- 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/DatagridDesign.d.ts +7 -6
- package/lib/datagrids/ServerDatagridDataSource.d.ts +7 -6
- package/lib/datagrids/ServerDatagridDataSource.js +87 -33
- package/lib/demo.js +3 -3
- package/lib/index.css +5 -0
- package/lib/index.d.ts +1 -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 -57
- 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/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 +2 -1
- package/lib/maps/ChoroplethLayer.js +2 -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/MapComponent.d.ts +1 -4
- package/lib/maps/MapComponent.js +3 -3
- package/lib/maps/MarkersLayer.js +30 -25
- package/lib/maps/RasterMapViewComponent.d.ts +1 -4
- package/lib/maps/RasterMapViewComponent.js +3 -3
- package/lib/maps/ServerMapDataSource.d.ts +2 -3
- 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.js +61 -55
- 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 +1 -2
- package/lib/widgets/ImageWidgetComponent.d.ts +2 -3
- package/lib/widgets/MapWidget.d.ts +2 -0
- package/lib/widgets/MapWidget.js +2 -1
- 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 -62
- 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/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 +3 -0
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +21 -3
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +1 -2
- 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 -112
- 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 +1 -1
- 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 -28
- package/lib/widgets/charts/pivot/PivotChartViewComponent.js +20 -60
- 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 +11 -11
- 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 +13 -1
- 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 +9 -0
- package/src/FiltersDesignerComponent.ts +3 -4
- 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 +8 -17
- package/src/MWaterLoaderComponent.ts +6 -3
- package/src/MWaterTableSelectComponent.tsx +11 -12
- package/src/{UIComponents.ts → UIComponents.tsx} +7 -15
- package/src/axes/AxisBuilder.ts +7 -5
- package/src/axes/AxisComponent.ts +3 -4
- package/src/axes/{ColorPaletteCollectionComponent.ts → ColorPaletteCollectionComponent.tsx} +87 -61
- package/src/dashboards/DashboardComponent.tsx +71 -107
- package/src/dashboards/DashboardDesign.ts +3 -3
- 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 +380 -75
- package/src/dashboards/ServerDashboardDataSource.ts +52 -33
- package/src/dashboards/WidgetComponent.tsx +6 -12
- package/src/dashboards/WidgetDataSourcePrioritizer.ts +82 -0
- package/src/dashboards/layoutOptions.tsx +581 -0
- package/src/datagrids/DatagridDesign.ts +8 -3
- package/src/datagrids/ServerDatagridDataSource.ts +106 -43
- package/src/demo.ts +3 -3
- package/src/index.css +5 -0
- package/src/index.ts +1 -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 +2 -1
- package/src/maps/ChoroplethLayer.ts +2 -1
- package/src/maps/DirectMapDataSource.ts +12 -3
- package/src/maps/EditPopupComponent.ts +2 -1
- package/src/maps/MapComponent.ts +3 -3
- package/src/maps/MarkersLayer.ts +38 -41
- package/src/maps/RasterMapViewComponent.ts +3 -3
- package/src/maps/ServerMapDataSource.ts +7 -7
- package/src/maps/VectorMapViewComponent.tsx +2 -1
- package/src/maps/mapSymbols.ts +2 -0
- package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/src/maps/vectorMaps.tsx +79 -74
- 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 +13 -14
- 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 +22 -1
- package/src/ColorComponent.ts +0 -117
- package/src/dashboards/DashboardViewComponent.ts +0 -303
- 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,249 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import _ from "lodash"
|
|
3
|
+
import TextComponent from "./TextComponent"
|
|
4
|
+
import TextWidget from "./TextWidget"
|
|
5
|
+
import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent"
|
|
6
|
+
import { DataSource, Schema } from "@mwater/expressions"
|
|
7
|
+
import { JsonQLFilter } from "../../JsonQLFilter"
|
|
8
|
+
import { TextWidgetDesign } from "./TextWidgetDesign"
|
|
9
|
+
import { HtmlItem } from "../../richtext/ItemsHtmlConverter"
|
|
10
|
+
import { HtmlItemExpr } from "../../richtext/ExprItemsHtmlConverter"
|
|
11
|
+
import DropdownWidgetComponent from "../DropdownWidgetComponent"
|
|
12
|
+
import ActionCancelModalComponent from "@mwater/react-library/lib/ActionCancelModalComponent"
|
|
13
|
+
import { FormGroup } from "@mwater/react-library/lib/bootstrap"
|
|
14
|
+
import ColorComponent from "../../ColorComponent"
|
|
15
|
+
import { Select } from "@mwater/react-library/lib/bootstrap"
|
|
16
|
+
|
|
17
|
+
export interface TextWidgetComponentProps {
|
|
18
|
+
design: TextWidgetDesign
|
|
19
|
+
/** Called with new design. null/undefined for readonly */
|
|
20
|
+
onDesignChange?: (design: TextWidgetDesign) => void
|
|
21
|
+
filters: JsonQLFilter[]
|
|
22
|
+
schema: Schema
|
|
23
|
+
/** Data source to use for chart */
|
|
24
|
+
dataSource: DataSource
|
|
25
|
+
widgetDataSource: any
|
|
26
|
+
width?: number
|
|
27
|
+
height?: number
|
|
28
|
+
/** Table that is filtered to have one row */
|
|
29
|
+
singleRowTable?: string
|
|
30
|
+
namedStrings?: any
|
|
31
|
+
/** A key that changes when the widget should be refreshed */
|
|
32
|
+
refreshKey?: any
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Widget which displays styled text with embedded expressions
|
|
36
|
+
export default class TextWidgetComponent extends AsyncLoadComponent<TextWidgetComponentProps, { loading: boolean, exprValues: any, error: any, cacheExpiry: any, editModalOpen: boolean }> {
|
|
37
|
+
divComp: HTMLElement | null
|
|
38
|
+
constructor(props: TextWidgetComponentProps) {
|
|
39
|
+
super(props)
|
|
40
|
+
|
|
41
|
+
this.state = {
|
|
42
|
+
loading: false,
|
|
43
|
+
// Map of expression id to expression value
|
|
44
|
+
exprValues: {},
|
|
45
|
+
error: null,
|
|
46
|
+
cacheExpiry: props.dataSource.getCacheExpiry(), // Save cache expiry to see if changes
|
|
47
|
+
editModalOpen: false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Override to determine if a load is needed. Not called on mounting
|
|
52
|
+
isLoadNeeded(newProps: any, oldProps: any) {
|
|
53
|
+
// Get expression items recursively
|
|
54
|
+
function getExprItems(items: HtmlItem[]): HtmlItemExpr[] {
|
|
55
|
+
let exprItems: HtmlItemExpr[] = []
|
|
56
|
+
for (let item of items || []) {
|
|
57
|
+
if (typeof item === "object") {
|
|
58
|
+
if (item.type === "expr") {
|
|
59
|
+
exprItems.push(item as HtmlItemExpr)
|
|
60
|
+
}
|
|
61
|
+
if (item.items) {
|
|
62
|
+
exprItems = exprItems.concat(getExprItems(item.items))
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return exprItems
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Reload if filters or expressions have changed or cache expiry
|
|
70
|
+
return (
|
|
71
|
+
!_.isEqual(newProps.filters, oldProps.filters) ||
|
|
72
|
+
!_.isEqual(getExprItems(newProps.design.items), getExprItems(oldProps.design.items)) ||
|
|
73
|
+
newProps.dataSource.getCacheExpiry() !== this.state.cacheExpiry ||
|
|
74
|
+
newProps.refreshKey !== oldProps.refreshKey
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Call callback with state changes
|
|
79
|
+
load(props: TextWidgetComponentProps, prevProps: TextWidgetComponentProps, callback: any) {
|
|
80
|
+
// Shortcut if no expressions in text widget
|
|
81
|
+
const widget = new TextWidget()
|
|
82
|
+
if (widget.getExprItems(props.design.items).length === 0) {
|
|
83
|
+
callback({ error: null, exprValues: {} }, props.dataSource.getCacheExpiry())
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Get data
|
|
88
|
+
props.widgetDataSource.getData(props.design, props.filters, (error: any, data: any) => {
|
|
89
|
+
callback({ error, exprValues: data || {}, cacheExpiry: props.dataSource.getCacheExpiry() })
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
scrollToTOCEntry(entryId: any) {
|
|
94
|
+
// Find entry in divComp
|
|
95
|
+
const entries = this.divComp!.querySelectorAll("h1,h2,h3,h4,h5,h6,h7,h8,h9")
|
|
96
|
+
|
|
97
|
+
const entry = entries[entryId]
|
|
98
|
+
if (entry) {
|
|
99
|
+
return entry.scrollIntoView(true)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
handleEditClick = () => {
|
|
104
|
+
this.setState({ editModalOpen: true })
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
handleEditModalClose = () => {
|
|
108
|
+
this.setState({ editModalOpen: false })
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
handleBackgroundColorChange = (color: string | null) => {
|
|
112
|
+
const newDesign = { ...this.props.design, backgroundColor: color }
|
|
113
|
+
this.props.onDesignChange!(newDesign)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
handleSpacingChange = (spacing: number | null) => {
|
|
117
|
+
const newDesign = { ...this.props.design, padding: spacing ?? undefined }
|
|
118
|
+
this.props.onDesignChange!(newDesign)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
handleBorderColorChange = (color: string | null) => {
|
|
122
|
+
const newDesign = { ...this.props.design, borderColor: color }
|
|
123
|
+
this.props.onDesignChange!(newDesign)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
handleBorderThicknessChange = (thickness: number | null) => {
|
|
127
|
+
const newDesign = { ...this.props.design, borderThickness: thickness }
|
|
128
|
+
this.props.onDesignChange!(newDesign)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
handleBorderRadiusChange = (radius: number | null) => {
|
|
132
|
+
const newDesign = { ...this.props.design, borderRadius: radius }
|
|
133
|
+
this.props.onDesignChange!(newDesign)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
renderEditModal() {
|
|
137
|
+
if (!this.state.editModalOpen) {
|
|
138
|
+
return null
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const spacingOptions = [0, 5, 10, 15, 20, 25, 30, 35, 40].map(value => ({ value, label: `${value}px` }))
|
|
142
|
+
const borderThicknessOptions = [0, 1, 2, 3, 4, 5].map(value => ({ value, label: value === 0 ? "None" : `${value}px` }))
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<ActionCancelModalComponent
|
|
146
|
+
title="Edit Text Widget"
|
|
147
|
+
onCancel={this.handleEditModalClose}
|
|
148
|
+
onAction={this.handleEditModalClose}
|
|
149
|
+
>
|
|
150
|
+
<FormGroup label="Background Color">
|
|
151
|
+
<ColorComponent
|
|
152
|
+
color={this.props.design.backgroundColor || null}
|
|
153
|
+
onChange={this.handleBackgroundColorChange}
|
|
154
|
+
/>
|
|
155
|
+
<div className="text-muted">
|
|
156
|
+
Choose a background color for the text widget
|
|
157
|
+
</div>
|
|
158
|
+
</FormGroup>
|
|
159
|
+
<FormGroup label="Padding">
|
|
160
|
+
<Select
|
|
161
|
+
value={this.props.design.padding ?? 0}
|
|
162
|
+
onChange={this.handleSpacingChange}
|
|
163
|
+
options={spacingOptions}
|
|
164
|
+
/>
|
|
165
|
+
<div className="text-muted">
|
|
166
|
+
Choose extra padding for the text widget
|
|
167
|
+
</div>
|
|
168
|
+
</FormGroup>
|
|
169
|
+
<FormGroup label="Border Thickness" help="Choose the border thickness for the text widget">
|
|
170
|
+
<Select
|
|
171
|
+
value={this.props.design.borderThickness ?? 0}
|
|
172
|
+
onChange={this.handleBorderThicknessChange}
|
|
173
|
+
options={borderThicknessOptions}
|
|
174
|
+
/>
|
|
175
|
+
</FormGroup>
|
|
176
|
+
{this.props.design.borderThickness &&
|
|
177
|
+
<FormGroup label="Border Color" help="Choose the border color for the text widget">
|
|
178
|
+
<ColorComponent
|
|
179
|
+
color={this.props.design.borderColor || null}
|
|
180
|
+
onChange={this.handleBorderColorChange}
|
|
181
|
+
/>
|
|
182
|
+
</FormGroup>
|
|
183
|
+
}
|
|
184
|
+
{this.props.design.borderThickness &&
|
|
185
|
+
<FormGroup label="Border Radius" help="Choose the border radius for the text widget">
|
|
186
|
+
<Select
|
|
187
|
+
value={this.props.design.borderRadius ?? 0}
|
|
188
|
+
onChange={this.handleBorderRadiusChange}
|
|
189
|
+
options={spacingOptions}
|
|
190
|
+
/>
|
|
191
|
+
</FormGroup>
|
|
192
|
+
}
|
|
193
|
+
</ActionCancelModalComponent>
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
renderTextComponent() {
|
|
198
|
+
// If loading, don't display old values
|
|
199
|
+
const exprValues = !this.state.loading ? this.state.exprValues : {}
|
|
200
|
+
|
|
201
|
+
const padding = this.props.design.padding ?? 0
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<TextComponent
|
|
205
|
+
design={this.props.design}
|
|
206
|
+
onDesignChange={this.props.onDesignChange}
|
|
207
|
+
schema={this.props.schema}
|
|
208
|
+
dataSource={this.props.dataSource}
|
|
209
|
+
exprValues={exprValues}
|
|
210
|
+
width={this.props.width ? this.props.width - padding * 2 : undefined}
|
|
211
|
+
height={this.props.height ? this.props.height - padding * 2 : undefined}
|
|
212
|
+
singleRowTable={this.props.singleRowTable}
|
|
213
|
+
namedStrings={this.props.namedStrings}
|
|
214
|
+
/>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
render() {
|
|
219
|
+
const borderStyle = this.props.design.borderThickness && this.props.design.borderColor
|
|
220
|
+
? `${this.props.design.borderThickness}px solid ${this.props.design.borderColor}`
|
|
221
|
+
: undefined
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<div
|
|
225
|
+
style={{
|
|
226
|
+
backgroundColor: this.props.design.backgroundColor ?? undefined,
|
|
227
|
+
padding: this.props.design.padding != null ? `${this.props.design.padding}px` : undefined,
|
|
228
|
+
border: borderStyle,
|
|
229
|
+
borderRadius: this.props.design.borderRadius != null ? `${this.props.design.borderRadius}px` : undefined
|
|
230
|
+
}}
|
|
231
|
+
ref={comp => this.divComp = comp}
|
|
232
|
+
>
|
|
233
|
+
{this.props.onDesignChange ? (
|
|
234
|
+
<DropdownWidgetComponent
|
|
235
|
+
dropdownItems={[{
|
|
236
|
+
label: "Edit",
|
|
237
|
+
onClick: this.handleEditClick
|
|
238
|
+
}]}
|
|
239
|
+
>
|
|
240
|
+
{this.renderTextComponent()}
|
|
241
|
+
</DropdownWidgetComponent>
|
|
242
|
+
) : (
|
|
243
|
+
this.renderTextComponent()
|
|
244
|
+
)}
|
|
245
|
+
{this.renderEditModal()}
|
|
246
|
+
</div>
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
@@ -6,5 +6,26 @@ export interface TextWidgetDesign {
|
|
|
6
6
|
items: (HtmlItem | HtmlItemExpr)[]
|
|
7
7
|
|
|
8
8
|
/** "title" for title block. default is "default" */
|
|
9
|
-
style?: "title" | "default"
|
|
9
|
+
style?: "title" | "default" | "header" | "footer"
|
|
10
|
+
|
|
11
|
+
/** Background color of the text widget (optional) */
|
|
12
|
+
backgroundColor?: string | null
|
|
13
|
+
|
|
14
|
+
/** Extra padding for the text widget */
|
|
15
|
+
padding?: number
|
|
16
|
+
|
|
17
|
+
/** Border color of the text widget (optional) */
|
|
18
|
+
borderColor?: string | null
|
|
19
|
+
|
|
20
|
+
/** Border thickness of the text widget (optional) */
|
|
21
|
+
borderThickness?: number | null
|
|
22
|
+
|
|
23
|
+
/** Border radius of the text widget (optional) */
|
|
24
|
+
borderRadius?: number | null
|
|
10
25
|
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/** Returns true if the text widget design is empty. */
|
|
29
|
+
export function isEmptyTextWidgetDesign(design: TextWidgetDesign | undefined): boolean {
|
|
30
|
+
return design == null || design.items.length === 0
|
|
31
|
+
}
|
package/src/ColorComponent.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import PropTypes from "prop-types"
|
|
2
|
-
import React, { CSSProperties } from "react"
|
|
3
|
-
const R = React.createElement
|
|
4
|
-
|
|
5
|
-
import ClickOutHandler from "react-onclickout"
|
|
6
|
-
import { SketchPicker } from "react-color"
|
|
7
|
-
import { SwatchesPicker } from "react-color"
|
|
8
|
-
|
|
9
|
-
interface ColorComponentProps {
|
|
10
|
-
color: string | null | undefined
|
|
11
|
-
onChange: (value: string | null) => void
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface ColorComponentState {
|
|
15
|
-
open: any
|
|
16
|
-
advanced: any
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Simple color well with popup
|
|
20
|
-
export default class ColorComponent extends React.Component<ColorComponentProps, ColorComponentState> {
|
|
21
|
-
constructor(props: any) {
|
|
22
|
-
super(props)
|
|
23
|
-
this.state = { open: false, advanced: false }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
handleClick = () => {
|
|
27
|
-
return this.setState({ open: !this.state.open, advanced: false })
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
handleClose = (color: any) => {
|
|
31
|
-
return this.props.onChange(color.hex)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
handleReset = () => {
|
|
35
|
-
this.setState({ open: false })
|
|
36
|
-
return this.props.onChange(null)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
handleTransparent = () => {
|
|
40
|
-
this.setState({ open: false })
|
|
41
|
-
return this.props.onChange("transparent")
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
handleAdvanced = () => {
|
|
45
|
-
return this.setState({ advanced: !this.state.advanced })
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
render() {
|
|
49
|
-
const style: CSSProperties = {
|
|
50
|
-
height: 20,
|
|
51
|
-
width: 20,
|
|
52
|
-
border: "solid 2px #888",
|
|
53
|
-
borderRadius: 4,
|
|
54
|
-
backgroundColor: this.props.color || undefined,
|
|
55
|
-
cursor: "pointer",
|
|
56
|
-
display: "inline-block"
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (!this.props.color) {
|
|
60
|
-
// http://lea.verou.me/css3patterns/#diagonal-stripes
|
|
61
|
-
style.backgroundColor = "#AAA"
|
|
62
|
-
style.backgroundImage =
|
|
63
|
-
"repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(255,255,255,.7) 2px, rgba(255,255,255,.7) 4px)"
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const popupPosition = {
|
|
67
|
-
position: "absolute",
|
|
68
|
-
top: 0,
|
|
69
|
-
left: 30,
|
|
70
|
-
zIndex: 1000,
|
|
71
|
-
backgroundColor: "white",
|
|
72
|
-
border: "solid 1px #DDD",
|
|
73
|
-
borderRadius: 3
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return R(
|
|
77
|
-
"div",
|
|
78
|
-
{ style: { position: "relative", display: "inline-block" } },
|
|
79
|
-
R("div", { style, onClick: this.handleClick }),
|
|
80
|
-
this.state.open
|
|
81
|
-
? React.createElement(
|
|
82
|
-
ClickOutHandler,
|
|
83
|
-
{ onClickOut: () => this.setState({ open: false }) },
|
|
84
|
-
R(
|
|
85
|
-
"div",
|
|
86
|
-
{ style: popupPosition },
|
|
87
|
-
R(
|
|
88
|
-
"button",
|
|
89
|
-
{ type: "button", className: "btn btn-link btn-sm", onClick: this.handleReset },
|
|
90
|
-
R("i", { className: "fa fa-undo" }),
|
|
91
|
-
" Reset Color"
|
|
92
|
-
),
|
|
93
|
-
// R 'button', type: "button", className: "btn btn-link btn-sm", onClick: @handleTransparent,
|
|
94
|
-
// R 'i', className: "fa fa-ban"
|
|
95
|
-
// " None"
|
|
96
|
-
R(
|
|
97
|
-
"button",
|
|
98
|
-
{ type: "button", className: "btn btn-link btn-sm", onClick: this.handleAdvanced },
|
|
99
|
-
this.state.advanced ? "Basic" : "Advanced"
|
|
100
|
-
),
|
|
101
|
-
|
|
102
|
-
this.state.advanced
|
|
103
|
-
? React.createElement(SketchPicker, {
|
|
104
|
-
color: this.props.color || undefined,
|
|
105
|
-
disableAlpha: true,
|
|
106
|
-
onChangeComplete: this.handleClose
|
|
107
|
-
})
|
|
108
|
-
: React.createElement(SwatchesPicker, {
|
|
109
|
-
color: this.props.color || undefined,
|
|
110
|
-
onChangeComplete: this.handleClose
|
|
111
|
-
})
|
|
112
|
-
)
|
|
113
|
-
)
|
|
114
|
-
: undefined
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import _ from "lodash"
|
|
2
|
-
import PropTypes from "prop-types"
|
|
3
|
-
import React, { CSSProperties } from "react"
|
|
4
|
-
const R = React.createElement
|
|
5
|
-
|
|
6
|
-
import ImplicitFilterBuilder from "../ImplicitFilterBuilder"
|
|
7
|
-
import * as DashboardUtils from "./DashboardUtils"
|
|
8
|
-
import { DataSource, Schema } from "@mwater/expressions"
|
|
9
|
-
import WidgetFactory from "../widgets/WidgetFactory"
|
|
10
|
-
import WidgetScoper from "../widgets/WidgetScoper"
|
|
11
|
-
import ReactElementPrinter from "@mwater/react-library/lib/ReactElementPrinter"
|
|
12
|
-
import LayoutManager from "../layouts/LayoutManager"
|
|
13
|
-
import WidgetScopesViewComponent from "../widgets/WidgetScopesViewComponent"
|
|
14
|
-
import { getLayoutOptions } from "./layoutOptions"
|
|
15
|
-
import { WidgetComponent } from "./WidgetComponent"
|
|
16
|
-
import { DashboardDataSource, DashboardDesign, JsonQLFilter } from ".."
|
|
17
|
-
import { setPrintingModeEnabled } from "../maps/vectorMaps"
|
|
18
|
-
|
|
19
|
-
export interface DashboardViewComponentProps {
|
|
20
|
-
/** schema to use */
|
|
21
|
-
schema: Schema
|
|
22
|
-
/** data source to use. Only used when designing, for display uses dashboardDataSource */
|
|
23
|
-
dataSource: DataSource
|
|
24
|
-
/** dashboard data source */
|
|
25
|
-
dashboardDataSource: DashboardDataSource
|
|
26
|
-
|
|
27
|
-
design: DashboardDesign
|
|
28
|
-
|
|
29
|
-
/** Leave unset for readonly */
|
|
30
|
-
onDesignChange?: (design: DashboardDesign) => void
|
|
31
|
-
|
|
32
|
-
/** Called with (tableId, rowId) when item is clicked */
|
|
33
|
-
onRowClick?: (tableId: string, rowId: any) => void
|
|
34
|
-
|
|
35
|
-
/** Optional lookup of string name to value. Used for {{branding}} and other replacement strings in text widget */
|
|
36
|
-
namedStrings?: { [key: string]: string }
|
|
37
|
-
|
|
38
|
-
/** Filters to add to the dashboard (includes extra filters and any quickfilters from the dashboard component. Does not include dashboard level filters) */
|
|
39
|
-
filters?: JsonQLFilter[]
|
|
40
|
-
|
|
41
|
-
/** Entry to scroll to initially when dashboard is loaded */
|
|
42
|
-
initialTOCEntryScroll?: { widgetId: string; entryId: any }
|
|
43
|
-
|
|
44
|
-
/** True to hide scope display */
|
|
45
|
-
hideScopes?: boolean
|
|
46
|
-
|
|
47
|
-
/** True to render in print mode (prevents odd clipping issue) */
|
|
48
|
-
printMode?: boolean
|
|
49
|
-
|
|
50
|
-
/** Change to force a refresh */
|
|
51
|
-
refreshKey?: any
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Displays a dashboard, handling removing of widgets. No title bar or other decorations.
|
|
56
|
-
* Handles scoping and stores the state of scope
|
|
57
|
-
*/
|
|
58
|
-
export default class DashboardViewComponent extends React.Component<
|
|
59
|
-
DashboardViewComponentProps,
|
|
60
|
-
{ widgetScoper: WidgetScoper }
|
|
61
|
-
> {
|
|
62
|
-
static childContextTypes = { locale: PropTypes.string }
|
|
63
|
-
widgetComps: { [widgetId: string]: any }
|
|
64
|
-
|
|
65
|
-
// Pass locale down. Both here and DashboardViewComponent to ensure that quickfilters also get context
|
|
66
|
-
getChildContext() {
|
|
67
|
-
return { locale: this.props.design.locale }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
constructor(props: any) {
|
|
71
|
-
super(props)
|
|
72
|
-
this.state = {
|
|
73
|
-
widgetScoper: new WidgetScoper() // Empty scoping
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
this.widgetComps = {} // Lookup of widget components by id
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
componentDidMount() {
|
|
80
|
-
if (this.props.initialTOCEntryScroll) {
|
|
81
|
-
// Getting heights of widgets properly requires a 0 length timeout
|
|
82
|
-
setTimeout(() => {
|
|
83
|
-
return this.handleScrollToTOCEntry(
|
|
84
|
-
this.props.initialTOCEntryScroll!.widgetId,
|
|
85
|
-
this.props.initialTOCEntryScroll!.entryId
|
|
86
|
-
)
|
|
87
|
-
}, 0)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Add listener to localstorage to update clipboard display
|
|
91
|
-
return window.addEventListener("storage", this.handleStorageChange)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
componentWillUnmount() {
|
|
95
|
-
// Remove listener
|
|
96
|
-
return window.addEventListener("storage", this.handleStorageChange)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
handleStorageChange = () => {
|
|
100
|
-
return this.forceUpdate()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
handleScopeChange = (id: any, scope: any) => {
|
|
104
|
-
return this.setState({ widgetScoper: this.state.widgetScoper.applyScope(id, scope) })
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
handleRemoveScope = (id: any) => {
|
|
108
|
-
return this.setState({ widgetScoper: this.state.widgetScoper.applyScope(id, null) })
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
handleItemsChange = (items: any) => {
|
|
112
|
-
const design = _.extend({}, this.props.design, { items }) as DashboardDesign
|
|
113
|
-
return this.props.onDesignChange!(design)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Handle a change of the clipboard and determine which tables the clipboard block uses
|
|
117
|
-
handleClipboardChange = (block: any) => {
|
|
118
|
-
try {
|
|
119
|
-
// If empty, just set it
|
|
120
|
-
if (!block) {
|
|
121
|
-
window.localStorage.removeItem("DashboardViewComponent.clipboard")
|
|
122
|
-
this.forceUpdate()
|
|
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(this.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
|
-
return this.forceUpdate()
|
|
135
|
-
} catch (err) {
|
|
136
|
-
return alert("Clipboard not available")
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
getClipboardContents() {
|
|
141
|
-
try {
|
|
142
|
-
return JSON.parse(window.localStorage.getItem("DashboardViewComponent.clipboard") || "null")
|
|
143
|
-
} catch (err) {
|
|
144
|
-
return null
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Call to print the dashboard
|
|
149
|
-
print = async () => {
|
|
150
|
-
// Temporarily enable print mode for vector maps
|
|
151
|
-
try {
|
|
152
|
-
setPrintingModeEnabled(true)
|
|
153
|
-
|
|
154
|
-
// Create element at 1080 wide (use as standard printing width)
|
|
155
|
-
const elem = R(
|
|
156
|
-
"div",
|
|
157
|
-
{ style: { width: 1080 } },
|
|
158
|
-
R(DashboardViewComponent, _.extend({}, this.props, { onDesignChange: null, printMode: true }))
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
const printer = new ReactElementPrinter()
|
|
162
|
-
await printer.print(elem, { delay: 5000 })
|
|
163
|
-
} finally {
|
|
164
|
-
setPrintingModeEnabled(false)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Get filters from props filters combined with dashboard filters
|
|
169
|
-
getCompiledFilters() {
|
|
170
|
-
let compiledFilters = DashboardUtils.getCompiledFilters(
|
|
171
|
-
this.props.design,
|
|
172
|
-
this.props.schema,
|
|
173
|
-
DashboardUtils.getFilterableTables(this.props.design, this.props.schema)
|
|
174
|
-
)
|
|
175
|
-
compiledFilters = compiledFilters.concat(this.props.filters || [])
|
|
176
|
-
return compiledFilters
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Get list of TOC entries
|
|
180
|
-
getTOCEntries(layoutManager: any) {
|
|
181
|
-
const entries = []
|
|
182
|
-
|
|
183
|
-
for (let { id, type, design } of layoutManager.getAllWidgets(this.props.design.items)) {
|
|
184
|
-
const widget = WidgetFactory.createWidget(type)
|
|
185
|
-
// Add widgetId to each one
|
|
186
|
-
for (let entry of widget.getTOCEntries(design, this.props.namedStrings)) {
|
|
187
|
-
entries.push(_.extend({}, entry, { widgetId: id }))
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return entries
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
handleScrollToTOCEntry = (widgetId: any, entryId: any) => {
|
|
195
|
-
const widgetComp = this.widgetComps[widgetId]
|
|
196
|
-
if (!widgetComp) {
|
|
197
|
-
return
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Call scrollToTOCEntry if present
|
|
201
|
-
return widgetComp.scrollToTOCEntry?.(entryId)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
renderScopes() {
|
|
205
|
-
return R(WidgetScopesViewComponent, {
|
|
206
|
-
scopes: this.state.widgetScoper.getScopes(),
|
|
207
|
-
onRemoveScope: this.handleRemoveScope
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
compRef = (widgetId: any, comp: any) => {
|
|
212
|
-
return (this.widgetComps[widgetId] = comp)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
render() {
|
|
216
|
-
let cantPasteMessage = ""
|
|
217
|
-
const layoutManager = LayoutManager.createLayoutManager(this.props.design.layout)
|
|
218
|
-
|
|
219
|
-
const compiledFilters = this.getCompiledFilters()
|
|
220
|
-
|
|
221
|
-
// Get filterable tables
|
|
222
|
-
const filterableTables = DashboardUtils.getFilterableTables(this.props.design, this.props.schema)
|
|
223
|
-
|
|
224
|
-
// Determine toc entries
|
|
225
|
-
const tocEntries = this.getTOCEntries(layoutManager)
|
|
226
|
-
|
|
227
|
-
// Get clipboard contents
|
|
228
|
-
const clipboardContents = this.getClipboardContents()
|
|
229
|
-
|
|
230
|
-
// Check if can't paste because of missing table
|
|
231
|
-
if (clipboardContents && !_.all(clipboardContents.tables, (table: string) => this.props.schema.getTable(table))) {
|
|
232
|
-
cantPasteMessage = "Dashboard is missing one or more data sources needed for the copied item."
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const renderWidget = (options: any) => {
|
|
236
|
-
const widget = WidgetFactory.createWidget(options.type)
|
|
237
|
-
|
|
238
|
-
// Get filters (passed in plus dashboard widget scoper filters)
|
|
239
|
-
let filters = compiledFilters.concat(this.state.widgetScoper.getFilters(options.id))
|
|
240
|
-
|
|
241
|
-
// Extend the filters to include implicit filters (filter children in 1-n relationships)
|
|
242
|
-
if (this.props.design.implicitFiltersEnabled || this.props.design.implicitFiltersEnabled == null) {
|
|
243
|
-
// Default is true
|
|
244
|
-
const implicitFilterBuilder = new ImplicitFilterBuilder(this.props.schema)
|
|
245
|
-
filters = implicitFilterBuilder.extendFilters(filterableTables, filters)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const widgetElem = R(WidgetComponent, {
|
|
249
|
-
key: options.id,
|
|
250
|
-
id: options.id,
|
|
251
|
-
type: options.type,
|
|
252
|
-
schema: this.props.schema,
|
|
253
|
-
dataSource: this.props.dataSource,
|
|
254
|
-
dashboardDataSource: this.props.dashboardDataSource,
|
|
255
|
-
design: options.design,
|
|
256
|
-
scope: this.state.widgetScoper.getScope(options.id),
|
|
257
|
-
filters,
|
|
258
|
-
onScopeChange: this.handleScopeChange.bind(null, options.id),
|
|
259
|
-
onDesignChange: options.onDesignChange,
|
|
260
|
-
width: options.width,
|
|
261
|
-
height: options.height,
|
|
262
|
-
onRowClick: this.props.onRowClick,
|
|
263
|
-
namedStrings: this.props.namedStrings,
|
|
264
|
-
tocEntries,
|
|
265
|
-
onScrollToTOCEntry: this.handleScrollToTOCEntry,
|
|
266
|
-
// Keep references to widget elements
|
|
267
|
-
widgetRef: this.compRef.bind(null, options.id),
|
|
268
|
-
refreshKey: this.props.refreshKey
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
return widgetElem
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const style: CSSProperties = {
|
|
275
|
-
height: "100%",
|
|
276
|
-
position: "relative"
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (!this.props.printMode) {
|
|
280
|
-
// Prevent this block from taking up too much space. Scrolling handled by layout manager.
|
|
281
|
-
// Setting overflow-x stops the inner div from becoming too tall
|
|
282
|
-
style.overflowX = "auto"
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Render widget container
|
|
286
|
-
return R(
|
|
287
|
-
"div",
|
|
288
|
-
{ style },
|
|
289
|
-
!this.props.hideScopes ? this.renderScopes() : undefined,
|
|
290
|
-
|
|
291
|
-
layoutManager.renderLayout({
|
|
292
|
-
items: this.props.design.items,
|
|
293
|
-
onItemsChange: this.props.onDesignChange != null ? this.handleItemsChange : undefined,
|
|
294
|
-
style: this.props.design.style || null,
|
|
295
|
-
layoutOptions: getLayoutOptions(this.props.design),
|
|
296
|
-
renderWidget,
|
|
297
|
-
clipboard: clipboardContents?.block,
|
|
298
|
-
onClipboardChange: this.handleClipboardChange,
|
|
299
|
-
cantPasteMessage
|
|
300
|
-
})
|
|
301
|
-
)
|
|
302
|
-
}
|
|
303
|
-
}
|