@pega/cosmos-react-condition-builder 8.5.0 → 8.7.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 (32) hide show
  1. package/lib/components/ConditionBuilder/ConditionBuilder.types.d.ts +5 -0
  2. package/lib/components/ConditionBuilder/ConditionBuilder.types.d.ts.map +1 -1
  3. package/lib/components/ConditionBuilder/ConditionBuilder.types.js.map +1 -1
  4. package/lib/components/ConditionBuilder/RhsControls/CSVInput.d.ts +18 -0
  5. package/lib/components/ConditionBuilder/RhsControls/CSVInput.d.ts.map +1 -0
  6. package/lib/components/ConditionBuilder/RhsControls/CSVInput.js +59 -0
  7. package/lib/components/ConditionBuilder/RhsControls/CSVInput.js.map +1 -0
  8. package/lib/components/ConditionBuilder/RhsControls/NumericInput.d.ts +2 -0
  9. package/lib/components/ConditionBuilder/RhsControls/NumericInput.d.ts.map +1 -1
  10. package/lib/components/ConditionBuilder/RhsControls/NumericInput.js +21 -5
  11. package/lib/components/ConditionBuilder/RhsControls/NumericInput.js.map +1 -1
  12. package/lib/components/ConditionBuilder/RhsControls/NumericRangeInput.d.ts +31 -0
  13. package/lib/components/ConditionBuilder/RhsControls/NumericRangeInput.d.ts.map +1 -0
  14. package/lib/components/ConditionBuilder/RhsControls/NumericRangeInput.js +52 -0
  15. package/lib/components/ConditionBuilder/RhsControls/NumericRangeInput.js.map +1 -0
  16. package/lib/components/ConditionBuilder/RhsControls/index.d.ts +2 -4
  17. package/lib/components/ConditionBuilder/RhsControls/index.d.ts.map +1 -1
  18. package/lib/components/ConditionBuilder/RhsControls/index.js +21 -34
  19. package/lib/components/ConditionBuilder/RhsControls/index.js.map +1 -1
  20. package/lib/components/ConditionBuilder/core/formatter.d.ts.map +1 -1
  21. package/lib/components/ConditionBuilder/core/formatter.js +51 -4
  22. package/lib/components/ConditionBuilder/core/formatter.js.map +1 -1
  23. package/lib/components/ConditionInput/ConditionInput.d.ts.map +1 -1
  24. package/lib/components/ConditionInput/ConditionInput.js +7 -10
  25. package/lib/components/ConditionInput/ConditionInput.js.map +1 -1
  26. package/lib/components/ConditionInput/ConditionInput.types.d.ts +2 -0
  27. package/lib/components/ConditionInput/ConditionInput.types.d.ts.map +1 -1
  28. package/lib/components/ConditionInput/ConditionInput.types.js.map +1 -1
  29. package/lib/components/PromotedFilters/PromotedFilters.d.ts.map +1 -1
  30. package/lib/components/PromotedFilters/PromotedFilters.js +2 -12
  31. package/lib/components/PromotedFilters/PromotedFilters.js.map +1 -1
  32. package/package.json +2 -2
