@mwater/visualization 5.0.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/lib/MWaterAddRelatedFormComponent.d.ts +1 -1
  2. package/lib/MWaterAddRelatedFormComponent.js +10 -17
  3. package/lib/MWaterContextComponent.d.ts +17 -7
  4. package/lib/MWaterContextComponent.js +51 -67
  5. package/lib/MWaterLoaderComponent.d.ts +2 -2
  6. package/lib/MWaterLoaderComponent.js +1 -1
  7. package/lib/MWaterTableSelectComponent.d.ts +0 -1
  8. package/lib/MWaterTableSelectComponent.js +20 -41
  9. package/lib/axes/RangesComponent.d.ts +12 -6
  10. package/lib/axes/RangesComponent.js +21 -10
  11. package/lib/dashboards/DashboardComponent.d.ts +1 -9
  12. package/lib/dashboards/DashboardComponent.js +16 -27
  13. package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -0
  14. package/lib/dashboards/ServerDashboardDataSource.js +3 -0
  15. package/lib/datagrids/DatagridComponent.d.ts +8 -4
  16. package/lib/datagrids/DatagridComponent.js +27 -5
  17. package/lib/datagrids/DatagridDataSource.d.ts +1 -0
  18. package/lib/datagrids/DatagridDataSource.js +3 -0
  19. package/lib/datagrids/DatagridDesign.d.ts +2 -0
  20. package/lib/datagrids/DatagridDesignerComponent.js +3 -2
  21. package/lib/datagrids/DatagridViewComponent.js +1 -1
  22. package/lib/datagrids/DirectDatagridDataSource.d.ts +1 -0
  23. package/lib/datagrids/DirectDatagridDataSource.js +26 -0
  24. package/lib/datagrids/ServerDatagridDataSource.d.ts +1 -0
  25. package/lib/datagrids/ServerDatagridDataSource.js +15 -0
  26. package/lib/index.d.ts +0 -1
  27. package/lib/index.js +2 -4
  28. package/lib/layouts/blocks/BlocksDisplayComponent.js +2 -2
  29. package/lib/layouts/grid/LegoLayoutEngine.d.ts +1 -1
  30. package/lib/maps/BufferLayerDesignerComponent.js +2 -2
  31. package/lib/maps/ChoroplethLayerDesigner.js +2 -2
  32. package/lib/maps/ClusterLayerDesignerComponent.js +2 -2
  33. package/lib/maps/DirectMapDataSource.js +1 -2
  34. package/lib/maps/GridLayerDesigner.js +2 -2
  35. package/lib/maps/MapDesignerComponent.d.ts +1 -12
  36. package/lib/maps/MapDesignerComponent.js +5 -12
  37. package/lib/maps/MarkersLayerDesignerComponent.js +2 -2
  38. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -1
  39. package/lib/maps/PopupFilterJoinsUtils.js +4 -3
  40. package/lib/maps/UtfGridLayer.js +1 -1
  41. package/lib/widgets/ImageWidgetComponent.js +2 -2
  42. package/lib/widgets/charts/calendar/CalendarChartDesignerComponent.js +2 -2
  43. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -1
  44. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +1 -1
  45. package/lib/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.js +2 -2
  46. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -2
  47. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +2 -2
  48. package/lib/widgets/charts/table/TableChartDesignerComponent.js +2 -2
  49. package/lib/widgets/text/ExprItemEditorComponent.js +2 -2
  50. package/package.json +1 -1
  51. package/src/MWaterAddRelatedFormComponent.ts +15 -20
  52. package/src/MWaterContextComponent.tsx +140 -0
  53. package/src/MWaterLoaderComponent.ts +2 -2
  54. package/src/{MWaterTableSelectComponent.ts → MWaterTableSelectComponent.tsx} +61 -66
  55. package/src/axes/AxisBuilder.ts +1 -1
  56. package/src/axes/RangesComponent.ts +27 -16
  57. package/src/dashboards/{DashboardComponent.ts → DashboardComponent.tsx} +37 -40
  58. package/src/dashboards/ServerDashboardDataSource.ts +16 -12
  59. package/src/datagrids/DatagridComponent.ts +45 -14
  60. package/src/datagrids/DatagridDataSource.ts +8 -0
  61. package/src/datagrids/DatagridDesign.ts +3 -0
  62. package/src/datagrids/DatagridDesignerComponent.tsx +9 -1
  63. package/src/datagrids/DatagridViewComponent.ts +1 -1
  64. package/src/datagrids/DirectDatagridDataSource.ts +35 -0
  65. package/src/datagrids/ServerDatagridDataSource.ts +22 -4
  66. package/src/index.ts +0 -2
  67. package/src/layouts/blocks/BlocksDisplayComponent.ts +2 -2
  68. package/src/layouts/grid/LegoLayoutEngine.ts +2 -2
  69. package/src/layouts/grid/WidgetContainerComponent.ts +2 -2
  70. package/src/maps/BingLayer.ts +2 -2
  71. package/src/maps/BufferLayerDesignerComponent.ts +1 -1
  72. package/src/maps/ChoroplethLayerDesigner.tsx +1 -1
  73. package/src/maps/ClusterLayerDesignerComponent.ts +1 -1
  74. package/src/maps/DirectMapDataSource.ts +1 -2
  75. package/src/maps/GridLayerDesigner.tsx +1 -1
  76. package/src/maps/LegendGroup.ts +1 -1
  77. package/src/maps/MWaterServerLayer.ts +2 -2
  78. package/src/maps/{MapDesignerComponent.ts → MapDesignerComponent.tsx} +8 -16
  79. package/src/maps/MarkersLayerDesignerComponent.ts +1 -1
  80. package/src/maps/PopupFilterJoinsUtils.ts +4 -4
  81. package/src/maps/ServerMapDataSource.ts +6 -6
  82. package/src/maps/SwitchableTileUrlLayerDesigner.tsx +1 -13
  83. package/src/maps/UtfGridLayer.ts +4 -4
  84. package/src/maps/mapboxUtils.ts +2 -2
  85. package/src/richtext/ExprItemsHtmlConverter.ts +1 -1
  86. package/src/richtext/FontColorPaletteItem.ts +1 -1
  87. package/src/richtext/FontSizePaletteItem.ts +1 -1
  88. package/src/richtext/ItemsHtmlConverter.ts +2 -2
  89. package/src/widgets/ImageWidgetComponent.ts +1 -1
  90. package/src/widgets/charts/calendar/CalendarChartDesignerComponent.ts +1 -1
  91. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +1 -1
  92. package/src/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.ts +1 -1
  93. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +1 -1
  94. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +1 -1
  95. package/src/widgets/charts/table/TableChartDesignerComponent.ts +1 -1
  96. package/src/widgets/text/ExprItemEditorComponent.tsx +1 -1
  97. package/src/MWaterContextComponent.ts +0 -141
  98. package/src/TableSelectComponent.ts +0 -60
