@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
|
@@ -4,10 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.LayoutOptionsComponent = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
7
8
|
const react_1 = __importDefault(require("react"));
|
|
8
9
|
const react_2 = require("react");
|
|
9
10
|
const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
|
|
10
11
|
const layoutOptions_1 = require("./layoutOptions");
|
|
12
|
+
const ColorComponent_1 = __importDefault(require("../ColorComponent"));
|
|
13
|
+
const FontStyleEditor_1 = require("./FontStyleEditor");
|
|
14
|
+
const immer_1 = __importDefault(require("immer"));
|
|
15
|
+
const file_saver_1 = __importDefault(require("file-saver"));
|
|
11
16
|
const sizeOptions = [
|
|
12
17
|
{ value: { width: 360, height: 640 }, label: "Phone (360x640)" },
|
|
13
18
|
{ value: { width: 768, height: 1024 }, label: "Tablet (768x1024)" },
|
|
@@ -20,45 +25,20 @@ function LayoutOptionsComponent(props) {
|
|
|
20
25
|
function setLayoutOptions(layoutOptions) {
|
|
21
26
|
props.onDesignChange({ ...props.design, layoutOptions });
|
|
22
27
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
react_1.default.createElement("div", { style: { padding: 5, gridRow: "1 / 3" } },
|
|
28
|
-
react_1.default.createElement("div", { key: "back" },
|
|
29
|
-
react_1.default.createElement("button", { className: "btn btn-sm btn-link", onClick: props.onClose },
|
|
30
|
-
react_1.default.createElement("i", { className: "fa fa-arrow-left" }),
|
|
31
|
-
" Close")),
|
|
32
|
-
react_1.default.createElement("br", null),
|
|
28
|
+
const isCustomized = !lodash_1.default.isEqual(layoutOptions, (0, layoutOptions_1.getDefaultLayoutOptions)(props.design.style));
|
|
29
|
+
return (react_1.default.createElement("div", { style: { display: "grid", gridTemplateRows: "auto 1fr", gridTemplateColumns: "360px 1fr", height: "100%" } },
|
|
30
|
+
react_1.default.createElement("div", { style: { padding: "5px 10px 5px 0px", gridRow: "1 / 3", overflowY: "auto" } },
|
|
31
|
+
react_1.default.createElement("h5", null, "Theme"),
|
|
33
32
|
react_1.default.createElement(ThemeToggle, { theme: props.design.style, onChange: (theme) => {
|
|
33
|
+
if (isCustomized) {
|
|
34
|
+
if (!confirm("Are you sure you want to change the theme? Your customizations will be lost."))
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
34
37
|
props.onDesignChange({ ...props.design, style: theme, layoutOptions: (0, layoutOptions_1.getDefaultLayoutOptions)(theme) });
|
|
35
|
-
} }),
|
|
38
|
+
}, isCustomized: isCustomized }),
|
|
36
39
|
react_1.default.createElement("br", null),
|
|
37
|
-
react_1.default.createElement("
|
|
38
|
-
|
|
39
|
-
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Collapse to Single Column" },
|
|
40
|
-
react_1.default.createElement(WidthSelector, { value: layoutOptions.collapseColumnsWidth, onChange: (collapseColumnsWidth) => {
|
|
41
|
-
setLayoutOptions({ ...layoutOptions, collapseColumnsWidth });
|
|
42
|
-
}, sign: "< " })),
|
|
43
|
-
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Hide Quickfilters" },
|
|
44
|
-
react_1.default.createElement(WidthSelector, { value: layoutOptions.hideQuickfiltersWidth, onChange: (hideQuickfiltersWidth) => {
|
|
45
|
-
setLayoutOptions({ ...layoutOptions, hideQuickfiltersWidth });
|
|
46
|
-
}, sign: "< " })),
|
|
47
|
-
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Minimum Width (before scrolling or scaling)" },
|
|
48
|
-
react_1.default.createElement(WidthSelector, { value: layoutOptions.minimumWidth, onChange: (minimumWidth) => {
|
|
49
|
-
setLayoutOptions({ ...layoutOptions, minimumWidth });
|
|
50
|
-
}, sign: "< " }),
|
|
51
|
-
react_1.default.createElement(bootstrap_1.FormGroup, { label: "When Below Minimum Width" },
|
|
52
|
-
react_1.default.createElement(bootstrap_1.Toggle, { value: layoutOptions.belowMinimumWidth, onChange: (belowMinimumWidth) => {
|
|
53
|
-
setLayoutOptions({ ...layoutOptions, belowMinimumWidth: belowMinimumWidth });
|
|
54
|
-
}, options: [
|
|
55
|
-
{ value: "scroll", label: "Scroll" },
|
|
56
|
-
{ value: "scale", label: "Scale" }
|
|
57
|
-
] }))),
|
|
58
|
-
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Maximum Width (before padding)" },
|
|
59
|
-
react_1.default.createElement(WidthSelector, { value: layoutOptions.maximumWidth, onChange: (maximumWidth) => {
|
|
60
|
-
setLayoutOptions({ ...layoutOptions, maximumWidth });
|
|
61
|
-
}, sign: "> " }))),
|
|
40
|
+
react_1.default.createElement(bootstrap_1.CollapsibleSection, { label: react_1.default.createElement("h5", { style: { display: "inline-block" } }, "Customize Layout"), initiallyOpen: isCustomized },
|
|
41
|
+
react_1.default.createElement(CustomizeLayout, { layoutOptions: layoutOptions, onLayoutOptionsChange: setLayoutOptions }))),
|
|
62
42
|
react_1.default.createElement("div", { style: { textAlign: "center", padding: 3 } },
|
|
63
43
|
react_1.default.createElement("span", { className: "text-muted" }, "Preview As:\u00A0"),
|
|
64
44
|
react_1.default.createElement(bootstrap_1.Toggle, { value: previewSize, onChange: setPreviewSize, size: "xs", options: sizeOptions.map((so, index) => ({ value: index, label: so.label })) })),
|
|
@@ -84,7 +64,7 @@ function LayoutOptionsComponent(props) {
|
|
|
84
64
|
exports.LayoutOptionsComponent = LayoutOptionsComponent;
|
|
85
65
|
function ThemeToggle(props) {
|
|
86
66
|
function renderStyleItem(theme) {
|
|
87
|
-
const isActive = (props.theme || "default") == theme;
|
|
67
|
+
const isActive = props.isCustomized ? theme == "custom" : (props.theme || "default") == theme;
|
|
88
68
|
if (theme == "default") {
|
|
89
69
|
return (react_1.default.createElement("a", { key: theme, className: isActive ? "list-group-item active" : "list-group-item", onClick: props.onChange.bind(null, "default") },
|
|
90
70
|
react_1.default.createElement("div", null, "Classic Dashboard"),
|
|
@@ -100,13 +80,202 @@ function ThemeToggle(props) {
|
|
|
100
80
|
react_1.default.createElement("div", null, "Story"),
|
|
101
81
|
react_1.default.createElement("div", { style: { opacity: 0.6 } }, "Ideal for data-driven storytelling with lots of text")));
|
|
102
82
|
}
|
|
83
|
+
if (theme == "custom") {
|
|
84
|
+
return (react_1.default.createElement("a", { key: theme, className: isActive ? "list-group-item active" : "list-group-item" },
|
|
85
|
+
react_1.default.createElement("div", null, "Custom"),
|
|
86
|
+
react_1.default.createElement("div", { style: { opacity: 0.6 } }, "Customized theme")));
|
|
87
|
+
}
|
|
103
88
|
return null;
|
|
104
89
|
}
|
|
105
|
-
return (react_1.default.createElement(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
90
|
+
return (react_1.default.createElement("div", { className: "list-group" },
|
|
91
|
+
renderStyleItem("default"),
|
|
92
|
+
renderStyleItem("greybg"),
|
|
93
|
+
renderStyleItem("story"),
|
|
94
|
+
props.isCustomized && renderStyleItem("custom")));
|
|
95
|
+
}
|
|
96
|
+
function CustomizeLayout(props) {
|
|
97
|
+
const { layoutOptions, onLayoutOptionsChange } = props;
|
|
98
|
+
const handleDownloadTheme = () => {
|
|
99
|
+
const blob = new Blob([JSON.stringify(layoutOptions, null, 2)], { type: "application/json" });
|
|
100
|
+
file_saver_1.default.saveAs(blob, "custom_theme.theme");
|
|
101
|
+
};
|
|
102
|
+
const handleUploadTheme = (event) => {
|
|
103
|
+
const file = event.target.files?.[0];
|
|
104
|
+
if (file) {
|
|
105
|
+
const reader = new FileReader();
|
|
106
|
+
reader.onload = (e) => {
|
|
107
|
+
try {
|
|
108
|
+
const uploadedTheme = JSON.parse(e.target?.result);
|
|
109
|
+
onLayoutOptionsChange(uploadedTheme);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
alert("Invalid theme file");
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
reader.readAsText(file);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
return (react_1.default.createElement("div", null,
|
|
119
|
+
react_1.default.createElement(bootstrap_1.CollapsiblePanel, { title: "Text" },
|
|
120
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Title" },
|
|
121
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.titleWidgetFont, onChange: (titleWidgetFont) => {
|
|
122
|
+
onLayoutOptionsChange({ ...layoutOptions, titleWidgetFont });
|
|
123
|
+
} })),
|
|
124
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Heading H1" },
|
|
125
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.textWidgetH1Font, onChange: (textWidgetH1Font) => {
|
|
126
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetH1Font });
|
|
127
|
+
} }),
|
|
128
|
+
react_1.default.createElement("div", { className: "mt-1" },
|
|
129
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Top Margin:", horizontal: true, labelMuted: true },
|
|
130
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.textWidgetH1MarginTop, onChange: (textWidgetH1MarginTop) => {
|
|
131
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetH1MarginTop: textWidgetH1MarginTop });
|
|
132
|
+
} })))),
|
|
133
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Heading H2" },
|
|
134
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.textWidgetH2Font, onChange: (textWidgetH2Font) => {
|
|
135
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetH2Font });
|
|
136
|
+
} }),
|
|
137
|
+
react_1.default.createElement("div", { className: "mt-1" },
|
|
138
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Top Margin:", horizontal: true, labelMuted: true },
|
|
139
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.textWidgetH2MarginTop, onChange: (textWidgetH2MarginTop) => {
|
|
140
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetH2MarginTop: textWidgetH2MarginTop });
|
|
141
|
+
} })))),
|
|
142
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Text" },
|
|
143
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.textWidgetFont, onChange: (textWidgetFont) => {
|
|
144
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetFont });
|
|
145
|
+
} }),
|
|
146
|
+
react_1.default.createElement("div", { className: "mt-1" },
|
|
147
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Line Height:", horizontal: true, labelMuted: true },
|
|
148
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.textWidgetLineHeight, onChange: (textWidgetLineHeight) => {
|
|
149
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetLineHeight: textWidgetLineHeight });
|
|
150
|
+
}, allowDefault: true, defaultLabel: "Default" })),
|
|
151
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Paragraph Spacing:", horizontal: true, labelMuted: true },
|
|
152
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.textWidgetParagraphSpacing, onChange: (textWidgetParagraphSpacing) => {
|
|
153
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetParagraphSpacing: textWidgetParagraphSpacing });
|
|
154
|
+
} })))),
|
|
155
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "List Line Height:", horizontal: true },
|
|
156
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.textWidgetListLineHeight, onChange: (textWidgetListLineHeight) => {
|
|
157
|
+
onLayoutOptionsChange({ ...layoutOptions, textWidgetListLineHeight: textWidgetListLineHeight });
|
|
158
|
+
}, allowDefault: true, defaultLabel: "Default" })),
|
|
159
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Chart Header Font" },
|
|
160
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.widgetHeaderFont, onChange: (widgetHeaderFont) => {
|
|
161
|
+
onLayoutOptionsChange({ ...layoutOptions, widgetHeaderFont });
|
|
162
|
+
} })),
|
|
163
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Chart Footer Font" },
|
|
164
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.widgetFooterFont, onChange: (widgetFooterFont) => {
|
|
165
|
+
onLayoutOptionsChange({ ...layoutOptions, widgetFooterFont });
|
|
166
|
+
} })),
|
|
167
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Chart Font" },
|
|
168
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.chartFont, onChange: (chartFont) => {
|
|
169
|
+
onLayoutOptionsChange({ ...layoutOptions, chartFont });
|
|
170
|
+
} })),
|
|
171
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Table Font" },
|
|
172
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.tableFont, onChange: (tableFont) => {
|
|
173
|
+
onLayoutOptionsChange({ ...layoutOptions, tableFont });
|
|
174
|
+
} })),
|
|
175
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Pivot Table Font" },
|
|
176
|
+
react_1.default.createElement(FontStyleEditor_1.FontStyleEditor, { value: layoutOptions.pivotTableFont, onChange: (pivotTableFont) => {
|
|
177
|
+
onLayoutOptionsChange({ ...layoutOptions, pivotTableFont });
|
|
178
|
+
} }))),
|
|
179
|
+
react_1.default.createElement(bootstrap_1.CollapsiblePanel, { title: "Spacing" },
|
|
180
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Outer Padding:", horizontal: true },
|
|
181
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.outerPadding, onChange: (outerPadding) => {
|
|
182
|
+
onLayoutOptionsChange({ ...layoutOptions, outerPadding: outerPadding });
|
|
183
|
+
} })),
|
|
184
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Block Margins" },
|
|
185
|
+
react_1.default.createElement(SpacingInput, { value: layoutOptions.blockMargin, onChange: (blockMargin) => {
|
|
186
|
+
onLayoutOptionsChange({ ...layoutOptions, blockMargin });
|
|
187
|
+
} })),
|
|
188
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Block Padding" },
|
|
189
|
+
react_1.default.createElement(SpacingInput, { value: layoutOptions.blockPadding, onChange: (blockPadding) => {
|
|
190
|
+
onLayoutOptionsChange({ ...layoutOptions, blockPadding });
|
|
191
|
+
} })),
|
|
192
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Block Border Radius:", horizontal: true },
|
|
193
|
+
react_1.default.createElement(PixelsInput, { value: layoutOptions.blockBorderRadius, onChange: (blockBorderRadius) => {
|
|
194
|
+
onLayoutOptionsChange({ ...layoutOptions, blockBorderRadius: blockBorderRadius });
|
|
195
|
+
} }))),
|
|
196
|
+
react_1.default.createElement(bootstrap_1.CollapsiblePanel, { title: "Colors" },
|
|
197
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Background Color:", horizontal: true },
|
|
198
|
+
react_1.default.createElement(ColorComponent_1.default, { color: layoutOptions.backgroundColor, onChange: (backgroundColor) => {
|
|
199
|
+
onLayoutOptionsChange({ ...layoutOptions, backgroundColor: backgroundColor ?? "white" });
|
|
200
|
+
} })),
|
|
201
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Block Background Color:", horizontal: true },
|
|
202
|
+
react_1.default.createElement(ColorComponent_1.default, { color: layoutOptions.blockBackgroundColor, onChange: (blockBackgroundColor) => {
|
|
203
|
+
onLayoutOptionsChange({ ...layoutOptions, blockBackgroundColor: blockBackgroundColor ?? "white" });
|
|
204
|
+
} })),
|
|
205
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Custom Colors" },
|
|
206
|
+
react_1.default.createElement("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', gap: '5px' } }, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((colorIndex) => (react_1.default.createElement(ColorComponent_1.default, { key: colorIndex, color: layoutOptions.customColors[colorIndex], onChange: (color) => {
|
|
207
|
+
onLayoutOptionsChange((0, immer_1.default)(layoutOptions, (draft) => {
|
|
208
|
+
draft.customColors[colorIndex] = color;
|
|
209
|
+
}));
|
|
210
|
+
} })))))),
|
|
211
|
+
react_1.default.createElement(bootstrap_1.CollapsiblePanel, { title: "Responsive Layout" },
|
|
212
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Collapse to Single Column" },
|
|
213
|
+
react_1.default.createElement(WidthSelector, { value: layoutOptions.collapseColumnsWidth, onChange: (collapseColumnsWidth) => {
|
|
214
|
+
onLayoutOptionsChange({ ...layoutOptions, collapseColumnsWidth });
|
|
215
|
+
}, sign: "< " })),
|
|
216
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Hide Quickfilters" },
|
|
217
|
+
react_1.default.createElement(WidthSelector, { value: layoutOptions.hideQuickfiltersWidth, onChange: (hideQuickfiltersWidth) => {
|
|
218
|
+
onLayoutOptionsChange({ ...layoutOptions, hideQuickfiltersWidth });
|
|
219
|
+
}, sign: "< " })),
|
|
220
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Minimum Width (before scrolling or scaling)" },
|
|
221
|
+
react_1.default.createElement(WidthSelector, { value: layoutOptions.minimumWidth, onChange: (minimumWidth) => {
|
|
222
|
+
onLayoutOptionsChange({ ...layoutOptions, minimumWidth });
|
|
223
|
+
}, sign: "< " }),
|
|
224
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "When Below Minimum Width" },
|
|
225
|
+
react_1.default.createElement(bootstrap_1.Toggle, { value: layoutOptions.belowMinimumWidth, onChange: (belowMinimumWidth) => {
|
|
226
|
+
onLayoutOptionsChange({ ...layoutOptions, belowMinimumWidth: belowMinimumWidth });
|
|
227
|
+
}, size: "sm", options: [
|
|
228
|
+
{ value: "scroll", label: "Scroll" },
|
|
229
|
+
{ value: "scale", label: "Scale" }
|
|
230
|
+
] }))),
|
|
231
|
+
react_1.default.createElement(bootstrap_1.FormGroup, { label: "Maximum Width (before padding)" },
|
|
232
|
+
react_1.default.createElement(WidthSelector, { value: layoutOptions.maximumWidth, onChange: (maximumWidth) => {
|
|
233
|
+
onLayoutOptionsChange({ ...layoutOptions, maximumWidth });
|
|
234
|
+
}, sign: "> " })),
|
|
235
|
+
react_1.default.createElement(bootstrap_1.Checkbox, { value: layoutOptions.collapseSpacers, onChange: (collapseSpacers) => {
|
|
236
|
+
onLayoutOptionsChange({ ...layoutOptions, collapseSpacers });
|
|
237
|
+
} }, "Collapse Spacers on Mobile")),
|
|
238
|
+
react_1.default.createElement(bootstrap_1.CollapsiblePanel, { title: "Download/Upload Theme", initiallyClosed: true },
|
|
239
|
+
react_1.default.createElement("div", { className: "mb-2 text-muted" }, "Download or upload a custom theme to use for this dashboard. This saves the current theme as a theme file that you can then use on other dashboards by uploading it there."),
|
|
240
|
+
react_1.default.createElement("div", { style: { display: "flex", flexDirection: "column", marginTop: "10px", gap: "10px" } },
|
|
241
|
+
react_1.default.createElement("button", { className: "btn btn-sm btn-secondary", onClick: handleDownloadTheme },
|
|
242
|
+
react_1.default.createElement("i", { className: "fas fa-download" }),
|
|
243
|
+
" Download Custom Theme"),
|
|
244
|
+
react_1.default.createElement("label", { className: "btn btn-sm btn-secondary" },
|
|
245
|
+
react_1.default.createElement("i", { className: "fas fa-upload" }),
|
|
246
|
+
" Upload Custom Theme",
|
|
247
|
+
react_1.default.createElement("input", { type: "file", accept: ".theme", style: { display: "none" }, onChange: handleUploadTheme }))))));
|
|
248
|
+
}
|
|
249
|
+
function SpacingInput(props) {
|
|
250
|
+
return (react_1.default.createElement("div", { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', width: '100%' } },
|
|
251
|
+
react_1.default.createElement("div", null, "Top"),
|
|
252
|
+
react_1.default.createElement("div", null, "Bottom"),
|
|
253
|
+
react_1.default.createElement("div", null, "Left"),
|
|
254
|
+
react_1.default.createElement("div", null, "Right"),
|
|
255
|
+
react_1.default.createElement(PixelsInput, { value: props.value.top, onChange: (top) => props.onChange({ ...props.value, top: top }) }),
|
|
256
|
+
react_1.default.createElement(PixelsInput, { value: props.value.bottom, onChange: (bottom) => props.onChange({ ...props.value, bottom: bottom }) }),
|
|
257
|
+
react_1.default.createElement(PixelsInput, { value: props.value.left, onChange: (left) => props.onChange({ ...props.value, left: left }) }),
|
|
258
|
+
react_1.default.createElement(PixelsInput, { value: props.value.right, onChange: (right) => props.onChange({ ...props.value, right: right }) })));
|
|
259
|
+
}
|
|
260
|
+
function PixelsInput(props) {
|
|
261
|
+
const options = [
|
|
262
|
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40
|
|
263
|
+
];
|
|
264
|
+
return (react_1.default.createElement("div", { className: "dropdown" },
|
|
265
|
+
react_1.default.createElement("a", { className: "dropdown-toggle", type: "button", id: "pixelsInputDropdown", "data-bs-toggle": "dropdown", "aria-expanded": "false" }, props.value === null ? (props.defaultLabel || "Default") : `${props.value}px`),
|
|
266
|
+
react_1.default.createElement("ul", { className: "dropdown-menu", "aria-labelledby": "pixelsInputDropdown" },
|
|
267
|
+
props.allowDefault && (react_1.default.createElement("li", { key: "default" },
|
|
268
|
+
react_1.default.createElement("a", { className: "dropdown-item", href: "#", onClick: (e) => {
|
|
269
|
+
e.preventDefault();
|
|
270
|
+
props.onChange(null);
|
|
271
|
+
} }, props.defaultLabel || "Default"))),
|
|
272
|
+
options.map(option => (react_1.default.createElement("li", { key: option },
|
|
273
|
+
react_1.default.createElement("a", { className: "dropdown-item", href: "#", onClick: (e) => {
|
|
274
|
+
e.preventDefault();
|
|
275
|
+
props.onChange(option);
|
|
276
|
+
} },
|
|
277
|
+
option,
|
|
278
|
+
"px")))))));
|
|
110
279
|
}
|
|
111
280
|
function WidthSelector(props) {
|
|
112
281
|
return (react_1.default.createElement(bootstrap_1.Select, { value: props.value, onChange: props.onChange, nullLabel: "N/A", options: [
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="jquery" />
|
|
2
1
|
import { DataSource, Expr } from "@mwater/expressions";
|
|
3
2
|
import { JsonQLFilter } from "../JsonQLFilter";
|
|
4
3
|
import { QuickfiltersDataSource } from "../quickfilter/QuickfiltersDataSource";
|
|
@@ -42,7 +41,7 @@ declare class ServerQuickfilterDataSource implements QuickfiltersDataSource {
|
|
|
42
41
|
declare class ServerWidgetDataSource {
|
|
43
42
|
options: ServerWidgetDataSourceOptions;
|
|
44
43
|
constructor(options: ServerWidgetDataSourceOptions);
|
|
45
|
-
getData(design: any, filters: JsonQLFilter[], callback: (error: any, data?: any) => void):
|
|
44
|
+
getData(design: any, filters: JsonQLFilter[], callback: (error: any, data?: any) => void): void;
|
|
46
45
|
getMapDataSource(design: any): ServerWidgetMapDataSource;
|
|
47
46
|
getImageUrl(imageId: string, height?: number): string;
|
|
48
47
|
}
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const lodash_1 = __importDefault(require("lodash"));
|
|
7
|
-
const jquery_1 = __importDefault(require("jquery"));
|
|
8
7
|
const expressions_1 = require("@mwater/expressions");
|
|
9
8
|
const querystring_1 = __importDefault(require("querystring"));
|
|
10
9
|
const LayerFactory_1 = __importDefault(require("../maps/LayerFactory"));
|
|
@@ -55,18 +54,23 @@ class ServerQuickfilterDataSource {
|
|
|
55
54
|
const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000);
|
|
56
55
|
headers["Cache-Control"] = `max-age=${seconds}`;
|
|
57
56
|
}
|
|
58
|
-
|
|
59
|
-
dataType: "json",
|
|
57
|
+
fetch(url, {
|
|
60
58
|
method: "GET",
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
headers: headers
|
|
60
|
+
})
|
|
61
|
+
.then(async (response) => {
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
throw new Error(text);
|
|
65
|
+
}
|
|
66
|
+
return response.json();
|
|
63
67
|
})
|
|
64
|
-
.
|
|
68
|
+
.then(data => {
|
|
65
69
|
return callback(null, data);
|
|
66
70
|
})
|
|
67
|
-
.
|
|
68
|
-
console.log(
|
|
69
|
-
return callback(
|
|
71
|
+
.catch(error => {
|
|
72
|
+
console.log(error.message);
|
|
73
|
+
return callback(error);
|
|
70
74
|
});
|
|
71
75
|
}
|
|
72
76
|
}
|
|
@@ -102,18 +106,23 @@ class ServerWidgetDataSource {
|
|
|
102
106
|
const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000);
|
|
103
107
|
headers["Cache-Control"] = `max-age=${seconds}`;
|
|
104
108
|
}
|
|
105
|
-
|
|
106
|
-
dataType: "json",
|
|
109
|
+
fetch(url, {
|
|
107
110
|
method: "GET",
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
headers: headers
|
|
112
|
+
})
|
|
113
|
+
.then(async (response) => {
|
|
114
|
+
if (!response.ok) {
|
|
115
|
+
const text = await response.text();
|
|
116
|
+
throw new Error(text);
|
|
117
|
+
}
|
|
118
|
+
return response.json();
|
|
110
119
|
})
|
|
111
|
-
.
|
|
120
|
+
.then(data => {
|
|
112
121
|
return callback(null, data);
|
|
113
122
|
})
|
|
114
|
-
.
|
|
115
|
-
console.log(
|
|
116
|
-
return callback(
|
|
123
|
+
.catch(error => {
|
|
124
|
+
console.log(error.message);
|
|
125
|
+
return callback(error);
|
|
117
126
|
});
|
|
118
127
|
}
|
|
119
128
|
// For map widgets, the following is required
|
|
@@ -170,18 +179,23 @@ class ServerWidgetMapDataSource {
|
|
|
170
179
|
const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000);
|
|
171
180
|
headers["Cache-Control"] = `max-age=${seconds}`;
|
|
172
181
|
}
|
|
173
|
-
|
|
174
|
-
dataType: "json",
|
|
182
|
+
fetch(url, {
|
|
175
183
|
method: "GET",
|
|
176
|
-
url,
|
|
177
184
|
headers
|
|
178
185
|
})
|
|
179
|
-
.
|
|
186
|
+
.then(async (response) => {
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
const text = await response.text();
|
|
189
|
+
throw new Error(text);
|
|
190
|
+
}
|
|
191
|
+
return response.json();
|
|
192
|
+
})
|
|
193
|
+
.then(data => {
|
|
180
194
|
return callback(null, data);
|
|
181
195
|
})
|
|
182
|
-
.
|
|
183
|
-
console.log(
|
|
184
|
-
return callback(
|
|
196
|
+
.catch(error => {
|
|
197
|
+
console.log(error.message);
|
|
198
|
+
return callback(error);
|
|
185
199
|
});
|
|
186
200
|
}
|
|
187
201
|
getQuickfiltersDataSource() {
|
|
@@ -356,18 +370,23 @@ class ServerWidgetLayerPopupWidgetDataSource {
|
|
|
356
370
|
const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000);
|
|
357
371
|
headers["Cache-Control"] = `max-age=${seconds}`;
|
|
358
372
|
}
|
|
359
|
-
|
|
360
|
-
dataType: "json",
|
|
373
|
+
fetch(url, {
|
|
361
374
|
method: "GET",
|
|
362
|
-
|
|
363
|
-
headers
|
|
375
|
+
headers: headers
|
|
364
376
|
})
|
|
365
|
-
.
|
|
366
|
-
|
|
377
|
+
.then(async (response) => {
|
|
378
|
+
if (!response.ok) {
|
|
379
|
+
const text = await response.text();
|
|
380
|
+
throw new Error(text);
|
|
381
|
+
}
|
|
382
|
+
return response.json();
|
|
383
|
+
})
|
|
384
|
+
.then(data => {
|
|
385
|
+
callback(null, data);
|
|
367
386
|
})
|
|
368
|
-
.
|
|
369
|
-
console.log(
|
|
370
|
-
|
|
387
|
+
.catch(error => {
|
|
388
|
+
console.log(error.message);
|
|
389
|
+
callback(error);
|
|
371
390
|
});
|
|
372
391
|
}
|
|
373
392
|
/** For map widgets, the following is required */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Schema, DataSource } from "@mwater/expressions";
|
|
3
3
|
import { JsonQLFilter } from "../JsonQLFilter";
|
|
4
4
|
import { WidgetScope } from "../WidgetScope";
|
|
5
|
-
import
|
|
5
|
+
import { WidgetDataSource } from "../widgets/WidgetDataSource";
|
|
6
6
|
/**
|
|
7
7
|
* Component which renders a widget and ensures that props do not change
|
|
8
8
|
* unnecessarily.
|
|
@@ -18,8 +18,8 @@ export declare function WidgetComponent(props: {
|
|
|
18
18
|
onDesignChange?: {
|
|
19
19
|
(design: object): void;
|
|
20
20
|
} | null;
|
|
21
|
-
/** Data source for
|
|
22
|
-
|
|
21
|
+
/** Data source for widget */
|
|
22
|
+
widgetDataSource: WidgetDataSource;
|
|
23
23
|
/** schema to use **/
|
|
24
24
|
schema: Schema;
|
|
25
25
|
/** data source to use. Only used when designing, for display uses widgetDataSource **/
|
|
@@ -11,10 +11,6 @@ const WidgetFactory_1 = __importDefault(require("../widgets/WidgetFactory"));
|
|
|
11
11
|
* unnecessarily.
|
|
12
12
|
*/
|
|
13
13
|
function WidgetComponent(props) {
|
|
14
|
-
// Get and stabilize widget data source
|
|
15
|
-
// TODO!!! There is a global problem with DashboardDataSources being re-created on each render.
|
|
16
|
-
// TODO!!! This now only uses the type of the dashboard data source. They should be more stable in the future.
|
|
17
|
-
const widgetDataSource = (0, react_1.useMemo)(() => props.dashboardDataSource.getWidgetDataSource(props.type, props.id), [props.dashboardDataSource.constructor, props.type, props.id, props.schema, props.dataSource, props.refreshKey]);
|
|
18
14
|
const widget = WidgetFactory_1.default.createWidget(props.type);
|
|
19
15
|
// Stabilize functions
|
|
20
16
|
const onDesignChange = useStabilizeFunction(props.onDesignChange);
|
|
@@ -27,7 +23,7 @@ function WidgetComponent(props) {
|
|
|
27
23
|
return widget.createViewElement({
|
|
28
24
|
schema: props.schema,
|
|
29
25
|
dataSource: props.dataSource,
|
|
30
|
-
widgetDataSource,
|
|
26
|
+
widgetDataSource: props.widgetDataSource,
|
|
31
27
|
design: props.design,
|
|
32
28
|
scope,
|
|
33
29
|
filters,
|
|
@@ -40,7 +36,8 @@ function WidgetComponent(props) {
|
|
|
40
36
|
namedStrings: props.namedStrings,
|
|
41
37
|
tocEntries: props.tocEntries,
|
|
42
38
|
onScrollToTOCEntry: props.onScrollToTOCEntry,
|
|
43
|
-
widgetRef
|
|
39
|
+
widgetRef,
|
|
40
|
+
refreshKey: props.refreshKey
|
|
44
41
|
});
|
|
45
42
|
}
|
|
46
43
|
exports.WidgetComponent = WidgetComponent;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import DashboardDataSource from './DashboardDataSource';
|
|
2
|
+
import { WidgetDataSource } from '../widgets/WidgetDataSource';
|
|
3
|
+
/**
|
|
4
|
+
* A class that prioritizes widget data sources based on the priority of the data source
|
|
5
|
+
* and ensures that only N requests is made at a time for a given widget data source.
|
|
6
|
+
*/
|
|
7
|
+
export declare class WidgetDataSourcePrioritizer {
|
|
8
|
+
private queue;
|
|
9
|
+
private dashboardDataSource;
|
|
10
|
+
/**
|
|
11
|
+
* Key is widget type + ":" + widget id + ":" + priority
|
|
12
|
+
*/
|
|
13
|
+
widgetDataSources: {
|
|
14
|
+
[key: string]: WidgetDataSource;
|
|
15
|
+
};
|
|
16
|
+
constructor(dashboardDataSource: DashboardDataSource, concurrency: number);
|
|
17
|
+
/** Get a widget data source with the given priority */
|
|
18
|
+
getWidgetDataSource(widgetType: string, widgetId: string, priority: number): WidgetDataSource;
|
|
19
|
+
cancel(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WidgetDataSourcePrioritizer = void 0;
|
|
7
|
+
const p_queue_1 = __importDefault(require("p-queue"));
|
|
8
|
+
/**
|
|
9
|
+
* A class that prioritizes widget data sources based on the priority of the data source
|
|
10
|
+
* and ensures that only N requests is made at a time for a given widget data source.
|
|
11
|
+
*/
|
|
12
|
+
class WidgetDataSourcePrioritizer {
|
|
13
|
+
queue;
|
|
14
|
+
dashboardDataSource;
|
|
15
|
+
/**
|
|
16
|
+
* Key is widget type + ":" + widget id + ":" + priority
|
|
17
|
+
*/
|
|
18
|
+
widgetDataSources;
|
|
19
|
+
constructor(dashboardDataSource, concurrency) {
|
|
20
|
+
this.dashboardDataSource = dashboardDataSource;
|
|
21
|
+
this.queue = new p_queue_1.default({ concurrency: concurrency });
|
|
22
|
+
this.widgetDataSources = {};
|
|
23
|
+
}
|
|
24
|
+
/** Get a widget data source with the given priority */
|
|
25
|
+
getWidgetDataSource(widgetType, widgetId, priority) {
|
|
26
|
+
let widgetDataSource = this.widgetDataSources[widgetType + ":" + widgetId + ":" + priority];
|
|
27
|
+
if (!widgetDataSource) {
|
|
28
|
+
const innerWidgetDataSource = this.dashboardDataSource.getWidgetDataSource(widgetType, widgetId);
|
|
29
|
+
widgetDataSource = {
|
|
30
|
+
getData: (design, filters, callback) => {
|
|
31
|
+
const task = () => new Promise((resolve, reject) => {
|
|
32
|
+
innerWidgetDataSource.getData(design, filters, (error, data) => {
|
|
33
|
+
if (error) {
|
|
34
|
+
callback(error);
|
|
35
|
+
reject(error);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
callback(null, data);
|
|
39
|
+
resolve(data);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
// Create an abort controller for this task
|
|
44
|
+
const taskAbortController = new AbortController();
|
|
45
|
+
// Queue the task and handle errors
|
|
46
|
+
this.queue.add(task, { priority: priority, signal: taskAbortController.signal }).catch((e) => {
|
|
47
|
+
console.log("Task failed", e);
|
|
48
|
+
callback(e);
|
|
49
|
+
});
|
|
50
|
+
return taskAbortController;
|
|
51
|
+
},
|
|
52
|
+
/** Get the url to download an image (by id from an image or imagelist column)
|
|
53
|
+
* Height, if specified, is minimum height needed. May return larger image */
|
|
54
|
+
getImageUrl: (imageId, height) => {
|
|
55
|
+
return innerWidgetDataSource.getImageUrl(imageId, height);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
if (innerWidgetDataSource.getMapDataSource) {
|
|
59
|
+
widgetDataSource.getMapDataSource = (design) => {
|
|
60
|
+
return innerWidgetDataSource.getMapDataSource(design);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
this.widgetDataSources[widgetType + ":" + widgetId + ":" + priority] = widgetDataSource;
|
|
64
|
+
}
|
|
65
|
+
return widgetDataSource;
|
|
66
|
+
}
|
|
67
|
+
cancel() {
|
|
68
|
+
// Clear the queue
|
|
69
|
+
this.queue.clear();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.WidgetDataSourcePrioritizer = WidgetDataSourcePrioritizer;
|