@mwater/visualization 5.0.1 → 5.2.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 (172) hide show
  1. package/lib/GlobalFilter.d.ts +13 -0
  2. package/lib/GlobalFilter.js +2 -0
  3. package/lib/MWaterAddRelatedFormComponent.d.ts +1 -1
  4. package/lib/MWaterAddRelatedFormComponent.js +10 -17
  5. package/lib/MWaterCompleteTableSelectComponent.d.ts +2 -9
  6. package/lib/MWaterContextComponent.d.ts +31 -9
  7. package/lib/MWaterContextComponent.js +85 -76
  8. package/lib/MWaterCustomTablesetListComponent.js +9 -3
  9. package/lib/MWaterGlobalFiltersComponent.d.ts +6 -5
  10. package/lib/MWaterGlobalFiltersComponent.js +4 -4
  11. package/lib/MWaterLoaderComponent.d.ts +14 -4
  12. package/lib/MWaterLoaderComponent.js +10 -2
  13. package/lib/MWaterTableSelectComponent.d.ts +0 -1
  14. package/lib/MWaterTableSelectComponent.js +20 -41
  15. package/lib/axes/Axis.d.ts +20 -25
  16. package/lib/axes/AxisBuilder.js +9 -7
  17. package/lib/axes/AxisComponent.d.ts +4 -4
  18. package/lib/axes/RangesComponent.d.ts +12 -6
  19. package/lib/axes/RangesComponent.js +21 -10
  20. package/lib/dashboards/DashboardComponent.d.ts +1 -14
  21. package/lib/dashboards/DashboardComponent.js +18 -56
  22. package/lib/dashboards/DashboardDesign.d.ts +2 -17
  23. package/lib/dashboards/DashboardViewComponent.js +3 -4
  24. package/lib/dashboards/LayoutOptionsComponent.js +4 -3
  25. package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -0
  26. package/lib/dashboards/ServerDashboardDataSource.js +3 -0
  27. package/lib/dashboards/SettingsModalComponent.d.ts +4 -15
  28. package/lib/dashboards/SettingsModalComponent.js +24 -38
  29. package/lib/datagrids/DatagridComponent.d.ts +10 -13
  30. package/lib/datagrids/DatagridComponent.js +27 -5
  31. package/lib/datagrids/DatagridDataSource.d.ts +3 -2
  32. package/lib/datagrids/DatagridDataSource.js +0 -11
  33. package/lib/datagrids/DatagridDesign.d.ts +2 -0
  34. package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -93
  35. package/lib/datagrids/DatagridDesignerComponent.js +11 -8
  36. package/lib/datagrids/DatagridViewComponent.js +2 -2
  37. package/lib/datagrids/DirectDatagridDataSource.d.ts +1 -0
  38. package/lib/datagrids/DirectDatagridDataSource.js +26 -0
  39. package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -20
  40. package/lib/datagrids/FindReplaceModalComponent.js +27 -13
  41. package/lib/datagrids/ServerDatagridDataSource.d.ts +2 -1
  42. package/lib/datagrids/ServerDatagridDataSource.js +16 -3
  43. package/lib/demo.js +1 -1
  44. package/lib/index.d.ts +1 -1
  45. package/lib/index.js +2 -4
  46. package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +2 -1
  47. package/lib/layouts/blocks/BlocksDisplayComponent.js +2 -2
  48. package/lib/layouts/grid/GridLayoutManager.d.ts +2 -1
  49. package/lib/layouts/grid/LegoLayoutEngine.d.ts +1 -1
  50. package/lib/maps/BufferLayer.js +3 -1
  51. package/lib/maps/BufferLayerDesignerComponent.js +2 -2
  52. package/lib/maps/ChoroplethLayerDesigner.js +2 -2
  53. package/lib/maps/ClusterLayer.js +3 -1
  54. package/lib/maps/ClusterLayerDesignerComponent.js +2 -2
  55. package/lib/maps/DirectMapDataSource.js +1 -2
  56. package/lib/maps/GridLayer.js +5 -3
  57. package/lib/maps/GridLayerDesigner.js +2 -3
  58. package/lib/maps/LayerSwitcherComponent.js +1 -1
  59. package/lib/maps/MapComponent.d.ts +2 -7
  60. package/lib/maps/MapDesign.d.ts +2 -13
  61. package/lib/maps/MapDesignerComponent.d.ts +1 -12
  62. package/lib/maps/MapDesignerComponent.js +5 -12
  63. package/lib/maps/MapFiltersDesignerComponent.d.ts +0 -4
  64. package/lib/maps/MapFiltersDesignerComponent.js +4 -5
  65. package/lib/maps/MarkersLayerDesignerComponent.js +2 -2
  66. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -1
  67. package/lib/maps/PopupFilterJoinsUtils.js +4 -3
  68. package/lib/maps/RasterMapViewComponent.d.ts +2 -9
  69. package/lib/maps/RegionSelectComponent.d.ts +2 -1
  70. package/lib/maps/ServerMapDataSource.d.ts +1 -1
  71. package/lib/maps/UtfGridLayer.js +1 -1
  72. package/lib/maps/vectorMaps.d.ts +1 -0
  73. package/lib/maps/vectorMaps.js +10 -2
  74. package/lib/quickfilter/QuickfilterCompiler.d.ts +1 -1
  75. package/lib/widgets/IFrameWidgetComponent.d.ts +2 -9
  76. package/lib/widgets/ImageWidgetComponent.d.ts +6 -24
  77. package/lib/widgets/ImageWidgetComponent.js +2 -2
  78. package/lib/widgets/MapWidget.d.ts +2 -7
  79. package/lib/widgets/MarkdownWidget.d.ts +2 -7
  80. package/lib/widgets/TOCWidget.d.ts +2 -9
  81. package/lib/widgets/charts/ChartWidget.d.ts +3 -15
  82. package/lib/widgets/charts/calendar/CalendarChartDesignerComponent.js +2 -2
  83. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -1
  84. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +1 -1
  85. package/lib/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.js +2 -2
  86. package/lib/widgets/charts/imagemosaic/ImagePopupComponent.d.ts +2 -7
  87. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.d.ts +2 -31
  88. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.d.ts +2 -7
  89. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -2
  90. package/lib/widgets/charts/pivot/IntersectionDesignerComponent.d.ts +73 -66
  91. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +10 -6
  92. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +2 -2
  93. package/lib/widgets/charts/pivot/PivotChartViewComponent.d.ts +3 -22
  94. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +55 -58
  95. package/lib/widgets/charts/table/TableChartDesignerComponent.js +2 -2
  96. package/lib/widgets/charts/table/TableChartViewComponent.js +21 -7
  97. package/lib/widgets/text/ExprInsertModalComponent.d.ts +2 -13
  98. package/lib/widgets/text/ExprItemEditorComponent.js +2 -2
  99. package/lib/widgets/text/ExprUpdateModalComponent.d.ts +2 -13
  100. package/lib/widgets/text/TextWidgetDesign.d.ts +3 -1
  101. package/package.json +1 -1
  102. package/src/GlobalFilter.ts +17 -0
  103. package/src/MWaterAddRelatedFormComponent.ts +15 -20
  104. package/src/MWaterContextComponent.tsx +158 -0
  105. package/src/MWaterCustomTablesetListComponent.tsx +21 -3
  106. package/src/MWaterGlobalFiltersComponent.ts +8 -8
  107. package/src/MWaterLoaderComponent.ts +10 -3
  108. package/src/{MWaterTableSelectComponent.ts → MWaterTableSelectComponent.tsx} +61 -66
  109. package/src/axes/Axis.ts +24 -25
  110. package/src/axes/AxisBuilder.ts +10 -9
  111. package/src/axes/RangesComponent.ts +27 -16
  112. package/src/dashboards/{DashboardComponent.ts → DashboardComponent.tsx} +39 -80
  113. package/src/dashboards/DashboardDesign.ts +2 -22
  114. package/src/dashboards/DashboardViewComponent.ts +4 -5
  115. package/src/dashboards/LayoutOptionsComponent.tsx +6 -4
  116. package/src/dashboards/ServerDashboardDataSource.ts +16 -12
  117. package/src/dashboards/SettingsModalComponent.tsx +170 -0
  118. package/src/datagrids/DatagridComponent.ts +45 -14
  119. package/src/datagrids/DatagridDataSource.ts +10 -8
  120. package/src/datagrids/DatagridDesign.ts +3 -0
  121. package/src/datagrids/DatagridDesignerComponent.tsx +31 -19
  122. package/src/datagrids/DatagridViewComponent.ts +4 -4
  123. package/src/datagrids/DirectDatagridDataSource.ts +35 -0
  124. package/src/datagrids/ExprCellComponent.ts +0 -1
  125. package/src/datagrids/FindReplaceModalComponent.ts +39 -22
  126. package/src/datagrids/ServerDatagridDataSource.ts +23 -6
  127. package/src/demo.ts +1 -1
  128. package/src/index.ts +1 -2
  129. package/src/layouts/blocks/BlocksDisplayComponent.ts +2 -2
  130. package/src/layouts/grid/LegoLayoutEngine.ts +2 -2
  131. package/src/layouts/grid/WidgetContainerComponent.ts +2 -2
  132. package/src/maps/BingLayer.ts +2 -2
  133. package/src/maps/BufferLayer.ts +3 -1
  134. package/src/maps/BufferLayerDesignerComponent.ts +1 -1
  135. package/src/maps/ChoroplethLayerDesigner.tsx +1 -1
  136. package/src/maps/ClusterLayer.ts +3 -1
  137. package/src/maps/ClusterLayerDesignerComponent.ts +1 -1
  138. package/src/maps/DirectMapDataSource.ts +1 -2
  139. package/src/maps/GridLayer.ts +5 -3
  140. package/src/maps/GridLayerDesigner.tsx +1 -2
  141. package/src/maps/LayerSwitcherComponent.tsx +1 -1
  142. package/src/maps/LegendGroup.ts +1 -1
  143. package/src/maps/MWaterServerLayer.ts +2 -2
  144. package/src/maps/MapDesign.ts +2 -17
  145. package/src/maps/{MapDesignerComponent.ts → MapDesignerComponent.tsx} +8 -16
  146. package/src/maps/{MapFiltersDesignerComponent.ts → MapFiltersDesignerComponent.tsx} +25 -25
  147. package/src/maps/MarkersLayerDesignerComponent.ts +1 -1
  148. package/src/maps/PopupFilterJoinsUtils.ts +4 -4
  149. package/src/maps/ServerMapDataSource.ts +7 -7
  150. package/src/maps/SwitchableTileUrlLayerDesigner.tsx +1 -13
  151. package/src/maps/UtfGridLayer.ts +4 -4
  152. package/src/maps/VectorMapViewComponent.tsx +0 -1
  153. package/src/maps/mapboxUtils.ts +2 -2
  154. package/src/maps/vectorMaps.tsx +10 -1
  155. package/src/quickfilter/QuickfilterCompiler.ts +1 -1
  156. package/src/richtext/ExprItemsHtmlConverter.ts +1 -1
  157. package/src/richtext/FontColorPaletteItem.ts +1 -1
  158. package/src/richtext/FontSizePaletteItem.ts +1 -1
  159. package/src/richtext/ItemsHtmlConverter.ts +2 -2
  160. package/src/widgets/ImageWidgetComponent.ts +1 -1
  161. package/src/widgets/charts/calendar/CalendarChartDesignerComponent.ts +1 -1
  162. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +1 -1
  163. package/src/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.ts +1 -1
  164. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +1 -1
  165. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +1 -1
  166. package/src/widgets/charts/table/TableChartDesignerComponent.ts +1 -1
  167. package/src/widgets/charts/table/TableChartViewComponent.ts +21 -7
  168. package/src/widgets/text/ExprItemEditorComponent.tsx +1 -1
  169. package/src/widgets/text/TextWidgetDesign.ts +4 -1
  170. package/src/MWaterContextComponent.ts +0 -141
  171. package/src/TableSelectComponent.ts +0 -60
  172. package/src/dashboards/SettingsModalComponent.ts +0 -169