@@ -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() {
@@ -1,7 +1,9 @@
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 { Schema, Section } from "@mwater/expressions";
4
+ import { CustomTableSelectComponentFactoryOptions, DecorateScalarExprTreeSectionChildrenOptions } from "@mwater/expressions-ui";
5
+ /**
6
+ * Creates several contexts to allow selecting of a table in an mWater-friendly way
5
7
  * and several other context items
6
8
  */
7
9
  export default class MWaterContextComponent extends React.Component<{
@@ -18,14 +20,22 @@ export default class MWaterContextComponent extends React.Component<{
18
20
  addLayerElementFactory?: any;
19
21
  }> {
20
22
  static childContextTypes: {
21
- tableSelectElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
22
23
  addLayerElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
23
24
  globalFiltersElementFactory: PropTypes.Requireable<(...args: any[]) => any>;
24
- decorateScalarExprTreeSectionChildren: PropTypes.Requireable<(...args: any[]) => any>;
25
- isScalarExprTreeSectionInitiallyOpen: PropTypes.Requireable<(...args: any[]) => any>;
26
- isScalarExprTreeSectionMatch: PropTypes.Requireable<(...args: any[]) => any>;
27
25
  };
26
+ createTableSelectElementFactory: (options: CustomTableSelectComponentFactoryOptions) => React.JSX.Element;
28
27
  getChildContext(): any;
28
+ isScalarExprTreeSectionMatch: (options: {
29
+ tableId: string;
30
+ section: Section;
31
+ filter?: string;
32
+ }) => true | null;
33
+ isScalarExprTreeSectionInitiallyOpen: (options: {
34
+ tableId: string;
35
+ section: Section;
36
+ filter?: string;
37
+ }) => boolean;
38
+ decorateScalarExprTreeSectionChildren: (options: DecorateScalarExprTreeSectionChildrenOptions) => React.ReactNode;
29
39
  handleAddTable: (table: any) => void;
30
- render(): React.ReactNode;
40
+ render(): React.JSX.Element;
31
41
  }
@@ -11,40 +11,23 @@ const MWaterTableSelectComponent_1 = __importDefault(require("./MWaterTableSelec
11
11
  const MWaterAddRelatedFormComponent_1 = __importDefault(require("./MWaterAddRelatedFormComponent"));
12
12
  const MWaterAddRelatedIndicatorComponent_1 = __importDefault(require("./MWaterAddRelatedIndicatorComponent"));
13
13
  const MWaterGlobalFiltersComponent_1 = __importDefault(require("./MWaterGlobalFiltersComponent"));
14
- /** Creates a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
14
+ const expressions_ui_1 = require("@mwater/expressions-ui");
15
+ const expressions_ui_2 = require("@mwater/expressions-ui");
16
+ /**
17
+ * Creates several contexts to allow selecting of a table in an mWater-friendly way
15
18
  * and several other context items
16
19
  */
17
20
  class MWaterContextComponent extends react_1.default.Component {
18
21
  static childContextTypes = {
19
- tableSelectElementFactory: prop_types_1.default.func,
20
22
  addLayerElementFactory: prop_types_1.default.func,
21
- globalFiltersElementFactory: prop_types_1.default.func,
23
+ globalFiltersElementFactory: prop_types_1.default.func, // Call with props { schema, dataSource, filterableTables, globalFilters, onChange, nullIfIrrelevant }.
22
24
  // Displays a component to edit global filters. nullIfIrrelevant causes null element if not applicable to filterableTables
23
- // 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
25
+ };
26
+ createTableSelectElementFactory = (options) => {
27
+ return (react_1.default.createElement(MWaterTableSelectComponent_1.default, { apiUrl: this.props.apiUrl, client: this.props.client, schema: options.schema, user: this.props.user, table: options.value ?? undefined, onChange: options.onChange, extraTables: this.props.extraTables, onExtraTablesChange: this.props.onExtraTablesChange, filter: options.filter, onFilterChange: options.onFilterChange }));
31
28
  };
32
29
  getChildContext() {
33
30
  const context = {};
34
- context.tableSelectElementFactory = (props) => {
35
- return react_1.default.createElement(MWaterTableSelectComponent_1.default, {
36
- apiUrl: this.props.apiUrl,
37
- client: this.props.client,
38
- schema: props.schema,
39
- user: this.props.user,
40
- table: props.value,
41
- onChange: props.onChange,
42
- extraTables: this.props.extraTables,
43
- onExtraTablesChange: this.props.onExtraTablesChange,
44
- filter: props.filter,
45
- onFilterChange: props.onFilterChange
46
- });
47
- };
48
31
  if (this.props.addLayerElementFactory) {
49
32
  context.addLayerElementFactory = this.props.addLayerElementFactory;
50
33
  }
@@ -54,55 +37,56 @@ class MWaterContextComponent extends react_1.default.Component {
54
37
  }
55
38
  return react_1.default.createElement(MWaterGlobalFiltersComponent_1.default, props);
56
39
  };
57
- context.decorateScalarExprTreeSectionChildren = (options) => {
58
- // If related forms section of entities table or assets table
59
- if ((options.tableId.match(/^entities\./) || options.tableId.match(/^assets:/)) && options.section.id === "!related_forms") {
60
- return R("div", { key: "_add_related_form_parent" }, options.children, R(MWaterAddRelatedFormComponent_1.default, {
61
- key: "_add_related_form",
62
- table: options.tableId,
63
- apiUrl: this.props.apiUrl,
64
- client: this.props.client,
65
- user: this.props.user,
66
- schema: this.props.schema,
67
- onSelect: this.handleAddTable
68
- }));
69
- }
70
- // If indicators section of entities table
71
- if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
72
- return R("div", { key: "_add_related_indicator_parent" }, options.children, R(MWaterAddRelatedIndicatorComponent_1.default, {
73
- key: "_add_related_indicator",
74
- table: options.tableId,
75
- apiUrl: this.props.apiUrl,
76
- client: this.props.client,
77
- user: this.props.user,
78
- schema: this.props.schema,
79
- onSelect: this.handleAddTable,
80
- filter: options.filter
81
- }));
82
- }
83
- else {
84
- return options.children;
85
- }
86
- };
87
- // Always match indicator section
88
- context.isScalarExprTreeSectionMatch = (options) => {
89
- if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
90
- return true;
91
- }
92
- return null;
93
- };
94
- // Nothing initially open
95
- context.isScalarExprTreeSectionInitiallyOpen = (options) => {
96
- return null;
97
- };
98
40
  return context;
99
41
  }
42
+ isScalarExprTreeSectionMatch = (options) => {
43
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
44
+ return true;
45
+ }
46
+ return null;
47
+ };
48
+ isScalarExprTreeSectionInitiallyOpen = (options) => {
49
+ return false;
50
+ };
51
+ decorateScalarExprTreeSectionChildren = (options) => {
52
+ // If related forms section of entities table or assets table
53
+ if (options.tableId.match(/^entities\./) && options.section.id === "!related_forms") {
54
+ return R("div", { key: "_add_related_form_parent" }, options.children, R(MWaterAddRelatedFormComponent_1.default, {
55
+ key: "_add_related_form",
56
+ table: options.tableId,
57
+ apiUrl: this.props.apiUrl,
58
+ client: this.props.client,
59
+ user: this.props.user,
60
+ schema: this.props.schema,
61
+ onSelect: this.handleAddTable
62
+ }));
63
+ }
64
+ // If indicators section of entities table
65
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
66
+ return R("div", { key: "_add_related_indicator_parent" }, options.children, R(MWaterAddRelatedIndicatorComponent_1.default, {
67
+ key: "_add_related_indicator",
68
+ table: options.tableId,
69
+ apiUrl: this.props.apiUrl,
70
+ client: this.props.client,
71
+ user: this.props.user,
72
+ schema: this.props.schema,
73
+ onSelect: this.handleAddTable,
74
+ filter: options.filter
75
+ }));
76
+ }
77
+ else {
78
+ return options.children;
79
+ }
80
+ };
100
81
  handleAddTable = (table) => {
101
82
  const extraTables = lodash_1.default.union(this.props.extraTables || [], [table]);
102
83
  return this.props.onExtraTablesChange(extraTables);
103
84
  };
104
85
  render() {
105
- return this.props.children;
86
+ return react_1.default.createElement(expressions_ui_1.CustomTableSelectComponentFactoryContext.Provider, { value: this.createTableSelectElementFactory },
87
+ react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionMatchContext.Provider, { value: this.isScalarExprTreeSectionMatch },
88
+ react_1.default.createElement(expressions_ui_2.IsScalarExprTreeSectionInitiallyOpenContext.Provider, { value: this.isScalarExprTreeSectionInitiallyOpen },
89
+ react_1.default.createElement(expressions_ui_1.DecorateScalarExprTreeSectionChildrenContext.Provider, { value: this.decorateScalarExprTreeSectionChildren }, this.props.children))));
106
90
  }
107
91
  }
108
92
  exports.default = MWaterContextComponent;
@@ -3,7 +3,7 @@ import { DataSource, Schema } from "@mwater/expressions";
3
3
  import AsyncLoadComponent from "@mwater/react-library/lib/AsyncLoadComponent";
4
4
  /**
5
5
  * Loads an mWater schema from the server and creates child with schema and dataSource
6
- * Also creates a tableSelectElementFactory context to allow selecting of a table in an mWater-friendly way
6
+ * Also creates context to allow selecting of a table in an mWater-friendly way
7
7
  * and several other context items
8
8
  */
