@mwater/visualization 5.4.0 → 5.4.2

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 (271) hide show
  1. package/lib/ColorComponent.js +2 -1
  2. package/lib/IdSelection.d.ts +16 -0
  3. package/lib/IdSelection.js +59 -0
  4. package/lib/MWaterAddRelatedIndicatorComponent.js +2 -2
  5. package/lib/MWaterCompleteTableSelectComponent.d.ts +3 -8
  6. package/lib/MWaterCompleteTableSelectComponent.js +36 -42
  7. package/lib/MWaterLoaderComponent.d.ts +11 -10
  8. package/lib/MWaterLoaderComponent.js +1 -1
  9. package/lib/MWaterResponsesFilterComponent.js +1 -1
  10. package/lib/MWaterTableSelectComponent.d.ts +0 -1
  11. package/lib/MWaterTableSelectComponent.js +4 -6
  12. package/lib/autotranslate.d.ts +20 -0
  13. package/lib/autotranslate.js +122 -0
  14. package/lib/axes/AxisBuilder.js +3 -3
  15. package/lib/axes/AxisColorEditorComponent.js +4 -0
  16. package/lib/axes/AxisComponent.d.ts +8 -12
  17. package/lib/axes/AxisComponent.js +32 -80
  18. package/lib/axes/CategoryMapComponent.js +4 -4
  19. package/lib/axes/RangesComponent.js +2 -2
  20. package/lib/dashboards/DashboardComponent.d.ts +6 -0
  21. package/lib/dashboards/DashboardComponent.js +44 -12
  22. package/lib/dashboards/DashboardDesign.d.ts +11 -2
  23. package/lib/dashboards/DashboardUtils.d.ts +5 -0
  24. package/lib/dashboards/DashboardUtils.js +30 -0
  25. package/lib/dashboards/DashboardViewComponent.d.ts +2 -0
  26. package/lib/dashboards/DashboardViewComponent.js +16 -3
  27. package/lib/dashboards/ServerDashboardDataSource.js +2 -1
  28. package/lib/dashboards/SettingsModalComponent.d.ts +1 -1
  29. package/lib/dashboards/SettingsModalComponent.js +256 -19
  30. package/lib/dashboards/WidgetComponent.d.ts +6 -3
  31. package/lib/dashboards/WidgetComponent.js +3 -1
  32. package/lib/datagrids/CellEditor.d.ts +19 -0
  33. package/lib/datagrids/CellEditor.js +223 -0
  34. package/lib/datagrids/DatagridComponent.d.ts +18 -87
  35. package/lib/datagrids/DatagridComponent.js +304 -222
  36. package/lib/datagrids/DatagridViewComponent.d.ts +15 -53
  37. package/lib/datagrids/DatagridViewComponent.js +256 -257
  38. package/lib/datagrids/DirectDatagridDataSource.js +2 -3
  39. package/lib/datagrids/ExprCellComponent.d.ts +8 -15
  40. package/lib/datagrids/ExprCellComponent.js +11 -15
  41. package/lib/datagrids/FindReplaceModalComponent.d.ts +4 -6
  42. package/lib/datagrids/FindReplaceModalComponent.js +38 -75
  43. package/lib/index.css +1 -1
  44. package/lib/index.d.ts +0 -1
  45. package/lib/index.js +0 -1
  46. package/lib/layouts/blocks/HorizontalBlockComponent.js +2 -2
  47. package/lib/mWaterLoader.d.ts +1 -1
  48. package/lib/maps/BufferLayer.d.ts +7 -5
  49. package/lib/maps/BufferLayer.js +69 -48
  50. package/lib/maps/BufferLayerDesign.d.ts +21 -14
  51. package/lib/maps/BufferLayerDesignerComponent.d.ts +16 -31
  52. package/lib/maps/BufferLayerDesignerComponent.js +68 -102
  53. package/lib/maps/ChoroplethLayer.d.ts +5 -4
  54. package/lib/maps/ChoroplethLayer.js +32 -9
  55. package/lib/maps/ChoroplethLayerDesign.d.ts +6 -2
  56. package/lib/maps/ChoroplethLayerDesigner.js +4 -2
  57. package/lib/maps/ClusterLayer.d.ts +3 -4
  58. package/lib/maps/ClusterLayer.js +2 -1
  59. package/lib/maps/DetailLevelSelectComponent.js +1 -1
  60. package/lib/maps/DirectMapDataSource.js +2 -1
  61. package/lib/maps/EditPopupComponent.js +5 -3
  62. package/lib/maps/GridLayer.d.ts +3 -4
  63. package/lib/maps/GridLayer.js +2 -1
  64. package/lib/maps/GridLayerDesigner.js +5 -3
  65. package/lib/maps/HoverContent.d.ts +11 -3
  66. package/lib/maps/HoverContent.js +25 -9
  67. package/lib/maps/Layer.d.ts +24 -3
  68. package/lib/maps/Layer.js +5 -1
  69. package/lib/maps/LayerFactory.js +0 -8
  70. package/lib/maps/LayerLegendComponent.js +0 -1
  71. package/lib/maps/LayerSwitcherComponent.d.ts +1 -0
  72. package/lib/maps/LayerSwitcherComponent.js +1 -1
  73. package/lib/maps/LeafletMapComponent.js +3 -1
  74. package/lib/maps/LegendComponent.d.ts +1 -0
  75. package/lib/maps/LegendComponent.js +9 -1
  76. package/lib/maps/MWaterServerLayer.d.ts +2 -2
  77. package/lib/maps/MWaterServerLayer.js +2 -2
  78. package/lib/maps/MapComponent.js +3 -3
  79. package/lib/maps/MapDesign.d.ts +2 -0
  80. package/lib/maps/MapDesignerComponent.d.ts +4 -3
  81. package/lib/maps/MapDesignerComponent.js +68 -74
  82. package/lib/maps/MapLayerViewDesignerComponent.js +2 -2
  83. package/lib/maps/MapUtils.d.ts +4 -0
  84. package/lib/maps/MapUtils.js +19 -0
  85. package/lib/maps/MapViewComponent.d.ts +8 -3
  86. package/lib/maps/MarkersLayer.d.ts +5 -4
  87. package/lib/maps/MarkersLayer.js +33 -7
  88. package/lib/maps/MarkersLayerDesign.d.ts +19 -16
  89. package/lib/maps/PopupFilterJoinsUtils.d.ts +6 -3
  90. package/lib/maps/PopupFilterJoinsUtils.js +0 -6
  91. package/lib/maps/RasterMapViewComponent.d.ts +3 -31
  92. package/lib/maps/RasterMapViewComponent.js +7 -2
  93. package/lib/maps/ServerMapDataSource.js +2 -1
  94. package/lib/maps/SwitchableTileUrlLayer.d.ts +3 -3
  95. package/lib/maps/SwitchableTileUrlLayer.js +2 -1
  96. package/lib/maps/TileUrlLayer.d.ts +4 -5
  97. package/lib/maps/TileUrlLayer.js +2 -1
  98. package/lib/maps/VectorMapViewComponent.d.ts +5 -37
  99. package/lib/maps/VectorMapViewComponent.js +19 -8
  100. package/lib/maps/maps.d.ts +3 -0
  101. package/lib/quickfilter/QuickfiltersComponent.d.ts +2 -0
  102. package/lib/quickfilter/QuickfiltersComponent.js +9 -7
  103. package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +1 -1
  104. package/lib/quickfilter/QuickfiltersDesignComponent.js +19 -35
  105. package/lib/richtext/ExprItemsHtmlConverter.d.ts +5 -2
  106. package/lib/richtext/ExprItemsHtmlConverter.js +4 -4
  107. package/lib/richtext/ExprItemsTranslator.d.ts +5 -0
  108. package/lib/richtext/ExprItemsTranslator.js +149 -0
  109. package/lib/richtext/ItemsHtmlConverter.d.ts +1 -1
  110. package/lib/richtext/ItemsHtmlConverter.js +31 -15
  111. package/lib/wellknown.js +12 -9
  112. package/lib/widgets/IFrameWidget.d.ts +4 -4
  113. package/lib/widgets/ImageWidget.d.ts +7 -4
  114. package/lib/widgets/ImageWidget.js +9 -1
  115. package/lib/widgets/ImageWidgetComponent.d.ts +1 -0
  116. package/lib/widgets/ImageWidgetComponent.js +1 -1
  117. package/lib/widgets/MapWidget.d.ts +5 -48
  118. package/lib/widgets/MapWidget.js +26 -63
  119. package/lib/widgets/MarkdownWidget.d.ts +3 -0
  120. package/lib/widgets/MarkdownWidget.js +3 -0
  121. package/lib/widgets/TOCWidget.d.ts +15 -27
  122. package/lib/widgets/TOCWidget.js +107 -183
  123. package/lib/widgets/Widget.d.ts +18 -7
  124. package/lib/widgets/Widget.js +4 -0
  125. package/lib/widgets/WidgetScopesViewComponent.js +1 -1
  126. package/lib/widgets/charts/Chart.d.ts +10 -1
  127. package/lib/widgets/charts/Chart.js +22 -11
  128. package/lib/widgets/charts/ChartViewComponent.d.ts +4 -0
  129. package/lib/widgets/charts/ChartViewComponent.js +6 -3
  130. package/lib/widgets/charts/ChartWidget.d.ts +2 -0
  131. package/lib/widgets/charts/ChartWidget.js +9 -1
  132. package/lib/widgets/charts/ChartWidgetComponent.d.ts +4 -0
  133. package/lib/widgets/charts/ChartWidgetComponent.js +2 -2
  134. package/lib/widgets/charts/calendar/CalendarChart.d.ts +1 -0
  135. package/lib/widgets/charts/calendar/CalendarChart.js +26 -0
  136. package/lib/widgets/charts/calendar/CalendarChartViewComponent.js +3 -1
  137. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.d.ts +1 -0
  138. package/lib/widgets/charts/imagemosaic/ImageMosaicChart.js +8 -0
  139. package/lib/widgets/charts/layered/LayeredChart.d.ts +2 -0
  140. package/lib/widgets/charts/layered/LayeredChart.js +63 -3
  141. package/lib/widgets/charts/layered/LayeredChartCompiler.d.ts +1 -1
  142. package/lib/widgets/charts/layered/LayeredChartCompiler.js +3 -3
  143. package/lib/widgets/charts/layered/LayeredChartDesignerComponent.js +2 -2
  144. package/lib/widgets/charts/layered/LayeredChartViewComponent.js +8 -3
  145. package/lib/widgets/charts/pivot/PivotChart.d.ts +1 -0
  146. package/lib/widgets/charts/pivot/PivotChart.js +63 -0
  147. package/lib/widgets/charts/pivot/PivotChartDesignerComponent.d.ts +1 -0
  148. package/lib/widgets/charts/pivot/PivotChartLayoutComponent.js +1 -1
  149. package/lib/widgets/charts/pivot/SegmentDesignerComponent.d.ts +6 -0
  150. package/lib/widgets/charts/pivot/SegmentDesignerComponent.js +7 -4
  151. package/lib/widgets/charts/table/OrderingsComponent.js +1 -1
  152. package/lib/widgets/charts/table/TableChart.d.ts +1 -0
  153. package/lib/widgets/charts/table/TableChart.js +15 -0
  154. package/lib/widgets/text/TextComponent.d.ts +11 -4
  155. package/lib/widgets/text/TextComponent.js +11 -8
  156. package/lib/widgets/text/TextWidget.d.ts +6 -3
  157. package/lib/widgets/text/TextWidget.js +7 -1
  158. package/lib/widgets/text/TextWidgetComponent.d.ts +4 -0
  159. package/lib/widgets/text/TextWidgetComponent.js +7 -1
  160. package/lib/widgets/text/TextWidgetDesign.d.ts +2 -4
  161. package/lib/widgets/text/TextWidgetDesign.js +1 -1
  162. package/package.json +7 -8
  163. package/src/ColorComponent.tsx +1 -2
  164. package/src/IdSelection.ts +62 -0
  165. package/src/MWaterAddRelatedIndicatorComponent.ts +3 -2
  166. package/src/MWaterCompleteTableSelectComponent.tsx +36 -46
  167. package/src/MWaterLoaderComponent.ts +28 -26
  168. package/src/MWaterResponsesFilterComponent.ts +5 -2
  169. package/src/MWaterTableSelectComponent.tsx +5 -9
  170. package/src/autotranslate.ts +141 -0
  171. package/src/axes/AxisBuilder.ts +3 -3
  172. package/src/axes/AxisColorEditorComponent.tsx +5 -0
  173. package/src/axes/{AxisComponent.ts → AxisComponent.tsx} +106 -106
  174. package/src/axes/CategoryMapComponent.ts +4 -4
  175. package/src/axes/RangesComponent.ts +3 -2
  176. package/src/dashboards/DashboardComponent.tsx +79 -14
  177. package/src/dashboards/DashboardDesign.ts +9 -2
  178. package/src/dashboards/DashboardUtils.ts +39 -0
  179. package/src/dashboards/DashboardViewComponent.tsx +22 -3
  180. package/src/dashboards/ServerDashboardDataSource.ts +2 -1
  181. package/src/dashboards/SettingsModalComponent.tsx +450 -35
  182. package/src/dashboards/WidgetComponent.tsx +12 -6
  183. package/src/datagrids/CellEditor.tsx +354 -0
  184. package/src/datagrids/DatagridComponent.tsx +646 -0
  185. package/src/datagrids/DatagridViewComponent.tsx +539 -0
  186. package/src/datagrids/DirectDatagridDataSource.ts +2 -3
  187. package/src/datagrids/{ExprCellComponent.ts → ExprCellComponent.tsx} +28 -23
  188. package/src/datagrids/{FindReplaceModalComponent.ts → FindReplaceModalComponent.tsx} +109 -122
  189. package/src/index.css +1 -1
  190. package/src/index.ts +0 -1
  191. package/src/layouts/blocks/HorizontalBlockComponent.ts +2 -2
  192. package/src/mWaterLoader.ts +1 -1
  193. package/src/maps/BufferLayer.ts +83 -60
  194. package/src/maps/BufferLayerDesign.ts +20 -14
  195. package/src/maps/BufferLayerDesignerComponent.tsx +309 -0
  196. package/src/maps/ChoroplethLayer.ts +40 -19
  197. package/src/maps/ChoroplethLayerDesign.ts +4 -2
  198. package/src/maps/ChoroplethLayerDesigner.tsx +4 -2
  199. package/src/maps/ClusterLayer.ts +4 -10
  200. package/src/maps/DetailLevelSelectComponent.ts +1 -1
  201. package/src/maps/DirectMapDataSource.ts +2 -1
  202. package/src/maps/EditPopupComponent.ts +7 -3
  203. package/src/maps/GridLayer.ts +4 -10
  204. package/src/maps/GridLayerDesigner.tsx +5 -3
  205. package/src/maps/HoverContent.tsx +40 -16
  206. package/src/maps/Layer.ts +28 -10
  207. package/src/maps/LayerFactory.ts +0 -8
  208. package/src/maps/LayerLegendComponent.ts +2 -4
  209. package/src/maps/LayerSwitcherComponent.tsx +6 -2
  210. package/src/maps/LeafletMapComponent.tsx +3 -1
  211. package/src/maps/LegendComponent.tsx +10 -1
  212. package/src/maps/MWaterServerLayer.ts +3 -3
  213. package/src/maps/MapComponent.ts +3 -3
  214. package/src/maps/MapDesign.ts +3 -0
  215. package/src/maps/MapDesignerComponent.tsx +165 -162
  216. package/src/maps/MapLayerViewDesignerComponent.ts +2 -2
  217. package/src/maps/MapUtils.ts +24 -0
  218. package/src/maps/MapViewComponent.tsx +11 -3
  219. package/src/maps/MarkersLayer.ts +44 -18
  220. package/src/maps/MarkersLayerDesign.ts +19 -16
  221. package/src/maps/PopupFilterJoinsUtils.ts +6 -2
  222. package/src/maps/RasterMapViewComponent.ts +9 -45
  223. package/src/maps/ServerMapDataSource.ts +2 -2
  224. package/src/maps/SwitchableTileUrlLayer.tsx +4 -10
  225. package/src/maps/TileUrlLayer.tsx +4 -10
  226. package/src/maps/VectorMapViewComponent.tsx +28 -55
  227. package/src/maps/maps.ts +3 -0
  228. package/src/quickfilter/QuickfiltersComponent.ts +13 -7
  229. package/src/quickfilter/QuickfiltersDesignComponent.tsx +56 -74
  230. package/src/richtext/ExprItemsHtmlConverter.ts +9 -5
  231. package/src/richtext/ExprItemsTranslator.ts +176 -0
  232. package/src/richtext/ItemsHtmlConverter.ts +33 -18
  233. package/src/wellknown.ts +33 -30
  234. package/src/widgets/ImageWidget.ts +10 -1
  235. package/src/widgets/ImageWidgetComponent.ts +3 -2
  236. package/src/widgets/{MapWidget.ts → MapWidget.tsx} +90 -101
  237. package/src/widgets/MarkdownWidget.ts +3 -0
  238. package/src/widgets/TOCWidget.tsx +281 -0
  239. package/src/widgets/Widget.ts +25 -5
  240. package/src/widgets/WidgetScopesViewComponent.ts +2 -1
  241. package/src/widgets/charts/Chart.ts +31 -12
  242. package/src/widgets/charts/ChartViewComponent.ts +13 -3
  243. package/src/widgets/charts/ChartWidget.ts +11 -1
  244. package/src/widgets/charts/ChartWidgetComponent.tsx +9 -1
  245. package/src/widgets/charts/calendar/CalendarChart.ts +29 -0
  246. package/src/widgets/charts/calendar/CalendarChartViewComponent.tsx +3 -1
  247. package/src/widgets/charts/imagemosaic/ImageMosaicChart.ts +9 -0
  248. package/src/widgets/charts/layered/LayeredChart.ts +71 -3
  249. package/src/widgets/charts/layered/LayeredChartCompiler.ts +4 -4
  250. package/src/widgets/charts/layered/LayeredChartDesignerComponent.tsx +4 -2
  251. package/src/widgets/charts/layered/LayeredChartViewComponent.ts +10 -4
  252. package/src/widgets/charts/pivot/PivotChart.ts +73 -0
  253. package/src/widgets/charts/pivot/PivotChartLayoutComponent.tsx +1 -1
  254. package/src/widgets/charts/pivot/SegmentDesignerComponent.tsx +6 -4
  255. package/src/widgets/charts/table/OrderingsComponent.tsx +2 -1
  256. package/src/widgets/charts/table/TableChart.ts +17 -0
  257. package/src/widgets/text/TextComponent.tsx +22 -12
  258. package/src/widgets/text/TextWidget.ts +9 -2
  259. package/src/widgets/text/TextWidgetComponent.tsx +16 -1
  260. package/src/widgets/text/TextWidgetDesign.ts +4 -7
  261. package/test/IdSelectionTests.ts +54 -0
  262. package/test/LayeredChartCompilerTests.ts +0 -2
  263. package/test/richtext/ExprItemsTranslatorTests.ts +144 -0
  264. package/test/wellknownTests.ts +144 -0
  265. package/src/datagrids/DatagridComponent.ts +0 -478
  266. package/src/datagrids/DatagridViewComponent.ts +0 -464
  267. package/src/datagrids/EditExprCellComponent.tsx +0 -305
  268. package/src/datagrids/README.md +0 -3
  269. package/src/maps/BufferLayerDesignerComponent.ts +0 -311
  270. package/src/widgets/TOCWidget.ts +0 -326
  271. package/test/LegoLayoutEngineTests.ts +0 -69
