@mwater/visualization 5.5.0 → 5.6.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.js +2 -2
- package/lib/MWaterContextComponent.d.ts +1 -1
- package/lib/MWaterGlobalFiltersComponent.d.ts +2 -2
- package/lib/MWaterGlobalFiltersComponent.js +11 -20
- package/lib/MWaterLoaderComponent.d.ts +4 -13
- package/lib/MWaterLoaderComponent.js +2 -11
- package/lib/TranslationsTabComponent.d.ts +34 -0
- package/lib/TranslationsTabComponent.js +256 -0
- package/lib/UndoStack.d.ts +2 -1
- package/lib/UndoStack.js +12 -6
- package/lib/dashboards/DashboardComponent.js +6 -5
- package/lib/dashboards/DashboardDesign.d.ts +1 -1
- package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
- package/lib/dashboards/ServerDashboardDataSource.js +0 -25
- package/lib/dashboards/SettingsModalComponent.js +9 -233
- package/lib/datagrids/DatagridComponent.js +27 -2
- package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -3
- package/lib/datagrids/DatagridDesignerComponent.js +108 -120
- package/lib/datagrids/DatagridViewComponent.js +33 -6
- package/lib/datagrids/OrderBysDesignerComponent.d.ts +7 -7
- package/lib/datagrids/OrderBysDesignerComponent.js +19 -28
- package/lib/index.css +45 -2
- package/lib/index.d.ts +5 -5
- package/lib/index.js +2 -3
- package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +8 -1
- package/lib/layouts/blocks/BlocksDisplayComponent.js +46 -4
- package/lib/maps/BufferLayer.d.ts +0 -13
- package/lib/maps/BufferLayer.js +24 -237
- package/lib/maps/BufferLayerDesign.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.js +2 -7
- package/lib/maps/ChoroplethLayer.d.ts +1 -16
- package/lib/maps/ChoroplethLayer.js +25 -358
- package/lib/maps/ChoroplethLayerDesign.d.ts +5 -2
- package/lib/maps/ChoroplethLayerDesigner.d.ts +10 -32
- package/lib/maps/ChoroplethLayerDesigner.js +58 -89
- package/lib/maps/ClusterLayer.d.ts +0 -9
- package/lib/maps/ClusterLayer.js +0 -250
- package/lib/maps/DirectMapDataSource.js +1 -48
- package/lib/maps/EditHoverOver.d.ts +4 -3
- package/lib/maps/EditHoverOver.js +3 -3
- package/lib/maps/GridLayer.d.ts +0 -15
- package/lib/maps/GridLayer.js +0 -212
- package/lib/maps/HoverContent.js +1 -1
- package/lib/maps/Layer.d.ts +1 -26
- package/lib/maps/Layer.js +0 -13
- package/lib/maps/LeafletMapComponent.js +10 -19
- package/lib/maps/MapComponent.d.ts +19 -35
- package/lib/maps/MapComponent.js +135 -77
- package/lib/maps/MapControlComponent.d.ts +4 -5
- package/lib/maps/MapControlComponent.js +5 -12
- package/lib/maps/MapDesign.d.ts +8 -0
- package/lib/maps/MapDesignerComponent.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.js +7 -2
- package/lib/maps/MapLayerDataSource.d.ts +0 -4
- package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
- package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
- package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
- package/lib/maps/MapLayersDesignerComponent.js +2 -1
- package/lib/maps/MapTranslationsTab.d.ts +15 -0
- package/lib/maps/MapTranslationsTab.js +47 -0
- package/lib/maps/MapUtils.d.ts +11 -0
- package/lib/maps/MapUtils.js +57 -1
- package/lib/maps/MapViewComponent.d.ts +1 -1
- package/lib/maps/MapViewComponent.js +1 -8
- package/lib/maps/MarkersLayer.d.ts +1 -14
- package/lib/maps/MarkersLayer.js +89 -254
- package/lib/maps/MarkersLayerDesign.d.ts +5 -1
- package/lib/maps/MarkersLayerDesignerComponent.d.ts +32 -57
- package/lib/maps/MarkersLayerDesignerComponent.js +158 -134
- package/lib/maps/ServerMapDataSource.d.ts +0 -1
- package/lib/maps/ServerMapDataSource.js +0 -25
- package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
- package/lib/maps/SwitchableTileUrlLayer.js +0 -9
- package/lib/maps/TileUrlLayer.d.ts +0 -1
- package/lib/maps/TileUrlLayer.js +0 -5
- package/lib/maps/VectorMapViewComponent.js +13 -10
- package/lib/maps/symbols/font-awesome/asterisk.png +0 -0
- package/lib/maps/symbols/font-awesome/ban.png +0 -0
- package/lib/maps/symbols/font-awesome/beer.png +0 -0
- package/lib/maps/symbols/font-awesome/bell.png +0 -0
- package/lib/maps/symbols/font-awesome/bolt.png +0 -0
- package/lib/maps/symbols/font-awesome/building.png +0 -0
- package/lib/maps/symbols/font-awesome/bullseye.png +0 -0
- package/lib/maps/symbols/font-awesome/bus.png +0 -0
- package/lib/maps/symbols/font-awesome/caret-up.png +0 -0
- package/lib/maps/symbols/font-awesome/certificate.png +0 -0
- package/lib/maps/symbols/font-awesome/check-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/check.png +0 -0
- package/lib/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
- package/lib/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
- package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/lib/maps/symbols/font-awesome/cloud.png +0 -0
- package/lib/maps/symbols/font-awesome/comment.png +0 -0
- package/lib/maps/symbols/font-awesome/crosshairs.png +0 -0
- package/lib/maps/symbols/font-awesome/dot-circle-o.png +0 -0
- package/lib/maps/symbols/font-awesome/exclamation-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
- package/lib/maps/symbols/font-awesome/female.png +0 -0
- package/lib/maps/symbols/font-awesome/file.png +0 -0
- package/lib/maps/symbols/font-awesome/flag.png +0 -0
- package/lib/maps/symbols/font-awesome/flask.png +0 -0
- package/lib/maps/symbols/font-awesome/h-square.png +0 -0
- package/lib/maps/symbols/font-awesome/home.png +0 -0
- package/lib/maps/symbols/font-awesome/info-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/male.png +0 -0
- package/lib/maps/symbols/font-awesome/medkit.png +0 -0
- package/lib/maps/symbols/font-awesome/mobile.png +0 -0
- package/lib/maps/symbols/font-awesome/plus-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/plus-square.png +0 -0
- package/lib/maps/symbols/font-awesome/plus.png +0 -0
- package/lib/maps/symbols/font-awesome/square.png +0 -0
- package/lib/maps/symbols/font-awesome/star.png +0 -0
- package/lib/maps/symbols/font-awesome/thumbs-down.png +0 -0
- package/lib/maps/symbols/font-awesome/thumbs-up.png +0 -0
- package/lib/maps/symbols/font-awesome/ticket.png +0 -0
- package/lib/maps/symbols/font-awesome/times-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/times.png +0 -0
- package/lib/maps/symbols/font-awesome/tint.png +0 -0
- package/lib/maps/symbols/font-awesome/tree.png +0 -0
- package/lib/maps/symbols/font-awesome/university.png +0 -0
- package/lib/maps/symbols/font-awesome/usd.png +0 -0
- package/lib/maps/symbols/font-awesome/user.png +0 -0
- package/lib/maps/symbols/font-awesome/users.png +0 -0
- package/lib/maps/symbols/font-awesome/wheelchair.png +0 -0
- package/lib/maps/symbols/sdf-ize.sh +93 -0
- package/lib/maps/vectorMaps.d.ts +6 -6
- package/lib/maps/vectorMaps.js +33 -45
- package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +4 -2
- package/lib/mwater_table_selection/IndicatorsListComponent.js +103 -34
- package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.d.ts +18 -0
- package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.js +80 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +26 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +237 -51
- package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +2 -2
- package/lib/mwater_table_selection/MWaterTableSelectComponent.js +9 -4
- package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.d.ts +19 -0
- package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.js +111 -0
- package/lib/quickfilter/QuickfiltersComponent.d.ts +3 -102
- package/lib/quickfilter/QuickfiltersComponent.js +53 -110
- package/lib/quickfilter/TextLiteralComponent.d.ts +23 -47
- package/lib/quickfilter/TextLiteralComponent.js +85 -82
- package/lib/widgets/MapWidget.js +6 -3
- package/lib/widgets/text/ExprItemEditorComponent.d.ts +3 -8
- package/lib/widgets/text/ExprItemEditorComponent.js +36 -33
- package/lib/widgets/text/ExprUpdateModalComponent.d.ts +1 -0
- package/package.json +3 -4
- package/src/ColorComponent.tsx +2 -2
- package/src/MWaterContextComponent.tsx +1 -1
- package/src/{MWaterGlobalFiltersComponent.ts → MWaterGlobalFiltersComponent.tsx} +32 -33
- package/src/{MWaterLoaderComponent.ts → MWaterLoaderComponent.tsx} +17 -18
- package/src/TranslationsTabComponent.tsx +429 -0
- package/src/UndoStack.ts +14 -6
- package/src/dashboards/DashboardComponent.tsx +6 -5
- package/src/dashboards/DashboardDesign.ts +1 -1
- package/src/dashboards/ServerDashboardDataSource.ts +0 -31
- package/src/dashboards/SettingsModalComponent.tsx +27 -383
- package/src/datagrids/DatagridComponent.tsx +36 -2
- package/src/datagrids/DatagridDesignerComponent.tsx +241 -229
- package/src/datagrids/DatagridViewComponent.tsx +44 -7
- package/src/datagrids/OrderBysDesignerComponent.tsx +61 -70
- package/src/index.css +45 -2
- package/src/index.ts +5 -11
- package/src/layouts/blocks/BlocksDisplayComponent.tsx +60 -5
- package/src/maps/BufferLayer.ts +30 -263
- package/src/maps/BufferLayerDesign.ts +1 -1
- package/src/maps/BufferLayerDesignerComponent.tsx +2 -7
- package/src/maps/ChoroplethLayer.ts +30 -394
- package/src/maps/ChoroplethLayerDesign.ts +5 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +169 -165
- package/src/maps/ClusterLayer.ts +0 -274
- package/src/maps/DirectMapDataSource.ts +2 -61
- package/src/maps/EditHoverOver.tsx +9 -5
- package/src/maps/GridLayer.ts +0 -224
- package/src/maps/HoverContent.tsx +1 -1
- package/src/maps/Layer.ts +1 -35
- package/src/maps/LeafletMapComponent.tsx +10 -19
- package/src/maps/MapComponent.tsx +448 -0
- package/src/maps/MapControlComponent.tsx +41 -0
- package/src/maps/MapDesign.ts +6 -0
- package/src/maps/MapDesignerComponent.tsx +18 -1
- package/src/maps/MapLayerDataSource.ts +0 -5
- package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
- package/src/maps/MapLayersDesignerComponent.ts +4 -1
- package/src/maps/MapTranslationsTab.tsx +53 -0
- package/src/maps/MapUtils.ts +61 -1
- package/src/maps/MapViewComponent.tsx +2 -8
- package/src/maps/MarkersLayer.ts +101 -275
- package/src/maps/MarkersLayerDesign.ts +7 -1
- package/src/maps/MarkersLayerDesignerComponent.tsx +436 -0
- package/src/maps/ServerMapDataSource.ts +0 -31
- package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
- package/src/maps/TileUrlLayer.tsx +0 -6
- package/src/maps/VectorMapViewComponent.tsx +15 -15
- package/src/maps/symbols/font-awesome/asterisk.png +0 -0
- package/src/maps/symbols/font-awesome/ban.png +0 -0
- package/src/maps/symbols/font-awesome/beer.png +0 -0
- package/src/maps/symbols/font-awesome/bell.png +0 -0
- package/src/maps/symbols/font-awesome/bolt.png +0 -0
- package/src/maps/symbols/font-awesome/building.png +0 -0
- package/src/maps/symbols/font-awesome/bullseye.png +0 -0
- package/src/maps/symbols/font-awesome/bus.png +0 -0
- package/src/maps/symbols/font-awesome/caret-up.png +0 -0
- package/src/maps/symbols/font-awesome/certificate.png +0 -0
- package/src/maps/symbols/font-awesome/check-circle.png +0 -0
- package/src/maps/symbols/font-awesome/check.png +0 -0
- package/src/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
- package/src/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
- package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/src/maps/symbols/font-awesome/cloud.png +0 -0
- package/src/maps/symbols/font-awesome/comment.png +0 -0
- package/src/maps/symbols/font-awesome/crosshairs.png +0 -0
- package/src/maps/symbols/font-awesome/dot-circle-o.png +0 -0
- package/src/maps/symbols/font-awesome/exclamation-circle.png +0 -0
- package/src/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
- package/src/maps/symbols/font-awesome/female.png +0 -0
- package/src/maps/symbols/font-awesome/file.png +0 -0
- package/src/maps/symbols/font-awesome/flag.png +0 -0
- package/src/maps/symbols/font-awesome/flask.png +0 -0
- package/src/maps/symbols/font-awesome/h-square.png +0 -0
- package/src/maps/symbols/font-awesome/home.png +0 -0
- package/src/maps/symbols/font-awesome/info-circle.png +0 -0
- package/src/maps/symbols/font-awesome/male.png +0 -0
- package/src/maps/symbols/font-awesome/medkit.png +0 -0
- package/src/maps/symbols/font-awesome/mobile.png +0 -0
- package/src/maps/symbols/font-awesome/plus-circle.png +0 -0
- package/src/maps/symbols/font-awesome/plus-square.png +0 -0
- package/src/maps/symbols/font-awesome/plus.png +0 -0
- package/src/maps/symbols/font-awesome/square.png +0 -0
- package/src/maps/symbols/font-awesome/star.png +0 -0
- package/src/maps/symbols/font-awesome/thumbs-down.png +0 -0
- package/src/maps/symbols/font-awesome/thumbs-up.png +0 -0
- package/src/maps/symbols/font-awesome/ticket.png +0 -0
- package/src/maps/symbols/font-awesome/times-circle.png +0 -0
- package/src/maps/symbols/font-awesome/times.png +0 -0
- package/src/maps/symbols/font-awesome/tint.png +0 -0
- package/src/maps/symbols/font-awesome/tree.png +0 -0
- package/src/maps/symbols/font-awesome/university.png +0 -0
- package/src/maps/symbols/font-awesome/usd.png +0 -0
- package/src/maps/symbols/font-awesome/user.png +0 -0
- package/src/maps/symbols/font-awesome/users.png +0 -0
- package/src/maps/symbols/font-awesome/wheelchair.png +0 -0
- package/src/maps/symbols/sdf-ize.sh +93 -0
- package/src/maps/vectorMaps.tsx +32 -53
- package/src/mwater_table_selection/IndicatorsListComponent.tsx +165 -37
- package/src/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.tsx +111 -0
- package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +373 -37
- package/src/mwater_table_selection/MWaterTableSelectComponent.tsx +12 -8
- package/src/mwater_table_selection/MWaterWorkflowsSelectComponent.tsx +159 -0
- package/src/quickfilter/{QuickfiltersComponent.ts → QuickfiltersComponent.tsx} +165 -158
- package/src/quickfilter/TextLiteralComponent.tsx +197 -0
- package/src/widgets/MapWidget.tsx +11 -1
- package/src/widgets/text/ExprItemEditorComponent.tsx +83 -77
- package/src/widgets/text/ExprUpdateModalComponent.tsx +1 -0
- package/test/UndoStackTests.ts +52 -1
- package/.storybook/config.js +0 -7
- package/.storybook/head.html +0 -3
- package/.storybook/webpack.config.js +0 -15
- package/src/maps/BingLayer.ts +0 -146
- package/src/maps/MapComponent.ts +0 -312
- package/src/maps/MapControlComponent.ts +0 -46
- package/src/maps/MarkersLayerDesignerComponent.ts +0 -374
- package/src/maps/RasterMapViewComponent.ts +0 -345
- package/src/quickfilter/TextLiteralComponent.ts +0 -165
- package/stories/UpdateableComponent.js +0 -29
- package/stories/consoles.js +0 -202
- package/stories/dashboards.js +0 -217
- package/stories/datagridDesign.js +0 -114
- package/stories/datagrids.js +0 -69
- package/stories/dates.js +0 -80
- package/stories/exprcomponent.js +0 -43
- package/stories/index.js +0 -18
- package/stories/leaflet.js +0 -59
- package/stories/maps.js +0 -24
- package/stories/pivotChart.js +0 -235
package/lib/maps/MapComponent.js
CHANGED
|
@@ -5,28 +5,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const lodash_1 = __importDefault(require("lodash"));
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const R = react_1.default.createElement;
|
|
9
8
|
const MapViewComponent_1 = require("./MapViewComponent");
|
|
10
9
|
const MapDesignerComponent_1 = __importDefault(require("./MapDesignerComponent"));
|
|
11
10
|
const MapControlComponent_1 = __importDefault(require("./MapControlComponent"));
|
|
12
11
|
const AutoSizeComponent_1 = __importDefault(require("@mwater/react-library/lib/AutoSizeComponent"));
|
|
13
12
|
const UndoStack_1 = __importDefault(require("../UndoStack"));
|
|
14
13
|
const PopoverHelpComponent_1 = __importDefault(require("@mwater/react-library/lib/PopoverHelpComponent"));
|
|
14
|
+
const __1 = require("..");
|
|
15
15
|
const QuickfilterCompiler_1 = __importDefault(require("../quickfilter/QuickfilterCompiler"));
|
|
16
16
|
const QuickfiltersComponent_1 = __importDefault(require("../quickfilter/QuickfiltersComponent"));
|
|
17
17
|
const MapUtils_1 = require("./MapUtils");
|
|
18
|
-
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
19
18
|
/** Map with designer on right */
|
|
20
19
|
class MapComponent extends react_1.default.Component {
|
|
21
|
-
static contextType = expressions_ui_1.LocaleContext;
|
|
22
20
|
constructor(props) {
|
|
23
21
|
super(props);
|
|
22
|
+
// Prefer the T.locale if available when loading the map
|
|
23
|
+
let initialLocale = props.design.locale || "en";
|
|
24
|
+
const otherLocales = props.design.otherLocales || [];
|
|
25
|
+
if (props.preferredLocale && otherLocales.includes(props.preferredLocale)) {
|
|
26
|
+
initialLocale = props.preferredLocale;
|
|
27
|
+
}
|
|
28
|
+
else if (otherLocales.includes(T.locale)) {
|
|
29
|
+
initialLocale = T.locale;
|
|
30
|
+
}
|
|
24
31
|
this.state = {
|
|
25
32
|
undoStack: new UndoStack_1.default().push(props.design),
|
|
26
33
|
transientDesign: props.design, // Temporary design for read-only maps
|
|
27
34
|
zoomLocked: true,
|
|
28
35
|
quickfiltersValues: props.quickfiltersValues ?? null,
|
|
29
|
-
hideQuickfilters: false
|
|
36
|
+
hideQuickfilters: false,
|
|
37
|
+
locale: initialLocale,
|
|
38
|
+
previewLocale: null
|
|
30
39
|
};
|
|
31
40
|
}
|
|
32
41
|
componentDidUpdate(prevProps) {
|
|
@@ -54,39 +63,93 @@ class MapComponent extends react_1.default.Component {
|
|
|
54
63
|
handleZoomLockClick = () => {
|
|
55
64
|
return this.setState({ zoomLocked: !this.state.zoomLocked });
|
|
56
65
|
};
|
|
66
|
+
/** Handle locale selection from dropdown */
|
|
67
|
+
handleLocaleSelect = (locale) => {
|
|
68
|
+
const baseLocale = this.props.design.locale || "en";
|
|
69
|
+
const isEditing = this.props.onDesignChange != null;
|
|
70
|
+
if (isEditing) {
|
|
71
|
+
// In edit mode, selecting base language exits preview mode
|
|
72
|
+
// Selecting other language enters preview mode
|
|
73
|
+
if (locale === baseLocale) {
|
|
74
|
+
this.setState({ previewLocale: null });
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.setState({ previewLocale: locale });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// In readonly mode, just change the locale
|
|
82
|
+
this.setState({ locale: locale });
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/** Render the language selector dropdown */
|
|
86
|
+
renderLanguageDropdown() {
|
|
87
|
+
const baseLocale = this.props.design.locale || "en";
|
|
88
|
+
const otherLocales = this.props.design.otherLocales || [];
|
|
89
|
+
const isEditing = this.props.onDesignChange != null;
|
|
90
|
+
const isPreviewMode = isEditing && this.state.previewLocale != null;
|
|
91
|
+
// Determine which locale to display in the dropdown button
|
|
92
|
+
let displayedLocale;
|
|
93
|
+
if (isEditing) {
|
|
94
|
+
displayedLocale = this.state.previewLocale || baseLocale;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
displayedLocale = this.state.locale;
|
|
98
|
+
}
|
|
99
|
+
return (react_1.default.createElement("div", { key: "translations", className: "dropdown d-inline-block" },
|
|
100
|
+
react_1.default.createElement("a", { className: `btn btn-link btn-sm dropdown-toggle ${isPreviewMode ? "text-info" : ""}`, "data-bs-toggle": "dropdown" },
|
|
101
|
+
react_1.default.createElement("span", { className: "fal fa-globe" }),
|
|
102
|
+
" ",
|
|
103
|
+
__1.languages.find(l => l.code === displayedLocale)?.name || displayedLocale,
|
|
104
|
+
isPreviewMode && react_1.default.createElement("span", { className: "badge bg-info ms-1" }, T `Preview`)),
|
|
105
|
+
react_1.default.createElement("ul", { className: "dropdown-menu dropdown-menu-end" },
|
|
106
|
+
react_1.default.createElement("li", { key: baseLocale },
|
|
107
|
+
react_1.default.createElement("a", { className: `dropdown-item ${displayedLocale === baseLocale ? "active" : ""}`, onClick: () => this.handleLocaleSelect(baseLocale) }, __1.languages.find(l => l.code === baseLocale)?.name || baseLocale)),
|
|
108
|
+
isEditing && otherLocales.length > 0 && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
109
|
+
react_1.default.createElement("li", null,
|
|
110
|
+
react_1.default.createElement("hr", { className: "dropdown-divider" })),
|
|
111
|
+
react_1.default.createElement("li", null,
|
|
112
|
+
react_1.default.createElement("span", { className: "dropdown-header" }, T `Preview translations:`)))),
|
|
113
|
+
otherLocales.filter(loc => loc !== baseLocale).map(locale => react_1.default.createElement("li", { key: locale },
|
|
114
|
+
react_1.default.createElement("a", { className: `dropdown-item ${displayedLocale === locale ? "active" : ""}`, onClick: () => this.handleLocaleSelect(locale) }, __1.languages.find(l => l.code === locale)?.name || locale))))));
|
|
115
|
+
}
|
|
57
116
|
renderActionLinks() {
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
className: `fa ${this.state.zoomLocked ? "fa-lock red" : "fa-unlock green"}`,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}, R("span", { className: "fas fa-caret-left" }), R("span", { className: "hide-600px" }, " ", T `Undo`)),
|
|
117
|
+
return (react_1.default.createElement("div", null,
|
|
118
|
+
this.props.onDesignChange != null && [
|
|
119
|
+
react_1.default.createElement("a", { key: "lock", className: "btn btn-link btn-sm", onClick: this.handleZoomLockClick },
|
|
120
|
+
react_1.default.createElement("span", { className: `fa ${this.state.zoomLocked ? "fa-lock red" : "fa-unlock green"}`, style: { marginRight: 5 } }),
|
|
121
|
+
react_1.default.createElement(PopoverHelpComponent_1.default, { placement: "bottom" }, T `Changes to zoom level wont be saved in locked mode`)),
|
|
122
|
+
react_1.default.createElement("a", { key: "undo", className: `btn btn-link btn-sm ${!this.state.undoStack.canUndo() ? "disabled" : ""}`, onClick: this.handleUndo },
|
|
123
|
+
react_1.default.createElement("span", { className: "fas fa-caret-left" }),
|
|
124
|
+
react_1.default.createElement("span", { className: "hide-600px" },
|
|
125
|
+
" ",
|
|
126
|
+
T `Undo`)),
|
|
69
127
|
" ",
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
128
|
+
react_1.default.createElement("a", { key: "redo", className: `btn btn-link btn-sm ${!this.state.undoStack.canRedo() ? "disabled" : ""}`, onClick: this.handleRedo },
|
|
129
|
+
react_1.default.createElement("span", { className: "fas fa-caret-right" }),
|
|
130
|
+
react_1.default.createElement("span", { className: "hide-600px" },
|
|
131
|
+
" ",
|
|
132
|
+
T `Redo`))
|
|
133
|
+
],
|
|
134
|
+
this.props.design.otherLocales && this.props.design.otherLocales.length > 0
|
|
135
|
+
? this.renderLanguageDropdown()
|
|
136
|
+
: undefined,
|
|
137
|
+
this.state.hideQuickfilters && this.props.design.quickfilters && this.props.design.quickfilters.length > 0 && (react_1.default.createElement("a", { key: "showQuickfilters", className: "btn btn-link btn-sm", onClick: this.handleShowQuickfilters },
|
|
138
|
+
react_1.default.createElement("span", { className: "fa fa-filter" }),
|
|
139
|
+
react_1.default.createElement("span", { className: "hide-600px" },
|
|
140
|
+
" ",
|
|
141
|
+
T `Show Quickfilters`))),
|
|
142
|
+
this.props.extraTitleButtonsElem,
|
|
143
|
+
react_1.default.createElement("a", { key: "toggleDesign", className: "btn btn-link btn-sm", onClick: this.handleToggleDesignPanel, title: T `Toggle design panel` }, this.getDesign().hideDesignPanel ? (react_1.default.createElement("span", { className: "fas fa-angle-double-left" })) : (react_1.default.createElement("span", { className: "fas fa-angle-double-right" })))));
|
|
81
144
|
}
|
|
82
145
|
renderHeader() {
|
|
83
|
-
return
|
|
84
|
-
style: {
|
|
146
|
+
return (react_1.default.createElement("div", { style: {
|
|
85
147
|
padding: 4,
|
|
86
148
|
borderBottom: "solid 1px #e8e8e8",
|
|
87
149
|
gridArea: "header"
|
|
88
|
-
}
|
|
89
|
-
|
|
150
|
+
} },
|
|
151
|
+
react_1.default.createElement("div", { style: { float: "right" } }, this.renderActionLinks()),
|
|
152
|
+
this.props.titleElem));
|
|
90
153
|
}
|
|
91
154
|
handleDesignChange = (design) => {
|
|
92
155
|
if (this.props.onDesignChange) {
|
|
@@ -115,21 +178,19 @@ class MapComponent extends react_1.default.Component {
|
|
|
115
178
|
let filters = this.props.extraFilters || [];
|
|
116
179
|
// Compile quickfilters
|
|
117
180
|
filters = filters.concat(new QuickfilterCompiler_1.default(this.props.schema).compile(this.props.design.quickfilters || [], this.state.quickfiltersValues, this.props.quickfilterLocks));
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
});
|
|
181
|
+
const isPreviewMode = this.props.onDesignChange != null && this.state.previewLocale != null;
|
|
182
|
+
// Determine display locale:
|
|
183
|
+
// - In preview mode: use previewLocale
|
|
184
|
+
// - In edit mode (no preview): use design locale
|
|
185
|
+
// - In readonly mode: use state locale
|
|
186
|
+
const displayLocale = isPreviewMode
|
|
187
|
+
? this.state.previewLocale
|
|
188
|
+
: (this.props.onDesignChange != null
|
|
189
|
+
? this.props.design.locale || "en"
|
|
190
|
+
: this.state.locale);
|
|
191
|
+
return (react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true, injectHeight: true }, (size) => {
|
|
192
|
+
return (react_1.default.createElement(MapViewComponent_1.MapViewComponent, { mapDataSource: this.props.mapDataSource, schema: this.props.schema, dataSource: this.props.dataSource, design: this.getDesign(), onDesignChange: isPreviewMode ? undefined : this.handleDesignChange, zoomLocked: this.state.zoomLocked, onRowClick: this.props.onRowClick, extraFilters: filters, locale: displayLocale, width: size.width, height: size.height }));
|
|
193
|
+
}));
|
|
133
194
|
}
|
|
134
195
|
// Get filters from props filters combined with maps filters
|
|
135
196
|
getCompiledFilters() {
|
|
@@ -138,49 +199,46 @@ class MapComponent extends react_1.default.Component {
|
|
|
138
199
|
return compiledFilters;
|
|
139
200
|
}
|
|
140
201
|
renderQuickfilter() {
|
|
141
|
-
return
|
|
142
|
-
design: this.props.design.quickfilters || [],
|
|
143
|
-
schema: this.props.schema,
|
|
144
|
-
dataSource: this.props.dataSource,
|
|
145
|
-
quickfiltersDataSource: this.props.mapDataSource.getQuickfiltersDataSource(),
|
|
146
|
-
values: this.state.quickfiltersValues || undefined,
|
|
147
|
-
onValuesChange: (values) => this.setState({ quickfiltersValues: values }),
|
|
148
|
-
locks: this.props.quickfilterLocks,
|
|
149
|
-
filters: this.getCompiledFilters(),
|
|
150
|
-
hideTopBorder: this.props.hideTitleBar,
|
|
151
|
-
onHide: () => this.setState({ hideQuickfilters: true })
|
|
152
|
-
}));
|
|
202
|
+
return (react_1.default.createElement("div", { style: { gridArea: "quickfilters", borderBottom: "solid 1px #e8e8e8" } },
|
|
203
|
+
react_1.default.createElement(QuickfiltersComponent_1.default, { design: this.props.design.quickfilters || [], schema: this.props.schema, dataSource: this.props.dataSource, quickfiltersDataSource: this.props.mapDataSource.getQuickfiltersDataSource(), values: this.state.quickfiltersValues || undefined, onValuesChange: (values) => this.setState({ quickfiltersValues: values }), locks: this.props.quickfilterLocks, filters: this.getCompiledFilters(), hideTopBorder: this.props.hideTitleBar, onHide: () => this.setState({ hideQuickfilters: true }) })));
|
|
153
204
|
}
|
|
205
|
+
/** Translate function to use for display based on current locale */
|
|
206
|
+
translate = (input) => {
|
|
207
|
+
const design = this.getDesign();
|
|
208
|
+
const designLocale = design.locale || "en";
|
|
209
|
+
const isPreviewMode = this.props.onDesignChange != null && this.state.previewLocale != null;
|
|
210
|
+
// Determine display locale:
|
|
211
|
+
// - In preview mode: use previewLocale
|
|
212
|
+
// - In edit mode (no preview): use design locale
|
|
213
|
+
// - In readonly mode: use state locale
|
|
214
|
+
const displayLocale = isPreviewMode
|
|
215
|
+
? this.state.previewLocale
|
|
216
|
+
: (this.props.onDesignChange != null
|
|
217
|
+
? designLocale
|
|
218
|
+
: this.state.locale);
|
|
219
|
+
if (designLocale === displayLocale) {
|
|
220
|
+
return input;
|
|
221
|
+
}
|
|
222
|
+
return design.translations?.[displayLocale]?.[input] ?? input;
|
|
223
|
+
};
|
|
154
224
|
renderDesigner() {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
schema: this.props.schema,
|
|
158
|
-
dataSource: this.props.dataSource,
|
|
159
|
-
design: this.getDesign(),
|
|
160
|
-
onDesignChange: this.handleDesignChange,
|
|
161
|
-
enableQuickfilters: this.props.enableQuickfilters
|
|
162
|
-
})
|
|
163
|
-
:
|
|
164
|
-
react_1.default.createElement(MapControlComponent_1.default, {
|
|
165
|
-
schema: this.props.schema,
|
|
166
|
-
dataSource: this.props.dataSource,
|
|
167
|
-
design: this.getDesign(),
|
|
168
|
-
onDesignChange: this.handleDesignChange
|
|
169
|
-
}));
|
|
225
|
+
const isPreviewMode = this.props.onDesignChange != null && this.state.previewLocale != null;
|
|
226
|
+
return (react_1.default.createElement("div", { style: { gridArea: "designer", borderLeft: "solid 2px #e8e8e8", overflowY: 'scroll' } }, this.props.onDesignChange && !isPreviewMode ? (react_1.default.createElement(MapDesignerComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, design: this.getDesign(), onDesignChange: this.handleDesignChange, enableQuickfilters: this.props.enableQuickfilters })) : (react_1.default.createElement(MapControlComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, design: this.getDesign(), onDesignChange: this.handleDesignChange, translate: this.translate }))));
|
|
170
227
|
}
|
|
171
228
|
render() {
|
|
172
229
|
const designerVisible = !this.getDesign().hideDesignPanel;
|
|
173
|
-
|
|
174
|
-
return R("div", {
|
|
175
|
-
style: {
|
|
230
|
+
return (react_1.default.createElement("div", { style: {
|
|
176
231
|
width: "100%",
|
|
177
232
|
height: "100%",
|
|
178
233
|
display: "grid",
|
|
179
234
|
gridTemplateColumns: designerVisible ? "70% 30%" : "100%",
|
|
180
235
|
gridTemplateRows: "auto auto 1fr",
|
|
181
236
|
gridTemplateAreas: `"header designer" "quickfilters designer" "view designer"`
|
|
182
|
-
}
|
|
183
|
-
|
|
237
|
+
} },
|
|
238
|
+
this.props.hideTitleBar != true ? this.renderHeader() : null,
|
|
239
|
+
this.state.hideQuickfilters ? null : this.renderQuickfilter(),
|
|
240
|
+
react_1.default.createElement("div", { style: { width: "100%", height: "100%", gridArea: "view", overflow: "hidden" } }, this.renderView()),
|
|
241
|
+
designerVisible ? this.renderDesigner() : null));
|
|
184
242
|
}
|
|
185
243
|
}
|
|
186
244
|
exports.default = MapComponent;
|
|
@@ -7,11 +7,10 @@ export interface MapControlComponentProps {
|
|
|
7
7
|
/** See Map Design.md */
|
|
8
8
|
design: any;
|
|
9
9
|
onDesignChange: any;
|
|
10
|
+
/** Translate function to use for display */
|
|
11
|
+
translate?: (input: string) => string;
|
|
10
12
|
}
|
|
13
|
+
/** Allows controlling readonly map */
|
|
11
14
|
export default class MapControlComponent extends React.Component<MapControlComponentProps> {
|
|
12
|
-
render(): React.
|
|
13
|
-
style: {
|
|
14
|
-
padding: number;
|
|
15
|
-
};
|
|
16
|
-
}, HTMLElement>;
|
|
15
|
+
render(): React.JSX.Element;
|
|
17
16
|
}
|
|
@@ -4,22 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
|
-
const R = react_1.default.createElement;
|
|
8
7
|
const MapLayersDesignerComponent_1 = __importDefault(require("./MapLayersDesignerComponent"));
|
|
9
8
|
const BaseLayerDesignerComponent_1 = __importDefault(require("./BaseLayerDesignerComponent"));
|
|
10
|
-
|
|
9
|
+
/** Allows controlling readonly map */
|
|
11
10
|
class MapControlComponent extends react_1.default.Component {
|
|
12
11
|
render() {
|
|
13
|
-
return
|
|
14
|
-
schema: this.props.schema,
|
|
15
|
-
|
|
16
|
-
design: this.props.design,
|
|
17
|
-
onDesignChange: this.props.onDesignChange,
|
|
18
|
-
allowEditingLayers: false
|
|
19
|
-
}), R("br"), R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, T `Map Style`), R(BaseLayerDesignerComponent_1.default, {
|
|
20
|
-
design: this.props.design,
|
|
21
|
-
onDesignChange: this.props.onDesignChange
|
|
22
|
-
})));
|
|
12
|
+
return (react_1.default.createElement("div", { style: { padding: 5 } },
|
|
13
|
+
react_1.default.createElement(MapLayersDesignerComponent_1.default, { schema: this.props.schema, dataSource: this.props.dataSource, design: this.props.design, onDesignChange: this.props.onDesignChange, allowEditingLayers: false, translate: this.props.translate }),
|
|
14
|
+
react_1.default.createElement("br", null),
|
|
15
|
+
react_1.default.createElement(BaseLayerDesignerComponent_1.default, { design: this.props.design, onDesignChange: this.props.onDesignChange })));
|
|
23
16
|
}
|
|
24
17
|
}
|
|
25
18
|
exports.default = MapControlComponent;
|
package/lib/maps/MapDesign.d.ts
CHANGED
|
@@ -35,6 +35,14 @@ export interface MapDesign {
|
|
|
35
35
|
initialLegendDisplay?: "open" | "closed" | "closedIfSmall";
|
|
36
36
|
/** optional locale (e.g. "fr") to use for display */
|
|
37
37
|
locale?: string;
|
|
38
|
+
/** Other locales that the map is available in. */
|
|
39
|
+
otherLocales?: string[];
|
|
40
|
+
/** Translation map for map. Maps locale to translation map. Does not include default locale. */
|
|
41
|
+
translations?: {
|
|
42
|
+
[locale: string]: {
|
|
43
|
+
[key: string]: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
38
46
|
/** True if design panel is hidden */
|
|
39
47
|
hideDesignPanel?: boolean;
|
|
40
48
|
}
|
|
@@ -15,6 +15,8 @@ export interface MapDesignerComponentProps {
|
|
|
15
15
|
filters?: JsonQLFilter[];
|
|
16
16
|
/** True to enable quickfilters */
|
|
17
17
|
enableQuickfilters?: boolean;
|
|
18
|
+
/** True to enable translations tab. Defaults to true. Set to false when map is embedded in a dashboard. */
|
|
19
|
+
enableTranslations?: boolean;
|
|
18
20
|
}
|
|
19
21
|
export default class MapDesignerComponent extends React.Component<MapDesignerComponentProps> {
|
|
20
22
|
handleAttributionChange: (text: string | undefined) => void;
|
|
@@ -41,6 +41,7 @@ const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
|
|
|
41
41
|
const QuickfiltersDesignComponent_1 = __importDefault(require("../quickfilter/QuickfiltersDesignComponent"));
|
|
42
42
|
const immer_1 = __importDefault(require("immer"));
|
|
43
43
|
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
44
|
+
const MapTranslationsTab_1 = require("./MapTranslationsTab");
|
|
44
45
|
class MapDesignerComponent extends react_1.default.Component {
|
|
45
46
|
handleAttributionChange = (text) => {
|
|
46
47
|
const design = { ...this.props.design, attribution: text };
|
|
@@ -69,7 +70,7 @@ class MapDesignerComponent extends react_1.default.Component {
|
|
|
69
70
|
return this.props.onDesignChange(design);
|
|
70
71
|
};
|
|
71
72
|
renderOptionsTab() {
|
|
72
|
-
return (react_1.default.createElement("div",
|
|
73
|
+
return (react_1.default.createElement("div", { style: { marginBottom: 200 } },
|
|
73
74
|
react_1.default.createElement(BaseLayerDesignerComponent_1.default, { design: this.props.design, onDesignChange: this.props.onDesignChange }),
|
|
74
75
|
react_1.default.createElement(CheckboxComponent_1.default, { checked: this.props.design.autoBounds, onChange: this.handleAutoBoundsChange },
|
|
75
76
|
react_1.default.createElement("span", { className: "text-muted" },
|
|
@@ -94,7 +95,11 @@ class MapDesignerComponent extends react_1.default.Component {
|
|
|
94
95
|
react_1.default.createElement("a", { onClick: this.handleConvertToMarkersMap, className: "btn btn-link btn-sm" }, T `Convert to markers map`))) : undefined,
|
|
95
96
|
react_1.default.createElement(AttributionComponent, { text: this.props.design.attribution, onTextChange: this.handleAttributionChange }),
|
|
96
97
|
react_1.default.createElement("br", null),
|
|
97
|
-
react_1.default.createElement(AdvancedOptionsComponent, { design: this.props.design, onDesignChange: this.props.onDesignChange })
|
|
98
|
+
react_1.default.createElement(AdvancedOptionsComponent, { design: this.props.design, onDesignChange: this.props.onDesignChange }),
|
|
99
|
+
this.props.enableTranslations !== false && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
100
|
+
react_1.default.createElement("hr", null),
|
|
101
|
+
react_1.default.createElement("h5", null, T `Translations`),
|
|
102
|
+
react_1.default.createElement(MapTranslationsTab_1.MapTranslationsTab, { schema: this.props.schema, design: this.props.design, onDesignChange: this.props.onDesignChange })))));
|
|
98
103
|
}
|
|
99
104
|
render() {
|
|
100
105
|
const filterableTables = MapUtils.getFilterableTables(this.props.design, this.props.schema);
|
|
@@ -6,10 +6,6 @@ export interface MapLayerDataSource {
|
|
|
6
6
|
* Called with (design, filters) where design is the design of the layer and filters are filters to apply. Returns URL
|
|
7
7
|
* Only called on layers that are valid */
|
|
8
8
|
getTileUrl(design: any, filters: JsonQLFilter[]): string | null;
|
|
9
|
-
/** Get the url for the interactivity tiles with the specified filters applied
|
|
10
|
-
* Called with (design, filters) where design is the design of the layer and filters are filters to apply. Returns URL
|
|
11
|
-
* Only called on layers that are valid */
|
|
12
|
-
getUtfGridUrl(design: any, filters: JsonQLFilter[]): string | null;
|
|
13
9
|
/** Get the url for vector tile source with an expiry time. Only for layers of type "VectorTile"
|
|
14
10
|
* @param createdAfter ISO 8601 timestamp requiring that tile source on server is created after specified datetime
|
|
15
11
|
*/
|
|
@@ -18,12 +18,14 @@ export interface MapLayerViewDesignerComponentProps {
|
|
|
18
18
|
connectDropTarget?: any;
|
|
19
19
|
allowEditingLayer: boolean;
|
|
20
20
|
filters?: any;
|
|
21
|
+
/** Translate function to use for display */
|
|
22
|
+
translate?: (input: string) => string;
|
|
21
23
|
}
|
|
22
24
|
interface MapLayerViewDesignerComponentState {
|
|
23
25
|
editing: any;
|
|
24
26
|
}
|
|
25
27
|
export default class MapLayerViewDesignerComponent extends React.Component<MapLayerViewDesignerComponentProps, MapLayerViewDesignerComponentState> {
|
|
26
|
-
constructor(props:
|
|
28
|
+
constructor(props: MapLayerViewDesignerComponentProps);
|
|
27
29
|
update(updates: any): any;
|
|
28
30
|
handleVisibleClick: () => any;
|
|
29
31
|
handleHideLegend: (hideLegend: any) => any;
|
|
@@ -97,7 +97,11 @@ class MapLayerViewDesignerComponent extends react_1.default.Component {
|
|
|
97
97
|
}), R("div", null, R(PopoverHelpComponent_1.default, { placement: "top", key: "help" }, T `Layers in the same group can only be selected one at a time`)));
|
|
98
98
|
}
|
|
99
99
|
renderName() {
|
|
100
|
-
|
|
100
|
+
// Translate the name if a translate function is provided
|
|
101
|
+
const displayName = this.props.translate
|
|
102
|
+
? this.props.translate(this.props.layerView.name)
|
|
103
|
+
: this.props.layerView.name;
|
|
104
|
+
return R("span", { className: "hover-display-parent", onClick: this.handleRename, style: { cursor: "pointer" } }, displayName, " ", R("span", { className: "hover-display-child fas fa-pencil-alt text-muted" }));
|
|
101
105
|
}
|
|
102
106
|
renderEditor() {
|
|
103
107
|
const layer = LayerFactory_1.default.createLayer(this.props.layerView.type);
|
|
@@ -12,6 +12,8 @@ export interface MapLayersDesignerComponentProps {
|
|
|
12
12
|
/** True to allow editing layers */
|
|
13
13
|
allowEditingLayers: boolean;
|
|
14
14
|
filters?: any;
|
|
15
|
+
/** Translate function to use for display */
|
|
16
|
+
translate?: (input: string) => string;
|
|
15
17
|
}
|
|
16
18
|
export default class MapLayersDesignerComponent extends React.Component<MapLayersDesignerComponentProps> {
|
|
17
19
|
updateDesign(changes: any): void;
|
|
@@ -70,7 +70,8 @@ class MapLayersDesignerComponent extends react_1.default.Component {
|
|
|
70
70
|
connectDragPreview,
|
|
71
71
|
connectDropTarget,
|
|
72
72
|
allowEditingLayer: this.props.allowEditingLayers,
|
|
73
|
-
filters: lodash_1.default.compact(filters)
|
|
73
|
+
filters: lodash_1.default.compact(filters),
|
|
74
|
+
translate: this.props.translate
|
|
74
75
|
}));
|
|
75
76
|
};
|
|
76
77
|
render() {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Schema } from "@mwater/expressions";
|
|
3
|
+
import { MapDesign } from "./MapDesign";
|
|
4
|
+
export interface MapTranslationsTabProps {
|
|
5
|
+
/** Schema to use */
|
|
6
|
+
schema: Schema;
|
|
7
|
+
/** Map design */
|
|
8
|
+
design: MapDesign;
|
|
9
|
+
/** Called with new design */
|
|
10
|
+
onDesignChange: (design: MapDesign) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Translations tab for map designer that wraps the reusable TranslationsTabComponent
|
|
14
|
+
*/
|
|
15
|
+
export declare function MapTranslationsTab(props: MapTranslationsTabProps): React.JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.MapTranslationsTab = MapTranslationsTab;
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
31
|
+
const TranslationsTabComponent_1 = require("../TranslationsTabComponent");
|
|
32
|
+
const MapUtils = __importStar(require("./MapUtils"));
|
|
33
|
+
const immer_1 = __importDefault(require("immer"));
|
|
34
|
+
/**
|
|
35
|
+
* Translations tab for map designer that wraps the reusable TranslationsTabComponent
|
|
36
|
+
*/
|
|
37
|
+
function MapTranslationsTab(props) {
|
|
38
|
+
const { design, onDesignChange, schema } = props;
|
|
39
|
+
const translatableStrings = (0, react_1.useMemo)(() => MapUtils.getTranslatableStrings(design, schema), [design, schema]);
|
|
40
|
+
return (react_1.default.createElement(TranslationsTabComponent_1.TranslationsTabComponent, { locale: design.locale || "en", otherLocales: design.otherLocales || [], translations: design.translations || {}, translatableStrings: translatableStrings, onLocaleChange: (locale) => onDesignChange((0, immer_1.default)(design, draft => {
|
|
41
|
+
draft.locale = locale;
|
|
42
|
+
})), onOtherLocalesChange: (otherLocales) => onDesignChange((0, immer_1.default)(design, draft => {
|
|
43
|
+
draft.otherLocales = otherLocales;
|
|
44
|
+
})), onTranslationsChange: (translations) => onDesignChange((0, immer_1.default)(design, draft => {
|
|
45
|
+
draft.translations = translations;
|
|
46
|
+
})), downloadFilename: "Map Translations.xlsx", baseLanguageDescription: T `This is the language that the map is written in.` }));
|
|
47
|
+
}
|
package/lib/maps/MapUtils.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { DataSource, Schema } from "@mwater/expressions";
|
|
|
3
3
|
import { JsonQLFilter } from "../JsonQLFilter";
|
|
4
4
|
import { MapDesign } from "./MapDesign";
|
|
5
5
|
import { HoverOverItem } from "./maps";
|
|
6
|
+
import { Axis } from "../axes/Axis";
|
|
6
7
|
export interface MapScope {
|
|
7
8
|
name: string;
|
|
8
9
|
filter: JsonQLFilter;
|
|
@@ -24,6 +25,16 @@ export declare function getCompiledFilters(design: MapDesign, schema: Schema, fi
|
|
|
24
25
|
* Get a list of translatable strings in the map design
|
|
25
26
|
*/
|
|
26
27
|
export declare function getTranslatableStrings(design: MapDesign, schema: Schema): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Get translatable strings from an axis's categoryLabels and nullLabel.
|
|
30
|
+
* Always includes "None" since it's the default label for null values in AxisBuilder.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getTranslatableStringsFromAxis(axis: Axis | null | undefined): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Translate an axis's category labels and null label.
|
|
35
|
+
* If no nullLabel is set, translates the default "None" and sets it so AxisBuilder uses it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function translateAxis(axis: Axis | null | undefined, translate: (input: string) => string): Axis | null | undefined;
|
|
27
38
|
/**
|
|
28
39
|
* Convenience function to get hover over data for a map given an id and a list of hover over items
|
|
29
40
|
*/
|
package/lib/maps/MapUtils.js
CHANGED
|
@@ -34,10 +34,13 @@ exports.convertToMarkersMap = convertToMarkersMap;
|
|
|
34
34
|
exports.getFilterableTables = getFilterableTables;
|
|
35
35
|
exports.getCompiledFilters = getCompiledFilters;
|
|
36
36
|
exports.getTranslatableStrings = getTranslatableStrings;
|
|
37
|
+
exports.getTranslatableStringsFromAxis = getTranslatableStringsFromAxis;
|
|
38
|
+
exports.translateAxis = translateAxis;
|
|
37
39
|
exports.getSimpleHoverOverData = getSimpleHoverOverData;
|
|
38
40
|
const lodash_1 = __importStar(require("lodash"));
|
|
39
41
|
const expressions_1 = require("@mwater/expressions");
|
|
40
42
|
const LayerFactory_1 = __importDefault(require("./LayerFactory"));
|
|
43
|
+
const immer_1 = require("immer");
|
|
41
44
|
// Check if can convert to a cluster map. Only maps containing marker views can be
|
|
42
45
|
function canConvertToClusterMap(design) {
|
|
43
46
|
return lodash_1.default.any(design.layerViews, (lv) => lv.type === "Markers");
|
|
@@ -159,25 +162,78 @@ function getTranslatableStrings(design, schema) {
|
|
|
159
162
|
// Remove duplicates
|
|
160
163
|
return lodash_1.default.uniq(strings);
|
|
161
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Get translatable strings from an axis's categoryLabels and nullLabel.
|
|
167
|
+
* Always includes "None" since it's the default label for null values in AxisBuilder.
|
|
168
|
+
*/
|
|
169
|
+
function getTranslatableStringsFromAxis(axis) {
|
|
170
|
+
const strings = [];
|
|
171
|
+
if (axis?.categoryLabels) {
|
|
172
|
+
strings.push(...Object.values(axis.categoryLabels));
|
|
173
|
+
}
|
|
174
|
+
if (axis?.nullLabel) {
|
|
175
|
+
strings.push(axis.nullLabel);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Always include "None" as it's the default nullLabel in AxisBuilder
|
|
179
|
+
strings.push("None");
|
|
180
|
+
}
|
|
181
|
+
return strings;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Translate an axis's category labels and null label.
|
|
185
|
+
* If no nullLabel is set, translates the default "None" and sets it so AxisBuilder uses it.
|
|
186
|
+
*/
|
|
187
|
+
function translateAxis(axis, translate) {
|
|
188
|
+
if (!axis)
|
|
189
|
+
return axis;
|
|
190
|
+
return (0, immer_1.produce)(axis, draft => {
|
|
191
|
+
if (draft.categoryLabels) {
|
|
192
|
+
for (const key in draft.categoryLabels) {
|
|
193
|
+
draft.categoryLabels[key] = translate(draft.categoryLabels[key]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (draft.nullLabel) {
|
|
197
|
+
draft.nullLabel = translate(draft.nullLabel);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
// Translate the default "None" and set it so AxisBuilder uses it
|
|
201
|
+
// instead of falling back to T`None` which uses the global locale
|
|
202
|
+
const translatedNone = translate("None");
|
|
203
|
+
if (translatedNone !== "None") {
|
|
204
|
+
draft.nullLabel = translatedNone;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
162
209
|
/**
|
|
163
210
|
* Convenience function to get hover over data for a map given an id and a list of hover over items
|
|
164
211
|
*/
|
|
165
212
|
async function getSimpleHoverOverData(options) {
|
|
166
213
|
const { id, table, filters, schema, dataSource, hoverOverItems } = options;
|
|
214
|
+
const exprUtils = new expressions_1.ExprUtils(schema);
|
|
167
215
|
const exprCompiler = new expressions_1.ExprCompiler(schema);
|
|
168
216
|
const query = {
|
|
169
217
|
type: "query",
|
|
170
218
|
selects: [],
|
|
171
219
|
from: exprCompiler.compileTable(table, "main"),
|
|
220
|
+
groupBy: [],
|
|
172
221
|
limit: 1
|
|
173
222
|
};
|
|
174
|
-
|
|
223
|
+
// Check if any items are aggregate
|
|
224
|
+
const isAggregate = hoverOverItems.some(item => exprUtils.getExprAggrStatus(item.value ?? null) === "aggregate");
|
|
225
|
+
for (let i = 0; i < hoverOverItems.length; i++) {
|
|
226
|
+
const item = hoverOverItems[i];
|
|
175
227
|
if (item.value) {
|
|
176
228
|
query.selects.push({
|
|
177
229
|
type: "select",
|
|
178
230
|
expr: exprCompiler.compileExpr({ expr: item.value, tableAlias: "main" }),
|
|
179
231
|
alias: item.id
|
|
180
232
|
});
|
|
233
|
+
// Group by if there are aggregate items and this is not aggregate
|
|
234
|
+
if (isAggregate && exprUtils.getExprAggrStatus(item.value) !== "aggregate") {
|
|
235
|
+
query.groupBy.push(i + 1);
|
|
236
|
+
}
|
|
181
237
|
}
|
|
182
238
|
}
|
|
183
239
|
if (filters) {
|