@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.
Files changed (136) hide show
  1. package/.storybook/head.html +0 -1
  2. package/lib/MWaterContextComponent.js +1 -1
  3. package/lib/MWaterLoaderComponent.d.ts +2 -2
  4. package/lib/dashboards/DashboardComponent.js +2 -1
  5. package/lib/dashboards/LayoutOptionsComponent.js +18 -11
  6. package/lib/dashboards/ServerDashboardDataSource.d.ts +10 -1
  7. package/lib/dashboards/ServerDashboardDataSource.js +29 -0
  8. package/lib/dashboards/layoutOptions.d.ts +5 -1
  9. package/lib/datagrids/DatagridComponent.js +1 -1
  10. package/lib/datagrids/ExprCellComponent.d.ts +1 -0
  11. package/lib/datagrids/ExprCellComponent.js +22 -20
  12. package/lib/maps/BufferLayer.d.ts +18 -0
  13. package/lib/maps/BufferLayer.js +24 -14
  14. package/lib/maps/ChoroplethLayer.d.ts +18 -0
  15. package/lib/maps/ChoroplethLayer.js +34 -25
  16. package/lib/maps/ChoroplethLayerDesign.d.ts +3 -2
  17. package/lib/maps/ChoroplethLayerDesigner.d.ts +11 -1
  18. package/lib/maps/DirectMapDataSource.js +17 -0
  19. package/lib/maps/EditHoverOver.d.ts +1 -1
  20. package/lib/maps/EditHoverOver.js +62 -33
  21. package/lib/maps/HoverContent.d.ts +10 -5
  22. package/lib/maps/HoverContent.js +6 -35
  23. package/lib/maps/Layer.d.ts +37 -0
  24. package/lib/maps/Layer.js +30 -4
  25. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  26. package/lib/maps/MWaterServerLayer.js +6 -6
  27. package/lib/maps/MapLayerDataSource.d.ts +9 -0
  28. package/lib/maps/MapUtils.d.ts +19 -1
  29. package/lib/maps/MapUtils.js +71 -1
  30. package/lib/maps/MarkersLayer.d.ts +18 -0
  31. package/lib/maps/MarkersLayer.js +24 -24
  32. package/lib/maps/MarkersLayerDesignerComponent.d.ts +14 -1
  33. package/lib/maps/RasterMapViewComponent.js +1 -1
  34. package/lib/maps/ServerMapDataSource.d.ts +9 -0
  35. package/lib/maps/ServerMapDataSource.js +29 -0
  36. package/lib/maps/VectorMapViewComponent.js +6 -6
  37. package/lib/maps/maps.d.ts +4 -2
  38. package/lib/mwater_table_selection/FormsListComponent.d.ts +33 -0
  39. package/lib/mwater_table_selection/FormsListComponent.js +141 -0
  40. package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +47 -0
  41. package/lib/mwater_table_selection/IndicatorsListComponent.js +182 -0
  42. package/lib/mwater_table_selection/IssuesListComponent.d.ts +29 -0
  43. package/lib/mwater_table_selection/IssuesListComponent.js +123 -0
  44. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.d.ts +20 -0
  45. package/lib/mwater_table_selection/MWaterAccountingSystemListComponent.js +157 -0
  46. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.d.ts +17 -0
  47. package/lib/mwater_table_selection/MWaterAssetSystemsListComponent.js +79 -0
  48. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +37 -0
  49. package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +275 -0
  50. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.d.ts +17 -0
  51. package/lib/mwater_table_selection/MWaterCustomTablesetListComponent.js +94 -0
  52. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.d.ts +17 -0
  53. package/lib/mwater_table_selection/MWaterMetricsTableListComponent.js +80 -0
  54. package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +32 -0
  55. package/lib/mwater_table_selection/MWaterTableSelectComponent.js +158 -0
  56. package/lib/quickfilter/Quickfilter.d.ts +2 -0
  57. package/lib/quickfilter/QuickfiltersDesignComponent.js +18 -10
  58. package/lib/widgets/charts/Chart.d.ts +11 -0
  59. package/lib/widgets/charts/Chart.js +15 -0
  60. package/lib/widgets/charts/ChartWidgetComponent.d.ts +1 -0
  61. package/lib/widgets/charts/ChartWidgetComponent.js +27 -1
  62. package/lib/widgets/charts/layered/LayeredChartDesign.d.ts +1 -1
  63. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +1 -1
  64. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +5 -12
  65. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +43 -57
  66. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +113 -110
  67. package/lib/widgets/charts/layered/LayeredChartUtils.d.ts +2 -1
  68. package/lib/widgets/charts/layered/LayeredChartUtils.js +0 -2
  69. package/lib/widgets/charts/pivot/PivotChart.d.ts +2 -0
  70. package/lib/widgets/charts/pivot/PivotChart.js +156 -0
  71. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +5 -20
  72. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +31 -61
  73. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.d.ts +4 -0
  74. package/lib/widgets/charts/pivot/PivotChartLayoutBuilder.js +4 -2
  75. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.d.ts +5 -44
  76. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +38 -63
  77. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +7 -68
  78. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +58 -106
  79. package/lib/widgets/charts/table/TableChart.d.ts +2 -0
  80. package/lib/widgets/charts/table/TableChart.js +172 -1
  81. package/lib/widgets/charts/table/TableChartDesignerComponent.d.ts +7 -17
  82. package/lib/widgets/charts/table/TableChartDesignerComponent.js +79 -95
  83. package/lib/widgets/charts/table/TableChartViewComponent.d.ts +1 -7
  84. package/lib/widgets/charts/table/TableChartViewComponent.js +19 -27
  85. package/package.json +3 -8
  86. package/src/MWaterContextComponent.tsx +1 -1
  87. package/src/MWaterLoaderComponent.ts +1 -1
  88. package/src/dashboards/DashboardComponent.tsx +2 -1
  89. package/src/dashboards/LayoutOptionsComponent.tsx +22 -10
  90. package/src/dashboards/ServerDashboardDataSource.ts +36 -1
  91. package/src/dashboards/layoutOptions.tsx +5 -1
  92. package/src/datagrids/DatagridComponent.tsx +1 -1
  93. package/src/datagrids/ExprCellComponent.tsx +23 -20
  94. package/src/maps/BufferLayer.ts +35 -20
  95. package/src/maps/ChoroplethLayer.ts +51 -33
  96. package/src/maps/ChoroplethLayerDesign.ts +3 -2
  97. package/src/maps/ChoroplethLayerDesigner.tsx +2 -2
  98. package/src/maps/DirectMapDataSource.ts +21 -1
  99. package/src/maps/EditHoverOver.tsx +91 -51
  100. package/src/maps/HoverContent.tsx +16 -47
  101. package/src/maps/Layer.ts +42 -4
  102. package/src/maps/MWaterServerLayer.ts +6 -6
  103. package/src/maps/MapLayerDataSource.ts +8 -0
  104. package/src/maps/MapUtils.ts +70 -3
  105. package/src/maps/MarkersLayer.ts +34 -24
  106. package/src/maps/RasterMapViewComponent.ts +1 -1
  107. package/src/maps/ServerMapDataSource.ts +35 -0
  108. package/src/maps/VectorMapViewComponent.tsx +6 -6
  109. package/src/maps/maps.ts +4 -2
  110. package/src/mwater_table_selection/FormsListComponent.tsx +188 -0
  111. package/src/mwater_table_selection/IndicatorsListComponent.tsx +283 -0
  112. package/src/mwater_table_selection/IssuesListComponent.tsx +167 -0
  113. package/src/mwater_table_selection/MWaterAccountingSystemListComponent.tsx +225 -0
  114. package/src/{MWaterAssetSystemsListComponent.tsx → mwater_table_selection/MWaterAssetSystemsListComponent.tsx} +2 -2
  115. package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +377 -0
  116. package/src/{MWaterCustomTablesetListComponent.tsx → mwater_table_selection/MWaterCustomTablesetListComponent.tsx} +1 -1
  117. package/src/{MWaterMetricsTableListComponent.tsx → mwater_table_selection/MWaterMetricsTableListComponent.tsx} +1 -1
  118. package/src/{MWaterTableSelectComponent.tsx → mwater_table_selection/MWaterTableSelectComponent.tsx} +83 -86
  119. package/src/quickfilter/Quickfilter.ts +3 -0
  120. package/src/quickfilter/QuickfiltersDesignComponent.tsx +19 -14
  121. package/src/widgets/charts/Chart.ts +17 -0
  122. package/src/widgets/charts/ChartWidgetComponent.tsx +36 -1
  123. package/src/widgets/charts/layered/LayeredChartDesign.ts +1 -1
  124. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +23 -24
  125. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +260 -211
  126. package/src/widgets/charts/layered/LayeredChartUtils.ts +7 -7
  127. package/src/widgets/charts/pivot/PivotChart.ts +191 -0
  128. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +124 -129
  129. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +4 -2
  130. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +120 -149
  131. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +178 -198
  132. package/src/widgets/charts/table/TableChart.ts +177 -1
  133. package/src/widgets/charts/table/TableChartDesignerComponent.tsx +422 -0
  134. package/src/widgets/charts/table/{TableChartViewComponent.ts → TableChartViewComponent.tsx} +65 -60
  135. package/src/MWaterCompleteTableSelectComponent.tsx +0 -975
  136. package/src/widgets/charts/table/TableChartDesignerComponent.ts +0 -441