@@ -0,0 +1,13 @@
1
+ import { Expr, LiteralType } from "@mwater/expressions";
2
+ /** Global filters apply to multiple tables at once if a certain column is present. User-interface to set them
3
+ * is application-specific and the default (non-mWater) dashboard applies them but does not allow editing. */
4
+ export interface GlobalFilter {
5
+ /** id of column to filter */
6
+ columnId: string;
7
+ /** type of column to filter (to ensure that consistent) */
8
+ columnType: LiteralType;
9
+ /** op of expression for filtering */
10
+ op: string;
11
+ /** array of expressions to use for filtering. field expression for column will be injected as expression 0 in the resulting filter expression */
12
+ exprs: Expr[];
13
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Schema } from "@mwater/expressions";
3
3
  export interface MWaterAddRelatedFormComponentProps {
4
- /** Entities or assets table id */
4
+ /** Entities table id */
5
5
  table: string;
6
6
  apiUrl: string;
7
7
  client?: string;
@@ -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 Entity/Site question to the extraTables
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({ state: { $ne: "deleted" } });
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 all form names
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
- return this.setState({ items });
113
+ this.setState({ items });
121
114
  }).fail((xhr) => {
122
- return this.setState({ error: xhr.responseText });
115
+ this.setState({ error: xhr.responseText });
123
116
  });
