@mwater/visualization 5.5.0 → 5.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ColorComponent.js +2 -2
- package/lib/MWaterContextComponent.d.ts +1 -1
- package/lib/MWaterGlobalFiltersComponent.d.ts +2 -2
- package/lib/MWaterGlobalFiltersComponent.js +11 -20
- package/lib/MWaterLoaderComponent.d.ts +4 -13
- package/lib/MWaterLoaderComponent.js +2 -11
- package/lib/TranslationsTabComponent.d.ts +34 -0
- package/lib/TranslationsTabComponent.js +256 -0
- package/lib/UndoStack.d.ts +2 -1
- package/lib/UndoStack.js +12 -6
- package/lib/dashboards/DashboardComponent.js +6 -5
- package/lib/dashboards/DashboardDesign.d.ts +1 -1
- package/lib/dashboards/ServerDashboardDataSource.d.ts +0 -1
- package/lib/dashboards/ServerDashboardDataSource.js +0 -25
- package/lib/dashboards/SettingsModalComponent.js +9 -233
- package/lib/datagrids/DatagridComponent.js +27 -2
- package/lib/datagrids/DatagridDesignerComponent.d.ts +2 -3
- package/lib/datagrids/DatagridDesignerComponent.js +108 -120
- package/lib/datagrids/DatagridViewComponent.js +33 -6
- package/lib/datagrids/OrderBysDesignerComponent.d.ts +7 -7
- package/lib/datagrids/OrderBysDesignerComponent.js +19 -28
- package/lib/index.css +45 -2
- package/lib/index.d.ts +5 -5
- package/lib/index.js +2 -3
- package/lib/layouts/blocks/BlocksDisplayComponent.d.ts +8 -1
- package/lib/layouts/blocks/BlocksDisplayComponent.js +46 -4
- package/lib/maps/BufferLayer.d.ts +0 -13
- package/lib/maps/BufferLayer.js +24 -237
- package/lib/maps/BufferLayerDesign.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.d.ts +1 -1
- package/lib/maps/BufferLayerDesignerComponent.js +2 -7
- package/lib/maps/ChoroplethLayer.d.ts +1 -16
- package/lib/maps/ChoroplethLayer.js +25 -358
- package/lib/maps/ChoroplethLayerDesign.d.ts +5 -2
- package/lib/maps/ChoroplethLayerDesigner.d.ts +10 -32
- package/lib/maps/ChoroplethLayerDesigner.js +58 -89
- package/lib/maps/ClusterLayer.d.ts +0 -9
- package/lib/maps/ClusterLayer.js +0 -250
- package/lib/maps/DirectMapDataSource.js +1 -48
- package/lib/maps/EditHoverOver.d.ts +4 -3
- package/lib/maps/EditHoverOver.js +3 -3
- package/lib/maps/GridLayer.d.ts +0 -15
- package/lib/maps/GridLayer.js +0 -212
- package/lib/maps/HoverContent.js +1 -1
- package/lib/maps/Layer.d.ts +1 -26
- package/lib/maps/Layer.js +0 -13
- package/lib/maps/LeafletMapComponent.js +10 -19
- package/lib/maps/MapComponent.d.ts +19 -35
- package/lib/maps/MapComponent.js +135 -77
- package/lib/maps/MapControlComponent.d.ts +4 -5
- package/lib/maps/MapControlComponent.js +5 -12
- package/lib/maps/MapDesign.d.ts +8 -0
- package/lib/maps/MapDesignerComponent.d.ts +2 -0
- package/lib/maps/MapDesignerComponent.js +7 -2
- package/lib/maps/MapLayerDataSource.d.ts +0 -4
- package/lib/maps/MapLayerViewDesignerComponent.d.ts +3 -1
- package/lib/maps/MapLayerViewDesignerComponent.js +5 -1
- package/lib/maps/MapLayersDesignerComponent.d.ts +2 -0
- package/lib/maps/MapLayersDesignerComponent.js +2 -1
- package/lib/maps/MapTranslationsTab.d.ts +15 -0
- package/lib/maps/MapTranslationsTab.js +47 -0
- package/lib/maps/MapUtils.d.ts +11 -0
- package/lib/maps/MapUtils.js +57 -1
- package/lib/maps/MapViewComponent.d.ts +1 -1
- package/lib/maps/MapViewComponent.js +1 -8
- package/lib/maps/MarkersLayer.d.ts +1 -14
- package/lib/maps/MarkersLayer.js +89 -254
- package/lib/maps/MarkersLayerDesign.d.ts +5 -1
- package/lib/maps/MarkersLayerDesignerComponent.d.ts +32 -57
- package/lib/maps/MarkersLayerDesignerComponent.js +158 -134
- package/lib/maps/ServerMapDataSource.d.ts +0 -1
- package/lib/maps/ServerMapDataSource.js +0 -25
- package/lib/maps/SwitchableTileUrlLayer.d.ts +0 -2
- package/lib/maps/SwitchableTileUrlLayer.js +0 -9
- package/lib/maps/TileUrlLayer.d.ts +0 -1
- package/lib/maps/TileUrlLayer.js +0 -5
- package/lib/maps/VectorMapViewComponent.js +13 -10
- package/lib/maps/symbols/font-awesome/asterisk.png +0 -0
- package/lib/maps/symbols/font-awesome/ban.png +0 -0
- package/lib/maps/symbols/font-awesome/beer.png +0 -0
- package/lib/maps/symbols/font-awesome/bell.png +0 -0
- package/lib/maps/symbols/font-awesome/bolt.png +0 -0
- package/lib/maps/symbols/font-awesome/building.png +0 -0
- package/lib/maps/symbols/font-awesome/bullseye.png +0 -0
- package/lib/maps/symbols/font-awesome/bus.png +0 -0
- package/lib/maps/symbols/font-awesome/caret-up.png +0 -0
- package/lib/maps/symbols/font-awesome/certificate.png +0 -0
- package/lib/maps/symbols/font-awesome/check-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/check.png +0 -0
- package/lib/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
- package/lib/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
- package/lib/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/lib/maps/symbols/font-awesome/cloud.png +0 -0
- package/lib/maps/symbols/font-awesome/comment.png +0 -0
- package/lib/maps/symbols/font-awesome/crosshairs.png +0 -0
- package/lib/maps/symbols/font-awesome/dot-circle-o.png +0 -0
- package/lib/maps/symbols/font-awesome/exclamation-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
- package/lib/maps/symbols/font-awesome/female.png +0 -0
- package/lib/maps/symbols/font-awesome/file.png +0 -0
- package/lib/maps/symbols/font-awesome/flag.png +0 -0
- package/lib/maps/symbols/font-awesome/flask.png +0 -0
- package/lib/maps/symbols/font-awesome/h-square.png +0 -0
- package/lib/maps/symbols/font-awesome/home.png +0 -0
- package/lib/maps/symbols/font-awesome/info-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/male.png +0 -0
- package/lib/maps/symbols/font-awesome/medkit.png +0 -0
- package/lib/maps/symbols/font-awesome/mobile.png +0 -0
- package/lib/maps/symbols/font-awesome/plus-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/plus-square.png +0 -0
- package/lib/maps/symbols/font-awesome/plus.png +0 -0
- package/lib/maps/symbols/font-awesome/square.png +0 -0
- package/lib/maps/symbols/font-awesome/star.png +0 -0
- package/lib/maps/symbols/font-awesome/thumbs-down.png +0 -0
- package/lib/maps/symbols/font-awesome/thumbs-up.png +0 -0
- package/lib/maps/symbols/font-awesome/ticket.png +0 -0
- package/lib/maps/symbols/font-awesome/times-circle.png +0 -0
- package/lib/maps/symbols/font-awesome/times.png +0 -0
- package/lib/maps/symbols/font-awesome/tint.png +0 -0
- package/lib/maps/symbols/font-awesome/tree.png +0 -0
- package/lib/maps/symbols/font-awesome/university.png +0 -0
- package/lib/maps/symbols/font-awesome/usd.png +0 -0
- package/lib/maps/symbols/font-awesome/user.png +0 -0
- package/lib/maps/symbols/font-awesome/users.png +0 -0
- package/lib/maps/symbols/font-awesome/wheelchair.png +0 -0
- package/lib/maps/symbols/sdf-ize.sh +93 -0
- package/lib/maps/vectorMaps.d.ts +6 -6
- package/lib/maps/vectorMaps.js +33 -45
- package/lib/mwater_table_selection/IndicatorsListComponent.d.ts +4 -2
- package/lib/mwater_table_selection/IndicatorsListComponent.js +103 -34
- package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.d.ts +18 -0
- package/lib/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.js +80 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.d.ts +26 -0
- package/lib/mwater_table_selection/MWaterCompleteTableSelectComponent.js +237 -51
- package/lib/mwater_table_selection/MWaterTableSelectComponent.d.ts +2 -2
- package/lib/mwater_table_selection/MWaterTableSelectComponent.js +9 -4
- package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.d.ts +19 -0
- package/lib/mwater_table_selection/MWaterWorkflowsSelectComponent.js +111 -0
- package/lib/quickfilter/QuickfiltersComponent.d.ts +3 -102
- package/lib/quickfilter/QuickfiltersComponent.js +53 -110
- package/lib/quickfilter/TextLiteralComponent.d.ts +23 -47
- package/lib/quickfilter/TextLiteralComponent.js +85 -82
- package/lib/widgets/MapWidget.js +6 -3
- package/lib/widgets/text/ExprItemEditorComponent.d.ts +3 -8
- package/lib/widgets/text/ExprItemEditorComponent.js +36 -33
- package/lib/widgets/text/ExprUpdateModalComponent.d.ts +1 -0
- package/package.json +3 -4
- package/src/ColorComponent.tsx +2 -2
- package/src/MWaterContextComponent.tsx +1 -1
- package/src/{MWaterGlobalFiltersComponent.ts → MWaterGlobalFiltersComponent.tsx} +32 -33
- package/src/{MWaterLoaderComponent.ts → MWaterLoaderComponent.tsx} +17 -18
- package/src/TranslationsTabComponent.tsx +429 -0
- package/src/UndoStack.ts +14 -6
- package/src/dashboards/DashboardComponent.tsx +6 -5
- package/src/dashboards/DashboardDesign.ts +1 -1
- package/src/dashboards/ServerDashboardDataSource.ts +0 -31
- package/src/dashboards/SettingsModalComponent.tsx +27 -383
- package/src/datagrids/DatagridComponent.tsx +36 -2
- package/src/datagrids/DatagridDesignerComponent.tsx +241 -229
- package/src/datagrids/DatagridViewComponent.tsx +44 -7
- package/src/datagrids/OrderBysDesignerComponent.tsx +61 -70
- package/src/index.css +45 -2
- package/src/index.ts +5 -11
- package/src/layouts/blocks/BlocksDisplayComponent.tsx +60 -5
- package/src/maps/BufferLayer.ts +30 -263
- package/src/maps/BufferLayerDesign.ts +1 -1
- package/src/maps/BufferLayerDesignerComponent.tsx +2 -7
- package/src/maps/ChoroplethLayer.ts +30 -394
- package/src/maps/ChoroplethLayerDesign.ts +5 -2
- package/src/maps/ChoroplethLayerDesigner.tsx +169 -165
- package/src/maps/ClusterLayer.ts +0 -274
- package/src/maps/DirectMapDataSource.ts +2 -61
- package/src/maps/EditHoverOver.tsx +9 -5
- package/src/maps/GridLayer.ts +0 -224
- package/src/maps/HoverContent.tsx +1 -1
- package/src/maps/Layer.ts +1 -35
- package/src/maps/LeafletMapComponent.tsx +10 -19
- package/src/maps/MapComponent.tsx +448 -0
- package/src/maps/MapControlComponent.tsx +41 -0
- package/src/maps/MapDesign.ts +6 -0
- package/src/maps/MapDesignerComponent.tsx +18 -1
- package/src/maps/MapLayerDataSource.ts +0 -5
- package/src/maps/MapLayerViewDesignerComponent.ts +9 -2
- package/src/maps/MapLayersDesignerComponent.ts +4 -1
- package/src/maps/MapTranslationsTab.tsx +53 -0
- package/src/maps/MapUtils.ts +61 -1
- package/src/maps/MapViewComponent.tsx +2 -8
- package/src/maps/MarkersLayer.ts +101 -275
- package/src/maps/MarkersLayerDesign.ts +7 -1
- package/src/maps/MarkersLayerDesignerComponent.tsx +436 -0
- package/src/maps/ServerMapDataSource.ts +0 -31
- package/src/maps/SwitchableTileUrlLayer.tsx +0 -11
- package/src/maps/TileUrlLayer.tsx +0 -6
- package/src/maps/VectorMapViewComponent.tsx +15 -15
- package/src/maps/symbols/font-awesome/asterisk.png +0 -0
- package/src/maps/symbols/font-awesome/ban.png +0 -0
- package/src/maps/symbols/font-awesome/beer.png +0 -0
- package/src/maps/symbols/font-awesome/bell.png +0 -0
- package/src/maps/symbols/font-awesome/bolt.png +0 -0
- package/src/maps/symbols/font-awesome/building.png +0 -0
- package/src/maps/symbols/font-awesome/bullseye.png +0 -0
- package/src/maps/symbols/font-awesome/bus.png +0 -0
- package/src/maps/symbols/font-awesome/caret-up.png +0 -0
- package/src/maps/symbols/font-awesome/certificate.png +0 -0
- package/src/maps/symbols/font-awesome/check-circle.png +0 -0
- package/src/maps/symbols/font-awesome/check.png +0 -0
- package/src/maps/symbols/font-awesome/chevron-circle-down.png +0 -0
- package/src/maps/symbols/font-awesome/chevron-circle-up.png +0 -0
- package/src/maps/symbols/font-awesome/cloud-rain.png +0 -0
- package/src/maps/symbols/font-awesome/cloud.png +0 -0
- package/src/maps/symbols/font-awesome/comment.png +0 -0
- package/src/maps/symbols/font-awesome/crosshairs.png +0 -0
- package/src/maps/symbols/font-awesome/dot-circle-o.png +0 -0
- package/src/maps/symbols/font-awesome/exclamation-circle.png +0 -0
- package/src/maps/symbols/font-awesome/exclamation-triangle.png +0 -0
- package/src/maps/symbols/font-awesome/female.png +0 -0
- package/src/maps/symbols/font-awesome/file.png +0 -0
- package/src/maps/symbols/font-awesome/flag.png +0 -0
- package/src/maps/symbols/font-awesome/flask.png +0 -0
- package/src/maps/symbols/font-awesome/h-square.png +0 -0
- package/src/maps/symbols/font-awesome/home.png +0 -0
- package/src/maps/symbols/font-awesome/info-circle.png +0 -0
- package/src/maps/symbols/font-awesome/male.png +0 -0
- package/src/maps/symbols/font-awesome/medkit.png +0 -0
- package/src/maps/symbols/font-awesome/mobile.png +0 -0
- package/src/maps/symbols/font-awesome/plus-circle.png +0 -0
- package/src/maps/symbols/font-awesome/plus-square.png +0 -0
- package/src/maps/symbols/font-awesome/plus.png +0 -0
- package/src/maps/symbols/font-awesome/square.png +0 -0
- package/src/maps/symbols/font-awesome/star.png +0 -0
- package/src/maps/symbols/font-awesome/thumbs-down.png +0 -0
- package/src/maps/symbols/font-awesome/thumbs-up.png +0 -0
- package/src/maps/symbols/font-awesome/ticket.png +0 -0
- package/src/maps/symbols/font-awesome/times-circle.png +0 -0
- package/src/maps/symbols/font-awesome/times.png +0 -0
- package/src/maps/symbols/font-awesome/tint.png +0 -0
- package/src/maps/symbols/font-awesome/tree.png +0 -0
- package/src/maps/symbols/font-awesome/university.png +0 -0
- package/src/maps/symbols/font-awesome/usd.png +0 -0
- package/src/maps/symbols/font-awesome/user.png +0 -0
- package/src/maps/symbols/font-awesome/users.png +0 -0
- package/src/maps/symbols/font-awesome/wheelchair.png +0 -0
- package/src/maps/symbols/sdf-ize.sh +93 -0
- package/src/maps/vectorMaps.tsx +32 -53
- package/src/mwater_table_selection/IndicatorsListComponent.tsx +165 -37
- package/src/mwater_table_selection/MWaterCalculatedDataSourcesListComponent.tsx +111 -0
- package/src/mwater_table_selection/MWaterCompleteTableSelectComponent.tsx +373 -37
- package/src/mwater_table_selection/MWaterTableSelectComponent.tsx +12 -8
- package/src/mwater_table_selection/MWaterWorkflowsSelectComponent.tsx +159 -0
- package/src/quickfilter/{QuickfiltersComponent.ts → QuickfiltersComponent.tsx} +165 -158
- package/src/quickfilter/TextLiteralComponent.tsx +197 -0
- package/src/widgets/MapWidget.tsx +11 -1
- package/src/widgets/text/ExprItemEditorComponent.tsx +83 -77
- package/src/widgets/text/ExprUpdateModalComponent.tsx +1 -0
- package/test/UndoStackTests.ts +52 -1
- package/.storybook/config.js +0 -7
- package/.storybook/head.html +0 -3
- package/.storybook/webpack.config.js +0 -15
- package/src/maps/BingLayer.ts +0 -146
- package/src/maps/MapComponent.ts +0 -312
- package/src/maps/MapControlComponent.ts +0 -46
- package/src/maps/MarkersLayerDesignerComponent.ts +0 -374
- package/src/maps/RasterMapViewComponent.ts +0 -345
- package/src/quickfilter/TextLiteralComponent.ts +0 -165
- package/stories/UpdateableComponent.js +0 -29
- package/stories/consoles.js +0 -202
- package/stories/dashboards.js +0 -217
- package/stories/datagridDesign.js +0 -114
- package/stories/datagrids.js +0 -69
- package/stories/dates.js +0 -80
- package/stories/exprcomponent.js +0 -43
- package/stories/index.js +0 -18
- package/stories/leaflet.js +0 -59
- package/stories/maps.js +0 -24
- package/stories/pivotChart.js +0 -235
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import _ from "lodash"
|
|
2
2
|
import React from "react"
|
|
3
|
-
import { default as TabbedComponent, TabbedComponentTab } from "@mwater/react-library/lib/TabbedComponent"
|
|
4
3
|
import * as uiComponents from "../UIComponents"
|
|
5
4
|
import { ExprUtils, Schema } from "@mwater/expressions"
|
|
6
5
|
import { MWaterCustomTablesetListComponent } from "./MWaterCustomTablesetListComponent"
|
|
@@ -10,6 +9,8 @@ import { FormsListComponent } from "./FormsListComponent"
|
|
|
10
9
|
import { IndicatorsListComponent } from "./IndicatorsListComponent"
|
|
11
10
|
import { IssuesListComponent } from "./IssuesListComponent"
|
|
12
11
|
import { MWaterAccountingSystemListComponent } from "./MWaterAccountingSystemListComponent"
|
|
12
|
+
import { MWaterCalculatedDataSourcesListComponent } from "./MWaterCalculatedDataSourcesListComponent"
|
|
13
|
+
import { MWaterWorkflowsSelectComponent } from "./MWaterWorkflowsSelectComponent"
|
|
13
14
|
|
|
14
15
|
const sitesOrder: { [table: string]: number } = {
|
|
15
16
|
"entities.water_point": 1,
|
|
@@ -45,15 +46,30 @@ interface MWaterCompleteTableSelectComponentProps {
|
|
|
45
46
|
onExtraTablesChange: any
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
interface Category {
|
|
50
|
+
id: string
|
|
51
|
+
name: string
|
|
52
|
+
description: string
|
|
53
|
+
icon: string
|
|
54
|
+
render: () => JSX.Element
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Allows selection of a table. Card-based layout with categories */
|
|
58
|
+
export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
59
|
+
MWaterCompleteTableSelectComponentProps,
|
|
60
|
+
{
|
|
61
|
+
selectedCategory: string | null
|
|
62
|
+
showLegacyAssets: boolean
|
|
63
|
+
searchText: string
|
|
64
|
+
}
|
|
65
|
+
> {
|
|
52
66
|
constructor(props: MWaterCompleteTableSelectComponentProps) {
|
|
53
67
|
super(props)
|
|
54
68
|
|
|
55
69
|
this.state = {
|
|
56
|
-
|
|
70
|
+
selectedCategory: null,
|
|
71
|
+
showLegacyAssets: false,
|
|
72
|
+
searchText: ""
|
|
57
73
|
}
|
|
58
74
|
}
|
|
59
75
|
|
|
@@ -62,12 +78,36 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
62
78
|
}
|
|
63
79
|
|
|
64
80
|
handleExtraTableRemove = (tableId: any) => {
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
81
|
+
const displayName = this.getExtraTableDisplayName(tableId)
|
|
82
|
+
if (!displayName) {
|
|
83
|
+
return
|
|
68
84
|
}
|
|
69
85
|
|
|
70
|
-
|
|
86
|
+
if (
|
|
87
|
+
confirm(
|
|
88
|
+
T`Remove ${displayName}? Any widgets that depend on it will no longer work properly.`
|
|
89
|
+
)
|
|
90
|
+
) {
|
|
91
|
+
// Set to null if current table matches (for wildcards, check if current table starts with prefix)
|
|
92
|
+
if (tableId.endsWith(".*")) {
|
|
93
|
+
const prefix = tableId.slice(0, -2)
|
|
94
|
+
if (this.props.table && this.props.table.startsWith(prefix + ".")) {
|
|
95
|
+
this.props.onChange(null)
|
|
96
|
+
}
|
|
97
|
+
} else if (this.props.table === tableId) {
|
|
98
|
+
this.props.onChange(null)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this.props.onExtraTablesChange(_.without(this.props.extraTables, tableId))
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
handleCategorySelect = (categoryId: string) => {
|
|
106
|
+
this.setState({ selectedCategory: categoryId })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
handleBackToCategories = () => {
|
|
110
|
+
this.setState({ selectedCategory: null, showLegacyAssets: false })
|
|
71
111
|
}
|
|
72
112
|
|
|
73
113
|
renderSites() {
|
|
@@ -147,6 +187,19 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
147
187
|
/>
|
|
148
188
|
}
|
|
149
189
|
|
|
190
|
+
renderWorkflows() {
|
|
191
|
+
return <MWaterWorkflowsSelectComponent
|
|
192
|
+
schema={this.props.schema}
|
|
193
|
+
client={this.props.client}
|
|
194
|
+
apiUrl={this.props.apiUrl}
|
|
195
|
+
user={this.props.user}
|
|
196
|
+
onChange={this.props.onChange}
|
|
197
|
+
extraTables={this.props.extraTables}
|
|
198
|
+
onExtraTableAdd={this.handleExtraTableAdd}
|
|
199
|
+
onExtraTableRemove={this.handleExtraTableRemove}
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
202
|
+
|
|
150
203
|
renderSweetSense() {
|
|
151
204
|
let sweetSenseTables = this.getSweetSenseTables()
|
|
152
205
|
|
|
@@ -238,7 +291,6 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
238
291
|
</div>
|
|
239
292
|
}
|
|
240
293
|
|
|
241
|
-
|
|
242
294
|
renderLegacyAssets() {
|
|
243
295
|
return <MWaterAssetSystemsListComponent
|
|
244
296
|
schema={this.props.schema}
|
|
@@ -253,6 +305,20 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
253
305
|
/>
|
|
254
306
|
}
|
|
255
307
|
|
|
308
|
+
renderCalculated() {
|
|
309
|
+
return <MWaterCalculatedDataSourcesListComponent
|
|
310
|
+
schema={this.props.schema}
|
|
311
|
+
client={this.props.client}
|
|
312
|
+
apiUrl={this.props.apiUrl}
|
|
313
|
+
user={this.props.user}
|
|
314
|
+
onChange={this.props.onChange}
|
|
315
|
+
extraTables={this.props.extraTables}
|
|
316
|
+
onExtraTableAdd={this.handleExtraTableAdd}
|
|
317
|
+
onExtraTableRemove={this.handleExtraTableRemove}
|
|
318
|
+
locale={T.locale}
|
|
319
|
+
/>
|
|
320
|
+
}
|
|
321
|
+
|
|
256
322
|
renderOther() {
|
|
257
323
|
let otherTables = _.filter(this.props.schema.getTables(), (table) => {
|
|
258
324
|
// Remove deprecated
|
|
@@ -300,6 +366,16 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
300
366
|
return false
|
|
301
367
|
}
|
|
302
368
|
|
|
369
|
+
// Remove calculated data sources
|
|
370
|
+
if (table.id.match(/^calculated:/)) {
|
|
371
|
+
return false
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Remove workflows
|
|
375
|
+
if (table.id.match(/^(workflows|workflow_events):/)) {
|
|
376
|
+
return false
|
|
377
|
+
}
|
|
378
|
+
|
|
303
379
|
return true
|
|
304
380
|
})
|
|
305
381
|
|
|
@@ -329,49 +405,309 @@ export default class MWaterCompleteTableSelectComponent extends React.Component<
|
|
|
329
405
|
})
|
|
330
406
|
}
|
|
331
407
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
408
|
+
/** Get all available categories */
|
|
409
|
+
getCategories(): Category[] {
|
|
410
|
+
const categories: Category[] = [
|
|
411
|
+
{
|
|
412
|
+
id: "sites",
|
|
413
|
+
name: T("Sites").toString(),
|
|
414
|
+
description: T("Water points, sanitation facilities, households, and other sites").toString(),
|
|
415
|
+
icon: "fa fa-map-marker",
|
|
416
|
+
render: () => this.renderSites()
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
id: "forms",
|
|
420
|
+
name: T("Surveys").toString(),
|
|
421
|
+
description: T("Data collected from survey forms").toString(),
|
|
422
|
+
icon: "fa fa-th-list",
|
|
423
|
+
render: () => this.renderForms()
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
id: "assets",
|
|
427
|
+
name: T("Assets").toString(),
|
|
428
|
+
description: T("Asset tracking and management").toString(),
|
|
429
|
+
icon: "fas fa-map-pin",
|
|
430
|
+
render: () => this.renderAssets()
|
|
431
|
+
},
|
|
338
432
|
{
|
|
339
433
|
id: "indicators",
|
|
340
|
-
|
|
341
|
-
|
|
434
|
+
name: T("Indicators").toString(),
|
|
435
|
+
description: T("Calculated indicators and metrics").toString(),
|
|
436
|
+
icon: "fa fa-check-circle",
|
|
437
|
+
render: () => this.renderIndicators()
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
id: "tablesets",
|
|
441
|
+
name: T("Tables").toString(),
|
|
442
|
+
description: T("Custom tables and datasets").toString(),
|
|
443
|
+
icon: "fa fa-table",
|
|
444
|
+
render: () => this.renderTablesets()
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
id: "calculated",
|
|
448
|
+
name: T("Calculated").toString(),
|
|
449
|
+
description: T("Calculated and derived data sources").toString(),
|
|
450
|
+
icon: "fa fa-cogs",
|
|
451
|
+
render: () => this.renderCalculated()
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
id: "accounting",
|
|
455
|
+
name: T("Accounting").toString(),
|
|
456
|
+
description: T("Financial and accounting data").toString(),
|
|
457
|
+
icon: "fa fa-calculator",
|
|
458
|
+
render: () => this.renderAccountingSystems()
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
id: "workflows",
|
|
462
|
+
name: T("Workflows").toString(),
|
|
463
|
+
description: T("Multi-step processes and workflows").toString(),
|
|
464
|
+
icon: "fa fa-project-diagram",
|
|
465
|
+
render: () => this.renderWorkflows()
|
|
342
466
|
},
|
|
343
467
|
{
|
|
344
468
|
id: "issues",
|
|
345
|
-
|
|
346
|
-
|
|
469
|
+
name: T("Issues").toString(),
|
|
470
|
+
description: T("Reported problems and issues").toString(),
|
|
471
|
+
icon: "fa fa-exclamation-circle",
|
|
472
|
+
render: () => this.renderIssues()
|
|
347
473
|
},
|
|
348
|
-
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
474
|
+
{
|
|
475
|
+
id: "metrics",
|
|
476
|
+
name: T("Metrics").toString(),
|
|
477
|
+
description: T("Performance metrics and KPIs").toString(),
|
|
478
|
+
icon: "fa fa-line-chart",
|
|
479
|
+
render: () => this.renderMetrics()
|
|
354
480
|
},
|
|
355
|
-
{
|
|
481
|
+
{
|
|
482
|
+
id: "other",
|
|
483
|
+
name: T("Advanced").toString(),
|
|
484
|
+
description: T("Other advanced data sources").toString(),
|
|
485
|
+
icon: "fa fa-ellipsis-h",
|
|
486
|
+
render: () => this.renderOther()
|
|
487
|
+
}
|
|
356
488
|
]
|
|
357
489
|
|
|
358
|
-
|
|
359
|
-
|
|
490
|
+
// // Add sensors if applicable
|
|
491
|
+
// const sweetSenseTables = this.getSweetSenseTables()
|
|
492
|
+
// if (sweetSenseTables.length > 0) {
|
|
493
|
+
// categories.splice(9, 0, {
|
|
494
|
+
// id: "sensors",
|
|
495
|
+
// name: T("Sensors").toString(),
|
|
496
|
+
// description: T("Sensor data and monitoring").toString(),
|
|
497
|
+
// icon: "fa fa-wifi",
|
|
498
|
+
// render: () => this.renderSweetSense()
|
|
499
|
+
// })
|
|
500
|
+
// }
|
|
501
|
+
|
|
502
|
+
return categories
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/** Render a single category card */
|
|
506
|
+
renderCategoryCard(category: Category) {
|
|
507
|
+
return (
|
|
508
|
+
<div
|
|
509
|
+
key={category.id}
|
|
510
|
+
className="card mb-2"
|
|
511
|
+
style={{
|
|
512
|
+
cursor: "pointer",
|
|
513
|
+
transition: "background-color 0.15s, border-color 0.15s"
|
|
514
|
+
}}
|
|
515
|
+
onMouseEnter={(e) => {
|
|
516
|
+
e.currentTarget.style.backgroundColor = "#f8f9fa"
|
|
517
|
+
e.currentTarget.style.borderColor = "#adb5bd"
|
|
518
|
+
}}
|
|
519
|
+
onMouseLeave={(e) => {
|
|
520
|
+
e.currentTarget.style.backgroundColor = ""
|
|
521
|
+
e.currentTarget.style.borderColor = ""
|
|
522
|
+
}}
|
|
523
|
+
onClick={() => this.handleCategorySelect(category.id)}
|
|
524
|
+
>
|
|
525
|
+
<div className="card-body d-flex align-items-center" style={{ padding: "0.75rem" }}>
|
|
526
|
+
<div style={{ fontSize: "1.75rem", width: "2.5rem", textAlign: "center", color: "#6c757d" }}>
|
|
527
|
+
<i className={category.icon} />
|
|
528
|
+
</div>
|
|
529
|
+
<div style={{ flex: 1, marginLeft: "0.75rem" }}>
|
|
530
|
+
<div style={{ fontWeight: 600, fontSize: "1rem", marginBottom: "0.15rem" }}>
|
|
531
|
+
{category.name}
|
|
532
|
+
</div>
|
|
533
|
+
<div className="text-muted" style={{ fontSize: "0.85rem" }}>
|
|
534
|
+
{category.description}
|
|
535
|
+
</div>
|
|
536
|
+
</div>
|
|
537
|
+
<div style={{ color: "#adb5bd", fontSize: "1.1rem" }}>
|
|
538
|
+
<i className="fa fa-chevron-right" />
|
|
539
|
+
</div>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
)
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/** Get display name for an extra table (handles wildcards) */
|
|
546
|
+
getExtraTableDisplayName(tableId: string): string | null {
|
|
547
|
+
// Check if it's a wildcard pattern
|
|
548
|
+
if (tableId.endsWith(".*")) {
|
|
549
|
+
// Find first matching table
|
|
550
|
+
const prefix = tableId.slice(0, -2) // Remove .*
|
|
551
|
+
const matchingTable = this.props.schema.getTables().find(t => t.id.startsWith(prefix + "."))
|
|
552
|
+
|
|
553
|
+
if (matchingTable) {
|
|
554
|
+
const fullName = ExprUtils.localizeString(matchingTable.name, T.locale)
|
|
555
|
+
// Split by " > " and take first part
|
|
556
|
+
const parts = fullName.split(" > ")
|
|
557
|
+
return parts[0]
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Fallback to showing the pattern
|
|
561
|
+
return tableId
|
|
360
562
|
}
|
|
563
|
+
|
|
564
|
+
// Regular table
|
|
565
|
+
const table = this.props.schema.getTable(tableId)
|
|
566
|
+
if (!table) {
|
|
567
|
+
return null
|
|
568
|
+
}
|
|
569
|
+
return ExprUtils.localizeString(table.name, T.locale)
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/** Render the currently included extra tables section */
|
|
573
|
+
renderExtraTables() {
|
|
574
|
+
if (!this.props.extraTables || this.props.extraTables.length === 0) {
|
|
575
|
+
return null
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return (
|
|
579
|
+
<div className="mb-3 pb-2" style={{ borderBottom: "1px solid #dee2e6" }}>
|
|
580
|
+
<span className="text-muted me-2" style={{ fontSize: "0.9rem" }}>
|
|
581
|
+
{T`Currently Included`}:
|
|
582
|
+
</span>
|
|
583
|
+
{this.props.extraTables.map((tableId: string) => {
|
|
584
|
+
const displayName = this.getExtraTableDisplayName(tableId)
|
|
585
|
+
if (!displayName) {
|
|
586
|
+
return null
|
|
587
|
+
}
|
|
588
|
+
return (
|
|
589
|
+
<span
|
|
590
|
+
key={tableId}
|
|
591
|
+
className="d-inline-flex align-items-center me-2 px-2 py-1 bg-light border rounded"
|
|
592
|
+
style={{ fontSize: "0.85rem" }}
|
|
593
|
+
>
|
|
594
|
+
<span>{displayName}</span>
|
|
595
|
+
<button
|
|
596
|
+
className="btn btn-link btn-sm p-0 ms-1"
|
|
597
|
+
style={{ fontSize: "0.9rem", color: "#6c757d" }}
|
|
598
|
+
onClick={(e) => {
|
|
599
|
+
e.stopPropagation()
|
|
600
|
+
this.handleExtraTableRemove(tableId)
|
|
601
|
+
}}
|
|
602
|
+
>
|
|
603
|
+
<i className="fa fa-times" />
|
|
604
|
+
</button>
|
|
605
|
+
</span>
|
|
606
|
+
)
|
|
607
|
+
})}
|
|
608
|
+
</div>
|
|
609
|
+
)
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/** Render the landing page with all categories */
|
|
613
|
+
renderLandingPage() {
|
|
614
|
+
const categories = this.getCategories()
|
|
615
|
+
|
|
616
|
+
// Filter by search text
|
|
617
|
+
const filteredCategories = this.state.searchText
|
|
618
|
+
? categories.filter((cat) => {
|
|
619
|
+
const searchLower = this.state.searchText.toLowerCase()
|
|
620
|
+
return (
|
|
621
|
+
cat.name.toLowerCase().includes(searchLower) ||
|
|
622
|
+
cat.description.toLowerCase().includes(searchLower)
|
|
623
|
+
)
|
|
624
|
+
})
|
|
625
|
+
: categories
|
|
626
|
+
|
|
627
|
+
return (
|
|
628
|
+
<div>
|
|
629
|
+
<div className="text-muted mb-3">
|
|
630
|
+
{T`Select a data source category to browse available tables and datasets.`}
|
|
631
|
+
</div>
|
|
632
|
+
|
|
633
|
+
{/* Search box */}
|
|
634
|
+
<div className="mb-3 position-relative">
|
|
635
|
+
<i className="fa fa-search position-absolute" style={{ left: "0.75rem", top: "50%", transform: "translateY(-50%)", color: "#6c757d" }} />
|
|
636
|
+
<input
|
|
637
|
+
type="text"
|
|
638
|
+
className="form-control"
|
|
639
|
+
style={{ paddingLeft: "2.5rem" }}
|
|
640
|
+
placeholder={T("Search categories...").toString()}
|
|
641
|
+
value={this.state.searchText}
|
|
642
|
+
onChange={(e) => this.setState({ searchText: e.target.value })}
|
|
643
|
+
ref={(c: HTMLInputElement | null) => {
|
|
644
|
+
if (c) {
|
|
645
|
+
c.focus()
|
|
646
|
+
}
|
|
647
|
+
}}
|
|
648
|
+
/>
|
|
649
|
+
</div>
|
|
650
|
+
|
|
651
|
+
{/* Extra tables section */}
|
|
652
|
+
{this.renderExtraTables()}
|
|
653
|
+
|
|
654
|
+
{/* Category cards grid */}
|
|
655
|
+
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.5rem" }}>
|
|
656
|
+
{filteredCategories.map((category) => this.renderCategoryCard(category))}
|
|
657
|
+
</div>
|
|
658
|
+
|
|
659
|
+
{filteredCategories.length === 0 && this.state.searchText && (
|
|
660
|
+
<div className="text-center text-muted mt-4">
|
|
661
|
+
{T`No categories match your search.`}
|
|
662
|
+
</div>
|
|
663
|
+
)}
|
|
664
|
+
</div>
|
|
665
|
+
)
|
|
666
|
+
}
|
|
361
667
|
|
|
362
|
-
|
|
668
|
+
/** Render a specific category view */
|
|
669
|
+
renderCategoryView() {
|
|
670
|
+
const categories = this.getCategories()
|
|
671
|
+
const category = categories.find((c) => c.id === this.state.selectedCategory)
|
|
672
|
+
|
|
673
|
+
if (!category) {
|
|
674
|
+
return null
|
|
675
|
+
}
|
|
363
676
|
|
|
364
677
|
return (
|
|
365
678
|
<div>
|
|
366
|
-
|
|
367
|
-
|
|
679
|
+
{/* Back button */}
|
|
680
|
+
<div className="mb-3">
|
|
681
|
+
<button
|
|
682
|
+
className="btn btn-link p-0"
|
|
683
|
+
style={{ textDecoration: "none" }}
|
|
684
|
+
onClick={this.handleBackToCategories}
|
|
685
|
+
>
|
|
686
|
+
<i className="fa fa-arrow-left me-2" />
|
|
687
|
+
{T`Back to All Data Sources`}
|
|
688
|
+
</button>
|
|
368
689
|
</div>
|
|
369
690
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
691
|
+
{/* Category title */}
|
|
692
|
+
<h5 className="mb-3">
|
|
693
|
+
<i className={`${category.icon} me-2 text-muted`} />
|
|
694
|
+
{category.name}
|
|
695
|
+
</h5>
|
|
696
|
+
|
|
697
|
+
{/* Category content */}
|
|
698
|
+
{category.render()}
|
|
699
|
+
</div>
|
|
700
|
+
)
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
render() {
|
|
704
|
+
return (
|
|
705
|
+
<div style={{ height: "65vh", overflowY: "auto" }}>
|
|
706
|
+
{this.state.selectedCategory === null
|
|
707
|
+
? this.renderLandingPage()
|
|
708
|
+
: this.renderCategoryView()}
|
|
374
709
|
</div>
|
|
375
710
|
)
|
|
376
711
|
}
|
|
377
712
|
}
|
|
713
|
+
|
|
@@ -18,8 +18,8 @@ export interface MWaterTableSelectComponentProps {
|
|
|
18
18
|
table?: string
|
|
19
19
|
/** Called with table selected */
|
|
20
20
|
onChange: (table: string | null) => void
|
|
21
|
-
extraTables
|
|
22
|
-
onExtraTablesChange
|
|
21
|
+
extraTables?: string[]
|
|
22
|
+
onExtraTablesChange?: (tables: string[]) => void
|
|
23
23
|
/** Can also perform filtering for some types. Include these props to enable this */
|
|
24
24
|
filter?: any
|
|
25
25
|
onFilterChange?: (filter: any) => void
|
|
@@ -94,11 +94,15 @@ export default class MWaterTableSelectComponent extends React.Component<
|
|
|
94
94
|
handleTableChange = (tableId: string | null) => {
|
|
95
95
|
// If not part of extra tables, add it and wait for new schema
|
|
96
96
|
if (tableId && !this.props.schema.getTable(tableId)) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
if (this.props.onExtraTablesChange) {
|
|
98
|
+
this.setState({ pendingExtraTable: tableId }, () => {
|
|
99
|
+
this.props.onExtraTablesChange!(_.union(this.props.extraTables || [], [tableId]))
|
|
100
|
+
})
|
|
101
|
+
} else {
|
|
102
|
+
alert(T`Cannot add new tables.`)
|
|
103
|
+
}
|
|
100
104
|
} else {
|
|
101
|
-
|
|
105
|
+
this.handleChange(tableId)
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
108
|
|
|
@@ -166,8 +170,8 @@ interface EditModeTableSelectComponentProps {
|
|
|
166
170
|
table?: string
|
|
167
171
|
/** Called with table selected */
|
|
168
172
|
onChange: (table: string | null) => void
|
|
169
|
-
extraTables
|
|
170
|
-
onExtraTablesChange
|
|
173
|
+
extraTables?: string[]
|
|
174
|
+
onExtraTablesChange?: (tables: string[]) => void
|
|
171
175
|
}
|
|
172
176
|
|
|
173
177
|
interface EditModeTableSelectComponentState {
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import _ from "lodash"
|
|
2
|
+
import $ from "jquery"
|
|
3
|
+
import React, { useState, useEffect } from "react"
|
|
4
|
+
import querystring from "querystring"
|
|
5
|
+
import * as uiComponents from "../UIComponents"
|
|
6
|
+
import { ExprUtils, Schema } from "@mwater/expressions"
|
|
7
|
+
import { WorkflowType } from "@mwater/common/lib/tables/workflow_types"
|
|
8
|
+
|
|
9
|
+
interface MWaterWorkflowsSelectComponentProps {
|
|
10
|
+
/** Url to hit api */
|
|
11
|
+
apiUrl: string
|
|
12
|
+
/** Optional client */
|
|
13
|
+
client?: string
|
|
14
|
+
schema: Schema
|
|
15
|
+
/** User id */
|
|
16
|
+
user?: string
|
|
17
|
+
/** Called with table selected */
|
|
18
|
+
onChange: (tableId: string) => void
|
|
19
|
+
extraTables: string[]
|
|
20
|
+
onExtraTableAdd: (tableId: string) => void
|
|
21
|
+
onExtraTableRemove: (tableId: string) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface WorkflowTypeItem {
|
|
25
|
+
id: string
|
|
26
|
+
name: string
|
|
27
|
+
desc?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Searchable list of workflow types */
|
|
31
|
+
export function MWaterWorkflowsSelectComponent(props: MWaterWorkflowsSelectComponentProps) {
|
|
32
|
+
const [workflowTypes, setWorkflowTypes] = useState<WorkflowTypeItem[] | null>(null)
|
|
33
|
+
const [search, setSearch] = useState("")
|
|
34
|
+
const [error, setError] = useState<string | null>(null)
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
// Get names and basic of workflow types
|
|
38
|
+
const query: any = {}
|
|
39
|
+
query.fields = JSON.stringify({
|
|
40
|
+
name: 1,
|
|
41
|
+
description: 1,
|
|
42
|
+
roles: 1,
|
|
43
|
+
_created_by: 1,
|
|
44
|
+
_modified_on: 1
|
|
45
|
+
})
|
|
46
|
+
query.client = props.client
|
|
47
|
+
|
|
48
|
+
// Get list of all workflow types
|
|
49
|
+
$.getJSON(props.apiUrl + "workflow_types?" + querystring.stringify(query), (types: WorkflowType[]) => {
|
|
50
|
+
// Sort by included first, then user-created, then by name
|
|
51
|
+
types = _.sortByOrder(
|
|
52
|
+
types,
|
|
53
|
+
[
|
|
54
|
+
(type: WorkflowType) => ((props.extraTables || []).includes("workflows:" + type._id) ? 0 : 1),
|
|
55
|
+
(type: WorkflowType) => (type._created_by === props.user ? 0 : 1),
|
|
56
|
+
(type: WorkflowType) => ExprUtils.localizeString(type.name, T.locale) || T`Untitled Workflow Type`
|
|
57
|
+
],
|
|
58
|
+
["asc", "asc", "asc"]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
setWorkflowTypes(
|
|
62
|
+
_.map(types, (type) => ({
|
|
63
|
+
id: type._id,
|
|
64
|
+
name: ExprUtils.localizeString(type.name, T.locale) || T`Untitled Workflow Type`,
|
|
65
|
+
desc: ExprUtils.localizeString(type.description, T.locale)
|
|
66
|
+
}))
|
|
67
|
+
)
|
|
68
|
+
}).fail((xhr: any) => {
|
|
69
|
+
setError(xhr.responseText)
|
|
70
|
+
})
|
|
71
|
+
}, [props.apiUrl, props.client, props.user, props.extraTables])
|
|
72
|
+
|
|
73
|
+
const handleTableRemove = (table: WorkflowTypeItem) => {
|
|
74
|
+
if (
|
|
75
|
+
confirm(
|
|
76
|
+
T`Remove ${table.name}? Any widgets that depend on it will no longer work properly.`
|
|
77
|
+
)
|
|
78
|
+
) {
|
|
79
|
+
props.onExtraTableRemove(`workflows:${table.id}`)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (error) {
|
|
84
|
+
return <div className="alert alert-danger">{error}</div>
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Filter workflow types by search
|
|
88
|
+
let filteredWorkflowTypes: WorkflowTypeItem[] | null = workflowTypes
|
|
89
|
+
if (search && workflowTypes) {
|
|
90
|
+
const escapeRegExp = (s: string) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")
|
|
91
|
+
const searchStringRegExp = new RegExp(escapeRegExp(search), "i")
|
|
92
|
+
filteredWorkflowTypes = _.filter(workflowTypes, (type) => type.name.match(searchStringRegExp))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Remove if already included
|
|
96
|
+
filteredWorkflowTypes = _.filter(
|
|
97
|
+
filteredWorkflowTypes || [],
|
|
98
|
+
(wt) => !(props.extraTables || []).includes(`workflows:${wt.id}`)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
// Get included workflow tables from schema
|
|
102
|
+
let includedTables = _.filter(
|
|
103
|
+
props.schema.getTables(),
|
|
104
|
+
(table) => (table.id.match(/^workflows:/) || table.id.match(/^workflow_events:/)) && !table.deprecated
|
|
105
|
+
)
|
|
106
|
+
includedTables = _.sortBy(includedTables, (t) => t.name.en)
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div>
|
|
110
|
+
<label>{T`Included Workflows:`}</label>
|
|
111
|
+
{includedTables.length > 0 ? (
|
|
112
|
+
<uiComponents.OptionListComponent
|
|
113
|
+
items={_.map(includedTables, (table) => {
|
|
114
|
+
return {
|
|
115
|
+
name: ExprUtils.localizeString(table.name, T.locale),
|
|
116
|
+
desc: ExprUtils.localizeString(table.desc, T.locale),
|
|
117
|
+
onClick: () => props.onChange(table.id),
|
|
118
|
+
onRemove: () => handleTableRemove({ id: table.id.replace(/^workflows:/, ""), name: ExprUtils.localizeString(table.name, T.locale) })
|
|
119
|
+
}
|
|
120
|
+
})}
|
|
121
|
+
/>
|
|
122
|
+
) : (
|
|
123
|
+
<div>{T`None`}</div>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
<br />
|
|
127
|
+
|
|
128
|
+
<label>{T`All Workflows:`}</label>
|
|
129
|
+
{!workflowTypes || workflowTypes.length === 0 ? (
|
|
130
|
+
<div className="alert alert-info">
|
|
131
|
+
<i className="fa fa-spinner fa-spin" />
|
|
132
|
+
{T`Loading...`}
|
|
133
|
+
</div>
|
|
134
|
+
) : (
|
|
135
|
+
<>
|
|
136
|
+
<input
|
|
137
|
+
type="text"
|
|
138
|
+
className="form-control form-control-sm"
|
|
139
|
+
placeholder={T`Search...`}
|
|
140
|
+
key="search"
|
|
141
|
+
autoFocus
|
|
142
|
+
style={{ maxWidth: "20em", marginBottom: 10 }}
|
|
143
|
+
value={search}
|
|
144
|
+
onChange={(ev) => setSearch(ev.target.value)}
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
<uiComponents.OptionListComponent
|
|
148
|
+
items={_.map(filteredWorkflowTypes, (workflowType) => ({
|
|
149
|
+
name: workflowType.name,
|
|
150
|
+
desc: workflowType.desc,
|
|
151
|
+
onClick: () => props.onChange("workflows:" + workflowType.id)
|
|
152
|
+
}))}
|
|
153
|
+
/>
|
|
154
|
+
</>
|
|
155
|
+
)}
|
|
156
|
+
</div>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|