@@ -0,0 +1,20 @@
1
+ import { Schema } from "@mwater/expressions";
2
+ import React from "react";
3
+ export interface MWaterAccountingSystemListComponentProps {
4
+ apiUrl: string;
5
+ schema: Schema;
6
+ client?: string;
7
+ /** User id (not currently used but good for consistency) */
8
+ user?: string;
9
+ /** Called with table selected, e.g. "custom.accounting:123.accounts" */
10
+ onChange: (tableId: string | null) => void;
11
+ /** Current list of extra table wildcards, e.g. ["accounting:123.*"] */
12
+ extraTables: string[];
13
+ /** Called to request loading tables for an accounting system, e.g. "accounting:123.*" */
14
+ onExtraTableAdd: (wildcardTableId: string) => void;
15
+ /** Called to request unloading tables for an accounting system */
16
+ onExtraTableRemove: (wildcardTableId: string) => void;
17
+ /** e.g. "en" */
18
+ locale?: string;
19
+ }
20
+ export declare function MWaterAccountingSystemListComponent(props: MWaterAccountingSystemListComponentProps): React.JSX.Element;
@@ -0,0 +1,157 @@
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.MWaterAccountingSystemListComponent = MWaterAccountingSystemListComponent;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const expressions_1 = require("@mwater/expressions");
9
+ const react_1 = require("react");
10
+ const react_2 = __importDefault(require("react"));
11
+ const UIComponents_1 = require("../UIComponents");
12
+ const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
13
+ function MWaterAccountingSystemListComponent(props) {
14
+ const { apiUrl, schema, client, onChange, extraTables, onExtraTableAdd, onExtraTableRemove, locale } = props;
15
+ const [rawAccountingSystems, setRawAccountingSystems] = (0, react_1.useState)();
16
+ const [accountingTablesetDesign, setAccountingTablesetDesign] = (0, react_1.useState)();
17
+ const [search, setSearch] = (0, react_1.useState)("");
18
+ // Stores the fully qualified table ID that we want to select after its system is loaded
19
+ const [targetSelection, setTargetSelection] = (0, react_1.useState)();
20
+ // Fetch accounting systems (partitions) and the main accounting tableset design
21
+ (0, react_1.useEffect)(() => {
22
+ // Fetch rows from the 'custom.accounting.partitions' table
23
+ fetch(`${apiUrl}custom/accounting/partitions?client=${client || ""}`)
24
+ .then((response) => {
25
+ if (!response.ok) {
26
+ console.error(`Error fetching accounting system partitions: ${response.status} ${response.statusText}`);
27
+ return []; // Return empty array on error
28
+ }
29
+ return response.json();
30
+ })
31
+ .then((systems) => {
32
+ setRawAccountingSystems(systems);
33
+ })
34
+ .catch(error => {
35
+ console.error("Failed to load accounting systems:", error);
36
+ setRawAccountingSystems([]);
37
+ });
38
+ // Fetch the design of the 'custom.accounting' tableset
39
+ const filter = encodeURIComponent(JSON.stringify({ code: "accounting" }));
40
+ fetch(`${apiUrl}custom_tablesets?filter=${filter}&client=${client || ""}`)
41
+ .then((response) => {
42
+ if (!response.ok) {
43
+ console.error(`Error fetching accounting tableset design: ${response.status} ${response.statusText}`);
44
+ return null;
45
+ }
46
+ return response.json();
47
+ })
48
+ .then((tablesets) => {
49
+ if (tablesets && tablesets.length > 0 && tablesets[0].design) {
50
+ setAccountingTablesetDesign(tablesets[0].design);
51
+ }
52
+ else {
53
+ console.error("Accounting tableset design not found or invalid structure.");
54
+ }
55
+ })
56
+ .catch(error => {
57
+ console.error("Failed to load accounting tableset design:", error);
58
+ });
59
+ }, [apiUrl, client]);
60
+ const sortedAccountingSystems = (0, react_1.useMemo)(() => {
61
+ if (!rawAccountingSystems) {
62
+ return undefined;
63
+ }
64
+ return lodash_1.default.sortByAll(rawAccountingSystems, [
65
+ (sys) => {
66
+ const wildcard = `custom.accounting:${String(sys._partition)}.*`;
67
+ return !extraTables.includes(wildcard); // false (0) for included, true (1) for not
68
+ },
69
+ (sys) => sys.name
70
+ ]);
71
+ }, [rawAccountingSystems, extraTables]);
72
+ // Effect to handle selecting a table once its accounting system's tables are loaded into the schema
73
+ (0, react_1.useEffect)(() => {
74
+ if (targetSelection && schema.getTable(targetSelection)) {
75
+ onChange(targetSelection);
76
+ setTargetSelection(undefined); // Clear the target selection
77
+ }
78
+ }, [targetSelection, schema, onChange]);
79
+ const handleSelectTable = (partitionId, table) => {
80
+ const qualifiedTableId = `custom.accounting:${String(partitionId)}.${table.id}`;
81
+ const accountingSystemWildcard = `custom.accounting:${String(partitionId)}.*`;
82
+ if (!extraTables.includes(accountingSystemWildcard)) {
83
+ onExtraTableAdd(accountingSystemWildcard);
84
+ }
85
+ if (schema.getTable(qualifiedTableId)) {
86
+ onChange(qualifiedTableId);
87
+ }
88
+ else {
89
+ // If not yet in schema, ensure add request is made and set for future selection
90
+ if (!extraTables.includes(accountingSystemWildcard)) {
91
+ onExtraTableAdd(accountingSystemWildcard);
92
+ }
93
+ setTargetSelection(qualifiedTableId);
94
+ }
95
+ };
96
+ const handleRemoveAccountingSystem = (partitionId) => {
97
+ const accountingSystemWildcard = `custom.accounting:${String(partitionId)}.*`;
98
+ if (confirm(T `Remove this accounting system? Some widgets may not work correctly.`)) {
99
+ onExtraTableRemove(accountingSystemWildcard);
100
+ }
101
+ };
102
+ if (!sortedAccountingSystems || !accountingTablesetDesign) {
103
+ return (react_2.default.createElement("div", null,
104
+ react_2.default.createElement("i", { className: "fa fa-spin fa-spinner" }),
105
+ " ",
106
+ T `Loading accounting data...`));
107
+ }
108
+ const filteredSystems = sortedAccountingSystems.filter(system => {
109
+ if (search === "") {
110
+ return true;
111
+ }
112
+ const systemName = expressions_1.ExprUtils.localizeString(system.name, locale) || "";
113
+ if (systemName.toLowerCase().includes(search.toLowerCase())) {
114
+ return true;
115
+ }
116
+ return accountingTablesetDesign.tables.some(t => !t.deprecated && (expressions_1.ExprUtils.localizeString(t.name, locale) || "").toLowerCase().includes(search.toLowerCase()));
117
+ });
118
+ const renderSingleAccountingSystem = (system) => {
119
+ const systemName = expressions_1.ExprUtils.localizeString(system.name, locale) || T `Unnamed System (${system._partition})`;
120
+ const accountingSystemWildcard = `custom.accounting:${String(system._partition)}.*`;
121
+ const isIncluded = extraTables.includes(accountingSystemWildcard);
122
+ const tablesForThisSystem = accountingTablesetDesign.tables
123
+ .filter(t => !t.deprecated)
124
+ .filter(t => t.id != "partitions" && t.id != "roles")
125
+ .filter(t => {
126
+ if (search === "") {
127
+ return true;
128
+ }
129
+ if ((expressions_1.ExprUtils.localizeString(system.name, locale) || "").toLowerCase().includes(search.toLowerCase())) {
130
+ return true;
131
+ }
132
+ return (expressions_1.ExprUtils.localizeString(t.name, locale) || "").toLowerCase().includes(search.toLowerCase());
133
+ })
134
+ .map(t => ({
135
+ name: expressions_1.ExprUtils.localizeString(t.name, locale),
136
+ onClick: () => handleSelectTable(system._partition, t)
137
+ }));
138
+ if (search !== "" && !(expressions_1.ExprUtils.localizeString(system.name, locale) || "").toLowerCase().includes(search.toLowerCase()) && tablesForThisSystem.length === 0) {
139
+ return null;
140
+ }
141
+ return (react_2.default.createElement("div", { key: system._partition, className: "mt-3" },
142
+ react_2.default.createElement("div", { className: "d-flex justify-content-between align-items-center" },
143
+ react_2.default.createElement("h4", { className: "text-muted mb-1" }, systemName),
144
+ isIncluded && (react_2.default.createElement("button", { className: "btn btn-sm btn-link", type: "button", onClick: () => handleRemoveAccountingSystem(system._partition), title: T `Remove this accounting system` },
145
+ react_2.default.createElement("i", { className: "fa fa-times" })))),
146
+ react_2.default.createElement(UIComponents_1.OptionListComponent, { items: tablesForThisSystem })));
147
+ };
148
+ return (react_2.default.createElement("div", null,
149
+ react_2.default.createElement(bootstrap_1.TextInput, { value: search, onChange: setSearch, placeholder: T `Search accounting systems or tables...` }),
150
+ targetSelection && !schema.getTable(targetSelection) && (react_2.default.createElement("div", { className: "alert alert-info my-2" },
151
+ react_2.default.createElement("i", { className: "fa fa-spinner fa-spin me-2" }),
152
+ T `Loading tables for selected accounting system...`)),
153
+ filteredSystems.length > 0
154
+ ? filteredSystems.map(system => renderSingleAccountingSystem(system))
155
+ : (sortedAccountingSystems.length > 0 && search !== "" && react_2.default.createElement("p", null, T `No accounting systems or tables match your search.`)),
156
+ sortedAccountingSystems.length === 0 && !targetSelection && react_2.default.createElement("p", null, T `No accounting systems found.`)));
157
+ }
@@ -0,0 +1,17 @@
1
+ import { Schema } from "@mwater/expressions";
2
+ import React from "react";
3
+ /** Searchable list of asset system tables */
4
+ export declare const MWaterAssetSystemsListComponent: (props: {
5
+ apiUrl: string;
6
+ schema: Schema;
7
+ client?: string;
8
+ /** User id */
9
+ user?: string;
10
+ /** Called with table selected */
11
+ onChange: (tableId: string | null) => void;
12
+ extraTables: string[];
13
+ onExtraTableAdd: (tableId: string) => void;
14
+ onExtraTableRemove: (tableId: string) => void;
15
+ /** e.g. "en" */
16
+ locale?: string;
17
+ }) => React.JSX.Element;
@@ -0,0 +1,79 @@
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.MWaterAssetSystemsListComponent = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const expressions_1 = require("@mwater/expressions");
9
+ const react_1 = require("react");
10
+ const react_2 = __importDefault(require("react"));
11
+ const UIComponents_1 = require("../UIComponents");
12
+ const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
13
+ /** Searchable list of asset system tables */
14
+ const MWaterAssetSystemsListComponent = (props) => {
15
+ const [systems, setSystems] = (0, react_1.useState)();
16
+ const [search, setSearch] = (0, react_1.useState)("");
17
+ const [extraTableNeeded, setExtraTableNeeded] = (0, react_1.useState)();
18
+ // Get list of all systems
19
+ (0, react_1.useEffect)(() => {
20
+ fetch(`${props.apiUrl}asset_systems?client=${props.client || ""}`)
21
+ .then((response) => response.json())
22
+ .then((body) => {
23
+ // Put included ones first
24
+ setSystems(lodash_1.default.sortByAll(body, [
25
+ (m) => (props.extraTables.some(t => t == `assets:${m.sid}`)) ? 0 : 1,
26
+ (m) => expressions_1.ExprUtils.localizeString(m.design.name, props.locale)
27
+ ]));
28
+ });
29
+ }, []);
30
+ (0, react_1.useEffect)(() => {
31
+ if (extraTableNeeded && props.schema.getTable(extraTableNeeded)) {
32
+ props.onChange(extraTableNeeded);
33
+ }
34
+ });
35
+ const selectTable = (system) => {
36
+ const qualifiedTableId = `assets:${system.sid}`;
37
+ // If already included, select it
38
+ if (props.schema.getTable(qualifiedTableId)) {
39
+ props.onChange(qualifiedTableId);
40
+ return;
41
+ }
42
+ // Request extra tables as wildcard
43
+ setExtraTableNeeded(qualifiedTableId);
44
+ props.onExtraTableAdd(qualifiedTableId);
45
+ };
46
+ const handleRemove = (system) => {
47
+ // Remove from extra tables
48
+ const match = props.extraTables.find((t) => t == `assets:${system.sid}`);
49
+ if (match) {
50
+ if (confirm(T `Remove this table? Some widgets may not work correctly.`)) {
51
+ props.onChange(null);
52
+ props.onExtraTableRemove(match);
53
+ }
54
+ }
55
+ };
56
+ if (!systems || extraTableNeeded) {
57
+ return (react_2.default.createElement("div", null,
58
+ react_2.default.createElement("i", { className: "fa fa-spin fa-spinner" }),
59
+ " ",
60
+ T `Loading...`));
61
+ }
62
+ const renderAssetSystems = () => {
63
+ const items = systems
64
+ .map((m) => {
65
+ const alreadyIncluded = props.extraTables.some((t) => t == `assets:${m.sid}`);
66
+ return {
67
+ name: expressions_1.ExprUtils.localizeString(m.design.name, props.locale) || "",
68
+ onClick: () => selectTable(m),
69
+ onRemove: alreadyIncluded ? handleRemove.bind(null, m) : undefined
70
+ };
71
+ })
72
+ .filter((item) => !search || !item.name.toLowerCase().includes(search.toLowerCase()));
73
+ return react_2.default.createElement(UIComponents_1.OptionListComponent, { items: items });
74
+ };
75
+ return (react_2.default.createElement("div", null,
76
+ react_2.default.createElement(bootstrap_1.TextInput, { value: search, onChange: setSearch, placeholder: T `Search...` }),
77
+ renderAssetSystems()));
78
+ };
79
+ exports.MWaterAssetSystemsListComponent = MWaterAssetSystemsListComponent;
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import { Schema } from "@mwater/expressions";
3
+ interface MWaterCompleteTableSelectComponentProps {
4
+ /** Url to hit api */
5
+ apiUrl: string;
6
+ /** Optional client */
7
+ client?: string;
8
+ schema: Schema;
9
+ /** User id */
10
+ user?: string;
11
+ table?: string;
12
+ /** Called with table selected */
13
+ onChange: any;
14
+ extraTables: any;
15
+ onExtraTablesChange: any;
16
+ }
17
+ export default class MWaterCompleteTableSelectComponent extends React.Component<MWaterCompleteTableSelectComponentProps, {
18
+ showLegacyAssets: boolean;
19
+ }> {
20
+ constructor(props: MWaterCompleteTableSelectComponentProps);
21
+ handleExtraTableAdd: (tableId: any) => any;
22
+ handleExtraTableRemove: (tableId: any) => any;
23
+ renderSites(): React.JSX.Element;
24
+ renderForms(): React.JSX.Element;
25
+ renderIndicators(): React.JSX.Element;
26
+ renderIssues(): React.JSX.Element;
27
+ renderSweetSense(): React.JSX.Element;
28
+ renderTablesets(): React.JSX.Element;
29
+ renderMetrics(): React.JSX.Element;
30
+ renderAccountingSystems(): React.JSX.Element;
31
+ renderAssets(): React.JSX.Element;
32
+ renderLegacyAssets(): React.JSX.Element;
33
+ renderOther(): React.JSX.Element;
34
+ getSweetSenseTables(): import("@mwater/expressions").Table[];
35
+ render(): React.JSX.Element;
36
+ }
37
+ export {};
@@ -0,0 +1,275 @@
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
+ const lodash_1 = __importDefault(require("lodash"));
30
+ const react_1 = __importDefault(require("react"));
31
+ const TabbedComponent_1 = __importDefault(require("@mwater/react-library/lib/TabbedComponent"));
32
+ const uiComponents = __importStar(require("../UIComponents"));
33
+ const expressions_1 = require("@mwater/expressions");
34
+ const MWaterCustomTablesetListComponent_1 = require("./MWaterCustomTablesetListComponent");
35
+ const MWaterMetricsTableListComponent_1 = require("./MWaterMetricsTableListComponent");
36
+ const MWaterAssetSystemsListComponent_1 = require("./MWaterAssetSystemsListComponent");
37
+ const FormsListComponent_1 = require("./FormsListComponent");
38
+ const IndicatorsListComponent_1 = require("./IndicatorsListComponent");
39
+ const IssuesListComponent_1 = require("./IssuesListComponent");
40
+ const MWaterAccountingSystemListComponent_1 = require("./MWaterAccountingSystemListComponent");
41
+ const sitesOrder = {
42
+ "entities.water_point": 1,
43
+ "entities.sanitation_facility": 2,
44
+ "entities.household": 3,
45
+ "entities.community": 4,
46
+ "entities.school": 5,
47
+ "entities.health_facility": 6,
48
+ "entities.place_of_worship": 7,
49
+ "entities.water_system": 8,
50
+ "entities.water_system_component": 9,
51
+ "entities.wastewater_treatment_system": 10,
52
+ "entities.waste_disposal_site": 11
53
+ };
54
+ /** Entity types that are assets */
55
+ const assetEntities = [
56
+ "entities.water_asset"
57
+ ];
58
+ // Allows selection of a table. Is the complete list mode of tables
59
+ class MWaterCompleteTableSelectComponent extends react_1.default.Component {
60
+ constructor(props) {
61
+ super(props);
62
+ this.state = {
63
+ showLegacyAssets: false
64
+ };
65
+ }
66
+ handleExtraTableAdd = (tableId) => {
67
+ return this.props.onExtraTablesChange(lodash_1.default.union(this.props.extraTables, [tableId]));
68
+ };
69
+ handleExtraTableRemove = (tableId) => {
70
+ // Set to null if current table
71
+ if (this.props.table === tableId) {
72
+ this.props.onChange(null);
73
+ }
74
+ return this.props.onExtraTablesChange(lodash_1.default.without(this.props.extraTables, tableId));
75
+ };
76
+ renderSites() {
77
+ let table;
78
+ let types = [];
79
+ for (table of this.props.schema.getTables()) {
80
+ if (table.deprecated) {
81
+ continue;
82
+ }
83
+ if (!table.id.match(/^entities\./)) {
84
+ continue;
85
+ }
86
+ // Skip assets
87
+ if (assetEntities.includes(table.id)) {
88
+ continue;
89
+ }
90
+ types.push(table.id);
91
+ }
92
+ // Sort by order if present
93
+ types = lodash_1.default.sortBy(types, (type) => sitesOrder[type] || 999);
94
+ return react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.compact(lodash_1.default.map(types, (tableId) => {
95
+ table = this.props.schema.getTable(tableId);
96
+ return {
97
+ name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
98
+ desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
99
+ onClick: this.props.onChange.bind(null, table.id)
100
+ };
101
+ })) });
102
+ }
103
+ renderForms() {
104
+ return react_1.default.createElement(FormsListComponent_1.FormsListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove });
105
+ }
106
+ renderIndicators() {
107
+ return react_1.default.createElement(IndicatorsListComponent_1.IndicatorsListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove });
108
+ }
109
+ renderIssues() {
110
+ return react_1.default.createElement(IssuesListComponent_1.IssuesListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove });
111
+ }
112
+ renderSweetSense() {
113
+ let sweetSenseTables = this.getSweetSenseTables();
114
+ sweetSenseTables = lodash_1.default.sortBy(sweetSenseTables, (table) => table.name.en);
115
+ return react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(sweetSenseTables, (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.props.onChange.bind(null, table.id)
120
+ };
121
+ }) });
122
+ }
123
+ renderTablesets() {
124
+ return react_1.default.createElement(MWaterCustomTablesetListComponent_1.MWaterCustomTablesetListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove, locale: T.locale });
125
+ }
126
+ renderMetrics() {
127
+ return react_1.default.createElement(MWaterMetricsTableListComponent_1.MWaterMetricsTableListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove, locale: T.locale });
128
+ }
129
+ renderAccountingSystems() {
130
+ return react_1.default.createElement(MWaterAccountingSystemListComponent_1.MWaterAccountingSystemListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove, locale: T.locale });
131
+ }
132
+ renderAssets() {
133
+ const items = [];
134
+ for (const tableId of assetEntities) {
135
+ const table = this.props.schema.getTable(tableId);
136
+ if (!table) {
137
+ continue;
138
+ }
139
+ items.push({
140
+ name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
141
+ desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
142
+ onClick: this.props.onChange.bind(null, table.id),
143
+ onRemove: this.handleExtraTableRemove.bind(null, table.id)
144
+ });
145
+ }
146
+ return react_1.default.createElement("div", null,
147
+ react_1.default.createElement(uiComponents.OptionListComponent, { items: items }),
148
+ react_1.default.createElement("div", { className: "text-center mt-2 mb-2" },
149
+ react_1.default.createElement("button", { className: "btn btn-link", onClick: () => this.setState({ showLegacyAssets: !this.state.showLegacyAssets }) },
150
+ this.state.showLegacyAssets ? T `Hide` : T `Show`,
151
+ " ",
152
+ T `Legacy Assets`)),
153
+ this.state.showLegacyAssets && this.renderLegacyAssets());
154
+ }
155
+ renderLegacyAssets() {
156
+ return react_1.default.createElement(MWaterAssetSystemsListComponent_1.MWaterAssetSystemsListComponent, { schema: this.props.schema, client: this.props.client, apiUrl: this.props.apiUrl, user: this.props.user, onChange: this.props.onChange, extraTables: this.props.extraTables, onExtraTableAdd: this.handleExtraTableAdd, onExtraTableRemove: this.handleExtraTableRemove, locale: T.locale });
157
+ }
158
+ renderOther() {
159
+ let otherTables = lodash_1.default.filter(this.props.schema.getTables(), (table) => {
160
+ // Remove deprecated
161
+ if (table.deprecated) {
162
+ return false;
163
+ }
164
+ // Remove sites
165
+ if (table.id.match(/^entities\./)) {
166
+ return false;
167
+ }
168
+ // sweetsense tables
169
+ if (table.id.match(/^sweetsense/)) {
170
+ return false;
171
+ }
172
+ // Remove responses
173
+ if (table.id.match(/^responses:/)) {
174
+ return false;
175
+ }
176
+ // Remove indicators
177
+ if (table.id.match(/^indicator_values:/)) {
178
+ return false;
179
+ }
180
+ // Remove issues
181
+ if (table.id.match(/^(issues|issue_events):/)) {
182
+ return false;
183
+ }
184
+ // Remove custom tablesets
185
+ if (table.id.match(/^custom\./)) {
186
+ return false;
187
+ }
188
+ // Remove metrics
189
+ if (table.id.match(/^metrics:/)) {
190
+ return false;
191
+ }
192
+ // Remove assets
193
+ if (table.id.match(/^assets:/)) {
194
+ return false;
195
+ }
196
+ return true;
197
+ });
198
+ otherTables = lodash_1.default.sortBy(otherTables, (table) => table.name.en);
199
+ return react_1.default.createElement(uiComponents.OptionListComponent, { items: lodash_1.default.map(otherTables, (table) => {
200
+ return {
201
+ name: expressions_1.ExprUtils.localizeString(table.name, T.locale),
202
+ desc: expressions_1.ExprUtils.localizeString(table.desc, T.locale),
203
+ onClick: this.props.onChange.bind(null, table.id)
204
+ };
205
+ }) });
206
+ }
207
+ getSweetSenseTables() {
208
+ return lodash_1.default.filter(this.props.schema.getTables(), (table) => {
209
+ if (table.deprecated) {
210
+ return false;
211
+ }
212
+ if (table.id.match(/^sweetsense/)) {
213
+ return true;
214
+ }
215
+ return false;
216
+ });
217
+ }
218
+ render() {
219
+ const sweetSenseTables = this.getSweetSenseTables();
220
+ const tabs = [
221
+ { id: "sites", label: react_1.default.createElement(react_1.default.Fragment, null,
222
+ react_1.default.createElement("i", { className: "fa fa-map-marker" }),
223
+ " ",
224
+ T `Sites`), elem: this.renderSites() },
225
+ { id: "forms", label: react_1.default.createElement(react_1.default.Fragment, null,
226
+ react_1.default.createElement("i", { className: "fa fa-th-list" }),
227
+ " ",
228
+ T `Surveys`), elem: this.renderForms() },
229
+ {
230
+ id: "indicators",
231
+ label: react_1.default.createElement(react_1.default.Fragment, null,
232
+ react_1.default.createElement("i", { className: "fa fa-check-circle" }),
233
+ " ",
234
+ T `Indicators`),
235
+ elem: this.renderIndicators()
236
+ },
237
+ {
238
+ id: "issues",
239
+ label: react_1.default.createElement(react_1.default.Fragment, null,
240
+ react_1.default.createElement("i", { className: "fa fa-exclamation-circle" }),
241
+ " ",
242
+ T `Issues`),
243
+ elem: this.renderIssues()
244
+ },
245
+ { id: "tablesets", label: react_1.default.createElement(react_1.default.Fragment, null,
246
+ react_1.default.createElement("i", { className: "fa fa-table" }),
247
+ " ",
248
+ T `Tables`), elem: this.renderTablesets() },
249
+ { id: "metrics", label: react_1.default.createElement(react_1.default.Fragment, null,
250
+ react_1.default.createElement("i", { className: "fa fa-line-chart" }),
251
+ " ",
252
+ T `Metrics`), elem: this.renderMetrics() },
253
+ {
254
+ id: "accounting",
255
+ label: react_1.default.createElement(react_1.default.Fragment, null,
256
+ react_1.default.createElement("i", { className: "fa fa-calculator" }),
257
+ " ",
258
+ T `Accounting`),
259
+ elem: this.renderAccountingSystems()
260
+ },
261
+ { id: "assets", label: react_1.default.createElement(react_1.default.Fragment, null,
262
+ react_1.default.createElement("i", { className: "fas fa-map-pin" }),
263
+ " ",
264
+ T `Assets`), elem: this.renderAssets() }
265
+ ];
266
+ if (sweetSenseTables.length > 0) {
267
+ tabs.push({ id: "sensors", label: T `Sensors`, elem: this.renderSweetSense() });
268
+ }
269
+ tabs.push({ id: "other", label: T `Advanced`, elem: this.renderOther() });
270
+ return (react_1.default.createElement("div", null,
271
+ react_1.default.createElement("div", { className: "text-muted" }, T `Select data from sites, surveys or an advanced category below. Indicators can be found within their associated site types.`),
272
+ react_1.default.createElement(TabbedComponent_1.default, { tabs: tabs, initialTabId: "sites" })));
273
+ }
274
+ }
275
+ exports.default = MWaterCompleteTableSelectComponent;
@@ -0,0 +1,17 @@
1
+ import { Schema } from "@mwater/expressions";
2
+ import React from "react";
3
+ /** Searchable list of custom tables */
4
+ export declare const MWaterCustomTablesetListComponent: (props: {
5
+ apiUrl: string;
6
+ schema: Schema;
7
+ client?: string;
8
+ /** User id */
9
+ user?: string;
10
+ /** Called with table selected */
11
+ onChange: (tableId: string | null) => void;
12
+ extraTables: string[];
13
+ onExtraTableAdd: (tableId: string) => void;
14
+ onExtraTableRemove: (tableId: string) => void;
15
+ /** e.g. "en" */
16
+ locale?: string;
17
+ }) => React.JSX.Element;