@@ -99,6 +99,11 @@ export type Field = BasicField & ({
99
99
  * e.g. Text(single value)/Picklist/... should be used as `TEXT`
100
100
  */
101
101
  type: FieldType;
102
+ /**
103
+ * Used to handle percentages are stored in the database,
104
+ * determine whether value is stored in the range of 0 to 1 or 0 to 100
105
+ */
106
+ unit?: 'percent_1' | 'percent_100';
102
107
  } | {
103
108
  /** An array of type Field to represent the child items. */
104
109
  items: Field[];
@@ -1 +1 @@
1
- {"version":3,"file":"ConditionBuilder.types.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ConditionBuilder.types.d.ts","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConditionBuilder.types.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.types.ts"],"names":[],"mappings":"","sourcesContent":["// cspell:words DDTHH\nimport type { Ref } from 'react';\n\nimport type { BaseProps, MenuItemProps, NoChildrenProp } from '@pega/cosmos-react-core';\n\nimport type {\n Comparator,\n ComparatorsByType,\n DateFunction,\n DatePart,\n FieldType,\n RHSType,\n TimePeriod\n} from './core/types';\n\n/** RHS object with a Date function */\nexport interface RhsWithDateFunction {\n /**\n * Output format for the value varies based on the dateFunction:\n * YEARS: First day of year as YYYY-MM-DD\n * QUARTERS: First day of quarter as YYYY-MM-DD\n * MONTHS: First day of month as YYYY-MM-DD\n * WEEKS: First day of week as YYYY-MM-DD\n * DAYS: Date as YYYY-MM-DD\n * HOURS: YYYY-MM-DDTHH:mm:ss\n * MINUTES: YYYY-MM-DDTHH:mm:ss\n * SECONDS: YYYY-MM-DDTHH:mm:ss\n * HOURS_OF_DAY: 0-23\n * MONTHS_OF_YEAR: 1-12\n * DAYS_OF_MONTH: 1-31\n * DAYS_OF_WEEK: 1-7\n */\n value: string | number;\n dateFunction: DateFunction;\n}\n\n/** RHS object with a Relative Date */\nexport interface RhsWithRelativeDate {\n relativeDate: {\n timePeriod: TimePeriod;\n interval?: number;\n datePart: DatePart;\n };\n}\n\n/** RHS object with PARAMETER type */\nexport interface RhsWithParameter {\n parameterId: string;\n}\n\n/** Type definition for the leaf-level nodes in nested conditions */\nexport interface LeafCondition {\n comparator: Comparator;\n\n lhs: {\n field: string;\n };\n\n // Optional for some of the comparators like IS_TRUE, IS_NULL, etc.\n rhs?:\n | { field: string } // When comparing the LHS with another field\n | { value: string | number } // When comparing the LHS with a single literal value (for comparators like EQ, GTE etc.)\n | { values: string[] | number[] } // When comparing the LHS with a list of literal values (for comparators like IN, NOT_IN etc.)\n | { start: string | number; end: string | number } // When comparing numeric or date field with two values that determine range\n | RhsWithDateFunction // When comparing a date field with a date function on RHS\n | RhsWithRelativeDate // When comparing a date field with a symbolic date on RHS\n | RhsWithParameter; // When comparing the LHS with PARAMETER type\n}\n\n/** Type definition for objects representing condition-rows in the builder UI */\nexport interface ConditionRow extends LeafCondition {\n id: string; // To use as `key` prop when rendering a list of rows\n label: string; // Used to refer the row from a logic-string\n}\n\n/**\n * Type definition for simple/complex conditions\n * At a given node in the condition tree, it can have exactly one of the keys AND/OR/NOT/condition\n */\nexport type Condition =\n | { AND: Condition[] }\n | { OR: Condition[] }\n | { NOT: Condition }\n | { condition: LeafCondition };\n\n/** Type definition for the input Field objects for the ConditionBuilder */\n\nexport type ParameterValue = Pick<MenuItemProps, 'id' | 'primary'>;\n\nexport type ReferenceValue = Pick<MenuItemProps, 'id' | 'primary'>;\n\nexport type ValueSelectionFunction<F> = (\n args:\n | { lhs?: F; ids: string[] }\n | {\n lhs?: F;\n searchString?: string; // If missing, assume empty string\n comparator?: string; // If missing, assume EQ\n\n // If the below are missing, fetch maximum possible results\n pageNumber?: number;\n pageSize?: number;\n }\n) => Promise<string[] | ReferenceValue[]>;\n\nexport type ValueSelection<F> = string[] | ReferenceValue[] | ValueSelectionFunction<F>;\n\ninterface BasicField extends Pick<MenuItemProps, 'id' | 'primary'> {}\n\nexport type Field = BasicField &\n (\n | {\n parameters?: ParameterValue[];\n\n /**\n * For TEXT fields, if a list of possible values is known ahead of time, they can be passed.\n * Otherwise we fetch data from api and pass a promise which returns list of values\n * This enables users to select from those values instead of manually typing them\n */\n possibleValues?: ValueSelection<Field>;\n\n /**\n * Data-type for the field.\n * Has to be one of these values. Convert where necessary\n * e.g. Currency/Percentage... should be used as `DECIMAL`\n * e.g. Text(single value)/Picklist/... should be used as `TEXT`\n */\n type: FieldType;\n }\n | {\n /** An array of type Field to represent the child items. */\n items: Field[];\n }\n );\n\n/** Valid date functions by field type */\nexport interface DateFunctionsByType {\n /** Date functions to enable for DATE_TIME fields */\n DATE_TIME: DateFunction[];\n /** Date functions to enable for DATE_ONLY fields */\n DATE_ONLY: DateFunction[];\n}\n\nexport interface HandleValue {\n /**\n * Returns condition validity and condition or undefined if valid.\n * Undefined indicates no condition.\n */\n getCondition: () => [valid: false] | [valid: true, condition: Condition | undefined];\n}\n\n/** Type definition for the input props of ConditionBuilder */\nexport default interface ConditionBuilderProps extends BaseProps, NoChildrenProp {\n /** Metadata (data-model) for the Fields to use in the builder */\n fields: Field[];\n\n /** (Optional) A seed condition for the builder. To use when editing an existing condition */\n condition?: Condition;\n\n /** (Optional) Used to limit the Comparators allowed in the builder. */\n validComparators?: ComparatorsByType[];\n\n /**\n * (Optional) Pass this to control which all types of RHS are enabled in the component\n * DEFAULT: Set(['LITERAL', 'FIELD'])\n * NOTE: If enabling `DATE_FUNCTION`s, additionally pass a `dateFunctions` prop to specify which functions are enabled\n */\n validRhsTypes?: Set<RHSType>;\n\n /** (Optional) When enabling 'DATE_FUNCTION's via `validRhsTypes`, pass this to specify which all date functions are applicable per field type */\n dateFunctions?: DateFunctionsByType;\n\n /** (Optional) Pass this if the `NOT` operator should be considered as invalid */\n disallowNOT?: boolean;\n\n /** Imperative handle for the component. */\n handle?: Ref<HandleValue>;\n}\n"]}
1
+ {"version":3,"file":"ConditionBuilder.types.js","sourceRoot":"","sources":["../../../src/components/ConditionBuilder/ConditionBuilder.types.ts"],"names":[],"mappings":"","sourcesContent":["// cspell:words DDTHH\nimport type { Ref } from 'react';\n\nimport type { BaseProps, MenuItemProps, NoChildrenProp } from '@pega/cosmos-react-core';\n\nimport type {\n Comparator,\n ComparatorsByType,\n DateFunction,\n DatePart,\n FieldType,\n RHSType,\n TimePeriod\n} from './core/types';\n\n/** RHS object with a Date function */\nexport interface RhsWithDateFunction {\n /**\n * Output format for the value varies based on the dateFunction:\n * YEARS: First day of year as YYYY-MM-DD\n * QUARTERS: First day of quarter as YYYY-MM-DD\n * MONTHS: First day of month as YYYY-MM-DD\n * WEEKS: First day of week as YYYY-MM-DD\n * DAYS: Date as YYYY-MM-DD\n * HOURS: YYYY-MM-DDTHH:mm:ss\n * MINUTES: YYYY-MM-DDTHH:mm:ss\n * SECONDS: YYYY-MM-DDTHH:mm:ss\n * HOURS_OF_DAY: 0-23\n * MONTHS_OF_YEAR: 1-12\n * DAYS_OF_MONTH: 1-31\n * DAYS_OF_WEEK: 1-7\n */\n value: string | number;\n dateFunction: DateFunction;\n}\n\n/** RHS object with a Relative Date */\nexport interface RhsWithRelativeDate {\n relativeDate: {\n timePeriod: TimePeriod;\n interval?: number;\n datePart: DatePart;\n };\n}\n\n/** RHS object with PARAMETER type */\nexport interface RhsWithParameter {\n parameterId: string;\n}\n\n/** Type definition for the leaf-level nodes in nested conditions */\nexport interface LeafCondition {\n comparator: Comparator;\n\n lhs: {\n field: string;\n };\n\n // Optional for some of the comparators like IS_TRUE, IS_NULL, etc.\n rhs?:\n | { field: string } // When comparing the LHS with another field\n | { value: string | number } // When comparing the LHS with a single literal value (for comparators like EQ, GTE etc.)\n | { values: string[] | number[] } // When comparing the LHS with a list of literal values (for comparators like IN, NOT_IN etc.)\n | { start: string | number; end: string | number } // When comparing numeric or date field with two values that determine range\n | RhsWithDateFunction // When comparing a date field with a date function on RHS\n | RhsWithRelativeDate // When comparing a date field with a symbolic date on RHS\n | RhsWithParameter; // When comparing the LHS with PARAMETER type\n}\n\n/** Type definition for objects representing condition-rows in the builder UI */\nexport interface ConditionRow extends LeafCondition {\n id: string; // To use as `key` prop when rendering a list of rows\n label: string; // Used to refer the row from a logic-string\n}\n\n/**\n * Type definition for simple/complex conditions\n * At a given node in the condition tree, it can have exactly one of the keys AND/OR/NOT/condition\n */\nexport type Condition =\n | { AND: Condition[] }\n | { OR: Condition[] }\n | { NOT: Condition }\n | { condition: LeafCondition };\n\n/** Type definition for the input Field objects for the ConditionBuilder */\n\nexport type ParameterValue = Pick<MenuItemProps, 'id' | 'primary'>;\n\nexport type ReferenceValue = Pick<MenuItemProps, 'id' | 'primary'>;\n\nexport type ValueSelectionFunction<F> = (\n args:\n | { lhs?: F; ids: string[] }\n | {\n lhs?: F;\n searchString?: string; // If missing, assume empty string\n comparator?: string; // If missing, assume EQ\n\n // If the below are missing, fetch maximum possible results\n pageNumber?: number;\n pageSize?: number;\n }\n) => Promise<string[] | ReferenceValue[]>;\n\nexport type ValueSelection<F> = string[] | ReferenceValue[] | ValueSelectionFunction<F>;\n\ninterface BasicField extends Pick<MenuItemProps, 'id' | 'primary'> {}\n\nexport type Field = BasicField &\n (\n | {\n parameters?: ParameterValue[];\n\n /**\n * For TEXT fields, if a list of possible values is known ahead of time, they can be passed.\n * Otherwise we fetch data from api and pass a promise which returns list of values\n * This enables users to select from those values instead of manually typing them\n */\n possibleValues?: ValueSelection<Field>;\n\n /**\n * Data-type for the field.\n * Has to be one of these values. Convert where necessary\n * e.g. Currency/Percentage... should be used as `DECIMAL`\n * e.g. Text(single value)/Picklist/... should be used as `TEXT`\n */\n type: FieldType;\n\n /**\n * Used to handle percentages are stored in the database,\n * determine whether value is stored in the range of 0 to 1 or 0 to 100\n */\n unit?: 'percent_1' | 'percent_100';\n }\n | {\n /** An array of type Field to represent the child items. */\n items: Field[];\n }\n );\n\n/** Valid date functions by field type */\nexport interface DateFunctionsByType {\n /** Date functions to enable for DATE_TIME fields */\n DATE_TIME: DateFunction[];\n /** Date functions to enable for DATE_ONLY fields */\n DATE_ONLY: DateFunction[];\n}\n\nexport interface HandleValue {\n /**\n * Returns condition validity and condition or undefined if valid.\n * Undefined indicates no condition.\n */\n getCondition: () => [valid: false] | [valid: true, condition: Condition | undefined];\n}\n\n/** Type definition for the input props of ConditionBuilder */\nexport default interface ConditionBuilderProps extends BaseProps, NoChildrenProp {\n /** Metadata (data-model) for the Fields to use in the builder */\n fields: Field[];\n\n /** (Optional) A seed condition for the builder. To use when editing an existing condition */\n condition?: Condition;\n\n /** (Optional) Used to limit the Comparators allowed in the builder. */\n validComparators?: ComparatorsByType[];\n\n /**\n * (Optional) Pass this to control which all types of RHS are enabled in the component\n * DEFAULT: Set(['LITERAL', 'FIELD'])\n * NOTE: If enabling `DATE_FUNCTION`s, additionally pass a `dateFunctions` prop to specify which functions are enabled\n */\n validRhsTypes?: Set<RHSType>;\n\n /** (Optional) When enabling 'DATE_FUNCTION's via `validRhsTypes`, pass this to specify which all date functions are applicable per field type */\n dateFunctions?: DateFunctionsByType;\n\n /** (Optional) Pass this if the `NOT` operator should be considered as invalid */\n disallowNOT?: boolean;\n\n /** Imperative handle for the component. */\n handle?: Ref<HandleValue>;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { type FormControlProps } from '@pega/cosmos-react-core';
2
+ import type { Field, LeafCondition } from '../ConditionBuilder.types';
3
+ import type { FieldType } from '../core/types';
4
+ type CSVField = Field & {
5
+ type: FieldType;
6
+ unit?: 'percent_1' | 'percent_100';
7
+ };
8
+ export interface CSVInputProps extends FormControlProps {
9
+ /** Rhs for the condition */
10
+ rhs?: LeafCondition['rhs'];
11
+ /** Field associated with the condition */
12
+ field: CSVField;
13
+ /** Callback for any modifications to the Rhs */
14
+ onChange: (rhs: LeafCondition['rhs']) => void;
15
+ }
16
+ export declare const CSVInput: ({ rhs, field, onChange, ...restProps }: CSVInputProps) => import("react/jsx-runtime").JSX.Element;
17
+ export {};
18
+ //# sourceMappingURL=CSVInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSVInput.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/CSVInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,KAAK,QAAQ,GAAG,KAAK,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,GAAG,aAAa,CAAA;CAAE,CAAC;AAEhF,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,4BAA4B;IAC5B,GAAG,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3B,0CAA0C;IAC1C,KAAK,EAAE,QAAQ,CAAC;IAChB,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,QAAQ,GAAI,wCAAwC,aAAa,4CA6D7E,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { hasProp, Input, useAfterInitialEffect } from '@pega/cosmos-react-core';
4
+ export const CSVInput = ({ rhs, field, onChange, ...restProps }) => {
5
+ const fieldType = field.type;
6
+ const fieldUnit = field.unit;
7
+ // Set up a CSV input for IN/NOT_IN comparators
8
+ const [csvInput, setCsvInput] = useState(() => {
9
+ if (rhs && hasProp(rhs, 'values')) {
10
+ if ((fieldType === 'DECIMAL' || fieldType === 'INTEGER') && fieldUnit === 'percent_1') {
11
+ return rhs.values
12
+ .map(v => (typeof v === 'number' ? parseFloat((v * 100).toFixed(2)) : v))
13
+ .join(', ');
14
+ }
15
+ return rhs.values.join(', ');
16
+ }
17
+ return '';
18
+ });
19
+ useEffect(() => {
20
+ // If moving away from the CSV-mode, clear the CSV Input.
21
+ // This ensures that if a different `rhs.values` is passed (a new empty array can be passed when an applicable comparator is selected), the local state matches the new input.
22
+ if (csvInput && (!rhs || !hasProp(rhs, 'values'))) {
23
+ setCsvInput('');
24
+ }
25
+ }, [rhs]);
26
+ useAfterInitialEffect(() => {
27
+ if (rhs && hasProp(rhs, 'values')) {
28
+ if ((fieldType === 'DECIMAL' || fieldType === 'INTEGER') && fieldUnit === 'percent_1') {
29
+ setCsvInput(rhs.values
30
+ .map(v => (typeof v === 'number' ? parseFloat((v * 100).toFixed(2)) : v))
31
+ .join(', '));
32
+ }
33
+ else {
34
+ setCsvInput(rhs.values.join(', '));
35
+ }
36
+ }
37
+ }, [rhs]);
38
+ const handleChange = (e) => {
39
+ setCsvInput(e.target.value);
40
+ };
41
+ const handleBlur = () => {
42
+ // Submit a new RHS
43
+ let newValues = csvInput
44
+ .split(',')
45
+ .map(v => v.trim())
46
+ .filter(v => v.length > 0); // Ignore empty strings
47
+ if (fieldType === 'DECIMAL' || fieldType === 'INTEGER') {
48
+ newValues = newValues.map(v => {
49
+ if (fieldUnit === 'percent_1' && !Number.isNaN(Number(v))) {
50
+ return Number(v) / 100;
51
+ }
52
+ return Number(v);
53
+ }); // This can set up some NaN values. Those are used to show an appropriate feedback when the submit button is hit
54
+ }
55
+ onChange({ values: newValues });
56
+ };
57
+ return _jsx(Input, { ...restProps, value: csvInput, onChange: handleChange, onBlur: handleBlur });
58
+ };
59
+ //# sourceMappingURL=CSVInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSVInput.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/CSVInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState, type ChangeEvent } from 'react';\n\nimport {\n hasProp,\n Input,\n useAfterInitialEffect,\n type FormControlProps\n} from '@pega/cosmos-react-core';\n\nimport type { Field, LeafCondition } from '../ConditionBuilder.types';\nimport type { FieldType } from '../core/types';\n\ntype CSVField = Field & { type: FieldType; unit?: 'percent_1' | 'percent_100' };\n\nexport interface CSVInputProps extends FormControlProps {\n /** Rhs for the condition */\n rhs?: LeafCondition['rhs'];\n /** Field associated with the condition */\n field: CSVField;\n /** Callback for any modifications to the Rhs */\n onChange: (rhs: LeafCondition['rhs']) => void;\n}\n\nexport const CSVInput = ({ rhs, field, onChange, ...restProps }: CSVInputProps) => {\n const fieldType = field.type;\n const fieldUnit = field.unit;\n\n // Set up a CSV input for IN/NOT_IN comparators\n const [csvInput, setCsvInput] = useState(() => {\n if (rhs && hasProp(rhs, 'values')) {\n if ((fieldType === 'DECIMAL' || fieldType === 'INTEGER') && fieldUnit === 'percent_1') {\n return rhs.values\n .map(v => (typeof v === 'number' ? parseFloat((v * 100).toFixed(2)) : v))\n .join(', ');\n }\n return rhs.values.join(', ');\n }\n return '';\n });\n\n useEffect(() => {\n // If moving away from the CSV-mode, clear the CSV Input.\n // This ensures that if a different `rhs.values` is passed (a new empty array can be passed when an applicable comparator is selected), the local state matches the new input.\n if (csvInput && (!rhs || !hasProp(rhs, 'values'))) {\n setCsvInput('');\n }\n }, [rhs]);\n\n useAfterInitialEffect(() => {\n if (rhs && hasProp(rhs, 'values')) {\n if ((fieldType === 'DECIMAL' || fieldType === 'INTEGER') && fieldUnit === 'percent_1') {\n setCsvInput(\n rhs.values\n .map(v => (typeof v === 'number' ? parseFloat((v * 100).toFixed(2)) : v))\n .join(', ')\n );\n } else {\n setCsvInput(rhs.values.join(', '));\n }\n }\n }, [rhs]);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n setCsvInput(e.target.value);\n };\n\n const handleBlur = () => {\n // Submit a new RHS\n let newValues: string[] | number[] = csvInput\n .split(',')\n .map(v => v.trim())\n .filter(v => v.length > 0); // Ignore empty strings\n if (fieldType === 'DECIMAL' || fieldType === 'INTEGER') {\n newValues = newValues.map(v => {\n if (fieldUnit === 'percent_1' && !Number.isNaN(Number(v))) {\n return Number(v) / 100;\n }\n return Number(v);\n }); // This can set up some NaN values. Those are used to show an appropriate feedback when the submit button is hit\n }\n onChange({ values: newValues });\n };\n\n return <Input {...restProps} value={csvInput} onChange={handleChange} onBlur={handleBlur} />;\n};\n"]}
@@ -13,6 +13,8 @@ interface NumericInputProps extends BaseProps, NoChildrenProp {
13
13
  status?: 'error';
14
14
  /** Determines whether decimals can be entered */
15
15
  allowDecimal?: boolean;
16
+ /** Determines whether value is stored in the database in the range of 0 to 1 or 0 to 100 */
17
+ unit?: 'percent_1' | 'percent_100';
16
18
  }
17
19
  /** Wrapper over the NumberInput to parse values as Numbers, while still allowing the user to type partial values like `12.`, `12.0`, ... */
18
20
  declare const NumericInput: FunctionComponent<NumericInputProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"NumericInput.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzE,UAAU,iBAAkB,SAAQ,SAAS,EAAE,cAAc;IAC3D,4BAA4B;IAC5B,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAEhC,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAEpD,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,iDAAiD;IACjD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,4IAA4I;AAC5I,QAAA,MAAM,YAAY,EAAE,iBAAiB,CAAC,iBAAiB,CA4BtD,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"NumericInput.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzE,UAAU,iBAAkB,SAAQ,SAAS,EAAE,cAAc;IAC3D,4BAA4B;IAC5B,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAChC,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpD,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC;CACpC;AAED,4IAA4I;AAC5I,QAAA,MAAM,YAAY,EAAE,iBAAiB,CAAC,iBAAiB,CAgDtD,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -3,20 +3,36 @@ import { useState } from 'react';
3
3
  import { NumberInput, useAfterInitialEffect, useI18n } from '@pega/cosmos-react-core';
4
4
  /** Wrapper over the NumberInput to parse values as Numbers, while still allowing the user to type partial values like `12.`, `12.0`, ... */
5
5
  const NumericInput = (props) => {
6
- const { rhs, onChange, status, allowDecimal = true } = props;
6
+ const { rhs, onChange, status, allowDecimal = true, unit } = props;
7
7
  const t = useI18n();
8
+ // Formats a value as a percentage and fixes floating point rounding errors in input box
9
+ const convertPercentToDisplayValue = (value) => {
10
+ if (unit === 'percent_1' && typeof value === 'number') {
11
+ return parseFloat((value * 100).toFixed(2));
12
+ }
13
+ return value;
14
+ };
8
15
  // Since we want to always call onChange with parsed Numbers,
9
16
  // if we parse values like `12.`, `12.0`, etc., the decimals will be lost leading to bad UX
10
17
  // Using a local state to avoid that
11
- const [localValue, setLocalValue] = useState(rhs.value.toString());
18
+ const [localValue, setLocalValue] = useState(convertPercentToDisplayValue(rhs.value).toString());
12
19
  useAfterInitialEffect(() => {
13
- setLocalValue(rhs.value.toString());
20
+ setLocalValue(convertPercentToDisplayValue(rhs.value).toString());
14
21
  }, [rhs.value]);
15
22
  const handleInputChange = (newValue) => {
16
23
  setLocalValue(newValue);
17
- onChange({ value: newValue.trim() ? Number(newValue) : '' }); // Save as a number unless the input is empty
18
24
  };
19
- return (_jsx(NumberInput, { value: localValue, onChange: handleInputChange, status: status, info: status === 'error' ? t('condition_builder_invalid_number') : undefined, label: t('condition_builder_value_label'), numberOfDecimals: allowDecimal ? undefined : 0 }));
25
+ const handleBlur = (newValue) => {
26
+ let outValue = '';
27
+ if (newValue) {
28
+ const valueAsNumber = Number(newValue);
29
+ if (!Number.isNaN(valueAsNumber)) {
30
+ outValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;
31
+ }
32
+ }
33
+ onChange({ value: outValue });
34
+ };
35
+ return (_jsx(NumberInput, { value: localValue, onChange: handleInputChange, onBlur: handleBlur, status: status, info: status === 'error' ? t('condition_builder_invalid_number') : undefined, label: t('condition_builder_value_label'), numberOfDecimals: allowDecimal ? undefined : 0, unit: unit === 'percent_1' || unit === 'percent_100' ? 'percent' : undefined }));
20
36
  };
21
37
  export default NumericInput;
22
38
  //# sourceMappingURL=NumericInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NumericInput.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAiBtF,4IAA4I;AAC5I,MAAM,YAAY,GAAyC,CAAC,KAAwB,EAAE,EAAE;IACtF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC7D,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IAEpB,6DAA6D;IAC7D,2FAA2F;IAC3F,oCAAoC;IACpC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEnE,qBAAqB,CAAC,GAAG,EAAE;QACzB,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAEhB,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE;QAC7C,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxB,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,6CAA6C;IAC7G,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,WAAW,IACV,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,SAAS,EAC5E,KAAK,EAAE,CAAC,CAAC,+BAA+B,CAAC,EACzC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC9C,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import { useState } from 'react';\nimport type { FunctionComponent } from 'react';\n\nimport { NumberInput, useAfterInitialEffect, useI18n } from '@pega/cosmos-react-core';\nimport type { BaseProps, NoChildrenProp } from '@pega/cosmos-react-core';\n\ninterface NumericInputProps extends BaseProps, NoChildrenProp {\n /** Rhs for the condition */\n rhs: { value: string | number };\n\n /** Callback for any modifications to the Rhs */\n onChange: (rhs: { value: string | number }) => void;\n\n /** Used to indicate any errors on the control */\n status?: 'error';\n\n /** Determines whether decimals can be entered */\n allowDecimal?: boolean;\n}\n\n/** Wrapper over the NumberInput to parse values as Numbers, while still allowing the user to type partial values like `12.`, `12.0`, ... */\nconst NumericInput: FunctionComponent<NumericInputProps> = (props: NumericInputProps) => {\n const { rhs, onChange, status, allowDecimal = true } = props;\n const t = useI18n();\n\n // Since we want to always call onChange with parsed Numbers,\n // if we parse values like `12.`, `12.0`, etc., the decimals will be lost leading to bad UX\n // Using a local state to avoid that\n const [localValue, setLocalValue] = useState(rhs.value.toString());\n\n useAfterInitialEffect(() => {\n setLocalValue(rhs.value.toString());\n }, [rhs.value]);\n\n const handleInputChange = (newValue: string) => {\n setLocalValue(newValue);\n onChange({ value: newValue.trim() ? Number(newValue) : '' }); // Save as a number unless the input is empty\n };\n\n return (\n <NumberInput\n value={localValue}\n onChange={handleInputChange}\n status={status}\n info={status === 'error' ? t('condition_builder_invalid_number') : undefined}\n label={t('condition_builder_value_label')}\n numberOfDecimals={allowDecimal ? undefined : 0}\n />\n );\n};\n\nexport default NumericInput;\n"]}
1
+ {"version":3,"file":"NumericInput.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAgBtF,4IAA4I;AAC5I,MAAM,YAAY,GAAyC,CAAC,KAAwB,EAAE,EAAE;IACtF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACnE,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IAEpB,wFAAwF;IACxF,MAAM,4BAA4B,GAAG,CAAC,KAAsB,EAAE,EAAE;QAC9D,IAAI,IAAI,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACtD,OAAO,UAAU,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,6DAA6D;IAC7D,2FAA2F;IAC3F,oCAAoC;IACpC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEjG,qBAAqB,CAAC,GAAG,EAAE;QACzB,aAAa,CAAC,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IAEhB,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE;QAC7C,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAE,EAAE;QACtC,IAAI,QAAQ,GAAoB,EAAE,CAAC;QACnC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;gBACjC,QAAQ,GAAG,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC;YACxE,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,WAAW,IACV,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,SAAS,EAC5E,KAAK,EAAE,CAAC,CAAC,+BAA+B,CAAC,EACzC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC9C,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAC5E,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["import { useState } from 'react';\nimport type { FunctionComponent } from 'react';\n\nimport { NumberInput, useAfterInitialEffect, useI18n } from '@pega/cosmos-react-core';\nimport type { BaseProps, NoChildrenProp } from '@pega/cosmos-react-core';\n\ninterface NumericInputProps extends BaseProps, NoChildrenProp {\n /** Rhs for the condition */\n rhs: { value: string | number };\n /** Callback for any modifications to the Rhs */\n onChange: (rhs: { value: string | number }) => void;\n /** Used to indicate any errors on the control */\n status?: 'error';\n /** Determines whether decimals can be entered */\n allowDecimal?: boolean;\n /** Determines whether value is stored in the database in the range of 0 to 1 or 0 to 100 */\n unit?: 'percent_1' | 'percent_100';\n}\n\n/** Wrapper over the NumberInput to parse values as Numbers, while still allowing the user to type partial values like `12.`, `12.0`, ... */\nconst NumericInput: FunctionComponent<NumericInputProps> = (props: NumericInputProps) => {\n const { rhs, onChange, status, allowDecimal = true, unit } = props;\n const t = useI18n();\n\n // Formats a value as a percentage and fixes floating point rounding errors in input box\n const convertPercentToDisplayValue = (value: string | number) => {\n if (unit === 'percent_1' && typeof value === 'number') {\n return parseFloat((value * 100).toFixed(2));\n }\n return value;\n };\n\n // Since we want to always call onChange with parsed Numbers,\n // if we parse values like `12.`, `12.0`, etc., the decimals will be lost leading to bad UX\n // Using a local state to avoid that\n const [localValue, setLocalValue] = useState(convertPercentToDisplayValue(rhs.value).toString());\n\n useAfterInitialEffect(() => {\n setLocalValue(convertPercentToDisplayValue(rhs.value).toString());\n }, [rhs.value]);\n\n const handleInputChange = (newValue: string) => {\n setLocalValue(newValue);\n };\n\n const handleBlur = (newValue: string) => {\n let outValue: string | number = '';\n if (newValue) {\n const valueAsNumber = Number(newValue);\n if (!Number.isNaN(valueAsNumber)) {\n outValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;\n }\n }\n onChange({ value: outValue });\n };\n\n return (\n <NumberInput\n value={localValue}\n onChange={handleInputChange}\n onBlur={handleBlur}\n status={status}\n info={status === 'error' ? t('condition_builder_invalid_number') : undefined}\n label={t('condition_builder_value_label')}\n numberOfDecimals={allowDecimal ? undefined : 0}\n unit={unit === 'percent_1' || unit === 'percent_100' ? 'percent' : undefined}\n />\n );\n};\n\nexport default NumericInput;\n"]}
@@ -0,0 +1,31 @@
1
+ import type { Ref } from 'react';
2
+ import type { BaseProps, FormControlProps, NoChildrenProp } from '@pega/cosmos-react-core';
3
+ export interface NumericRangeInputProps extends BaseProps, NoChildrenProp {
4
+ /** Label for the range input. */
5
+ label: FormControlProps['label'];
6
+ /** Determines whether the label is hidden. */
7
+ labelHidden?: FormControlProps['labelHidden'];
8
+ /** Rhs for the condition. */
9
+ rhs?: {
10
+ start: string | number;
11
+ end: string | number;
12
+ };
13
+ /** Callback for any modifications to the Rhs. */
14
+ onChange: (rhs: {
15
+ start: number | undefined;
16
+ end: number | undefined;
17
+ }) => void;
18
+ /** Used to indicate any errors on the control. */
19
+ status?: 'error';
20
+ /**
21
+ * Determines whether decimals can be entered.
22
+ * @default true
23
+ */
24
+ allowDecimal?: boolean;
25
+ /** Determines whether value is stored in the database in the range of 0 to 1 or 0 to 100. */
26
+ unit?: 'percent_1' | 'percent_100';
27
+ /** Ref to the component. */
28
+ ref?: Ref<HTMLFieldSetElement>;
29
+ }
30
+ export declare const NumericRangeInput: import("react").ForwardRefExoticComponent<Omit<NumericRangeInputProps, "ref"> & import("react").RefAttributes<HTMLFieldSetElement>>;
31
+ //# sourceMappingURL=NumericRangeInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumericRangeInput.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericRangeInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE3F,MAAM,WAAW,sBAAuB,SAAQ,SAAS,EAAE,cAAc;IACvE,iCAAiC;IACjC,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACjC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAC9C,6BAA6B;IAC7B,GAAG,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvD,iDAAiD;IACjD,QAAQ,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;IAChF,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC;IACnC,4BAA4B;IAC5B,GAAG,CAAC,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,iBAAiB,qIAqE7B,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useState } from 'react';
3
+ import { NumberRangeInput, useAfterInitialEffect, useI18n } from '@pega/cosmos-react-core';
4
+ export const NumericRangeInput = forwardRef(({ rhs, onChange, status, allowDecimal = true, unit, ...props }, ref) => {
5
+ const t = useI18n();
6
+ // Formats a value as a percentage and fixes floating point rounding errors in input box
7
+ const convertPercentToDisplayValue = (value) => {
8
+ if (unit === 'percent_1') {
9
+ const num = typeof value === 'number' ? value : Number(value);
10
+ // Number value of empty string is 0, which we don't want, so we return just value instead
11
+ if (!Number.isNaN(num) && value !== '') {
12
+ return parseFloat((num * 100).toFixed(2));
13
+ }
14
+ }
15
+ return value;
16
+ };
17
+ const [internalValue, setInternalValue] = useState({
18
+ start: convertPercentToDisplayValue(rhs?.start)?.toString(),
19
+ end: convertPercentToDisplayValue(rhs?.end)?.toString()
20
+ });
21
+ useAfterInitialEffect(() => {
22
+ setInternalValue({
23
+ start: convertPercentToDisplayValue(rhs?.start)?.toString(),
24
+ end: convertPercentToDisplayValue(rhs?.end)?.toString()
25
+ });
26
+ }, [rhs?.start, rhs?.end]);
27
+ const handleChange = (newValue) => {
28
+ setInternalValue(newValue);
29
+ };
30
+ const handleBlur = (newValue) => {
31
+ let outStartValue;
32
+ let outEndValue;
33
+ if (newValue.start) {
34
+ const valueAsNumber = Number(newValue.start);
35
+ if (!Number.isNaN(valueAsNumber)) {
36
+ outStartValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;
37
+ }
38
+ }
39
+ if (newValue.end) {
40
+ const valueAsNumber = Number(newValue.end);
41
+ if (!Number.isNaN(valueAsNumber)) {
42
+ outEndValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;
43
+ }
44
+ }
45
+ onChange({
46
+ start: outStartValue,
47
+ end: outEndValue
48
+ });
49
+ };
50
+ return (_jsx(NumberRangeInput, { ...props, ref: ref, value: internalValue, onChange: handleChange, onBlur: handleBlur, status: status, info: status === 'error' ? t('condition_builder_invalid_number_range') : undefined, numberOfDecimals: allowDecimal ? undefined : 0, unit: unit === 'percent_1' || unit === 'percent_100' ? 'percent' : undefined }));
51
+ });
52
+ //# sourceMappingURL=NumericRangeInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumericRangeInput.js","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/NumericRangeInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef, useState } from 'react';\nimport type { Ref } from 'react';\n\nimport { NumberRangeInput, useAfterInitialEffect, useI18n } from '@pega/cosmos-react-core';\nimport type { BaseProps, FormControlProps, NoChildrenProp } from '@pega/cosmos-react-core';\n\nexport interface NumericRangeInputProps extends BaseProps, NoChildrenProp {\n /** Label for the range input. */\n label: FormControlProps['label'];\n /** Determines whether the label is hidden. */\n labelHidden?: FormControlProps['labelHidden'];\n /** Rhs for the condition. */\n rhs?: { start: string | number; end: string | number };\n /** Callback for any modifications to the Rhs. */\n onChange: (rhs: { start: number | undefined; end: number | undefined }) => void;\n /** Used to indicate any errors on the control. */\n status?: 'error';\n /**\n * Determines whether decimals can be entered.\n * @default true\n */\n allowDecimal?: boolean;\n /** Determines whether value is stored in the database in the range of 0 to 1 or 0 to 100. */\n unit?: 'percent_1' | 'percent_100';\n /** Ref to the component. */\n ref?: Ref<HTMLFieldSetElement>;\n}\n\nexport const NumericRangeInput = forwardRef<HTMLFieldSetElement, NumericRangeInputProps>(\n ({ rhs, onChange, status, allowDecimal = true, unit, ...props }, ref) => {\n const t = useI18n();\n // Formats a value as a percentage and fixes floating point rounding errors in input box\n const convertPercentToDisplayValue = (value: string | number | undefined) => {\n if (unit === 'percent_1') {\n const num = typeof value === 'number' ? value : Number(value);\n // Number value of empty string is 0, which we don't want, so we return just value instead\n if (!Number.isNaN(num) && value !== '') {\n return parseFloat((num * 100).toFixed(2));\n }\n }\n return value;\n };\n\n const [internalValue, setInternalValue] = useState<{\n start: string | undefined;\n end: string | undefined;\n }>({\n start: convertPercentToDisplayValue(rhs?.start)?.toString(),\n end: convertPercentToDisplayValue(rhs?.end)?.toString()\n });\n\n useAfterInitialEffect(() => {\n setInternalValue({\n start: convertPercentToDisplayValue(rhs?.start)?.toString(),\n end: convertPercentToDisplayValue(rhs?.end)?.toString()\n });\n }, [rhs?.start, rhs?.end]);\n\n const handleChange = (newValue: { start: string; end: string }) => {\n setInternalValue(newValue);\n };\n\n const handleBlur = (newValue: { start: string; end: string }) => {\n let outStartValue: number | undefined;\n let outEndValue: number | undefined;\n if (newValue.start) {\n const valueAsNumber = Number(newValue.start);\n if (!Number.isNaN(valueAsNumber)) {\n outStartValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;\n }\n }\n if (newValue.end) {\n const valueAsNumber = Number(newValue.end);\n if (!Number.isNaN(valueAsNumber)) {\n outEndValue = unit === 'percent_1' ? valueAsNumber / 100 : valueAsNumber;\n }\n }\n onChange({\n start: outStartValue,\n end: outEndValue\n });\n };\n\n return (\n <NumberRangeInput\n {...props}\n ref={ref}\n value={internalValue}\n onChange={handleChange}\n onBlur={handleBlur}\n status={status}\n info={status === 'error' ? t('condition_builder_invalid_number_range') : undefined}\n numberOfDecimals={allowDecimal ? undefined : 0}\n unit={unit === 'percent_1' || unit === 'percent_100' ? 'percent' : undefined}\n />\n );\n }\n);\n"]}
@@ -1,5 +1,5 @@
1
- import type { FunctionComponent, Ref } from 'react';
2
- import type { BaseProps, ForwardProps, HandleValue } from '@pega/cosmos-react-core';
1
+ import type { FunctionComponent } from 'react';
2
+ import type { BaseProps, ForwardProps } from '@pega/cosmos-react-core';
3
3
  import type { FieldType, Comparator, RHSType } from '../core/types';
4
4
  import type { LeafCondition, Field, DateFunctionsByType } from '../ConditionBuilder.types';
5
5
  /**
@@ -33,8 +33,6 @@ interface RhsControlProps extends BaseProps {
33
33
  validRhsTypes: Set<RHSType>;
34
34
  /** Passed to enable additional date controls on the RHS, when a DATE_TIME/DATE_ONLY field is selected on the LHS */
35
35
  dateFunctions?: DateFunctionsByType;
36
- /** Imperative handle */
37
- handle?: Ref<HandleValue>;
38
36
  }
39
37
  /** A controlled component for controls on a Condition's RHS */
40
38
  declare const RhsControls: FunctionComponent<RhsControlProps & ForwardProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAe,GAAG,EAAE,MAAM,OAAO,CAAC;AAcjE,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMpF,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAyC3F;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EACzB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EACzB,MAAM,EAAE,KAAK,EAAE,EACf,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,GAAE,OAAe,GAC1B,OAAO,CAiGT;AAED,wHAAwH;AACxH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,EAC3B,aAAa,CAAC,EAAE,mBAAmB,GAClC,aAAa,CAAC,KAAK,CAAC,CAgDtB;AAID,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAkBtF;AAED,yDAAyD;AACzD,UAAU,eAAgB,SAAQ,SAAS;IACzC,4BAA4B;IAC5B,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1B,mCAAmC;IACnC,UAAU,EAAE,UAAU,CAAC;IAEvB,4BAA4B;IAC5B,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1B,4EAA4E;IAC5E,MAAM,EAAE,KAAK,EAAE,CAAC;IAEhB,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAEhE,+DAA+D;IAC/D,cAAc,EAAE,OAAO,CAAC;IAExB,0BAA0B;IAC1B,aAAa,EAAE,KAAK,GAAG,QAAQ,CAAC;IAEhC,uDAAuD;IACvD,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAE5B,oHAAoH;IACpH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IAEpC,wBAAwB;IACxB,MAAM,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,+DAA+D;AAC/D,QAAA,MAAM,WAAW,EAAE,iBAAiB,CAAC,eAAe,GAAG,YAAY,CAoblE,CAAC;AACF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ConditionBuilder/RhsControls/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAa5D,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAMvE,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA2C3F;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EACzB,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EACzB,MAAM,EAAE,KAAK,EAAE,EACf,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,GAAE,OAAe,GAC1B,OAAO,CAwGT;AAED,wHAAwH;AACxH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,EAC3B,aAAa,CAAC,EAAE,mBAAmB,GAClC,aAAa,CAAC,KAAK,CAAC,CAgDtB;AAID,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAkBtF;AAED,yDAAyD;AACzD,UAAU,eAAgB,SAAQ,SAAS;IACzC,4BAA4B;IAC5B,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1B,mCAAmC;IACnC,UAAU,EAAE,UAAU,CAAC;IAEvB,4BAA4B;IAC5B,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAE1B,4EAA4E;IAC5E,MAAM,EAAE,KAAK,EAAE,CAAC;IAEhB,gDAAgD;IAChD,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAEhE,+DAA+D;IAC/D,cAAc,EAAE,OAAO,CAAC;IAExB,0BAA0B;IAC1B,aAAa,EAAE,KAAK,GAAG,QAAQ,CAAC;IAEhC,uDAAuD;IACvD,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAE5B,oHAAoH;IACpH,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,+DAA+D;AAC/D,QAAA,MAAM,WAAW,EAAE,iBAAiB,CAAC,eAAe,GAAG,YAAY,CAkalE,CAAC;AACF,eAAe,WAAW,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect, useMemo } from 'react';
3
- import { DateInput, DateTimeInput, Flex, Input, hasProp, TimeInput, useI18n, DateRangeInput, TimeRangeInput, NumberRangeInput } from '@pega/cosmos-react-core';
2
+ import { useState, useMemo } from 'react';
3
+ import { DateInput, DateTimeInput, Flex, Input, hasProp, TimeInput, useI18n, DateRangeInput, TimeRangeInput } from '@pega/cosmos-react-core';
4
4
  import { convertTimeValueToMs } from '../core/time-utils';
5
5
  import { getItem } from '../core/utils';
6
6
  import ValueSelector from './ValueSelector';
@@ -9,6 +9,8 @@ import RhsModeSwitch from './RhsModeSwitch';
9
9
  import TimePeriodInput from './TimePeriodInput';
10
10
  import TimePeriodMenu from './TimePeriodMenu';
11
11
  import NumericInput from './NumericInput';
12
+ import { NumericRangeInput } from './NumericRangeInput';
13
+ import { CSVInput } from './CSVInput';
12
14
  function isValidLiteralValue(value, fieldType, trimValues = false) {
13
15
  // Identify any invalid numbers (e.g. when `-` is entered)
14
16
  if (typeof value === 'number') {
@@ -102,6 +104,11 @@ export function isValidRhs(rhs, lhs, fields, fieldType, trimValues = false) {
102
104
  !isValidLiteralValue(rhs.end, fieldType, trimValues)) {
103
105
  return false;
104
106
  }
107
+ if (fieldType === 'DECIMAL' || fieldType === 'INTEGER') {
108
+ return (!Number.isNaN(Number(rhs.start)) &&
109
+ !Number.isNaN(Number(rhs.end)) &&
110
+ Number(rhs.start) < Number(rhs.end));
111
+ }
105
112
  if (fieldType === 'TIME_ONLY') {
106
113
  if (typeof rhs.start === 'number' && typeof rhs.end === 'number')
107
114
  return rhs.start < rhs.end;
@@ -175,7 +182,7 @@ export function truncateISODateString(dateString, fieldType) {
175
182
  }
176
183
  /** A controlled component for controls on a Condition's RHS */
177
184
  const RhsControls = (props) => {
178
- const { lhs, comparator, rhs, fields, onChange, indicateErrors, itemDirection, validRhsTypes, dateFunctions, handle } = props;
185
+ const { lhs, comparator, rhs, fields, onChange, indicateErrors, itemDirection, validRhsTypes, dateFunctions } = props;
179
186
  const t = useI18n();
180
187
  const [apiError, setApiError] = useState(null);
181
188
  // Find the field corresponding to the LHS
@@ -203,15 +210,6 @@ const RhsControls = (props) => {
203
210
  };
204
211
  return findMatchingObjectType(fields, matchingField.type);
205
212
  }, [fields, lhs]);
206
- // Set up a CSV input for IN/NOT_IN comparators
207
- const [csvInput, setCsvInput] = useState(rhs && hasProp(rhs, 'values') ? rhs.values.join(', ') : '');
208
- useEffect(() => {
209
- // If moving away from the CSV-mode, clear the CSV Input.
210
- // This ensures that if a different `rhs.values` is passed (a new empty array can be passed when an applicable comparator is selected), the local state matches the new input.
211
- if (csvInput && (!rhs || !hasProp(rhs, 'values'))) {
212
- setCsvInput('');
213
- }
214
- }, [rhs]);
215
213
  // If a field is not selected or if the comparator doesn't need any RHS, don't render anything
216
214
  if (rhs === undefined) {
217
215
  return _jsx("div", {}); // Rendering a placeholder div to keep the layout consistent
@@ -222,6 +220,7 @@ const RhsControls = (props) => {
222
220
  return _jsx("div", {}); // Rendering a placeholder div to keep the layout consistent
223
221
  }
224
222
  const fieldType = matchingField.type;
223
+ const fieldUnit = matchingField.unit;
225
224
  const parameters = matchingField.parameters !== undefined ? matchingField.parameters : [];
226
225
  // If errors should be indicated inline, validate the current rhs
227
226
  let showError = false;
@@ -298,32 +297,20 @@ const RhsControls = (props) => {
298
297
  onChange(onChangeParam);
299
298
  };
300
299
  const handleNumberRangeValueChange = ({ start, end }) => {
301
- const startValue = start.trim();
302
- const endValue = end.trim();
300
+ const startValue = start;
301
+ const endValue = end;
302
+ const hasStartValue = startValue !== undefined;
303
+ const hasEndValue = endValue !== undefined;
303
304
  onChange({
304
- start: startValue ? Number(start) : '',
305
- end: endValue ? Number(end) : ''
305
+ start: hasStartValue ? Number(start) : '',
306
+ end: hasEndValue ? Number(end) : ''
306
307
  },
307
308
  // checking one of values is empty, but not both
308
- ((!startValue || !endValue) && (startValue || endValue)) ||
309
- (startValue && endValue && startValue > endValue)
309
+ ((!hasStartValue || !hasEndValue) && (hasStartValue || hasEndValue)) ||
310
+ (hasStartValue && hasEndValue && startValue > endValue)
310
311
  ? 'error'
311
312
  : undefined);
312
313
  };
313
- // Handle changes from a CSV-input
314
- const handleCSVChange = (e) => {
315
- // Update the controlled input
316
- setCsvInput(e.target.value);
317
- // Submit a new RHS
318
- let newValues = e.target.value
319
- .split(',')
320
- .map(v => v.trim())
321
- .filter(v => v.length > 0); // Ignore empty strings
322
- if (fieldType === 'DECIMAL' || fieldType === 'INTEGER') {
323
- newValues = newValues.map(v => Number(v)); // This can set up some NaN values. Those are used to show an appropriate feedback when the submit button is hit
324
- }
325
- onChange({ values: newValues });
326
- };
327
314
  // Render the menu directly if in a vertical layout
328
315
  const TimePeriodComp = itemDirection === 'column' ? TimePeriodMenu : TimePeriodInput;
329
316
  const alignItems = showError ? 'center' : 'end';
@@ -332,8 +319,8 @@ const RhsControls = (props) => {
332
319
  alignItems: itemDirection === 'column' ? 'stretch' : alignItems,
333
320
  justify: 'between',
334
321
  gap: 0.5
335
- }, children: [_jsx(RhsModeSwitch, { parameters: parameters, fieldType: fieldType, comparator: comparator, rhs: rhs, onChange: onChange, mode: itemDirection === 'column' ? 'combo-box' : 'menu-button', validRhsTypes: validRhsTypes, dateFunctions: dateFunctions }), hasProp(rhs, 'field') && (_jsx(Flex, { item: { grow: 1 }, children: _jsx(FieldSelector, { value: rhs.field, onChange: handleFieldChange, fields: fieldOptions, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : undefined, label: t('condition_builder_compare_with_another_field') }) })), hasProp(rhs, 'parameterId') && (_jsxs(Flex, { item: { grow: 1 }, children: [parameters.length === 1 && (_jsx(Input, { value: parameters[0].primary.toString(), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_empty_value_text') : undefined, name: 'rhs-text-parameter-input', label: t('condition_builder_value_label'), readOnly: true })), parameters.length > 1 && (_jsx(ValueSelector, { parameters: parameters, mode: 'single-select', values: rhs.parameterId.toString(), selectedField: matchingField, rhs: rhs, comparator: comparator, onChange: handleValueSelection, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_empty_selection_error_text') : undefined, label: t('condition_builder_value_label'), placeholder: t('condition_builder_single_selection_placeholder') }))] })), hasProp(rhs, 'value') && !hasProp(rhs, 'dateFunction') && (_jsxs(Flex, { item: { grow: 1 }, children: [fieldType === 'TEXT' && useValueSelector && (_jsx(ValueSelector, { parameters: parameters, mode: 'single-select', values: rhs.value.toString(), selectedField: matchingField, comparator: comparator, rhs: rhs, onChange: handleValueSelection, status: showError || apiError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : apiError, setApiError: setApiError, label: t('condition_builder_value_label'), placeholder: t('condition_builder_single_selection_placeholder') })), fieldType === 'TEXT' && !useValueSelector && (_jsx(Input, { value: rhs.value.toString(), onChange: handleValueChange, status: showError ? 'error' : undefined, info: showError ? t('empty_value') : undefined, name: 'rhs-text-literal-input', label: t('condition_builder_value_label') })), (fieldType === 'DECIMAL' || fieldType === 'INTEGER') && (_jsx(NumericInput, { rhs: rhs, onChange: onChange, allowDecimal: fieldType !== 'INTEGER', status: showError ? 'error' : undefined })), fieldType === 'TIME_ONLY' && (_jsx(TimeInput, { value: rhs.value === '' ? undefined : rhs.value, withSeconds: true, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_time') : '', label: t('condition_builder_value_label') })), fieldType === 'DATE_ONLY' && (_jsx(DateInput, { value: rhs.value, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date') : '', label: t('condition_builder_value_label') })), fieldType === 'DATE_TIME' && (_jsx(DateTimeInput, { value: rhs.value !== '' ? rhs.value : undefined, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date') : '', label: t('condition_builder_value_label') }))] })), (fieldType === 'DATE_ONLY' || fieldType === 'DATE_TIME') &&
336
- (hasProp(rhs, 'relativeDate') || hasProp(rhs, 'dateFunction')) && (_jsx(Flex, { item: { grow: 1 }, children: _jsx(TimePeriodComp, { rhs: rhs, fieldType: fieldType, onChange: onChange, dateFunctionsList: dateFunctions ? dateFunctions[fieldType] : [], status: showError ? 'error' : undefined }) })), hasProp(rhs, 'values') && (_jsxs(Flex, { item: { grow: 1 }, children: [useValueSelector && (_jsx(ValueSelector, { parameters: parameters, mode: 'multi-select', values: rhs.values.map(String), selectedField: matchingField, comparator: comparator, rhs: rhs, onChange: handleValueSelection, status: showError || apiError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : apiError, setApiError: setApiError, label: t('condition_builder_value_label'), placeholder: t('condition_builder_multi_selection_placeholder') })), !useValueSelector && (_jsx(Input, { value: csvInput, onChange: handleCSVChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_values') : undefined, label: t('condition_builder_value_label'), placeholder: t('condition_builder_enter_csv_placeholder') }))] })), hasProp(rhs, 'start') && (_jsxs(Flex, { item: { grow: 1 }, children: [(fieldType === 'DECIMAL' || fieldType === 'INTEGER') && (_jsx(NumberRangeInput, { value: { start: rhs.start.toString(), end: rhs.end.toString() }, onChange: handleNumberRangeValueChange, status: showError ? 'error' : undefined, label: t('condition_builder_value_label'), info: showError ? t('condition_builder_invalid_number_range') : undefined, handle: handle, numberOfDecimals: fieldType === 'INTEGER' ? 0 : undefined })), fieldType === 'DATE_ONLY' && (_jsx(DateRangeInput, { value: { start: rhs.start, end: rhs.end }, onChange: handleDateRangeValueChange, label: t('condition_builder_value_label'), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date_range') : '' })), fieldType === 'TIME_ONLY' && (_jsx(TimeRangeInput, { mode: 'time', value: {
322
+ }, children: [_jsx(RhsModeSwitch, { parameters: parameters, fieldType: fieldType, comparator: comparator, rhs: rhs, onChange: onChange, mode: itemDirection === 'column' ? 'combo-box' : 'menu-button', validRhsTypes: validRhsTypes, dateFunctions: dateFunctions }), hasProp(rhs, 'field') && (_jsx(Flex, { item: { grow: 1 }, children: _jsx(FieldSelector, { value: rhs.field, onChange: handleFieldChange, fields: fieldOptions, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : undefined, label: t('condition_builder_compare_with_another_field') }) })), hasProp(rhs, 'parameterId') && (_jsxs(Flex, { item: { grow: 1 }, children: [parameters.length === 1 && (_jsx(Input, { value: parameters[0].primary.toString(), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_empty_value_text') : undefined, name: 'rhs-text-parameter-input', label: t('condition_builder_value_label'), readOnly: true })), parameters.length > 1 && (_jsx(ValueSelector, { parameters: parameters, mode: 'single-select', values: rhs.parameterId.toString(), selectedField: matchingField, rhs: rhs, comparator: comparator, onChange: handleValueSelection, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_empty_selection_error_text') : undefined, label: t('condition_builder_value_label'), placeholder: t('condition_builder_single_selection_placeholder') }))] })), hasProp(rhs, 'value') && !hasProp(rhs, 'dateFunction') && (_jsxs(Flex, { item: { grow: 1 }, children: [fieldType === 'TEXT' && useValueSelector && (_jsx(ValueSelector, { parameters: parameters, mode: 'single-select', values: rhs.value.toString(), selectedField: matchingField, comparator: comparator, rhs: rhs, onChange: handleValueSelection, status: showError || apiError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : apiError, setApiError: setApiError, label: t('condition_builder_value_label'), placeholder: t('condition_builder_single_selection_placeholder') })), fieldType === 'TEXT' && !useValueSelector && (_jsx(Input, { value: rhs.value.toString(), onChange: handleValueChange, status: showError ? 'error' : undefined, info: showError ? t('empty_value') : undefined, name: 'rhs-text-literal-input', label: t('condition_builder_value_label') })), (fieldType === 'DECIMAL' || fieldType === 'INTEGER') && (_jsx(NumericInput, { rhs: rhs, onChange: onChange, allowDecimal: fieldType !== 'INTEGER', status: showError ? 'error' : undefined, unit: fieldUnit })), fieldType === 'TIME_ONLY' && (_jsx(TimeInput, { value: rhs.value === '' ? undefined : rhs.value, withSeconds: true, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_time') : '', label: t('condition_builder_value_label') })), fieldType === 'DATE_ONLY' && (_jsx(DateInput, { value: rhs.value, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date') : '', label: t('condition_builder_value_label') })), fieldType === 'DATE_TIME' && (_jsx(DateTimeInput, { value: rhs.value !== '' ? rhs.value : undefined, onChange: handleDateValueChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date') : '', label: t('condition_builder_value_label') }))] })), (fieldType === 'DATE_ONLY' || fieldType === 'DATE_TIME') &&
323
+ (hasProp(rhs, 'relativeDate') || hasProp(rhs, 'dateFunction')) && (_jsx(Flex, { item: { grow: 1 }, children: _jsx(TimePeriodComp, { rhs: rhs, fieldType: fieldType, onChange: onChange, dateFunctionsList: dateFunctions ? dateFunctions[fieldType] : [], status: showError ? 'error' : undefined }) })), hasProp(rhs, 'values') && (_jsxs(Flex, { item: { grow: 1 }, children: [useValueSelector && (_jsx(ValueSelector, { parameters: parameters, mode: 'multi-select', values: rhs.values.map(String), selectedField: matchingField, comparator: comparator, rhs: rhs, onChange: handleValueSelection, status: showError || apiError ? 'error' : undefined, info: showError ? t('condition_builder_no_selection') : apiError, setApiError: setApiError, label: t('condition_builder_value_label'), placeholder: t('condition_builder_multi_selection_placeholder') })), !useValueSelector && (_jsx(CSVInput, { rhs: rhs, field: matchingField, onChange: onChange, status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_values') : undefined, label: t('condition_builder_value_label'), placeholder: t('condition_builder_enter_csv_placeholder') }))] })), hasProp(rhs, 'start') && (_jsxs(Flex, { item: { grow: 1 }, children: [(fieldType === 'DECIMAL' || fieldType === 'INTEGER') && (_jsx(NumericRangeInput, { label: t('condition_builder_value_label'), rhs: { start: rhs.start.toString(), end: rhs.end.toString() }, onChange: handleNumberRangeValueChange, status: showError ? 'error' : undefined, allowDecimal: fieldType !== 'INTEGER', unit: fieldUnit })), fieldType === 'DATE_ONLY' && (_jsx(DateRangeInput, { value: { start: rhs.start, end: rhs.end }, onChange: handleDateRangeValueChange, label: t('condition_builder_value_label'), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date_range') : '' })), fieldType === 'TIME_ONLY' && (_jsx(TimeRangeInput, { mode: 'time', value: {
337
324
  start: rhs.start === '' ? undefined : rhs.start,
338
325
  end: rhs.end === '' ? undefined : rhs.end
339
326
  }, withSeconds: true, onChange: handleDateRangeValueChange, label: t('condition_builder_value_label'), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_time_range') : '' })), fieldType === 'DATE_TIME' && (_jsx(TimeRangeInput, { mode: 'datetime', value: { start: rhs.start, end: rhs.end }, onChange: handleDateRangeValueChange, label: t('condition_builder_value_label'), status: showError ? 'error' : undefined, info: showError ? t('condition_builder_invalid_date_range') : '' }))] }))] }));