@@ -1,11 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
29
  const lodash_1 = __importDefault(require("lodash"));
7
- const react_1 = __importDefault(require("react"));
8
- const R = react_1.default.createElement;
30
+ const react_1 = __importStar(require("react"));
9
31
  const AutoSizeComponent_1 = __importDefault(require("@mwater/react-library/lib/AutoSizeComponent"));
10
32
  const ActionCancelModalComponent_1 = __importDefault(require("@mwater/react-library/lib/ActionCancelModalComponent"));
11
33
  const expressions_1 = require("@mwater/expressions");
@@ -14,120 +36,186 @@ const expressions_3 = require("@mwater/expressions");
14
36
  const DatagridViewComponent_1 = __importDefault(require("./DatagridViewComponent"));
15
37
  const DatagridDesignerComponent_1 = __importDefault(require("./DatagridDesignerComponent"));
16
38
  const DatagridUtils_1 = __importDefault(require("./DatagridUtils"));
39
+ const bootstrap_1 = require("@mwater/react-library/lib/bootstrap");
17
40
  const QuickfiltersComponent_1 = __importDefault(require("../quickfilter/QuickfiltersComponent"));
18
41
  const QuickfilterCompiler_1 = __importDefault(require("../quickfilter/QuickfilterCompiler"));
