@adaptabletools/adaptable 20.0.0-canary.18 → 20.0.0-canary.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable",
3
- "version": "20.0.0-canary.18",
3
+ "version": "20.0.0-canary.19",
4
4
  "description": "Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -218,7 +218,7 @@ const DefaultAdaptableOptions = {
218
218
  quickSearchOptions: {
219
219
  clearQuickSearchOnStartUp: false,
220
220
  quickSearchPlaceholder: 'Search',
221
- filterResultsAfterQuickSearch: false,
221
+ filterGridAfterQuickSearch: false,
222
222
  isQuickSearchCaseSensitive: false,
223
223
  runCustomQuickSearch: undefined,
224
224
  },
@@ -30,13 +30,13 @@ export interface QuickSearchOptions<TData = any> {
30
30
  */
31
31
  clearQuickSearchOnStartUp?: boolean;
32
32
  /**
33
- * Filters quick search results so only matching rows are displayed
33
+ * Filters Grid after quick search so only matching rows are displayed
34
34
  *
35
35
  * @defaultValue false
36
36
  * @gridInfoItem
37
37
  * @noCodeItem
38
38
  */
39
- filterResultsAfterQuickSearch?: boolean;
39
+ filterGridAfterQuickSearch?: boolean;
40
40
  /**
41
41
  * Run Quick Search using Case Sensitivity
42
42
  *
@@ -115,7 +115,7 @@ export class ColumnFilterApiImpl extends ApiBase {
115
115
  return ('[' +
116
116
  friendlyName +
117
117
  '] ' +
118
- this.getPredicateApi().predicatesToString(columnFilter.Predicates, columnFilter.PredicatesLogic));
118
+ this.getPredicateApi().predicatesToString(columnFilter.Predicates, columnFilter.PredicatesOperator));
119
119
  }
120
120
  columnFiltersToString(columnFilters) {
121
121
  return columnFilters.map((cf) => this.columnFilterToString(cf)).join(', ');
@@ -117,7 +117,7 @@ export class PredicateApiImpl extends ApiBase {
117
117
  if (predicates === undefined || predicates === null || predicates?.length === 0) {
118
118
  return this.handlePredicate(undefined, params, defaultReturn);
119
119
  }
120
- if (params.predicatesLogic && params.predicatesLogic === 'OR') {
120
+ if (params.predicatesOperator && params.predicatesOperator === 'OR') {
121
121
  return predicates?.some((p) => this.handlePredicate(p, params, defaultReturn));
122
122
  }
123
123
  return predicates?.every((p) => this.handlePredicate(p, params, defaultReturn));
@@ -92,7 +92,7 @@ export class ColumnFilterInternalApi extends ApiBase {
92
92
  displayValue: gridCell.displayValue,
93
93
  node,
94
94
  column,
95
- predicatesLogic: columnFilter.PredicatesLogic,
95
+ predicatesOperator: columnFilter.PredicatesOperator,
96
96
  ...this.getAdaptableInternalApi().buildBaseContext(),
97
97
  };
98
98
  return this.getPredicateApi().handlePredicates(columnFilter.Predicates, predicateDefHandlerContext, true);
@@ -104,7 +104,7 @@ export interface PredicateDefHandlerContext extends BaseContext {
104
104
  * Any (optional) inputs required to perform evaluation
105
105
  */
106
106
  inputs?: any[];
107
- predicatesLogic?: ColumnFilter['PredicatesLogic'];
107
+ predicatesOperator?: ColumnFilter['PredicatesOperator'];
108
108
  }
109
109
  /**
110
110
  * Inputs required for a Predicate
@@ -13,10 +13,10 @@ export interface ColumnFilter extends SuspendableObject {
13
13
  */
14
14
  Predicates: ColumnFilterPredicate[];
15
15
  /**
16
- * The Logic to use when combining multiple Predicates
16
+ * Logic used when combining multiple Predicates ('AND'|'OR')
17
17
  * @defaultValue 'AND'
18
18
  */
19
- PredicatesLogic?: 'AND' | 'OR';
19
+ PredicatesOperator?: PredicatesOperator;
20
20
  }
