@mwater/visualization 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/lib/MWaterAddRelatedFormComponent.d.ts +1 -1
  2. package/lib/MWaterAddRelatedFormComponent.js +10 -17
  3. package/lib/MWaterContextComponent.d.ts +17 -7
  4. package/lib/MWaterContextComponent.js +51 -70
  5. package/lib/MWaterLoaderComponent.d.ts +2 -2
  6. package/lib/MWaterLoaderComponent.js +1 -1
  7. package/lib/MWaterTableSelectComponent.d.ts +0 -1
  8. package/lib/MWaterTableSelectComponent.js +20 -41
  9. package/lib/axes/RangesComponent.d.ts +12 -6
  10. package/lib/axes/RangesComponent.js +21 -10
  11. package/lib/dashboards/DashboardComponent.d.ts +1 -9
  12. package/lib/dashboards/DashboardComponent.js +16 -27
  13. package/lib/dashboards/ServerDashboardDataSource.d.ts +1 -0
  14. package/lib/dashboards/ServerDashboardDataSource.js +3 -0
  15. package/lib/datagrids/DatagridComponent.d.ts +10 -4
  16. package/lib/datagrids/DatagridComponent.js +34 -6
  17. package/lib/datagrids/DatagridDataSource.d.ts +1 -0
  18. package/lib/datagrids/DatagridDataSource.js +3 -0
  19. package/lib/datagrids/DatagridDesign.d.ts +2 -0
  20. package/lib/datagrids/DatagridDesignerComponent.js +3 -2
  21. package/lib/datagrids/DatagridViewComponent.d.ts +2 -0
  22. package/lib/datagrids/DatagridViewComponent.js +4 -3
  23. package/lib/datagrids/DirectDatagridDataSource.d.ts +1 -0
  24. package/lib/datagrids/DirectDatagridDataSource.js +26 -0
  25. package/lib/datagrids/LabeledExprGenerator.js +15 -0
  26. package/lib/datagrids/ServerDatagridDataSource.d.ts +1 -0
  27. package/lib/datagrids/ServerDatagridDataSource.js +15 -0
  28. package/lib/dayjs.d.ts +2 -0
  29. package/lib/dayjs.js +9 -0
  30. package/lib/index.d.ts +0 -1
  31. package/lib/index.js +2 -4
  32. package/lib/languages.js +5 -0
  33. package/lib/layouts/blocks/BlocksDisplayComponent.js +2 -2
  34. package/lib/layouts/grid/LegoLayoutEngine.d.ts +1 -1
  35. package/lib/maps/BufferLayerDesignerComponent.js +2 -2
  36. package/lib/maps/ChoroplethLayerDesigner.js +2 -2
  37. package/lib/maps/ClusterLayerDesignerComponent.js +2 -2
  38. package/lib/maps/DetailLevelSelectComponent.d.ts +1 -93
  39. package/lib/maps/DirectMapDataSource.js +1 -2
  40. package/lib/maps/GridLayerDesigner.js +2 -2
  41. package/lib/maps/Layer.js +7 -18
  42. package/lib/maps/MapComponent.js +1 -1
  43. package/lib/maps/MapDesignerComponent.d.ts +1 -12
  44. package/lib/maps/MapDesignerComponent.js +5 -12
  45. package/lib/maps/MarkersLayerDesignerComponent.js +2 -2
  46. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -1
  47. package/lib/maps/PopupFilterJoinsUtils.js +4 -3
  48. package/lib/maps/RegionSelectComponent.d.ts +1 -33
  49. package/lib/maps/UtfGridLayer.js +1 -1
  50. package/lib/maps/VectorMapViewComponent.js +21 -29
  51. package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -186
  52. package/lib/quickfilter/QuickfiltersDesignComponent.js +1 -1
  53. package/lib/quickfilter/TextLiteralComponent.d.ts +2 -186
  54. package/lib/quickfilter/TextLiteralComponent.js +3 -0
  55. package/lib/valueFormatter.js +52 -1
  56. package/lib/widgets/ImageWidgetComponent.js +2 -2
  57. package/lib/widgets/charts/calendar/CalendarChartDesignerComponent.js +2 -2
  58. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -1
  59. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +1 -1
  60. package/lib/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.js +2 -2
  61. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
  62. package/lib/widgets/charts/layered/LayeredChartLayerDesignerComponent.js +2 -2
  63. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.js +2 -2
  64. package/lib/widgets/charts/pivot/PivotChartLayout.d.ts +3 -2
  65. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +4 -1
  66. package/lib/widgets/charts/pivot/PivotChartQueryBuilder.js +1 -1
  67. package/lib/widgets/charts/table/TableChart.js +15 -4
  68. package/lib/widgets/charts/table/TableChartDesignerComponent.js +2 -2
  69. package/lib/widgets/charts/table/TableChartViewComponent.d.ts +2 -1
  70. package/lib/widgets/charts/table/TableChartViewComponent.js +9 -4
  71. package/lib/widgets/text/ExprItemEditorComponent.js +2 -2
  72. package/package.json +8 -8
  73. package/src/MWaterAddRelatedFormComponent.ts +15 -20
  74. package/src/MWaterAddRelatedIndicatorComponent.ts +1 -1
  75. package/src/MWaterContextComponent.tsx +140 -0
  76. package/src/MWaterLoaderComponent.ts +2 -2
  77. package/src/{MWaterTableSelectComponent.ts → MWaterTableSelectComponent.tsx} +61 -66
  78. package/src/axes/AxisBuilder.ts +1 -1
  79. package/src/axes/RangesComponent.ts +27 -16
  80. package/src/dashboards/{DashboardComponent.ts → DashboardComponent.tsx} +37 -40
  81. package/src/dashboards/ServerDashboardDataSource.ts +16 -12
  82. package/src/datagrids/DatagridComponent.ts +59 -14
  83. package/src/datagrids/DatagridDataSource.ts +8 -0
  84. package/src/datagrids/DatagridDesign.ts +3 -0
  85. package/src/datagrids/DatagridDesignerComponent.tsx +9 -1
  86. package/src/datagrids/DatagridViewComponent.ts +7 -3
  87. package/src/datagrids/DirectDatagridDataSource.ts +35 -0
  88. package/src/datagrids/LabeledExprGenerator.ts +15 -0
  89. package/src/datagrids/ServerDatagridDataSource.ts +22 -4
  90. package/src/dayjs.ts +5 -0
  91. package/src/index.ts +0 -2
  92. package/src/languages.ts +5 -0
  93. package/src/layouts/blocks/BlocksDisplayComponent.ts +2 -2
  94. package/src/layouts/grid/LegoLayoutEngine.ts +2 -2
  95. package/src/layouts/grid/WidgetContainerComponent.ts +2 -2
  96. package/src/maps/BingLayer.ts +2 -2
  97. package/src/maps/BufferLayerDesignerComponent.ts +1 -1
  98. package/src/maps/ChoroplethLayerDesigner.tsx +1 -1
  99. package/src/maps/ClusterLayerDesignerComponent.ts +1 -1
  100. package/src/maps/DirectMapDataSource.ts +1 -2
  101. package/src/maps/GridLayerDesigner.tsx +1 -1
  102. package/src/maps/Layer.ts +6 -16
  103. package/src/maps/LegendGroup.ts +1 -1
  104. package/src/maps/MWaterServerLayer.ts +2 -2
  105. package/src/maps/MapComponent.ts +1 -1
  106. package/src/maps/{MapDesignerComponent.ts → MapDesignerComponent.tsx} +8 -16
  107. package/src/maps/MarkersLayerDesignerComponent.ts +1 -1
  108. package/src/maps/PopupFilterJoinsUtils.ts +4 -4
  109. package/src/maps/RasterMapViewComponent.ts +0 -1
  110. package/src/maps/ServerMapDataSource.ts +6 -6
  111. package/src/maps/SwitchableTileUrlLayerDesigner.tsx +1 -13
  112. package/src/maps/UtfGridLayer.ts +4 -4
  113. package/src/maps/VectorMapViewComponent.tsx +23 -36
  114. package/src/maps/mapboxUtils.ts +2 -2
  115. package/src/quickfilter/QuickfiltersDesignComponent.tsx +1 -1
  116. package/src/quickfilter/TextLiteralComponent.ts +4 -0
  117. package/src/richtext/ExprItemsHtmlConverter.ts +1 -1
  118. package/src/richtext/FontColorPaletteItem.ts +1 -1
  119. package/src/richtext/FontSizePaletteItem.ts +1 -1
  120. package/src/richtext/ItemsHtmlConverter.ts +2 -2
  121. package/src/valueFormatter.ts +54 -1
  122. package/src/widgets/ImageWidgetComponent.ts +1 -1
  123. package/src/widgets/charts/calendar/CalendarChartDesignerComponent.ts +1 -1
  124. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +1 -1
  125. package/src/widgets/charts/imagemosaic/ImageMosaicChartDesignerComponent.ts +1 -1
  126. package/src/widgets/charts/layered/LayeredChartLayerDesignerComponent.tsx +1 -1
  127. package/src/widgets/charts/pivot/PivotChartDesignerComponent.tsx +1 -1
  128. package/src/widgets/charts/pivot/PivotChartLayout.ts +3 -2
  129. package/src/widgets/charts/pivot/PivotChartLayoutBuilder.ts +2 -2
  130. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +7 -3
  131. package/src/widgets/charts/pivot/PivotChartQueryBuilder.ts +1 -1
  132. package/src/widgets/charts/table/TableChart.ts +24 -14
  133. package/src/widgets/charts/table/TableChartDesignerComponent.ts +1 -1
  134. package/src/widgets/charts/table/TableChartViewComponent.ts +10 -5
  135. package/src/widgets/text/ExprItemEditorComponent.tsx +1 -1
  136. package/stories/dashboards.js +3 -3
  137. package/src/MWaterContextComponent.ts +0 -144
  138. package/src/TableSelectComponent.ts +0 -60
