@mwater/visualization 5.4.1 → 5.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ColorComponent.js +2 -1
- package/lib/IdSelection.d.ts +16 -0
- package/lib/IdSelection.js +59 -0
- package/lib/MWaterAddRelatedIndicatorComponent.js +2 -2
- package/lib/MWaterCompleteTableSelectComponent.d.ts +3 -8
- package/lib/MWaterCompleteTableSelectComponent.js +36 -42
- package/lib/MWaterLoaderComponent.d.ts +11 -10
- package/lib/MWaterLoaderComponent.js +1 -1
- package/lib/MWaterResponsesFilterComponent.js +1 -1
- package/lib/MWaterTableSelectComponent.d.ts +0 -1
- package/lib/MWaterTableSelectComponent.js +4 -6
- package/lib/autotranslate.d.ts +20 -0
- package/lib/autotranslate.js +122 -0
- package/lib/axes/AxisBuilder.js +3 -3
- package/lib/axes/AxisColorEditorComponent.js +4 -0
- package/lib/axes/AxisComponent.d.ts +8 -12
- package/lib/axes/AxisComponent.js +32 -80
- package/lib/axes/CategoryMapComponent.js +4 -4
- package/lib/axes/RangesComponent.js +2 -2
- package/lib/dashboards/DashboardComponent.d.ts +12 -20
- package/lib/dashboards/DashboardComponent.js +109 -69
- package/lib/dashboards/DashboardDesign.d.ts +11 -2
- package/lib/dashboards/DashboardUtils.d.ts +5 -0
- package/lib/dashboards/DashboardUtils.js +30 -0
- package/lib/dashboards/DashboardViewComponent.d.ts +2 -0
- package/lib/dashboards/DashboardViewComponent.js +16 -3
- package/lib/dashboards/ServerDashboardDataSource.js +2 -1
- package/lib/dashboards/SettingsModalComponent.d.ts +1 -1
- package/lib/dashboards/SettingsModalComponent.js +256 -19
- package/lib/dashboards/WidgetComponent.d.ts +6 -3
- package/lib/dashboards/WidgetComponent.js +3 -1
- package/lib/datagrids/CellEditor.d.ts +19 -0
- package/lib/datagrids/CellEditor.js +223 -0
- package/lib/datagrids/DatagridComponent.d.ts +18 -87
- package/lib/datagrids/DatagridComponent.js +304 -222
- package/lib/datagrids/DatagridViewComponent.d.ts +15 -53
- package/lib/datagrids/DatagridViewComponent.js +256 -257
- package/lib/datagrids/DirectDatagridDataSource.js +2 -3
- package/lib/datagrids/ExprCellComponent.d.ts +8 -15
- package/lib/datagrids/ExprCellComponent.js +11 -15
- package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -6
- package/lib/datagrids/FindReplaceModalComponent.js +38 -75
- package/lib/index.css +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/languages.js +6 -1
- package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
- package/lib/mWaterLoader.d.ts +1 -1
- package/lib/maps/BufferLayer.d.ts +7 -5
- package/lib/maps/BufferLayer.js +69 -48
- package/lib/maps/BufferLayerDesign.d.ts +21 -14
- package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
- package/lib/maps/BufferLayerDesignerComponent.js +68 -102
- package/lib/maps/ChoroplethLayer.d.ts +5 -4
- package/lib/maps/ChoroplethLayer.js +32 -9
- package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
- package/lib/maps/ChoroplethLayerDesigner.js +4 -2
- package/lib/maps/ClusterLayer.d.ts +3 -4
- package/lib/maps/ClusterLayer.js +2 -1
- package/lib/maps/DetailLevelSelectComponent.js +1 -1
- package/lib/maps/DirectMapDataSource.js +2 -1
- package/lib/maps/EditPopupComponent.js +5 -3
- package/lib/maps/GridLayer.d.ts +3 -4
- package/lib/maps/GridLayer.js +2 -1
- package/lib/maps/GridLayerDesigner.js +5 -3
- package/lib/maps/HoverContent.d.ts +11 -3
- package/lib/maps/HoverContent.js +25 -9
- package/lib/maps/Layer.d.ts +24 -3
- package/lib/maps/Layer.js +5 -1
- package/lib/maps/LayerFactory.js +0 -8
- package/lib/maps/LayerLegendComponent.js +0 -1
- package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
- package/lib/maps/LayerSwitcherComponent.js +1 -1
- package/lib/maps/LeafletMapComponent.js +3 -1
- package/lib/maps/LegendComponent.d.ts +1 -0
- package/lib/maps/LegendComponent.js +9 -1
- package/lib/maps/MWaterServerLayer.d.ts +2 -2
- package/lib/maps/MWaterServerLayer.js +2 -2
- package/lib/maps/MapComponent.js +3 -3
- package/lib/maps/MapDesign.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.d.ts +4 -3
- package/lib/maps/MapDesignerComponent.js +68 -74
- package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
- package/lib/maps/MapUtils.d.ts +4 -0
- package/lib/maps/MapUtils.js +19 -0
- package/lib/maps/MapViewComponent.d.ts +8 -3
- package/lib/maps/MarkersLayer.d.ts +5 -4
- package/lib/maps/MarkersLayer.js +33 -7
- package/lib/maps/MarkersLayerDesign.d.ts +19 -16
- package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
- package/lib/maps/PopupFilterJoinsUtils.js +0 -6
- package/lib/maps/RasterMapViewComponent.d.ts +3 -31
- package/lib/maps/RasterMapViewComponent.js +7 -2
- package/lib/maps/ServerMapDataSource.js +2 -1
- package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
- package/lib/maps/SwitchableTileUrlLayer.js +2 -1
- package/lib/maps/TileUrlLayer.d.ts +4 -5
- package/lib/maps/TileUrlLayer.js +2 -1
- package/lib/maps/VectorMapViewComponent.d.ts +5 -37
- package/lib/maps/VectorMapViewComponent.js +19 -8
- package/lib/maps/maps.d.ts +3 -0
- package/lib/quickfilter/Quickfilter.d.ts +2 -0
- package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
- package/lib/quickfilter/QuickfiltersComponent.js +9 -7
- package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +5 -30
- package/lib/quickfilter/QuickfiltersDesignComponent.js +56 -63
- package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
- package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
- package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
- package/lib/richtext/ExprItemsTranslator.js +149 -0
- package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
- package/lib/richtext/ItemsHtmlConverter.js +31 -15
- package/lib/wellknown.js +12 -9
- package/lib/widgets/IFrameWidget.d.ts +4 -4
- package/lib/widgets/ImageWidget.d.ts +7 -4
- package/lib/widgets/ImageWidget.js +9 -1
- package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
- package/lib/widgets/ImageWidgetComponent.js +1 -1
- package/lib/widgets/MapWidget.d.ts +5 -48
- package/lib/widgets/MapWidget.js +26 -63
- package/lib/widgets/MarkdownWidget.d.ts +3 -0
- package/lib/widgets/MarkdownWidget.js +3 -0
- package/lib/widgets/TOCWidget.d.ts +15 -27
- package/lib/widgets/TOCWidget.js +107 -183
- package/lib/widgets/Widget.d.ts +18 -7
- package/lib/widgets/Widget.js +4 -0
- package/lib/widgets/WidgetScopesViewComponent.js +1 -1
- package/lib/widgets/charts/Chart.d.ts +10 -1
- package/lib/widgets/charts/Chart.js +22 -11
- package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartViewComponent.js +6 -3
- package/lib/widgets/charts/ChartWidget.d.ts +2 -0
- package/lib/widgets/charts/ChartWidget.js +9 -1
- package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
- package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
- package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
- package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
- package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
- package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
- package/lib/widgets/charts/layered/LayeredChart.js +63 -3
- package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
- package/lib/widgets/charts/layered/LayeredChartCompiler.js +1 -1
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
- package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
- package/lib/widgets/charts/pivot/PivotChart.js +63 -0
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
- package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
- package/lib/widgets/charts/table/TableChart.d.ts +1 -0
- package/lib/widgets/charts/table/TableChart.js +15 -0
- package/lib/widgets/text/TextComponent.d.ts +11 -4
- package/lib/widgets/text/TextComponent.js +11 -8
- package/lib/widgets/text/TextWidget.d.ts +6 -3
- package/lib/widgets/text/TextWidget.js +7 -1
- package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
- package/lib/widgets/text/TextWidgetComponent.js +7 -1
- package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
- package/lib/widgets/text/TextWidgetDesign.js +1 -1
- package/package.json +7 -8
- package/src/ColorComponent.tsx +1 -2
- package/src/IdSelection.ts +62 -0
- package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
- package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
- package/src/MWaterLoaderComponent.ts +28 -26
- package/src/MWaterResponsesFilterComponent.ts +5 -2
- package/src/MWaterTableSelectComponent.tsx +5 -9
- package/src/autotranslate.ts +141 -0
- package/src/axes/AxisBuilder.ts +3 -3
- package/src/axes/AxisColorEditorComponent.tsx +5 -0
- package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
- package/src/axes/CategoryMapComponent.ts +4 -4
- package/src/axes/RangesComponent.ts +3 -2
- package/src/dashboards/DashboardComponent.tsx +189 -125
- package/src/dashboards/DashboardDesign.ts +9 -2
- package/src/dashboards/DashboardUtils.ts +39 -0
- package/src/dashboards/DashboardViewComponent.tsx +22 -3
- package/src/dashboards/ServerDashboardDataSource.ts +2 -1
- package/src/dashboards/SettingsModalComponent.tsx +450 -35
- package/src/dashboards/WidgetComponent.tsx +12 -6
- package/src/datagrids/CellEditor.tsx +354 -0
- package/src/datagrids/DatagridComponent.tsx +646 -0
- package/src/datagrids/DatagridViewComponent.tsx +539 -0
- package/src/datagrids/DirectDatagridDataSource.ts +2 -3
- package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
- package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
- package/src/index.css +1 -1
- package/src/index.ts +0 -1
- package/src/languages.ts +6 -1
- package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
- package/src/mWaterLoader.ts +1 -1
- package/src/maps/BufferLayer.ts +83 -60
- package/src/maps/BufferLayerDesign.ts +20 -14
- package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
- package/src/maps/ChoroplethLayer.ts +40 -19
- package/src/maps/ChoroplethLayerDesign.ts +4 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
- package/src/maps/ClusterLayer.ts +4 -10
- package/src/maps/DetailLevelSelectComponent.ts +1 -1
- package/src/maps/DirectMapDataSource.ts +2 -1
- package/src/maps/EditPopupComponent.ts +7 -3
- package/src/maps/GridLayer.ts +4 -10
- package/src/maps/GridLayerDesigner.tsx +5 -3
- package/src/maps/HoverContent.tsx +40 -16
- package/src/maps/Layer.ts +28 -10
- package/src/maps/LayerFactory.ts +0 -8
- package/src/maps/LayerLegendComponent.ts +2 -4
- package/src/maps/LayerSwitcherComponent.tsx +6 -2
- package/src/maps/LeafletMapComponent.tsx +3 -1
- package/src/maps/LegendComponent.tsx +10 -1
- package/src/maps/MWaterServerLayer.ts +3 -3
- package/src/maps/MapComponent.ts +3 -3
- package/src/maps/MapDesign.ts +3 -0
- package/src/maps/MapDesignerComponent.tsx +165 -162
- package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
- package/src/maps/MapUtils.ts +24 -0
- package/src/maps/MapViewComponent.tsx +11 -3
- package/src/maps/MarkersLayer.ts +44 -18
- package/src/maps/MarkersLayerDesign.ts +19 -16
- package/src/maps/PopupFilterJoinsUtils.ts +6 -2
- package/src/maps/RasterMapViewComponent.ts +9 -45
- package/src/maps/ServerMapDataSource.ts +2 -2
- package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
- package/src/maps/TileUrlLayer.tsx +4 -10
- package/src/maps/VectorMapViewComponent.tsx +28 -55
- package/src/maps/maps.ts +3 -0
- package/src/quickfilter/Quickfilter.ts +3 -0
- package/src/quickfilter/QuickfiltersComponent.ts +13 -7
- package/src/quickfilter/QuickfiltersDesignComponent.tsx +127 -128
- package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
- package/src/richtext/ExprItemsTranslator.ts +176 -0
- package/src/richtext/ItemsHtmlConverter.ts +33 -18
- package/src/wellknown.ts +33 -30
- package/src/widgets/ImageWidget.ts +10 -1
- package/src/widgets/ImageWidgetComponent.ts +3 -2
- package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
- package/src/widgets/MarkdownWidget.ts +3 -0
- package/src/widgets/TOCWidget.tsx +281 -0
- package/src/widgets/Widget.ts +25 -5
- package/src/widgets/WidgetScopesViewComponent.ts +2 -1
- package/src/widgets/charts/Chart.ts +31 -12
- package/src/widgets/charts/ChartViewComponent.ts +13 -3
- package/src/widgets/charts/ChartWidget.ts +11 -1
- package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
- package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
- package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
- package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
- package/src/widgets/charts/layered/LayeredChart.ts +71 -3
- package/src/widgets/charts/layered/LayeredChartCompiler.ts +2 -2
- package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
- package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
- package/src/widgets/charts/pivot/PivotChart.ts +73 -0
- package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
- package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
- package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
- package/src/widgets/charts/table/TableChart.ts +17 -0
- package/src/widgets/text/TextComponent.tsx +22 -12
- package/src/widgets/text/TextWidget.ts +9 -2
- package/src/widgets/text/TextWidgetComponent.tsx +16 -1
- package/src/widgets/text/TextWidgetDesign.ts +4 -7
- package/test/IdSelectionTests.ts +54 -0
- package/test/LayeredChartCompilerTests.ts +0 -2
- package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
- package/test/wellknownTests.ts +144 -0
- package/src/datagrids/DatagridComponent.ts +0 -478
- package/src/datagrids/DatagridViewComponent.ts +0 -464
- package/src/datagrids/EditExprCellComponent.tsx +0 -305
- package/src/datagrids/README.md +0 -3
- package/src/maps/BufferLayerDesignerComponent.ts +0 -311
- package/src/widgets/TOCWidget.ts +0 -326
- package/test/LegoLayoutEngineTests.ts +0 -69
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import _ from "lodash"
|
|
2
2
|
import React, { ReactNode } from "react"
|
|
3
|
-
const R = React.createElement
|
|
4
|
-
|
|
5
3
|
import { DataSource, ExprCompiler, Schema } from "@mwater/expressions"
|
|
6
4
|
import UndoStack from "../UndoStack"
|
|
7
5
|
import * as DashboardUtils from "./DashboardUtils"
|
|
@@ -15,7 +13,7 @@ import ModalWindowComponent from "@mwater/react-library/lib/ModalWindowComponent
|
|
|
15
13
|
import { getLayoutOptions } from "./layoutOptions"
|
|
16
14
|
import { DashboardDesign } from "./DashboardDesign"
|
|
17
15
|
import DashboardDataSource from "./DashboardDataSource"
|
|
18
|
-
import { JsonQLFilter } from ".."
|
|
16
|
+
import { JsonQLFilter, languages } from ".."
|
|
19
17
|
import { ActiveTablesContext, LocaleContext } from "@mwater/expressions-ui"
|
|
20
18
|
|
|
21
19
|
export interface DashboardComponentProps {
|
|
@@ -61,6 +59,9 @@ export interface DashboardComponentProps {
|
|
|
61
59
|
|
|
62
60
|
/** Called when the edit mode changes */
|
|
63
61
|
onEditModeChange?: (editing: boolean) => void
|
|
62
|
+
|
|
63
|
+
/** Locale to prefer if available */
|
|
64
|
+
preferredLocale?: string
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
export interface DashboardComponentState {
|
|
@@ -70,6 +71,8 @@ export interface DashboardComponentState {
|
|
|
70
71
|
layoutOptionsOpen: boolean
|
|
71
72
|
hideQuickfilters: boolean
|
|
72
73
|
refreshKey: number
|
|
74
|
+
/** Locale to use for display. Ignored if in edit mode */
|
|
75
|
+
locale: string
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
/** Dashboard component that includes an action bar at the top
|
|
@@ -87,6 +90,15 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
87
90
|
|
|
88
91
|
const layoutOptions = getLayoutOptions(props.design)
|
|
89
92
|
|
|
93
|
+
// Prefer the T.en locale if available when loading the dashboard
|
|
94
|
+
let initialLocale = props.design.locale || "en"
|
|
95
|
+
const otherLocales = props.design.otherLocales || []
|
|
96
|
+
if (props.preferredLocale && otherLocales.includes(props.preferredLocale)) {
|
|
97
|
+
initialLocale = props.preferredLocale
|
|
98
|
+
} else if (otherLocales.includes(T.locale)) {
|
|
99
|
+
initialLocale = T.locale
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
this.state = {
|
|
91
103
|
undoStack: new UndoStack().push(props.design),
|
|
92
104
|
quickfiltersValues: props.quickfiltersValues || null,
|
|
@@ -96,7 +108,8 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
96
108
|
layoutOptionsOpen: false,
|
|
97
109
|
hideQuickfilters:
|
|
98
110
|
layoutOptions.hideQuickfiltersWidth != null && layoutOptions.hideQuickfiltersWidth > document.body.clientWidth,
|
|
99
|
-
refreshKey: 1
|
|
111
|
+
refreshKey: 1,
|
|
112
|
+
locale: initialLocale
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
if (props.onEditModeChange) {
|
|
@@ -207,118 +220,165 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
207
220
|
return compiledFilters
|
|
208
221
|
}
|
|
209
222
|
|
|
223
|
+
/** Translate function to use for display. Do not use when editing. */
|
|
224
|
+
translate = (input: string) => {
|
|
225
|
+
const designLocale = this.props.design.locale ?? "en"
|
|
226
|
+
const displayLocale = this.state.editing ? designLocale : (this.state.locale ?? designLocale ?? "en")
|
|
227
|
+
if (designLocale === displayLocale) {
|
|
228
|
+
return input
|
|
229
|
+
}
|
|
230
|
+
return this.props.design.translations?.[displayLocale]?.[input] ?? input
|
|
231
|
+
}
|
|
232
|
+
|
|
210
233
|
renderEditingSwitch() {
|
|
211
|
-
return
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
234
|
+
return (
|
|
235
|
+
<a
|
|
236
|
+
key="edit"
|
|
237
|
+
className={`btn btn-primary btn-sm ${this.state.editing ? "active" : ""}`}
|
|
238
|
+
onClick={this.handleToggleEditing}
|
|
239
|
+
>
|
|
240
|
+
<span className="fas fa-pencil-alt"/>
|
|
241
|
+
{" "}
|
|
242
|
+
{this.state.editing ? T`Editing` : T`Edit`}
|
|
243
|
+
</a>
|
|
220
244
|
)
|
|
221
245
|
}
|
|
222
246
|
|
|
223
247
|
renderStyle() {
|
|
224
|
-
return
|
|
225
|
-
"button"
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
return (
|
|
249
|
+
<button type="button" key="style" className="btn btn-link btn-sm" onClick={this.handleOpenLayoutOptions}>
|
|
250
|
+
<span className="fa fa-mobile"/>
|
|
251
|
+
<span className="hide-600px"> {T`Layout`}</span>
|
|
252
|
+
</button>
|
|
229
253
|
)
|
|
230
254
|
}
|
|
231
255
|
|
|
232
256
|
renderActionLinks() {
|
|
233
|
-
return
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
className
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
257
|
+
return (
|
|
258
|
+
<div>
|
|
259
|
+
{this.state.editing
|
|
260
|
+
? [
|
|
261
|
+
<a
|
|
262
|
+
key="undo"
|
|
263
|
+
className={`btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`}
|
|
264
|
+
onClick={this.handleUndo}
|
|
265
|
+
>
|
|
266
|
+
<span className="fas fa-caret-left"/>
|
|
267
|
+
<span className="hide-600px"> {T`Undo`}</span>
|
|
268
|
+
</a>,
|
|
269
|
+
" ",
|
|
270
|
+
<a
|
|
271
|
+
key="redo"
|
|
272
|
+
className={`btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`}
|
|
273
|
+
onClick={this.handleRedo}
|
|
274
|
+
>
|
|
275
|
+
<span className="fas fa-caret-right"/>
|
|
276
|
+
<span className="hide-600px"> {T`Redo`}</span>
|
|
277
|
+
</a>
|
|
278
|
+
]
|
|
279
|
+
: undefined}
|
|
280
|
+
{!this.state.editing && this.props.design.otherLocales && this.props.design.otherLocales.length > 0
|
|
281
|
+
? <div key="translations" className="dropdown d-inline-block">
|
|
282
|
+
<a
|
|
283
|
+
className="btn btn-link btn-sm dropdown-toggle"
|
|
284
|
+
data-bs-toggle="dropdown"
|
|
285
|
+
>
|
|
286
|
+
<span className="fal fa-globe"/>
|
|
287
|
+
{" "}
|
|
288
|
+
{this.state.locale}
|
|
289
|
+
</a>
|
|
290
|
+
<ul className="dropdown-menu dropdown-menu-end">
|
|
291
|
+
{[this.props.design.locale || "en", ...this.props.design.otherLocales].map(locale =>
|
|
292
|
+
<li key={locale}>
|
|
293
|
+
<a
|
|
294
|
+
className="dropdown-item"
|
|
295
|
+
onClick={() => this.setState({ locale: locale })}
|
|
296
|
+
>
|
|
297
|
+
{languages.find(l => l.code === locale)?.name || locale}
|
|
298
|
+
</a>
|
|
299
|
+
</li>
|
|
300
|
+
)}
|
|
301
|
+
</ul>
|
|
302
|
+
</div>
|
|
303
|
+
: undefined}
|
|
304
|
+
<a key="print" className="btn btn-link btn-sm" onClick={this.handlePrint}>
|
|
305
|
+
<span className="fas fa-print"/>
|
|
306
|
+
<span className="hide-600px"> {T`Print`}</span>
|
|
307
|
+
</a>
|
|
308
|
+
<a key="refresh" className="btn btn-link btn-sm" onClick={this.handleRefreshData}>
|
|
309
|
+
<span className="fas fa-sync"/>
|
|
310
|
+
<span className="hide-600px"> {T`Refresh`}</span>
|
|
311
|
+
</a>
|
|
312
|
+
{this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0
|
|
313
|
+
? <a key="showQuickfilters" className="btn btn-link btn-sm" onClick={this.handleShowQuickfilters}>
|
|
314
|
+
<span className="fa fa-filter"/>
|
|
315
|
+
<span className="hide-600px"> {T`Show Quickfilters`}</span>
|
|
316
|
+
</a>
|
|
317
|
+
: undefined}
|
|
318
|
+
|
|
319
|
+
{this.state.editing
|
|
320
|
+
? <a key="settings" className="btn btn-link btn-sm" onClick={this.handleSettings}>
|
|
321
|
+
<span className="fas fa-cog"/>
|
|
322
|
+
<span className="hide-600px"> {T`Settings`}</span>
|
|
323
|
+
</a>
|
|
324
|
+
: undefined}
|
|
325
|
+
{this.state.editing ? this.renderStyle() : undefined}
|
|
326
|
+
{this.props.extraTitleButtonsElem}
|
|
327
|
+
{this.props.onDesignChange != null ? this.renderEditingSwitch() : undefined}
|
|
328
|
+
</div>
|
|
296
329
|
)
|
|
297
330
|
}
|
|
298
331
|
|
|
299
332
|
renderTitleBar() {
|
|
300
|
-
return
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
333
|
+
return (
|
|
334
|
+
<div style={{ height: 40, padding: 4 }}>
|
|
335
|
+
<div style={{ float: "right" }}>{this.renderActionLinks()}</div>
|
|
336
|
+
{this.props.titleElem}
|
|
337
|
+
</div>
|
|
305
338
|
)
|
|
306
339
|
}
|
|
307
340
|
|
|
308
341
|
renderQuickfilter() {
|
|
309
|
-
return
|
|
310
|
-
design
|
|
311
|
-
schema
|
|
312
|
-
dataSource
|
|
313
|
-
quickfiltersDataSource
|
|
314
|
-
values
|
|
315
|
-
onValuesChange
|
|
316
|
-
locks
|
|
317
|
-
filters
|
|
318
|
-
hideTopBorder
|
|
342
|
+
return <QuickfiltersComponent
|
|
343
|
+
design={this.props.design.quickfilters || []}
|
|
344
|
+
schema={this.props.schema}
|
|
345
|
+
dataSource={this.props.dataSource}
|
|
346
|
+
quickfiltersDataSource={this.props.dashboardDataSource.getQuickfiltersDataSource()}
|
|
347
|
+
values={this.state.quickfiltersValues || undefined}
|
|
348
|
+
onValuesChange={(values: any) => this.setState({ quickfiltersValues: values })}
|
|
349
|
+
locks={this.props.quickfilterLocks}
|
|
350
|
+
filters={this.getCompiledFilters()}
|
|
351
|
+
hideTopBorder={this.props.hideTitleBar}
|
|
319
352
|
// Don't hide if title bar is hidden as it can't be shown again
|
|
320
|
-
onHide
|
|
321
|
-
|
|
353
|
+
onHide={() => this.setState({ hideQuickfilters: true })}
|
|
354
|
+
translate={this.translate}
|
|
355
|
+
/>
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
renderFloatingShowQuickfiltersButton() {
|
|
359
|
+
// Only show if:
|
|
360
|
+
// 1. Quick filters exist
|
|
361
|
+
// 2. Quick filters are hidden
|
|
362
|
+
// 3. Title bar is hidden (since otherwise button is in title bar)
|
|
363
|
+
if (!this.props.design.quickfilters?.length || !this.state.hideQuickfilters || !this.props.hideTitleBar) {
|
|
364
|
+
return null
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return (
|
|
368
|
+
<div style={{
|
|
369
|
+
position: "absolute",
|
|
370
|
+
top: 5,
|
|
371
|
+
right: 20,
|
|
372
|
+
zIndex: 1000
|
|
373
|
+
}}>
|
|
374
|
+
<button
|
|
375
|
+
className="btn btn-link btn-sm"
|
|
376
|
+
onClick={() => this.setState({ hideQuickfilters: false })}
|
|
377
|
+
>
|
|
378
|
+
<i className="fa fa-angle-double-down"/>
|
|
379
|
+
</button>
|
|
380
|
+
</div>
|
|
381
|
+
)
|
|
322
382
|
}
|
|
323
383
|
|
|
324
384
|
refDashboardView = (el: any) => {
|
|
@@ -337,37 +397,40 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
337
397
|
)
|
|
338
398
|
)
|
|
339
399
|
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
400
|
+
const displayLocale = this.state.editing ? this.props.design.locale || "en" : this.state.locale
|
|
401
|
+
|
|
402
|
+
const dashboardView = <DashboardViewComponent
|
|
403
|
+
schema={this.props.schema}
|
|
404
|
+
dataSource={this.props.dataSource}
|
|
405
|
+
dashboardDataSource={this.props.dashboardDataSource}
|
|
406
|
+
ref={this.refDashboardView}
|
|
407
|
+
design={this.props.design}
|
|
408
|
+
onDesignChange={this.state.editing ? this.props.onDesignChange : undefined}
|
|
409
|
+
filters={filters}
|
|
410
|
+
onRowClick={this.props.onRowClick}
|
|
411
|
+
namedStrings={this.props.namedStrings}
|
|
412
|
+
hideScopes={this.state.hideQuickfilters}
|
|
413
|
+
refreshKey={this.state.refreshKey}
|
|
414
|
+
locale={displayLocale}
|
|
415
|
+
/>
|
|
416
|
+
|
|
417
|
+
const readonlyDashboardView = <DashboardViewComponent
|
|
418
|
+
schema={this.props.schema}
|
|
419
|
+
dataSource={this.props.dataSource}
|
|
420
|
+
dashboardDataSource={this.props.dashboardDataSource}
|
|
421
|
+
ref={this.refDashboardView}
|
|
422
|
+
design={this.props.design}
|
|
423
|
+
filters={filters}
|
|
424
|
+
onRowClick={this.props.onRowClick}
|
|
425
|
+
namedStrings={this.props.namedStrings}
|
|
426
|
+
hideScopes={this.state.hideQuickfilters}
|
|
427
|
+
locale={displayLocale}
|
|
428
|
+
/>
|
|
366
429
|
|
|
367
430
|
// Pass active tables down to table select components so they can present a shorter list
|
|
368
431
|
return <ActiveTablesContext.Provider
|
|
369
432
|
value={DashboardUtils.getFilterableTables(this.props.design, this.props.schema)}>
|
|
370
|
-
<LocaleContext.Provider value={
|
|
433
|
+
<LocaleContext.Provider value={displayLocale}>
|
|
371
434
|
<div style={{
|
|
372
435
|
display: "grid",
|
|
373
436
|
gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
|
|
@@ -376,6 +439,7 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
376
439
|
{!this.props.hideTitleBar ? this.renderTitleBar() : undefined}
|
|
377
440
|
<div>{!this.state.hideQuickfilters ? this.renderQuickfilter() : undefined}</div>
|
|
378
441
|
{dashboardView}
|
|
442
|
+
{this.renderFloatingShowQuickfiltersButton()}
|
|
379
443
|
{this.props.onDesignChange != null && (
|
|
380
444
|
<SettingsModalComponent
|
|
381
445
|
onDesignChange={this.handleDesignChange}
|
|
@@ -2,6 +2,7 @@ import { Quickfilter } from "../quickfilter/Quickfilter"
|
|
|
2
2
|
import { Expr } from "@mwater/expressions"
|
|
3
3
|
import { BlocksLayoutOptions, DashboardTheme } from "./layoutOptions"
|
|
4
4
|
import { GlobalFilter } from "../GlobalFilter"
|
|
5
|
+
import { LayoutBlock } from "../layouts/blocks/blockUtils"
|
|
5
6
|
|
|
6
7
|
/** Dashboard design
|
|
7
8
|
* Each understands enough of the dashboard design to create widgets.
|
|
@@ -9,7 +10,7 @@ import { GlobalFilter } from "../GlobalFilter"
|
|
|
9
10
|
*/
|
|
10
11
|
export interface DashboardDesign {
|
|
11
12
|
/** dashboard items. Format depends on layout of dashboard. See layouts/.../README.md */
|
|
12
|
-
items:
|
|
13
|
+
items: LayoutBlock
|
|
13
14
|
|
|
14
15
|
/** array of quick filters (user-selectable filters). See quickfilter/README.md */
|
|
15
16
|
quickfilters?: Quickfilter[]
|
|
@@ -26,9 +27,15 @@ export interface DashboardDesign {
|
|
|
26
27
|
/** filter expression indexed by table. e.g. { sometable: logical expression, etc. } */
|
|
27
28
|
filters?: { [tableId: string]: Expr }
|
|
28
29
|
|
|
29
|
-
/** optional locale (e.g. "fr") to use for display */
|
|
30
|
+
/** optional locale (e.g. "fr") to use for display. Defaults to "en" */
|
|
30
31
|
locale?: string
|
|
31
32
|
|
|
33
|
+
/** Other locales that the dashboard is available in. */
|
|
34
|
+
otherLocales?: string[]
|
|
35
|
+
|
|
36
|
+
/** Translation map for dashboard. Maps locale to translation map. Does not include default locale. */
|
|
37
|
+
translations?: { [locale: string]: { [key: string]: string } }
|
|
38
|
+
|
|
32
39
|
/** true to enable implicit filtering (see ImplicitFilterBuilder). Defaults to true for older dashboards. */
|
|
33
40
|
implicitFiltersEnabled?: boolean
|
|
34
41
|
|
|
@@ -25,6 +25,45 @@ export function getFilterableTables(design: DashboardDesign, schema: Schema) {
|
|
|
25
25
|
return filterableTables
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/** Gets all translatable strings from a dashboard */
|
|
29
|
+
export function getTranslatableStringsFromDashboard(design: DashboardDesign, schema: Schema): string[] {
|
|
30
|
+
const layoutManager = LayoutManager.createLayoutManager(design.layout)
|
|
31
|
+
|
|
32
|
+
// Get translatable strings from layout manager
|
|
33
|
+
let strings = getTranslatableStringsFromLayoutManager(layoutManager, design.items, schema)
|
|
34
|
+
|
|
35
|
+
// Get translatable strings from quickfilters
|
|
36
|
+
if (design.quickfilters) {
|
|
37
|
+
for (let quickfilter of design.quickfilters) {
|
|
38
|
+
if (quickfilter.label) {
|
|
39
|
+
strings.push(quickfilter.label)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Remove duplicates
|
|
45
|
+
return _.uniq(strings)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Gets translatable strings from a layout manager and items */
|
|
49
|
+
export function getTranslatableStringsFromLayoutManager(
|
|
50
|
+
layoutManager: LayoutManager,
|
|
51
|
+
items: any,
|
|
52
|
+
schema: Schema
|
|
53
|
+
) {
|
|
54
|
+
let strings: string[] = []
|
|
55
|
+
for (let widgetItem of layoutManager.getAllWidgets(items)) {
|
|
56
|
+
// Create widget
|
|
57
|
+
const widget = WidgetFactory.createWidget(widgetItem.type)
|
|
58
|
+
|
|
59
|
+
// Get translatable strings
|
|
60
|
+
strings = strings.concat(widget.getTranslatableStrings(widgetItem.design, schema))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Remove duplicates
|
|
64
|
+
return _.uniq(strings)
|
|
65
|
+
}
|
|
66
|
+
|
|
28
67
|
/** Get filters from props filters combined with dashboard filters */
|
|
29
68
|
export function getCompiledFilters(
|
|
30
69
|
design: DashboardDesign,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from "lodash"
|
|
2
|
-
import React, { CSSProperties, useEffect, useImperativeHandle, useRef, useMemo, useState } from "react"
|
|
2
|
+
import React, { CSSProperties, useEffect, useImperativeHandle, useRef, useMemo, useState, useCallback } from "react"
|
|
3
3
|
|
|
4
4
|
import ImplicitFilterBuilder from "../ImplicitFilterBuilder"
|
|
5
5
|
import * as DashboardUtils from "./DashboardUtils"
|
|
@@ -51,6 +51,9 @@ export interface DashboardViewComponentProps {
|
|
|
51
51
|
|
|
52
52
|
/** Change to force a refresh */
|
|
53
53
|
refreshKey?: any
|
|
54
|
+
|
|
55
|
+
/** Locale to use for display. Defaults to dashboard design locale. */
|
|
56
|
+
locale?: string
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
export interface DashboardViewComponentHandle {
|
|
@@ -211,6 +214,20 @@ const DashboardViewComponent = React.forwardRef<DashboardViewComponentHandle, Da
|
|
|
211
214
|
)
|
|
212
215
|
}
|
|
213
216
|
|
|
217
|
+
/** Locale that the dashboard design is in */
|
|
218
|
+
const designLocale = props.design.locale ?? "en"
|
|
219
|
+
|
|
220
|
+
/** Locale to display the dashboard in. If editing, always use design locale. */
|
|
221
|
+
const displayLocale = props.onDesignChange != null ? designLocale : (props.locale ?? designLocale ?? "en")
|
|
222
|
+
|
|
223
|
+
/** Translate function to use for display. Do not use when editing. */
|
|
224
|
+
const translate = useCallback((input: string) => {
|
|
225
|
+
if (designLocale === displayLocale) {
|
|
226
|
+
return input
|
|
227
|
+
}
|
|
228
|
+
return props.design.translations?.[displayLocale]?.[input] ?? input
|
|
229
|
+
}, [props.design.translations, designLocale, displayLocale])
|
|
230
|
+
|
|
214
231
|
const compRef = (widgetId: any, comp: any) => {
|
|
215
232
|
return (widgetComps.current[widgetId] = comp)
|
|
216
233
|
}
|
|
@@ -254,7 +271,6 @@ const DashboardViewComponent = React.forwardRef<DashboardViewComponentHandle, Da
|
|
|
254
271
|
const widgetElem = (
|
|
255
272
|
<WidgetComponent
|
|
256
273
|
key={options.id}
|
|
257
|
-
id={options.id}
|
|
258
274
|
type={options.type}
|
|
259
275
|
schema={props.schema}
|
|
260
276
|
dataSource={props.dataSource}
|
|
@@ -273,6 +289,9 @@ const DashboardViewComponent = React.forwardRef<DashboardViewComponentHandle, Da
|
|
|
273
289
|
// Keep references to widget elements
|
|
274
290
|
widgetRef={compRef.bind(null, options.id)}
|
|
275
291
|
refreshKey={props.refreshKey}
|
|
292
|
+
// Use locale from props, design, or default to en
|
|
293
|
+
locale={displayLocale}
|
|
294
|
+
translate={translate}
|
|
276
295
|
/>
|
|
277
296
|
)
|
|
278
297
|
|
|
@@ -292,7 +311,7 @@ const DashboardViewComponent = React.forwardRef<DashboardViewComponentHandle, Da
|
|
|
292
311
|
|
|
293
312
|
// Render widget container
|
|
294
313
|
return (
|
|
295
|
-
<LocaleContext.Provider value={
|
|
314
|
+
<LocaleContext.Provider value={displayLocale}>
|
|
296
315
|
<div style={style}>
|
|
297
316
|
{!props.hideScopes ? renderScopes() : undefined}
|
|
298
317
|
|
|
@@ -377,7 +377,8 @@ class ServerWidgetLayerDataSource implements MapLayerDataSource {
|
|
|
377
377
|
}
|
|
378
378
|
const { token, expires } = await response.json()
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
// Client isn't necessary, but allows tracking of usage easier
|
|
381
|
+
return { url: this.options.apiUrl + `vector_tiles/tiles/{z}/{x}/{y}?token=${token}&client=${this.options.client ?? ""}`, expires }
|
|
381
382
|
}
|
|
382
383
|
|
|
383
384
|
// Gets widget data source for a popup widget
|