124
117
  }
125
118
  renderContents() {
@@ -3,6 +3,7 @@ import PropTypes from "prop-types";
3
3
  import React from "react";
4
4
  import * as uiComponents from "./UIComponents";
5
5
  import { Schema } from "@mwater/expressions";
6
+ import ModalPopupComponent from "@mwater/react-library/lib/ModalPopupComponent";
6
7
  interface MWaterCompleteTableSelectComponentProps {
7
8
  /** Url to hit api */
8
9
  apiUrl: string;
@@ -180,15 +181,7 @@ declare class AddIndicatorConfirmPopupComponent extends React.Component<AddIndic
180
181
  renderContents(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement> | React.DetailedReactHTMLElement<{
181
182
  className: string;
182
183
  }, HTMLElement>;
183
- render(): React.CElement<{
184
- showCloseX: boolean;
185
- onClose: () => void;
186
- header: string;
187
- }, React.Component<{
188
- showCloseX: boolean;
189
- onClose: () => void;
190
- header: string;
191
- }, any, any>> | null;
184
+ render(): React.CElement<import("@mwater/react-library/lib/ModalPopupComponent").ModalPopupComponentProps, ModalPopupComponent> | null;
192
185
  }
193
186
  interface IssuesListComponentProps {
194
187
  /** Url to hit api */
@@ -1,13 +1,27 @@
1
1
  import PropTypes from "prop-types";
2
2
  import React from "react";
3
- import { Schema } from "@mwater/expressions";
4
- /** Creates a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
3
+ import { DataSource, Schema, Section } from "@mwater/expressions";
4
+ import { CustomTableSelectComponentFactoryOptions, DecorateScalarExprTreeSectionChildrenOptions } from "@mwater/expressions-ui";
5
+ import { GlobalFilter } from "./GlobalFilter";
6
+ export interface GlobalFiltersElementFactoryProps {
7
+ schema: Schema;
8
+ dataSource: DataSource;
9
+ filterableTables: string[];
10
+ globalFilters?: GlobalFilter[];
11
+ onChange: (globalFilters: GlobalFilter[]) => void;
12
+ /** If true, return null element if not applicable to filterableTables */
13
+ nullIfIrrelevant?: boolean;
14
+ }
15
+ export type GlobalFiltersElementFactory = (props: GlobalFiltersElementFactoryProps) => React.ReactElement | null;
16
+ export declare const GlobalFiltersElementFactoryContext: React.Context<GlobalFiltersElementFactory | null>;
17
+ /**
18
+ * Creates several contexts to allow selecting of a table in an mWater-friendly way
5
19
  * and several other context items
6
20
  */
7
21
  export default class MWaterContextComponent extends React.Component<{
8
22
  apiUrl: string;
9
23
  client?: string;
10
- /** user id of logged in user */
24
+ /** user id of logged in user */
11
25
  user?: string;
12
26
  schema: Schema;
13
27
  /** Extra tables to load in schema. Forms are not loaded by default as they are too many */
@@ -18,14 +32,22 @@ export default class MWaterContextComponent extends React.Component<{
18
32
  addLayerElementFactory?: any;
19
33
  }> {
20
34
  static childContextTypes: {
21
- tableSelectElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
22
35
  addLayerElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
23
- 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
36
  };
37
+ createTableSelectElementFactory: (options: CustomTableSelectComponentFactoryOptions) => React.JSX.Element;
28
38
  getChildContext(): any;
39
+ createGlobalFiltersElementFactory: (props: GlobalFiltersElementFactoryProps) => React.JSX.Element | null;
40
+ isScalarExprTreeSectionMatch: (options: {
41
+ tableId: string;
42
+ section: Section;
43
+ filter?: string;
44
+ }) => true | null;
45
+ isScalarExprTreeSectionInitiallyOpen: (options: {
46
+ tableId: string;
47
+ section: Section;
48
+ filter?: string;
49
+ }) => boolean;
50
+ decorateScalarExprTreeSectionChildren: (options: DecorateScalarExprTreeSectionChildrenOptions) => React.ReactNode;
29
51
  handleAddTable: (table: any) => void;
30
- render(): React.ReactNode;
52
+ render(): React.JSX.Element;
31
53
  }
@@ -1,108 +1,117 @@
1
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
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.GlobalFiltersElementFactoryContext = void 0;
6
30
  const prop_types_1 = __importDefault(require("prop-types"));
7
31
  const lodash_1 = __importDefault(require("lodash"));
8
- const react_1 = __importDefault(require("react"));
32
+ const react_1 = __importStar(require("react"));
9
33
  const R = react_1.default.createElement;
10
34
  const MWaterTableSelectComponent_1 = __importDefault(require("./MWaterTableSelectComponent"));
11
35
  const MWaterAddRelatedFormComponent_1 = __importDefault(require("./MWaterAddRelatedFormComponent"));
12
36
  const MWaterAddRelatedIndicatorComponent_1 = __importDefault(require("./MWaterAddRelatedIndicatorComponent"));
13
37
  const MWaterGlobalFiltersComponent_1 = __importDefault(require("./MWaterGlobalFiltersComponent"));
14
- /** Creates a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
38
+ const expressions_ui_1 = require("@mwater/expressions-ui");
39
+ const expressions_ui_2 = require("@mwater/expressions-ui");
40
+ exports.GlobalFiltersElementFactoryContext = (0, react_1.createContext)(null);
41
+ /**
42
+ * Creates several contexts to allow selecting of a table in an mWater-friendly way
15
43
  * and several other context items
16
44
  */
17
45
  class MWaterContextComponent extends react_1.default.Component {
18
46
  static childContextTypes = {
19
- tableSelectElementFactory: prop_types_1.default.func,
20
- addLayerElementFactory: prop_types_1.default.func,
21
- globalFiltersElementFactory: prop_types_1.default.func,
22
- // Displays a component to edit global filters. nullIfIrrelevant causes null element if not applicable to filterableTables
23
- // Decorates sections (the children element, specifically) in the expression picker
24
- decorateScalarExprTreeSectionChildren: prop_types_1.default.func,
25
- // Function to override initial open state of a section. Passed { tableId: id of table, section: section object from schema, filter: optional string filter }
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
47
+ addLayerElementFactory: prop_types_1.default.func, // Call with props of AddLayerComponent
48
+ };
49
+ createTableSelectElementFactory = (options) => {
50
+ 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
51
  };
32
52
  getChildContext() {
33
53
  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
54
  if (this.props.addLayerElementFactory) {
49
55
  context.addLayerElementFactory = this.props.addLayerElementFactory;
50
56
  }
51
- context.globalFiltersElementFactory = (props) => {
52
- if (props.nullIfIrrelevant && !lodash_1.default.any(props.filterableTables, (t) => t.match(/^entities./))) {
53
- return null;
54
- }
55
- return react_1.default.createElement(MWaterGlobalFiltersComponent_1.default, props);
56
- };
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
57
  return context;
99
58
  }
59
+ createGlobalFiltersElementFactory = (props) => {
60
+ if (props.nullIfIrrelevant && !lodash_1.default.any(props.filterableTables, (t) => t.match(/^entities./))) {
61
+ return null;
62
+ }
63
+ return react_1.default.createElement(MWaterGlobalFiltersComponent_1.default, { ...props });
64
+ };
65
+ isScalarExprTreeSectionMatch = (options) => {
66
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
67
+ return true;
68
+ }
69
+ return null;
70
+ };
71
+ isScalarExprTreeSectionInitiallyOpen = (options) => {
72
+ return false;
73
+ };
74
+ decorateScalarExprTreeSectionChildren = (options) => {
75
+ // If related forms section of entities table or assets table
76
+ if (options.tableId.match(/^entities\./) && options.section.id === "!related_forms") {
77
+ return R("div", { key: "_add_related_form_parent" }, options.children, R(MWaterAddRelatedFormComponent_1.default, {
78
+ key: "_add_related_form",
79
+ table: options.tableId,
80
+ apiUrl: this.props.apiUrl,
81
+ client: this.props.client,
82
+ user: this.props.user,
83
+ schema: this.props.schema,
84
+ onSelect: this.handleAddTable
85
+ }));
86
+ }
87
+ // If indicators section of entities table
88
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
89
+ return R("div", { key: "_add_related_indicator_parent" }, options.children, R(MWaterAddRelatedIndicatorComponent_1.default, {
90
+ key: "_add_related_indicator",
91
+ table: options.tableId,
92
+ apiUrl: this.props.apiUrl,
93
+ client: this.props.client,
94
+ user: this.props.user,
95
+ schema: this.props.schema,
96
+ onSelect: this.handleAddTable,
97
+ filter: options.filter
98
+ }));
99
+ }
100
+ else {
101
+ return options.children;
102
+ }
103
+ };
100
104
  handleAddTable = (table) => {
101
105
  const extraTables = lodash_1.default.union(this.props.extraTables || [], [table]);
102
106
  return this.props.onExtraTablesChange(extraTables);
103
107
  };
104
108
  render() {
105
- return this.props.children;
109
+ return react_1.default.createElement(expressions_ui_1.CustomTableSelectComponentFactoryContext.Provider, { value: this.createTableSelectElementFactory },
110
+ react_1.default.createElement(exports.GlobalFiltersElementFactoryContext.Provider, { value: this.createGlobalFiltersElementFactory },
111
+ react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionMatchContext.Provider, { value: this.isScalarExprTreeSectionMatch },
112
+ react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionInitiallyOpenContext.Provider, { value: this.isScalarExprTreeSectionInitiallyOpen },
113
+ react_1.default.createElement(expressions_ui_1.DecorateScalarExprTreeSectionChildrenContext.Provider, { value: this.decorateScalarExprTreeSectionChildren }, this.props.children)))),
114
+ " ");
106
115
  }
