@adaptabletools/adaptable-cjs 21.0.11 → 21.1.0-canary.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 (63) hide show
  1. package/base.css +1811 -2336
  2. package/base.css.map +1 -1
  3. package/index.css +1768 -1413
  4. package/index.css.map +1 -1
  5. package/package.json +3 -3
  6. package/src/AdaptableInterfaces/IAdaptable.d.ts +2 -1
  7. package/src/AdaptableOptions/FilterOptions.d.ts +7 -0
  8. package/src/AdaptableOptions/PredicateOptions.d.ts +4 -3
  9. package/src/AdaptableState/Common/AdaptableColumn.d.ts +1 -1
  10. package/src/AdaptableState/Common/AdaptablePredicate.d.ts +12 -0
  11. package/src/AdaptableState/Common/AdaptablePredicate.js +132 -18
  12. package/src/AdaptableState/Selection/GridCell.d.ts +10 -0
  13. package/src/Api/Implementation/ExportApiImpl.js +1 -7
  14. package/src/Api/Implementation/PredicateApiImpl.d.ts +3 -1
  15. package/src/Api/Implementation/PredicateApiImpl.js +27 -3
  16. package/src/Api/Internal/AdaptableInternalApi.d.ts +2 -1
  17. package/src/Api/Internal/AdaptableInternalApi.js +6 -0
  18. package/src/Api/Internal/PredicateInternalApi.d.ts +3 -1
  19. package/src/Api/Internal/PredicateInternalApi.js +14 -0
  20. package/src/Api/PredicateApi.d.ts +1 -1
  21. package/src/Redux/Store/AdaptableStore.js +111 -3
  22. package/src/Utilities/Helpers/Helper.js +26 -2
  23. package/src/Utilities/Hooks/index.d.ts +4 -0
  24. package/src/Utilities/Hooks/index.js +9 -0
  25. package/src/Utilities/Hooks/useAdaptableColumn.d.ts +2 -0
  26. package/src/Utilities/Hooks/useAdaptableColumn.js +10 -0
  27. package/src/Utilities/Hooks/useAdaptableOptions.d.ts +2 -0
  28. package/src/Utilities/Hooks/useAdaptableOptions.js +9 -0
  29. package/src/Utilities/Hooks/useAdaptableState.d.ts +3 -0
  30. package/src/Utilities/Hooks/useAdaptableState.js +43 -0
  31. package/src/Utilities/adaptableQlUtils.js +3 -0
  32. package/src/View/AdaptableComputedCSSVarsContext.d.ts +12 -0
  33. package/src/View/AdaptableComputedCSSVarsContext.js +32 -0
  34. package/src/View/Components/AdaptableInput/AdaptableDateInlineInput.d.ts +1 -1
  35. package/src/View/Components/ColumnFilter/FloatingFilter.js +5 -1
  36. package/src/View/Components/ColumnFilter/components/FloatingFilterInputList.js +1 -1
  37. package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +34 -9
  38. package/src/View/Components/FilterForm/ListBoxFilterForm.d.ts +1 -0
  39. package/src/View/Components/FilterForm/ListBoxFilterForm.js +93 -16
  40. package/src/View/Layout/Wizard/sections/ColumnsSection.js +1 -1
  41. package/src/View/renderWithAdaptableContext.js +3 -1
  42. package/src/agGrid/AdaptableAgGrid.d.ts +3 -1
  43. package/src/agGrid/AdaptableAgGrid.js +360 -23
  44. package/src/agGrid/AdaptableFilterHandler.d.ts +3 -1
  45. package/src/agGrid/AdaptableFilterHandler.js +16 -12
  46. package/src/agGrid/AgGridAdapter.js +12 -6
  47. package/src/agGrid/AgGridColumnAdapter.js +19 -13
  48. package/src/components/OverlayTrigger/index.js +1 -1
  49. package/src/components/Select/Select.js +21 -21
  50. package/src/components/Tree/TreeDropdown/index.d.ts +27 -0
  51. package/src/components/Tree/TreeDropdown/index.js +256 -0
  52. package/src/components/Tree/TreeList/index.d.ts +25 -0
  53. package/src/components/Tree/TreeList/index.js +40 -0
  54. package/src/devTools/DevToolsTracks.d.ts +31 -0
  55. package/src/devTools/DevToolsTracks.js +34 -0
  56. package/src/devTools/PerfMarker.d.ts +12 -0
  57. package/src/devTools/PerfMarker.js +2 -0
  58. package/src/devTools/index.d.ts +102 -0
  59. package/src/devTools/index.js +165 -0
  60. package/src/env.js +2 -2
  61. package/src/layout-manager/src/index.d.ts +2 -0
  62. package/src/layout-manager/src/index.js +24 -0
  63. package/tsconfig.cjs.tsbuildinfo +1 -1
@@ -12,6 +12,7 @@ const agGridDataTypeDefinitions_1 = require("./agGridDataTypeDefinitions");
12
12
  const ColumnApiImpl_1 = require("../Api/Implementation/ColumnApiImpl");
13
13
  const isPivotColumnTotal_1 = require("../layout-manager/src/isPivotColumnTotal");
14
14
  const isPivotAggTotalColumn_1 = require("../layout-manager/src/isPivotAggTotalColumn");
