@mwater/visualization 5.0.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/MWaterAddRelatedFormComponent.d.ts +1 -1
- package/lib/MWaterAddRelatedFormComponent.js +10 -17
- package/lib/MWaterContextComponent.d.ts +17 -7
- package/lib/MWaterContextComponent.js +51 -67
- package/lib/MWaterLoaderComponent.d.ts +2 -2
- package/lib/MWaterLoaderComponent.js +1 -1
- package/lib/MWaterTableSelectComponent.d.ts +0 -1
- package/lib/MWaterTableSelectComponent.js +20 -41
- package/lib/axes/RangesComponent.d.ts +12 -6
- package/lib/axes/RangesComponent.js +21 -10
- package/lib/dashboards/DashboardComponent.d.ts +1 -9
- package/lib/dashboards/DashboardComponent.js +16 -27
- package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -0
- package/lib/dashboards/ServerDashboardDataSource.js +3 -0
- package/lib/datagrids/DatagridComponent.d.ts +8 -4
- package/lib/datagrids/DatagridComponent.js +27 -5
- package/lib/datagrids/DatagridDataSource.d.ts +1 -0
- package/lib/datagrids/DatagridDataSource.js +3 -0
- package/lib/datagrids/DatagridDesign.d.ts +2 -0
- package/lib/datagrids/DatagridDesignerComponent.js +3 -2
- package/lib/datagrids/DatagridViewComponent.js +1 -1
- package/lib/datagrids/DirectDatagridDataSource.d.ts +1 -0
- package/lib/datagrids/DirectDatagridDataSource.js +26 -0
- package/lib/datagrids/ServerDatagridDataSource.d.ts +1 -0
- package/lib/datagrids/ServerDatagridDataSource.js +15 -0
- package/lib/index.d.ts +0 -1
- package/lib/index.js +2 -4
- package/lib/layouts/blocks/BlocksDisplayComponent.js +2 -2
- package/lib/layouts/grid/LegoLayoutEngine.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.js +2 -2
- package/lib/maps/ChoroplethLayerDesigner.js +2 -2
- package/lib/maps/ClusterLayerDesignerComponent.js +2 -2
- package/lib/maps/DirectMapDataSource.js +1 -2
- package/lib/maps/GridLayerDesigner.js +2 -2
- package/lib/maps/MapDesignerComponent.d.ts +1 -12
- package/lib/maps/MapDesignerComponent.js +5 -12
- package/lib/maps/MarkersLayerDesignerComponent.js +2 -2
- package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -1
- package/lib/maps/PopupFilterJoinsUtils.js +4 -3
- package/lib/maps/UtfGridLayer.js +1 -1
- package/lib/widgets/ImageWidgetComponent.js +2 -2
- package/lib/widgets/charts/calendar/CalendarChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -1
- package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +1 -1
- package/lib/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -2
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +2 -2
- package/lib/widgets/charts/table/TableChartDesignerComponent.js +2 -2
- package/lib/widgets/text/ExprItemEditorComponent.js +2 -2
- package/package.json +1 -1
- package/src/MWaterAddRelatedFormComponent.ts +15 -20
- package/src/MWaterContextComponent.tsx +140 -0
- package/src/MWaterLoaderComponent.ts +2 -2
- package/src/{MWaterTableSelectComponent.ts → MWaterTableSelectComponent.tsx} +61 -66
- package/src/axes/AxisBuilder.ts +1 -1
- package/src/axes/RangesComponent.ts +27 -16
- package/src/dashboards/{DashboardComponent.ts → DashboardComponent.tsx} +37 -40
- package/src/dashboards/ServerDashboardDataSource.ts +16 -12
- package/src/datagrids/DatagridComponent.ts +45 -14
- package/src/datagrids/DatagridDataSource.ts +8 -0
- package/src/datagrids/DatagridDesign.ts +3 -0
- package/src/datagrids/DatagridDesignerComponent.tsx +9 -1
- package/src/datagrids/DatagridViewComponent.ts +1 -1
- package/src/datagrids/DirectDatagridDataSource.ts +35 -0
- package/src/datagrids/ServerDatagridDataSource.ts +22 -4
- package/src/index.ts +0 -2
- package/src/layouts/blocks/BlocksDisplayComponent.ts +2 -2
- package/src/layouts/grid/LegoLayoutEngine.ts +2 -2
- package/src/layouts/grid/WidgetContainerComponent.ts +2 -2
- package/src/maps/BingLayer.ts +2 -2
- package/src/maps/BufferLayerDesignerComponent.ts +1 -1
- package/src/maps/ChoroplethLayerDesigner.tsx +1 -1
- package/src/maps/ClusterLayerDesignerComponent.ts +1 -1
- package/src/maps/DirectMapDataSource.ts +1 -2
- package/src/maps/GridLayerDesigner.tsx +1 -1
- package/src/maps/LegendGroup.ts +1 -1
- package/src/maps/MWaterServerLayer.ts +2 -2
- package/src/maps/{MapDesignerComponent.ts → MapDesignerComponent.tsx} +8 -16
- package/src/maps/MarkersLayerDesignerComponent.ts +1 -1
- package/src/maps/PopupFilterJoinsUtils.ts +4 -4
- package/src/maps/ServerMapDataSource.ts +6 -6
- package/src/maps/SwitchableTileUrlLayerDesigner.tsx +1 -13
- package/src/maps/UtfGridLayer.ts +4 -4
- package/src/maps/mapboxUtils.ts +2 -2
- package/src/richtext/ExprItemsHtmlConverter.ts +1 -1
- package/src/richtext/FontColorPaletteItem.ts +1 -1
- package/src/richtext/FontSizePaletteItem.ts +1 -1
- package/src/richtext/ItemsHtmlConverter.ts +2 -2
- package/src/widgets/ImageWidgetComponent.ts +1 -1
- package/src/widgets/charts/calendar/CalendarChartDesignerComponent.ts +1 -1
- package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +1 -1
- package/src/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.ts +1 -1
- package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +1 -1
- package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +1 -1
- package/src/widgets/charts/table/TableChartDesignerComponent.ts +1 -1
- package/src/widgets/text/ExprItemEditorComponent.tsx +1 -1
- package/src/MWaterContextComponent.ts +0 -141
- package/src/TableSelectComponent.ts +0 -60
|
@@ -36,9 +36,8 @@ const ModalPopupComponent_1 = __importDefault(require("@mwater/react-library/lib
|
|
|
36
36
|
const querystring_1 = __importDefault(require("querystring"));
|
|
37
37
|
const expressions_1 = require("@mwater/expressions");
|
|
38
38
|
const ui = __importStar(require("./UIComponents"));
|
|
39
|
-
const formUtils = __importStar(require("@mwater/forms/lib/formUtils")); // TODO requireing this directly because of bizarre backbone issue
|
|
40
39
|
// Link that when clicked popup up a modal window allowing user to select a form
|
|
41
|
-
// with an
|
|
40
|
+
// with an Site question to the extraTables
|
|
42
41
|
class MWaterAddRelatedFormComponent extends react_1.default.Component {
|
|
43
42
|
constructor(props) {
|
|
44
43
|
super(props);
|
|
@@ -91,35 +90,29 @@ class AddRelatedFormModalComponent extends react_1.default.Component {
|
|
|
91
90
|
};
|
|
92
91
|
}
|
|
93
92
|
componentDidMount() {
|
|
94
|
-
// Get all forms visible to user
|
|
93
|
+
// Get all forms visible to user that have _entity_types that include table
|
|
95
94
|
const query = {};
|
|
96
|
-
query.selector = JSON.stringify({
|
|
95
|
+
query.selector = JSON.stringify({
|
|
96
|
+
state: { $ne: "deleted" },
|
|
97
|
+
_entity_types: { $in: [this.props.table.split(".")[1]] }
|
|
98
|
+
});
|
|
99
|
+
query.fields = JSON.stringify({ "_id": 1, "design.name": 1, "modified": 1, "created": 1 });
|
|
97
100
|
if (this.props.client) {
|
|
98
101
|
query.client = this.props.client;
|
|
99
102
|
}
|
|
100
|
-
// Get list of
|
|
103
|
+
// Get list of related forms
|
|
101
104
|
return jquery_1.default.getJSON(this.props.apiUrl + "forms?" + querystring_1.default.stringify(query), (forms) => {
|
|
102
105
|
// Sort by modified.on desc but first by user
|
|
103
106
|
forms = lodash_1.default.sortByOrder(forms, [(form) => (form.created.by === this.props.user ? 1 : 0), (form) => form.modified.on], ["desc", "desc"]);
|
|
104
|
-
// Filter by Entity and Site questions of tableId type
|
|
105
|
-
if (this.props.table.startsWith("entities.")) {
|
|
106
|
-
forms = lodash_1.default.filter(forms, (form) => formUtils.findEntityQuestion(form.design, this.props.table.split(".")[1]));
|
|
107
|
-
}
|
|
108
|
-
else if (this.props.table.startsWith("assets:")) {
|
|
109
|
-
const assetSystemId = parseInt(this.props.table.split(":")[1]);
|
|
110
|
-
forms = forms.filter((form) => {
|
|
111
|
-
return formUtils.findAssetQuestion(form.design, assetSystemId) != null;
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
107
|
// Get _id, name, and description
|
|
115
108
|
const items = lodash_1.default.map(forms, (form) => ({
|
|
116
109
|
name: expressions_1.ExprUtils.localizeString(form.design.name, this.context.locale),
|
|
117
110
|
desc: `Modified ${(0, moment_1.default)(form.modified.on, moment_1.default.ISO_8601).format("ll")}`,
|
|
118
111
|
onClick: this.props.onSelect.bind(null, "responses:" + form._id)
|
|
119
112
|
}));
|
|
120
|
-
|
|
113
|
+
this.setState({ items });
|
|
121
114
|
}).fail((xhr) => {
|
|
122
|
-
|
|
115
|
+
this.setState({ error: xhr.responseText });
|
|
123
116
|
});
|
|
124
117
|
}
|
|
125
118
|
renderContents() {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import PropTypes from "prop-types";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Schema } from "@mwater/expressions";
|
|
4
|
-
|
|
3
|
+
import { Schema, Section } from "@mwater/expressions";
|
|
4
|
+
import { CustomTableSelectComponentFactoryOptions, DecorateScalarExprTreeSectionChildrenOptions } from "@mwater/expressions-ui";
|
|
5
|
+
/**
|
|
6
|
+
* Creates several contexts to allow selecting of a table in an mWater-friendly way
|
|
5
7
|
* and several other context items
|
|
6
8
|
*/
|
|
7
9
|
export default class MWaterContextComponent extends React.Component<{
|
|
@@ -18,14 +20,22 @@ export default class MWaterContextComponent extends React.Component<{
|
|
|
18
20
|
addLayerElementFactory?: any;
|
|
19
21
|
}> {
|
|
20
22
|
static childContextTypes: {
|
|
21
|
-
tableSelectElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
|
|
22
23
|
addLayerElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
|
|
23
24
|
globalFiltersElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
|
|
24
|
-
decorateScalarExprTreeSectionChildren: PropTypes.Requireable<(...args: any[]) => any>;
|
|
25
|
-
isScalarExprTreeSectionInitiallyOpen: PropTypes.Requireable<(...args: any[]) => any>;
|
|
26
|
-
isScalarExprTreeSectionMatch: PropTypes.Requireable<(...args: any[]) => any>;
|
|
27
25
|
};
|
|
26
|
+
createTableSelectElementFactory: (options: CustomTableSelectComponentFactoryOptions) => React.JSX.Element;
|
|
28
27
|
getChildContext(): any;
|
|
28
|
+
isScalarExprTreeSectionMatch: (options: {
|
|
29
|
+
tableId: string;
|
|
30
|
+
section: Section;
|
|
31
|
+
filter?: string;
|
|
32
|
+
}) => true | null;
|
|
33
|
+
isScalarExprTreeSectionInitiallyOpen: (options: {
|
|
34
|
+
tableId: string;
|
|
35
|
+
section: Section;
|
|
36
|
+
filter?: string;
|
|
37
|
+
}) => boolean;
|
|
38
|
+
decorateScalarExprTreeSectionChildren: (options: DecorateScalarExprTreeSectionChildrenOptions) => React.ReactNode;
|
|
29
39
|
handleAddTable: (table: any) => void;
|
|
30
|
-
render(): React.
|
|
40
|
+
render(): React.JSX.Element;
|
|
31
41
|
}
|
|
@@ -11,40 +11,23 @@ const MWaterTableSelectComponent_1 = __importDefault(require("./MWaterTableSelec
|
|
|
11
11
|
const MWaterAddRelatedFormComponent_1 = __importDefault(require("./MWaterAddRelatedFormComponent"));
|
|
12
12
|
const MWaterAddRelatedIndicatorComponent_1 = __importDefault(require("./MWaterAddRelatedIndicatorComponent"));
|
|
13
13
|
const MWaterGlobalFiltersComponent_1 = __importDefault(require("./MWaterGlobalFiltersComponent"));
|
|
14
|
-
|
|
14
|
+
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
15
|
+
const expressions_ui_2 = require("@mwater/expressions-ui");
|
|
16
|
+
/**
|
|
17
|
+
* Creates several contexts to allow selecting of a table in an mWater-friendly way
|
|
15
18
|
* and several other context items
|
|
16
19
|
*/
|
|
17
20
|
class MWaterContextComponent extends react_1.default.Component {
|
|
18
21
|
static childContextTypes = {
|
|
19
|
-
tableSelectElementFactory: prop_types_1.default.func,
|
|
20
22
|
addLayerElementFactory: prop_types_1.default.func,
|
|
21
|
-
globalFiltersElementFactory: prop_types_1.default.func,
|
|
23
|
+
globalFiltersElementFactory: prop_types_1.default.func, // Call with props { schema, dataSource, filterableTables, globalFilters, onChange, nullIfIrrelevant }.
|
|
22
24
|
// Displays a component to edit global filters. nullIfIrrelevant causes null element if not applicable to filterableTables
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Should return true to set initially open
|
|
27
|
-
isScalarExprTreeSectionInitiallyOpen: prop_types_1.default.func,
|
|
28
|
-
// Function to override filtering of a section. Passed { tableId: id of table, section: section object from schema, filter: optional string filter }
|
|
29
|
-
// Should return null for default, true to include, false to exclude
|
|
30
|
-
isScalarExprTreeSectionMatch: prop_types_1.default.func
|
|
25
|
+
};
|
|
26
|
+
createTableSelectElementFactory = (options) => {
|
|
27
|
+
return (react_1.default.createElement(MWaterTableSelectComponent_1.default, { apiUrl: this.props.apiUrl, client: this.props.client, schema: options.schema, user: this.props.user, table: options.value ?? undefined, onChange: options.onChange, extraTables: this.props.extraTables, onExtraTablesChange: this.props.onExtraTablesChange, filter: options.filter, onFilterChange: options.onFilterChange }));
|
|
31
28
|
};
|
|
32
29
|
getChildContext() {
|
|
33
30
|
const context = {};
|
|
34
|
-
context.tableSelectElementFactory = (props) => {
|
|
35
|
-
return react_1.default.createElement(MWaterTableSelectComponent_1.default, {
|
|
36
|
-
apiUrl: this.props.apiUrl,
|
|
37
|
-
client: this.props.client,
|
|
38
|
-
schema: props.schema,
|
|
39
|
-
user: this.props.user,
|
|
40
|
-
table: props.value,
|
|
41
|
-
onChange: props.onChange,
|
|
42
|
-
extraTables: this.props.extraTables,
|
|
43
|
-
onExtraTablesChange: this.props.onExtraTablesChange,
|
|
44
|
-
filter: props.filter,
|
|
45
|
-
onFilterChange: props.onFilterChange
|
|
46
|
-
});
|
|
47
|
-
};
|
|
48
31
|
if (this.props.addLayerElementFactory) {
|
|
49
32
|
context.addLayerElementFactory = this.props.addLayerElementFactory;
|
|
50
33
|
}
|
|
@@ -54,55 +37,56 @@ class MWaterContextComponent extends react_1.default.Component {
|
|
|
54
37
|
}
|
|
55
38
|
return react_1.default.createElement(MWaterGlobalFiltersComponent_1.default, props);
|
|
56
39
|
};
|
|
57
|
-
context.decorateScalarExprTreeSectionChildren = (options) => {
|
|
58
|
-
// If related forms section of entities table or assets table
|
|
59
|
-
if ((options.tableId.match(/^entities\./) || options.tableId.match(/^assets:/)) && options.section.id === "!related_forms") {
|
|
60
|
-
return R("div", { key: "_add_related_form_parent" }, options.children, R(MWaterAddRelatedFormComponent_1.default, {
|
|
61
|
-
key: "_add_related_form",
|
|
62
|
-
table: options.tableId,
|
|
63
|
-
apiUrl: this.props.apiUrl,
|
|
64
|
-
client: this.props.client,
|
|
65
|
-
user: this.props.user,
|
|
66
|
-
schema: this.props.schema,
|
|
67
|
-
onSelect: this.handleAddTable
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
// If indicators section of entities table
|
|
71
|
-
if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
|
|
72
|
-
return R("div", { key: "_add_related_indicator_parent" }, options.children, R(MWaterAddRelatedIndicatorComponent_1.default, {
|
|
73
|
-
key: "_add_related_indicator",
|
|
74
|
-
table: options.tableId,
|
|
75
|
-
apiUrl: this.props.apiUrl,
|
|
76
|
-
client: this.props.client,
|
|
77
|
-
user: this.props.user,
|
|
78
|
-
schema: this.props.schema,
|
|
79
|
-
onSelect: this.handleAddTable,
|
|
80
|
-
filter: options.filter
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return options.children;
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
// Always match indicator section
|
|
88
|
-
context.isScalarExprTreeSectionMatch = (options) => {
|
|
89
|
-
if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
};
|
|
94
|
-
// Nothing initially open
|
|
95
|
-
context.isScalarExprTreeSectionInitiallyOpen = (options) => {
|
|
96
|
-
return null;
|
|
97
|
-
};
|
|
98
40
|
return context;
|
|
99
41
|
}
|
|
42
|
+
isScalarExprTreeSectionMatch = (options) => {
|
|
43
|
+
if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
};
|
|
48
|
+
isScalarExprTreeSectionInitiallyOpen = (options) => {
|
|
49
|
+
return false;
|
|
50
|
+
};
|
|
51
|
+
decorateScalarExprTreeSectionChildren = (options) => {
|
|
52
|
+
// If related forms section of entities table or assets table
|
|
53
|
+
if (options.tableId.match(/^entities\./) && options.section.id === "!related_forms") {
|
|
54
|
+
return R("div", { key: "_add_related_form_parent" }, options.children, R(MWaterAddRelatedFormComponent_1.default, {
|
|
55
|
+
key: "_add_related_form",
|
|
56
|
+
table: options.tableId,
|
|
57
|
+
apiUrl: this.props.apiUrl,
|
|
58
|
+
client: this.props.client,
|
|
59
|
+
user: this.props.user,
|
|
60
|
+
schema: this.props.schema,
|
|
61
|
+
onSelect: this.handleAddTable
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
// If indicators section of entities table
|
|
65
|
+
if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
|
|
66
|
+
return R("div", { key: "_add_related_indicator_parent" }, options.children, R(MWaterAddRelatedIndicatorComponent_1.default, {
|
|
67
|
+
key: "_add_related_indicator",
|
|
68
|
+
table: options.tableId,
|
|
69
|
+
apiUrl: this.props.apiUrl,
|
|
70
|
+
client: this.props.client,
|
|
71
|
+
user: this.props.user,
|
|
72
|
+
schema: this.props.schema,
|
|
73
|
+
onSelect: this.handleAddTable,
|
|
74
|
+
filter: options.filter
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
return options.children;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
100
81
|
handleAddTable = (table) => {
|
|
101
82
|
const extraTables = lodash_1.default.union(this.props.extraTables || [], [table]);
|
|
102
83
|
return this.props.onExtraTablesChange(extraTables);
|
|
103
84
|
};
|
|
104
85
|
render() {
|
|
105
|
-
return this.
|
|
86
|
+
return react_1.default.createElement(expressions_ui_1.CustomTableSelectComponentFactoryContext.Provider, { value: this.createTableSelectElementFactory },
|
|
87
|
+
react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionMatchContext.Provider, { value: this.isScalarExprTreeSectionMatch },
|
|
88
|
+
react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionInitiallyOpenContext.Provider, { value: this.isScalarExprTreeSectionInitiallyOpen },
|
|
89
|
+
react_1.default.createElement(expressions_ui_1.DecorateScalarExprTreeSectionChildrenContext.Provider, { value: this.decorateScalarExprTreeSectionChildren }, this.props.children))));
|
|
106
90
|
}
|
|
107
91
|
}
|
|
108
92
|
exports.default = MWaterContextComponent;
|
|
@@ -3,7 +3,7 @@ import { DataSource, Schema } from "@mwater/expressions";
|
|
|
3
3
|
import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent";
|
|
4
4
|
/**
|
|
5
5
|
* Loads an mWater schema from the server and creates child with schema and dataSource
|
|
6
|
-
* Also creates
|
|
6
|
+
* Also creates context to allow selecting of a table in an mWater-friendly way
|
|
7
7
|
* and several other context items
|
|
8
8
|
*/
|
|
9
9
|
export default class MWaterLoaderComponent extends AsyncLoadComponent<{
|
|
@@ -27,7 +27,7 @@ export default class MWaterLoaderComponent extends AsyncLoadComponent<{
|
|
|
27
27
|
dataSource: DataSource;
|
|
28
28
|
}) => ReactElement<any>;
|
|
29
29
|
/** Custom error formatter that returns React node or string, gets passed the error response from server */
|
|
30
|
-
errorFormatter
|
|
30
|
+
errorFormatter?: (data: any, defaultError: string) => string;
|
|
31
31
|
}, {
|
|
32
32
|
error: any;
|
|
33
33
|
schema: Schema | null;
|
|
@@ -12,7 +12,7 @@ const mWaterLoader_1 = __importDefault(require("./mWaterLoader"));
|
|
|
12
12
|
const MWaterContextComponent_1 = __importDefault(require("./MWaterContextComponent"));
|
|
13
13
|
/**
|
|
14
14
|
* Loads an mWater schema from the server and creates child with schema and dataSource
|
|
15
|
-
* Also creates
|
|
15
|
+
* Also creates context to allow selecting of a table in an mWater-friendly way
|
|
16
16
|
* and several other context items
|
|
17
17
|
*/
|
|
18
18
|
class MWaterLoaderComponent extends AsyncLoadComponent_1.default {
|
|
@@ -24,7 +24,6 @@ interface MWaterTableSelectComponentState {
|
|
|
24
24
|
export default class MWaterTableSelectComponent extends React.Component<MWaterTableSelectComponentProps, MWaterTableSelectComponentState> {
|
|
25
25
|
static contextTypes: {
|
|
26
26
|
locale: PropTypes.Requireable<string>;
|
|
27
|
-
activeTables: PropTypes.Requireable<string[]>;
|
|
28
27
|
};
|
|
29
28
|
toggleEdit: any;
|
|
30
29
|
constructor(props: any);
|
|
@@ -12,12 +12,11 @@ const expressions_1 = require("@mwater/expressions");
|
|
|
12
12
|
const MWaterResponsesFilterComponent_1 = __importDefault(require("./MWaterResponsesFilterComponent"));
|
|
13
13
|
const ModalPopupComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalPopupComponent"));
|
|
14
14
|
const MWaterCompleteTableSelectComponent_1 = __importDefault(require("./MWaterCompleteTableSelectComponent"));
|
|
15
|
+
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
15
16
|
// Allows selection of a mwater-visualization table. Loads forms as well and calls event if modified
|
|
16
17
|
class MWaterTableSelectComponent extends react_1.default.Component {
|
|
17
18
|
static contextTypes = {
|
|
18
|
-
locale: prop_types_1.default.string,
|
|
19
|
-
// Optional list of tables (ids) being used. Use this to present an initially short list to select from
|
|
20
|
-
activeTables: prop_types_1.default.arrayOf(prop_types_1.default.string.isRequired)
|
|
19
|
+
locale: prop_types_1.default.string, // e.g. "en"
|
|
21
20
|
};
|
|
22
21
|
toggleEdit;
|
|
23
22
|
constructor(props) {
|
|
@@ -119,9 +118,7 @@ exports.default = MWaterTableSelectComponent;
|
|
|
119
118
|
// Is the table select component when in edit mode. Toggles between complete list and simplified list
|
|
120
119
|
class EditModeTableSelectComponent extends react_1.default.Component {
|
|
121
120
|
static contextTypes = {
|
|
122
|
-
locale: prop_types_1.default.string,
|
|
123
|
-
// Optional list of tables (ids) being used. Use this to present an initially short list to select from
|
|
124
|
-
activeTables: prop_types_1.default.arrayOf(prop_types_1.default.string.isRequired)
|
|
121
|
+
locale: prop_types_1.default.string, // e.g. "en"
|
|
125
122
|
};
|
|
126
123
|
constructor(props) {
|
|
127
124
|
super(props);
|
|
@@ -136,8 +133,8 @@ class EditModeTableSelectComponent extends react_1.default.Component {
|
|
|
136
133
|
// Get list of tables that should be included in shortlist
|
|
137
134
|
// This is all active tables and all responses tables in schema (so as to include rosters) and all extra tables
|
|
138
135
|
// Also includes current table
|
|
139
|
-
getTableShortlist() {
|
|
140
|
-
let tables =
|
|
136
|
+
getTableShortlist(activeTables) {
|
|
137
|
+
let tables = activeTables;
|
|
141
138
|
// Remove dead tables
|
|
142
139
|
tables = tables.filter((t) => this.props.schema.getTable(t) != null && !this.props.schema.getTable(t).deprecated);
|
|
143
140
|
tables = lodash_1.default.union(tables, lodash_1.default.filter(lodash_1.default.pluck(this.props.schema.getTables(), "id"), (t) => t.match(/^responses:/)));
|
|
@@ -169,38 +166,20 @@ class EditModeTableSelectComponent extends react_1.default.Component {
|
|
|
169
166
|
return this.props.onChange(tableId);
|
|
170
167
|
};
|
|
171
168
|
render() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
apiUrl: this.props.apiUrl,
|
|
188
|
-
client: this.props.client,
|
|
189
|
-
schema: this.props.schema,
|
|
190
|
-
user: this.props.user,
|
|
191
|
-
table: this.props.table,
|
|
192
|
-
onChange: this.handleCompleteChange,
|
|
193
|
-
extraTables: this.props.extraTables,
|
|
194
|
-
onExtraTablesChange: this.props.onExtraTablesChange
|
|
195
|
-
}))
|
|
196
|
-
: undefined, items.length > 0
|
|
197
|
-
? [
|
|
198
|
-
R("div", { className: "text-muted" }, "Select Data Source:"),
|
|
199
|
-
R(UIComponents_1.OptionListComponent, { items }),
|
|
200
|
-
R("div", null, items.length > 0
|
|
201
|
-
? R("button", { type: "button", className: "btn btn-link btn-sm", onClick: this.handleShowMore }, "Show All Available Data Sources...")
|
|
202
|
-
: undefined)
|
|
203
|
-
]
|
|
204
|
-
: R("button", { type: "button", className: "btn btn-link", onClick: this.handleShowMore }, "Select Data Source..."));
|
|
169
|
+
return (react_1.default.createElement(expressions_ui_1.ActiveTablesContext.Consumer, null, activeTables => (react_1.default.createElement("div", null,
|
|
170
|
+
this.state.completeMode ? (react_1.default.createElement(ModalPopupComponent_1.default, { header: "Select Data Source", onClose: () => this.setState({ completeMode: false }), showCloseX: true, size: "x-large" },
|
|
171
|
+
react_1.default.createElement(MWaterCompleteTableSelectComponent_1.default, { apiUrl: this.props.apiUrl, client: this.props.client, schema: this.props.schema, user: this.props.user, table: this.props.table, onChange: this.handleCompleteChange, extraTables: this.props.extraTables, onExtraTablesChange: this.props.onExtraTablesChange }))) : null,
|
|
172
|
+
this.getTableShortlist(activeTables).length > 0 ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
173
|
+
react_1.default.createElement("div", { className: "text-muted" }, "Select Data Source:"),
|
|
174
|
+
react_1.default.createElement(UIComponents_1.OptionListComponent, { items: this.getTableShortlist(activeTables).map((tableId) => {
|
|
175
|
+
const table = this.props.schema.getTable(tableId);
|
|
176
|
+
return {
|
|
177
|
+
name: expressions_1.ExprUtils.localizeString(table.name, this.context.locale),
|
|
178
|
+
desc: expressions_1.ExprUtils.localizeString(table.desc, this.context.locale),
|
|
179
|
+
onClick: () => this.props.onChange(table.id)
|
|
180
|
+
};
|
|
181
|
+
}) }),
|
|
182
|
+
react_1.default.createElement("div", null,
|
|
183
|
+
react_1.default.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: this.handleShowMore }, "Show All Available Data Sources...")))) : (react_1.default.createElement("button", { type: "button", className: "btn btn-link", onClick: this.handleShowMore }, "Select Data Source..."))))));
|
|
205
184
|
}
|
|
206
185
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { AxisXform } from "./Axis";
|
|
2
|
+
import { AxisXform, AxisXformRange } from "./Axis";
|
|
3
3
|
import { Expr, Schema } from "@mwater/expressions";
|
|
4
4
|
export interface RangesComponentProps {
|
|
5
5
|
schema: Schema;
|
|
@@ -18,9 +18,9 @@ export default class RangesComponent extends React.Component<RangesComponentProp
|
|
|
18
18
|
}
|
|
19
19
|
interface RangeComponentProps {
|
|
20
20
|
/** Range to edit */
|
|
21
|
-
range:
|
|
22
|
-
onChange:
|
|
23
|
-
onRemove:
|
|
21
|
+
range: AxisXformRange;
|
|
22
|
+
onChange: (range: AxisXformRange) => void;
|
|
23
|
+
onRemove: () => void;
|
|
24
24
|
/** reorderable connector */
|
|
25
25
|
connectDragSource: any;
|
|
26
26
|
/** reorderable connector */
|
|
@@ -28,8 +28,14 @@ interface RangeComponentProps {
|
|
|
28
28
|
connectDropTarget: any;
|
|
29
29
|
}
|
|
30
30
|
declare class RangeComponent extends React.Component<RangeComponentProps> {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Handles change in minimum open value
|
|
33
|
+
*/
|
|
34
|
+
handleMinOpenChange: (minOpen: boolean) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Handles change in maximum open value
|
|
37
|
+
*/
|
|
38
|
+
handleMaxOpenChange: (maxOpen: boolean) => void;
|
|
33
39
|
render(): any;
|
|
34
40
|
}
|
|
35
41
|
export {};
|
|
@@ -10,6 +10,7 @@ const update_object_1 = __importDefault(require("update-object"));
|
|
|
10
10
|
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
11
11
|
const NumberInputComponent_1 = __importDefault(require("@mwater/react-library/lib/NumberInputComponent"));
|
|
12
12
|
const ReorderableListComponent_1 = __importDefault(require("@mwater/react-library/lib/reorderable/ReorderableListComponent"));
|
|
13
|
+
const immer_1 = __importDefault(require("immer"));
|
|
13
14
|
// Allows setting of ranges
|
|
14
15
|
class RangesComponent extends react_1.default.Component {
|
|
15
16
|
handleRangeChange = (index, range) => {
|
|
@@ -59,11 +60,21 @@ class RangesComponent extends react_1.default.Component {
|
|
|
59
60
|
exports.default = RangesComponent;
|
|
60
61
|
// Single range (row)
|
|
61
62
|
class RangeComponent extends react_1.default.Component {
|
|
63
|
+
/**
|
|
64
|
+
* Handles change in minimum open value
|
|
65
|
+
*/
|
|
62
66
|
handleMinOpenChange = (minOpen) => {
|
|
63
|
-
return this.props.onChange((0,
|
|
67
|
+
return this.props.onChange((0, immer_1.default)(this.props.range, draft => {
|
|
68
|
+
draft.minOpen = minOpen;
|
|
69
|
+
}));
|
|
64
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Handles change in maximum open value
|
|
73
|
+
*/
|
|
65
74
|
handleMaxOpenChange = (maxOpen) => {
|
|
66
|
-
return this.props.onChange((0,
|
|
75
|
+
return this.props.onChange((0, immer_1.default)(this.props.range, draft => {
|
|
76
|
+
draft.maxOpen = maxOpen;
|
|
77
|
+
}));
|
|
67
78
|
};
|
|
68
79
|
render() {
|
|
69
80
|
let placeholder = "";
|
|
@@ -88,23 +99,23 @@ class RangeComponent extends react_1.default.Component {
|
|
|
88
99
|
}
|
|
89
100
|
return this.props.connectDragPreview(this.props.connectDropTarget(R("tr", null, R("td", null, this.props.connectDragSource(R("span", { className: "fa fa-bars" }))), R("td", { key: "minOpen" }, R(expressions_ui_1.LinkComponent, {
|
|
90
101
|
dropdownItems: [
|
|
91
|
-
{ id: true, name: "greater than" },
|
|
92
|
-
{ id: false, name: "greater than or equal to" }
|
|
102
|
+
{ id: "true", name: "greater than" },
|
|
103
|
+
{ id: "false", name: "greater than or equal to" }
|
|
93
104
|
],
|
|
94
|
-
onDropdownItemClicked: this.handleMinOpenChange
|
|
105
|
+
onDropdownItemClicked: (id) => this.handleMinOpenChange(id === "true")
|
|
95
106
|
}, this.props.range.minOpen ? "greater than" : "greater than or equal to")), R("td", { key: "minValue" }, R(NumberInputComponent_1.default, {
|
|
96
|
-
value: this.props.range.minValue,
|
|
107
|
+
value: this.props.range.minValue ?? undefined,
|
|
97
108
|
placeholder: "None",
|
|
98
109
|
small: true,
|
|
99
110
|
onChange: (v) => this.props.onChange((0, update_object_1.default)(this.props.range, { minValue: { $set: v } }))
|
|
100
111
|
})), R("td", { key: "and" }, "\u00A0and\u00A0"), R("td", { key: "maxOpen" }, R(expressions_ui_1.LinkComponent, {
|
|
101
112
|
dropdownItems: [
|
|
102
|
-
{ id: true, name: "less than" },
|
|
103
|
-
{ id: false, name: "less than or equal to" }
|
|
113
|
+
{ id: "true", name: "less than" },
|
|
114
|
+
{ id: "false", name: "less than or equal to" }
|
|
104
115
|
],
|
|
105
|
-
onDropdownItemClicked: this.handleMaxOpenChange
|
|
116
|
+
onDropdownItemClicked: (id) => this.handleMaxOpenChange(id === "true")
|
|
106
117
|
}, this.props.range.maxOpen ? "less than" : "less than or equal to")), R("td", { key: "maxValue" }, R(NumberInputComponent_1.default, {
|
|
107
|
-
value: this.props.range.maxValue,
|
|
118
|
+
value: this.props.range.maxValue ?? undefined,
|
|
108
119
|
placeholder: "None",
|
|
109
120
|
small: true,
|
|
110
121
|
onChange: (v) => this.props.onChange((0, update_object_1.default)(this.props.range, { maxValue: { $set: v } }))
|
|
@@ -57,12 +57,10 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
57
57
|
};
|
|
58
58
|
static childContextTypes: {
|
|
59
59
|
locale: PropTypes.Requireable<string>;
|
|
60
|
-
activeTables: PropTypes.Requireable<string[]>;
|
|
61
60
|
};
|
|
62
61
|
settings: SettingsModalComponent | null;
|
|
63
62
|
getChildContext(): {
|
|
64
63
|
locale: string | undefined;
|
|
65
|
-
activeTables: string[];
|
|
66
64
|
};
|
|
67
65
|
constructor(props: any);
|
|
68
66
|
getQuickfilterValues: () => any[];
|
|
@@ -105,11 +103,5 @@ export default class DashboardComponent extends React.Component<DashboardCompone
|
|
|
105
103
|
}, HTMLElement>;
|
|
106
104
|
renderQuickfilter(): React.CElement<import("../quickfilter/QuickfiltersComponent").QuickfiltersComponentProps, QuickfiltersComponent>;
|
|
107
105
|
refDashboardView: (el: any) => any;
|
|
108
|
-
render(): React.
|
|
109
|
-
style: {
|
|
110
|
-
display: "grid";
|
|
111
|
-
gridTemplateRows: string;
|
|
112
|
-
height: string;
|
|
113
|
-
};
|
|
114
|
-
}, HTMLElement>;
|
|
106
|
+
render(): React.JSX.Element;
|
|
115
107
|
}
|
|
@@ -41,6 +41,7 @@ const DashboardUpgrader_1 = __importDefault(require("./DashboardUpgrader"));
|
|
|
41
41
|
const LayoutOptionsComponent_1 = require("./LayoutOptionsComponent");
|
|
42
42
|
const ModalWindowComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalWindowComponent"));
|
|
43
43
|
const layoutOptions_1 = require("./layoutOptions");
|
|
44
|
+
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
44
45
|
/** Dashboard component that includes an action bar at the top
|
|
45
46
|
* Manages undo stack and quickfilter value
|
|
46
47
|
*/
|
|
@@ -49,15 +50,12 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
49
50
|
static defaultProps = { printScaling: true };
|
|
50
51
|
static childContextTypes = {
|
|
51
52
|
locale: prop_types_1.default.string,
|
|
52
|
-
activeTables: prop_types_1.default.arrayOf(prop_types_1.default.string.isRequired)
|
|
53
53
|
};
|
|
54
54
|
settings;
|
|
55
55
|
getChildContext() {
|
|
56
56
|
return {
|
|
57
57
|
// Pass locale down. Both here and DashboardViewComponent to ensure that quickfilters also get context
|
|
58
58
|
locale: this.props.design.locale,
|
|
59
|
-
// Pass active tables down to table select components so they can present a shorter list
|
|
60
|
-
activeTables: DashboardUtils.getFilterableTables(this.props.design, this.props.schema)
|
|
61
59
|
};
|
|
62
60
|
}
|
|
63
61
|
constructor(props) {
|
|
@@ -268,30 +266,21 @@ class DashboardComponent extends react_1.default.Component {
|
|
|
268
266
|
namedStrings: this.props.namedStrings,
|
|
269
267
|
hideScopes: this.state.hideQuickfilters
|
|
270
268
|
});
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
dataSource: this.props.dataSource,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
: undefined, this.state.layoutOptionsOpen
|
|
287
|
-
? R(ModalWindowComponent_1.default, { isOpen: true, outerPadding: 10, innerPadding: 10 }, R(LayoutOptionsComponent_1.LayoutOptionsComponent, {
|
|
288
|
-
design: this.props.design,
|
|
289
|
-
onDesignChange: this.props.onDesignChange,
|
|
290
|
-
onClose: () => this.setState({ layoutOptionsOpen: false }),
|
|
291
|
-
dashboardView: readonlyDashboardView,
|
|
292
|
-
quickfiltersView: this.renderQuickfilter()
|
|
293
|
-
}))
|
|
294
|
-
: undefined);
|
|
269
|
+
// Pass active tables down to table select components so they can present a shorter list
|
|
270
|
+
return react_1.default.createElement(expressions_ui_1.ActiveTablesContext.Provider, { value: DashboardUtils.getFilterableTables(this.props.design, this.props.schema) },
|
|
271
|
+
react_1.default.createElement("div", { style: {
|
|
272
|
+
display: "grid",
|
|
273
|
+
gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
|
|
274
|
+
height: "100%"
|
|
275
|
+
} },
|
|
276
|
+
!this.props.hideTitleBar ? this.renderTitleBar() : undefined,
|
|
277
|
+
react_1.default.createElement("div", null, !this.state.hideQuickfilters ? this.renderQuickfilter() : undefined),
|
|
278
|
+
dashboardView,
|
|
279
|
+
this.props.onDesignChange != null && (react_1.default.createElement(SettingsModalComponent_1.default, { onDesignChange: this.handleDesignChange, schema: this.props.schema, dataSource: this.props.dataSource, ref: (c) => {
|
|
280
|
+
this.settings = c;
|
|
281
|
+
} })),
|
|
282
|
+
this.state.layoutOptionsOpen && (react_1.default.createElement(ModalWindowComponent_1.default, { isOpen: true, outerPadding: 10, innerPadding: 10 },
|
|
283
|
+
react_1.default.createElement(LayoutOptionsComponent_1.LayoutOptionsComponent, { design: this.props.design, onDesignChange: this.props.onDesignChange, onClose: () => this.setState({ layoutOptionsOpen: false }), dashboardView: readonlyDashboardView, quickfiltersView: this.renderQuickfilter() })))));
|
|
295
284
|
}
|
|
296
285
|
}
|
|
297
286
|
exports.default = DashboardComponent;
|
|
@@ -56,6 +56,7 @@ declare class ServerWidgetMapDataSource implements MapDataSource {
|
|
|
56
56
|
e: number;
|
|
57
57
|
s: number;
|
|
58
58
|
} | null) => void): void;
|
|
59
|
+
getQuickfiltersDataSource(): QuickfiltersDataSource;
|
|
59
60
|
}
|
|
60
61
|
interface ServerWidgetLayerDataSourceOptions extends ServerDashboardDataSourceOptions {
|
|
61
62
|
widgetId: string;
|
|
@@ -184,6 +184,9 @@ class ServerWidgetMapDataSource {
|
|
|
184
184
|
return callback(new Error(xhr.responseText));
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
|
+
getQuickfiltersDataSource() {
|
|
188
|
+
return new ServerQuickfilterDataSource(this.options);
|
|
189
|
+
}
|
|
187
190
|
}
|
|
188
191
|
class ServerWidgetLayerDataSource {
|
|
189
192
|
options;
|
|
@@ -30,7 +30,7 @@ export interface DatagridComponentProps {
|
|
|
30
30
|
quickfilterLocks?: any[];
|
|
31
31
|
filters?: JsonQLFilter[];
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
interface DatagridComponentState {
|
|
34
34
|
/** is design being edited */
|
|
35
35
|
editingDesign: boolean;
|
|
36
36
|
/** True if cells can be edited directly */
|
|
@@ -39,14 +39,18 @@ export default class DatagridComponent extends React.Component<DatagridComponent
|
|
|
39
39
|
quickfiltersHeight: number | null;
|
|
40
40
|
quickfiltersValues: null | any[];
|
|
41
41
|
refreshKey: number;
|
|
42
|
-
|
|
42
|
+
/** Number of rows */
|
|
43
|
+
numRows?: number;
|
|
44
|
+
}
|
|
45
|
+
export default class DatagridComponent extends React.Component<DatagridComponentProps, DatagridComponentState> {
|
|
43
46
|
datagridView?: DatagridViewComponent | null;
|
|
44
47
|
quickfilters?: HTMLElement | null;
|
|
45
48
|
findReplaceModal: FindReplaceModalComponent | null;
|
|
46
49
|
constructor(props: DatagridComponentProps);
|
|
47
|
-
reload(): void
|
|
50
|
+
reload(): void;
|
|
48
51
|
componentDidMount(): void;
|
|
49
|
-
componentDidUpdate(): void;
|
|
52
|
+
componentDidUpdate(prevProps: DatagridComponentProps, prevState: DatagridComponentState): void;
|
|
53
|
+
loadRowCount(): void;
|
|
50
54
|
handleRefreshData: () => void;
|
|
51
55
|
updateHeight(): void;
|
|
52
56
|
getQuickfilterValues: () => any[];
|