@adaptabletools/adaptable 13.0.2 → 13.0.4-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 (56) hide show
  1. package/base.css +0 -7
  2. package/base.css.map +1 -1
  3. package/bundle.cjs.js +204 -204
  4. package/index.css +0 -8
  5. package/index.css.map +1 -1
  6. package/package.json +1 -1
  7. package/publishTimestamp.d.ts +1 -1
  8. package/publishTimestamp.js +1 -1
  9. package/src/AdaptableOptions/EntitlementOptions.d.ts +14 -1
  10. package/src/Api/ColumnApi.d.ts +1 -2
  11. package/src/Api/DashboardApi.d.ts +1 -1
  12. package/src/Api/Implementation/StyledColumnApiImpl.d.ts +4 -3
  13. package/src/Api/Implementation/StyledColumnApiImpl.js +66 -35
  14. package/src/Api/PredicateApi.d.ts +1 -2
  15. package/src/Api/StyledColumnApi.d.ts +12 -3
  16. package/src/PredefinedConfig/GridState.d.ts +1 -1
  17. package/src/PredefinedConfig/LayoutState.d.ts +1 -1
  18. package/src/PredefinedConfig/StyledColumnState.d.ts +14 -0
  19. package/src/Redux/ActionsReducers/FreeTextColumnRedux.d.ts +1 -1
  20. package/src/Redux/ActionsReducers/FreeTextColumnRedux.js +3 -3
  21. package/src/Strategy/FilterModule.js +0 -4
  22. package/src/Strategy/Interface/IModule.d.ts +1 -1
  23. package/src/Strategy/StyledColumnModule.js +13 -1
  24. package/src/Strategy/Utilities/Export/getExportColumnsViewItems.d.ts +1 -1
  25. package/src/Utilities/Services/EntitlementService.js +4 -1
  26. package/src/View/Components/AdaptableObjectList/AdaptableObjectCompactList.js +4 -3
  27. package/src/View/Components/AdaptableObjectList/AdaptableObjectList.js +4 -3
  28. package/src/View/Components/EntityRulesEditor/index.js +7 -14
  29. package/src/View/Components/PermittedValuesSelector/PermitedValuesSelector.d.ts +1 -2
  30. package/src/View/Components/PermittedValuesSelector/PermitedValuesSelector.js +1 -1
  31. package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +1 -5
  32. package/src/View/Components/PredicateEditor/PredicateEditor.d.ts +10 -0
  33. package/src/View/Components/PredicateEditor/PredicateEditor.js +44 -0
  34. package/src/View/Components/RangesComponent.d.ts +4 -3
  35. package/src/View/Components/RangesComponent.js +74 -53
  36. package/src/View/Layout/Wizard/LayoutWizard.js +1 -0
  37. package/src/View/Layout/Wizard/sections/FilterSection.d.ts +1 -0
  38. package/src/View/Layout/Wizard/sections/FilterSection.js +52 -3
  39. package/src/View/Query/QueryViewPanel.d.ts +1 -1
  40. package/src/View/StyledColumn/Wizard/StyledColumnWizard.js +11 -2
  41. package/src/View/StyledColumn/Wizard/StyledColumnWizardColumnSection.js +11 -7
  42. package/src/View/StyledColumn/Wizard/StyledColumnWizardSettingsSection.d.ts +8 -0
  43. package/src/View/StyledColumn/Wizard/StyledColumnWizardSettingsSection.js +38 -0
  44. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection.js +42 -15
  45. package/src/agGrid/Adaptable.js +23 -7
  46. package/src/agGrid/PercentBarRenderer.d.ts +2 -6
  47. package/src/agGrid/PercentBarRenderer.js +9 -10
  48. package/src/agGrid/agGridHelper.d.ts +2 -6
  49. package/src/agGrid/agGridHelper.js +2 -2
  50. package/src/bundle-dependencies/bundles/react-toastify/index.js +1 -1
  51. package/src/components/EllipsisContainer/index.js +1 -1
  52. package/src/metamodel/adaptable.metamodel.d.ts +22 -0
  53. package/src/metamodel/adaptable.metamodel.js +1 -1
  54. package/src/types.d.ts +1 -1
  55. package/version.d.ts +1 -1
  56. package/version.js +1 -1
@@ -97,10 +97,6 @@ class FilterModule extends AdaptableModuleBase_1.AdaptableModuleBase {
97
97
  name: 'Column',
98
98
  values: [this.api.columnApi.getFriendlyNameFromColumnId(filter.ColumnId)],
99
99
  },
100
- {
101
- name: 'Filter',
102
- values: [this.api.filterApi.columnFilterToString(filter)],
103
- },
104
100
  ],
105
101
  abObject: filter,
106
102
  };
@@ -44,7 +44,7 @@ export interface AdaptableObjectItemView {
44
44
  */
45
45
  view?: React.FunctionComponent<React.PropsWithChildren<{
46
46
  data: AdaptableObject | SuspendableObject;
47
- }>>;
47
+ }>> | React.ReactElement;
48
48
  /**
49
49
  * Values used for the component.
50
50
  * Could be later extended to include an 'onChange' prop.
@@ -76,6 +76,11 @@ class StyledColumnModule extends AdaptableModuleBase_1.AdaptableModuleBase {
76
76
  if (column.dataType === 'Number') {
77
77
  let styledColumn = this.api.styledColumnApi.getStyledColumnByColumnId(column.columnId);
78
78
  let styledColumnExists = Boolean(styledColumn);
79
+ if (!styledColumn) {
80
+ styledColumn = Object.assign(Object.assign({}, ObjectFactory_1.default.CreateEmptyStyledColumn()), { ColumnId: column.columnId,
81
+ // numbers default to gradient
82
+ GradientStyle: {} });
83
+ }
79
84
  if (styledColumn && styledColumn.IsReadOnly && styledColumn.IsReadOnly == true) {
80
85
  styledColumnExists = false;
81
86
  }
@@ -88,7 +93,10 @@ class StyledColumnModule extends AdaptableModuleBase_1.AdaptableModuleBase {
88
93
  returnColumnMenuItems.push(this.createColumnMenuItemShowPopup(label + 'Styled Column', this.moduleInfo.Popup, this.moduleInfo.Glyph, popupParam));
89
94
  }
90
95
  if (column.dataType == 'Boolean' && !this.api.columnApi.isFreeTextColumn(column.columnId)) {
91
- const styledColumn = this.api.styledColumnApi.getStyledColumnByColumnId(column.columnId);
96
+ let styledColumn = this.api.styledColumnApi.getStyledColumnByColumnId(column.columnId);
97
+ if (!styledColumn) {
98
+ styledColumn = Object.assign(Object.assign({}, ObjectFactory_1.default.CreateEmptyStyledColumn()), { ColumnId: column.columnId, CheckBoxStyle: true });
99
+ }
92
100
  const hasCheckBox = styledColumn && (styledColumn === null || styledColumn === void 0 ? void 0 : styledColumn.CheckBoxStyle);
93
101
  if (hasCheckBox) {
94
102
  returnColumnMenuItems.push(this.createColumnMenuItemClickFunction('Remove Checkbox', 'unchecked', () => {
@@ -140,6 +148,10 @@ class StyledColumnModule extends AdaptableModuleBase_1.AdaptableModuleBase {
140
148
  return (0, StyledColumnWizardStyleSection_1.renderStyledColumnStyleSummary)(styledColumn, this.api);
141
149
  },
142
150
  },
151
+ {
152
+ name: 'Settings',
153
+ values: [`Include grouped rows: ${styledColumn.IncludeGroupedRows ? 'Yes' : 'No'}`],
154
+ },
143
155
  ].filter(Boolean),
144
156
  };
145
157
  }
@@ -1,3 +1,3 @@
1
- import { AdaptableApi, Report } from '../../../../types';
2
1
  import { AdaptableObjectItemView } from '../../Interface/IModule';
2
+ import { AdaptableApi, Report } from '../../../../types';
3
3
  export declare const getExportColumnsViewItems: (report: Report, api: AdaptableApi) => AdaptableObjectItemView;
@@ -28,7 +28,10 @@ class EntitlementService {
28
28
  let entitlementOptions = adaptableOptions.entitlementOptions;
29
29
  if (entitlementOptions) {
30
30
  const defaultAccessLevel = typeof entitlementOptions.defaultAccessLevel === 'function'
31
- ? entitlementOptions.defaultAccessLevel(adaptableOptions.userName, adaptableOptions.adaptableId)
31
+ ? entitlementOptions.defaultAccessLevel({
32
+ userName: adaptableOptions.userName,
33
+ adaptableId: adaptableOptions.adaptableId,
34
+ })
32
35
  : entitlementOptions.defaultAccessLevel;
33
36
  const moduleEntitlements = entitlementOptions.moduleEntitlements;
34
37
  if (moduleEntitlements) {
@@ -46,10 +46,11 @@ const AdaptableObjectCompactListItem = (props) => {
46
46
  return (React.createElement(rebass_1.Flex, { className: `${baseClassName}__Item`, alignItems: "center" },
47
47
  labelEl && React.createElement(rebass_1.Flex, { className: `${baseClassName}__Item__Name` }, labelEl),
48
48
  React.createElement(rebass_1.Box, { flex: 1 },
49
- objectView.item.view &&
50
- React.createElement(objectView.item.view, {
49
+ typeof objectView.item.view === 'function'
50
+ ? React.createElement(objectView.item.view, {
51
51
  data: props.abObject,
52
- }),
52
+ })
53
+ : objectView.item.view,
53
54
  Boolean(((_f = objectView.item) === null || _f === void 0 ? void 0 : _f.values) && ((_h = (_g = objectView.item) === null || _g === void 0 ? void 0 : _g.values) === null || _h === void 0 ? void 0 : _h.length)) && (React.createElement(rebass_1.Box, { mb: 2, className: `${baseClassName}__Item__Values` },
54
55
  React.createElement(ValueSelector_1.ValueOptionsTags, { style: { marginRight: 0 }, readOnly: true, options: objectView.item.values, value: objectView.item.values, allowWrap: true, toIdentifier: (c) => c, toLabel: (c) => React.createElement(React.Fragment, null, c) })))),
55
56
  suspendAction && unSuspendAction && (React.createElement(SimpleButton_1.default, { onMouseDown: handleSuspendUnSuspend, tone: isSuspended ? 'neutral' : 'success', variant: "text", icon: isSuspended ? 'play' : 'pause' })),
@@ -35,10 +35,11 @@ const AdaptableObjectListItemView = (props) => {
35
35
  props.handleOnEdit(tag.name);
36
36
  } }))),
37
37
  React.createElement(rebass_1.Box, { flex: 1, className: `${baseClassName}__values` },
38
- tag.view &&
39
- React.createElement(tag.view, {
38
+ typeof tag.view === 'function'
39
+ ? React.createElement(tag.view, {
40
40
  data: props.abObject,
41
- }),
41
+ })
42
+ : tag.view,
42
43
  Boolean((tag === null || tag === void 0 ? void 0 : tag.values) && ((_a = tag === null || tag === void 0 ? void 0 : tag.values) === null || _a === void 0 ? void 0 : _a.length)) && (React.createElement(ValueSelector_1.ValueOptionsTags, { style: { marginRight: 0 }, readOnly: true, options: tag.values, value: tag.values, allowWrap: true, toIdentifier: (c) => c, toLabel: (c) => React.createElement(React.Fragment, null, c) })))));
43
44
  })),
44
45
  props.showActions && (React.createElement(rebass_1.Flex, { flexDirection: "column", className: `${baseClassName}__buttons` },
@@ -7,14 +7,12 @@ const react_1 = require("react");
7
7
  const rebass_1 = require("rebass");
8
8
  const Tabs_1 = require("../../../components/Tabs");
9
9
  const Radio_1 = tslib_1.__importDefault(require("../../../components/Radio"));
10
- const DropdownButton_1 = tslib_1.__importDefault(require("../../../components/DropdownButton"));
11
10
  const ExpressionEditor_1 = require("../../../components/ExpressionEditor");
12
11
  const HelpBlock_1 = tslib_1.__importDefault(require("../../../components/HelpBlock"));
13
- const AdaptableInput_1 = tslib_1.__importDefault(require("../AdaptableInput"));
14
12
  const AdaptableContext_1 = require("../../AdaptableContext");
15
13
  const ButtonInfo_1 = require("../Buttons/ButtonInfo");
16
14
  const DocumentationLinkConstants_1 = require("../../../Utilities/Constants/DocumentationLinkConstants");
17
- const PermittedValuesSelector_1 = require("../PermittedValuesSelector");
15
+ const PredicateEditor_1 = require("../PredicateEditor/PredicateEditor");
18
16
  const isRuleValid = (abObject, api, context) => {
19
17
  var _a, _b, _c, _d, _e, _f;
20
18
  if (!((_a = abObject === null || abObject === void 0 ? void 0 : abObject.Rule) === null || _a === void 0 ? void 0 : _a.Predicate) && !((_b = abObject === null || abObject === void 0 ? void 0 : abObject.Rule) === null || _b === void 0 ? void 0 : _b.BooleanExpression)) {
@@ -98,14 +96,13 @@ const EntityRulesEditor = (props) => {
98
96
  const predicateInputs = predicateId ? (_d = (_c = data.Rule) === null || _c === void 0 ? void 0 : _c.Predicate.Inputs) !== null && _d !== void 0 ? _d : [] : [];
99
97
  const currentPredicateDef = api.predicateApi.getPredicateDefById(predicateId);
100
98
  const isValuesPredicateDef = (colDef) => colDef && ['Values', 'ExcludeValues'].includes(colDef.id);
101
- const predicateDefsOptions = predicateDefs
102
- .filter((def) => {
99
+ const filteredPredicateDefs = predicateDefs.filter((def) => {
103
100
  if (isValuesPredicateDef(def)) {
104
101
  return 'ColumnIds' in data.Scope && data.Scope.ColumnIds.length === 1;
105
102
  }
106
103
  return true;
107
- })
108
- .map((item) => ({
104
+ });
105
+ const predicateDefsOptions = filteredPredicateDefs.map((item) => ({
109
106
  value: item.id,
110
107
  label: item.label,
111
108
  onClick: () => onPredicateChange(item),
@@ -173,13 +170,9 @@ const EntityRulesEditor = (props) => {
173
170
  React.createElement(Radio_1.default, { tabIndex: -1, margin: 0, checked: type === 'Predicate' }, "Predicate"))) : null,
174
171
  showPredicate ? (React.createElement(Tabs_1.Tabs.Content, { "data-name": "Predicate", value: "Predicate" },
175
172
  React.createElement(rebass_1.Text, { fontSize: 2, mb: 2 }, descriptions.selectPredicate),
176
- React.createElement(DropdownButton_1.default, { "data-name": "entity-rules-editor-predicate-dropdown", className: `${baseClassName}__predicate-dropdown`, placeholder: "Select Rule", showClearButton: !!((_e = data.Rule) === null || _e === void 0 ? void 0 : _e.Predicate), onClear: clearPredicate, items: predicateDefsOptions, columns: ['label'] }, currentPredicateDef ? currentPredicateDef.label : 'Select Rule'), (_f = currentPredicateDef === null || currentPredicateDef === void 0 ? void 0 : currentPredicateDef.inputs) === null || _f === void 0 ? void 0 :
177
- _f.map((predicateDefInput, index) => (React.createElement(rebass_1.Flex, { key: predicateId + index, flexDirection: "column" },
178
- index > 0 && React.createElement(HelpBlock_1.default, { marginTop: 2 }, "AND"),
179
- React.createElement(AdaptableInput_1.default, { marginTop: 2, type: predicateDefInput.type, autoFocus: index === 0, value: predicateInputs[index], onChange: (e) => onPredicateInputChange(e, index) })))),
180
- isValuesPredicateDef(currentPredicateDef) &&
181
- 'ColumnIds' in data.Scope &&
182
- data.Scope.ColumnIds.length === 1 && (React.createElement(PermittedValuesSelector_1.PermitedValuesSelector, { onPredicateValuesChange: onPredicateValuesChange, predicate: (_g = data.Rule) === null || _g === void 0 ? void 0 : _g.Predicate, scope: data.Scope })),
173
+ React.createElement(PredicateEditor_1.PredicateEditor, { columnId: 'ColumnIds' in data.Scope ? (_f = (_e = data.Scope) === null || _e === void 0 ? void 0 : _e.ColumnIds) === null || _f === void 0 ? void 0 : _f[0] : null, predicateDefs: filteredPredicateDefs, predicate: (_g = data.Rule) === null || _g === void 0 ? void 0 : _g.Predicate, onChange: (predicate) => {
174
+ props.onChange(Object.assign(Object.assign({}, data), { Rule: Object.assign(Object.assign({}, data.Rule), { Predicate: predicate }) }));
175
+ }, onClear: clearPredicate }),
183
176
  showDocumentationLinks && (React.createElement(HelpBlock_1.default, { "data-name": "query-documentation", mt: 3, mb: 2, style: {
184
177
  fontSize: 'var(--ab-font-size-3)',
185
178
  padding: 0,
@@ -1,8 +1,7 @@
1
1
  import * as React from 'react';
2
- import { ScopeColumnIds } from '../../../PredefinedConfig/Common/AdaptableScope';
3
2
  import { AdaptablePredicate } from '../../../types';
4
3
  export interface PermitedValuesSelectorProps {
5
- scope: ScopeColumnIds;
4
+ columnId: string;
6
5
  onPredicateValuesChange: (inputs: any[]) => void;
7
6
  predicate: AdaptablePredicate;
8
7
  }
@@ -11,7 +11,7 @@ const ListBoxFilterForm_1 = require("../FilterForm/ListBoxFilterForm");
11
11
  const PermitedValuesSelector = (props) => {
12
12
  var _a;
13
13
  const adaptable = (0, AdaptableContext_1.useAdaptable)();
14
- const columnId = props.scope.ColumnIds[0];
14
+ const columnId = props.columnId;
15
15
  const column = adaptable.api.columnApi.getColumnFromId(columnId);
16
16
  const distinctValues = ((_a = adaptable.api.columnApi.getDistinctDisplayValuesForColumn(columnId)) !== null && _a !== void 0 ? _a : []).map((value) => ({ value: value, label: value }));
17
17
  const predicateInputs = props.predicate.Inputs;
@@ -78,11 +78,7 @@ const AdaptablePopupModuleView = (props) => {
78
78
  " New"));
79
79
  }
80
80
  else if (EditWizard || moduleViewProperties.onOpenEditPopup) {
81
- newButton = (React.createElement(ButtonNew_1.ButtonNew, { onClick: () => handleOpenEditPopup(), tooltip: toolTipText, accessLevel: props.accessLevel, style: {
82
- color: 'var(--ab-color-text-on-add)',
83
- fill: 'var(--ab-color-text-on-add)',
84
- background: 'var(--ab-color-action-add)',
85
- } }));
81
+ newButton = (React.createElement(ButtonNew_1.ButtonNew, { onClick: () => handleOpenEditPopup(), tooltip: toolTipText, accessLevel: props.accessLevel }));
86
82
  }
87
83
  const handleWizardClose = () => {
88
84
  var _a;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { AdaptablePredicate, AdaptablePredicateDef } from '../../../types';
3
+ export interface PredicateEditorProps {
4
+ columnId?: string;
5
+ predicateDefs: AdaptablePredicateDef[];
6
+ predicate?: AdaptablePredicate;
7
+ onChange: (predicate: AdaptablePredicate) => void;
8
+ onClear?: () => void;
9
+ }
10
+ export declare const PredicateEditor: React.FunctionComponent<PredicateEditorProps>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PredicateEditor = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const React = tslib_1.__importStar(require("react"));
6
+ const rebass_1 = require("rebass");
7
+ const DropdownButton_1 = tslib_1.__importDefault(require("../../../components/DropdownButton"));
8
+ const HelpBlock_1 = tslib_1.__importDefault(require("../../../components/HelpBlock"));
9
+ const AdaptableInput_1 = tslib_1.__importDefault(require("../AdaptableInput"));
10
+ const PermittedValuesSelector_1 = require("../PermittedValuesSelector");
11
+ const isValuesPredicateDef = (colDef) => colDef && ['Values', 'ExcludeValues'].includes(colDef.id);
12
+ const PredicateEditor = (props) => {
13
+ var _a;
14
+ const baseClassName = 'ab-PredicateEditor';
15
+ const predicateDefsOptions = React.useMemo(() => props.predicateDefs.map((item) => ({
16
+ value: item.id,
17
+ label: item.label,
18
+ onClick: () => {
19
+ var _a;
20
+ props.onChange({
21
+ PredicateId: item.id,
22
+ Inputs: ((_a = item === null || item === void 0 ? void 0 : item.inputs) !== null && _a !== void 0 ? _a : []).map((input) => { var _a; return (_a = input.defaultValue) !== null && _a !== void 0 ? _a : ''; }),
23
+ });
24
+ },
25
+ })), [props.predicateDefs, props.onChange]);
26
+ const handlePredicateInputChange = React.useCallback((e, index) => {
27
+ const { value } = e.target;
28
+ const newInputs = [...props.predicate.Inputs];
29
+ newInputs[index] = value;
30
+ props.onChange(Object.assign(Object.assign({}, props.predicate), { Inputs: newInputs }));
31
+ }, [props.predicate]);
32
+ const handlePredicateValuesChange = React.useCallback((inputs) => {
33
+ props.onChange(Object.assign(Object.assign({}, props.predicate), { Inputs: inputs }));
34
+ }, [props.predicate]);
35
+ const currentPredicateDef = props.predicateDefs.find((item) => { var _a; return item.id === ((_a = props.predicate) === null || _a === void 0 ? void 0 : _a.PredicateId); });
36
+ return (React.createElement(rebass_1.Box, { className: baseClassName },
37
+ React.createElement(DropdownButton_1.default, { "data-name": "select-predicate", mb: 2, width: "100%", className: `${baseClassName}__predicate-dropdown`, placeholder: "Select Rule", showClearButton: !!props.predicate, onClear: props.onClear, items: predicateDefsOptions, columns: ['label'] }, currentPredicateDef ? currentPredicateDef.label : 'Select Rule'),
38
+ React.createElement(rebass_1.Flex, null, (_a = currentPredicateDef === null || currentPredicateDef === void 0 ? void 0 : currentPredicateDef.inputs) === null || _a === void 0 ? void 0 : _a.map((predicateDefInput, index) => (React.createElement(React.Fragment, null,
39
+ index > 0 && React.createElement(HelpBlock_1.default, { margin: 2 }, "AND"),
40
+ React.createElement(rebass_1.Flex, { key: index, flex: 1, flexDirection: "column" },
41
+ React.createElement(AdaptableInput_1.default, { "data-name": `predicate-input-${index}`, marginTop: 2, type: predicateDefInput.type, autoFocus: index === 0, value: props.predicate.Inputs[index], onChange: (e) => handlePredicateInputChange(e, index) })))))),
42
+ isValuesPredicateDef(currentPredicateDef) && (React.createElement(PermittedValuesSelector_1.PermitedValuesSelector, { onPredicateValuesChange: handlePredicateValuesChange, predicate: props.predicate, columnId: props.columnId }))));
43
+ };
44
+ exports.PredicateEditor = PredicateEditor;
@@ -1,10 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { AdaptableApi } from '../../Api/AdaptableApi';
3
- import { CellColorRange, ColumnComparison } from '../../PredefinedConfig/StyledColumnState';
3
+ import { CellColorRange, ColumnComparison, NumericStyledColumn } from '../../PredefinedConfig/StyledColumnState';
4
4
  import { AdaptableScope } from '../../PredefinedConfig/Common/AdaptableScope';
5
5
  export interface RangesComponentProps extends React.ClassAttributes<RangesComponent> {
6
6
  ranges: CellColorRange[];
7
7
  columnComparison?: ColumnComparison;
8
+ rangeValueType: NumericStyledColumn['RangeValueType'];
9
+ onRangeValueTypeChange: (rangeValueType: NumericStyledColumn['RangeValueType']) => void;
8
10
  scope: AdaptableScope;
9
11
  api: AdaptableApi;
10
12
  showRangeDirection: boolean;
@@ -17,14 +19,13 @@ export interface RangesComponentProps extends React.ClassAttributes<RangesCompon
17
19
  disabled?: boolean;
18
20
  }
19
21
  export interface RangesComponentState {
20
- ranges: CellColorRange[];
21
- columnComparison: ColumnComparison;
22
22
  rangesType: 'Standard' | 'ColumnComparison';
23
23
  }
24
24
  export declare class RangesComponent extends React.Component<RangesComponentProps, RangesComponentState> {
25
25
  constructor(props: RangesComponentProps);
26
26
  render(): JSX.Element;
27
27
  private onRangesTypeChanged;
28
+ private handleRangeValueTypeChange;
28
29
  changeRangeMin(index: number, value: string): void;
29
30
  changeRangeMax(index: number, value: string): void;
30
31
  changeRangeColor(index: number, value: string): void;
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RangesComponent = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const React = tslib_1.__importStar(require("react"));
6
- const ColorPicker_1 = require("../ColorPicker");
7
6
  const rebass_1 = require("rebass");
7
+ const ColorPicker_1 = require("../ColorPicker");
8
+ const clamp_1 = tslib_1.__importDefault(require("lodash/clamp"));
8
9
  const StringExtensions_1 = require("../../Utilities/Extensions/StringExtensions");
9
10
  const CheckBox_1 = require("../../components/CheckBox");
10
11
  const FormLayout_1 = tslib_1.__importStar(require("../../components/FormLayout"));
@@ -14,56 +15,64 @@ const UIHelper_1 = require("../UIHelper");
14
15
  const ColumnSelector_1 = require("./Selectors/ColumnSelector");
15
16
  const Enums_1 = require("../../PredefinedConfig/Common/Enums");
16
17
  const Tabs_1 = require("../../components/Tabs");
18
+ const Radio_1 = tslib_1.__importDefault(require("../../components/Radio"));
17
19
  class RangesComponent extends React.Component {
18
20
  constructor(props) {
19
21
  super(props);
20
22
  this.state = {
21
- ranges: this.props.ranges,
22
- columnComparison: this.props.columnComparison,
23
23
  rangesType: this.props.columnComparison ? 'ColumnComparison' : 'Standard',
24
24
  };
25
25
  }
26
26
  render() {
27
- var _a;
28
- let comparisonMinValueNumber = this.state.columnComparison != null &&
29
- this.state.columnComparison.MinValue != null &&
30
- !isNaN(Number(this.state.columnComparison.MinValue))
31
- ? Number(this.state.columnComparison.MinValue)
27
+ var _a, _b;
28
+ let comparisonMinValueNumber = this.props.columnComparison != null &&
29
+ this.props.columnComparison.MinValue != null &&
30
+ !isNaN(Number(this.props.columnComparison.MinValue))
31
+ ? Number(this.props.columnComparison.MinValue)
32
32
  : '';
33
- let comparisonMaxValueNumber = this.state.columnComparison != null &&
34
- this.state.columnComparison.MaxValue != null &&
35
- !isNaN(Number(this.state.columnComparison.MaxValue))
36
- ? Number(this.state.columnComparison.MaxValue)
33
+ let comparisonMaxValueNumber = this.props.columnComparison != null &&
34
+ this.props.columnComparison.MaxValue != null &&
35
+ !isNaN(Number(this.props.columnComparison.MaxValue))
36
+ ? Number(this.props.columnComparison.MaxValue)
37
37
  : '';
38
- let comparisonMinValueColumnId = this.state.columnComparison != null &&
39
- this.state.columnComparison.MinValue != null &&
40
- isNaN(Number(this.state.columnComparison.MinValue))
41
- ? String(this.state.columnComparison.MinValue)
38
+ let comparisonMinValueColumnId = this.props.columnComparison != null &&
39
+ this.props.columnComparison.MinValue != null &&
40
+ isNaN(Number(this.props.columnComparison.MinValue))
41
+ ? String(this.props.columnComparison.MinValue)
42
42
  : undefined;
43
- let comparisonMaxValueColumnId = this.state.columnComparison != null &&
44
- this.state.columnComparison.MaxValue != null &&
45
- isNaN(Number(this.state.columnComparison.MaxValue))
46
- ? String(this.state.columnComparison.MaxValue)
43
+ let comparisonMaxValueColumnId = this.props.columnComparison != null &&
44
+ this.props.columnComparison.MaxValue != null &&
45
+ isNaN(Number(this.props.columnComparison.MaxValue))
46
+ ? String(this.props.columnComparison.MaxValue)
47
47
  : undefined;
48
- let comparisonColor = this.state.columnComparison != null && this.state.columnComparison.Color != null
49
- ? this.state.columnComparison.Color
48
+ let comparisonColor = this.props.columnComparison != null && this.props.columnComparison.Color != null
49
+ ? this.props.columnComparison.Color
50
50
  : undefined;
51
+ const isRangeValueTypeNumber = ((_a = this.props.rangeValueType) !== null && _a !== void 0 ? _a : 'Number') === 'Number';
51
52
  return (React.createElement(React.Fragment, null,
52
53
  React.createElement(rebass_1.Flex, { flexDirection: "row" },
53
54
  React.createElement(CheckBox_1.CheckBox, { marginTop: 3, checked: this.state.rangesType == 'ColumnComparison', onChange: (checked) => this.onRangesTypeChanged(checked) }, "Use a Column Comparison")),
54
55
  this.state.rangesType == 'Standard' && (React.createElement(Tabs_1.Tabs, { autoFocus: false, marginTop: 2 },
55
56
  React.createElement(Tabs_1.Tabs.Tab, null, "Ranges"),
56
- React.createElement(Tabs_1.Tabs.Content, null, (_a = this.state.ranges) === null || _a === void 0 ? void 0 :
57
- _a.map((range, index, list) => (React.createElement(rebass_1.Flex, { key: index, alignItems: "end", mb: 2, "data-name": "percent-bar-range" },
57
+ React.createElement(Tabs_1.Tabs.Content, null,
58
+ React.createElement(rebass_1.Flex, { alignItems: "center", mb: 2 },
59
+ React.createElement(rebass_1.Text, { mr: 3 }, "Range Type"),
60
+ React.createElement(Radio_1.default, { onChange: () => this.handleRangeValueTypeChange('Number'), checked: isRangeValueTypeNumber, mr: 2 }, "Number"),
61
+ React.createElement(Radio_1.default, { onChange: () => this.handleRangeValueTypeChange('Percentage'), checked: !isRangeValueTypeNumber }, "Percentage")), (_b = this.props.ranges) === null || _b === void 0 ? void 0 :
62
+ _b.map((range, index, list) => (React.createElement(rebass_1.Flex, { key: index, alignItems: "end", mb: 2, "data-name": "percent-bar-range" },
58
63
  React.createElement(rebass_1.Flex, { flexDirection: "column" },
59
- index === 0 && (React.createElement(CheckBox_1.CheckBox, { onClick: () => this.setRangeColMin(range), checked: range.Min === 'Col-Min', mt: 0, mb: 1, fontSize: 3, disabled: this.props.disabled }, "Col Min")),
60
- React.createElement(Input_1.default, { type: typeof range.Min == 'number' ? 'number' : 'text', disabled: this.props.disabled || range.Min === 'Col-Min', value: range.Min, onChange: (event) => {
64
+ isRangeValueTypeNumber && index === 0 && (React.createElement(CheckBox_1.CheckBox, { onClick: () => this.setRangeColMin(range), checked: range.Min === 'Col-Min', mt: 0, mb: 1, fontSize: 3, disabled: this.props.disabled }, "Col Min")),
65
+ React.createElement(Input_1.default, { type: typeof range.Min == 'number' ? 'number' : 'text', disabled: this.props.disabled ||
66
+ range.Min === 'Col-Min' ||
67
+ (index === 0 && !isRangeValueTypeNumber), value: range.Min, onChange: (event) => {
61
68
  const { value } = event.target;
62
69
  this.changeRangeMin(index, value);
63
70
  }, mr: 2 })),
64
71
  React.createElement(rebass_1.Flex, { flexDirection: "column" },
65
- index === list.length - 1 && (React.createElement(CheckBox_1.CheckBox, { mt: 0, mb: 1, onClick: () => this.setRangeColMax(range), checked: range.Max === 'Col-Max', fontSize: 3, disabled: this.props.disabled }, "Col Max")),
66
- React.createElement(Input_1.default, { value: range.Max, type: typeof range.Max == 'number' ? 'number' : 'text', disabled: this.props.disabled || range.Max === 'Col-Max', onChange: (event) => {
72
+ isRangeValueTypeNumber && index === list.length - 1 && (React.createElement(CheckBox_1.CheckBox, { mt: 0, mb: 1, onClick: () => this.setRangeColMax(range), checked: range.Max === 'Col-Max', fontSize: 3, disabled: this.props.disabled }, "Col Max")),
73
+ React.createElement(Input_1.default, { value: range.Max, type: typeof range.Max == 'number' ? 'number' : 'text', disabled: this.props.disabled ||
74
+ range.Max === 'Col-Max' ||
75
+ (index === list.length - 1 && !isRangeValueTypeNumber), onChange: (event) => {
67
76
  const { value } = event.target;
68
77
  this.changeRangeMax(index, value);
69
78
  }, mr: 2 })),
@@ -72,7 +81,7 @@ class RangesComponent extends React.Component {
72
81
  this.changeRangeColor(index, color);
73
82
  }, mr: 2, height: 33 })),
74
83
  this.props.showRangeDirection && (React.createElement(CheckBox_1.CheckBox, { disabled: this.props.disabled, checked: range.ReverseGradient && range.ReverseGradient == true, onChange: (checked) => this.changeRangeDirectionUp(index, checked) }, "Reverse Gradient")),
75
- React.createElement(SimpleButton_1.default, { ml: 2, mb: 1, icon: "delete", disabled: this.props.disabled || (this.state.ranges && this.state.ranges.length == 1), onClick: () => this.removeRange(index) })))),
84
+ React.createElement(SimpleButton_1.default, { ml: 2, mb: 1, icon: "delete", disabled: this.props.disabled || (this.props.ranges && this.props.ranges.length == 1), onClick: () => this.removeRange(index) })))),
76
85
  React.createElement("div", null,
77
86
  React.createElement(SimpleButton_1.default, { disabled: this.props.disabled, variant: "raised", "data-name": "add", onClick: () => this.addRange() }, "Add New Range"))))),
78
87
  this.state.rangesType == 'ColumnComparison' && (React.createElement(Tabs_1.Tabs, { autoFocus: false, marginTop: 2 },
@@ -105,7 +114,6 @@ class RangesComponent extends React.Component {
105
114
  };
106
115
  this.setState({
107
116
  rangesType: 'ColumnComparison',
108
- columnComparison: columnComparison,
109
117
  });
110
118
  this.props.updateColumnComparison(columnComparison);
111
119
  }
@@ -113,64 +121,78 @@ class RangesComponent extends React.Component {
113
121
  const ranges = this.props.api.scopeApi.createCellColorRangesForScope(this.props.scope);
114
122
  this.setState({
115
123
  rangesType: 'Standard',
116
- ranges: ranges,
117
124
  });
118
125
  this.props.updateRanges(ranges);
119
126
  }
120
127
  }
128
+ handleRangeValueTypeChange(rangeValueType) {
129
+ this.props.onRangeValueTypeChange(rangeValueType);
130
+ }
121
131
  changeRangeMin(index, value) {
122
- const { ranges } = this.state;
123
- ranges[index].Min = Number(value);
132
+ const { ranges } = this.props;
133
+ let newMin = Number(value);
134
+ if (this.props.rangeValueType === 'Percentage') {
135
+ newMin = (0, clamp_1.default)(newMin, 0, 100);
136
+ }
137
+ ranges[index].Min = newMin;
124
138
  if (ranges[index - 1]) {
125
- ranges[index - 1].Max = Number(value);
139
+ ranges[index - 1].Max = newMin;
126
140
  }
127
141
  this.props.updateRanges(ranges);
128
142
  }
129
143
  changeRangeMax(index, value) {
130
- const { ranges } = this.state;
131
- ranges[index].Max = Number(value);
144
+ const { ranges } = this.props;
145
+ let newMax = Number(value);
146
+ if (this.props.rangeValueType === 'Percentage') {
147
+ newMax = (0, clamp_1.default)(newMax, 0, 100);
148
+ }
149
+ ranges[index].Max = newMax;
132
150
  if (ranges[index + 1]) {
133
- ranges[index + 1].Min = Number(value);
151
+ ranges[index + 1].Min = newMax;
134
152
  }
135
153
  this.props.updateRanges(ranges);
136
154
  }
137
155
  changeRangeColor(index, value) {
138
- const { ranges } = this.state;
156
+ const { ranges } = this.props;
139
157
  ranges[index].Color = value;
140
158
  this.props.updateRanges(ranges);
141
159
  }
142
160
  changeRangeDirectionUp(index, checked) {
143
- const { ranges } = this.state;
161
+ const { ranges } = this.props;
144
162
  ranges[index].ReverseGradient = checked;
145
163
  this.props.updateRanges(ranges);
146
164
  }
147
165
  removeRange(index) {
148
- const { ranges } = this.state;
166
+ let ranges = [...this.props.ranges];
149
167
  ranges.splice(index, 1);
168
+ // Max 100 is always disabled, this prevents from having a Max range lower than 100
169
+ if (this.props.rangeValueType === 'Percentage' && ranges.length === 1) {
170
+ ranges[0] = Object.assign(Object.assign({}, ranges[0]), { Max: 100 });
171
+ }
150
172
  this.props.updateRanges(ranges);
151
173
  }
152
174
  setRangeColMin(range) {
153
- const newRanges = this.state.ranges.map((rangeItem) => {
175
+ const newRanges = this.props.ranges.map((rangeItem) => {
154
176
  if (rangeItem === range) {
155
177
  let newMin = rangeItem.Min === 'Col-Min' ? this.props.minMaxRangeValues.min : 'Col-Min';
156
178
  return Object.assign(Object.assign({}, rangeItem), { Min: newMin });
157
179
  }
158
180
  return rangeItem;
159
181
  });
160
- this.setState({ ranges: newRanges }, () => this.props.updateRanges(this.state.ranges));
182
+ this.props.updateRanges(newRanges);
161
183
  }
162
184
  setRangeColMax(range) {
163
- const newRanges = this.state.ranges.map((rangeItem) => {
185
+ const newRanges = this.props.ranges.map((rangeItem) => {
164
186
  if (rangeItem === range) {
165
187
  let newMax = rangeItem.Max === 'Col-Max' ? this.props.minMaxRangeValues.max : 'Col-Max';
166
188
  return Object.assign(Object.assign({}, rangeItem), { Max: newMax });
167
189
  }
168
190
  return rangeItem;
169
191
  });
170
- this.setState({ ranges: newRanges }, () => this.props.updateRanges(this.state.ranges));
192
+ this.props.updateRanges(newRanges);
171
193
  }
172
194
  addRange() {
173
- const lastRange = this.state.ranges[this.state.ranges.length - 1];
195
+ const lastRange = this.props.ranges[this.props.ranges.length - 1];
174
196
  let previousRange = lastRange;
175
197
  let Min = null;
176
198
  if (lastRange.Max === 'Col-Max') {
@@ -185,38 +207,37 @@ class RangesComponent extends React.Component {
185
207
  Max: lastRange.Max,
186
208
  Color: (0, UIHelper_1.getHexForName)(UIHelper_1.GRAY),
187
209
  };
188
- const newRanges = [...this.state.ranges.slice(0, -1), previousRange, newRange];
189
- // this.state.ranges.push(newRange);
190
- this.setState({ ranges: newRanges }, () => this.props.updateRanges(this.state.ranges));
210
+ const newRanges = [...this.props.ranges.slice(0, -1), previousRange, newRange];
211
+ this.props.updateRanges(newRanges);
191
212
  }
192
213
  changeColumnComparisonMinValue(event) {
193
214
  let e = event.target;
194
- const { columnComparison } = this.state;
215
+ const { columnComparison } = this.props;
195
216
  columnComparison.MinValue = StringExtensions_1.StringExtensions.IsNotNullOrEmpty(e.value)
196
217
  ? Number(e.value)
197
218
  : undefined;
198
219
  this.props.updateColumnComparison(columnComparison);
199
220
  }
200
221
  onMinColumnSelectedChanged(columns) {
201
- const { columnComparison } = this.state;
222
+ const { columnComparison } = this.props;
202
223
  columnComparison.MinValue = columns.length > 0 ? columns[0].columnId : undefined;
203
224
  this.props.updateColumnComparison(columnComparison);
204
225
  }
205
226
  changeColumnComparisonMaxValue(event) {
206
227
  let e = event.target;
207
- const { columnComparison } = this.state;
228
+ const { columnComparison } = this.props;
208
229
  columnComparison.MaxValue = StringExtensions_1.StringExtensions.IsNotNullOrEmpty(e.value)
209
230
  ? Number(e.value)
210
231
  : undefined;
211
232
  this.props.updateColumnComparison(columnComparison);
212
233
  }
213
234
  onMaxColumnSelectedChanged(columns) {
214
- const { columnComparison } = this.state;
235
+ const { columnComparison } = this.props;
215
236
  columnComparison.MaxValue = columns.length > 0 ? columns[0].columnId : undefined;
216
237
  this.props.updateColumnComparison(columnComparison);
217
238
  }
218
239
  changeColumnComparisonColor(value) {
219
- const { columnComparison } = this.state;
240
+ const { columnComparison } = this.props;
220
241
  columnComparison.Color = value;
221
242
  this.props.updateColumnComparison(columnComparison);
222
243
  }
@@ -125,6 +125,7 @@ const LayoutWizard = (props) => {
125
125
  },
126
126
  {
127
127
  title: 'Filters',
128
+ isValid: (layout) => (0, FilterSection_1.isColumnFiltersValid)(layout),
128
129
  details: 'View Column Filters',
129
130
  renderSummary: () => React.createElement(FilterSection_1.FilterSectionSummary, null),
130
131
  render: () => (React.createElement(rebass_1.Box, { p: 2, style: { height: '100%' } },
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Layout } from '../../../../../types';
3
+ export declare const isColumnFiltersValid: (layout: Layout) => true | string;
3
4
  export declare const FilterSectionSummary: React.FunctionComponent;
4
5
  interface FilterSectionProps {
5
6
  onChange: (data: Layout) => void;