@@ -19,6 +19,7 @@ import { getLayoutOptions } from "./layoutOptions"
19
19
  import { DashboardDesign } from "./DashboardDesign"
20
20
  import DashboardDataSource from "./DashboardDataSource"
21
21
  import { JsonQLFilter } from ".."
22
+ import { ActiveTablesContext } from "@mwater/expressions-ui"
22
23
 
23
24
  export interface DashboardComponentProps {
24
25
  design: DashboardDesign
@@ -80,7 +81,6 @@ export default class DashboardComponent extends React.Component<DashboardCompone
80
81
 
81
82
  static childContextTypes = {
82
83
  locale: PropTypes.string,
83
- activeTables: PropTypes.arrayOf(PropTypes.string.isRequired)
84
84
  }
85
85
 
86
86
  settings: SettingsModalComponent | null
@@ -89,9 +89,6 @@ export default class DashboardComponent extends React.Component<DashboardCompone
89
89
  return {
90
90
  // Pass locale down. Both here and DashboardViewComponent to ensure that quickfilters also get context
91
91
  locale: this.props.design.locale,
92
-
93
- // Pass active tables down to table select components so they can present a shorter list
94
- activeTables: DashboardUtils.getFilterableTables(this.props.design, this.props.schema)
95
92
  }
96
93
  }