21
21
  /**
22
22
  * A Predicate used in Column Filtering
@@ -24,6 +24,10 @@ export interface ColumnFilter extends SuspendableObject {
24
24
  export interface ColumnFilterPredicate extends AdaptablePredicate {
25
25
  PredicateId: TypeHint<string, SystemFilterPredicateId>;
26
26
  }
27
+ /**
28
+ * Logic used to join multiple Predicates
29
+ */
30
+ export type PredicatesOperator = 'AND' | 'OR';
27
31
  /**
28
32
  * Array containing all System Filter Predicates
29
33
  */
@@ -125,7 +125,7 @@ export interface PivotLayout extends LayoutBase {
125
125
  */
126
126
  PivotColumns: string[];
127
127
  /**
128
- * How deep to expand Pivots
128
+ * How deep to expand Pivot Columns (0 for none, 1 for 1st level only etc, -1 to expand all)
129
129
  */
130
130
  PivotExpandLevel?: number;
131
131
  /**
@@ -180,7 +180,7 @@ export declare const getCurrentLayoutSelector: (state: AdaptableState) => Layout
180
180
  export declare const getColumnFilterSelector: (state: AdaptableState, columnId: string) => {
181
181
  ColumnId: string;
182
182
  Predicates: import("../../types").ColumnFilterPredicate[];
183
- PredicatesLogic?: "AND" | "OR";
183
+ PredicatesOperator?: import("../../types").PredicatesOperator;
184
184
  IsSuspended?: boolean;
185
185
  Uuid?: string;
186
186
  Source?: "Config" | "User";
@@ -500,7 +500,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
500
500
  let returnAction = next(action);
501
501
  adaptable.api.gridApi.refreshAllCells(true);
502
502
  // if set then return a query on the text
503
- if (adaptable.adaptableOptions.quickSearchOptions.filterResultsAfterQuickSearch) {
503
+ if (adaptable.adaptableOptions.quickSearchOptions.filterGridAfterQuickSearch) {
504
504
  const actionTyped = action;
505
505
  const searchText = actionTyped.quickSearchText;
506
506
  if (StringExtensions.IsNotNullOrEmpty(searchText)) {
@@ -3,6 +3,7 @@ import { format as dateFnsFormat } from 'date-fns';
3
3
  import { sentenceCase } from 'sentence-case';
4
4
  import { DEFAULT_DATE_FORMAT_PATTERN } from '../Constants/GeneralConstants';
5
5
  import Helper from './Helper';
6
+ import StringExtensions from '../Extensions/StringExtensions';
6
7
  export function NumberFormatter(input, options = {}, rowNode, column, api) {
7
8
  let preparedInput;
8
9
  if (options.Content) {
@@ -110,20 +111,33 @@ export function DateFormatter(input, options, strictFormatting = false) {
110
111
  }
111
112
  }
112
113
  export function StringFormatter(input, options = {}, rowNode, column, api) {
114
+ let normalisedTextInput = input;
115
+ if (input != undefined && typeof input !== 'string') {
116
+ const warningMessage = column
117
+ ? `StringFormatter: input '${input}' from column ${column.columnId} (${column.dataType}) is not a string, but a ${typeof input}`
118
+ : `StringFormatter: input '${input}' is not a string, received ${typeof input}`;
119
+ if (api) {
120
+ api.logWarn(warningMessage);
121
+ }
122
+ else {
123
+ console.warn(warningMessage);
124
+ }
125
+ normalisedTextInput = `${input}`;
126
+ }
113
127
  let preparedInput;
114
128
  if (options.Content) {
115
129
  const context = {
116
130
  column,
117
131
  rowNode,
118
- input,
132
+ input: normalisedTextInput,
119
133
  api,
120
134
  };
121
135
  preparedInput = formatPlaceholder(options.Content, context);
122
136
  }
123
137
  else {
124
- preparedInput = input;
138
+ preparedInput = normalisedTextInput;
125
139
  }
126
- if (preparedInput == null || preparedInput == undefined) {
140
+ if (StringExtensions.IsNullOrEmptyOrWhiteSpace(preparedInput)) {
127
141
  return undefined;
128
142
  }
129
143
  if (options.Empty) {
@@ -17,7 +17,7 @@ export const LayoutColumnFilter = (props) => {
17
17
  ...props.columnFilter,
18
18
  ColumnId: props.columnFilter.ColumnId,
19
19
  Predicates: newAdaptablePredicates,
20
- PredicatesLogic: newPredicate.operator,
20
+ PredicatesOperator: newPredicate.operator,
21
21
  };
22
22
  props.onColumnFilterChange(newFilter);
23
23
  };
@@ -31,7 +31,7 @@ export const useAdaptableFilterWrapper = (columnId, handleOnChangeOverride) => {
31
31
  ...columnFilter,
32
32
  ColumnId: columnId,
33
33
  Predicates: adaptablePredicate,
34
- PredicatesLogic: logic,
34
+ PredicatesOperator: logic,
35
35
  };
36
36
  if (handleOnChangeOverride) {
37
37
  handleOnChangeOverride(newFilter);
@@ -76,7 +76,7 @@ export const isPredicateEmpty = (predicate, predicateDef) => {
76
76
  predicate.args.every((arg) => arg == undefined));
77
77
  };
78
78
  export const mapColumnFilterToQlPredicate = (columnFilter, abColumn, qlPredicateDefs, columnFilterOptions) => {
79
- const combinator = columnFilter?.PredicatesLogic ?? 'AND';
79
+ const combinator = columnFilter?.PredicatesOperator ?? 'AND';
80
80
  const qlPredicate = {
81
81
  operator: combinator,
82
82
  args: (columnFilter?.Predicates ?? []).map?.(mapAdaptablePredicateToQlPredicate),
@@ -14,7 +14,7 @@ import { useQuickSearchDebounced } from './useQuickSearchDebounced';
14
14
  const QuickSearchPopupComponent = (props) => {
15
15
  const [searchText, search] = useQuickSearchDebounced(props);
16
16
  const [state, setState] = useState({
17
- RunQueryAfterQuickSearch: props.api.optionsApi.getQuickSearchOptions().filterResultsAfterQuickSearch,
17
+ RunQueryAfterQuickSearch: props.api.optionsApi.getQuickSearchOptions().filterGridAfterQuickSearch,
18
18
  EditedStyle: props.QuickSearchStyle,
19
19
  });
20
20
  const onUpdateStyle = (style) => {
@@ -23,7 +23,7 @@ const QuickSearchPopupComponent = (props) => {
23
23
  };
24
24
  const onQuickSearchBehaviourChange = (checked) => {
25
25
  setState({ ...state, RunQueryAfterQuickSearch: checked });
26
- props.api.optionsApi.getAdaptableOptions().quickSearchOptions.filterResultsAfterQuickSearch =
26
+ props.api.optionsApi.getAdaptableOptions().quickSearchOptions.filterGridAfterQuickSearch =
27
27
  checked;
28
28
  };
29
29
  return (React.createElement(PopupPanel, { headerText: props.moduleInfo.FriendlyName, glyphicon: props.moduleInfo.Glyph, infoLink: props.moduleInfo.HelpPage, infoLinkDisabled: !props.api.internalApi.isDocumentationLinksDisplayed() },
@@ -1,12 +1,18 @@
1
1
  import * as React from 'react';
2
+ import { useEffect } from 'react';
2
3
  import { useDispatch, useSelector } from 'react-redux';
3
4
  import { Flex } from 'rebass';
4
5
  import { getStatusPanelsSelector } from '../../Redux/ActionsReducers/StatusBarRedux';
5
6
  import { useAdaptable } from '../AdaptableContext';
6
7
  import { StatusBarPanel } from './StatusBarPanel';
8
+ import { useRerender } from '../../components/utils/useRerender';
7
9
  export const AdaptableStatusBar = (props) => {
8
- const statusPanels = useSelector(getStatusPanelsSelector);
9
10
  const adaptable = useAdaptable();
11
+ const rerender = useRerender();
12
+ useEffect(() => {
13
+ return adaptable.api.eventApi.on('AdaptableStateChanged', rerender);
14
+ }, [adaptable]);
15
+ const statusPanels = useSelector(getStatusPanelsSelector);
10
16
  const dispatch = useDispatch();
11
17
  const statusSubPanels = statusPanels.find((statusPanel) => statusPanel.Key === props.context.Key);
12
18
  const allMenuItems = useSelector((state) => state?.Internal?.SettingsPanelModuleEntries);
@@ -100,6 +100,11 @@ import { mapOldTypeToDataType } from '../migration/VersionUpgrade20';
100
100
  const LocalEventService_Prototype = LocalEventService.prototype;
101
101
  const LocalEventService_dispatchEvent = LocalEventService_Prototype.dispatchEvent;
102
102
  LocalEventService_Prototype.dispatchEvent = function (event) {
103
+ const agGridApi = event.api;
104
+ if (agGridApi?.isDestroyed()) {
105
+ // do nothing if AG Grid was destroyed in the meantime
106
+ return;
107
+ }
103
108
  LocalEventService_dispatchEvent.apply(this, arguments);
104
109
  if (event.type === 'cellChanged' || event.type === 'dataChanged') {
105
110
  const eventRowNode = event.node;
@@ -119,6 +124,10 @@ LocalEventService_Prototype.dispatchEvent = function (event) {
119
124
  // so IGNORE IT
120
125
  return;
121
126
  }
127
+ if (adaptable.isDestroyed) {
128
+ // do nothing if adaptable is destroyed (this is a rare case and happens when Adaptable is quickly destroyed and recreated)
129
+ return;
130
+ }
122
131
  // we're on the correct instance, so do this
123
132
  //@ts-ignore
124
133
  const fn = adaptable.rowListeners ? adaptable.rowListeners[event.type] : null;
@@ -354,7 +363,7 @@ export class AdaptableAgGrid {
354
363
  this.lifecycleState = 'initAgGrid';
355
364
  this.agGridAdapter.initialGridOptions = gridOptions;
356
365
  const perfInitAgGrid = this.logger.beginPerf(`initAgGrid()`);
357
- // AG Grid evaluates early on the floatingFilter params, so we need to "suppres" the floating filter temporarily
366
+ // AG Grid evaluates early on the floatingFilter params, so we need to "suppress" the floating filter temporarily
358
367
  // we will reset it once Adaptable is ready
359
368
  this.agGridColumnAdapter.setupColumnFloatingFilterTemporarily(gridOptions);
360
369
  this.validateColumnDefTypes(gridOptions.columnDefs);
package/src/env.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export default {
2
2
  NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
3
- PUBLISH_TIMESTAMP: 1741974502569 || Date.now(),
4
- VERSION: "20.0.0-canary.18" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1742230330103 || Date.now(),
4
+ VERSION: "20.0.0-canary.19" || '--current-version--',
5
5
  };
@@ -1856,12 +1856,14 @@ export declare const ADAPTABLE_METAMODEL: {
1856
1856
  desc: string;
1857
1857
  isOpt?: undefined;
1858
1858
  defVal?: undefined;
1859
+ ref?: undefined;
1859
1860
  } | {
1860
1861
  name: string;
1861
1862
  kind: string;
1862
1863
  desc: string;
1863
1864
  isOpt: boolean;
1864
1865
  defVal: string;
1866
+ ref: string;
1865
1867
  })[];
1866
1868
  };
1867
1869
  ColumnFilterDef: {
@@ -4466,6 +4468,11 @@ export declare const ADAPTABLE_METAMODEL: {
4466
4468
  gridInfo?: undefined;
4467
4469
  })[];
4468
4470
  };
4471
+ PredicatesOperator: {
4472
+ name: string;
4473
+ kind: string;
4474
+ desc: string;
4475
+ };
4469
4476
  PreProcessExportContext: {
4470
4477
  name: string;
4471
4478
  kind: string;