19
42
  const FindReplaceModalComponent_1 = __importDefault(require("./FindReplaceModalComponent"));
20
43
  const d3_format_1 = require("d3-format");
21
44
  const expressions_ui_1 = require("@mwater/expressions-ui");
22
- // Datagrid with decorations
23
- // See README.md for description of datagrid format
24
- // Design should be cleaned already before being passed in (see DatagridUtils)
25
- class DatagridComponent extends react_1.default.Component {
26
- datagridView;
27
- quickfilters;
28
- findReplaceModal;
29
- constructor(props) {
30
- super(props);
31
- this.state = {
32
- editingDesign: false, // is design being edited
33
- cellEditingEnabled: false, // True if cells can be edited directly
34
- quickfiltersHeight: null, // Height of quickfilters
35
- quickfiltersValues: null,
36
- refreshKey: 1
37
- };
38
- }
39
- reload() {
40
- this.datagridView?.reload();
41
- }
42
- componentDidMount() {
43
- this.loadRowCount();
44
- this.updateHeight();
45
- }
46
- componentDidUpdate(prevProps, prevState) {
47
- if (!lodash_1.default.isEqual(prevProps.design, this.props.design) || !lodash_1.default.isEqual(prevState.quickfiltersValues, this.state.quickfiltersValues) || prevState.refreshKey !== this.state.refreshKey) {
48
- this.loadRowCount();
49
- }
50
- this.updateHeight();
51
- }
52
- loadRowCount() {
53
- if (!this.props.design.showNumRows) {
45
+ const IdSelection_1 = __importDefault(require("../IdSelection"));
46
+ const useStableCallback_1 = require("@mwater/react-library/lib/useStableCallback");
47
+ const DatagridQueryBuilder_1 = __importDefault(require("./DatagridQueryBuilder"));
48
+ const immer_1 = __importDefault(require("immer"));
49
+ /**
50
+ * Datagrid with decorations
51
+ * Design should be cleaned already before being passed in (see DatagridUtils)
52
+ */
53
+ exports.default = (0, react_1.forwardRef)(function DatagridComponent(props, ref) {
54
+ const { schema, dataSource, datagridDataSource, design, onDesignChange, titleElem, extraTitleButtonsElem, canEditExpr, updateExprValues, onRowClick, onRowDoubleClick, quickfilterLocks, filters = [] } = props;
55
+ // State management
56
+ /** is design being edited */
57
+ const [editingDesign, setEditingDesign] = (0, react_1.useState)(false);
58
+ /** True if cells can be edited directly */
59
+ const [dataEditingEnabled, setDataEditingEnabled] = (0, react_1.useState)(false);
60
+ /** Height of quickfilters */
61
+ const [quickfiltersHeight, setQuickfiltersHeight] = (0, react_1.useState)(null);
62
+ /** Values of quickfilters */
63
+ const [quickfiltersValues, setQuickfiltersValues] = (0, react_1.useState)(null);
64
+ /** Refresh key */
65
+ const [refreshKey, setRefreshKey] = (0, react_1.useState)(1);
66
+ /** Number of rows */
67
+ const [numRows, setNumRows] = (0, react_1.useState)();
68
+ /** Selected rows */
69
+ const [selectedRows, setSelectedRows] = (0, react_1.useState)(new IdSelection_1.default());
70
+ /** True if delete confirmation modal is open */
71
+ const [showDeleteConfirmation, setShowDeleteConfirmation] = (0, react_1.useState)(false);
72
+ /** IDs of rows to be deleted */
73
+ const [rowIdsToDelete, setRowIdsToDelete] = (0, react_1.useState)();
74
+ /** True when loading IDs of rows to delete */
75
+ const [loadingRowIdsToDelete, setLoadingRowIdsToDelete] = (0, react_1.useState)(false);
76
+ // Refs
77
+ const datagridViewRef = react_1.default.useRef(null);
78
+ const quickfiltersRef = react_1.default.useRef(null);
79
+ const findReplaceModalRef = react_1.default.useRef(null);
80
+ const reload = () => {
81
+ datagridViewRef.current?.reload();
82
+ };
83
+ const loadRowCount = (0, useStableCallback_1.useStableCallback)(() => {
84
+ if (!design.showNumRows) {
54
85
  return;
55
86
  }
56
- let filters = this.props.filters || [];
87
+ let activeFilters = filters || [];
57
88
  // Compile quickfilters
58
- filters = filters.concat(this.getQuickfilterFilters());
59
- this.props.datagridDataSource.countRows(this.props.design, filters, (error, numRows) => {
89
+ activeFilters = activeFilters.concat(getQuickfilterFilters());
90
+ datagridDataSource.countRows(design, activeFilters, (error, count) => {
60
91
  if (error) {
61
92
  console.error(error);
62
93
  alert(T `Error loading data`);
63
94
  return;
64
95
  }
65
- console.log(numRows);
66
- this.setState({ numRows });
96
+ setNumRows(count);
67
97
  });
68
- }
69
- handleRefreshData = () => {
70
- this.props.dataSource.clearCache?.();
71
- this.setState({ refreshKey: this.state.refreshKey + 1 });
72
- };
73
- updateHeight() {
98
+ });
99
+ (0, react_1.useEffect)(() => {
100
+ loadRowCount();
101
+ }, [JSON.stringify(design), JSON.stringify(quickfiltersValues), refreshKey]);
102
+ (0, react_1.useEffect)(() => {
74
103
  // Calculate quickfilters height
75
- if (this.quickfilters) {
76
- if (this.state.quickfiltersHeight !== this.quickfilters.offsetHeight) {
77
- return this.setState({ quickfiltersHeight: this.quickfilters.offsetHeight });
104
+ if (quickfiltersRef.current) {
105
+ if (quickfiltersHeight !== quickfiltersRef.current.offsetHeight) {
106
+ setQuickfiltersHeight(quickfiltersRef.current.offsetHeight);
78
107
  }
79
108
  }
80
109
  else {
81
- return this.setState({ quickfiltersHeight: 0 });
110
+ setQuickfiltersHeight(0);
82
111
  }
83
- }
112
+ }, [quickfiltersRef.current, JSON.stringify(design.quickfilters)]);
113
+ const handleRefreshData = () => {
114
+ dataSource.clearCache?.();
115
+ setRefreshKey(refreshKey + 1);
116
+ };
117
+ const handleDeleteRows = async (signal) => {
118
+ try {
119
+ if (!rowIdsToDelete) {
120
+ return;
121
+ }
122
+ await props.onRowsDelete(design.table, rowIdsToDelete, signal);
123
+ setShowDeleteConfirmation(false);
124
+ // If not aborted, clear selected rows
125
+ if (!signal.aborted) {
126
+ setSelectedRows(new IdSelection_1.default());
127
+ handleRefreshData();
128
+ }
129
+ setRowIdsToDelete(undefined);
130
+ }
131
+ catch (error) {
132
+ if (error.name !== "AbortError") {
133
+ alert(`Error deleting rows: ${error}`);
134
+ }
135
+ }
136
+ };
137
+ const handleShowDeleteConfirmation = async () => {
138
+ setShowDeleteConfirmation(true);
139
+ setLoadingRowIdsToDelete(true);
140
+ setRowIdsToDelete(undefined);
141
+ try {
142
+ // Get row ids
143
+ let rowIds = Object.keys(selectedRows.ids);
144
+ // If inverted, get all ids and remove selected ids
145
+ if (selectedRows.inverted) {
146
+ // Create modified design to just get ids
147
+ const idsDesign = (0, immer_1.default)(design, (draft) => {
148
+ draft.columns = [];
149
+ draft.subtables = [];
150
+ });
151
+ // Create query builder
152
+ const queryBuilder = new DatagridQueryBuilder_1.default(schema);
153
+ const query = queryBuilder.createQuery(idsDesign, {
154
+ extraFilters: filters
155
+ });
156
+ // Perform query
157
+ const rows = await dataSource.performQuery(query);
158
+ rowIds = rows.map((row) => row.id);
159
+ // Remove rows from rowIds
160
+ rowIds = rowIds.filter(id => !selectedRows.ids[id]);
161
+ }
162
+ setRowIdsToDelete(rowIds);
163
+ }
164
+ catch (error) {
165
+ alert(`Error loading rows to delete: ${error}`);
166
+ setShowDeleteConfirmation(false);
167
+ }
168
+ finally {
169
+ setLoadingRowIdsToDelete(false);
170
+ }
171
+ };
84
172
  // Get the values of the quick filters
85
- getQuickfilterValues = () => {
86
- return this.state.quickfiltersValues || [];
173
+ const getQuickfilterValues = () => {
174
+ return quickfiltersValues || [];
87
175
  };
88
- // Get filters that are applied by the quickfilters
89
- getQuickfilterFilters = () => {
90
- return new QuickfilterCompiler_1.default(this.props.schema).compile(this.props.design.quickfilters, this.state.quickfiltersValues, this.props.quickfilterLocks);
176
+ /** Get filters that are applied by the quickfilters */
177
+ const getQuickfilterFilters = () => {
178
+ return new QuickfilterCompiler_1.default(schema).compile(design.quickfilters, quickfiltersValues, quickfilterLocks);
91
179
  };
92
- handleCellEditingToggle = () => {
93
- if (this.state.cellEditingEnabled) {
94
- return this.setState({ cellEditingEnabled: false });
180
+ const handleDataEditingToggle = () => {
181
+ if (dataEditingEnabled) {
182
+ setDataEditingEnabled(false);
95
183
  }
96
184
  else {
97
- if (confirm(T `Turn on cell editing? This will allow you to edit the live data and is an advanced feature.`)) {
98
- return this.setState({ cellEditingEnabled: true });
185
+ if (confirm(T `Turn on data editing? This will allow you to edit the live data and is an advanced feature.`)) {
186
+ setDataEditingEnabled(true);
99
187
  }
100
188
  }
101
189
  };
102
- handleEdit = () => {
103
- return this.setState({ editingDesign: true });
190
+ const handleEdit = () => {
191
+ setEditingDesign(true);
104
192
  };
105
- // Get datagrid filter compiled for quickfilter filtering
106
- getCompiledFilters() {
193
+ /** Get datagrid filter compiled for quickfilter filtering */
194
+ const getCompiledFilters = () => {
107
195
  let jsonql;
108
- const exprCompiler = new expressions_2.ExprCompiler(this.props.schema);
109
- const exprUtils = new expressions_1.ExprUtils(this.props.schema);
110
- const exprCleaner = new expressions_3.ExprCleaner(this.props.schema);
196
+ const exprCompiler = new expressions_2.ExprCompiler(schema);
197
+ const exprUtils = new expressions_1.ExprUtils(schema);
198
+ const exprCleaner = new expressions_3.ExprCleaner(schema);
111
199
  const compiledFilters = [];
112
- if (this.props.design.filter) {
200
+ if (design.filter) {
113
201
  // First clean the filter
114
- const cleanExpr = exprCleaner.cleanExpr(this.props.design.filter, { table: this.props.design.table });
202
+ const cleanExpr = exprCleaner.cleanExpr(design.filter, { table: design.table });
115
203
  jsonql = exprCompiler.compileExpr({ expr: cleanExpr, tableAlias: "{alias}" });
116
204
  if (jsonql) {
117
205
  compiledFilters.push({
118
- table: this.props.design.table,
206
+ table: design.table,
119
207
  jsonql
120
208
  });
121
209
  }
122
210
  }
123
211
  // Add global filters
124
- for (let filter of this.props.design.globalFilters || []) {
212
+ for (let filter of design.globalFilters || []) {
125
213
  // Check if exists and is correct type
126
- const column = this.props.schema.getColumn(this.props.design.table, filter.columnId);
214
+ const column = schema.getColumn(design.table, filter.columnId);
127
215
  if (!column) {
128
216
  continue;
129
217
  }
130
- const columnExpr = { type: "field", table: this.props.design.table, column: column.id };
218
+ const columnExpr = { type: "field", table: design.table, column: column.id };
131
219
  if (exprUtils.getExprType(columnExpr) !== filter.columnType) {
132
220
  continue;
133
221
  }
@@ -135,180 +223,174 @@ class DatagridComponent extends react_1.default.Component {
135
223
  let expr = {
136
224
  type: "op",
137
225
  op: filter.op,
138
- table: this.props.design.table,
226
+ table: design.table,
139
227
  exprs: [columnExpr].concat(filter.exprs)
140
228
  };
141
229
  // Clean expr
142
- expr = exprCleaner.cleanExpr(expr, { table: this.props.design.table });
230
+ expr = exprCleaner.cleanExpr(expr, { table: design.table });
143
231
  jsonql = exprCompiler.compileExpr({ expr, tableAlias: "{alias}" });
144
232
  if (jsonql) {
145
233
  compiledFilters.push({
146
- table: this.props.design.table,
234
+ table: design.table,
147
235
  jsonql
148
236
  });
149
237
  }
150
238
  }
151
239
  return compiledFilters;
152
- }
153
- // Toggle to allow cell editing
154
- renderCellEdit() {
155
- if (!this.props.canEditExpr) {
240
+ };
241
+ const renderDeleteRows = () => {
242
+ if (!props.onRowsDelete || selectedRows.isNone()) {
156
243
  return null;
157
244
  }
158
- const label = [
159
- R("i", { className: this.state.cellEditingEnabled ? "fa fa-fw fa-check-square" : "fa fa-fw fa-square-o" }),
245
+ return react_1.default.createElement("button", { className: "btn btn-link btn-sm", onClick: handleShowDeleteConfirmation },
246
+ react_1.default.createElement("i", { className: "fas fa-times" }),
160
247
  " ",
161
- T `Cell Editing`
162
- ];
163
- return R("a", {
164
- key: "cell-edit",
165
- className: "btn btn-link btn-sm",
166
- onClick: this.handleCellEditingToggle
167
- }, label);
168
- }
169
- renderEditButton() {
170
- if (!this.props.onDesignChange) {
248
+ T `Delete Selected Rows`);
249
+ };
250
+ /** Toggle to allow cell editing */
251
+ const renderCellEdit = () => {
252
+ if (!canEditExpr) {
171
253
  return null;
172
254
  }
173
- return R("button", {
174
- type: "button",
175
- className: "btn btn-primary",
176
- onClick: this.handleEdit
177
- }, R("span", { className: "fas fa-cog" }), " ", T `Settings`);
178
- }
179
- renderFindReplace() {
180
- if (!this.state.cellEditingEnabled) {
255
+ const label = react_1.default.createElement(react_1.default.Fragment, null,
256
+ react_1.default.createElement("i", { className: dataEditingEnabled ? "fa fa-fw fa-check-square" : "fa fa-fw fa-square-o" }),
257
+ " ",
258
+ T `Data Editing`);
259
+ return (react_1.default.createElement("a", { key: "cell-edit", className: "btn btn-link btn-sm", onClick: handleDataEditingToggle }, label));
260
+ };
261
+ const renderEditButton = () => {
262
+ if (!onDesignChange) {
181
263
  return null;
182
264
  }
183
- return R("a", {
184
- key: "findreplace",
185
- className: "btn btn-link btn-sm",
186
- onClick: () => this.findReplaceModal.show()
187
- }, T `Find/Replace`);
188
- }
189
- renderTitleBar() {
190
- return R("div", { style: { position: "absolute", top: 0, left: 0, right: 0, height: 40, padding: 4 } }, R("div", { style: { float: "right" } }, this.props.design.showNumRows && this.state.numRows ? R("small", { className: 'text-muted text-sm' }, `${(0, d3_format_1.format)(',')(this.state.numRows)} rows`) : undefined, this.renderFindReplace(), this.renderCellEdit(), this.renderEditButton(), R("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: this.handleRefreshData }, R("span", { className: "fas fa-sync" }), R("span", { className: "hide-600px" }, T `Refresh`)), this.props.extraTitleButtonsElem), this.props.titleElem);
191
- }
192
- renderQuickfilter() {
193
- return R("div", {
194
- style: { position: "absolute", top: 40, left: 0, right: 0 },
195
- ref: (c) => {
196
- this.quickfilters = c;
197
- }
198
- }, R(QuickfiltersComponent_1.default, {
199
- design: this.props.design.quickfilters,
200
- schema: this.props.schema,
201
- dataSource: this.props.dataSource,
202
- quickfiltersDataSource: this.props.datagridDataSource.getQuickfiltersDataSource(),
203
- values: this.state.quickfiltersValues || [],
204
- onValuesChange: (values) => this.setState({ quickfiltersValues: values }),
205
- locks: this.props.quickfilterLocks,
206
- filters: this.getCompiledFilters()
207
- }));
208
- }
265
+ return (react_1.default.createElement("button", { type: "button", className: "btn btn-primary", onClick: handleEdit },
266
+ react_1.default.createElement("span", { className: "fas fa-cog" }),
267
+ " ",
268
+ T `Settings`));
269
+ };
270
+ const renderFindReplace = () => {
271
+ if (!dataEditingEnabled) {
272
+ return null;
273
+ }
274
+ return (react_1.default.createElement("a", { key: "findreplace", className: "btn btn-link btn-sm", onClick: () => findReplaceModalRef.current.show() }, T `Find/Replace`));
275
+ };
276
+ const renderTitleBar = () => {
277
+ return (react_1.default.createElement("div", { style: { position: "absolute", top: 0, left: 0, right: 0, height: 40, padding: 4 } },
278
+ react_1.default.createElement("div", { style: { float: "right" } },
279
+ design.showNumRows && numRows ? react_1.default.createElement("small", { className: 'text-muted text-sm' }, `${(0, d3_format_1.format)(',')(numRows)} rows`) : undefined,
280
+ renderDeleteRows(),
281
+ renderFindReplace(),
282
+ renderCellEdit(),
283
+ renderEditButton(),
284
+ react_1.default.createElement("a", { key: "refresh", className: "btn btn-link btn-sm", onClick: handleRefreshData },
285
+ react_1.default.createElement("span", { className: "fas fa-sync" }),
286
+ " ",
287
+ react_1.default.createElement("span", { className: "hide-600px" }, T `Refresh`)),
288
+ extraTitleButtonsElem),
289
+ titleElem));
290
+ };
291
+ const renderQuickfilter = () => {
292
+ return (react_1.default.createElement("div", { style: { position: "absolute", top: 40, left: 0, right: 0 }, ref: quickfiltersRef },
293
+ react_1.default.createElement(QuickfiltersComponent_1.default, { design: design.quickfilters, schema: schema, dataSource: dataSource, quickfiltersDataSource: datagridDataSource.getQuickfiltersDataSource(), values: quickfiltersValues || [], onValuesChange: (values) => setQuickfiltersValues(values), locks: quickfilterLocks, filters: getCompiledFilters() })));
294
+ };
209
295
  // Renders the editor modal
210
- renderEditor() {
211
- if (!this.state.editingDesign) {
212
- return;
296
+ const renderEditor = () => {
297
+ if (!editingDesign) {
298
+ return null;
213
299
  }
214
- return R(DatagridEditorComponent, {
215
- schema: this.props.schema,
216
- dataSource: this.props.dataSource,
217
- design: this.props.design,
218
- onDesignChange: (design) => {
300
+ return (react_1.default.createElement(DatagridEditorComponent, { schema: schema, dataSource: dataSource, design: design, onDesignChange: (newDesign) => {
219
301
  // If quickfilters have changed, reset values
220
- if (!lodash_1.default.isEqual(this.props.design.quickfilters, design.quickfilters)) {
221
- this.setState({ quickfiltersValues: null });
302
+ if (!lodash_1.default.isEqual(design.quickfilters, newDesign.quickfilters)) {
303
+ setQuickfiltersValues(null);
222
304
  }
223
- this.props.onDesignChange(design);
224
- return this.setState({ editingDesign: false });
225
- },
226
- onCancel: () => this.setState({ editingDesign: false })
227
- });
228
- }
229
- renderFindReplaceModal(filters) {
230
- return R(FindReplaceModalComponent_1.default, {
231
- ref: (c) => {
232
- this.findReplaceModal = c;
233
- },
234
- schema: this.props.schema,
235
- dataSource: this.props.dataSource,
236
- datagridDataSource: this.props.datagridDataSource,
237
- design: this.props.design,
238
- filters,
239
- updateExprValues: this.props.updateExprValues,
240
- onUpdate: () => {
305
+ onDesignChange(newDesign);
306
+ setEditingDesign(false);
307
+ }, onCancel: () => setEditingDesign(false) }));
308
+ };
309
+ const renderFindReplaceModal = (filters) => {
310
+ return (react_1.default.createElement(FindReplaceModalComponent_1.default, { ref: findReplaceModalRef, schema: schema, dataSource: dataSource, design: design, filters: filters, updateExprValues: updateExprValues, onUpdate: () => {
241
311
  // Reload
242
- return this.datagridView?.reload();
243
- }
244
- });
245
- }
246
- render() {
247
- let filters = this.props.filters || [];
248
- // Compile quickfilters
249
- filters = filters.concat(this.getQuickfilterFilters());
250
- return R(expressions_ui_1.LocaleContext.Provider, { value: this.props.design.locale || "en" }, R("div", {
251
- style: {
312
+ datagridViewRef.current?.reload();
313
+ } }));
314
+ };
315
+ let activeFilters = filters || [];
316
+ // Compile quickfilters
317
+ activeFilters = activeFilters.concat(getQuickfilterFilters());
318
+ (0, react_1.useImperativeHandle)(ref, () => ({
319
+ getQuickfilterValues,
320
+ getQuickfilterFilters,
321
+ reload
322
+ }));
323
+ return (react_1.default.createElement(expressions_ui_1.LocaleContext.Provider, { value: design.locale || "en" },
324
+ react_1.default.createElement("div", { style: {
252
325
  width: "100%",
253
326
  height: "100%",
254
327
  position: "relative",
255
- paddingTop: 40 + (this.state.quickfiltersHeight || 0)
256
- }
257
- }, this.renderTitleBar(), this.renderQuickfilter(), this.renderEditor(), this.renderFindReplaceModal(filters), R(AutoSizeComponent_1.default, { injectWidth: true, injectHeight: true }, (size) => {
258
- // Clean before displaying
259
- const design = new DatagridUtils_1.default(this.props.schema).cleanDesign(this.props.design);
260
- if (!new DatagridUtils_1.default(this.props.schema).validateDesign(design)) {
261
- return R(DatagridViewComponent_1.default, {
262
- ref: (view) => {
263
- this.datagridView = view;
264
- },
265
- width: size.width - 1, // minus 1 px to test if it solves the jitter with scroll
266
- height: size.height - 1,
267
- pageSize: 100,
268
- schema: this.props.schema,
269
- dataSource: this.props.dataSource,
270
- datagridDataSource: this.props.datagridDataSource,
271
- design,
272
- filters,
273
- onDesignChange: this.props.onDesignChange,
274
- onRowClick: this.props.onRowClick,
275
- onRowDoubleClick: this.props.onRowDoubleClick,
276
- canEditExpr: this.state.cellEditingEnabled ? this.props.canEditExpr : undefined,
277
- updateExprValues: this.state.cellEditingEnabled ? this.props.updateExprValues : undefined,
278
- refreshKey: this.state.refreshKey
279
- });
280
- }
281
- else if (this.props.onDesignChange) {
282
- return R("div", { style: { textAlign: "center", marginTop: size.height / 2 } }, R("a", { className: "btn btn-link", onClick: this.handleEdit }, T `Click Here to Configure`));
283
- }
284
- else {
285
- return null;
286
- }
287
- })));
288
- }
289
- }
290
- exports.default = DatagridComponent;
328
+ paddingTop: 40 + (quickfiltersHeight || 0)
329
+ } },
330
+ renderTitleBar(),
331
+ renderQuickfilter(),
332
+ renderEditor(),
333
+ renderFindReplaceModal(activeFilters),
334
+ showDeleteConfirmation && (react_1.default.createElement(DeleteConfirmationModal, { onConfirm: handleDeleteRows, onCancel: () => {
335
+ setShowDeleteConfirmation(false);
336
+ setRowIdsToDelete(undefined);
337
+ }, numRows: rowIdsToDelete?.length, loadingNumRows: loadingRowIdsToDelete })),
338
+ react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true, injectHeight: true }, (size) => {
339
+ // Clean before displaying
340
+ const cleanedDesign = new DatagridUtils_1.default(schema).cleanDesign(design);
341
+ if (!new DatagridUtils_1.default(schema).validateDesign(cleanedDesign)) {
342
+ return (react_1.default.createElement(DatagridViewComponent_1.default, { ref: datagridViewRef, width: size.width - 1, height: size.height - 1, pageSize: 100, schema: schema, dataSource: dataSource, datagridDataSource: datagridDataSource, design: cleanedDesign, filters: activeFilters, onDesignChange: onDesignChange, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, selectedRows: dataEditingEnabled && props.onRowsDelete != null ? selectedRows : undefined, onSelectedRowsChange: dataEditingEnabled && props.onRowsDelete != null ? setSelectedRows : undefined, canEditExpr: dataEditingEnabled ? canEditExpr : undefined, updateExprValues: dataEditingEnabled ? updateExprValues : undefined, refreshKey: refreshKey }));
343
+ }
344
+ else if (onDesignChange) {
345
+ return (react_1.default.createElement("div", { style: { textAlign: "center", marginTop: size.height / 2 } },
346
+ react_1.default.createElement("a", { className: "btn btn-link", onClick: handleEdit }, T `Click Here to Configure`)));
347
+ }
348
+ else {
349
+ return null;
350
+ }
351
+ }))));
352
+ });
291
353
  /** Popup editor */
292
- class DatagridEditorComponent extends react_1.default.Component {
293
- constructor(props) {
294
- super(props);
295
- this.state = {
296
- design: props.design
297
- };
298
- }
299
- render() {
300
- return R(ActionCancelModalComponent_1.default, {
301
- onAction: () => {
302
- this.props.onDesignChange(this.state.design);
303
- return this.setState({ design: this.props.design });
304
- },
305
- onCancel: this.props.onCancel,
306
- size: "large"
307
- }, R(DatagridDesignerComponent_1.default, {
308
- schema: this.props.schema,
309
- dataSource: this.props.dataSource,
310
- design: this.state.design,
311
- onDesignChange: (design) => this.setState({ design })
312
- }));
313
- }
354
+ function DatagridEditorComponent(props) {
355
+ const { schema, dataSource, design, onDesignChange, onCancel } = props;
356
+ const [localDesign, setLocalDesign] = (0, react_1.useState)(design);
357
+ return (react_1.default.createElement(ActionCancelModalComponent_1.default, { onAction: () => {
358
+ onDesignChange(localDesign);
359
+ setLocalDesign(design);
360
+ }, onCancel: onCancel, size: "large" },
361
+ react_1.default.createElement(DatagridDesignerComponent_1.default, { schema: schema, dataSource: dataSource, design: localDesign, onDesignChange: (design) => setLocalDesign(design) })));
362
+ }
363
+ /** Modal that confirms deletion of rows */
364
+ function DeleteConfirmationModal(props) {
365
+ const { onConfirm, onCancel, numRows, loadingNumRows } = props;
366
+ const [confirmed, setConfirmed] = (0, react_1.useState)(false);
367
+ const [deleting, setDeleting] = (0, react_1.useState)(false);
368
+ const abortControllerRef = (0, react_1.useRef)();
369
+ // If more than 1000 rows, show an error
370
+ const tooManyRows = numRows && numRows > 1000;
371
+ const handleConfirm = async () => {
372
+ setDeleting(true);
373
+ abortControllerRef.current = new AbortController();
374
+ try {
375
+ await onConfirm(abortControllerRef.current.signal);
376
+ }
377
+ finally {
378
+ setDeleting(false);
379
+ }
380
+ };
381
+ const handleCancel = () => {
382
+ if (deleting) {
383
+ abortControllerRef.current?.abort();
384
+ }
385
+ onCancel();
386
+ };
387
+ return (react_1.default.createElement(ActionCancelModalComponent_1.default, { title: T `Confirm Delete`, onAction: handleConfirm, onCancel: handleCancel, actionLabel: T `Delete`, size: "normal", actionBusy: deleting, actionDisabled: !confirmed || loadingNumRows },
388
+ react_1.default.createElement("div", null,
389
+ loadingNumRows ? (react_1.default.createElement("div", { className: "text-muted" },
390
+ react_1.default.createElement("i", { className: "fa fa-spinner fa-spin" }),
391
+ " ",
392
+ T `Loading rows to delete...`)) : (react_1.default.createElement("div", null, T `This will permanently delete ${(0, d3_format_1.format)(",")(numRows || 0)} row(s).`)),
393
+ tooManyRows && (react_1.default.createElement("div", { className: "alert alert-danger" }, T `Cannot delete more than 1000 rows at a time.`)),
394
+ !tooManyRows && numRows && numRows > 0 && (react_1.default.createElement("div", { className: "mt-3" },
395
+ react_1.default.createElement(bootstrap_1.Checkbox, { value: confirmed, onChange: setConfirmed }, T `I understand that this action cannot be undone`))))));
314
396
  }