@mwater/visualization 5.4.4 → 5.5.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/.storybook/head.html +0 -1
- package/lib/MWaterContextComponent.js +1 -1
- package/lib/MWaterLoaderComponent.d.ts +2 -2
- package/lib/dashboards/DashboardComponent.js +2 -1
- package/lib/dashboards/LayoutOptionsComponent.js +18 -11
- package/lib/dashboards/ServerDashboardDataSource.d.ts +10 -1
- package/lib/dashboards/ServerDashboardDataSource.js +29 -0
- package/lib/dashboards/layoutOptions.d.ts +5 -1
- package/lib/datagrids/DatagridComponent.js +1 -1
- package/lib/datagrids/ExprCellComponent.d.ts +1 -0
- package/lib/datagrids/ExprCellComponent.js +22 -20
- package/lib/maps/BufferLayer.d.ts +18 -0
- package/lib/maps/BufferLayer.js +24 -14
- package/lib/maps/ChoroplethLayer.d.ts +18 -0
- package/lib/maps/ChoroplethLayer.js +34 -25
- package/lib/maps/ChoroplethLayerDesign.d.ts +3 -2
- package/lib/maps/ChoroplethLayerDesigner.d.ts +11 -1
- package/lib/maps/DirectMapDataSource.js +17 -0
- package/lib/maps/EditHoverOver.d.ts +1 -1
- package/lib/maps/EditHoverOver.js +62 -33
- package/lib/maps/HoverContent.d.ts +10 -5
- package/lib/maps/HoverContent.js +6 -35
- package/lib/maps/Layer.d.ts +37 -0
- package/lib/maps/Layer.js +30 -4
- package/lib/maps/MWaterServerLayer.d.ts +2 -2
- package/lib/maps/MWaterServerLayer.js +6 -6
- package/lib/maps/MapLayerDataSource.d.ts +9 -0
- package/lib/maps/MapUtils.d.ts +19 -1
- package/lib/maps/MapUtils.js +71 -1
- package/lib/maps/MarkersLayer.d.ts +18 -0
- package/lib/maps/MarkersLayer.js +24 -24
- package/lib/maps/MarkersLayerDesignerComponent.d.ts +14 -1
- package/lib/maps/RasterMapViewComponent.js +1 -1
- package/lib/maps/ServerMapDataSource.d.ts +9 -0
- package/lib/maps/ServerMapDataSource.js +29 -0
- package/lib/maps/VectorMapViewComponent.js +6 -6
- package/lib/maps/maps.d.ts +4 -2
- package/lib/mwater_table_selection/FormsListComponent.d.ts +33 -0
- package/lib/mwater_table_selection/FormsListComponent.js +141 -0
- package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +47 -0
- package/lib/mwater_table_selection/IndicatorsListComponent.js +182 -0
- package/lib/mwater_table_selection/IssuesListComponent.d.ts +29 -0
- package/lib/mwater_table_selection/IssuesListComponent.js +123 -0
- package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.d.ts +20 -0
- package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.js +157 -0
- package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.d.ts +17 -0
- package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.js +79 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +37 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +275 -0
- package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.d.ts +17 -0
- package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.js +94 -0
- package/lib/mwater_table_selection/MWaterMetricsTableListComponent.d.ts +17 -0
- package/lib/mwater_table_selection/MWaterMetricsTableListComponent.js +80 -0
- package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +32 -0
- package/lib/mwater_table_selection/MWaterTableSelectComponent.js +158 -0
- package/lib/quickfilter/Quickfilter.d.ts +2 -0
- package/lib/quickfilter/QuickfiltersDesignComponent.js +18 -10
- package/lib/widgets/charts/Chart.d.ts +11 -0
- package/lib/widgets/charts/Chart.js +15 -0
- package/lib/widgets/charts/ChartWidgetComponent.d.ts +1 -0
- package/lib/widgets/charts/ChartWidgetComponent.js +27 -1
- package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +1 -1
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +1 -1
- package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +5 -12
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +43 -57
- package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +113 -110
- package/lib/widgets/charts/layered/LayeredChartUtils.d.ts +2 -1
- package/lib/widgets/charts/layered/LayeredChartUtils.js +0 -2
- package/lib/widgets/charts/pivot/PivotChart.d.ts +2 -0
- package/lib/widgets/charts/pivot/PivotChart.js +156 -0
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +5 -20
- package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +31 -61
- package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +4 -0
- package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +4 -2
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.d.ts +5 -44
- package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +38 -63
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +7 -68
- package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +58 -106
- package/lib/widgets/charts/table/TableChart.d.ts +2 -0
- package/lib/widgets/charts/table/TableChart.js +172 -1
- package/lib/widgets/charts/table/TableChartDesignerComponent.d.ts +7 -17
- package/lib/widgets/charts/table/TableChartDesignerComponent.js +79 -95
- package/lib/widgets/charts/table/TableChartViewComponent.d.ts +1 -7
- package/lib/widgets/charts/table/TableChartViewComponent.js +19 -27
- package/package.json +3 -8
- package/src/MWaterContextComponent.tsx +1 -1
- package/src/MWaterLoaderComponent.ts +1 -1
- package/src/dashboards/DashboardComponent.tsx +2 -1
- package/src/dashboards/LayoutOptionsComponent.tsx +22 -10
- package/src/dashboards/ServerDashboardDataSource.ts +36 -1
- package/src/dashboards/layoutOptions.tsx +5 -1
- package/src/datagrids/DatagridComponent.tsx +1 -1
- package/src/datagrids/ExprCellComponent.tsx +23 -20
- package/src/maps/BufferLayer.ts +35 -20
- package/src/maps/ChoroplethLayer.ts +51 -33
- package/src/maps/ChoroplethLayerDesign.ts +3 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +2 -2
- package/src/maps/DirectMapDataSource.ts +21 -1
- package/src/maps/EditHoverOver.tsx +91 -51
- package/src/maps/HoverContent.tsx +16 -47
- package/src/maps/Layer.ts +42 -4
- package/src/maps/MWaterServerLayer.ts +6 -6
- package/src/maps/MapLayerDataSource.ts +8 -0
- package/src/maps/MapUtils.ts +70 -3
- package/src/maps/MarkersLayer.ts +34 -24
- package/src/maps/RasterMapViewComponent.ts +1 -1
- package/src/maps/ServerMapDataSource.ts +35 -0
- package/src/maps/VectorMapViewComponent.tsx +6 -6
- package/src/maps/maps.ts +4 -2
- package/src/mwater_table_selection/FormsListComponent.tsx +188 -0
- package/src/mwater_table_selection/IndicatorsListComponent.tsx +283 -0
- package/src/mwater_table_selection/IssuesListComponent.tsx +167 -0
- package/src/mwater_table_selection/MWaterAccountingSystemListComponent.tsx +225 -0
- package/src/{MWaterAssetSystemsListComponent.tsx → mwater_table_selection/MWaterAssetSystemsListComponent.tsx} +2 -2
- package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +377 -0
- package/src/{MWaterCustomTablesetListComponent.tsx → mwater_table_selection/MWaterCustomTablesetListComponent.tsx} +1 -1
- package/src/{MWaterMetricsTableListComponent.tsx → mwater_table_selection/MWaterMetricsTableListComponent.tsx} +1 -1
- package/src/{MWaterTableSelectComponent.tsx → mwater_table_selection/MWaterTableSelectComponent.tsx} +83 -86
- package/src/quickfilter/Quickfilter.ts +3 -0
- package/src/quickfilter/QuickfiltersDesignComponent.tsx +19 -14
- package/src/widgets/charts/Chart.ts +17 -0
- package/src/widgets/charts/ChartWidgetComponent.tsx +36 -1
- package/src/widgets/charts/layered/LayeredChartDesign.ts +1 -1
- package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +23 -24
- package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +260 -211
- package/src/widgets/charts/layered/LayeredChartUtils.ts +7 -7
- package/src/widgets/charts/pivot/PivotChart.ts +191 -0
- package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +124 -129
- package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +4 -2
- package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +120 -149
- package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +178 -198
- package/src/widgets/charts/table/TableChart.ts +177 -1
- package/src/widgets/charts/table/TableChartDesignerComponent.tsx +422 -0
- package/src/widgets/charts/table/{TableChartViewComponent.ts → TableChartViewComponent.tsx} +65 -60
- package/src/MWaterCompleteTableSelectComponent.tsx +0 -975
- package/src/widgets/charts/table/TableChartDesignerComponent.ts +0 -441
|
@@ -182,6 +182,35 @@ class ServerLayerDataSource {
|
|
|
182
182
|
}
|
|
183
183
|
return url;
|
|
184
184
|
}
|
|
185
|
+
/** Gets hover over data for hover over items
|
|
186
|
+
* @param design The design of the layer
|
|
187
|
+
* @param data The data of the current item being hovered over. e.g. { id: 123 }
|
|
188
|
+
* @param filters The filters to apply to the layer does not include filters that narrow down to a specific item
|
|
189
|
+
* @returns A promise that resolves to the hover over data, indexed by the id of the hover over item
|
|
190
|
+
*/
|
|
191
|
+
async getHoverOverData(design, data, filters) {
|
|
192
|
+
const query = {
|
|
193
|
+
client: this.options.client,
|
|
194
|
+
share: this.options.share,
|
|
195
|
+
filters: (0, compressJson_1.default)(filters || []),
|
|
196
|
+
data: (0, compressJson_1.default)(data),
|
|
197
|
+
rev: this.options.rev
|
|
198
|
+
};
|
|
199
|
+
const url = `${this.options.apiUrl}maps/${this.options.mapId}/layers/${this.options.layerView.id}/hoverdata?` +
|
|
200
|
+
querystring_1.default.stringify(query);
|
|
201
|
+
const response = await fetch(url, {
|
|
202
|
+
method: "GET",
|
|
203
|
+
headers: {
|
|
204
|
+
Accept: "application/json"
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
if (!response.ok) {
|
|
208
|
+
const errorText = await response.text();
|
|
209
|
+
console.error(errorText);
|
|
210
|
+
throw new Error(`Error fetching hover data: ${response.statusText}`);
|
|
211
|
+
}
|
|
212
|
+
return await response.json();
|
|
213
|
+
}
|
|
185
214
|
}
|
|
186
215
|
class ServerMapLayerPopupWidgetDataSource {
|
|
187
216
|
options;
|
|
@@ -66,7 +66,7 @@ function VectorMapViewComponent(props) {
|
|
|
66
66
|
const [legendHidden, setLegendHidden] = (0, react_1.useState)(initialLegendDisplay == "closed" || (props.width < 500 && initialLegendDisplay == "closedIfSmall"));
|
|
67
67
|
// Locale to use
|
|
68
68
|
const locale = props.locale || props.design.locale || "en";
|
|
69
|
-
// Translate function to use
|
|
69
|
+
// Translate function to use
|
|
70
70
|
const translate = props.translate || ((input) => input);
|
|
71
71
|
// Last feature that mouse entered
|
|
72
72
|
const lastFeature = (0, react_2.useRef)();
|
|
@@ -424,12 +424,12 @@ function VectorMapViewComponent(props) {
|
|
|
424
424
|
return;
|
|
425
425
|
}
|
|
426
426
|
if (!props.design.autoBounds && props.design.bounds) {
|
|
427
|
-
// If we set the new bounds, do not update map bounds
|
|
427
|
+
// If we set the new bounds, do not update map bounds unless they differ by more than 0.0001 degrees (roughly 10m)
|
|
428
428
|
if (boundsRef.current == null ||
|
|
429
|
-
props.design.bounds.n
|
|
430
|
-
props.design.bounds.e
|
|
431
|
-
props.design.bounds.s
|
|
432
|
-
props.design.bounds.w
|
|
429
|
+
Math.abs(props.design.bounds.n - boundsRef.current.n) > 0.0001 ||
|
|
430
|
+
Math.abs(props.design.bounds.e - boundsRef.current.e) > 0.0001 ||
|
|
431
|
+
Math.abs(props.design.bounds.s - boundsRef.current.s) > 0.0001 ||
|
|
432
|
+
Math.abs(props.design.bounds.w - boundsRef.current.w) > 0.0001) {
|
|
433
433
|
map.fitBounds([props.design.bounds.w, props.design.bounds.s, props.design.bounds.e, props.design.bounds.n]);
|
|
434
434
|
boundsRef.current = props.design.bounds;
|
|
435
435
|
}
|
package/lib/maps/maps.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { JsonQLQuery } from "@mwater/jsonql";
|
|
2
2
|
import { Expr } from "@mwater/expressions";
|
|
3
|
+
import { ReactNode } from "react";
|
|
3
4
|
export interface LayerDefinition {
|
|
4
5
|
layers: Array<{
|
|
5
6
|
/** Layer id */
|
|
@@ -16,6 +17,7 @@ export interface LayerDefinition {
|
|
|
16
17
|
fields: string[];
|
|
17
18
|
};
|
|
18
19
|
}
|
|
20
|
+
/** Results from onGridClick that can be used to display a popup */
|
|
19
21
|
export type OnGridClickResults = {
|
|
20
22
|
scope?: any;
|
|
21
23
|
row?: {
|
|
@@ -24,9 +26,9 @@ export type OnGridClickResults = {
|
|
|
24
26
|
};
|
|
25
27
|
popup?: React.ReactElement<{}>;
|
|
26
28
|
} | null;
|
|
29
|
+
/** Results from onGridHover that can be used to display a hover over */
|
|
27
30
|
export type OnGridHoverResults = {
|
|
28
|
-
|
|
29
|
-
hoverOver?: React.ReactElement<{}>;
|
|
31
|
+
hoverOver?: ReactNode;
|
|
30
32
|
} | null;
|
|
31
33
|
/** Item in hover over */
|
|
32
34
|
export interface HoverOverItem {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Schema } from "@mwater/expressions";
|
|
3
|
+
interface FormsListComponentProps {
|
|
4
|
+
/** Url to hit api */
|
|
5
|
+
apiUrl: string;
|
|
6
|
+
/** Optional client */
|
|
7
|
+
client?: string;
|
|
8
|
+
schema: Schema;
|
|
9
|
+
/** User id */
|
|
10
|
+
user?: string;
|
|
11
|
+
/** Called with table selected */
|
|
12
|
+
onChange: any;
|
|
13
|
+
extraTables: any;
|
|
14
|
+
onExtraTableAdd: any;
|
|
15
|
+
onExtraTableRemove: any;
|
|
16
|
+
}
|
|
17
|
+
interface FormsListComponentState {
|
|
18
|
+
error?: any;
|
|
19
|
+
search: any;
|
|
20
|
+
forms: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
desc?: string;
|
|
24
|
+
}[] | null;
|
|
25
|
+
}
|
|
26
|
+
export declare class FormsListComponent extends React.Component<FormsListComponentProps, FormsListComponentState> {
|
|
27
|
+
constructor(props: any);
|
|
28
|
+
componentDidMount(): void;
|
|
29
|
+
handleTableRemove: (table: any) => any;
|
|
30
|
+
searchRef: (comp: any) => any;
|
|
31
|
+
render(): React.JSX.Element;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,141 @@
|
|
|
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.FormsListComponent = void 0;
|
|
30
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
31
|
+
const jquery_1 = __importDefault(require("jquery"));
|
|
32
|
+
const react_1 = __importDefault(require("react"));
|
|
33
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
34
|
+
const uiComponents = __importStar(require("../UIComponents"));
|
|
35
|
+
const expressions_1 = require("@mwater/expressions");
|
|
36
|
+
const moment_1 = __importDefault(require("moment"));
|
|
37
|
+
// Searchable list of forms
|
|
38
|
+
class FormsListComponent extends react_1.default.Component {
|
|
39
|
+
constructor(props) {
|
|
40
|
+
super(props);
|
|
41
|
+
this.state = {
|
|
42
|
+
forms: null,
|
|
43
|
+
search: ""
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
componentDidMount() {
|
|
47
|
+
// Get names and basic of forms
|
|
48
|
+
const query = {};
|
|
49
|
+
query.fields = JSON.stringify({
|
|
50
|
+
"design.name": 1,
|
|
51
|
+
"design.description": 1,
|
|
52
|
+
roles: 1,
|
|
53
|
+
created: 1,
|
|
54
|
+
modified: 1,
|
|
55
|
+
state: 1,
|
|
56
|
+
isMaster: 1
|
|
57
|
+
});
|
|
58
|
+
query.selector = JSON.stringify({ design: { $exists: true }, state: { $ne: "deleted" } });
|
|
59
|
+
query.client = this.props.client;
|
|
60
|
+
// Get list of all form names
|
|
61
|
+
jquery_1.default.getJSON(this.props.apiUrl + "forms?" + querystring_1.default.stringify(query), (forms) => {
|
|
62
|
+
// Sort by modified.on desc but first by user
|
|
63
|
+
forms = lodash_1.default.sortByOrder(forms, [
|
|
64
|
+
(form) => ((this.props.extraTables || []).includes("responses:" + form._id) ? 1 : 0),
|
|
65
|
+
(form) => (form.created.by === this.props.user ? 1 : 0),
|
|
66
|
+
(form) => form.modified?.on
|
|
67
|
+
], ["desc", "desc", "desc"]);
|
|
68
|
+
// TODO use name instead of design.name
|
|
69
|
+
this.setState({
|
|
70
|
+
forms: lodash_1.default.map(forms, (form) => {
|
|
71
|
+
let desc = expressions_1.ExprUtils.localizeString(form.design.description, null) || "";
|
|
72
|
+
if (desc) {
|
|
73
|
+
desc += " - ";
|
|
74
|
+
}
|
|
75
|
+
desc += T `Modified ${(0, moment_1.default)(form.modified?.on, moment_1.default.ISO_8601).format("ll")}`;
|
|
76
|
+
return {
|
|
77
|
+
id: form._id,
|
|
78
|
+
name: expressions_1.ExprUtils.localizeString(form.design.name, null),
|
|
79
|
+
desc
|
|
80
|
+
};
|
|
81
|
+
})
|
|
82
|
+
});
|
|
83
|
+
}).fail((xhr) => {
|
|
84
|
+
this.setState({ error: xhr.responseText });
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
handleTableRemove = (table) => {
|
|
88
|
+
if (confirm(T `Remove ${expressions_1.ExprUtils.localizeString(table.name, T.locale)}? Any widgets that depend on it will no longer work properly.`)) {
|
|
89
|
+
return this.props.onExtraTableRemove(table.id);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
searchRef = (comp) => {
|
|
93
|
+
// Focus
|
|
94
|
+
if (comp) {
|
|
95
|
+
return comp.focus();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
render() {
|
|
99
|
+
let forms;
|
|
100
|
+
if (this.state.error) {
|
|
101
|
+
return react_1.default.createElement("div", { className: "alert alert-danger" }, this.state.error);
|
|
102
|
+
}
|
|
103
|
+
// Filter forms
|
|
104
|
+
if (this.state.search) {
|
|
105
|
+
const escapeRegExp = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
106
|
+
const searchStringRegExp = new RegExp(escapeRegExp(this.state.search), "i");
|
|
107
|
+
forms = lodash_1.default.filter(this.state.forms, (form) => form.name.match(searchStringRegExp));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
;
|
|
111
|
+
({ forms } = this.state);
|
|
112
|
+
}
|
|
113
|
+
// Remove if already included
|
|
114
|
+
forms = lodash_1.default.filter(forms || [], (f) => !(this.props.extraTables || []).includes(`responses:${f.id}`));
|
|
115
|
+
let tables = lodash_1.default.filter(this.props.schema.getTables(), (table) => (table.id.match(/^responses:/) || table.id.match(/^master_responses:/)) && !table.deprecated);
|
|
116
|
+
tables = lodash_1.default.sortBy(tables, (t) => t.name.en);
|
|
117
|
+
return (react_1.default.createElement("div", null,
|
|
118
|
+
react_1.default.createElement("label", null, T `Included Surveys:`),
|
|
119
|
+
tables.length > 0 ? (react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(tables, (table) => {
|
|
120
|
+
return {
|
|
121
|
+
name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
|
|
122
|
+
desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
|
|
123
|
+
onClick: this.props.onChange.bind(null, table.id),
|
|
124
|
+
onRemove: this.handleTableRemove.bind(null, table)
|
|
125
|
+
};
|
|
126
|
+
}) })) : (react_1.default.createElement("div", null, T `None`)),
|
|
127
|
+
react_1.default.createElement("br", null),
|
|
128
|
+
react_1.default.createElement("label", null, T `All Surveys:`),
|
|
129
|
+
!this.state.forms || this.state.forms.length === 0 ? (react_1.default.createElement("div", { className: "alert alert-info" },
|
|
130
|
+
react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
|
|
131
|
+
"\u00A0",
|
|
132
|
+
T `Loading...`)) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
133
|
+
react_1.default.createElement("input", { type: "text", className: "form-control form-control-sm", placeholder: T `Search...`, key: "search", ref: this.searchRef, style: { maxWidth: "20em", marginBottom: 10 }, value: this.state.search, onChange: (ev) => this.setState({ search: ev.target.value }) }),
|
|
134
|
+
react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(forms, (form) => ({
|
|
135
|
+
name: form.name,
|
|
136
|
+
desc: form.desc,
|
|
137
|
+
onClick: this.props.onChange.bind(null, "responses:" + form.id)
|
|
138
|
+
})) })))));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.FormsListComponent = FormsListComponent;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Schema } from "@mwater/expressions";
|
|
3
|
+
interface IndicatorsListComponentProps {
|
|
4
|
+
/** Url to hit api */
|
|
5
|
+
apiUrl: string;
|
|
6
|
+
/** Optional client */
|
|
7
|
+
client?: string;
|
|
8
|
+
schema: Schema;
|
|
9
|
+
/** User id */
|
|
10
|
+
user?: string;
|
|
11
|
+
/** Called with table selected */
|
|
12
|
+
onChange: any;
|
|
13
|
+
extraTables: any;
|
|
14
|
+
onExtraTableAdd: any;
|
|
15
|
+
onExtraTableRemove: any;
|
|
16
|
+
}
|
|
17
|
+
interface IndicatorsListComponentState {
|
|
18
|
+
error?: any;
|
|
19
|
+
search: any;
|
|
20
|
+
indicators: any[] | null;
|
|
21
|
+
}
|
|
22
|
+
export declare class IndicatorsListComponent extends React.Component<IndicatorsListComponentProps, IndicatorsListComponentState> {
|
|
23
|
+
addIndicatorConfirmPopup: AddIndicatorConfirmPopupComponent | null;
|
|
24
|
+
constructor(props: any);
|
|
25
|
+
componentDidMount(): JQuery.jqXHR<any>;
|
|
26
|
+
handleTableRemove: (table: any) => any;
|
|
27
|
+
searchRef: (comp: any) => any;
|
|
28
|
+
handleSelect: (tableId: any) => void;
|
|
29
|
+
render(): React.JSX.Element;
|
|
30
|
+
}
|
|
31
|
+
interface AddIndicatorConfirmPopupComponentProps {
|
|
32
|
+
schema: Schema;
|
|
33
|
+
/** Called with table selected */
|
|
34
|
+
onChange: any;
|
|
35
|
+
onExtraTableAdd: any;
|
|
36
|
+
}
|
|
37
|
+
interface AddIndicatorConfirmPopupComponentState {
|
|
38
|
+
indicatorTable: any;
|
|
39
|
+
visible: any;
|
|
40
|
+
}
|
|
41
|
+
declare class AddIndicatorConfirmPopupComponent extends React.Component<AddIndicatorConfirmPopupComponentProps, AddIndicatorConfirmPopupComponentState> {
|
|
42
|
+
constructor(props: any);
|
|
43
|
+
show(indicatorTable: any): void;
|
|
44
|
+
renderContents(): React.JSX.Element;
|
|
45
|
+
render(): React.JSX.Element | null;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,182 @@
|
|
|
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.IndicatorsListComponent = void 0;
|
|
30
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
31
|
+
const jquery_1 = __importDefault(require("jquery"));
|
|
32
|
+
const react_1 = __importDefault(require("react"));
|
|
33
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
34
|
+
const uiComponents = __importStar(require("../UIComponents"));
|
|
35
|
+
const expressions_1 = require("@mwater/expressions");
|
|
36
|
+
const ModalPopupComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalPopupComponent"));
|
|
37
|
+
// Searchable list of indicators
|
|
38
|
+
class IndicatorsListComponent extends react_1.default.Component {
|
|
39
|
+
addIndicatorConfirmPopup;
|
|
40
|
+
constructor(props) {
|
|
41
|
+
super(props);
|
|
42
|
+
this.state = {
|
|
43
|
+
indicators: null,
|
|
44
|
+
search: ""
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
componentDidMount() {
|
|
48
|
+
// Get names and basic of forms
|
|
49
|
+
const query = {};
|
|
50
|
+
query.fields = JSON.stringify({ "design.name": 1, "design.desc": 1, "design.recommended": 1, deprecated: 1 });
|
|
51
|
+
query.client = this.props.client;
|
|
52
|
+
// Get list of all indicator names
|
|
53
|
+
return jquery_1.default.getJSON(this.props.apiUrl + "indicators?" + querystring_1.default.stringify(query), (indicators) => {
|
|
54
|
+
// Remove deprecated
|
|
55
|
+
indicators = lodash_1.default.filter(indicators, (indicator) => !indicator.deprecated);
|
|
56
|
+
// Sort by name
|
|
57
|
+
indicators = lodash_1.default.sortByOrder(indicators, [
|
|
58
|
+
(indicator) => ((this.props.extraTables || []).includes("indicator_values:" + indicator._id) ? 0 : 1),
|
|
59
|
+
(indicator) => (indicator.design.recommended ? 0 : 1),
|
|
60
|
+
(indicator) => expressions_1.ExprUtils.localizeString(indicator.design.name, T.locale)
|
|
61
|
+
], ["asc", "asc", "asc"]);
|
|
62
|
+
return this.setState({
|
|
63
|
+
indicators: lodash_1.default.map(indicators, (indicator) => ({
|
|
64
|
+
id: indicator._id,
|
|
65
|
+
name: expressions_1.ExprUtils.localizeString(indicator.design.name, T.locale),
|
|
66
|
+
desc: expressions_1.ExprUtils.localizeString(indicator.design.desc, T.locale)
|
|
67
|
+
}))
|
|
68
|
+
});
|
|
69
|
+
}).fail((xhr) => {
|
|
70
|
+
return this.setState({ error: xhr.responseText });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
handleTableRemove = (table) => {
|
|
74
|
+
if (confirm(T `Remove ${expressions_1.ExprUtils.localizeString(table.name, T.locale)}? Any widgets that depend on it will no longer work properly.`)) {
|
|
75
|
+
return this.props.onExtraTableRemove(table.id);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
searchRef = (comp) => {
|
|
79
|
+
// Focus
|
|
80
|
+
if (comp) {
|
|
81
|
+
return comp.focus();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
handleSelect = (tableId) => {
|
|
85
|
+
// Add table if not present
|
|
86
|
+
if (!this.props.schema.getTable(tableId)) {
|
|
87
|
+
this.props.onExtraTableAdd(tableId);
|
|
88
|
+
}
|
|
89
|
+
this.addIndicatorConfirmPopup.show(tableId);
|
|
90
|
+
};
|
|
91
|
+
render() {
|
|
92
|
+
let indicators;
|
|
93
|
+
if (this.state.error) {
|
|
94
|
+
return react_1.default.createElement("div", { className: "alert alert-danger" }, this.state.error);
|
|
95
|
+
}
|
|
96
|
+
// Filter indicators
|
|
97
|
+
if (this.state.search) {
|
|
98
|
+
const escapeRegExp = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
99
|
+
const searchStringRegExp = new RegExp(escapeRegExp(this.state.search), "i");
|
|
100
|
+
indicators = lodash_1.default.filter(this.state.indicators || [], (indicator) => indicator.name.match(searchStringRegExp));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
;
|
|
104
|
+
({ indicators } = this.state);
|
|
105
|
+
}
|
|
106
|
+
// Remove if already included
|
|
107
|
+
indicators = lodash_1.default.filter(indicators || [], (f) => !(this.props.extraTables || []).includes(`indicator_values:${f.id}`));
|
|
108
|
+
let tables = lodash_1.default.filter(this.props.schema.getTables(), (table) => table.id.match(/^indicator_values:/) && !table.deprecated);
|
|
109
|
+
tables = lodash_1.default.sortBy(tables, (t) => t.name.en);
|
|
110
|
+
return (react_1.default.createElement("div", null,
|
|
111
|
+
react_1.default.createElement(AddIndicatorConfirmPopupComponent, { schema: this.props.schema, onChange: this.props.onChange, onExtraTableAdd: this.props.onExtraTableAdd, ref: (c) => {
|
|
112
|
+
this.addIndicatorConfirmPopup = c;
|
|
113
|
+
} }),
|
|
114
|
+
react_1.default.createElement("label", null, T `Included Indicators:`),
|
|
115
|
+
tables.length > 0 ? (react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(tables, (table) => {
|
|
116
|
+
return {
|
|
117
|
+
name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
|
|
118
|
+
desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
|
|
119
|
+
onClick: this.handleSelect.bind(null, table.id),
|
|
120
|
+
onRemove: this.handleTableRemove.bind(null, table)
|
|
121
|
+
};
|
|
122
|
+
}) })) : (react_1.default.createElement("div", null, T `None`)),
|
|
123
|
+
react_1.default.createElement("br", null),
|
|
124
|
+
react_1.default.createElement("label", null, T `All Indicators:`),
|
|
125
|
+
!this.state.indicators || this.state.indicators.length === 0 ? (react_1.default.createElement("div", { className: "alert alert-info" },
|
|
126
|
+
react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
|
|
127
|
+
"\u00A0",
|
|
128
|
+
T `Loading...`)) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
129
|
+
react_1.default.createElement("input", { type: "text", className: "form-control form-control-sm", placeholder: T `Search...`, key: "search", ref: this.searchRef, style: { maxWidth: "20em", marginBottom: 10 }, value: this.state.search, onChange: (ev) => this.setState({ search: ev.target.value }) }),
|
|
130
|
+
react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(indicators, (indicator) => ({
|
|
131
|
+
name: indicator.name,
|
|
132
|
+
desc: indicator.desc,
|
|
133
|
+
onClick: this.handleSelect.bind(null, "indicator_values:" + indicator.id)
|
|
134
|
+
})) })))));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.IndicatorsListComponent = IndicatorsListComponent;
|
|
138
|
+
class AddIndicatorConfirmPopupComponent extends react_1.default.Component {
|
|
139
|
+
constructor(props) {
|
|
140
|
+
super(props);
|
|
141
|
+
this.state = {
|
|
142
|
+
visible: false,
|
|
143
|
+
indicatorTable: null
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
show(indicatorTable) {
|
|
147
|
+
return this.setState({ visible: true, indicatorTable });
|
|
148
|
+
}
|
|
149
|
+
renderContents() {
|
|
150
|
+
// Show loading if table not loaded
|
|
151
|
+
if (!this.props.schema.getTable(this.state.indicatorTable)) {
|
|
152
|
+
return (react_1.default.createElement("div", { className: "alert alert-info" },
|
|
153
|
+
react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
|
|
154
|
+
"\u00A0",
|
|
155
|
+
T `Loading...`));
|
|
156
|
+
}
|
|
157
|
+
// Find entity links
|
|
158
|
+
const entityColumns = lodash_1.default.filter(this.props.schema.getColumns(this.state.indicatorTable), (col) => col.join?.toTable?.match(/^entities\./));
|
|
159
|
+
return (react_1.default.createElement("div", null,
|
|
160
|
+
react_1.default.createElement("p", null, T `In general, it is better to get indicator values from the related site. Please select the site
|
|
161
|
+
below, then find the indicator values in the 'Related Indicators' section. Or click on 'Use Raw Indicator' if you
|
|
162
|
+
are certain that you want to use the raw indicator table`),
|
|
163
|
+
react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(entityColumns, (entityColumn) => ({
|
|
164
|
+
name: expressions_1.ExprUtils.localizeString(entityColumn.name, T.locale),
|
|
165
|
+
desc: expressions_1.ExprUtils.localizeString(entityColumn.desc, T.locale),
|
|
166
|
+
onClick: () => {
|
|
167
|
+
// Select table
|
|
168
|
+
this.props.onChange(entityColumn.join.toTable);
|
|
169
|
+
return this.setState({ visible: false });
|
|
170
|
+
}
|
|
171
|
+
})) }),
|
|
172
|
+
react_1.default.createElement("br", null),
|
|
173
|
+
react_1.default.createElement("div", null,
|
|
174
|
+
react_1.default.createElement("a", { className: "link-plain", onClick: this.props.onChange.bind(null, this.state.indicatorTable) }, T `Use Raw Indicator`))));
|
|
175
|
+
}
|
|
176
|
+
render() {
|
|
177
|
+
if (!this.state.visible) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return (react_1.default.createElement(ModalPopupComponent_1.default, { showCloseX: true, onClose: () => this.setState({ visible: false }), header: T `Add Indicator` }, this.renderContents()));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Schema } from "@mwater/expressions";
|
|
3
|
+
interface IssuesListComponentProps {
|
|
4
|
+
/** Url to hit api */
|
|
5
|
+
apiUrl: string;
|
|
6
|
+
/** Optional client */
|
|
7
|
+
client?: string;
|
|
8
|
+
schema: Schema;
|
|
9
|
+
/** User id */
|
|
10
|
+
user?: string;
|
|
11
|
+
/** Called with table selected */
|
|
12
|
+
onChange: any;
|
|
13
|
+
extraTables: any;
|
|
14
|
+
onExtraTableAdd: any;
|
|
15
|
+
onExtraTableRemove: any;
|
|
16
|
+
}
|
|
17
|
+
interface IssuesListComponentState {
|
|
18
|
+
error?: any;
|
|
19
|
+
search: any;
|
|
20
|
+
issueTypes: any[] | null;
|
|
21
|
+
}
|
|
22
|
+
export declare class IssuesListComponent extends React.Component<IssuesListComponentProps, IssuesListComponentState> {
|
|
23
|
+
constructor(props: any);
|
|
24
|
+
componentDidMount(): JQuery.jqXHR<any>;
|
|
25
|
+
handleTableRemove: (table: any) => any;
|
|
26
|
+
searchRef: (comp: any) => any;
|
|
27
|
+
render(): React.JSX.Element;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
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.IssuesListComponent = void 0;
|
|
30
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
31
|
+
const jquery_1 = __importDefault(require("jquery"));
|
|
32
|
+
const react_1 = __importDefault(require("react"));
|
|
33
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
34
|
+
const uiComponents = __importStar(require("../UIComponents"));
|
|
35
|
+
const expressions_1 = require("@mwater/expressions");
|
|
36
|
+
// Searchable list of issue types
|
|
37
|
+
class IssuesListComponent extends react_1.default.Component {
|
|
38
|
+
constructor(props) {
|
|
39
|
+
super(props);
|
|
40
|
+
this.state = {
|
|
41
|
+
issueTypes: null,
|
|
42
|
+
search: ""
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
componentDidMount() {
|
|
46
|
+
// Get names and basic of issueTypes
|
|
47
|
+
const query = {};
|
|
48
|
+
query.fields = JSON.stringify({ name: 1, desc: 1, roles: 1, created: 1, modified: 1 });
|
|
49
|
+
query.client = this.props.client;
|
|
50
|
+
// Get list of all issueType names
|
|
51
|
+
return jquery_1.default.getJSON(this.props.apiUrl + "issue_types?" + querystring_1.default.stringify(query), (issueTypes) => {
|
|
52
|
+
// Sort by modified.on desc but first by user
|
|
53
|
+
issueTypes = lodash_1.default.sortByOrder(issueTypes, [
|
|
54
|
+
(issueType) => ((this.props.extraTables || []).includes("issues:" + issueType._id) ? 0 : 1),
|
|
55
|
+
(issueType) => (issueType.created.by === this.props.user ? 0 : 1),
|
|
56
|
+
(issueType) => expressions_1.ExprUtils.localizeString(issueType.name, T.locale)
|
|
57
|
+
], ["asc", "asc", "asc"]);
|
|
58
|
+
return this.setState({
|
|
59
|
+
issueTypes: lodash_1.default.map(issueTypes, (issueType) => ({
|
|
60
|
+
id: issueType._id,
|
|
61
|
+
name: expressions_1.ExprUtils.localizeString(issueType.name, T.locale),
|
|
62
|
+
desc: expressions_1.ExprUtils.localizeString(issueType.desc, T.locale)
|
|
63
|
+
}))
|
|
64
|
+
});
|
|
65
|
+
}).fail((xhr) => {
|
|
66
|
+
return this.setState({ error: xhr.responseText });
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
handleTableRemove = (table) => {
|
|
70
|
+
if (confirm(T `Remove ${expressions_1.ExprUtils.localizeString(table.name, T.locale)}? Any widgets that depend on it will no longer work properly.`)) {
|
|
71
|
+
return this.props.onExtraTableRemove(table.id);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
searchRef = (comp) => {
|
|
75
|
+
// Focus
|
|
76
|
+
if (comp) {
|
|
77
|
+
return comp.focus();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
render() {
|
|
81
|
+
let issueTypes;
|
|
82
|
+
if (this.state.error) {
|
|
83
|
+
return react_1.default.createElement("div", { className: "alert alert-danger" }, this.state.error);
|
|
84
|
+
}
|
|
85
|
+
// Filter issueTypes
|
|
86
|
+
if (this.state.search) {
|
|
87
|
+
const escapeRegExp = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
88
|
+
const searchStringRegExp = new RegExp(escapeRegExp(this.state.search), "i");
|
|
89
|
+
issueTypes = lodash_1.default.filter(this.state.issueTypes || [], (issueType) => issueType.name.match(searchStringRegExp));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
;
|
|
93
|
+
({ issueTypes } = this.state);
|
|
94
|
+
}
|
|
95
|
+
// Remove if already included
|
|
96
|
+
issueTypes = lodash_1.default.filter(issueTypes || [], (f) => !(this.props.extraTables || []).includes(`issues:${f.id}`));
|
|
97
|
+
let tables = lodash_1.default.filter(this.props.schema.getTables(), (table) => (table.id.match(/^issues:/) || table.id.match(/^issue_events:/)) && !table.deprecated);
|
|
98
|
+
tables = lodash_1.default.sortBy(tables, (t) => t.name.en);
|
|
99
|
+
return (react_1.default.createElement("div", null,
|
|
100
|
+
react_1.default.createElement("label", null, T `Included Issues:`),
|
|
101
|
+
tables.length > 0 ? (react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(tables, (table) => {
|
|
102
|
+
return {
|
|
103
|
+
name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
|
|
104
|
+
desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
|
|
105
|
+
onClick: this.props.onChange.bind(null, table.id),
|
|
106
|
+
onRemove: this.handleTableRemove.bind(null, table)
|
|
107
|
+
};
|
|
108
|
+
}) })) : (react_1.default.createElement("div", null, T `None`)),
|
|
109
|
+
react_1.default.createElement("br", null),
|
|
110
|
+
react_1.default.createElement("label", null, T `All Issues:`),
|
|
111
|
+
!this.state.issueTypes || this.state.issueTypes.length === 0 ? (react_1.default.createElement("div", { className: "alert alert-info" },
|
|
112
|
+
react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
|
|
113
|
+
"\u00A0",
|
|
114
|
+
T `Loading...`)) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
115
|
+
react_1.default.createElement("input", { type: "text", className: "form-control form-control-sm", placeholder: T `Search...`, key: "search", ref: this.searchRef, style: { maxWidth: "20em", marginBottom: 10 }, value: this.state.search, onChange: (ev) => this.setState({ search: ev.target.value }) }),
|
|
116
|
+
react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(issueTypes, (issueType) => ({
|
|
117
|
+
name: issueType.name,
|
|
118
|
+
desc: issueType.desc,
|
|
119
|
+
onClick: this.props.onChange.bind(null, "issues:" + issueType.id)
|
|
120
|
+
})) })))));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.IssuesListComponent = IssuesListComponent;
|