feat(dashboard): implement boolean conditional formatting (#36338)

Co-authored-by: Morris <morrisho215215@gmail.com>
This commit is contained in:
Edison Liem
2025-12-04 12:53:49 -05:00
committed by GitHub
parent e5da6d3183
commit eabb5bdf7d
9 changed files with 372 additions and 21 deletions

View File

@@ -40,6 +40,11 @@ const columnsStringType = [
{ label: 'Column 2', value: 'column2', dataType: GenericDataType.String },
];
const columnsBooleanType = [
{ label: 'Column 1', value: 'column1', dataType: GenericDataType.Boolean },
{ label: 'Column 2', value: 'column2', dataType: GenericDataType.Boolean },
];
const extraColorChoices = [
{
value: ColorSchemeEnum.Green,
@@ -148,6 +153,22 @@ test('displays the correct input fields based on the selected string type operat
expect(await screen.findByLabelText('Target value')).toBeInTheDocument();
});
test('does not display the input fields when selected a boolean type operator', async () => {
render(
<FormattingPopoverContent
onChange={mockOnChange}
columns={columnsBooleanType}
extraColorChoices={extraColorChoices}
/>,
);
fireEvent.change(screen.getAllByLabelText('Operator')[0], {
target: { value: Comparator.IsTrue },
});
fireEvent.click(await screen.findByTitle('is true'));
expect(await screen.queryByLabelText('Target value')).toBeNull();
});
test('displays the toAllRow and toTextColor flags based on the selected numeric type operator', () => {
render(
<FormattingPopoverContent

View File

@@ -91,6 +91,13 @@ const stringOperatorOptions = [
{ value: Comparator.NotContaining, label: t('not containing') },
];
const booleanOperatorOptions = [
{ value: Comparator.IsNull, label: t('is null') },
{ value: Comparator.IsTrue, label: t('is true') },
{ value: Comparator.IsFalse, label: t('is false') },
{ value: Comparator.IsNotNull, label: t('is not null') },
];
const targetValueValidator =
(
compare: (targetValue: number, compareValue: number) => boolean,
@@ -157,10 +164,17 @@ const renderOperator = ({
showOnlyNone,
columnType,
}: { showOnlyNone?: boolean; columnType?: GenericDataType } = {}) => {
const options =
columnType === GenericDataType.String
? stringOperatorOptions
: operatorOptions;
let options;
switch (columnType) {
case GenericDataType.String:
options = stringOperatorOptions;
break;
case GenericDataType.Boolean:
options = booleanOperatorOptions;
break;
default:
options = operatorOptions;
}
return (
<FormItem
@@ -182,9 +196,26 @@ const renderOperatorFields = (
columnType?: GenericDataType,
) => {
const columnTypeString = columnType === GenericDataType.String;
const operatorColSpan = columnTypeString ? 8 : 6;
const columnTypeBoolean = columnType === GenericDataType.Boolean;
const operatorColSpan = columnTypeString || columnTypeBoolean ? 8 : 6;
const valueColSpan = columnTypeString ? 16 : 18;
if (columnTypeBoolean) {
return (
<Row gutter={12}>
<Col span={operatorColSpan}>{renderOperator({ columnType })}</Col>
<Col span={valueColSpan}>
<FormItem
name="targetValue"
label={t('Target value')}
initialValue={''}
hidden
/>
</Col>
</Row>
);
}
return isOperatorNone(getFieldValue('operator')) ? (
<Row gutter={12}>
<Col span={operatorColSpan}>{renderOperator({ columnType })}</Col>
@@ -304,10 +335,20 @@ export const FormattingPopoverContent = ({
const handleColumnChange = (value: string) => {
const newColumnType = columns.find(item => item.value === value)?.dataType;
if (newColumnType !== previousColumnType) {
const defaultOperator =
newColumnType === GenericDataType.String
? stringOperatorOptions[0].value
: operatorOptions[0].value;
let defaultOperator: Comparator;
switch (newColumnType) {
case GenericDataType.String:
defaultOperator = stringOperatorOptions[0].value;
break;
case GenericDataType.Boolean:
defaultOperator = booleanOperatorOptions[0].value;
break;
default:
defaultOperator = operatorOptions[0].value;
}
form.setFieldsValue({
operator: defaultOperator,