From 5403ac0751f8e56fa33c76d5eb0929610d46488b Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Tue, 10 Jun 2025 13:41:07 +0200 Subject: [PATCH] add utils, fix some imports --- .../ConstraintItemHeader.tsx | 2 +- .../ConstraintOperatorSelect.tsx | 2 +- .../ConstraintOperatorSelect.tsx | 2 +- frontend/src/utils/createEmptyConstraint.ts | 25 ++++++++++ .../src/utils/formatOperatorDescription.ts | 47 +++++++++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 frontend/src/utils/createEmptyConstraint.ts create mode 100644 frontend/src/utils/formatOperatorDescription.ts diff --git a/frontend/src/component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader.tsx b/frontend/src/component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader.tsx index 2605f895c9..74e3ebdfae 100644 --- a/frontend/src/component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader.tsx +++ b/frontend/src/component/common/ConstraintsList/ConstraintItemHeader/ConstraintItemHeader.tsx @@ -1,7 +1,6 @@ import type { ComponentProps, FC, ReactNode } from 'react'; import { StrategyEvaluationItem } from '../StrategyEvaluationItem/StrategyEvaluationItem.tsx'; import type { ConstraintSchema } from 'openapi'; -import { formatOperatorDescription } from 'component/common/LegacyConstraintAccordion/ConstraintOperator/formatOperatorDescription'; import { StrategyEvaluationChip } from '../StrategyEvaluationChip/StrategyEvaluationChip.tsx'; import { styled, Tooltip } from '@mui/material'; import { Truncator } from 'component/common/Truncator/Truncator'; @@ -11,6 +10,7 @@ import { formatConstraintValue } from 'utils/formatConstraintValue'; import { useConstraintTooltips } from './hooks/useConstraintTooltips.ts'; import { ReactComponent as CaseSensitiveIcon } from 'assets/icons/case-sensitive.svg'; import { isCaseSensitive } from './isCaseSensitive.ts'; +import { formatOperatorDescription } from 'utils/formatOperatorDescription.ts'; const Operator: FC<{ label: ConstraintSchema['operator']; diff --git a/frontend/src/component/common/NewConstraintAccordion/ConstraintOperatorSelect.tsx b/frontend/src/component/common/NewConstraintAccordion/ConstraintOperatorSelect.tsx index e82aad96d9..6a40bf5f84 100644 --- a/frontend/src/component/common/NewConstraintAccordion/ConstraintOperatorSelect.tsx +++ b/frontend/src/component/common/NewConstraintAccordion/ConstraintOperatorSelect.tsx @@ -15,7 +15,7 @@ import { inOperators, } from 'constants/operators'; import { useState } from 'react'; -import { formatOperatorDescription } from 'component/common/LegacyConstraintAccordion/ConstraintOperator/formatOperatorDescription'; +import { formatOperatorDescription } from 'utils/formatOperatorDescription'; interface IConstraintOperatorSelectProps { options: Operator[]; diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/ConstraintOperatorSelect.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/ConstraintOperatorSelect.tsx index 3f54d319ed..2e04924886 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/ConstraintOperatorSelect.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/ConstraintOperatorSelect.tsx @@ -14,10 +14,10 @@ import { numOperators, inOperators, } from 'constants/operators'; -import { formatOperatorDescription } from 'component/common/LegacyConstraintAccordion/ConstraintOperator/formatOperatorDescription'; import { useId } from 'react'; import { ScreenReaderOnly } from 'component/common/ScreenReaderOnly/ScreenReaderOnly'; import KeyboardArrowDownOutlined from '@mui/icons-material/KeyboardArrowDownOutlined'; +import { formatOperatorDescription } from 'utils/formatOperatorDescription'; interface IConstraintOperatorSelectProps { options: Operator[]; diff --git a/frontend/src/utils/createEmptyConstraint.ts b/frontend/src/utils/createEmptyConstraint.ts new file mode 100644 index 0000000000..9e930ae74f --- /dev/null +++ b/frontend/src/utils/createEmptyConstraint.ts @@ -0,0 +1,25 @@ +import { dateOperators } from 'constants/operators'; +import type { IConstraint } from 'interfaces/strategy'; +import { oneOf } from 'utils/oneOf'; +import { operatorsForContext } from 'utils/operatorsForContext'; +import { v4 as uuidv4 } from 'uuid'; + +export const constraintId = Symbol('id'); + +export const createEmptyConstraint = (contextName: string): IConstraint => { + const operator = operatorsForContext(contextName)[0]; + + const value = oneOf(dateOperators, operator) + ? new Date().toISOString() + : ''; + + return { + contextName, + operator, + value, + values: [], + caseInsensitive: false, + inverted: false, + [constraintId]: uuidv4(), + }; +}; diff --git a/frontend/src/utils/formatOperatorDescription.ts b/frontend/src/utils/formatOperatorDescription.ts new file mode 100644 index 0000000000..5e01186ad6 --- /dev/null +++ b/frontend/src/utils/formatOperatorDescription.ts @@ -0,0 +1,47 @@ +import type { Operator } from 'constants/operators'; + +export const formatOperatorDescription = ( + operator: Operator, + inverted?: boolean, +): string => { + if (inverted) { + return invertedConstraintOperatorDescriptions[operator]; + } + return constraintOperatorDescriptions[operator]; +}; + +const constraintOperatorDescriptions = { + IN: 'is one of', + NOT_IN: 'is not one of', + STR_CONTAINS: 'is a string that contains', + STR_STARTS_WITH: 'is a string that starts with', + STR_ENDS_WITH: 'is a string that ends with', + NUM_EQ: 'is a number equal to', + NUM_GT: 'is a number greater than', + NUM_GTE: 'is a number greater than or equal to', + NUM_LT: 'is a number less than', + NUM_LTE: 'is a number less than or equal to', + DATE_BEFORE: 'is a date before', + DATE_AFTER: 'is a date after', + SEMVER_EQ: 'is a SemVer equal to', + SEMVER_GT: 'is a SemVer greater than', + SEMVER_LT: 'is a SemVer less than', +}; + +const invertedConstraintOperatorDescriptions = { + IN: 'is not one of', + NOT_IN: 'is one of', + STR_CONTAINS: 'is a string that does not contain', + STR_STARTS_WITH: 'is a string that does not start with', + STR_ENDS_WITH: 'is a string that does not end with', + NUM_EQ: 'is a number not equal to', + NUM_GT: 'is a number not greater than', + NUM_GTE: 'is a number less than', + NUM_LT: 'is a number not less than', + NUM_LTE: 'is a number greater than', + DATE_BEFORE: 'is a date not before', + DATE_AFTER: 'is a date not after', + SEMVER_EQ: 'is a SemVer not equal to', + SEMVER_GT: 'is a SemVer not greater than', + SEMVER_LT: 'is a SemVer not less than', +};