@lightdash/common 0.1477.4 → 0.1478.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.
@@ -1,12 +1,17 @@
1
1
  import { type ConditionalOperator, type ConditionalRule } from './conditionalRule';
2
2
  import { type FieldTarget } from './filter';
3
- export type ConditionalFormattingWithConditionalOperator<T = number> = ConditionalRule<ConditionalOperator, T> & {
4
- values: T[];
5
- };
6
- export type ConditionalFormattingWithRange<T = number> = {
3
+ export type ConditionalFormattingMinMax<T = number> = {
7
4
  min: T;
8
5
  max: T;
9
6
  };
7
+ export type ConditionalFormattingColorRange = {
8
+ start: string;
9
+ end: string;
10
+ steps: number;
11
+ };
12
+ export type ConditionalFormattingWithConditionalOperator<T = number> = ConditionalRule<ConditionalOperator, T> & {
13
+ values: T[];
14
+ };
10
15
  export type ConditionalFormattingConfigWithSingleColor = {
11
16
  target: FieldTarget | null;
12
17
  color: string;
@@ -15,12 +20,8 @@ export type ConditionalFormattingConfigWithSingleColor = {
15
20
  export declare const isConditionalFormattingConfigWithSingleColor: (rule: ConditionalFormattingConfig) => rule is ConditionalFormattingConfigWithSingleColor;
16
21
  export type ConditionalFormattingConfigWithColorRange = {
17
22
  target: FieldTarget | null;
18
- color: {
19
- start: string;
20
- end: string;
21
- steps: 5;
22
- };
23
- rule: ConditionalFormattingWithRange;
23
+ color: ConditionalFormattingColorRange;
24
+ rule: ConditionalFormattingMinMax<number | 'auto'>;
24
25
  };
25
26
  export declare const isConditionalFormattingConfigWithColorRange: (config: ConditionalFormattingConfig) => config is ConditionalFormattingConfigWithColorRange;
26
27
  export type ConditionalFormattingConfig = ConditionalFormattingConfigWithSingleColor | ConditionalFormattingConfigWithColorRange;
@@ -29,3 +30,4 @@ export declare enum ConditionalFormattingConfigType {
29
30
  Range = "range"
30
31
  }
31
32
  export declare const getConditionalFormattingConfigType: (rule: ConditionalFormattingConfig) => ConditionalFormattingConfigType;
33
+ export type ConditionalFormattingMinMaxMap = Record<string, ConditionalFormattingMinMax>;
@@ -1,5 +1,5 @@
1
1
  import type { ItemsMap } from '..';
2
- import { type ConditionalFormattingConfig, type ConditionalFormattingConfigWithColorRange, type ConditionalFormattingConfigWithSingleColor, type ConditionalFormattingWithConditionalOperator } from '../types/conditionalFormatting';
2
+ import { type ConditionalFormattingColorRange, type ConditionalFormattingConfig, type ConditionalFormattingConfigWithColorRange, type ConditionalFormattingConfigWithSingleColor, type ConditionalFormattingMinMax, type ConditionalFormattingMinMaxMap, type ConditionalFormattingWithConditionalOperator } from '../types/conditionalFormatting';
3
3
  import { type ConditionalRuleLabels } from '../types/conditionalRule';
4
4
  import { type FilterableItem } from '../types/field';
5
5
  import { type FieldTarget } from '../types/filter';
@@ -7,17 +7,35 @@ export declare const createConditionalFormatingRule: () => ConditionalFormatting
7
7
  export declare const createConditionalFormattingConfigWithSingleColor: (defaultColor: string, target?: FieldTarget | null) => ConditionalFormattingConfigWithSingleColor;
8
8
  export declare const createConditionalFormattingConfigWithColorRange: (defaultColor: string, target?: FieldTarget | null) => ConditionalFormattingConfigWithColorRange;
9
9
  export declare const hasPercentageFormat: (field: ItemsMap[string] | undefined) => boolean;
10
- export declare const hasMatchingConditionalRules: (field: ItemsMap[string], value: unknown, config: ConditionalFormattingConfig | undefined) => boolean;
11
- export declare const getConditionalFormattingConfig: (field: ItemsMap[string] | undefined, value: unknown | undefined, conditionalFormattings: ConditionalFormattingConfig[] | undefined) => ConditionalFormattingConfig | undefined;
10
+ export declare const convertFormattedValue: <T extends unknown>(value: T, field: ItemsMap[string] | undefined) => number | T;
11
+ export declare const getMinMaxFromMinMaxMap: (minMaxMap: ConditionalFormattingMinMaxMap) => {
12
+ min: number;
13
+ max: number;
14
+ };
15
+ export declare const hasMatchingConditionalRules: (field: ItemsMap[string], value: unknown, minMaxMap: ConditionalFormattingMinMaxMap, config: ConditionalFormattingConfig | undefined) => boolean;
16
+ export declare const getConditionalFormattingConfig: ({ field, value, minMaxMap, conditionalFormattings, }: {
17
+ field: ItemsMap[string] | undefined;
18
+ value: unknown | undefined;
19
+ minMaxMap: ConditionalFormattingMinMaxMap | undefined;
20
+ conditionalFormattings: ConditionalFormattingConfig[] | undefined;
21
+ }) => ConditionalFormattingConfig | undefined;
12
22
  export declare const getConditionalFormattingDescription: (field: ItemsMap[string] | undefined, conditionalFormattingConfig: ConditionalFormattingConfig | undefined, getConditionalRuleLabel: (rule: ConditionalFormattingWithConditionalOperator, item: FilterableItem) => ConditionalRuleLabels) => string | undefined;
13
- export declare const getConditionalFormattingColor: (field: ItemsMap[string] | undefined, value: unknown, conditionalFormattingConfig: ConditionalFormattingConfig | undefined, getColorFromRange: (value: number, config: {
14
- color: {
15
- start: string;
16
- end: string;
17
- steps: number;
18
- };
19
- rule: {
20
- min: number;
21
- max: number;
22
- };
23
- }) => string | undefined) => string | undefined;
23
+ type GetColorFromRangeFunction = (value: number, colorRange: ConditionalFormattingColorRange, minMaxRange: ConditionalFormattingMinMax) => string | undefined;
24
+ export declare const getConditionalFormattingColorWithColorRange: ({ field, value, config, minMaxMap, getColorFromRange, }: {
25
+ field: ItemsMap[string] | undefined;
26
+ value: unknown;
27
+ config: ConditionalFormattingConfigWithColorRange;
28
+ minMaxMap: ConditionalFormattingMinMaxMap | undefined;
29
+ getColorFromRange: GetColorFromRangeFunction;
30
+ }) => string | undefined;
31
+ export declare const getConditionalFormattingColorWithSingleColor: ({ config, }: {
32
+ config: ConditionalFormattingConfigWithSingleColor;
33
+ }) => string;
34
+ export declare const getConditionalFormattingColor: ({ field, value, config, minMaxMap, getColorFromRange, }: {
35
+ field: ItemsMap[string] | undefined;
36
+ value: unknown;
37
+ config: ConditionalFormattingConfig | undefined;
38
+ minMaxMap: ConditionalFormattingMinMaxMap | undefined;
39
+ getColorFromRange: GetColorFromRangeFunction;
40
+ }) => string | undefined;
41
+ export {};
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getConditionalFormattingColor = exports.getConditionalFormattingDescription = exports.getConditionalFormattingConfig = exports.hasMatchingConditionalRules = exports.hasPercentageFormat = exports.createConditionalFormattingConfigWithColorRange = exports.createConditionalFormattingConfigWithSingleColor = exports.createConditionalFormatingRule = void 0;
3
+ exports.getConditionalFormattingColor = exports.getConditionalFormattingColorWithSingleColor = exports.getConditionalFormattingColorWithColorRange = exports.getConditionalFormattingDescription = exports.getConditionalFormattingConfig = exports.hasMatchingConditionalRules = exports.getMinMaxFromMinMaxMap = exports.convertFormattedValue = exports.hasPercentageFormat = exports.createConditionalFormattingConfigWithColorRange = exports.createConditionalFormattingConfigWithSingleColor = exports.createConditionalFormatingRule = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const lodash_1 = require("lodash");
5
6
  const uuid_1 = require("uuid");
6
7
  const conditionalFormatting_1 = require("../types/conditionalFormatting");
7
8
  const conditionalRule_1 = require("../types/conditionalRule");
@@ -49,11 +50,22 @@ const convertFormattedValue = (value, field) => {
49
50
  }
50
51
  return value;
51
52
  };
52
- const hasMatchingConditionalRules = (field, value, config) => {
53
+ exports.convertFormattedValue = convertFormattedValue;
54
+ const getMinMaxFromMinMaxMap = (minMaxMap) => ({
55
+ min: Math.min(...Object.values(minMaxMap).map((m) => m.min)),
56
+ max: Math.max(...Object.values(minMaxMap).map((m) => m.max)),
57
+ });
58
+ exports.getMinMaxFromMinMaxMap = getMinMaxFromMinMaxMap;
59
+ const hasMatchingConditionalRules = (field, value, minMaxMap, config) => {
53
60
  if (!config)
54
61
  return false;
55
62
  const parsedValue = typeof value === 'string' ? Number(value) : value;
56
- const convertedValue = convertFormattedValue(parsedValue, field);
63
+ const convertedValue = (0, exports.convertFormattedValue)(parsedValue, field);
64
+ const currentFieldId = (0, item_1.getItemId)(field);
65
+ const targetFieldId = config.target?.fieldId;
66
+ if (targetFieldId !== undefined && targetFieldId !== currentFieldId) {
67
+ return false;
68
+ }
57
69
  if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithSingleColor)(config)) {
58
70
  return config.rules.every((rule) => {
59
71
  switch (rule.operator) {
@@ -94,23 +106,37 @@ const hasMatchingConditionalRules = (field, value, config) => {
94
106
  if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithColorRange)(config)) {
95
107
  if (typeof convertedValue !== 'number')
96
108
  return false;
97
- return (convertedValue >= config.rule.min &&
98
- convertedValue <= config.rule.max);
109
+ let min;
110
+ let max;
111
+ if (config.rule.min === 'auto') {
112
+ min = targetFieldId
113
+ ? minMaxMap[targetFieldId].min
114
+ : (0, exports.getMinMaxFromMinMaxMap)(minMaxMap).min;
115
+ }
116
+ else {
117
+ min = config.rule.min;
118
+ }
119
+ if (config.rule.max === 'auto') {
120
+ max = targetFieldId
121
+ ? minMaxMap[targetFieldId].max
122
+ : (0, exports.getMinMaxFromMinMaxMap)(minMaxMap).max;
123
+ }
124
+ else {
125
+ max = config.rule.max;
126
+ }
127
+ return convertedValue >= min && convertedValue <= max;
99
128
  }
100
129
  return (0, assertUnreachable_1.default)(config, 'Unknown conditional formatting config');
101
130
  };
102
131
  exports.hasMatchingConditionalRules = hasMatchingConditionalRules;
103
- const getConditionalFormattingConfig = (field, value, conditionalFormattings) => {
132
+ const getConditionalFormattingConfig = ({ field, value, minMaxMap = {}, conditionalFormattings, }) => {
104
133
  // For backwards compatibility with old table calculations without type
105
134
  const isCalculationTypeUndefined = field && (0, field_1.isTableCalculation)(field) && field.type === undefined;
106
135
  if (!conditionalFormattings ||
107
136
  !field ||
108
137
  (!(0, item_1.isNumericItem)(field) && !isCalculationTypeUndefined))
109
138
  return undefined;
110
- const fieldConfigs = conditionalFormattings.filter((c) => c.target?.fieldId === (0, item_1.getItemId)(field) || !c.target);
111
- return fieldConfigs
112
- .reverse()
113
- .find((config) => (0, exports.hasMatchingConditionalRules)(field, value, config));
139
+ return (0, lodash_1.findLast)(conditionalFormattings, (config) => (0, exports.hasMatchingConditionalRules)(field, value, minMaxMap, config));
114
140
  };
115
141
  exports.getConditionalFormattingConfig = getConditionalFormattingConfig;
116
142
  const getConditionalFormattingDescription = (field, conditionalFormattingConfig, getConditionalRuleLabel) => {
@@ -119,8 +145,12 @@ const getConditionalFormattingDescription = (field, conditionalFormattingConfig,
119
145
  }
120
146
  if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithColorRange)(conditionalFormattingConfig)) {
121
147
  return [
122
- `is greater than or equal to ${conditionalFormattingConfig.rule.min}`,
123
- `is less than or equal to ${conditionalFormattingConfig.rule.max}`,
148
+ `is greater than or equal to ${conditionalFormattingConfig.rule.min === 'auto'
149
+ ? 'min value in table'
150
+ : conditionalFormattingConfig.rule.min}`,
151
+ `is less than or equal to ${conditionalFormattingConfig.rule.max === 'auto'
152
+ ? 'max value in table'
153
+ : conditionalFormattingConfig.rule.max}`,
124
154
  ].join(' and ');
125
155
  }
126
156
  if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithSingleColor)(conditionalFormattingConfig)) {
@@ -132,20 +162,53 @@ const getConditionalFormattingDescription = (field, conditionalFormattingConfig,
132
162
  return (0, assertUnreachable_1.default)(conditionalFormattingConfig, 'Unknown conditional formatting config');
133
163
  };
134
164
  exports.getConditionalFormattingDescription = getConditionalFormattingDescription;
135
- const getConditionalFormattingColor = (field, value, conditionalFormattingConfig, getColorFromRange) => {
136
- if (!conditionalFormattingConfig) {
165
+ const getConditionalFormattingColorWithColorRange = ({ field, value, config, minMaxMap = {}, getColorFromRange, }) => {
166
+ if (!field)
167
+ return undefined;
168
+ const numericValue = typeof value === 'string' ? parseFloat(value) : value;
169
+ const convertedValue = (0, exports.convertFormattedValue)(numericValue, field);
170
+ const currentFieldId = (0, item_1.getItemId)(field);
171
+ const targetFieldId = config.target?.fieldId;
172
+ if (targetFieldId !== undefined && targetFieldId !== currentFieldId) {
137
173
  return undefined;
138
174
  }
139
- if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithColorRange)(conditionalFormattingConfig)) {
140
- const numericValue = typeof value === 'string' ? parseFloat(value) : value;
141
- const convertedValue = convertFormattedValue(numericValue, field);
142
- if (typeof convertedValue !== 'number')
143
- return undefined;
144
- return getColorFromRange(convertedValue, conditionalFormattingConfig);
175
+ if (typeof convertedValue !== 'number')
176
+ return undefined;
177
+ let min;
178
+ let max;
179
+ if (config.rule.min === 'auto') {
180
+ min = targetFieldId
181
+ ? minMaxMap[targetFieldId].min
182
+ : (0, exports.getMinMaxFromMinMaxMap)(minMaxMap).min;
145
183
  }
146
- if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithSingleColor)(conditionalFormattingConfig)) {
147
- return conditionalFormattingConfig.color;
184
+ else {
185
+ min = config.rule.min;
148
186
  }
149
- return (0, assertUnreachable_1.default)(conditionalFormattingConfig, 'Unknown conditional formatting config');
187
+ if (config.rule.max === 'auto') {
188
+ max = targetFieldId
189
+ ? minMaxMap[targetFieldId].max
190
+ : (0, exports.getMinMaxFromMinMaxMap)(minMaxMap).max;
191
+ }
192
+ else {
193
+ max = config.rule.max;
194
+ }
195
+ return getColorFromRange(convertedValue, config.color, { min, max });
196
+ };
197
+ exports.getConditionalFormattingColorWithColorRange = getConditionalFormattingColorWithColorRange;
198
+ const getConditionalFormattingColorWithSingleColor = ({ config, }) => config.color;
199
+ exports.getConditionalFormattingColorWithSingleColor = getConditionalFormattingColorWithSingleColor;
200
+ const getConditionalFormattingColor = ({ field, value, config, minMaxMap, getColorFromRange, }) => {
201
+ if (!config)
202
+ return undefined;
203
+ if ((0, conditionalFormatting_1.isConditionalFormattingConfigWithSingleColor)(config)) {
204
+ return (0, exports.getConditionalFormattingColorWithSingleColor)({ config });
205
+ }
206
+ return (0, exports.getConditionalFormattingColorWithColorRange)({
207
+ field,
208
+ value,
209
+ config,
210
+ minMaxMap,
211
+ getColorFromRange,
212
+ });
150
213
  };
151
214
  exports.getConditionalFormattingColor = getConditionalFormattingColor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1477.4",
3
+ "version": "0.1478.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [