@adaptabletools/adaptable 15.2.0-canary.5 → 15.2.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 (57) hide show
  1. package/bundle.cjs.js +162 -162
  2. package/package.json +1 -1
  3. package/publishTimestamp.d.ts +1 -1
  4. package/publishTimestamp.js +1 -1
  5. package/src/AdaptableInterfaces/IAdaptable.d.ts +1 -0
  6. package/src/AdaptableOptions/AlertOptions.d.ts +3 -3
  7. package/src/AdaptableOptions/ColumnOptions.d.ts +1 -5
  8. package/src/AdaptableOptions/FilterOptions.d.ts +7 -0
  9. package/src/AdaptableOptions/Glue42PluginOptions.d.ts +1 -1
  10. package/src/AdaptableOptions/Glue42WebPluginOptions.d.ts +7 -0
  11. package/src/AdaptableOptions/LayoutOptions.d.ts +1 -1
  12. package/src/AdaptableOptions/PredicateOptions.d.ts +5 -1
  13. package/src/Api/AlertApi.d.ts +2 -2
  14. package/src/Api/Glue42Api.d.ts +1 -1
  15. package/src/Api/GridApi.d.ts +2 -2
  16. package/src/Api/Implementation/AlertApiImpl.d.ts +2 -2
  17. package/src/Api/Implementation/AlertApiImpl.js +6 -6
  18. package/src/Api/Implementation/FilterApiImpl.js +4 -1
  19. package/src/Api/Implementation/FlashingCellApiImpl.js +1 -1
  20. package/src/Api/Implementation/PluginsApiImpl.d.ts +2 -0
  21. package/src/Api/Implementation/PluginsApiImpl.js +6 -0
  22. package/src/Api/Implementation/PredicateApiImpl.d.ts +5 -5
  23. package/src/Api/Implementation/PredicateApiImpl.js +8 -8
  24. package/src/Api/Implementation/ThemeApiImpl.js +2 -0
  25. package/src/Api/Internal/AlertInternalApi.d.ts +3 -3
  26. package/src/Api/Internal/AlertInternalApi.js +7 -7
  27. package/src/Api/Internal/FormatColumnInternalApi.js +1 -1
  28. package/src/Api/Internal/PredicateInternalApi.d.ts +5 -4
  29. package/src/Api/Internal/PredicateInternalApi.js +16 -12
  30. package/src/Api/PluginsApi.d.ts +6 -1
  31. package/src/Api/PredicateApi.d.ts +5 -5
  32. package/src/Strategy/AlertModule.js +1 -1
  33. package/src/Utilities/Defaults/DefaultAdaptableOptions.js +1 -0
  34. package/src/Utilities/Services/ThemeService.d.ts +1 -0
  35. package/src/Utilities/Services/ThemeService.js +38 -3
  36. package/src/View/Alert/Wizard/AlertNotificationWizardSection.js +1 -1
  37. package/src/View/Components/AdaptableDateInput/index.d.ts +1 -1
  38. package/src/View/Components/FilterForm/FilterForm.js +1 -1
  39. package/src/View/Components/FilterForm/ListBoxFilterForm.js +4 -2
  40. package/src/View/Components/FilterForm/QuickFilterForm.d.ts +0 -5
  41. package/src/View/Components/FilterForm/QuickFilterForm.js +60 -206
  42. package/src/View/Components/FilterForm/QuickFilterValues.d.ts +19 -0
  43. package/src/View/Components/FilterForm/QuickFilterValues.js +168 -0
  44. package/src/View/CustomSort/Wizard/CustomSortColumnWizardSection.js +1 -1
  45. package/src/agGrid/Adaptable.d.ts +1 -0
  46. package/src/agGrid/Adaptable.js +24 -50
  47. package/src/components/ColorPicker/ColorPicker.d.ts +1 -1
  48. package/src/components/Datepicker/index.d.ts +1 -1
  49. package/src/components/Input/index.d.ts +1 -1
  50. package/src/components/List/ListGroupItem/index.d.ts +1 -1
  51. package/src/components/OverlayTrigger/index.d.ts +3 -1
  52. package/src/components/OverlayTrigger/index.js +2 -1
  53. package/src/metamodel/adaptable.metamodel.d.ts +20 -0
  54. package/src/metamodel/adaptable.metamodel.js +1 -1
  55. package/src/types.d.ts +2 -0
  56. package/version.d.ts +1 -1
  57. package/version.js +1 -1
@@ -215,6 +215,7 @@ exports.DefaultAdaptableOptions = {
215
215
  quickFilterWildcards: {},
216
216
  quickFilterDebounce: 250,
217
217
  showValuesCount: undefined,
218
+ quickFilterValuesWidth: 180,
218
219
  },