97
94
 
@@ -428,41 +425,41 @@ export default class DashboardComponent extends React.Component<DashboardCompone
428
425
  hideScopes: this.state.hideQuickfilters
429
426
  })
430
427
 
431
- return R(
432
- "div",
433
- {
434
- style: {
435
- display: "grid",
436
- gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
437
- height: "100%"
438
- }
439
- },
440
- !this.props.hideTitleBar ? this.renderTitleBar() : undefined,
441
- R("div", null, !this.state.hideQuickfilters ? this.renderQuickfilter() : undefined),
442
- dashboardView,
443
- this.props.onDesignChange != null
444
- ? R(SettingsModalComponent, {
445
- onDesignChange: this.handleDesignChange,
446
- schema: this.props.schema,
447
- dataSource: this.props.dataSource,
448
- ref: (c: SettingsModalComponent | null) => {
449
- this.settings = c
450
- }
451
- })
452
- : undefined,
453
- this.state.layoutOptionsOpen
454
- ? R(
455
- ModalWindowComponent,
456
- { isOpen: true, outerPadding: 10, innerPadding: 10 },
457
- R(LayoutOptionsComponent, {
458
- design: this.props.design,
459
- onDesignChange: this.props.onDesignChange!,
460
- onClose: () => this.setState({ layoutOptionsOpen: false }),
461
- dashboardView: readonlyDashboardView,
462
- quickfiltersView: this.renderQuickfilter()
463
- })
464
- )
465
- : undefined
466
- )
428
+
429
+ // Pass active tables down to table select components so they can present a shorter list
430
+ return <ActiveTablesContext.Provider
431
+ value={DashboardUtils.getFilterableTables(this.props.design, this.props.schema)}>
432
+
433
+ <div style={{
434
+ display: "grid",
435
+ gridTemplateRows: this.props.hideTitleBar ? "auto 1fr" : "auto auto 1fr",
436
+ height: "100%"
437
+ }}>
438
+ {!this.props.hideTitleBar ? this.renderTitleBar() : undefined}
439
+ <div>{!this.state.hideQuickfilters ? this.renderQuickfilter() : undefined}</div>
440
+ {dashboardView}
441
+ {this.props.onDesignChange != null && (
442
+ <SettingsModalComponent
443
+ onDesignChange={this.handleDesignChange}
444
+ schema={this.props.schema}
445
+ dataSource={this.props.dataSource}
446
+ ref={(c: SettingsModalComponent | null) => {
447
+ this.settings = c
448
+ }}
449
+ />
450
+ )}
451
+ {this.state.layoutOptionsOpen && (
452
+ <ModalWindowComponent isOpen={true} outerPadding={10} innerPadding={10}>
453
+ <LayoutOptionsComponent
454
+ design={this.props.design}
455
+ onDesignChange={this.props.onDesignChange!}
456
+ onClose={() => this.setState({ layoutOptionsOpen: false })}
457
+ dashboardView={readonlyDashboardView}
458
+ quickfiltersView={this.renderQuickfilter()}
459
+ />
460
+ </ModalWindowComponent>
461
+ )}
462
+ </div>
463
+ </ActiveTablesContext.Provider>
467
464
  }
468
465
  }
@@ -97,7 +97,7 @@ class ServerQuickfilterDataSource implements QuickfiltersDataSource {
97
97
  `dashboards/${this.options.dashboardId}/quickfilters/${index}/values?` +
98
98
  querystring.stringify(query)
99
99
 
100
- const headers = {}
100
+ const headers: any = {}
101
101
  const cacheExpiry = this.options.dataSource.getCacheExpiry()
102
102
  if (cacheExpiry) {
103
103
  const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000)
@@ -110,10 +110,10 @@ class ServerQuickfilterDataSource implements QuickfiltersDataSource {
110
110
  url,
111
111
  headers
112
112
  })
