libs/designer-ui/src/lib/unitTesting/assertionsPanel/assertionField.tsx (169 lines of code) (raw):
import constants from '../../constants';
import type { GetConditionExpressionHandler } from './assertion';
import type { ILabelStyles, IStyle, ITextFieldStyles } from '@fluentui/react';
import { Label, TextField } from '@fluentui/react';
import { type AssertionDefinition, isEmptyString, isNullOrUndefined } from '@microsoft/logic-apps-shared';
import { MediumText } from '../../text';
import { useIntl } from 'react-intl';
export const labelStyles: Partial<ILabelStyles> = {
root: {
display: 'inline-block',
minWidth: '120px',
verticalAlign: 'top',
padding: '5px 0px',
},
};
const fieldStyles: IStyle = {
display: 'inline-block',
flexGrow: 1,
flexShrink: 1,
flexBasis: 'auto',
};
const textFieldStyles: Partial<ITextFieldStyles> = {
root: fieldStyles,
};
const DESCRIPTION_KEY = 'description';
const NAME_KEY = 'name';
const EXPRESSION_KEY = 'expression';
export interface ParameterFieldDetails {
description: string;
name: string;
expressionKey: string;
expression: string;
}
export interface AssertionFieldProps {
id: string;
assertion: AssertionDefinition;
isExpanded: boolean;
getConditionExpression: GetConditionExpressionHandler;
handleUpdate: (newAssertion: AssertionDefinition) => void;
validationErrors?: Record<string, string | undefined>;
}
export const AssertionField = ({
id,
assertion,
isExpanded,
getConditionExpression,
handleUpdate,
validationErrors,
}: AssertionFieldProps): JSX.Element => {
const intl = useIntl();
const parameterDetails: ParameterFieldDetails = {
description: `${assertion.name}-${DESCRIPTION_KEY}`,
name: `${assertion.name}-${NAME_KEY}`,
expressionKey: `${id}-${EXPRESSION_KEY}`,
expression: `${assertion.name}-${EXPRESSION_KEY}`,
};
const nameTitle = intl.formatMessage({
defaultMessage: 'Assertion name',
id: 'LdBN0m',
description: 'Assertion field name title',
});
const descriptionTitle = intl.formatMessage({
defaultMessage: 'Description',
id: 's4omwa',
description: 'Assertion field description title',
});
const conditionTitle = intl.formatMessage({
defaultMessage: 'Condition expression',
id: 'ujp53j',
description: 'Assertion field condition title',
});
const noDescription = intl.formatMessage({
defaultMessage: 'No description',
id: 'kSXjTx',
description: 'Assertion field no description text',
});
const namePlaceholder = intl.formatMessage({
defaultMessage: 'Enter name',
id: 'PhBS5+',
description: 'Assertion field name placeholder',
});
const descriptionPlaceholder = intl.formatMessage({
defaultMessage: 'Enter description',
id: 'hW7oe7',
description: 'Assertion field description placeholder',
});
const onDescriptionChange = (_event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string): void => {
handleUpdate({ ...assertion, description: newValue ?? '' });
};
const onNameChange = (_event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string): void => {
handleUpdate({ ...assertion, name: newValue ?? '' });
};
const conditionExpression = getConditionExpression(
parameterDetails.expressionKey,
parameterDetails.expression,
assertion.id,
assertion.assertionString,
constants.SWAGGER.TYPE.ANY,
!assertion.isEditable
);
return (
<>
<div className="msla-assertion-field">
{isExpanded ? (
<Label styles={labelStyles} required={true} htmlFor={parameterDetails.name}>
{nameTitle}
</Label>
) : null}
{isExpanded ? (
<TextField
data-testid={parameterDetails.name}
styles={textFieldStyles}
id={parameterDetails.name}
ariaLabel={nameTitle}
placeholder={namePlaceholder}
errorMessage={validationErrors && validationErrors[NAME_KEY]}
value={assertion.name}
onChange={onNameChange}
disabled={!assertion.isEditable}
/>
) : null}
</div>
<div className="msla-assertion-field">
{isExpanded ? (
<Label styles={labelStyles} htmlFor={parameterDetails.description}>
{descriptionTitle}
</Label>
) : null}
{isExpanded ? (
<TextField
data-testid={parameterDetails.description}
styles={textFieldStyles}
id={parameterDetails.description}
ariaLabel={descriptionTitle}
placeholder={descriptionPlaceholder}
value={assertion.description}
onChange={onDescriptionChange}
disabled={!assertion.isEditable}
multiline
autoAdjustHeight
/>
) : isEmptyString(assertion.description) ? (
<MediumText text={noDescription} className="msla-assertion-field-read-only assertion-field-no-content" />
) : (
<MediumText text={assertion.description} className="msla-assertion-field-read-only" />
)}
</div>
<div className="msla-assertion-condition">
{isExpanded ? (
<Label styles={labelStyles} required={true} htmlFor={parameterDetails.expression}>
{conditionTitle}
</Label>
) : null}
<div className="msla-assertion-condition-editor">
{isExpanded ? (
<>
{conditionExpression}
{!isNullOrUndefined(validationErrors) && validationErrors[EXPRESSION_KEY] && (
<span className="msla-input-parameter-error" role="alert">
{validationErrors[EXPRESSION_KEY]}
</span>
)}
</>
) : null}
</div>
</div>
</>
);
};