219
220
  searchOptions: {
220
221
  excludeColumnFromQuickSearch: undefined,
@@ -9,4 +9,5 @@ export declare class ThemeService implements IThemeService {
9
9
  onThemeChanged: () => void;
10
10
  applyNewThemeVariables(theme: AdaptableTheme): void;
11
11
  destroy(): void;
12
+ showMissingThemeFiles(theme: AdaptableTheme): void;
12
13
  }
@@ -8,6 +8,9 @@ class ThemeService {
8
8
  this.onThemeChanged = () => {
9
9
  const currentTheme = this.api.themeApi.getCurrentThemeObject();
10
10
  this.applyNewThemeVariables(currentTheme);
11
+ // this needs to be called after variables are set
12
+ // as it may show the warning for a custom/runtime theme
13
+ this.showMissingThemeFiles(currentTheme);
11
14
  };
12
15
  this.api = api;
13
16
  this.subscribe();
@@ -29,10 +32,12 @@ class ThemeService {
29
32
  };
30
33
  }
31
34
  applyNewThemeVariables(theme) {
32
- var _a;
33
- const variables = (_a = theme.CSSVariables) !== null && _a !== void 0 ? _a : {};
35
+ const variables = theme.CSSVariables;
36
+ if (!variables || Object.keys(variables).length === 0) {
37
+ return;
38
+ }
34
39
  let str = `html.${this.api.themeApi.internalApi.getThemeClassName(theme.Name)} {
35
- --ab-theme-loaded: custom-theme;
40
+ --ab-theme-loaded: ab--theme-${theme.Name};
36
41
  `;
37
42
  for (const [key, value] of Object.entries(variables)) {
38
43
  if (key.includes('--')) {
@@ -47,5 +52,35 @@ class ThemeService {
47
52
  this.unsubscribe();
48
53
  document.adoptedStyleSheets = [...document.adoptedStyleSheets].filter((sheet) => sheet !== this.styleSheetObject);
49
54
  }
55
+ showMissingThemeFiles(theme) {
56
+ // run time defined theme
57
+ // because it may be an empty theme
58
+ if (theme.Source === 'User') {
59
+ return;
60
+ }
61
+ const themeName = theme.Name;
62
+ const adaptable = this.api.internalApi.getAdaptableInstance();
63
+ const logger = adaptable.logger;
64
+ const documentElement = document.documentElement;
65
+ const computedDocumentStyle = getComputedStyle(documentElement);
66
+ const [abLoaded, abThemeLoaded] = ['--ab-loaded', '--ab-theme-loaded'].map((variable) => {
67
+ let val = computedDocumentStyle.getPropertyValue(variable);
68
+ if (typeof val === 'string' && val.trim) {
69
+ val = val.trim();
70
+ }
71
+ return val;
72
+ });
73
+ if (abLoaded !== '777') {
74
+ logger.consoleError('Please import Adaptable styles from "@adaptabletools/adaptable/index.css"');
75
+ }
76
+ // every theme should define a custom css variable: --ab-theme-loaded: <themeName> defined on the document element.
77
+ if (abThemeLoaded !== themeName) {
78
+ logger.consoleWarn(`Theme "${themeName}" doesn't seem to be loaded! Make sure you import the css file for the "${themeName}" theme!
79
+
80
+ If it's a default theme, try
81
+
82
+ import "@adaptabletools/adaptable/themes/${themeName}.css"`);
83
+ }
84
+ }
50
85
  }
51
86
  exports.ThemeService = ThemeService;
@@ -42,7 +42,7 @@ const AlertPreview = (_a) => {
42
42
  const Buttons = (((_a = alertForm === null || alertForm === void 0 ? void 0 : alertForm.Buttons) === null || _a === void 0 ? void 0 : _a.length) ? alertForm.Buttons : DEFAULT_BUTTONS).map(mapButtons);
43
43
  const result = {
44
44
  alertType: 'generic',
45
- header: api.alertApi.internalApi.getAlertMessageTitle(alertDefinition),
45
+ header: api.alertApi.internalApi.getAlertMessageHeader(alertDefinition),
46
46
  message: api.alertApi.internalApi.getAlertDescription(alertDefinition),
47
47
  alertDefinition: Object.assign(Object.assign({}, alertDefinition), { AlertForm: Object.assign(Object.assign({}, alertForm), { Buttons }) }),
48
48
  };
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
2
  import { AdaptableInputProps } from '../AdaptableInput';
3
3
  export declare type AdaptableDateInputProps = AdaptableInputProps;
4
- declare const AdaptableDateInput: React.ForwardRefExoticComponent<Omit<import("../../../components/Input").InputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
4
+ declare const AdaptableDateInput: React.ForwardRefExoticComponent<Pick<import("../../../components/Input").InputProps, "max" | "required" | "type" | "data" | "default" | "high" | "low" | "key" | "id" | "media" | "height" | "width" | "start" | "open" | "name" | "alignContent" | "alignItems" | "alignSelf" | "backgroundColor" | "color" | "content" | "display" | "flex" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontFamily" | "fontSize" | "fontStyle" | "fontWeight" | "justifyContent" | "justifyItems" | "justifySelf" | "letterSpacing" | "lineHeight" | "margin" | "marginBottom" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "opacity" | "order" | "overflow" | "overflowX" | "overflowY" | "padding" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingTop" | "textAlign" | "translate" | "verticalAlign" | "value" | "hidden" | "cite" | "dir" | "form" | "label" | "p" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "acceptCharset" | "action" | "method" | "noValidate" | "target" | "accessKey" | "draggable" | "lang" | "className" | "prefix" | "children" | "contentEditable" | "inputMode" | "nonce" | "tabIndex" | "async" | "disabled" | "multiple" | "size" | "manifest" | "m" | "wrap" | "accept" | "allowFullScreen" | "allowTransparency" | "alt" | "as" | "autoComplete" | "autoFocus" | "autoPlay" | "capture" | "cellPadding" | "cellSpacing" | "charSet" | "challenge" | "checked" | "classID" | "cols" | "colSpan" | "controls" | "coords" | "crossOrigin" | "dateTime" | "defer" | "download" | "encType" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "frameBorder" | "headers" | "href" | "hrefLang" | "htmlFor" | "httpEquiv" | "integrity" | "keyParams" | "keyType" | "kind" | "list" | "loop" | "marginHeight" | "marginWidth" | "maxLength" | "mediaGroup" | "min" | "minLength" | "muted" | "optimum" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "contextMenu" | "placeholder" | "spellCheck" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "playsInline" | "poster" | "preload" | "readOnly" | "rel" | "reversed" | "rows" | "rowSpan" | "sandbox" | "scope" | "scoped" | "scrolling" | "seamless" | "selected" | "shape" | "sizes" | "src" | "srcDoc" | "srcLang" | "srcSet" | "step" | "useMap" | "wmode" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "bg" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "css" | "variant" | "tx" | "sx" | "placehoder"> & React.RefAttributes<HTMLInputElement>>;
5
5
  export default AdaptableDateInput;
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const React = tslib_1.__importStar(require("react"));
6
6
  const react_redux_1 = require("react-redux");
7
7
  const LayoutRedux = tslib_1.__importStar(require("../../../Redux/ActionsReducers/LayoutRedux"));
8
+ const LayoutRedux_1 = require("../../../Redux/ActionsReducers/LayoutRedux");
8
9
  const SystemRedux = tslib_1.__importStar(require("../../../Redux/ActionsReducers/SystemRedux"));
9
10
  const Enums_1 = require("../../../PredefinedConfig/Common/Enums");
10
11
  const ListBoxFilterForm_1 = require("./ListBoxFilterForm");
@@ -23,7 +24,6 @@ const renderWithAdaptableContext_1 = require("../../renderWithAdaptableContext")
23
24
  const CheckBox_1 = require("../../../components/CheckBox");
24
25
  const runIfNotResolvedIn_1 = require("../../../Utilities/runIfNotResolvedIn");
25
26
  const getDefaultColumnFilterPredicate_1 = require("./getDefaultColumnFilterPredicate");
26
- const LayoutRedux_1 = require("../../../Redux/ActionsReducers/LayoutRedux");
27
27
  const panelStyle = {
28
28
  width: '100%',
29
29
  minWidth: 150,
@@ -41,15 +41,17 @@ const ListBoxFilterForm = (props) => {
41
41
  }
42
42
  };
43
43
  const columnValuesItemsElements = props.columnDistinctValues.map((distinctValue, index) => {
44
- var _a, _b, _c;
45
44
  const isActive = UiSelectedColumnValues.indexOf(distinctValue.value) >= 0;
46
45
  const columnLabel = distinctValue.label;
47
46
  if (StringExtensions_1.StringExtensions.IsNullOrEmpty(columnLabel)) {
48
47
  return null;
49
48
  }
49
+ const noMatch = StringExtensions_1.StringExtensions.IsNullOrEmpty(FilterValue.toLocaleLowerCase()) ||
50
+ StringExtensions_1.StringExtensions.IsNullOrEmpty(columnLabel === null || columnLabel === void 0 ? void 0 : columnLabel.toLocaleLowerCase()) ||
51
+ columnLabel.toLocaleLowerCase().indexOf(FilterValue.toLocaleLowerCase()) < 0;
50
52
  if (!props.suppressClientSideFilter &&
51
53
  StringExtensions_1.StringExtensions.IsNotNullOrEmpty(FilterValue) &&
52
- ((_c = (_a = columnLabel === null || columnLabel === void 0 ? void 0 : columnLabel.toLocaleLowerCase) === null || _a === void 0 ? void 0 : (_b = _a.call(columnLabel)).indexOf) === null || _c === void 0 ? void 0 : _c.call(_b, FilterValue.toLocaleLowerCase())) < 0) {
54
+ noMatch) {
53
55
  return null;
54
56
  }
55
57
  if (props.useAgGridStyle) {
@@ -1,10 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { ColumnFilterContext } from '../../../Utilities/Interface/ColumnFilterContext';
3
- import { ColumnFilter } from '../../../types';
4
3
  export interface QuickFilterFormState {
5
- filter: ColumnFilter;
6
- distinctColumnValues: any[];
7
- isDistinctColumnValuesLoading: boolean;
8
- suppressClientSideFilter: boolean;
9
4
  }
10
5
  export declare const QuickFilterFormReact: (FilterContext: ColumnFilterContext) => JSX.Element;
@@ -5,128 +5,39 @@ const tslib_1 = require("tslib");
5
5
  const React = tslib_1.__importStar(require("react"));
6
6
  const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
7
7
  const LayoutRedux = tslib_1.__importStar(require("../../../Redux/ActionsReducers/LayoutRedux"));
8
+ const LayoutRedux_1 = require("../../../Redux/ActionsReducers/LayoutRedux");
8
9
  const react_redux_1 = require("react-redux");
9
10
  const ObjectFactory_1 = require("../../../Utilities/ObjectFactory");
10
11
  const OverlayTrigger_1 = tslib_1.__importDefault(require("../../../components/OverlayTrigger"));
11
12
  const SimpleButton_1 = tslib_1.__importDefault(require("../../../components/SimpleButton"));
12
13
  const icons_1 = require("../../../components/icons");
13
14
  const rebass_1 = require("rebass");
14
- const ListBoxFilterForm_1 = require("./ListBoxFilterForm");
15
- const ArrayExtensions_1 = tslib_1.__importDefault(require("../../../Utilities/Extensions/ArrayExtensions"));
16
15
  const AdaptableInput_1 = tslib_1.__importDefault(require("../AdaptableInput"));
17
16
  const renderWithAdaptableContext_1 = require("../../renderWithAdaptableContext");
18
17
  const CheckBox_1 = require("../../../components/CheckBox");
19
- const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
20
- const runIfNotResolvedIn_1 = require("../../../Utilities/runIfNotResolvedIn");
21
18
  const getDefaultColumnFilterPredicate_1 = require("./getDefaultColumnFilterPredicate");
22
- const date_fns_1 = require("date-fns");
23
- const LayoutRedux_1 = require("../../../Redux/ActionsReducers/LayoutRedux");
24
19
  const AdaptableIconComponent_1 = require("../../../components/AdaptableIconComponent");
20
+ const QuickFilterValues_1 = require("./QuickFilterValues");
25
21
  class QuickFilterFormComponent extends React.Component {
26
- //private debounceTime =
27
22
  constructor(props) {
28
23
  var _a, _b;
29
24
  super(props);
25
+ this.shouldOpenValuesDropdown = false;
30
26
  this._isMounted = false;
31
- this.handleFilterChange = (filter) => {
32
- if (this.state.suppressClientSideFilter) {
33
- this.loadPermittedValues(filter);
34
- }
35
- };
36
- this.loadPermittedValues = async (filter = '') => {
37
- const { values, suppressClientSideFilter } = await (0, runIfNotResolvedIn_1.runIfNotResolvedIn)(this.props.api.gridApi.internalApi.getDistinctFilterDisplayValuesForColumn(this.props.currentColumn.columnId, filter, this.props.api.optionsApi.getFilterOptions().showDistinctFilteredValuesOnly), () => this._isMounted && this.setState({ isDistinctColumnValuesLoading: true }));
38
- if (this._isMounted) {
39
- this.setState({
40
- distinctColumnValues: values,
41
- suppressClientSideFilter,
42
- isDistinctColumnValuesLoading: false,
43
- });
44
- }
45
- };
46
- this.debouncedAddFilter = (0, debounce_1.default)(() => this.props.onAddColumnFilter(this.state.filter), (_a = this.props.api.optionsApi.getFilterOptions()) === null || _a === void 0 ? void 0 : _a.quickFilterDebounce);
47
- this.debouncedEditFilter = (0, debounce_1.default)(() => this.props.onEditColumnFilter(this.state.filter), (_b = this.props.api.optionsApi.getFilterOptions()) === null || _b === void 0 ? void 0 : _b.quickFilterDebounce);
48
- this.debouncedLoadPermittedValues = (0, debounce_1.default)(() => this.loadPermittedValues(), 500);
49
- const filter = this.getFilterFromProps();
27
+ this.debouncedAddFilter = (0, debounce_1.default)((filter) => this.props.onAddColumnFilter(filter), (_a = this.props.api.optionsApi.getFilterOptions()) === null || _a === void 0 ? void 0 : _a.quickFilterDebounce);
28
+ this.debouncedEditFilter = (0, debounce_1.default)((filter) => this.props.onEditColumnFilter(filter), (_b = this.props.api.optionsApi.getFilterOptions()) === null || _b === void 0 ? void 0 : _b.quickFilterDebounce);
50
29
  this._isMounted = true;
51
- this.state = {
52
- filter,
53
- suppressClientSideFilter: false,
54
- isDistinctColumnValuesLoading: false,
55
- distinctColumnValues: [],
56
- };
57
- }
58
- componentDidMount() {
59
- var _a, _b, _c;
60
- if (this.hasValuesPredicate((_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.Predicate)) {
61
- this.loadPermittedValues();
62
- }
63
- this.unsubscribeOnCellChanged = this.props.api.eventApi.on('CellChanged', (cellChangedInfo) => {
64
- this.handleGridValueChange(cellChangedInfo.cellChange.column.columnId);
65
- });
66
- this.unsubscribeOnGridDataChanged = this.props.api.eventApi.on('GridDataChanged', () => {
67
- // there is no way to find out if the changed rows are relevant for this filter, so we have to update it every time :/
68
- this.handleGridValueChange();
69
- });
70
- if ((_c = this.props.api.optionsApi.getFilterOptions()) === null || _c === void 0 ? void 0 : _c.showDistinctFilteredValuesOnly) {
71
- this.unsubscribeOnGridFiltered = this.props.api.internalApi
72
- .getAdaptableInstance()
73
- ._on('GridFiltered', () => {
74
- const filter = this.getFilterFromProps();
75
- if (this.hasValuesPredicate(filter === null || filter === void 0 ? void 0 : filter.Predicate)) {
76
- this.loadPermittedValues();
77
- }
78
- });
79
- }
80
30
  }
81
31
  componentWillUnmount() {
82
- var _a, _b, _c;
83
32
  this._isMounted = false;
84
- (_a = this.unsubscribeOnCellChanged) === null || _a === void 0 ? void 0 : _a.call(this);
85
- (_b = this.unsubscribeOnGridDataChanged) === null || _b === void 0 ? void 0 : _b.call(this);
86
- if (this.unsubscribeOnGridFiltered) {
87
- (_c = this.unsubscribeOnGridFiltered) === null || _c === void 0 ? void 0 : _c.call(this);
88
- }
89
33
  }
90
34
  isFilterDisabled() {
91
- return Boolean(this.state.filter.IsSuspended);
92
- }
93
- UNSAFE_componentWillReceiveProps(nextProps) {
94
- const filter = this.getFilterFromProps(nextProps);
95
- if ((0, isEqual_1.default)(filter, this.state.filter)) {
96
- return;
97
- }
98
- this.setState({ filter });
99
- if (this.hasValuesPredicate(filter === null || filter === void 0 ? void 0 : filter.Predicate)) {
100
- this.setState({ isDistinctColumnValuesLoading: true });
101
- this.loadPermittedValues();
102
- }
103
- }
104
- getFilterFromProps(props = this.props) {
105
- const filter = props.columnFilters.find((cf) => cf.ColumnId == props.currentColumn.columnId);
106
- const filterOptions = props.api.optionsApi.getFilterOptions();
107
- if (filter) {
108
- return filter;
109
- }
110
- if (!filter && props.currentColumn.dataType === 'Number') {
111
- return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultNumericColumnFilter), ['']);
112
- }
113
- if (!filter && props.currentColumn.dataType === 'String') {
114
- return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultStringColumnFilter), ['']);
115
- }
116
- if (!filter && props.currentColumn.dataType === 'Date') {
117
- return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultDateColumnFilter), ['']);
118
- }
119
- if (!filter && props.currentColumn.dataType === 'Boolean') {
120
- return ObjectFactory_1.ObjectFactory.CreateColumnFilter(this.props.currentColumn.columnId, 'BooleanToggle', [
121
- 'all',
122
- ]);
123
- }
124
- return ObjectFactory_1.ObjectFactory.CreateColumnFilter(this.props.currentColumn.columnId, null, null);
35
+ return Boolean(this.props.columnFilter.IsSuspended);
125
36
  }
126
37
  render() {
127
- const { filter } = this.state;
38
+ const { columnFilter } = this.props;
128
39
  const predicateDefs = this.props.api.filterApi.getFilterPredicateDefsForColumn(this.props.currentColumn);
129
- const activePredicateDef = this.props.api.predicateApi.getPredicateDefById(filter === null || filter === void 0 ? void 0 : filter.Predicate.PredicateId);
40
+ const activePredicateDef = this.props.api.predicateApi.getPredicateDefById(columnFilter === null || columnFilter === void 0 ? void 0 : columnFilter.Predicate.PredicateId);
130
41
  if (!this.props.currentColumn || !this.props.currentColumn.filterable) {
131
42
  return null;
132
43
  }
@@ -148,30 +59,31 @@ class QuickFilterFormComponent extends React.Component {
148
59
  }
149
60
  return (React.createElement(React.Fragment, null,
150
61
  showQuickFilterDropdown && (React.createElement(OverlayTrigger_1.default, { className: "ab-QuickFilter", showEvent: showEvent, hideEvent: hideEvent, preventPortalEventPropagation: showEvent === 'click', targetOffset: 10, hideDelay: 300, "data-name": "quick-filter-overlay", render: () => (React.createElement(rebass_1.Flex, { className: "ab-QuickFilter__dropdown", flexDirection: "column", "data-name": "quick-filter", fontSize: 2 },
151
- (filter === null || filter === void 0 ? void 0 : filter.Predicate.PredicateId) && (React.createElement(SimpleButton_1.default, { p: 2, variant: "text", onClick: () => this.clearFilter() },
62
+ (columnFilter === null || columnFilter === void 0 ? void 0 : columnFilter.Predicate.PredicateId) && (React.createElement(SimpleButton_1.default, { p: 2, variant: "text", onClick: () => this.clearFilter() },
152
63
  React.createElement("span", { style: { width: 20, marginRight: 10 } },
153
64
  React.createElement(icons_1.Icon, { name: "delete" })),
154
65
  "Clear")),
155
- predicateDefs.map((p) => (React.createElement(SimpleButton_1.default, { "data-name": filter.Predicate.PredicateId, disabled: this.isFilterDisabled(), key: p.id, p: 2, variant: "text", tone: (filter === null || filter === void 0 ? void 0 : filter.Predicate.PredicateId) === p.id ? 'info' : 'none', onClick: () => this.selectColumnPredicate(p.id) },
66
+ predicateDefs.map((p) => (React.createElement(SimpleButton_1.default, { "data-name": columnFilter.Predicate.PredicateId, disabled: this.isFilterDisabled(), key: p.id, p: 2, variant: "text", tone: (columnFilter === null || columnFilter === void 0 ? void 0 : columnFilter.Predicate.PredicateId) === p.id ? 'info' : 'none', onClick: () => this.selectColumnPredicate(p.id) },
156
67
  React.createElement("span", { style: { width: 20, marginRight: 10 } }, this.renderPredicateIcon(p)),
157
68
  p.label))))) },
158
- React.createElement(SimpleButton_1.default, { "data-name": filter.Predicate.PredicateId, style: {
69
+ React.createElement(SimpleButton_1.default, { "data-name": columnFilter.Predicate.PredicateId, style: {
159
70
  borderRadius: 0,
160
71
  borderColor: 'var(--ab-color-primarydark)',
161
72
  } }, this.renderPredicateIcon(activePredicateDef)))),
162
- showQuickFilterInput && this.renderLabel(filter, activePredicateDef),
163
- showQuickFilterInput && this.renderPredicateInput(activePredicateDef, filter)));
73
+ showQuickFilterInput && this.renderLabel(columnFilter, activePredicateDef),
74
+ showQuickFilterInput && this.renderPredicateInput(activePredicateDef, columnFilter)));
164
75
  }
165
76
  renderLabel(filter, activePredicateDef) {
166
77
  if (this.hasValuesPredicate(filter === null || filter === void 0 ? void 0 : filter.Predicate)) {
167
- if (ArrayExtensions_1.default.IsNullOrEmpty(filter.Predicate.Inputs) &&
168
- ArrayExtensions_1.default.IsNullOrEmptyOrContainsSingleEmptyValue(this.state.distinctColumnValues)) {
169
- return this.renderNoValuesDropdown(filter);
170
- }
171
- return this.renderValuesDropdown(filter);
78
+ return (React.createElement(QuickFilterValues_1.QuickFilterValues, { api: this.props.api, currentColumn: this.props.currentColumn, isFilterDisabled: this.isFilterDisabled(), columnFilter: filter, clearColumnFilter: () => this.clearFilter(), updateColumnFilter: (columnFilter) => this.updateFilter(columnFilter), registerValuesDropdownApi: (api) => {
79
+ if (api && this.shouldOpenValuesDropdown) {
80
+ api.show();
81
+ this.shouldOpenValuesDropdown = false;
82
+ }
83
+ }, quickFilterValuesTrigger: this.props.quickFilterValuesTrigger }));
172
84
  }
173
85
  return (activePredicateDef &&
174
- (activePredicateDef === null || activePredicateDef === void 0 ? void 0 : activePredicateDef.inputs) === undefined && (React.createElement(rebass_1.Box, { color: this.isFilterDisabled() && 'var(--ab-color-text-on-primary)', disabled: this.isFilterDisabled(), p: 1, alignSelf: "center" }, activePredicateDef.label)));
86
+ (activePredicateDef === null || activePredicateDef === void 0 ? void 0 : activePredicateDef.inputs) === undefined && (React.createElement(rebass_1.Box, { color: this.isFilterDisabled() ? undefined : 'var(--ab-color-text-on-primary)', disabled: this.isFilterDisabled(), p: 1, alignSelf: "center" }, activePredicateDef.label)));
175
87
  }
176
88
  renderPredicateIcon(predicateDef) {
177
89
  if (!predicateDef || !predicateDef.icon) {
@@ -223,117 +135,39 @@ class QuickFilterFormComponent extends React.Component {
223
135
  } }));
224
136
  });
225
137
  }
226
- renderNoValuesDropdown(filter) {
227
- return (React.createElement(SimpleButton_1.default, { disabled: true, style: {
228
- flex: 1,
229
- whiteSpace: 'nowrap',
230
- overflow: 'hidden',
231
- textOverflow: 'ellipsis',
232
- borderRadius: 0,
233
- borderLeftWidth: 0,
234
- borderColor: 'var(--ab-color-primarydark)',
235
- } }, 'No Column Values'));
236
- }
237
- renderValuesDropdown(filter) {
238
- let showEvent = 'mouseenter';
239
- if (this.props.quickFilterValuesTrigger === 'click') {
240
- showEvent = 'click';
241
- }
242
- let selectedValues = filter.Predicate.PredicateId === 'Values' ? 'Select Values' : 'Exclude Values';
243
- if (filter.Predicate.Inputs.length) {
244
- selectedValues = filter.Predicate.Inputs.map((input) => {
245
- var _a, _b;
246
- const label = (_b = (_a = this.state.distinctColumnValues) === null || _a === void 0 ? void 0 : _a.find((distinctValue) => {
247
- if (input instanceof Date) {
248
- return (0, date_fns_1.isSameDay)(input, distinctValue.value);
249
- }
250
- return distinctValue.value === input;
251
- })) === null || _b === void 0 ? void 0 : _b.label;
252
- return label !== null && label !== void 0 ? label : input;
253
- }).join(', ');
254
- }
255
- return (React.createElement(OverlayTrigger_1.default, { showEvent: showEvent,
256
- // cannot hide on blur, because the form input receives the input when this is opened
257
- hideEvent: "mouseleave", hideDelay: 300, ref: (api) => {
258
- this.valuesDropdown = api;
259
- }, render: () => {
260
- var _a;
261
- return (React.createElement(rebass_1.Flex, { onMouseEnter: () => {
262
- var _a;
263
- if (showEvent === 'click') {
264
- // For showEvent=mousenter this is not needed.
265
- // When mouseenter is triggered on the overlay, onShowFn is called, the overlay is no longer hidden.
266
- // But in this case because the trigger is click, another show is not triggered.
267
- (_a = this.valuesDropdown) === null || _a === void 0 ? void 0 : _a.show();
268
- }
269
- }, "data-name": "quick-filter-form", flexDirection: "column", style: {
270
- fontSize: 'var(--ab-font-size-2)',
271
- border: '1px solid var(--ab-color-primarydark)',
272
- background: 'var(--ab-color-defaultbackground)',
273
- zIndex: 1000,
274
- } },
275
- React.createElement(rebass_1.Flex, { m: 2 },
276
- React.createElement(SimpleButton_1.default, { onClick: () => this.clearFilter() }, "Clear Filter"),
277
- ((_a = this.props.api.optionsApi.getFilterOptions()) === null || _a === void 0 ? void 0 : _a.autoApplyFilter) == false && (React.createElement(SimpleButton_1.default, { ml: 2, onClick: () => this.updateFilter(this.state.filter) }, "Apply Filter"))),
278
- React.createElement(ListBoxFilterForm_1.ListBoxFilterForm, { disabled: this.isFilterDisabled(), suppressClientSideFilter: this.state.suppressClientSideFilter, isLoading: this.state.isDistinctColumnValuesLoading, onFilterChange: this.handleFilterChange, currentColumn: this.props.currentColumn, columns: [], columnDistinctValues: this.state.distinctColumnValues, dataType: this.props.currentColumn.dataType, uiSelectedColumnValues: this.state.filter.Predicate.Inputs.filter((input) => input !== ''), useAgGridStyle: true, onColumnValueSelectedChange: (list) => this.onColumnValuesChange(list) })));
279
- } },
280
- React.createElement(SimpleButton_1.default, { "data-name": 'Select Values', style: {
281
- flex: 1,
282
- whiteSpace: 'nowrap',
283
- overflow: 'hidden',
284
- textOverflow: 'ellipsis',
285
- borderRadius: 0,
286
- borderLeftWidth: 0,
287
- borderColor: 'var(--ab-color-primarydark)',
288
- }, disabled: this.isFilterDisabled() ||
289
- ArrayExtensions_1.default.IsNullOrEmptyOrContainsSingleEmptyValue(this.state.distinctColumnValues) }, selectedValues)));
290
- }
291
138
  onColumnValuesChange(columnValues) {
292
139
  var _a;
293
- const { filter } = this.state;
294
- filter.Predicate = { PredicateId: filter.Predicate.PredicateId, Inputs: columnValues };
140
+ const columnFilter = Object.assign({}, this.props.columnFilter);
141
+ columnFilter.Predicate = {
142
+ PredicateId: columnFilter.Predicate.PredicateId,
143
+ Inputs: columnValues,
144
+ };
295
145
  if ((_a = this.props.api.optionsApi.getFilterOptions()) === null || _a === void 0 ? void 0 : _a.autoApplyFilter) {
296
- this.updateFilter(filter);
146
+ this.updateFilter(columnFilter);
297
147
  }
298
148
  else {
299
- this.setState({ filter });
149
+ this.setState({ transientColumnFilter: columnFilter });
300
150
  }
301
151
  }
302
152
  selectColumnPredicate(predicateId) {
303
153
  var _a;
304
- const filter = Object.assign({}, this.state.filter);
154
+ const columnFilter = Object.assign({}, this.props.columnFilter);
305
155
  const predicateDef = this.props.api.predicateApi.getPredicateDefById(predicateId);
306
- filter.Predicate = {
156
+ columnFilter.Predicate = {
307
157
  PredicateId: predicateId,
308
158
  Inputs: ((_a = predicateDef.inputs) !== null && _a !== void 0 ? _a : []).map((i) => { var _a; return (_a = i.defaultValue) !== null && _a !== void 0 ? _a : ''; }),
309
159
  };
310
- this.updateFilter(filter);
160
+ this.updateFilter(columnFilter);
311
161
  if (predicateId === 'Values' || predicateId === 'ExcludeValues') {
312
- this.loadPermittedValues();
313
- requestAnimationFrame(() => {
314
- if (this.valuesDropdown) {
315
- this.valuesDropdown.show();
316
- }
317
- });
162
+ this.shouldOpenValuesDropdown = true;
318
163
  }
319
164
  }
320
- handleGridValueChange(changedColumnId) {
321
- var _a, _b, _c, _d;
322
- if (!this.hasValuesPredicate((_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.Predicate)) {
323
- return;
324
- }
325
- if (changedColumnId && changedColumnId !== ((_d = (_c = this.state) === null || _c === void 0 ? void 0 : _c.filter) === null || _d === void 0 ? void 0 : _d.ColumnId)) {
326
- return;
327
- }
328
- this.debouncedLoadPermittedValues();
329
- }
330
165
  updateFilter(filter) {
331
- this.setState({ filter });
332
166
  if (filter.Uuid) {
333
- this.debouncedEditFilter();
167
+ this.debouncedEditFilter(filter);
334
168
  }
335
169
  else {
336
- this.debouncedAddFilter();
170
+ this.debouncedAddFilter(filter);
337
171
  }
338
172
  }
339
173
  changeColumnPredicateInput(value, index) {
@@ -342,10 +176,10 @@ class QuickFilterFormComponent extends React.Component {
342
176
  this.selectColumnPredicate(predicateId);
343
177
  }
344
178
  else {
345
- const { filter } = this.state;
346
- filter.Predicate.Inputs = filter.Predicate.Inputs || [];
347
- filter.Predicate.Inputs[index] = value;
348
- this.updateFilter(filter);
179
+ const columnFilter = Object.assign({}, this.props.columnFilter);
180
+ columnFilter.Predicate.Inputs = columnFilter.Predicate.Inputs || [];
181
+ columnFilter.Predicate.Inputs[index] = value;
182
+ this.updateFilter(columnFilter);
349
183
  }
350
184
  }
351
185
  getPredicateIdForShortcutValue(value) {
@@ -353,17 +187,37 @@ class QuickFilterFormComponent extends React.Component {
353
187
  return (_a = this.props.api.filterApi.internalApi.findPredicateDefByShortcut(value, this.props.currentColumn)) === null || _a === void 0 ? void 0 : _a.id;
354
188
  }
355
189
  clearFilter() {
356
- const { filter } = this.state;
357
- this.props.api.filterApi.clearColumnFilterForColumn(filter.ColumnId);
190
+ const columnFilter = Object.assign({}, this.props.columnFilter);
191
+ this.props.api.filterApi.clearColumnFilterForColumn(columnFilter.ColumnId);
358
192
  }
359
193
  hasValuesPredicate(predicate) {
360
194
  return this.props.api.predicateApi.internalApi.hasPredicateValues(predicate);
361
195
  }
362
196
  }
197
+ function getColumnFilterWithDefault(state, props) {
198
+ const columnFilter = (0, LayoutRedux_1.getColumnFilterSelector)(state).find((cf) => cf.ColumnId == props.currentColumn.columnId);
199
+ if (columnFilter) {
200
+ return columnFilter;
201
+ }
202
+ const filterOptions = props.api.optionsApi.getFilterOptions();
203
+ if (!columnFilter && props.currentColumn.dataType === 'Number') {
204
+ return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultNumericColumnFilter), ['']);
205
+ }
206
+ if (!columnFilter && props.currentColumn.dataType === 'String') {
207
+ return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultStringColumnFilter), ['']);
208
+ }
209
+ if (!columnFilter && props.currentColumn.dataType === 'Date') {
210
+ return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, (0, getDefaultColumnFilterPredicate_1.getDefaultColumnFilterPredicate)(props.currentColumn, filterOptions.defaultDateColumnFilter), ['']);
211
+ }
212
+ if (!columnFilter && props.currentColumn.dataType === 'Boolean') {
213
+ return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, 'BooleanToggle', ['all']);
214
+ }
215
+ return ObjectFactory_1.ObjectFactory.CreateColumnFilter(props.currentColumn.columnId, null, null);
216
+ }
363
217
  function mapStateToProps(state, ownProps) {
364
218
  return {
365
219
  currentColumn: ownProps.currentColumn,
366
- columnFilters: (0, LayoutRedux_1.getColumnFilterSelector)(state),
220
+ columnFilter: getColumnFilterWithDefault(state, ownProps),
367
221
  };
368
222
  }
369
223
  function mapDispatchToProps(dispatch) {
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { ColumnFilter } from '../../../PredefinedConfig/Common/ColumnFilter';
3
+ import { AdaptableApi } from '../../../Api/AdaptableApi';
4
+ import { FilterOptions } from '../../../AdaptableOptions/FilterOptions';
5
+ import { AdaptableColumn } from '../../../PredefinedConfig/Common/AdaptableColumn';
6
+ export interface QuickFilterValuesProps {
7
+ api: AdaptableApi;
8
+ currentColumn: AdaptableColumn;
9
+ isFilterDisabled: boolean;
10
+ columnFilter: ColumnFilter;
11
+ clearColumnFilter: () => void;
12
+ updateColumnFilter: (filter: ColumnFilter) => void;
13
+ registerValuesDropdownApi: (api: {
14
+ show: () => any;
15
+ hide: () => any;
16
+ }) => void;
17
+ quickFilterValuesTrigger?: FilterOptions['quickFilterValuesTrigger'];
18
+ }
19
+ export declare const QuickFilterValues: (props: QuickFilterValuesProps) => JSX.Element;