@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
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import * as ui from "@mwater/react-library/lib/bootstrap";
2
3
  import { DataSource, Schema } from "@mwater/expressions";
3
4
  import { PivotChartSegment } from "./PivotChartDesign";
4
5
  export interface SegmentDesignerComponentProps {
@@ -27,70 +28,66 @@ export default class SegmentDesignerComponent extends React.Component<SegmentDes
27
28
  handleOrderExprChange: (orderExpr: any) => any;
28
29
  handleOrderDirChange: (orderDir: any) => any;
29
30
  renderMode(): React.CElement<{
30
- labelMuted: boolean;
31
- label: string;
32
- }, React.Component<{
33
- labelMuted: boolean;
34
- label: string;
35
- }, any, any>>;
31
+ label: React.ReactNode;
32
+ labelMuted?: boolean | undefined;
33
+ hint?: React.ReactNode;
34
+ help?: React.ReactNode;
35
+ required?: boolean | undefined;
36
+ hasSuccess?: boolean | undefined;
37
+ hasWarnings?: boolean | undefined;
38
+ hasErrors?: boolean | undefined;
39
+ }, ui.FormGroup>;
36
40
  renderLabel(): React.CElement<{
37
- labelMuted: boolean;
38
- label: string;
39
- help: string | undefined;
40
- }, React.Component<{
41
- labelMuted: boolean;
42
- label: string;
43
- help: string | undefined;
44
- }, any, any>>;
41
+ label: React.ReactNode;
42
+ labelMuted?: boolean | undefined;
43
+ hint?: React.ReactNode;
44
+ help?: React.ReactNode;
45
+ required?: boolean | undefined;
46
+ hasSuccess?: boolean | undefined;
47
+ hasWarnings?: boolean | undefined;
48
+ hasErrors?: boolean | undefined;
49
+ }, ui.FormGroup>;
45
50
  renderValueAxis(): React.JSX.Element;
46
51
  renderFilter(): React.CElement<{
47
- labelMuted: boolean;
48
- label: (string | React.CElement<{
49
- id: string;
50
- }, React.Component<{
51
- id: string;
52
- }, any, any>>)[];
53
- hint: string;
54
- }, React.Component<{
55
- labelMuted: boolean;
56
- label: (string | React.CElement<{
57
- id: string;
58
- }, React.Component<{
59
- id: string;
60
- }, any, any>>)[];
61
- hint: string;
62
- }, any, any>>;
52
+ label: React.ReactNode;
53
+ labelMuted?: boolean | undefined;
54
+ hint?: React.ReactNode;
55
+ help?: React.ReactNode;
56
+ required?: boolean | undefined;
57
+ hasSuccess?: boolean | undefined;
58
+ hasWarnings?: boolean | undefined;
59
+ hasErrors?: boolean | undefined;
60
+ }, ui.FormGroup>;
63
61
  renderStyling(): React.CElement<{
64
- labelMuted: boolean;
65
- label: string;
66
- }, React.Component<{
67
- labelMuted: boolean;
68
- label: string;
69
- }, any, any>>;
62
+ label: React.ReactNode;
63
+ labelMuted?: boolean | undefined;
64
+ hint?: React.ReactNode;
65
+ help?: React.ReactNode;
66
+ required?: boolean | undefined;
67
+ hasSuccess?: boolean | undefined;
68
+ hasWarnings?: boolean | undefined;
69
+ hasErrors?: boolean | undefined;
70
+ }, ui.FormGroup>;
70
71
  renderBorders(): React.CElement<{
71
- labelMuted: boolean;
72
- label: string;
73
- }, React.Component<{
74
- labelMuted: boolean;
75
- label: string;
76
- }, any, any>>;
72
+ label: React.ReactNode;
73
+ labelMuted?: boolean | undefined;
74
+ hint?: React.ReactNode;
75
+ help?: React.ReactNode;
76
+ required?: boolean | undefined;
77
+ hasSuccess?: boolean | undefined;
78
+ hasWarnings?: boolean | undefined;
79
+ hasErrors?: boolean | undefined;
80
+ }, ui.FormGroup>;
77
81
  renderOrderExpr(): React.CElement<{
78
- labelMuted: boolean;
79
- label: (string | React.CElement<{
80
- id: string;
81
- }, React.Component<{
82
- id: string;
83
- }, any, any>>)[];
84
- hint: string;
85
- }, React.Component<{
86
- labelMuted: boolean;
87
- label: (string | React.CElement<{
88
- id: string;
89
- }, React.Component<{
90
- id: string;
91
- }, any, any>>)[];
92
- hint: string;
93
- }, any, any>>;
82
+ label: React.ReactNode;
83
+ labelMuted?: boolean | undefined;
84
+ hint?: React.ReactNode;
85
+ help?: React.ReactNode;
86
+ required?: boolean | undefined;
87
+ hasSuccess?: boolean | undefined;
88
+ hasWarnings?: boolean | undefined;
89
+ hasErrors?: boolean | undefined;
90
+ }, ui.FormGroup>;
94
91
  render(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
95
92
  }
96
93
  export {};
@@ -36,7 +36,7 @@ const AxisBuilder_1 = __importDefault(require("../../../axes/AxisBuilder"));
36
36
  const expressions_ui_1 = require("@mwater/expressions-ui");
37
37
  const expressions_ui_2 = require("@mwater/expressions-ui");
38
38
  const OrderingsComponent_1 = __importDefault(require("./OrderingsComponent"));
39
- const TableSelectComponent_1 = __importDefault(require("../../../TableSelectComponent"));
39
+ const expressions_ui_3 = require("@mwater/expressions-ui");
40
40
  const ReorderableListComponent_1 = __importDefault(require("@mwater/react-library/lib/reorderable/ReorderableListComponent"));
41
41
  const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
42
42
  const valueFormatter_1 = require("../../../valueFormatter");
@@ -79,7 +79,7 @@ class TableChartDesignerComponent extends react_1.default.Component {
79
79
  this.updateDesign({ columns });
80
80
  };
81
81
  renderTable() {
82
- return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("i", { className: "fa fa-database" }), " ", "Data Source"), ": ", R(TableSelectComponent_1.default, {
82
+ return R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("i", { className: "fa fa-database" }), " ", "Data Source"), ": ", R(expressions_ui_3.TableSelectComponent, {
83
83
  schema: this.props.schema,
84
84
  value: this.props.design.table,
85
85
  onChange: this.handleTableChange,
@@ -124,7 +124,7 @@ class TableContentsComponent extends react_1.default.Component {
124
124
  }
125
125
  renderImage(id) {
126
126
  const url = this.props.dataSource.getImageUrl(id);
127
- return R("a", { href: url, key: id, target: "_blank", style: { paddingLeft: 5, paddingRight: 5 } }, "Image");
127
+ return R("a", { href: url, onClick: (e) => { e.stopPropagation(); }, key: id, target: "_blank", style: { paddingLeft: 5, paddingRight: 5 } }, "Image");
128
128
  }
129
129
  renderCell(rowIndex, columnIndex) {
130
130
  const axisBuilder = new AxisBuilder_1.default({ schema: this.props.schema });
@@ -162,7 +162,9 @@ class TableContentsComponent extends react_1.default.Component {
162
162
  // Convert to node based on type
163
163
  switch (exprType) {
164
164
  case "text":
165
- node = R(react_linkify_1.default, { properties: { target: "_blank" } }, value);
165
+ if (lodash_1.default.isString(value)) {
166
+ node = R(react_linkify_1.default, { properties: { target: "_blank" } }, value);
167
+ }
166
168
  break;
167
169
  case "number":
168
170
  case "geometry":
@@ -170,21 +172,33 @@ class TableContentsComponent extends react_1.default.Component {
170
172
  break;
171
173
  case "boolean":
172
174
  case "enum":
175
+ node = exprUtils.stringifyExprLiteral(column.textAxis?.expr, value, this.context.locale);
176
+ break;
173
177
  case "enumset":
174
178
  case "text[]":
175
- node = exprUtils.stringifyExprLiteral(column.textAxis?.expr, value, this.context.locale);
179
+ if (lodash_1.default.isArray(value)) {
180
+ node = exprUtils.stringifyExprLiteral(column.textAxis?.expr, value, this.context.locale);
181
+ }
176
182
  break;
177
183
  case "date":
178
- node = (0, valueFormatter_1.formatValue)(exprType, value, column.format);
184
+ if (lodash_1.default.isString(value)) {
185
+ node = (0, valueFormatter_1.formatValue)(exprType, value, column.format);
186
+ }
179
187
  break;
180
188
  case "datetime":
181
- node = (0, valueFormatter_1.formatValue)(exprType, value, column.format);
189
+ if (lodash_1.default.isString(value)) {
190
+ node = (0, valueFormatter_1.formatValue)(exprType, value, column.format);
191
+ }
182
192
  break;
183
193
  case "image":
184
- node = this.renderImage(value.id);
194
+ if (lodash_1.default.isObject(value) && value.id != null) {
195
+ node = this.renderImage(value.id);
196
+ }
185
197
  break;
186
198
  case "imagelist":
187
- node = lodash_1.default.map(value, (v) => this.renderImage(v.id));
199
+ if (lodash_1.default.isArray(value)) {
200
+ node = lodash_1.default.map(value, (v) => this.renderImage(v.id));
201
+ }
188
202
  break;
189
203
  default:
190
204
  node = "" + value;
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
+ import ActionCancelModalComponent from "@mwater/react-library/lib/ActionCancelModalComponent";
3
4
  import { HtmlItemExpr } from "../../richtext/ExprItemsHtmlConverter";
4
5
  export interface ExprInsertModalComponentProps {
5
6
  /** Schema to use */
@@ -18,18 +19,6 @@ export default class ExprInsertModalComponent extends React.Component<ExprInsert
18
19
  constructor(props: ExprInsertModalComponentProps);
19
20
  open(): void;
20
21
  handleInsert: () => void;
21
- render(): React.CElement<{
22
- actionLabel: string;
23
- onAction: () => void;
24
- onCancel: () => void;
25
- title: string;
26
- size: string;
27
- }, React.Component<{
28
- actionLabel: string;
29
- onAction: () => void;
30
- onCancel: () => void;
31
- title: string;
32
- size: string;
33
- }, any, any>> | null;
22
+ render(): React.CElement<import("@mwater/react-library/lib/ActionCancelModalComponent").ActionCancelModalComponentProps, ActionCancelModalComponent> | null;
34
23
  }
35
24
  export {};
@@ -8,7 +8,7 @@ const react_1 = __importDefault(require("react"));
8
8
  const R = react_1.default.createElement;
9
9
  const expressions_1 = require("@mwater/expressions");
10
10
  const expressions_ui_1 = require("@mwater/expressions-ui");
11
- const TableSelectComponent_1 = __importDefault(require("../../TableSelectComponent"));
11
+ const expressions_ui_2 = require("@mwater/expressions-ui");
12
12
  const valueFormatter_1 = require("../../valueFormatter");
13
13
  const valueFormatter_2 = require("../../valueFormatter");
14
14
  const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
@@ -61,7 +61,7 @@ class ExprItemEditorComponent extends react_1.default.Component {
61
61
  }, lodash_1.default.map(formats, (format) => R("option", { key: format.value, value: format.value }, format.label))));
62
62
  }
63
63
  render() {
64
- return R("div", { style: { paddingBottom: 200 } }, R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("i", { className: "fa fa-database" }), " ", "Data Source"), ": ", R(TableSelectComponent_1.default, {
64
+ return R("div", { style: { paddingBottom: 200 } }, R("div", { className: "mb-3" }, R("label", { className: "text-muted" }, R("i", { className: "fa fa-database" }), " ", "Data Source"), ": ", R(expressions_ui_2.TableSelectComponent, {
65
65
  schema: this.props.schema,
66
66
  value: this.state.table,
67
67
  onChange: this.handleTableChange
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { DataSource, Schema } from "@mwater/expressions";
3
+ import ActionCancelModalComponent from "@mwater/react-library/lib/ActionCancelModalComponent";
3
4
  import { HtmlItemExpr } from "../../richtext/ExprItemsHtmlConverter";
4
5
  export interface ExprUpdateModalComponentProps {
5
6
  /** Schema to use */
@@ -16,18 +17,6 @@ interface ExprUpdateModalComponentState {
16
17
  export default class ExprUpdateModalComponent extends React.Component<ExprUpdateModalComponentProps, ExprUpdateModalComponentState> {
17
18
  constructor(props: any);
18
19
  open(item: any, onUpdate: any): void;
19
- render(): React.CElement<{
20
- actionLabel: string;
21
- onAction: () => void;
22
- onCancel: () => void;
23
- title: string;
24
- size: string;
25
- }, React.Component<{
26
- actionLabel: string;
27
- onAction: () => void;
28
- onCancel: () => void;
29
- title: string;
30
- size: string;
31
- }, any, any>> | null;
20
+ render(): React.CElement<import("@mwater/react-library/lib/ActionCancelModalComponent").ActionCancelModalComponentProps, ActionCancelModalComponent> | null;
32
21
  }
33
22
  export {};
@@ -1,6 +1,8 @@
1
+ import { HtmlItemExpr } from "../../richtext/ExprItemsHtmlConverter";
2
+ import { HtmlItem } from "../../richtext/ItemsHtmlConverter";
1
3
  export interface TextWidgetDesign {
2
4
  /** Text widget stores its content as array of items. See ItemsHtmlConverter TODO */
3
- items: any[];
5
+ items: (HtmlItem | HtmlItemExpr)[];
4
6
  /** "title" for title block. default is "default" */
5
7
  style?: "title" | "default";
6
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mwater/visualization",
3
- "version": "5.0.1",
3
+ "version": "5.2.0",
4
4
  "description": "Visualization library",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -0,0 +1,17 @@
1
+ import { Expr, LiteralType } from "@mwater/expressions"
2
+
3
+ /** Global filters apply to multiple tables at once if a certain column is present. User-interface to set them
4
+ * is application-specific and the default (non-mWater) dashboard applies them but does not allow editing. */
5
+ export interface GlobalFilter {
6
+ /** id of column to filter */
7
+ columnId: string
8
+
9
+ /** type of column to filter (to ensure that consistent) */
10
+ columnType: LiteralType
11
+
12
+ /** op of expression for filtering */
13
+ op: string
14
+
15
+ /** array of expressions to use for filtering. field expression for column will be injected as expression 0 in the resulting filter expression */
16
+ exprs: Expr[]
17
+ }
@@ -10,10 +10,10 @@ import querystring from "querystring"
10
10
  import { ExprUtils, Schema } from "@mwater/expressions"
11
11
  import * as ui from "./UIComponents"
12
12
  import * as formUtils from "@mwater/forms/lib/formUtils" // TODO requireing this directly because of bizarre backbone issue
13
- import { AssetQuestion, Form, FormDesign } from "@mwater/forms"
13
+ import { Form, FormDesign } from "@mwater/forms"
14
14
 
15
15
  export interface MWaterAddRelatedFormComponentProps {
16
- /** Entities or assets table id */
16
+ /** Entities table id */
17
17
  table: string
18
18
 
19
19
  apiUrl: string
@@ -33,7 +33,7 @@ interface MWaterAddRelatedFormComponentState {
33
33
  }
34
34
 
35
35
  // Link that when clicked popup up a modal window allowing user to select a form
36
- // with an Entity/Site question to the extraTables
36
+ // with an Site question to the extraTables
37
37
  export default class MWaterAddRelatedFormComponent extends React.Component<
38
38
  MWaterAddRelatedFormComponentProps,
39
39
  MWaterAddRelatedFormComponentState
@@ -91,7 +91,7 @@ export default class MWaterAddRelatedFormComponent extends React.Component<
91
91
  }
92
92
 
93
93
  interface AddRelatedFormModalComponentProps {
94
- /** Entities or assets table id */
94
+ /** Entities table id */
95
95
  table: string
96
96
 
97
97
  apiUrl: string
@@ -126,14 +126,19 @@ class AddRelatedFormModalComponent extends React.Component<
126
126
  }
127
127
 
128
128
  componentDidMount() {
129
- // Get all forms visible to user
129
+ // Get all forms visible to user that have _entity_types that include table
130
130
  const query: any = {}
131
- query.selector = JSON.stringify({ state: { $ne: "deleted" } })
131
+ query.selector = JSON.stringify({
132
+ state: { $ne: "deleted" },
133
+ _entity_types: { $in: [this.props.table.split(".")[1]] }
134
+ })
135
+ query.fields = JSON.stringify({ "_id": 1, "design.name": 1, "modified": 1, "created": 1 })
136
+
132
137
  if (this.props.client) {
133
138
  query.client = this.props.client
134
139
  }
135
140
 
136
- // Get list of all form names
141
+ // Get list of related forms
137
142
  return $.getJSON(this.props.apiUrl + "forms?" + querystring.stringify(query), (forms: Form[]) => {
138
143
  // Sort by modified.on desc but first by user
139
144
  forms = _.sortByOrder(
@@ -142,16 +147,6 @@ class AddRelatedFormModalComponent extends React.Component<
142
147
  ["desc", "desc"]
143
148
  )
144
149
 
145
- // Filter by Entity and Site questions of tableId type
146
- if (this.props.table.startsWith("entities.")) {
147
- forms = _.filter(forms, (form) => formUtils.findEntityQuestion(form.design, this.props.table.split(".")[1]))
148
- } else if (this.props.table.startsWith("assets:")) {
149
- const assetSystemId = parseInt(this.props.table.split(":")[1])
150
- forms = forms.filter((form) => {
151
- return formUtils.findAssetQuestion(form.design, assetSystemId) != null
152
- })
153
- }
154
-
155
150
  // Get _id, name, and description
156
151
  const items = _.map(forms, (form) => ({
157
152
  name: ExprUtils.localizeString(form.design.name, this.context.locale),
@@ -159,9 +154,9 @@ class AddRelatedFormModalComponent extends React.Component<
159
154
  onClick: this.props.onSelect.bind(null, "responses:" + form._id)
160
155
  }))
161
156
 
162
- return this.setState({ items })
163
- }).fail((xhr) => {
164
- return this.setState({ error: xhr.responseText })
157
+ this.setState({ items })
158
+ }).fail((xhr: any) => {
159
+ this.setState({ error: xhr.responseText })
165
160
  })
166
161
  }
167
162
 
@@ -0,0 +1,158 @@
1
+ import PropTypes from "prop-types"
2
+ import _ from "lodash"
3
+ import React, { createContext } from "react"
4
+ const R = React.createElement
5
+
6
+ import MWaterTableSelectComponent from "./MWaterTableSelectComponent"
7
+ import MWaterAddRelatedFormComponent from "./MWaterAddRelatedFormComponent"
8
+ import MWaterAddRelatedIndicatorComponent from "./MWaterAddRelatedIndicatorComponent"
9
+ import MWaterGlobalFiltersComponent from "./MWaterGlobalFiltersComponent"
10
+ import { DataSource, Schema, Section } from "@mwater/expressions"
11
+ import { CustomTableSelectComponentFactoryContext, CustomTableSelectComponentFactoryOptions, DecorateScalarExprTreeSectionChildrenContext, DecorateScalarExprTreeSectionChildrenOptions } from "@mwater/expressions-ui"
12
+ import { IsScalarExprTreeSectionInitiallyOpenContext, IsScalarExprTreeSectionMatchContext } from "@mwater/expressions-ui"
13
+ import { GlobalFilter } from "./GlobalFilter"
14
+
15
+
16
+ export interface GlobalFiltersElementFactoryProps {
17
+ schema: Schema
18
+ dataSource: DataSource
19
+ filterableTables: string[]
20
+ globalFilters?: GlobalFilter[]
21
+ onChange: (globalFilters: GlobalFilter[]) => void
22
+
23
+ /** If true, return null element if not applicable to filterableTables */
24
+ nullIfIrrelevant?: boolean
25
+ }
26
+
27
+ export type GlobalFiltersElementFactory = (props: GlobalFiltersElementFactoryProps) => React.ReactElement | null
28
+
29
+ export const GlobalFiltersElementFactoryContext = createContext<GlobalFiltersElementFactory | null>(null)
30
+
31
+
32
+ /**
33
+ * Creates several contexts to allow selecting of a table in an mWater-friendly way
34
+ * and several other context items
35
+ */
36
+ export default class MWaterContextComponent extends React.Component<{
37
+ apiUrl: string
38
+ client?: string
39
+ /** user id of logged in user */
40
+ user?: string
41
+ schema: Schema
42
+ /** Extra tables to load in schema. Forms are not loaded by default as they are too many */
43
+ extraTables?: string[]
44
+ /** Called when extra tables are changed and schema will be reloaded */
45
+ onExtraTablesChange?: (extraTables: string[]) => void
46
+ /** Override default add layer component. See AddLayerComponent for details */
47
+ addLayerElementFactory?: any
48
+ }> {
49
+ static childContextTypes = {
50
+ addLayerElementFactory: PropTypes.func, // Call with props of AddLayerComponent
51
+ }
52
+
53
+ createTableSelectElementFactory = (options: CustomTableSelectComponentFactoryOptions) => {
54
+ return (
55
+ <MWaterTableSelectComponent
56
+ apiUrl={this.props.apiUrl}
57
+ client={this.props.client}
58
+ schema={options.schema}
59
+ user={this.props.user}
60
+ table={options.value ?? undefined}
61
+ onChange={options.onChange}
62
+ extraTables={this.props.extraTables}
63
+ onExtraTablesChange={this.props.onExtraTablesChange}
64
+ filter={options.filter}
65
+ onFilterChange={options.onFilterChange}
66
+ />
67
+ )
68
+ }
69
+
70
+ getChildContext() {
71
+ const context: any = {}
72
+
73
+ if (this.props.addLayerElementFactory) {
74
+ context.addLayerElementFactory = this.props.addLayerElementFactory
75
+ }
76
+
77
+ return context
78
+ }
79
+
80
+ createGlobalFiltersElementFactory = (props: GlobalFiltersElementFactoryProps) => {
81
+ if (props.nullIfIrrelevant && !_.any(props.filterableTables, (t: string) => t.match(/^entities./))) {
82
+ return null
83
+ }
84
+
85
+ return <MWaterGlobalFiltersComponent {...props} />
86
+ }
87
+
88
+ isScalarExprTreeSectionMatch = (options: { tableId: string; section: Section; filter?: string }) => {
89
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
90
+ return true
91
+ }
92
+ return null
93
+ }
94
+
95
+ isScalarExprTreeSectionInitiallyOpen = (options: { tableId: string; section: Section; filter?: string }) => {
96
+ return false
97
+ }
98
+
99
+ decorateScalarExprTreeSectionChildren = (options: DecorateScalarExprTreeSectionChildrenOptions) => {
100
+ // If related forms section of entities table or assets table
101
+ if (options.tableId.match(/^entities\./) && options.section.id === "!related_forms") {
102
+ return R(
103
+ "div",
104
+ { key: "_add_related_form_parent" },
105
+ options.children,
106
+ R(MWaterAddRelatedFormComponent, {
107
+ key: "_add_related_form",
108
+ table: options.tableId,
109
+ apiUrl: this.props.apiUrl,
110
+ client: this.props.client,
111
+ user: this.props.user,
112
+ schema: this.props.schema,
113
+ onSelect: this.handleAddTable
114
+ })
115
+ )
116
+ }
117
+
118
+ // If indicators section of entities table
119
+ if (options.tableId.match(/^entities\./) && options.section.id === "!indicators") {
120
+ return R(
121
+ "div",
122
+ { key: "_add_related_indicator_parent" },
123
+ options.children,
124
+ R(MWaterAddRelatedIndicatorComponent, {
125
+ key: "_add_related_indicator",
126
+ table: options.tableId,
127
+ apiUrl: this.props.apiUrl,
128
+ client: this.props.client,
129
+ user: this.props.user,
130
+ schema: this.props.schema,
131
+ onSelect: this.handleAddTable,
132
+ filter: options.filter
133
+ })
134
+ )
135
+ } else {
136
+ return options.children
137
+ }
138
+ }
139
+
140
+ handleAddTable = (table: any) => {
141
+ const extraTables = _.union(this.props.extraTables || [], [table])
142
+ return this.props.onExtraTablesChange!(extraTables)
143
+ }
144
+
145
+ render() {
146
+ return <CustomTableSelectComponentFactoryContext.Provider value={this.createTableSelectElementFactory}>
147
+ <GlobalFiltersElementFactoryContext.Provider value={this.createGlobalFiltersElementFactory}>
148
+ <IsScalarExprTreeSectionMatchContext.Provider value={this.isScalarExprTreeSectionMatch}>
149
+ <IsScalarExprTreeSectionInitiallyOpenContext.Provider value={this.isScalarExprTreeSectionInitiallyOpen}>
150
+ <DecorateScalarExprTreeSectionChildrenContext.Provider value={this.decorateScalarExprTreeSectionChildren}>
151
+ {this.props.children}
152
+ </DecorateScalarExprTreeSectionChildrenContext.Provider>
153
+ </IsScalarExprTreeSectionInitiallyOpenContext.Provider>
154
+
155
+ </IsScalarExprTreeSectionMatchContext.Provider>
156
+ </GlobalFiltersElementFactoryContext.Provider> </CustomTableSelectComponentFactoryContext.Provider>
157
+ }
158
+ }
@@ -27,14 +27,19 @@ export const MWaterCustomTablesetListComponent = (props: {
27
27
  const [search, setSearch] = useState<string | null>("")
28
28
  const [extraTableNeeded, setExtraTableNeeded] = useState<string>()
29
29
 
30
+ const [showSystem, setShowSystem] = useState(false)
31
+
30
32
  // Get list of all tablesets
31
33
  useEffect(() => {
32
34
  fetch(`${props.apiUrl}custom_tablesets?client=${props.client || ""}`)
33
35
  .then((response) => response.json())
34
- .then((body) => {
36
+ .then((tablesets) => {
37
+ // Filter out non-normal
38
+ tablesets = tablesets.filter((ts: CustomTableset) => ts.type === "normal")
39
+
35
40
  // Put included ones first
36
41
  setTablesets(
37
- _.sortByAll(body, [
42
+ _.sortByAll(tablesets, [
38
43
  (ts) => (props.extraTables.some((t) => (t || "").startsWith(`custom.${ts.code}.`)) ? 0 : 1),
39
44
  (ts) => ExprUtils.localizeString(ts.design.name, props.locale)
40
45
  ])
@@ -117,10 +122,17 @@ export const MWaterCustomTablesetListComponent = (props: {
117
122
  )
118
123
  }
119
124
 
125
+ const visibleTablesets = tablesets.filter((ts) => (showSystem || !ts.design.system) && !ts.design.deprecated)
126
+
120
127
  return (
121
128
  <div>
122
129
  <TextInput value={search} onChange={setSearch} placeholder="Search..." />
123
- {tablesets.map((ts) => renderTableset(ts))}
130
+ {visibleTablesets.map((ts) => renderTableset(ts))}
131
+ <div>
132
+ <button className="btn btn-link btn-sm" onClick={() => setShowSystem(!showSystem)}>
133
+ {showSystem ? "Hide system tables" : "Show system tables"}
134
+ </button>
135
+ </div>
124
136
  </div>
125
137
  )
126
138
  }
@@ -137,5 +149,11 @@ interface CustomTableset {
137
149
  desc?: LocalizedString
138
150
 
139
151
  tables: Table[]
152
+
153
+ /** True if tableset is deprecated */
154
+ deprecated?: boolean
155
+
156
+ /** True if tableset is for system use and should only be visible to admins in the UI */
157
+ system?: boolean
140
158
  }
141
159
  }