Summary: Project doc: https://docs.google.com/document/d/1miofxds9DJgWScj0zFyBbdpRH5Rj0T9FqiCapof5-vU Reviewed By: lblasa Differential Revision: D48644510 fbshipit-source-id: 0a1a382f3052c0e1e1f78ad6e8c51211fb78f9ce
180 lines
4.7 KiB
TypeScript
180 lines
4.7 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
import {CloseOutlined} from '@ant-design/icons';
|
|
import {Button, Space} from 'antd';
|
|
import dayjs from 'dayjs';
|
|
import * as React from 'react';
|
|
import {
|
|
DATE_ONLY_FORMAT,
|
|
DATE_TIME_FORMAT,
|
|
PowerSearchAbsoluteDateTerm,
|
|
} from './PowerSearchAbsoluteDateTerm';
|
|
import {FieldConfig, OperatorConfig} from './PowerSearchConfig';
|
|
import {PowerSearchEnumTerm} from './PowerSearchEnumTerm';
|
|
import {PowerSearchFloatTerm} from './PowerSearchFloatTerm';
|
|
import {PowerSearchIntegerTerm} from './PowerSearchIntegerTerm';
|
|
import {PowerSearchStringTerm} from './PowerSearchStringTerm';
|
|
|
|
export type IncompleteSearchExpressionTerm = {
|
|
field: FieldConfig;
|
|
operator: OperatorConfig;
|
|
searchValue?: any;
|
|
};
|
|
export type SearchExpressionTerm = Required<IncompleteSearchExpressionTerm>;
|
|
|
|
type PowerSearchTermProps = {
|
|
searchTerm: IncompleteSearchExpressionTerm;
|
|
searchValueRenderer: 'input' | 'button';
|
|
onCancel: () => void;
|
|
onFinalize: (completeSearchTerm: SearchExpressionTerm) => void;
|
|
};
|
|
|
|
export const PowerSearchTerm: React.FC<PowerSearchTermProps> = ({
|
|
searchTerm,
|
|
searchValueRenderer,
|
|
onCancel,
|
|
onFinalize,
|
|
}) => {
|
|
let searchValueComponent: React.ReactNode = null;
|
|
if (searchValueRenderer === 'input') {
|
|
switch (searchTerm.operator.valueType) {
|
|
case 'STRING': {
|
|
searchValueComponent = (
|
|
<PowerSearchStringTerm
|
|
onCancel={onCancel}
|
|
onChange={(newValue) => {
|
|
onFinalize({
|
|
...searchTerm,
|
|
searchValue: newValue,
|
|
});
|
|
}}
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
case 'INTEGER': {
|
|
searchValueComponent = (
|
|
<PowerSearchIntegerTerm
|
|
onCancel={onCancel}
|
|
onChange={(newValue) => {
|
|
onFinalize({
|
|
...searchTerm,
|
|
searchValue: newValue,
|
|
});
|
|
}}
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
case 'FLOAT': {
|
|
searchValueComponent = (
|
|
<PowerSearchFloatTerm
|
|
onCancel={onCancel}
|
|
onChange={(newValue) => {
|
|
onFinalize({
|
|
...searchTerm,
|
|
searchValue: newValue,
|
|
});
|
|
}}
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
case 'NO_VALUE': {
|
|
// Nothing needs to be done. It should never be the case.
|
|
searchValueComponent = null;
|
|
break;
|
|
}
|
|
case 'ENUM': {
|
|
searchValueComponent = (
|
|
<PowerSearchEnumTerm
|
|
onCancel={onCancel}
|
|
onChange={(newValue) => {
|
|
onFinalize({
|
|
...searchTerm,
|
|
searchValue: newValue,
|
|
});
|
|
}}
|
|
enumLabels={searchTerm.operator.enumLabels}
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
case 'ABSOLUTE_DATE': {
|
|
searchValueComponent = (
|
|
<PowerSearchAbsoluteDateTerm
|
|
onCancel={onCancel}
|
|
onChange={(newValue) => {
|
|
onFinalize({
|
|
...searchTerm,
|
|
searchValue: newValue,
|
|
});
|
|
}}
|
|
minValue={searchTerm.operator.minValue}
|
|
maxValue={searchTerm.operator.maxValue}
|
|
dateOnly={searchTerm.operator.dateOnly}
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
default: {
|
|
console.error(
|
|
'PowerSearchTerm -> unknown operator.valueType',
|
|
searchTerm,
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
switch (searchTerm.operator.valueType) {
|
|
case 'ENUM': {
|
|
searchValueComponent = (
|
|
<Button>
|
|
{searchTerm.operator.enumLabels[searchTerm.searchValue]}
|
|
</Button>
|
|
);
|
|
break;
|
|
}
|
|
case 'ABSOLUTE_DATE': {
|
|
searchValueComponent = (
|
|
<Button>
|
|
{searchTerm.operator.dateOnly
|
|
? dayjs(searchTerm.searchValue).format(DATE_ONLY_FORMAT)
|
|
: dayjs(searchTerm.searchValue).format(DATE_TIME_FORMAT)}
|
|
</Button>
|
|
);
|
|
break;
|
|
}
|
|
case 'NO_VALUE': {
|
|
searchValueComponent = null;
|
|
break;
|
|
}
|
|
default: {
|
|
searchValueComponent = <Button>{searchTerm.searchValue}</Button>;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Space.Compact block size="small">
|
|
<Button>{searchTerm.field.label}</Button>
|
|
{searchTerm.operator.label ? (
|
|
<Button>{searchTerm.operator.label}</Button>
|
|
) : null}
|
|
{searchValueComponent}
|
|
<Button
|
|
icon={<CloseOutlined />}
|
|
onClick={() => {
|
|
onCancel();
|
|
}}
|
|
/>
|
|
</Space.Compact>
|
|
);
|
|
};
|