@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,8 +1,7 @@
|
|
|
1
1
|
import _ from "lodash"
|
|
2
2
|
import React from "react"
|
|
3
|
-
const R = React.createElement
|
|
4
3
|
import { default as ReactSelect } from "react-select"
|
|
5
|
-
import { DataSource, ExprUtils, LocalizedString, Schema } from "@mwater/expressions"
|
|
4
|
+
import { DataSource, Expr, ExprUtils, LocalizedString, Schema } from "@mwater/expressions"
|
|
6
5
|
import { ExprCleaner } from "@mwater/expressions"
|
|
7
6
|
import TextLiteralComponent from "./TextLiteralComponent"
|
|
8
7
|
import DateExprComponent from "./DateExprComponent"
|
|
@@ -45,7 +44,7 @@ export interface QuickfiltersComponentProps {
|
|
|
45
44
|
|
|
46
45
|
/** Displays quick filters and allows their value to be modified */
|
|
47
46
|
export default class QuickfiltersComponent extends React.Component<QuickfiltersComponentProps> {
|
|
48
|
-
renderQuickfilter(item:
|
|
47
|
+
renderQuickfilter(item: Quickfilter, index: number) {
|
|
49
48
|
// Skip if merged
|
|
50
49
|
let onValueChange
|
|
51
50
|
if (item.merged) {
|
|
@@ -56,10 +55,12 @@ export default class QuickfiltersComponent extends React.Component<QuickfiltersC
|
|
|
56
55
|
let itemValue = values[index]
|
|
57
56
|
|
|
58
57
|
// Translate label
|
|
59
|
-
const label = this.props.translate?.(item.label) ?? item.label
|
|
58
|
+
const label = this.props.translate?.(item.label ?? "") ?? item.label ?? ""
|
|
59
|
+
|
|
60
|
+
const exprCleaner = new ExprCleaner(this.props.schema)
|
|
60
61
|
|
|
61
62
|
// Clean expression first
|
|
62
|
-
const expr =
|
|
63
|
+
const expr = exprCleaner.cleanExpr(item.expr)
|
|
63
64
|
|
|
64
65
|
// Do not render if nothing
|
|
65
66
|
if (!expr) {
|
|
@@ -72,6 +73,22 @@ export default class QuickfiltersComponent extends React.Component<QuickfiltersC
|
|
|
72
73
|
return null
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
// If this quickfilter is text or text[] and has subsequent merged quickfilters, gather their expressions
|
|
77
|
+
let exprsToPass: Expr[] = [expr]
|
|
78
|
+
if (["text", "text[]"].includes(type)) {
|
|
79
|
+
for (let i2 = index + 1; i2 < this.props.design.length; i2++) {
|
|
80
|
+
const nextItem = this.props.design[i2]
|
|
81
|
+
if (nextItem.merged) {
|
|
82
|
+
const cleaned = exprCleaner.cleanExpr(nextItem.expr)
|
|
83
|
+
if (cleaned) {
|
|
84
|
+
exprsToPass.push(cleaned)
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
break
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
75
92
|
// Determine if locked
|
|
76
93
|
const lock = _.find(this.props.locks || [], (lock) => _.isEqual(lock.expr, expr))
|
|
77
94
|
|
|
@@ -110,71 +127,71 @@ export default class QuickfiltersComponent extends React.Component<QuickfiltersC
|
|
|
110
127
|
const filters = (this.props.filters || []).concat(otherQuickfilterFilters)
|
|
111
128
|
|
|
112
129
|
if (["enum", "enumset"].includes(type)) {
|
|
113
|
-
return
|
|
114
|
-
key
|
|
115
|
-
label
|
|
116
|
-
schema
|
|
117
|
-
options
|
|
118
|
-
value
|
|
119
|
-
onValueChange
|
|
120
|
-
multi
|
|
121
|
-
|
|
130
|
+
return <EnumQuickfilterComponent
|
|
131
|
+
key={JSON.stringify(item)}
|
|
132
|
+
label={label}
|
|
133
|
+
schema={this.props.schema}
|
|
134
|
+
options={new ExprUtils(this.props.schema).getExprEnumValues(expr)!}
|
|
135
|
+
value={itemValue}
|
|
136
|
+
onValueChange={onValueChange}
|
|
137
|
+
multi={item.multi}
|
|
138
|
+
/>
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
if (type === "text") {
|
|
125
|
-
return
|
|
126
|
-
key
|
|
127
|
-
index
|
|
128
|
-
label
|
|
129
|
-
expr
|
|
130
|
-
schema
|
|
131
|
-
quickfiltersDataSource
|
|
132
|
-
value
|
|
133
|
-
onValueChange
|
|
134
|
-
filters
|
|
135
|
-
multi
|
|
136
|
-
|
|
142
|
+
return <TextQuickfilterComponent
|
|
143
|
+
key={JSON.stringify(item)}
|
|
144
|
+
index={index}
|
|
145
|
+
label={label}
|
|
146
|
+
expr={exprsToPass}
|
|
147
|
+
schema={this.props.schema}
|
|
148
|
+
quickfiltersDataSource={this.props.quickfiltersDataSource}
|
|
149
|
+
value={itemValue}
|
|
150
|
+
onValueChange={onValueChange}
|
|
151
|
+
filters={filters}
|
|
152
|
+
multi={item.multi}
|
|
153
|
+
/>
|
|
137
154
|
}
|
|
138
155
|
|
|
139
156
|
if (["date", "datetime"].includes(type)) {
|
|
140
|
-
return
|
|
141
|
-
key
|
|
142
|
-
label
|
|
143
|
-
expr
|
|
144
|
-
schema
|
|
145
|
-
value
|
|
146
|
-
onValueChange
|
|
147
|
-
|
|
157
|
+
return <DateQuickfilterComponent
|
|
158
|
+
key={JSON.stringify(item)}
|
|
159
|
+
label={label}
|
|
160
|
+
expr={expr}
|
|
161
|
+
schema={this.props.schema}
|
|
162
|
+
value={itemValue}
|
|
163
|
+
onValueChange={onValueChange}
|
|
164
|
+
/>
|
|
148
165
|
}
|
|
149
166
|
|
|
150
167
|
if (type === "id[]") {
|
|
151
|
-
return
|
|
152
|
-
key
|
|
153
|
-
index
|
|
154
|
-
label
|
|
155
|
-
expr
|
|
156
|
-
schema
|
|
157
|
-
dataSource
|
|
158
|
-
value
|
|
159
|
-
onValueChange
|
|
160
|
-
filters
|
|
161
|
-
multi
|
|
162
|
-
|
|
168
|
+
return <IdArrayQuickfilterComponent
|
|
169
|
+
key={JSON.stringify(item)}
|
|
170
|
+
index={index}
|
|
171
|
+
label={label}
|
|
172
|
+
expr={expr}
|
|
173
|
+
schema={this.props.schema}
|
|
174
|
+
dataSource={this.props.dataSource}
|
|
175
|
+
value={itemValue}
|
|
176
|
+
onValueChange={onValueChange}
|
|
177
|
+
filters={filters}
|
|
178
|
+
multi={item.multi}
|
|
179
|
+
/>
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
if (type === "text[]") {
|
|
166
|
-
return
|
|
167
|
-
key
|
|
168
|
-
index
|
|
169
|
-
label
|
|
170
|
-
expr
|
|
171
|
-
schema
|
|
172
|
-
quickfiltersDataSource
|
|
173
|
-
value
|
|
174
|
-
onValueChange
|
|
175
|
-
filters
|
|
176
|
-
multi
|
|
177
|
-
|
|
183
|
+
return <TextArrayQuickfilterComponent
|
|
184
|
+
key={JSON.stringify(item)}
|
|
185
|
+
index={index}
|
|
186
|
+
label={label}
|
|
187
|
+
expr={exprsToPass}
|
|
188
|
+
schema={this.props.schema}
|
|
189
|
+
quickfiltersDataSource={this.props.quickfiltersDataSource}
|
|
190
|
+
value={itemValue}
|
|
191
|
+
onValueChange={onValueChange}
|
|
192
|
+
filters={filters}
|
|
193
|
+
multi={item.multi}
|
|
194
|
+
/>
|
|
178
195
|
}
|
|
179
196
|
|
|
180
197
|
return null
|
|
@@ -185,23 +202,21 @@ export default class QuickfiltersComponent extends React.Component<QuickfiltersC
|
|
|
185
202
|
return null
|
|
186
203
|
}
|
|
187
204
|
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
style: {
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
style={{
|
|
192
208
|
borderTop: !this.props.hideTopBorder ? "solid 1px #E8E8E8" : undefined,
|
|
193
209
|
borderBottom: "solid 1px #E8E8E8",
|
|
194
210
|
padding: 5
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
: undefined
|
|
211
|
+
}}
|
|
212
|
+
>
|
|
213
|
+
{_.map(this.props.design, (item, i) => this.renderQuickfilter(item, i))}
|
|
214
|
+
{this.props.onHide ? (
|
|
215
|
+
<button className="btn btn-sm btn-link" onClick={this.props.onHide}>
|
|
216
|
+
<i className="fa fa-angle-double-up" />
|
|
217
|
+
</button>
|
|
218
|
+
) : undefined}
|
|
219
|
+
</div>
|
|
205
220
|
)
|
|
206
221
|
}
|
|
207
222
|
}
|
|
@@ -244,38 +259,38 @@ class EnumQuickfilterComponent extends React.Component<EnumQuickfilterComponentP
|
|
|
244
259
|
}
|
|
245
260
|
|
|
246
261
|
renderSingleSelect(options: any[]) {
|
|
247
|
-
return
|
|
248
|
-
placeholder
|
|
249
|
-
value
|
|
250
|
-
options
|
|
251
|
-
isClearable
|
|
252
|
-
onChange
|
|
262
|
+
return <ReactSelect
|
|
263
|
+
placeholder={T`All`}
|
|
264
|
+
value={_.findWhere(options, { value: this.props.value }) || null}
|
|
265
|
+
options={options}
|
|
266
|
+
isClearable={true}
|
|
267
|
+
onChange={(value: any) => {
|
|
253
268
|
if (this.props.onValueChange) {
|
|
254
269
|
return this.handleSingleChange(value?.value)
|
|
255
270
|
}
|
|
256
|
-
}
|
|
257
|
-
isDisabled
|
|
258
|
-
styles
|
|
271
|
+
}}
|
|
272
|
+
isDisabled={this.props.onValueChange == null}
|
|
273
|
+
styles={{
|
|
259
274
|
// Keep menu above fixed data table headers
|
|
260
275
|
menu: (style) => _.extend({}, style, { zIndex: 2000 })
|
|
261
|
-
}
|
|
262
|
-
|
|
276
|
+
}}
|
|
277
|
+
/>
|
|
263
278
|
}
|
|
264
279
|
|
|
265
280
|
renderMultiSelect(options: any[]) {
|
|
266
|
-
return
|
|
267
|
-
placeholder
|
|
268
|
-
value
|
|
269
|
-
isClearable
|
|
270
|
-
isMulti
|
|
271
|
-
options
|
|
272
|
-
onChange
|
|
273
|
-
isDisabled
|
|
274
|
-
styles
|
|
281
|
+
return <ReactSelect
|
|
282
|
+
placeholder={T`All`}
|
|
283
|
+
value={_.map(this.props.value, (v) => _.find(options, (o) => o.value === v))}
|
|
284
|
+
isClearable={true}
|
|
285
|
+
isMulti={true}
|
|
286
|
+
options={options}
|
|
287
|
+
onChange={this.props.onValueChange ? this.handleMultiChange : undefined}
|
|
288
|
+
isDisabled={this.props.onValueChange == null}
|
|
289
|
+
styles={{
|
|
275
290
|
// Keep menu above fixed data table headers
|
|
276
291
|
menu: (style) => _.extend({}, style, { zIndex: 2000 })
|
|
277
|
-
}
|
|
278
|
-
|
|
292
|
+
}}
|
|
293
|
+
/>
|
|
279
294
|
}
|
|
280
295
|
|
|
281
296
|
render() {
|
|
@@ -289,16 +304,14 @@ class EnumQuickfilterComponent extends React.Component<EnumQuickfilterComponentP
|
|
|
289
304
|
width = width ? width * 8 + 120 : 280
|
|
290
305
|
const minWidth = width > 280 || this.props.multi ? "280px" : `${width}px`
|
|
291
306
|
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
{
|
|
299
|
-
|
|
300
|
-
),
|
|
301
|
-
!this.props.onValueChange ? R("i", { className: "text-warning fa fa-fw fa-lock" }) : undefined
|
|
307
|
+
return (
|
|
308
|
+
<div style={{ display: "inline-block", paddingRight: 10 }}>
|
|
309
|
+
{this.props.label ? <span style={{ color: "gray" }}>{this.props.label + ":\u00a0"}</span> : undefined}
|
|
310
|
+
<div style={{ display: "inline-block", minWidth, verticalAlign: "middle" }}>
|
|
311
|
+
{this.props.multi ? this.renderMultiSelect(options) : this.renderSingleSelect(options)}
|
|
312
|
+
</div>
|
|
313
|
+
{!this.props.onValueChange ? <i className="text-warning fa fa-fw fa-lock" /> : undefined}
|
|
314
|
+
</div>
|
|
302
315
|
)
|
|
303
316
|
}
|
|
304
317
|
}
|
|
@@ -308,7 +321,7 @@ interface TextQuickfilterComponentProps {
|
|
|
308
321
|
schema: Schema
|
|
309
322
|
/** See QuickfiltersDataSource */
|
|
310
323
|
quickfiltersDataSource: QuickfiltersDataSource
|
|
311
|
-
expr:
|
|
324
|
+
expr: Expr[]
|
|
312
325
|
index: number
|
|
313
326
|
/** Current value of quickfilter (state of filter selected) */
|
|
314
327
|
value?: any
|
|
@@ -324,25 +337,23 @@ interface TextQuickfilterComponentProps {
|
|
|
324
337
|
// Quickfilter for a text value
|
|
325
338
|
class TextQuickfilterComponent extends React.Component<TextQuickfilterComponentProps> {
|
|
326
339
|
render() {
|
|
327
|
-
return
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
),
|
|
345
|
-
!this.props.onValueChange ? R("i", { className: "text-warning fa fa-fw fa-lock" }) : undefined
|
|
340
|
+
return (
|
|
341
|
+
<div style={{ display: "inline-block", paddingRight: 10 }}>
|
|
342
|
+
{this.props.label ? <span style={{ color: "gray" }}>{this.props.label + ":\u00a0"}</span> : undefined}
|
|
343
|
+
<div style={{ display: "inline-block", minWidth: "280px", verticalAlign: "middle" }}>
|
|
344
|
+
<TextLiteralComponent
|
|
345
|
+
value={this.props.value}
|
|
346
|
+
onChange={this.props.onValueChange}
|
|
347
|
+
schema={this.props.schema}
|
|
348
|
+
expr={this.props.expr}
|
|
349
|
+
index={this.props.index}
|
|
350
|
+
multi={this.props.multi}
|
|
351
|
+
quickfiltersDataSource={this.props.quickfiltersDataSource}
|
|
352
|
+
filters={this.props.filters}
|
|
353
|
+
/>
|
|
354
|
+
</div>
|
|
355
|
+
{!this.props.onValueChange ? <i className="text-warning fa fa-fw fa-lock" /> : undefined}
|
|
356
|
+
</div>
|
|
346
357
|
)
|
|
347
358
|
}
|
|
348
359
|
}
|
|
@@ -359,20 +370,18 @@ interface DateQuickfilterComponentProps {
|
|
|
359
370
|
// Quickfilter for a date value
|
|
360
371
|
class DateQuickfilterComponent extends React.Component<DateQuickfilterComponentProps> {
|
|
361
372
|
render() {
|
|
362
|
-
return
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
),
|
|
375
|
-
!this.props.onValueChange ? R("i", { className: "text-warning fa fa-fw fa-lock" }) : undefined
|
|
373
|
+
return (
|
|
374
|
+
<div style={{ display: "inline-block", paddingRight: 10 }}>
|
|
375
|
+
{this.props.label ? <span style={{ color: "gray" }}>{this.props.label + ":\u00a0"}</span> : undefined}
|
|
376
|
+
<div style={{ display: "inline-block", minWidth: "280px", verticalAlign: "middle" }}>
|
|
377
|
+
<DateExprComponent
|
|
378
|
+
datetime={new ExprUtils(this.props.schema).getExprType(this.props.expr) === "datetime"}
|
|
379
|
+
value={this.props.value}
|
|
380
|
+
onChange={this.props.onValueChange}
|
|
381
|
+
/>
|
|
382
|
+
</div>
|
|
383
|
+
{!this.props.onValueChange ? <i className="text-warning fa fa-fw fa-lock" /> : undefined}
|
|
384
|
+
</div>
|
|
376
385
|
)
|
|
377
386
|
}
|
|
378
387
|
}
|
|
@@ -382,7 +391,7 @@ interface TextArrayQuickfilterComponentProps {
|
|
|
382
391
|
schema: Schema
|
|
383
392
|
/** See QuickfiltersDataSource */
|
|
384
393
|
quickfiltersDataSource: QuickfiltersDataSource
|
|
385
|
-
expr:
|
|
394
|
+
expr: Expr[]
|
|
386
395
|
index: number
|
|
387
396
|
/** Current value of quickfilter (state of filter selected) */
|
|
388
397
|
value?: any
|
|
@@ -398,25 +407,23 @@ interface TextArrayQuickfilterComponentProps {
|
|
|
398
407
|
/** Quickfilter for a text value */
|
|
399
408
|
class TextArrayQuickfilterComponent extends React.Component<TextArrayQuickfilterComponentProps> {
|
|
400
409
|
render() {
|
|
401
|
-
return
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
),
|
|
419
|
-
!this.props.onValueChange ? R("i", { className: "text-warning fa fa-fw fa-lock" }) : undefined
|
|
410
|
+
return (
|
|
411
|
+
<div style={{ display: "inline-block", paddingRight: 10 }}>
|
|
412
|
+
{this.props.label ? <span style={{ color: "gray" }}>{this.props.label + ":\u00a0"}</span> : undefined}
|
|
413
|
+
<div style={{ display: "inline-block", minWidth: "280px", verticalAlign: "middle" }}>
|
|
414
|
+
<TextLiteralComponent
|
|
415
|
+
value={this.props.value}
|
|
416
|
+
onChange={this.props.onValueChange}
|
|
417
|
+
schema={this.props.schema}
|
|
418
|
+
expr={this.props.expr}
|
|
419
|
+
index={this.props.index}
|
|
420
|
+
multi={this.props.multi}
|
|
421
|
+
quickfiltersDataSource={this.props.quickfiltersDataSource}
|
|
422
|
+
filters={this.props.filters}
|
|
423
|
+
/>
|
|
424
|
+
</div>
|
|
425
|
+
{!this.props.onValueChange ? <i className="text-warning fa fa-fw fa-lock" /> : undefined}
|
|
426
|
+
</div>
|
|
420
427
|
)
|
|
421
428
|
}
|
|
422
429
|
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import _ from "lodash"
|
|
2
|
+
import React from "react"
|
|
3
|
+
import { default as AsyncReactSelect } from "react-select/async"
|
|
4
|
+
import { Expr, ExprCompiler, Schema } from "@mwater/expressions"
|
|
5
|
+
import { ExprUtils } from "@mwater/expressions"
|
|
6
|
+
import { JsonQLFilter } from "../JsonQLFilter"
|
|
7
|
+
import { QuickfiltersDataSource } from "./QuickfiltersDataSource"
|
|
8
|
+
|
|
9
|
+
export interface TextLiteralComponentProps {
|
|
10
|
+
value?: string | string[] | null
|
|
11
|
+
onChange?: (value: string | string[] | null) => void
|
|
12
|
+
schema: Schema
|
|
13
|
+
/** See QuickfiltersDataSource */
|
|
14
|
+
quickfiltersDataSource: QuickfiltersDataSource
|
|
15
|
+
/**
|
|
16
|
+
* One or more expressions whose values should be combined into a single option list.
|
|
17
|
+
* Each subsequent expression represents another quickfilter that is merged with this one.
|
|
18
|
+
* The first expression is the main quickfilter, and the subsequent expressions are merged with it.
|
|
19
|
+
*/
|
|
20
|
+
expr: Expr[]
|
|
21
|
+
index: number
|
|
22
|
+
/** true to display multiple values */
|
|
23
|
+
multi?: boolean
|
|
24
|
+
|
|
25
|
+
/** Filters to add to restrict quick filter data to */
|
|
26
|
+
filters?: JsonQLFilter[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Displays a combo box that allows selecting single or multiple text values from an expression
|
|
30
|
+
* The expression can be type `text` or `text[]`
|
|
31
|
+
*/
|
|
32
|
+
export default class TextLiteralComponent extends React.Component<TextLiteralComponentProps> {
|
|
33
|
+
handleSingleChange = (val: any) => {
|
|
34
|
+
const value = val ? val.value || null : null // Blank is null
|
|
35
|
+
return this.props.onChange?.(value)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
handleMultipleChange = (val: any) => {
|
|
39
|
+
const value = val ? _.pluck(val, "value") : []
|
|
40
|
+
|
|
41
|
+
if (value.length > 0) {
|
|
42
|
+
return this.props.onChange?.(value)
|
|
43
|
+
} else {
|
|
44
|
+
return this.props.onChange?.(null)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Load the options for the select. If multiple expressions are supplied, each
|
|
50
|
+
* is queried independently and the union of the results (unique values) is
|
|
51
|
+
* returned.
|
|
52
|
+
*/
|
|
53
|
+
getOptions = (input: string, cb: (rows: { value: string; label: string }[]) => void) => {
|
|
54
|
+
// Normalise to array so we can treat single and multiple uniformly
|
|
55
|
+
const exprs = this.props.expr
|
|
56
|
+
|
|
57
|
+
// Keep the unique set of text values that come back from each expression
|
|
58
|
+
const uniqueValues = new Set<string>()
|
|
59
|
+
|
|
60
|
+
// Early exit if no expressions
|
|
61
|
+
if (exprs.length === 0) {
|
|
62
|
+
cb([])
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let remaining = exprs.length
|
|
67
|
+
|
|
68
|
+
// Helper that is called after each async query completes
|
|
69
|
+
const maybeFinish = () => {
|
|
70
|
+
remaining -= 1
|
|
71
|
+
if (remaining === 0) {
|
|
72
|
+
const result = Array.from(uniqueValues).map((value) => ({ value, label: value }))
|
|
73
|
+
cb(result)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Execute a query for each expression
|
|
78
|
+
for (let i = 0; i < exprs.length; i++) {
|
|
79
|
+
const expr = exprs[i]
|
|
80
|
+
// Clone base filters for this expression so that each expression gets its own copy
|
|
81
|
+
const filters = (this.props.filters || []).slice()
|
|
82
|
+
|
|
83
|
+
const exprUtils = new ExprUtils(this.props.schema)
|
|
84
|
+
const exprType = exprUtils.getExprType(expr)
|
|
85
|
+
|
|
86
|
+
// Create query to get matches
|
|
87
|
+
const exprCompiler = new ExprCompiler(this.props.schema)
|
|
88
|
+
const exprTable = exprUtils.getExprTable(expr)
|
|
89
|
+
|
|
90
|
+
if (!exprTable) {
|
|
91
|
+
maybeFinish()
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Add filter for the input text depending on expression type
|
|
96
|
+
if (exprType === "text") {
|
|
97
|
+
if (input) {
|
|
98
|
+
filters.push({
|
|
99
|
+
table: exprTable,
|
|
100
|
+
jsonql: {
|
|
101
|
+
type: "op",
|
|
102
|
+
op: "~*",
|
|
103
|
+
exprs: [
|
|
104
|
+
exprCompiler.compileExpr({ expr, tableAlias: "{alias}" }),
|
|
105
|
+
escapeRegex(input) // Avoid _.escapeRegExp to prevent extra backslashes that Postgres dislikes
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
} else if (exprType === "text[]") {
|
|
111
|
+
if (input) {
|
|
112
|
+
filters.push({
|
|
113
|
+
table: "values",
|
|
114
|
+
jsonql: {
|
|
115
|
+
type: "op",
|
|
116
|
+
op: "~*",
|
|
117
|
+
exprs: [
|
|
118
|
+
{ type: "field", tableAlias: "{alias}", column: "value" },
|
|
119
|
+
"^" + escapeRegex(input) // Avoid _.escapeRegExp to prevent extra backslashes that Postgres dislikes
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// Unsupported type – skip this expression
|
|
126
|
+
maybeFinish()
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Execute the data source query for this expression
|
|
131
|
+
this.props.quickfiltersDataSource.getValues(
|
|
132
|
+
this.props.index + i, // Index of this quickfilter in the design
|
|
133
|
+
expr,
|
|
134
|
+
filters,
|
|
135
|
+
null,
|
|
136
|
+
250,
|
|
137
|
+
(err: any, values: any[] = []) => {
|
|
138
|
+
if (!err && values) {
|
|
139
|
+
// Filter out null / blank and add to unique set
|
|
140
|
+
_.filter(values, (v) => v).forEach((v) => uniqueValues.add(v))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
maybeFinish()
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
renderSingle() {
|
|
150
|
+
const currentValue = this.props.value ? { value: this.props.value, label: this.props.value } : null
|
|
151
|
+
|
|
152
|
+
return <AsyncReactSelect
|
|
153
|
+
key={JSON.stringify(this.props.filters)} // Include to force a change when filters change
|
|
154
|
+
placeholder={T`All`}
|
|
155
|
+
value={currentValue}
|
|
156
|
+
loadOptions={this.getOptions}
|
|
157
|
+
onChange={this.props.onChange ? this.handleSingleChange : undefined}
|
|
158
|
+
isClearable={true}
|
|
159
|
+
defaultOptions={true}
|
|
160
|
+
isDisabled={this.props.onChange == null}
|
|
161
|
+
noOptionsMessage={() => T`Type to search`}
|
|
162
|
+
styles={{
|
|
163
|
+
// Keep menu above fixed data table headers
|
|
164
|
+
menu: (style) => _.extend({}, style, { zIndex: 2000 })
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
renderMultiple() {
|
|
170
|
+
const currentValue = this.props.value ? _.map(this.props.value, (v) => ({ value: v, label: v })) : null
|
|
171
|
+
|
|
172
|
+
return <AsyncReactSelect
|
|
173
|
+
placeholder={T`All`}
|
|
174
|
+
value={currentValue}
|
|
175
|
+
key={JSON.stringify(this.props.filters)} // Include to force a change when filters change
|
|
176
|
+
isMulti={true}
|
|
177
|
+
loadOptions={this.getOptions}
|
|
178
|
+
defaultOptions={true}
|
|
179
|
+
onChange={this.props.onChange ? this.handleMultipleChange : undefined}
|
|
180
|
+
isClearable={true}
|
|
181
|
+
isDisabled={this.props.onChange == null}
|
|
182
|
+
noOptionsMessage={() => T`Type to search`}
|
|
183
|
+
styles={{
|
|
184
|
+
// Keep menu above fixed data table headers
|
|
185
|
+
menu: (style) => _.extend({}, style, { zIndex: 2000 })
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
render() {
|
|
191
|
+
return <div style={{ width: "100%" }}>{this.props.multi ? this.renderMultiple() : this.renderSingle()}</div>
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function escapeRegex(s: any) {
|
|
196
|
+
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")
|
|
197
|
+
}
|
|
@@ -123,12 +123,14 @@ class MapWidgetComponent extends React.Component<MapWidgetComponentProps, MapWid
|
|
|
123
123
|
const MapDesignerComponent = require("../maps/MapDesignerComponent").default
|
|
124
124
|
|
|
125
125
|
// Create editor
|
|
126
|
+
// Note: enableTranslations is false because translations are managed at the dashboard level
|
|
126
127
|
const editor = <MapDesignerComponent
|
|
127
128
|
schema={this.props.schema}
|
|
128
129
|
dataSource={this.props.dataSource}
|
|
129
130
|
design={this.state.editDesign}
|
|
130
131
|
onDesignChange={this.handleEditDesignChange}
|
|
131
132
|
filters={this.props.filters}
|
|
133
|
+
enableTranslations={false}
|
|
132
134
|
/>
|
|
133
135
|
|
|
134
136
|
// Create map (maxing out at half of width of screen)
|
|
@@ -196,8 +198,15 @@ class MapWidgetComponent extends React.Component<MapWidgetComponentProps, MapWid
|
|
|
196
198
|
|
|
197
199
|
const handleDesignChange = (d: any) => this.setState({ transientDesign: d })
|
|
198
200
|
|
|
201
|
+
// Only allow single click to edit if there are no layers
|
|
202
|
+
const handleClick = this.props.onDesignChange != null && this.state.editDesign === null && this.props.design.layerViews.length == 0 ? this.handleStartEditing : undefined
|
|
203
|
+
|
|
199
204
|
// Wrap in a simple widget
|
|
200
|
-
return
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
onClick={handleClick}
|
|
208
|
+
style={{ position: "relative", width: this.props.width }}
|
|
209
|
+
>
|
|
201
210
|
{this.props.onDesignChange != null ? this.renderEditor() : undefined}
|
|
202
211
|
<DropdownWidgetComponent
|
|
203
212
|
width={this.props.width}
|
|
@@ -207,5 +216,6 @@ class MapWidgetComponent extends React.Component<MapWidgetComponentProps, MapWid
|
|
|
207
216
|
{this.renderContent(this.state.transientDesign, handleDesignChange, this.props.width, this.props.height)}
|
|
208
217
|
</DropdownWidgetComponent>
|
|
209
218
|
</div>
|
|
219
|
+
)
|
|
210
220
|
}
|
|
211
221
|
}
|