9
9
  export default class MWaterLoaderComponent extends AsyncLoadComponent<{
@@ -27,7 +27,7 @@ export default class MWaterLoaderComponent extends AsyncLoadComponent<{
27
27
  dataSource: DataSource;
28
28
  }) => ReactElement<any>;
29
29
  /** Custom error formatter that returns React node or string, gets passed the error response from server */
30
- errorFormatter: (data: any, defaultError: string) => string;
30
+ errorFormatter?: (data: any, defaultError: string) => string;
31
31
  }, {
32
32
  error: any;
33
33
  schema: Schema | null;
@@ -12,7 +12,7 @@ const mWaterLoader_1 = __importDefault(require("./mWaterLoader"));
12
12
  const MWaterContextComponent_1 = __importDefault(require("./MWaterContextComponent"));
13
13
  /**
14
14
  * Loads an mWater schema from the server and creates child with schema and dataSource
15
- * Also creates 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 {
@@ -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
  }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { AxisXform } from "./Axis";
2
+ import { AxisXform, AxisXformRange } from "./Axis";
3
3
  import { Expr, Schema } from "@mwater/expressions";
4
4
  export interface RangesComponentProps {
5
5
  schema: Schema;
@@ -18,9 +18,9 @@ export default class RangesComponent extends React.Component<RangesComponentProp
18
18
  }
19
19
  interface RangeComponentProps {
20
20
  /** Range to edit */
21
- range: any;
22
- onChange: any;
23
- onRemove: any;
21
+ range: AxisXformRange;
22
+ onChange: (range: AxisXformRange) => void;
23
+ onRemove: () => void;
24
24
  /** reorderable connector */
25
25
  connectDragSource: any;
26
26
  /** reorderable connector */
@@ -28,8 +28,14 @@ interface RangeComponentProps {
28
28
  connectDropTarget: any;
29
29
  }
30
30
  declare class RangeComponent extends React.Component<RangeComponentProps> {
31
- handleMinOpenChange: (minOpen: any) => any;
32
- handleMaxOpenChange: (maxOpen: any) => any;
31
+ /**
32
+ * Handles change in minimum open value
33
+ */
34
+ handleMinOpenChange: (minOpen: boolean) => void;
35
+ /**
36
+ * Handles change in maximum open value
37
+ */
38
+ handleMaxOpenChange: (maxOpen: boolean) => void;
33
39
  render(): any;
34
40
  }
35
41
  export {};
@@ -10,6 +10,7 @@ const update_object_1 = __importDefault(require("update-object"));
10
10
  const expressions_ui_1 = require("@mwater/expressions-ui");
11
11
  const NumberInputComponent_1 = __importDefault(require("@mwater/react-library/lib/NumberInputComponent"));
12
12
  const ReorderableListComponent_1 = __importDefault(require("@mwater/react-library/lib/reorderable/ReorderableListComponent"));
13
+ const immer_1 = __importDefault(require("immer"));
13
14
  // Allows setting of ranges
14
15
  class RangesComponent extends react_1.default.Component {
15
16
  handleRangeChange = (index, range) => {
@@ -59,11 +60,21 @@ class RangesComponent extends react_1.default.Component {
59
60
  exports.default = RangesComponent;
60
61
  // Single range (row)
61
62
  class RangeComponent extends react_1.default.Component {
63
+ /**
64
+ * Handles change in minimum open value
65
+ */
62
66
  handleMinOpenChange = (minOpen) => {
63
- return this.props.onChange((0, update_object_1.default)(this.props.range, { minOpen: { $set: minOpen } }));
67
+ return this.props.onChange((0, immer_1.default)(this.props.range, draft => {
68
+ draft.minOpen = minOpen;
69
+ }));
64
70
  };
71
+ /**
72
+ * Handles change in maximum open value
73
+ */
65
74
  handleMaxOpenChange = (maxOpen) => {
66
- return this.props.onChange((0, update_object_1.default)(this.props.range, { maxOpen: { $set: maxOpen } }));
75
+ return this.props.onChange((0, immer_1.default)(this.props.range, draft => {
76
+ draft.maxOpen = maxOpen;
77
+ }));
67
78
  };
68
79
  render() {
69
80
  let placeholder = "";
@@ -88,23 +99,23 @@ class RangeComponent extends react_1.default.Component {
88
99
  }
89
100
  return this.props.connectDragPreview(this.props.connectDropTarget(R("tr", null, R("td", null, this.props.connectDragSource(R("span", { className: "fa fa-bars" }))), R("td", { key: "minOpen" }, R(expressions_ui_1.LinkComponent, {
90
101
  dropdownItems: [
91
- { id: true, name: "greater than" },
92
- { id: false, name: "greater than or equal to" }
102
+ { id: "true", name: "greater than" },
103
+ { id: "false", name: "greater than or equal to" }
93
104
  ],
94
- onDropdownItemClicked: this.handleMinOpenChange
105
+ onDropdownItemClicked: (id) => this.handleMinOpenChange(id === "true")
95
106
  }, this.props.range.minOpen ? "greater than" : "greater than or equal to")), R("td", { key: "minValue" }, R(NumberInputComponent_1.default, {
96
- value: this.props.range.minValue,
107
+ value: this.props.range.minValue ?? undefined,
97
108
  placeholder: "None",
98
109
  small: true,
99
110
  onChange: (v) => this.props.onChange((0, update_object_1.default)(this.props.range, { minValue: { $set: v } }))
100
111
  })), R("td", { key: "and" }, "\u00A0and\u00A0"), R("td", { key: "maxOpen" }, R(expressions_ui_1.LinkComponent, {
101
112
  dropdownItems: [
102
- { id: true, name: "less than" },
103
- { id: false, name: "less than or equal to" }
113
+ { id: "true", name: "less than" },
114
+ { id: "false", name: "less than or equal to" }
104
115
  ],
105
- onDropdownItemClicked: this.handleMaxOpenChange
116
+ onDropdownItemClicked: (id) => this.handleMaxOpenChange(id === "true")
106
117
  }, this.props.range.maxOpen ? "less than" : "less than or equal to")), R("td", { key: "maxValue" }, R(NumberInputComponent_1.default, {
107
- value: this.props.range.maxValue,
118
+ value: this.props.range.maxValue ?? undefined,
108
119
  placeholder: "None",
109
120
  small: true,
110
121
  onChange: (v) => this.props.onChange((0, update_object_1.default)(this.props.range, { maxValue: { $set: v } }))
@@ -57,12 +57,10 @@ export default class DashboardComponent extends React.Component<DashboardCompone
57
57
  };
58
58
  static childContextTypes: {
59
59
  locale: PropTypes.Requireable<string>;
60
- activeTables: PropTypes.Requireable<string[]>;
61
60
  };
62
61
  settings: SettingsModalComponent | null;
63
62
  getChildContext(): {
64
63
  locale: string | undefined;
65
- activeTables: string[];
66
64
  };
67
65
  constructor(props: any);
68
66
  getQuickfilterValues: () => any[];
@@ -105,11 +103,5 @@ export default class DashboardComponent extends React.Component<DashboardCompone
105
103
  }, HTMLElement>;
106
104
  renderQuickfilter(): React.CElement<import("../quickfilter/QuickfiltersComponent").QuickfiltersComponentProps, QuickfiltersComponent>;
107
105
  refDashboardView: (el: any) => any;
108
- render(): React.DetailedReactHTMLElement<{
109
- style: {
110
- display: "grid";
111
- gridTemplateRows: string;
112
- height: string;
113
- };
114
- }, HTMLElement>;
106
+ render(): React.JSX.Element;
115
107
  }
@@ -41,6 +41,7 @@ const DashboardUpgrader_1 = __importDefault(require("./DashboardUpgrader"));
41
41
  const LayoutOptionsComponent_1 = require("./LayoutOptionsComponent");
42
42
  const ModalWindowComponent_1 = __importDefault(require("@mwater/react-library/lib/ModalWindowComponent"));
43
43
  const layoutOptions_1 = require("./layoutOptions");
44
+ const expressions_ui_1 = require("@mwater/expressions-ui");
44
45
  /** Dashboard component that includes an action bar at the top
45
46
  * Manages undo stack and quickfilter value
46
47
  */
@@ -49,15 +50,12 @@ class DashboardComponent extends react_1.default.Component {
49
50
  static defaultProps = { printScaling: true };
50
51
  static childContextTypes = {
51
52
  locale: prop_types_1.default.string,
52
- activeTables: prop_types_1.default.arrayOf(prop_types_1.default.string.isRequired)
53
53
  };
54
54
  settings;
55
55
  getChildContext() {
56
56
  return {
57
57
  // Pass locale down. Both here and DashboardViewComponent to ensure that quickfilters also get context
58
58
  locale: this.props.design.locale,
59
- // Pass active tables down to table select components so they can present a shorter list
60
- activeTables: DashboardUtils.getFilterableTables(this.props.design, this.props.schema)
61
59
  };
62
60
  }
63
61
  constructor(props) {
@@ -268,30 +266,21 @@ class DashboardComponent extends react_1.default.Component {
268
266
  namedStrings: this.props.namedStrings,
269
267
  hideScopes: this.state.hideQuickfilters
270
268
  });
271
- return R("div", {
272
- style: {
273
- display: "grid",
274
- gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
275
- height: "100%"
276
- }
277
- }, !this.props.hideTitleBar ? this.renderTitleBar() : undefined, R("div", null, !this.state.hideQuickfilters ? this.renderQuickfilter() : undefined), dashboardView, this.props.onDesignChange != null
278
- ? R(SettingsModalComponent_1.default, {
279
- onDesignChange: this.handleDesignChange,
280
- schema: this.props.schema,
281
- dataSource: this.props.dataSource,
282
- ref: (c) => {
283
- this.settings = c;
284
- }
285
- })
286
- : undefined, this.state.layoutOptionsOpen
287
- ? R(ModalWindowComponent_1.default, { isOpen: true, outerPadding: 10, innerPadding: 10 }, R(LayoutOptionsComponent_1.LayoutOptionsComponent, {
288
- design: this.props.design,
289
- onDesignChange: this.props.onDesignChange,
290
- onClose: () => this.setState({ layoutOptionsOpen: false }),
291
- dashboardView: readonlyDashboardView,
292
- quickfiltersView: this.renderQuickfilter()
293
- }))
294
- : undefined);
269
+ // Pass active tables down to table select components so they can present a shorter list
270
+ return react_1.default.createElement(expressions_ui_1.ActiveTablesContext.Provider, { value: DashboardUtils.getFilterableTables(this.props.design, this.props.schema) },
271
+ react_1.default.createElement("div", { style: {
272
+ display: "grid",
273
+ gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
274
+ height: "100%"
275
+ } },
276
+ !this.props.hideTitleBar ? this.renderTitleBar() : undefined,
277
+ react_1.default.createElement("div", null, !this.state.hideQuickfilters ? this.renderQuickfilter() : undefined),
278
+ dashboardView,
279
+ this.props.onDesignChange != null && (react_1.default.createElement(SettingsModalComponent_1.default, { onDesignChange: this.handleDesignChange, schema: this.props.schema, dataSource: this.props.dataSource, ref: (c) => {
280
+ this.settings = c;
281
+ } })),
282
+ this.state.layoutOptionsOpen && (react_1.default.createElement(ModalWindowComponent_1.default, { isOpen: true, outerPadding: 10, innerPadding: 10 },
283
+ react_1.default.createElement(LayoutOptionsComponent_1.LayoutOptionsComponent, { design: this.props.design, onDesignChange: this.props.onDesignChange, onClose: () => this.setState({ layoutOptionsOpen: false }), dashboardView: readonlyDashboardView, quickfiltersView: this.renderQuickfilter() })))));
295
284
  }
296
285
  }
297
286
  exports.default = DashboardComponent;
@@ -56,6 +56,7 @@ declare class ServerWidgetMapDataSource implements MapDataSource {
56
56
  e: number;
57
57
  s: number;
58
58
  } | null) => void): void;
59
+ getQuickfiltersDataSource(): QuickfiltersDataSource;
59
60
  }
60
61
  interface ServerWidgetLayerDataSourceOptions extends ServerDashboardDataSourceOptions {
61
62
  widgetId: string;
@@ -184,6 +184,9 @@ class ServerWidgetMapDataSource {
184
184
  return callback(new Error(xhr.responseText));
185
185
  });
186
186
  }
187
+ getQuickfiltersDataSource() {
188
+ return new ServerQuickfilterDataSource(this.options);
189
+ }
187
190
  }
188
191
  class ServerWidgetLayerDataSource {
189
192
  options;
@@ -30,7 +30,7 @@ export interface DatagridComponentProps {
30
30
  quickfilterLocks?: any[];
31
31
  filters?: JsonQLFilter[];
32
32
  }
33
- export default class DatagridComponent extends React.Component<DatagridComponentProps, {
33
+ interface DatagridComponentState {
34
34
  /** is design being edited */
35
35
  editingDesign: boolean;
36
36
  /** True if cells can be edited directly */
@@ -39,14 +39,18 @@ export default class DatagridComponent extends React.Component<DatagridComponent
39
39
  quickfiltersHeight: number | null;
40
40
  quickfiltersValues: null | any[];
41
41
  refreshKey: number;
42
- }> {
42
+ /** Number of rows */
43
+ numRows?: number;
44
+ }
45
+ export default class DatagridComponent extends React.Component<DatagridComponentProps, DatagridComponentState> {
43
46
  datagridView?: DatagridViewComponent | null;
44
47
  quickfilters?: HTMLElement | null;
45
48
  findReplaceModal: FindReplaceModalComponent | null;
46
49
  constructor(props: DatagridComponentProps);
47
- reload(): void | undefined;
50
+ reload(): void;
48
51
  componentDidMount(): void;
49
- componentDidUpdate(): void;
52
+ componentDidUpdate(prevProps: DatagridComponentProps, prevState: DatagridComponentState): void;
53
+ loadRowCount(): void;
50
54
  handleRefreshData: () => void;
51
55
  updateHeight(): void;
52
56
  getQuickfilterValues: () => any[];