107
116
  }
108
117
  exports.default = MWaterContextComponent;
@@ -15,13 +15,16 @@ const MWaterCustomTablesetListComponent = (props) => {
15
15
  const [tablesets, setTablesets] = (0, react_1.useState)();
16
16
  const [search, setSearch] = (0, react_1.useState)("");
17
17
  const [extraTableNeeded, setExtraTableNeeded] = (0, react_1.useState)();
18
+ const [showSystem, setShowSystem] = (0, react_1.useState)(false);
18
19
  // Get list of all tablesets
19
20
  (0, react_1.useEffect)(() => {
20
21
  fetch(`${props.apiUrl}custom_tablesets?client=${props.client || ""}`)
21
22
  .then((response) => response.json())
22
- .then((body) => {
23
+ .then((tablesets) => {
24
+ // Filter out non-normal
25
+ tablesets = tablesets.filter((ts) => ts.type === "normal");
23
26
  // Put included ones first
24
- setTablesets(lodash_1.default.sortByAll(body, [
27
+ setTablesets(lodash_1.default.sortByAll(tablesets, [
25
28
  (ts) => (props.extraTables.some((t) => (t || "").startsWith(`custom.${ts.code}.`)) ? 0 : 1),
26
29
  (ts) => expressions_1.ExprUtils.localizeString(ts.design.name, props.locale)
27
30
  ]));
@@ -80,8 +83,11 @@ const MWaterCustomTablesetListComponent = (props) => {
80
83
  react_2.default.createElement("h4", { className: "text-muted" }, name),
81
84
  react_2.default.createElement(UIComponents_1.OptionListComponent, { items: items })));
82
85
  };
86
+ const visibleTablesets = tablesets.filter((ts) => (showSystem || !ts.design.system) && !ts.design.deprecated);
83
87
  return (react_2.default.createElement("div", null,
84
88
  react_2.default.createElement(bootstrap_1.TextInput, { value: search, onChange: setSearch, placeholder: "Search..." }),
85
- tablesets.map((ts) => renderTableset(ts))));
89
+ visibleTablesets.map((ts) => renderTableset(ts)),
90
+ react_2.default.createElement("div", null,
91
+ react_2.default.createElement("button", { className: "btn btn-link btn-sm", onClick: () => setShowSystem(!showSystem) }, showSystem ? "Hide system tables" : "Show system tables"))));
86
92
  };
87
93
  exports.MWaterCustomTablesetListComponent = MWaterCustomTablesetListComponent;
@@ -1,16 +1,17 @@
1
1
  import React from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
+ import { GlobalFilter } from "./GlobalFilter";
3
4
  export interface MWaterGlobalFiltersComponentProps {
4
5
  /** Schema of the database */
5
6
  schema: Schema;
6
7
  /** Data source to use to get values */
7
8
  dataSource: DataSource;
8
- filterableTables: any;
9
- globalFilters?: any;
10
- onChange: any;
9
+ filterableTables: string[];
10
+ globalFilters?: GlobalFilter[];
11
+ onChange: (globalFilters: GlobalFilter[]) => void;
11
12
  }
12
13
  export default class MWaterGlobalFiltersComponent extends React.Component<MWaterGlobalFiltersComponentProps> {
13
- handleRegionsChange: (regions: any) => any;
14
- handleManagedByChange: (managedBy: any) => any;
14
+ handleRegionsChange: (regions: any) => void;
15
+ handleManagedByChange: (managedBy: any) => void;
15
16
  render(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
16
17
  }
@@ -45,7 +45,7 @@ class MWaterGlobalFiltersComponent extends react_1.default.Component {
45
45
  exprs: [{ type: "literal", valueType: "id[]", idTable: "admin_regions", value: regions }]
46
46
  });
47
47
  }
48
- return this.props.onChange(globalFilters);
48
+ this.props.onChange(globalFilters);
49
49
  };
50
50
  handleManagedByChange = (managedBy) => {
51
51
  // Remove existing filter
@@ -59,12 +59,12 @@ class MWaterGlobalFiltersComponent extends react_1.default.Component {
59
59
  exprs: [{ type: "literal", valueType: "id", idTable: "subjects", value: "group:" + managedBy }]
60
60
  });
61
61
  }
62
- return this.props.onChange(globalFilters);
62
+ this.props.onChange(globalFilters);
63
63
  };
64
64
  render() {
65
65
  // Find managed by
66
66
  let adminRegions, managedBy;
67
- const managedByEntry = lodash_1.default.find(this.props.globalFilters, (gf) => gf.op === "within" && gf.columnId === "_managed_by");
67
+ const managedByEntry = lodash_1.default.find(this.props.globalFilters || [], (gf) => gf.op === "within" && gf.columnId === "_managed_by");
68
68
  if (managedByEntry) {
69
69
  managedBy = managedByEntry.exprs[0].value.split(":")[1];
70
70
  }
@@ -72,7 +72,7 @@ class MWaterGlobalFiltersComponent extends react_1.default.Component {
72
72
  managedBy = null;
73
73
  }
74
74
  // Find admin region
75
- const adminRegionEntry = lodash_1.default.find(this.props.globalFilters, (gf) => gf.op === "within any" && gf.columnId === "admin_region");
75
+ const adminRegionEntry = lodash_1.default.find(this.props.globalFilters || [], (gf) => gf.op === "within any" && gf.columnId === "admin_region");
76
76
  if (adminRegionEntry) {
77
77
  adminRegions = adminRegionEntry.exprs[0].value;
78
78
  }
@@ -1,9 +1,11 @@
1
- import { ReactElement } from "react";
1
+ import React, { ReactElement } from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
3
  import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent";
4
+ import LoadingComponent from "@mwater/react-library/lib/LoadingComponent";
5
+ import MWaterContextComponent from "./MWaterContextComponent";
4
6
  /**
5
7
  * Loads an mWater schema from the server and creates child with schema and dataSource
6
- * Also creates a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
8
+ * Also creates context to allow selecting of a table in an mWater-friendly way
7
9
  * and several other context items
8
10
  */
9
11
  export default class MWaterLoaderComponent extends AsyncLoadComponent<{
@@ -27,7 +29,7 @@ export default class MWaterLoaderComponent extends AsyncLoadComponent<{
27
29
  dataSource: DataSource;
28
30
  }) => ReactElement<any>;
29
31
  /** Custom error formatter that returns React node or string, gets passed the error response from server */
30
- errorFormatter: (data: any, defaultError: string) => string;
32
+ errorFormatter?: (data: any, defaultError: string) => string;
31
33
  }, {
32
34
  error: any;
33
35
  schema: Schema | null;
@@ -38,5 +40,13 @@ export default class MWaterLoaderComponent extends AsyncLoadComponent<{
38
40
  constructor(props: any);
39
41
  isLoadNeeded(newProps: any, oldProps: any): boolean;
40
42
  load(props: any, prevProps: any, callback: any): void;
41
- render(): any;
43
+ render(): React.ReactElement<any, string | React.JSXElementConstructor<any>> | React.CElement<import("@mwater/react-library/lib/LoadingComponent").LoadingComponentProps, LoadingComponent> | React.CElement<{
44
+ apiUrl: string;
45
+ client?: string | undefined;
46
+ user?: string | undefined;
47
+ schema: Schema;
48
+ extraTables?: string[] | undefined;
49
+ onExtraTablesChange?: ((extraTables: string[]) => void) | undefined;
50
+ addLayerElementFactory?: any;
51
+ }, MWaterContextComponent>;
42
52
  }
@@ -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 a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
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 {
@@ -45,7 +45,15 @@ class MWaterLoaderComponent extends AsyncLoadComponent_1.default {
45
45
  if (error) {
46
46
  const defaultError = `Cannot load one of the forms that this depends on. Perhaps the administrator has not shared the form with you? Details: ${error.message}`;
47
47
  if (this.props.errorFormatter) {
48
- return callback({ error: this.props.errorFormatter(JSON.parse(error.message), defaultError) });
48
+ try {
49
+ const parsedError = JSON.parse(error.message);
50
+ if (parsedError) {
51
+ return callback({ error: this.props.errorFormatter(parsedError, defaultError) });
52
+ }
53
+ }
54
+ catch (e) {
55
+ // Ignore
56
+ }
49
57
  }
50
58
  return callback({ error: defaultError });
51
59
  }
@@ -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 = this.context.activeTables || [];
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
- const items = lodash_1.default.map(this.getTableShortlist(), (tableId) => {
173
- const table = this.props.schema.getTable(tableId);
174
- return {
175
- name: expressions_1.ExprUtils.localizeString(table.name, this.context.locale),
176
- desc: expressions_1.ExprUtils.localizeString(table.desc, this.context.locale),
177
- onClick: this.props.onChange.bind(null, table.id)
178
- };
179
- });
180
- return R("div", null, this.state.completeMode
181
- ? R(ModalPopupComponent_1.default, {
182
- header: "Select Data Source",
183
- onClose: () => this.setState({ completeMode: false }),
184
- showCloseX: true,
185
- size: "x-large"
186
- }, R(MWaterCompleteTableSelectComponent_1.default, {
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
  }