15
+ const AggregationColumns_1 = require("../AdaptableState/Common/AggregationColumns");
15
16
  // AG GRID obfuscates its internals, this is (currently) the best way to get hold of its internal services
16
17
  const DANGER_AG_GRID_BEANS_MAP = {};
17
18
  const getColumnApiModule = () => ag_grid_enterprise_1.ColumnApiModule;
@@ -27,7 +28,7 @@ class AgGridAdapter {
27
28
  const ColumnDefFactory_Prototye_preWireBeans = ColumnDefFactory_Prototype.preWireBeans;
28
29
  ColumnDefFactory_Prototype.preWireBeans = function (beans) {
29
30
  ColumnDefFactory_Prototye_preWireBeans?.apply(this, arguments);
30
- const gridId = beans?.context?.getGridId();
31
+ const gridId = beans?.context?.getId();
31
32
  if (!gridId) {
32
33
  console.error('CRITICAL: No gridId found in beans, this should never happen!');
33
34
  }
@@ -140,7 +141,8 @@ class AgGridAdapter {
140
141
  }
141
142
  const pivotColumnFilters = self.adaptableApi.filterApi.columnFilterApi
142
143
  .getActiveColumnFilters()
143
- .filter((columnFilter) => self.adaptableApi.columnApi.isPivotResultColumn(columnFilter.ColumnId));
144
+ .filter((columnFilter) => self.adaptableApi.columnApi.isPivotResultColumn(columnFilter.ColumnId) ||
145
+ self.adaptableApi.columnApi.isAutoRowGroupColumnForSingle(columnFilter.ColumnId));
144
146
  try {
145
147
  if (pivotColumnFilters.length > 0) {
146
148
  for (const columnFilter of pivotColumnFilters) {
@@ -163,7 +165,8 @@ class AgGridAdapter {
163
165
  agGridColumnFilterService.doFiltersPass = this.DANGER_doFiltersPassMonkeyPatcher;
164
166
  this.DANGER_isAggFilterPresentMonkeyPatcher = function () {
165
167
  const columnFilters = self.adaptableApi.filterApi.columnFilterApi.getActiveColumnFilters();
166
- return columnFilters.some((colFilter) => self.adaptableApi.columnApi.isPivotResultColumn(colFilter.ColumnId));
168
+ return columnFilters.some((colFilter) => self.adaptableApi.columnApi.isPivotResultColumn(colFilter.ColumnId) ||
169
+ self.adaptableApi.columnApi.isAutoRowGroupColumnForSingle(colFilter.ColumnId));
167
170
  };
168
171
  agGridColumnFilterService.isAggFilterPresent = this.DANGER_isAggFilterPresentMonkeyPatcher;
169
172
  }
@@ -487,8 +490,10 @@ class AgGridAdapter {
487
490
  this.logger.warn(`Column is undefined, returning 'text' for Type`);
488
491
  return 'text';
489
492
  }
490
- if (this.adaptableApi.columnApi.isAutoRowGroupColumnForSingle(agColumn.getId()) ||
491
- this.adaptableApi.columnApi.isSelectionColumn(agColumn.getId())) {
493
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumnForSingle(agColumn.getId())) {
494
+ return 'groupColumn';
495
+ }
496
+ if (this.adaptableApi.columnApi.isSelectionColumn(agColumn.getId())) {
492
497
  return 'unknown';
493
498
  }
494
499
  if (this.adaptableApi.columnApi.isAutoRowGroupColumnForMulti(agColumn.getId())) {
@@ -612,9 +617,10 @@ class AgGridAdapter {
612
617
  return false;
613
618
  }
614
619
  getColumnAggregationFunctions(colDef) {
615
- const result = colDef.allowedAggFuncs || ['sum', 'min', 'max', 'count', 'avg', 'first', 'last']; // those are the default fns aggrid supports out-of-the-box
620
+ let result = [].concat(colDef.allowedAggFuncs || ['sum', 'min', 'max', 'count', 'avg', 'first', 'last']); // those are the default fns aggrid supports out-of-the-box
616
621
  const gridOptionsAggFuncs = this.adaptableApi.agGridApi.getGridOption('aggFuncs') || {};
617
622
  result.push(...Object.keys(gridOptionsAggFuncs));
623
+ result = result.filter((func) => !(0, AggregationColumns_1.isWeightedAverageAggFuncName)(func));
618
624
  return [...new Set(result)];
619
625
  }
620
626
  isTreeColumn(isGeneratedRowGroupColumn) {
@@ -21,6 +21,7 @@ const AdaptableFilterHandler_1 = require("./AdaptableFilterHandler");
21
21
  const AgGridFilterAdapter_1 = require("./AgGridFilterAdapter");
22
22
  const AgGridFloatingFilterAdapter_1 = require("./AgGridFloatingFilterAdapter");
23
23
  const AdaptableLogger_1 = require("./AdaptableLogger");
24
+ const AggregationColumns_1 = require("../AdaptableState/Common/AggregationColumns");
24
25
  function getEditorForColumnDataType(columnDataType, variant) {
25
26
  if (columnDataType === 'number') {
26
27
  return variant === 'react' ? AdaptableNumberEditor_1.AdaptableReactNumberEditor : AdaptableNumberEditor_1.AdaptableNumberEditor;
@@ -521,7 +522,10 @@ class AgGridColumnAdapter {
521
522
  }
522
523
  setupColumnAllowedAggFuncs({ col, abColumn }) {
523
524
  this.setColDefProperty(col, 'allowedAggFuncs', () => {
524
- return abColumn.availableAggregationFunctions;
525
+ if (!abColumn.availableAggregationFunctions) {
526
+ return undefined;
527
+ }
528
+ return abColumn.availableAggregationFunctions.filter((func) => !(0, AggregationColumns_1.isWeightedAverageAggFuncName)(func));
525
529
  });
526
530
  }
527
531
  setupColumnType(columnSetupInfo) {
@@ -593,31 +597,33 @@ class AgGridColumnAdapter {
593
597
  });
594
598
  }
595
599
  else {
600
+ // TODO only set auto group column as filterable if at least one group columns is filterable
596
601
  this.setColDefProperty(col, 'filter', () => {
597
602
  return 'agGroupColumnFilter';
598
603
  });
599
604
  }
600
- return;
605
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumnForMulti(colId)) {
606
+ return;
607
+ }
601
608
  }
602
609
  // setup "normal" column filter
603
610
  this.setColDefProperty(col, 'filter', (original_filter) => {
604
- if (!colDef.filter) {
605
- return;
606
- }
611
+ const pivotMode = this.adaptableInstance.isInPivotMode();
607
612
  if (!useAdaptableFilter) {
608
613
  return original_filter;
609
614
  }
610
- if (useAdaptableFilter &&
611
- typeof original_filter !== 'boolean' &&
615
+ if (!colDef.filter) {
616
+ return;
617
+ }
618
+ if (typeof original_filter !== 'boolean' &&
612
619
  typeof original_filter?.handler !== 'function' &&
613
- !this.adaptableInstance.isInPivotMode()) {
620
+ !pivotMode) {
614
621
  this.adaptableApi.consoleError(`Column '${colId}' has a custom filter defined in colDef.filter, but Adaptable Filtering accepts only the TRUE/FALSE values!`);
615
622
  return false;
616
623
  }
617
624
  return {
618
625
  component: (0, AgGridFilterAdapter_1.AgGridFilterAdapterFactory)(this.adaptableInstance),
619
- // doesFilterPass,
620
- handler: (params) => new AdaptableFilterHandler_1.AdaptableFilterHandler(this.adaptableApi, columnSetup),
626
+ handler: () => new AdaptableFilterHandler_1.AdaptableFilterHandler(this.adaptableApi, columnSetup),
621
627
  };
622
628
  });
623
629
  }
@@ -634,7 +640,7 @@ class AgGridColumnAdapter {
634
640
  !colDef.floatingFilter ||
635
641
  !this.adaptableOptions.filterOptions.useAdaptableFiltering ||
636
642
  !this.adaptableApi.filterApi.columnFilterApi.isQuickFilterVisible();
637
- if (this.adaptableApi.columnApi.isAutoRowGroupColumn(col.getColId())) {
643
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumnForMulti(col.getColId())) {
638
644
  this.setColDefProperty(col, 'floatingFilter', (original_floatingFilter) => {
639
645
  // the floating filter for the group column is "inherited" from the base column
640
646
  // via the colDef.filter = 'agGroupColumnFilter'
@@ -645,7 +651,7 @@ class AgGridColumnAdapter {
645
651
  });
646
652
  this.setColDefProperty(col, 'suppressFloatingFilterButton', () => {
647
653
  // hide button for multi column groups
648
- return this.adaptableApi.columnApi.isAutoRowGroupColumnForMulti(col.getColId());
654
+ return true;
649
655
  });
650
656
  return;
651
657
  }
@@ -655,7 +661,7 @@ class AgGridColumnAdapter {
655
661
  }
656
662
  return (0, AgGridFloatingFilterAdapter_1.AgGridFloatingFilterAdapterFactory)(this.adaptableInstance);
657
663
  });
658
- this.setColDefProperty(col, 'floatingFilter', (original_floatingFilter) => {
664
+ this.setColDefProperty(col, 'floatingFilter', () => {
659
665
  if (isFloatingFilterDisabled) {
660
666
  return;
661
667
  }
@@ -200,7 +200,7 @@ const OverlayTrigger = React.forwardRef((givenProps, ref) => {
200
200
  clearAllOverlays();
201
201
  hideOverlay('overlay-trigger');
202
202
  }
203
- } }, props.render({ targetWidth: targetWidth })));
203
+ } }, props.render({ targetWidth })));
204
204
  let preparedConstrainTo;
205
205
  if (constrainTo) {
206
206
  preparedConstrainTo = (0, exports.getConstrainElement)(targetRef.current, constrainTo);
@@ -14,7 +14,8 @@ const join_1 = tslib_1.__importDefault(require("../utils/join"));
14
14
  const re_resizable_1 = require("re-resizable");
15
15
  const Tooltip_1 = tslib_1.__importDefault(require("../Tooltip"));
16
16
  const OverlayTrigger_1 = require("../OverlayTrigger");
17
- const CSSNumericVariableWatch_1 = require("./CSSNumericVariableWatch");
17
+ const CheckBox_1 = require("../CheckBox");
18
+ const AdaptableComputedCSSVarsContext_1 = require("../../View/AdaptableComputedCSSVarsContext");
18
19
  const resizableDirections = {
19
20
  right: true,
20
21
  bottom: true,
@@ -56,15 +57,27 @@ const INFINITE_COLUMNS_WITH_CHECKBOX = {
56
57
  renderSelectionCheckBox: (params) => {
57
58
  // disable reacting to onChange
58
59
  // as we handle selection change in the onCellClick
59
- return React.createElement(infinite_react_1.components.CheckBox, { checked: params.rowInfo?.rowSelected ?? false });
60
+ return React.createElement(CheckBox_1.CheckBox, { mx: 1, checked: params.rowInfo?.rowSelected ?? false });
60
61
  },
61
62
  renderHeaderSelectionCheckBox: true,
62
63
  className: 'ab-Select-CheckboxColumn',
63
64
  renderValue,
64
65
  renderHeader: (headerParams) => {
66
+ const selected = headerParams.allRowsSelected
67
+ ? true
68
+ : headerParams.someRowsSelected
69
+ ? null
70
+ : false;
71
+ const { api } = headerParams;
65
72
  return (React.createElement(React.Fragment, null,
66
- headerParams.renderBag.selectionCheckBox,
67
- headerParams.allRowsSelected ? '(Deselect All)' : '(Select All)'));
73
+ React.createElement(CheckBox_1.CheckBox, { mx: 1, checked: selected, onChange: (selected) => {
74
+ if (selected) {
75
+ api.rowSelectionApi.selectAll();
76
+ }
77
+ else {
78
+ api.rowSelectionApi.deselectAll();
79
+ }
80
+ } }, headerParams.allRowsSelected ? '(Deselect All)' : '(Select All)')));
68
81
  },
69
82
  renderMenuIcon: false,
70
83
  },
@@ -106,15 +119,11 @@ const doesOptionMatchValue = function (value) {
106
119
  };
107
120
  const Select = function (props) {
108
121
  let maxLabelLength = 0;
109
- const cssVarsValuesRef = React.useRef({
110
- '--ab-cmp-select-menu__max-width': 0,
111
- '--ab-cmp-select-menu__min-width': 0,
112
- '--ab-cmp-select-menu__max-height': 0,
113
- });
122
+ const computedCSSVars = (0, AdaptableComputedCSSVarsContext_1.useAdaptableComputedCSSVars)();
114
123
  const CSS_VARS_VALUES = {
115
- '--ab-cmp-select-menu__max-width': cssVarsValuesRef.current['--ab-cmp-select-menu__max-width'] || '60vw',
116
- '--ab-cmp-select-menu__min-width': cssVarsValuesRef.current['--ab-cmp-select-menu__min-width'] || 150,
117
- '--ab-cmp-select-menu__max-height': cssVarsValuesRef.current['--ab-cmp-select-menu__max-height'] || '60vh',
124
+ '--ab-cmp-select-menu__max-width': computedCSSVars['--ab-cmp-select-menu__max-width'] || '60vw',
125
+ '--ab-cmp-select-menu__min-width': computedCSSVars['--ab-cmp-select-menu__min-width'] || 150,
126
+ '--ab-cmp-select-menu__max-height': computedCSSVars['--ab-cmp-select-menu__max-height'] || '60vh',
118
127
  };
119
128
  const searchableInMenulist = props.searchable === 'menulist';
120
129
  const searchableInline = props.searchable === 'inline';
@@ -517,15 +526,6 @@ const Select = function (props) {
517
526
  props.onInputChange?.(value);
518
527
  }, [props.onInputChange, isMulti]);
519
528
  return (React.createElement(React.Fragment, null,
520
- React.createElement(CSSNumericVariableWatch_1.CSSNumericVariableWatch, { varName: "--ab-cmp-select-menu__max-width", onChange: (value) => {
521
- cssVarsValuesRef.current['--ab-cmp-select-menu__max-width'] = value;
522
- } }),
523
- React.createElement(CSSNumericVariableWatch_1.CSSNumericVariableWatch, { varName: "--ab-cmp-select-menu__min-width", onChange: (value) => {
524
- cssVarsValuesRef.current['--ab-cmp-select-menu__min-width'] = value;
525
- } }),
526
- React.createElement(CSSNumericVariableWatch_1.CSSNumericVariableWatch, { varName: "--ab-cmp-select-menu__max-height", onChange: (value) => {
527
- cssVarsValuesRef.current['--ab-cmp-select-menu__max-height'] = value;
528
- } }),
529
529
  React.createElement(SelectComponent, { ref: ref, openMenuOnClick: searchableInMenulist ? false : undefined, openMenuOnFocus: searchableInMenulist ? false : undefined, menuIsOpen: searchableInMenulist ? isSelectMenuOpen : undefined, isSearchable: searchableInline, "aria-label": props['aria-label'], onKeyDown: props.onKeyDown, inputValue: inputValue, onInputChange: onInputChange, onFocus: onFocus, onBlur: onBlur, onMenuOpen: props.onMenuOpen, isLoading: props.isLoading, options: props.options, className: (0, join_1.default)(props.className, 'ab-Select'), isDisabled: disabled, menuPlacement: props.menuPlacement ?? 'auto', hideSelectedOptions: false, isMulti: isMulti, value: selectedOption, blurInputOnSelect: false, menuPosition: props.menuPosition ?? 'absolute',
530
530
  // This needed so the menu is not clipped by overflow: hidden
531
531
  menuPortalTarget: (0, OverlayTrigger_1.ensurePortalElement)(), isClearable: props.isClearable, closeMenuOnSelect: props.closeMenuOnSelect, onChange: (option) => {
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import { TreeListItem, TreeListProps } from '../TreeList';
3
+ export type TreeDropdownProps<T extends TreeListItem<any>> = {
4
+ placeholder?: string;
5
+ style?: React.CSSProperties;
6
+ fieldStyle?: React.CSSProperties;
7
+ listSizeConstraints?: {
8
+ minWidth?: number | string;
9
+ maxWidth?: number | string;
10
+ minHeight?: number | string;
11
+ maxHeight?: number | string;
12
+ };
13
+ options: TreeListProps<T>['options'];
14
+ labelField?: string;
15
+ primaryKey?: keyof T;
16
+ value?: any[][] | string[];
17
+ defaultValue?: any[][] | string[];
18
+ toDisplayValue?: (value: any[][] | string[]) => string;
19
+ onChange: (value: any[][] | string[]) => void;
20
+ onMenuOpen?: () => void;
21
+ onMenuClose?: () => void;
22
+ onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;
23
+ resizable?: boolean;
24
+ clearable?: boolean;
25
+ };
26
+ export declare function toDisplayValueDefault(value: any[][] | string[]): string;
27
+ export declare function TreeDropdown<T extends TreeListItem<any>>(props: TreeDropdownProps<T>): React.JSX.Element;
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeDropdown = exports.toDisplayValueDefault = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const React = tslib_1.__importStar(require("react"));
6
+ const FieldWrap_1 = tslib_1.__importDefault(require("../../FieldWrap"));
7
+ const TreeList_1 = require("../TreeList");
8
+ const react_1 = require("react");
9
+ const OverlayTrigger_1 = tslib_1.__importDefault(require("../../OverlayTrigger"));
10
+ const rebass_1 = require("rebass");
11
+ const NotifyResize_1 = tslib_1.__importDefault(require("../../NotifyResize"));
12
+ const Input_1 = tslib_1.__importDefault(require("../../Input"));
13
+ const InfiniteTable_1 = require("../../InfiniteTable");
14
+ const SimpleButton_1 = tslib_1.__importDefault(require("../../SimpleButton"));
15
+ const CheckBox_1 = require("../../CheckBox");
16
+ const useLatest_1 = require("../../utils/useLatest");
17
+ const re_resizable_1 = require("re-resizable");
18
+ const AdaptableComputedCSSVarsContext_1 = require("../../../View/AdaptableComputedCSSVarsContext");
19
+ const resizableDirections = {
20
+ right: true,
21
+ bottom: true,
22
+ bottomRight: true,
23
+ };
24
+ function toDisplayValueDefault(value) {
25
+ if (!Array.isArray(value)) {
26
+ return `${value}`;
27
+ }
28
+ return value.map((v) => (Array.isArray(v) ? v.join('-') : v)).join(', ');
29
+ }
30
+ exports.toDisplayValueDefault = toDisplayValueDefault;
31
+ const getLabelColumn = (field) => {
32
+ return {
33
+ field,
34
+ defaultFlex: 1,
35
+ renderTreeIcon: true,
36
+ defaultSortable: false,
37
+ resizable: false,
38
+ renderSelectionCheckBox: ({ rowInfo, dataSourceApi, api }) => {
39
+ if (!rowInfo.isTreeNode) {
40
+ return null;
41
+ }
42
+ return (React.createElement(CheckBox_1.CheckBox, { mx: 1, checked: rowInfo?.rowSelected, onChange: (checked) => {
43
+ dataSourceApi.treeApi.setNodeSelection(rowInfo.nodePath, checked);
44
+ api.focus();
45
+ } }));
46
+ },
47
+ renderHeader: ({ dataSourceApi, api, allRowsSelected, someRowsSelected }) => {
48
+ const { treeApi } = dataSourceApi;
49
+ const allFirstLevelCollapsed = dataSourceApi
50
+ .getOriginalDataArray()
51
+ .every((item) => !treeApi.isNodeExpanded([item.id]));
52
+ return (React.createElement(rebass_1.Flex, { flexDirection: 'row', alignItems: 'center', width: '100%', onMouseDown: (e) => {
53
+ // so we can keep the focus on the Grid
54
+ e.preventDefault();
55
+ } },
56
+ React.createElement(CheckBox_1.CheckBox, { checked: someRowsSelected && !allRowsSelected ? null : allRowsSelected, mr: 2, onChange: () => {
57
+ if (allRowsSelected) {
58
+ dataSourceApi.treeApi.deselectAll();
59
+ }
60
+ else {
61
+ dataSourceApi.treeApi.selectAll();
62
+ }
63
+ api.focus();
64
+ } }),
65
+ React.createElement(rebass_1.Flex, { flex: 1 }),
66
+ React.createElement(SimpleButton_1.default, { label: "toggle-expand-collapse", icon: allFirstLevelCollapsed ? 'expand-all' : 'collapse-all', onMouseDown: () => {
67
+ if (allFirstLevelCollapsed) {
68
+ dataSourceApi.treeApi.expandAll();
69
+ }
70
+ else {
71
+ dataSourceApi.treeApi.collapseAll();
72
+ }
73
+ }, iconPosition: "end" }, allFirstLevelCollapsed ? 'Expand All' : 'Collapse All')));
74
+ },
75
+ };
76
+ };
77
+ const sizeFull = {
78
+ width: '100%',
79
+ height: '100%',
80
+ };
81
+ function getRowCount(options) {
82
+ return options.reduce((acc, option) => {
83
+ if (Array.isArray(option.children)) {
84
+ return acc + getRowCount(option.children) + 1;
85
+ }
86
+ return acc + 1;
87
+ }, 0);
88
+ }
89
+ function TreeDropdown(props) {
90
+ const [visible, doSetVisible] = (0, react_1.useState)(false);
91
+ const overlayDOMRef = (0, react_1.useRef)(null);
92
+ const getProps = (0, useLatest_1.useLatest)(props);
93
+ const computedCSSVars = (0, AdaptableComputedCSSVarsContext_1.useAdaptableComputedCSSVars)();
94
+ const [treeExpandState, setTreeExpandState] = (0, react_1.useState)(undefined);
95
+ const [searchValue, setSearchValue] = (0, react_1.useState)('');
96
+ const labelField = props.labelField ?? 'label';
97
+ const columns = (0, react_1.useMemo)(() => {
98
+ return {
99
+ label: getLabelColumn(labelField),
100
+ };
101
+ }, [labelField]);
102
+ const [stateValue, setStateValue] = (0, react_1.useState)(props.value !== undefined ? props.value : props.defaultValue || []);
103
+ const onChange = (0, react_1.useCallback)((value) => {
104
+ const paths = value instanceof InfiniteTable_1.TreeSelectionState
105
+ ? value.getState().selectedPaths
106
+ : value.selectedPaths || [];
107
+ if (props.value === undefined) {
108
+ setStateValue(paths);
109
+ }
110
+ props.onChange?.(paths);
111
+ }, [props.onChange, props.value]);
112
+ const value = props.value !== undefined ? props.value : stateValue;
113
+ const treeSelection = (0, react_1.useMemo)(() => {
114
+ const selection = {
115
+ defaultSelection: false,
116
+ selectedPaths: value,
117
+ };
118
+ return selection;
119
+ }, [value]);
120
+ const rowCount = (0, react_1.useMemo)(() => {
121
+ return getRowCount(props.options);
122
+ }, [props.options]);
123
+ const [size, setSize] = (0, react_1.useState)({
124
+ width: 0,
125
+ height: rowCount * 35,
126
+ });
127
+ const setHeight = (0, react_1.useCallback)((height) => {
128
+ setSize((s) => {
129
+ return {
130
+ ...s,
131
+ height,
132
+ };
133
+ });
134
+ }, []);
135
+ const setWidth = (0, react_1.useCallback)((width) => {
136
+ setSize((s) => {
137
+ return {
138
+ ...s,
139
+ width,
140
+ };
141
+ });
142
+ }, []);
143
+ const getSize = (0, useLatest_1.useLatest)(size);
144
+ (0, react_1.useEffect)(() => {
145
+ if (!getSize().height) {
146
+ setHeight(rowCount * 35);
147
+ }
148
+ }, [rowCount]);
149
+ const setVisible = (visible) => {
150
+ if (visible) {
151
+ const { onMenuOpen } = getProps();
152
+ if (onMenuOpen) {
153
+ onMenuOpen();
154
+ }
155
+ requestAnimationFrame(() => {
156
+ doSetVisible(visible);
157
+ });
158
+ }
159
+ else {
160
+ const { onMenuClose } = getProps();
161
+ if (onMenuClose) {
162
+ onMenuClose();
163
+ }
164
+ doSetVisible(visible);
165
+ }
166
+ };
167
+ const [treeListApi, setTreeListApi] = (0, react_1.useState)(null);
168
+ const { listSizeConstraints } = props;
169
+ const nodeMatches = (0, react_1.useCallback)(({ data }) => {
170
+ return !searchValue
171
+ ? data
172
+ : `${data[labelField]}`.toLowerCase().includes(searchValue.toLowerCase());
173
+ }, [searchValue]);
174
+ const filterFunction = (0, react_1.useCallback)(({ data, filterTreeNode }) => {
175
+ if (!Array.isArray(data.children)) {
176
+ return nodeMatches({ data });
177
+ }
178
+ // allow non-leaf nodes to match
179
+ if (nodeMatches({ data })) {
180
+ return data;
181
+ }
182
+ return filterTreeNode(data);
183
+ }, [nodeMatches]);
184
+ return (React.createElement(rebass_1.Flex, { flexDirection: 'row', className: "ab-TreeDropdown", style: {
185
+ width: '100%',
186
+ ...props.style,
187
+ }, onMouseDown: props.onMouseDown, onBlur: (e) => {
188
+ const { relatedTarget } = e;
189
+ const overlayDOMNode = overlayDOMRef.current;
190
+ if ((overlayDOMNode && relatedTarget == overlayDOMNode) ||
191
+ overlayDOMNode?.contains(relatedTarget)) {
192
+ return;
193
+ }
194
+ setVisible(false);
195
+ } },
196
+ React.createElement(NotifyResize_1.default, { onResize: (newSize) => {
197
+ setWidth(newSize.width);
198
+ } }),
199
+ React.createElement(OverlayTrigger_1.default, { visible: visible, targetOffset: 20, render: () => {
200
+ const minWidth = listSizeConstraints?.minWidth ||
201
+ computedCSSVars['--ab-cmp-select-menu__min-width'] ||
202
+ 240;
203
+ const maxWidth = listSizeConstraints?.maxWidth ||
204
+ computedCSSVars['--ab-cmp-select-menu__max-width'] ||
205
+ '60vw';
206
+ const minHeight = listSizeConstraints?.minHeight || 200;
207
+ const maxHeight = listSizeConstraints?.maxHeight ||
208
+ computedCSSVars['--ab-cmp-select-menu__max-height'] ||
209
+ '50vh';
210
+ const resizable = getProps().resizable;
211
+ const treeList = (React.createElement(TreeList_1.TreeList, { primaryKey: props.primaryKey ?? 'id', treeFilterFunction: filterFunction, columnHeaderHeight: 40, onReady: ({ api }) => {
212
+ setTreeListApi(api);
213
+ api.focus();
214
+ }, defaultTreeExpandState: treeExpandState, onTreeExpandStateChange: setTreeExpandState, columns: columns, options: props.options, treeSelection: treeSelection, onTreeSelectionChange: (0, InfiniteTable_1.withSelectedLeafNodesOnly)(onChange), style: resizable
215
+ ? sizeFull
216
+ : {
217
+ width: size.width,
218
+ height: size.height,
219
+ maxWidth,
220
+ minHeight,
221
+ maxHeight,
222
+ minWidth,
223
+ } }));
224
+ let children = (React.createElement(rebass_1.Flex, { flexDirection: 'column', height: '100%' },
225
+ React.createElement(rebass_1.Flex, { backgroundColor: 'defaultbackground', p: 1, alignItems: 'center', justifyContent: 'stretch', justifyItems: 'stretch' },
226
+ React.createElement(Input_1.default, { "data-name": "menulist-search-input", placeholder: "Search...", style: { width: '100%' }, value: searchValue, onChange: (e) => setSearchValue(e.target.value) })),
227
+ treeList));
228
+ if (resizable) {
229
+ const onResizeStop = (_e, _direction, ref) => {
230
+ const newSize = {
231
+ width: ref.style.width,
232
+ height: ref.style.height,
233
+ };
234
+ setSize(newSize);
235
+ };
236
+ children = (React.createElement(re_resizable_1.Resizable, { enable: resizableDirections, minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight, defaultSize: size, onResizeStop: onResizeStop, onResizeStart: (e) => {
237
+ // in order to prevent focus from being lost
238
+ e.preventDefault();
239
+ } }, children));
240
+ }
241
+ return (React.createElement(rebass_1.Box, { ref: overlayDOMRef, className: "ab-TreeDropdownOverlay", "data-name": "menu-container" }, children));
242
+ } },
243
+ React.createElement(FieldWrap_1.default, { style: { width: '100%', ...props.fieldStyle } },
244
+ React.createElement(Input_1.default, { type: "text", readOnly: true, "data-name": "Select Values", placeholder: props.placeholder ?? 'Select a value', style: {
245
+ width: '100%',
246
+ }, pr: props.clearable ? 0 : undefined, value: props.toDisplayValue ? props.toDisplayValue(value) : toDisplayValueDefault(value), onFocus: () => {
247
+ if (!visible) {
248
+ setVisible(true);
249
+ }
250
+ treeListApi?.focus();
251
+ } }),
252
+ props.clearable && (React.createElement(SimpleButton_1.default, { style: {
253
+ visibility: Array.isArray(value) && value.length > 0 ? 'visible' : 'hidden',
254
+ }, variant: "text", icon: "close", onClick: () => onChange({ selectedPaths: [] }) }))))));
255
+ }
256
+ exports.TreeDropdown = TreeDropdown;
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { DataSourcePropOnTreeSelectionChange_MultiNode, InfiniteTableProps, TreeDataSourceProps } from '../../InfiniteTable';
3
+ export type TreeListItem<T = any> = {
4
+ id: string | number;
5
+ label: string;
6
+ children?: TreeListItem<T>[];
7
+ };
8
+ export type TreeListProps<T extends TreeListItem<T>> = {
9
+ options: T[];
10
+ debugId?: string;
11
+ primaryKey?: keyof T;
12
+ domProps?: InfiniteTableProps<T>['domProps'];
13
+ style?: React.CSSProperties;
14
+ rowHeight?: number | string;
15
+ treeSelection?: TreeDataSourceProps<T>['treeSelection'];
16
+ defaultTreeSelection?: TreeDataSourceProps<T>['defaultTreeSelection'];
17
+ onTreeSelectionChange?: DataSourcePropOnTreeSelectionChange_MultiNode;
18
+ defaultTreeExpandState?: TreeDataSourceProps<T>['defaultTreeExpandState'];
19
+ onTreeExpandStateChange?: TreeDataSourceProps<T>['onTreeExpandStateChange'];
20
+ columns?: InfiniteTableProps<T>['columns'];
21
+ columnHeaderHeight?: number | string;
22
+ onReady?: InfiniteTableProps<T>['onReady'];
23
+ treeFilterFunction?: TreeDataSourceProps<T>['treeFilterFunction'];
24
+ };
25
+ export declare function TreeList<T extends TreeListItem<T>>(props: TreeListProps<T>): React.JSX.Element;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeList = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const React = tslib_1.__importStar(require("react"));
6
+ const InfiniteTable_1 = require("../../InfiniteTable");
7
+ const rebass_1 = require("rebass");
8
+ const join_1 = tslib_1.__importDefault(require("../../../../../adaptable-react-aggrid/src/utils/join"));
9
+ const columns = {
10
+ label: {
11
+ field: 'label',
12
+ header: 'Label',
13
+ defaultFlex: 1,
14
+ renderTreeIcon: true,
15
+ renderSelectionCheckBox: true,
16
+ defaultSortable: false,
17
+ },
18
+ };
19
+ const domProps = {
20
+ style: {
21
+ height: '100%',
22
+ flex: 1,
23
+ },
24
+ className: 'ab-TreeList',
25
+ };
26
+ const DEFAULT_TREE_EXPAND_STATE = {
27
+ expandedPaths: [],
28
+ defaultExpanded: false,
29
+ };
30
+ function TreeList(props) {
31
+ return (React.createElement(rebass_1.Flex, { flex: 1, flexDirection: 'column', className: "ab-TreeList", style: props.style },
32
+ React.createElement(InfiniteTable_1.TreeDataSource, { data: props.options, primaryKey: props.primaryKey ?? 'id', defaultTreeSelection: props.defaultTreeSelection, treeSelection: props.treeSelection, onTreeSelectionChange: props.onTreeSelectionChange, treeFilterFunction: props.treeFilterFunction, onTreeExpandStateChange: props.onTreeExpandStateChange, defaultTreeExpandState: props.defaultTreeExpandState ?? DEFAULT_TREE_EXPAND_STATE },
33
+ React.createElement(InfiniteTable_1.TreeGrid, { defaultActiveRowIndex: 0, onReady: props.onReady, debugId: props.debugId, keyboardSelection: true, rowHeight: props.rowHeight ?? '--ab-grid-row-height', keyboardNavigation: "row", columnHeaderHeight: props.columnHeaderHeight, domProps: {
34
+ ...domProps,
35
+ ...props.domProps,
36
+ className: (0, join_1.default)(domProps.className, props.domProps?.className),
37
+ style: { ...domProps.style, ...props.domProps?.style },
38
+ }, columns: props.columns ?? columns, showZebraRows: false }))));
39
+ }
40
+ exports.TreeList = TreeList;
@@ -0,0 +1,31 @@
1
+ export declare const DevToolsTracks: {
2
+ readonly Init: {
3
+ readonly track: "Initialisation";
4
+ readonly labels: {
5
+ readonly Init: "Init";
6
+ readonly InitStore: "Init store";
7
+ readonly LoadStore: "Loading store";
8
+ readonly InitAGGrid: "AG Grid init";
9
+ };
10
+ };
11
+ readonly LayoutManager: {
12
+ readonly track: "Layout Manager";
13
+ readonly labels: {
14
+ readonly SetLayout: "Setting layout";
15
+ readonly ApplyPivotLayout: "Apply pivot layout";
16
+ readonly ApplyTableLayout: "Apply table layout";
17
+ };
18
+ };
19
+ readonly Runtime: {
20
+ readonly track: "Runtime";
21
+ readonly labels: {
22
+ readonly SetLayout: "Setting layout";
23
+ };
24
+ };
25
+ readonly Redux: {
26
+ readonly track: "Redux";
27
+ readonly labels: {
28
+ readonly Action: "Action";
29
+ };
30
+ };
31
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DevToolsTracks = void 0;
4
+ exports.DevToolsTracks = {
5
+ Init: {
6
+ track: 'Initialisation',
7
+ labels: {
8
+ Init: 'Init',
9
+ InitStore: 'Init store',
10
+ LoadStore: 'Loading store',
11
+ InitAGGrid: 'AG Grid init',
12
+ },
13
+ },
14
+ LayoutManager: {
15
+ track: 'Layout Manager',
16
+ labels: {
17
+ SetLayout: 'Setting layout',
18
+ ApplyPivotLayout: 'Apply pivot layout',
19
+ ApplyTableLayout: 'Apply table layout',
20
+ },
21
+ },
22
+ Runtime: {
23
+ track: 'Runtime',
24
+ labels: {
25
+ SetLayout: 'Setting layout',
26
+ },
27
+ },
28
+ Redux: {
29
+ track: 'Redux',
30
+ labels: {
31
+ Action: 'Action',
32
+ },
33
+ },
34
+ };