113
- .done((data) => {
113
+ .done((data: any) => {
114
114
  return callback(null, data)
115
115
  })
116
- .fail((xhr) => {
116
+ .fail((xhr: any) => {
117
117
  console.log(xhr.responseText)
118
118
  return callback(new Error(xhr.responseText))
119
119
  })
@@ -151,7 +151,7 @@ class ServerWidgetDataSource {
151
151
  `dashboards/${this.options.dashboardId}/widgets/${this.options.widgetId}/data?` +
152
152
  querystring.stringify(query)
153
153
 
154
- const headers = {}
154
+ const headers: any = {}
155
155
  const cacheExpiry = this.options.dataSource.getCacheExpiry()
156
156
  if (cacheExpiry) {
157
157
  const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000)
@@ -164,10 +164,10 @@ class ServerWidgetDataSource {
164
164
  url,
165
165
  headers
166
166
  })
167
- .done((data) => {
167
+ .done((data: any) => {
168
168
  return callback(null, data)
169
169
  })
170
- .fail((xhr) => {
170
+ .fail((xhr: any) => {
171
171
  console.log(xhr.responseText)
172
172
  return callback(new Error(xhr.responseText))
173
173
  })
@@ -235,7 +235,7 @@ class ServerWidgetMapDataSource implements MapDataSource {
235
235
  `dashboards/${this.options.dashboardId}/widgets/${this.options.widgetId}/bounds?` +
236
236
  querystring.stringify(query)
237
237
 
238
- const headers = {}
238
+ const headers: any = {}
239
239
  const cacheExpiry = this.options.dataSource.getCacheExpiry()
240
240
  if (cacheExpiry) {
241
241
  const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000)
@@ -248,14 +248,18 @@ class ServerWidgetMapDataSource implements MapDataSource {
248
248
  url,
249
249
  headers
250
250
  })
251
- .done((data) => {
251
+ .done((data: any) => {
252
252
  return callback(null, data)
253
253
  })
254
- .fail((xhr) => {
254
+ .fail((xhr: any) => {
255
255
  console.log(xhr.responseText)
256
256
  return callback(new Error(xhr.responseText))
257
257
  })
258
258
  }
259
+
260
+ getQuickfiltersDataSource(): QuickfiltersDataSource {
261
+ return new ServerQuickfilterDataSource(this.options)
262
+ }
259
263
  }
260
264
 
261
265
  interface ServerWidgetLayerDataSourceOptions extends ServerDashboardDataSourceOptions {
@@ -480,7 +484,7 @@ class ServerWidgetLayerPopupWidgetDataSource implements WidgetDataSource {
480
484
  `dashboards/${this.options.dashboardId}/widgets/${this.options.widgetId}/layers/${this.options.layerView.id}/widgets/${this.options.popupWidgetId}/data?` +
481
485
  querystring.stringify(query)
482
486
 
483
- const headers = {}
487
+ const headers: any = {}
484
488
  const cacheExpiry = this.options.dataSource.getCacheExpiry()
485
489
  if (cacheExpiry) {
486
490
  const seconds = Math.floor((new Date().getTime() - cacheExpiry) / 1000)
@@ -493,10 +497,10 @@ class ServerWidgetLayerPopupWidgetDataSource implements WidgetDataSource {
493
497
  url,
494
498
  headers
495
499
  })
496
- .done((data) => {
500
+ .done((data: any) => {
497
501
  return callback(null, data)
498
502
  })
499
- .fail((xhr) => {
503
+ .fail((xhr: any) => {
500
504
  console.log(xhr.responseText)
501
505
  return callback(new Error(xhr.responseText))
502
506
  })
@@ -16,6 +16,7 @@ import QuickfilterCompiler from "../quickfilter/QuickfilterCompiler"
16
16
  import FindReplaceModalComponent from "./FindReplaceModalComponent"
17
17
  import DatagridDataSource from "./DatagridDataSource"
18
18
  import { DatagridDesign, JsonQLFilter } from ".."
19
+ import { format as d3Format } from "d3-format"
19
20
 
20
21
  export interface DatagridComponentProps {
21
22
  /** schema to use */
@@ -55,20 +56,25 @@ export interface DatagridComponentProps {
55
56
  filters?: JsonQLFilter[]
56
57
  }
57
58
 
59
+ interface DatagridComponentState {
60
+ /** is design being edited */
61
+ editingDesign: boolean
62
+ /** True if cells can be edited directly */
63
+ cellEditingEnabled: boolean
64
+ /** Height of quickfilters */
65
+ quickfiltersHeight: number | null
66
+ quickfiltersValues: null | any[]
67
+ refreshKey: number
68
+ /** Number of rows */
69
+ numRows?: number
70
+ }
71
+
58
72
  // Datagrid with decorations
59
73
  // See README.md for description of datagrid format
60
74
  // Design should be cleaned already before being passed in (see DatagridUtils)
61
75
  export default class DatagridComponent extends React.Component<
62
76
  DatagridComponentProps,
63
- {
64
- /** is design being edited */
65
- editingDesign: boolean
66
- /** True if cells can be edited directly */
67
- cellEditingEnabled: boolean
68
- /** Height of quickfilters */
69
- quickfiltersHeight: number | null
70
- quickfiltersValues: null | any[]
71
- }
77
+ DatagridComponentState
72
78
  > {
73
79
  datagridView?: DatagridViewComponent | null
74
80
  quickfilters?: HTMLElement | null
@@ -81,20 +87,51 @@ export default class DatagridComponent extends React.Component<
81
87
  editingDesign: false, // is design being edited
82
88
  cellEditingEnabled: false, // True if cells can be edited directly
83
89
  quickfiltersHeight: null, // Height of quickfilters
84
- quickfiltersValues: null
90
+ quickfiltersValues: null,
91
+ refreshKey: 1
85
92
  }
86
93
  }
87
94
 
88
95
  reload() {
89
- return this.datagridView?.reload()
96
+ this.datagridView?.reload()
90
97
  }
91
98
 
92
99
  componentDidMount() {
93
- return this.updateHeight()
100
+ this.loadRowCount()
101
+ this.updateHeight()
102
+ }
103
+
104
+ componentDidUpdate(prevProps: DatagridComponentProps, prevState: DatagridComponentState) {
105
+ if (!_.isEqual(prevProps.design, this.props.design) || !_.isEqual(prevState.quickfiltersValues, this.state.quickfiltersValues) || prevState.refreshKey !== this.state.refreshKey) {
106
+ this.loadRowCount()
107
+ }
108
+ this.updateHeight()
109
+ }
110
+
111
+ loadRowCount() {
112
+ if(!this.props.design.showNumRows) {
113
+ return
114
+ }
115
+ let filters = this.props.filters || []
116
+
117
+ // Compile quickfilters
118
+ filters = filters.concat(this.getQuickfilterFilters())
119
+ this.props.datagridDataSource.countRows(this.props.design,
120
+ filters,
121
+ (error: any, numRows: any) => {
122
+ if (error) {
123
+ console.error(error)
124
+ alert(T("Error loading data"))
125
+ return
126
+ }
127
+ console.log(numRows)
128
+ this.setState({numRows})
129
+ })
94
130
  }
95
131
 
96
- componentDidUpdate() {
97
- return this.updateHeight()
132
+ handleRefreshData = () => {
133
+ this.props.dataSource.clearCache?.()
134
+ this.setState({ refreshKey: this.state.refreshKey + 1 })
98
135
  }
99
136
 
100
137
  updateHeight() {
@@ -258,9 +295,16 @@ export default class DatagridComponent extends React.Component<
258
295
  R(
259
296
  "div",
260
297
  { style: { float: "right" } },
298
+ this.props.design.showNumRows && this.state.numRows ? R("small", {className: 'text-muted text-sm'}, `${d3Format(',')(this.state.numRows)} rows`): undefined,
261
299
  this.renderFindReplace(),
262
300
  this.renderCellEdit(),
263
301
  this.renderEditButton(),
302
+ R(
303
+ "a",
304
+ { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData },
305
+ R("span", { className: "fas fa-sync" }),
306
+ R("span", { className: "hide-600px" }, " Refresh")
307
+ ),
264
308
  this.props.extraTitleButtonsElem
265
309
  ),
266
310
  this.props.titleElem
@@ -375,6 +419,7 @@ export default class DatagridComponent extends React.Component<
375
419
  onRowDoubleClick: this.props.onRowDoubleClick,
376
420
  canEditExpr: this.state.cellEditingEnabled ? this.props.canEditExpr : undefined,
377
421
  updateExprValues: this.state.cellEditingEnabled ? this.props.updateExprValues : undefined,
422
+ refreshKey: this.state.refreshKey
378
423
  })
379
424
  } else if (this.props.onDesignChange) {
380
425
  return R(
@@ -14,6 +14,14 @@ export default class DatagridDataSource {
14
14
  throw new Error("Not implemented")
15
15
  }
16
16
 
17
+ countRows(
18
+ design: DatagridDesign,
19
+ filters: JsonQLFilter[] | undefined,
20
+ callback: (error: any, numRows: number) => void
21
+ ): void {
22
+ throw new Error("Not implemented")
23
+ }
24
+
17
25
  /** Gets the quickfilters data source */
18
26
  getQuickfiltersDataSource(): QuickfiltersDataSource {
19
27
  throw new Error("Not implemented")
@@ -29,6 +29,9 @@ export interface DatagridDesign {
29
29
 
30
30
  /** array of global filters. See below. */
31
31
  globalFilters?: DatagridDesignGlobalFilter[]
32
+
33
+ /** true to show number of rows */
34
+ showNumRows?: boolean
32
35
  }
33
36
 
34
37
  export interface DatagridDesignColumn {
@@ -14,7 +14,7 @@ import OrderBysDesignerComponent from "./OrderBysDesignerComponent"
14
14
  import ReorderableListComponent from "@mwater/react-library/lib/reorderable/ReorderableListComponent"
15
15
  import QuickfiltersDesignComponent from "../quickfilter/QuickfiltersDesignComponent"
16
16
  import LabeledExprGenerator from "./LabeledExprGenerator"
17
- import TableSelectComponent from "../TableSelectComponent"
17
+ import { TableSelectComponent } from "@mwater/expressions-ui"
18
18
  import uuid from "uuid"
19
19
  import update from "update-object"
20
20
  import * as ui from "@mwater/react-library/lib/bootstrap"
@@ -196,6 +196,14 @@ function DatagridOptionsComponent(props: DatagridOptionsComponentProps) {
196
196
  >
197
197
  {T("Show row numbers")}
198
198
  </ui.Checkbox>
199
+ <ui.Checkbox
200
+ value={props.design.showNumRows}
201
+ onChange={(showNumRows) =>
202
+ props.onDesignChange({ ...props.design, showNumRows })
203
+ }
204
+ >
205
+ {T("Show number of rows")}
206
+ </ui.Checkbox>
199
207
  <ui.FormGroup label={T("Language")} hint={T("Preferred language of the datagrid")}>
200
208
  <ReactSelect
201
209
  value={localeOptions.find(opt => opt.value == (props.design.locale || "en")) || null}
@@ -38,6 +38,9 @@ export interface DatagridViewComponentProps {
38
38
 
39
39
  /** Called when a row is clicked with (tableId, rowId, rowIndex) */
40
40
  onRowClick?: (tableId: string, rowId: any, rowIndex: number) => void
41
+
42
+ /** Change to force a refresh */
43
+ refreshKey?: any
41
44
  }
42
45
 
43
46
  /** Update to one row expression value */
@@ -91,8 +94,8 @@ export default class DatagridViewComponent extends React.Component<
91
94
  componentWillReceiveProps(nextProps: DatagridViewComponentProps) {
92
95
  // If design or filters changed, delete all rows
93
96
  // TODO won't this reload on column resize?
94
- if (!_.isEqual(nextProps.design, this.props.design) || !_.isEqual(nextProps.filters, this.props.filters)) {
95
- return this.setState({ rows: [], entirelyLoaded: false })
97
+ if (!_.isEqual(nextProps.design, this.props.design) || !_.isEqual(nextProps.filters, this.props.filters) || nextProps.refreshKey !== this.props.refreshKey) {
98
+ this.setState({ rows: [], entirelyLoaded: false })
96
99
  }
97
100
  }
98
101
 
@@ -452,7 +455,8 @@ export default class DatagridViewComponent extends React.Component<
452
455
  onRowDoubleClick: this.handleRowDoubleClick,
453
456
  onRowClick: this.handleRowClick,
454
457
  isColumnResizing: false,
455
- onColumnResizeEndCallback: this.handleColumnResize
458
+ onColumnResizeEndCallback: this.handleColumnResize,
459
+ touchScrollEnabled: true
456
460
  },
457
461
  this.renderColumns()
458
462
  )
@@ -4,6 +4,8 @@ import * as QuickfilterUtils from "../quickfilter/QuickfilterUtils"
4
4
  import { DataSource, Row, Schema } from "@mwater/expressions"
5
5
  import { DatagridDesign } from "./DatagridDesign"
6
6
  import { JsonQLFilter } from "../JsonQLFilter"
7
+ import _ from "lodash"
8
+ import { JsonQLSelectQuery } from "@mwater/jsonql"
7
9
 
8
10
  /** Uses direct DataSource queries */
9
11
  export default class DirectDatagridDataSource implements DatagridDataSource {
@@ -37,6 +39,39 @@ export default class DirectDatagridDataSource implements DatagridDataSource {
37
39
  return this.options.dataSource.performQuery(query, callback)
38
40
  }
39
41
 
42
+ countRows(
43
+ design: DatagridDesign,
44
+ filters: JsonQLFilter[] | undefined,
45
+ callback: (error: any, numRows: number) => void
46
+ ): void {
47
+ const queryBuilder = new DatagridQueryBuilder(this.options.schema)
48
+
49
+ // Create query to get the page of rows at the specific offset
50
+ const query = queryBuilder.createQuery(design, {
51
+ extraFilters: filters
52
+ })
53
+
54
+ const countQuery: JsonQLSelectQuery = {
55
+ ..._.omit(query, 'orderBy'),
56
+ selects: [
57
+ {
58
+ type: 'select',
59
+ expr: {
60
+ type: 'op',
61
+ op: 'count',
62
+ exprs: []
63
+ },
64
+ alias: 'cnt'
65
+ }
66
+ ]
67
+ };
68
+
69
+ console.log(countQuery)
70
+ return this.options.dataSource.performQuery(countQuery, (error, rows) => {
71
+ callback(error, rows?.[0]?.cnt)
72
+ })
73
+ }
74
+
40
75
  // Gets the quickfilters data source
41
76
  getQuickfiltersDataSource() {
42
77
  return {
@@ -140,6 +140,21 @@ export default class LabeledExprGenerator {
140
140
  joins
141
141
  }
142
142
  ]
143
+ } else if (column.idTable!.match(/^custom./)) { // Support cascading ref question
144
+ return this.schema
145
+ .getColumns(column.idTable!)
146
+ .filter((c: any) => c.id[0] !== "_")
147
+ .map((c: any) => ({
148
+ expr: {
149
+ type: "scalar",
150
+ table,
151
+ joins: [column.id],
152
+ expr: { type: "field", table: column.idTable, column: c.id }
153
+ },
154
+
155
+ label: `${createLabel(column)} > ${createLabel(c)}`,
156
+ joins
157
+ }))
143
158
  } else {
144
159
  // Use label, code, full name, or name of dest table
145
160
  const destTable = this.schema.getTable(column.idTable!)
@@ -51,9 +51,27 @@ export default class ServerDatagridDataSource extends DatagridDataSource {
51
51
 
52
52
  const url = this.options.apiUrl + `datagrids/${this.options.datagridId}/data?` + querystring.stringify(query)
53
53
 
54
- return $.getJSON(url, (data) => {
54
+ return $.getJSON(url, (data: any) => {
55
55
  return callback(null, data)
56
- }).fail((xhr) => {
56
+ }).fail((xhr: any) => {
57
+ console.log(xhr.responseText)
58
+ return callback(new Error(xhr.responseText))
59
+ })
60
+ }
61
+
62
+ countRows(design: DatagridDesign, filters: any, callback: any) {
63
+ const query = {
64
+ client: this.options.client,
65
+ share: this.options.share,
66
+ filters: compressJson(filters),
67
+ rev: this.options.rev,
68
+ }
69
+
70
+ const url = this.options.apiUrl + `datagrids/${this.options.datagridId}/summary?` + querystring.stringify(query)
71
+
72
+ return $.getJSON(url, (data: any) => {
73
+ return callback(null, data?.[0]?.cnt)
74
+ }).fail((xhr: any) => {
57
75
  console.log(xhr.responseText)
58
76
  return callback(new Error(xhr.responseText))
59
77
  })
@@ -109,9 +127,9 @@ class ServerQuickfilterDataSource {
109
127
  `datagrids/${this.options.datagridId}/quickfilters/${index}/values?` +
110
128
  querystring.stringify(query)
111
129
 
112
- return $.getJSON(url, (data) => {
130
+ return $.getJSON(url, (data: any) => {
113
131
  return callback(null, data)
114
- }).fail((xhr) => {
132
+ }).fail((xhr: any) => {
115
133
  console.log(xhr.responseText)
116
134
  return callback(new Error(xhr.responseText))
117
135
  })
package/src/dayjs.ts ADDED
@@ -0,0 +1,5 @@
1
+ import dayjs from "dayjs"
2
+ import localizedFormat from 'dayjs/plugin/localizedFormat'
3
+ dayjs.extend(localizedFormat)
4
+
5
+ export default dayjs
package/src/index.ts CHANGED
@@ -12,8 +12,6 @@ export { default as RegionSelectComponent } from "./maps/RegionSelectComponent"
12
12
 
13
13
  export * from "./datagrids/DatagridDesign"
14
14
 
15
- export { default as TableSelectComponent } from "./TableSelectComponent"
16
-
17
15
  export * from "./JsonQLFilter"
18
16
 
19
17
  export { default as DashboardComponent } from "./dashboards/DashboardComponent"
package/src/languages.ts CHANGED
@@ -513,6 +513,11 @@ export const languages: {
513
513
  "name": "Māori",
514
514
  "en": "Maori"
515
515
  },
516
+ {
517
+ "code": "miq",
518
+ "name": "Miskitu",
519
+ "en": "Miskito"
520
+ },
516
521
  {
517
522
  "code": "mk",
518
523
  "name": "Македонски",
@@ -331,7 +331,7 @@ class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps
331
331
  R(
332
332
  "div",
333
333
  {
334
- style: { position: "absolute", left: 141, top: 0, bottom: 0, right: 0, overflow: "auto" },
334
+ style: { position: "absolute", left: 141, top: 0, bottom: 0, right: 0, overflowX: "auto", overflowY: "scroll" },
335
335
  className: `mwater-visualization-block-parent-outer mwater-visualization-block-parent-outer-${
336
336
  this.props.style || "default"
337
337
  } mwater-visualization-block-editing`
@@ -351,7 +351,7 @@ class BlocksDisplayComponent extends React.Component<BlocksDisplayComponentProps
351
351
  )
352
352
  } else {
353
353
  return R(AutoSizeComponent, { injectWidth: true, injectHeight: true } as any, (size: any) => {
354
- const outerParentStyle: CSSProperties = { width: "100%", height: "100%", overflowX: "auto" }
354
+ const outerParentStyle: CSSProperties = { width: "100%", height: "100%", overflowX: "auto", overflowY: "scroll" }
355
355
  innerParentStyle = {}
356
356
 
357
357
  // Remove padding if small
@@ -68,8 +68,8 @@ export default class LegoLayoutEngine {
68
68
  // Returns layout lookup of id -> layout
69
69
  performLayout(layouts: any, priority: any) {
70
70
  // Create list of placed layouts to avoid as placing new ones
71
- const placedLayouts = []
72
- const results = {}
71
+ const placedLayouts: any[] = []
72
+ const results: any = {}
73
73
 
74
74
  // Add priority first to displace others
75
75
  if (priority) {
@@ -106,7 +106,7 @@ class Container extends React.Component<ContainerProps, ContainerState> {
106
106
  let items = _.clone(this.props.items)
107
107
  items[id] = { layout: droppedLayout, widget }
108
108
 
109
- let layouts = {}
109
+ let layouts: any = {}
110
110
  for (id in items) {
111
111
  const item = items[id]
112
112
  layouts[id] = item.layout
@@ -279,7 +279,7 @@ class Container extends React.Component<ContainerProps, ContainerState> {
279
279
  hoveredLayout = props.layoutEngine.rectToLayout(hoveredRect)
280
280
  }
281
281
 
282
- let layouts = {}
282
+ let layouts: any = {}
283
283
  for (id in props.items) {
284
284
  const item = props.items[id]
285
285
  layouts[id] = item.layout
@@ -69,9 +69,9 @@ module.exports = L.TileLayer.extend({
69
69
  loadMetadata: function () {
70
70
  var _this = this
71
71
  var cbid = "_bing_metadata_" + L.Util.stamp(this)
72
- window[cbid] = function (meta: any) {
72
+ ;(window as any)[cbid] = function (meta: any) {
73
73
  _this.meta = meta
74
- window[cbid] = undefined
74
+ ;(window as any)[cbid] = undefined
75
75
  var e = document.getElementById(cbid)
76
76
  e!.parentNode!.removeChild(e!)
77
77
  if (meta.errorDetails) {
@@ -9,7 +9,7 @@ import { ExprCompiler } from "@mwater/expressions"
9
9
  import NumberInputComponent from "@mwater/react-library/lib/NumberInputComponent"
10
10
  import AxisComponent from "./../axes/AxisComponent"
11
11
  import ColorComponent from "../ColorComponent"
12
- import TableSelectComponent from "../TableSelectComponent"
12
+ import { TableSelectComponent } from "@mwater/expressions-ui"
13
13
  import { default as Rcslider } from "rc-slider"
14
14
  import EditPopupComponent from "./EditPopupComponent"
15
15
  import ZoomLevelsComponent from "./ZoomLevelsComponent"
@@ -6,7 +6,7 @@ import { produce } from "immer"
6
6
  import { ExprComponent, FilterExprComponent } from "@mwater/expressions-ui"
7
7
  import { ExprCompiler, Schema, DataSource, Expr, OpExpr } from "@mwater/expressions"
8
8
  import AxisComponent from "./../axes/AxisComponent"
9
- import TableSelectComponent from "../TableSelectComponent"
9
+ import { TableSelectComponent } from "@mwater/expressions-ui"
10
10
  import ColorComponent from "../ColorComponent"
11
11
  import Rcslider from "rc-slider"
12
12
  import ChoroplethLayerDesign from "./ChoroplethLayerDesign"
@@ -8,7 +8,7 @@ import { DataSource, ExprUtils, Schema } from "@mwater/expressions"
8
8
  import { ExprCompiler } from "@mwater/expressions"
9
9
  import AxisComponent from "./../axes/AxisComponent"
10
10
  import ColorComponent from "../ColorComponent"
11
- import TableSelectComponent from "../TableSelectComponent"
11
+ import { TableSelectComponent } from "@mwater/expressions-ui"
12
12
  import ZoomLevelsComponent from "./ZoomLevelsComponent"
13
13
 
14
14
  export interface ClusterLayerDesignerComponentProps {
@@ -249,8 +249,7 @@ class DirectLayerDataSource implements MapLayerDataSource {
249
249
  const { url, expires } = await getVectorTileFromDirectRequest({
250
250
  apiUrl: this.options.apiUrl,
251
251
  client: this.options.client,
252
- directTokenRequest,
253
- createdAfter
252
+ directTokenRequest
254
253
  })
255
254
 
256
255
  return { url, expires }
@@ -6,7 +6,7 @@ import { produce } from "immer"
6
6
  import { ExprComponent, FilterExprComponent } from "@mwater/expressions-ui"
7
7
  import { ExprCompiler, Schema, DataSource, Expr, OpExpr } from "@mwater/expressions"
8
8
  import AxisComponent from "../axes/AxisComponent"
9
- import TableSelectComponent from "../TableSelectComponent"
9
+ import { TableSelectComponent } from "@mwater/expressions-ui"
10
10
  import Rcslider from "rc-slider"
11
11
  import GridLayerDesign from "./GridLayerDesign"
12
12
  import { JsonQLFilter } from "../index"