Extract PowerSearchTerm
Summary: Project doc: https://docs.google.com/document/d/1miofxds9DJgWScj0zFyBbdpRH5Rj0T9FqiCapof5-vU Reviewed By: lblasa Differential Revision: D48599166 fbshipit-source-id: 13b447b55408a8673928489312c4d22cf864c232
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2c5bcb373d
commit
c9ab951e84
@@ -7,7 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {OperatorConfig, PowerSearchConfig} from './PowerSearchTypes';
|
import {OperatorConfig, PowerSearchConfig} from './PowerSearchConfig';
|
||||||
|
|
||||||
const MyStatusEnum = {
|
const MyStatusEnum = {
|
||||||
NEEDS_REVIEW: 'Needs review',
|
NEEDS_REVIEW: 'Needs review',
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* 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, Input, Space} from 'antd';
|
||||||
|
import * as React from 'react';
|
||||||
|
import {FieldConfig, OperatorConfig} from './PowerSearchConfig';
|
||||||
|
|
||||||
|
export type SearchExpressionTerm = {
|
||||||
|
field: FieldConfig;
|
||||||
|
operator: OperatorConfig;
|
||||||
|
searchValue?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PowerSearchTermProps = {
|
||||||
|
searchTerm: SearchExpressionTerm;
|
||||||
|
searchValueRenderer: 'input' | 'button';
|
||||||
|
onCancel: () => void;
|
||||||
|
onFinalize: (completeSearchTerm: Required<SearchExpressionTerm>) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PowerSearchTerm: React.FC<PowerSearchTermProps> = ({
|
||||||
|
searchTerm,
|
||||||
|
searchValueRenderer,
|
||||||
|
onCancel,
|
||||||
|
onFinalize,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Space.Compact block size="small">
|
||||||
|
<Button>{searchTerm.field.label}</Button>
|
||||||
|
<Button>{searchTerm.operator.label}</Button>
|
||||||
|
{searchValueRenderer === 'button' ? (
|
||||||
|
<Button>{searchTerm.searchValue ?? '...'}</Button>
|
||||||
|
) : (
|
||||||
|
// TODO: Fix width
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
style={{width: 100}}
|
||||||
|
placeholder="..."
|
||||||
|
onBlur={(event) => {
|
||||||
|
const newValue = event.target.value;
|
||||||
|
|
||||||
|
if (!newValue) {
|
||||||
|
onCancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFinalize({
|
||||||
|
...searchTerm,
|
||||||
|
searchValue: newValue,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === 'Enter' || event.key === 'Escape') {
|
||||||
|
event.currentTarget.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
icon={<CloseOutlined />}
|
||||||
|
onClick={() => {
|
||||||
|
onCancel();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Space.Compact>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -8,14 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {AutoComplete, Button, Input, Space} from 'antd';
|
import {AutoComplete, Space} from 'antd';
|
||||||
import {
|
import {PowerSearchConfig} from './PowerSearchConfig';
|
||||||
PowerSearchConfig,
|
|
||||||
FieldConfig,
|
|
||||||
OperatorConfig,
|
|
||||||
} from './PowerSearchTypes';
|
|
||||||
import {CloseOutlined} from '@ant-design/icons';
|
|
||||||
import {PowerSearchContainer} from './PowerSearchContainer';
|
import {PowerSearchContainer} from './PowerSearchContainer';
|
||||||
|
import {PowerSearchTerm, SearchExpressionTerm} from './PowerSearchTerm';
|
||||||
|
|
||||||
export {PowerSearchConfig};
|
export {PowerSearchConfig};
|
||||||
|
|
||||||
@@ -32,12 +28,6 @@ type AutocompleteOptionGroup = {
|
|||||||
|
|
||||||
const OPTION_KEY_DELIMITER = '::';
|
const OPTION_KEY_DELIMITER = '::';
|
||||||
|
|
||||||
type SearchExpressionTerm = {
|
|
||||||
field: FieldConfig;
|
|
||||||
operator: OperatorConfig;
|
|
||||||
searchValue?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
||||||
const [searchExpression, setSearchExpression] = React.useState<
|
const [searchExpression, setSearchExpression] = React.useState<
|
||||||
SearchExpressionTerm[]
|
SearchExpressionTerm[]
|
||||||
@@ -88,50 +78,13 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
const isLastTerm = i === searchExpression.length - 1;
|
const isLastTerm = i === searchExpression.length - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space.Compact block size="small" key={i.toString()}>
|
<PowerSearchTerm
|
||||||
<Button>{searchTerm.field.label}</Button>
|
key={i.toString()}
|
||||||
<Button>{searchTerm.operator.label}</Button>
|
searchTerm={searchTerm}
|
||||||
{lastSearchTermHasSearchValue || !isLastTerm ? (
|
searchValueRenderer={
|
||||||
<Button>{searchTerm.searchValue ?? '...'}</Button>
|
lastSearchTermHasSearchValue || !isLastTerm ? 'button' : 'input'
|
||||||
) : (
|
|
||||||
// TODO: Fix width
|
|
||||||
<Input
|
|
||||||
autoFocus
|
|
||||||
style={{width: 100}}
|
|
||||||
placeholder="..."
|
|
||||||
onBlur={(event) => {
|
|
||||||
const newValue = event.target.value;
|
|
||||||
|
|
||||||
if (!newValue) {
|
|
||||||
setSearchExpression((prevSearchExpression) => {
|
|
||||||
return prevSearchExpression.slice(0, -1);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
onCancel={() => {
|
||||||
setSearchExpression((prevSearchExpression) => {
|
|
||||||
return [
|
|
||||||
...prevSearchExpression.slice(0, -1),
|
|
||||||
{
|
|
||||||
...prevSearchExpression[
|
|
||||||
prevSearchExpression.length - 1
|
|
||||||
],
|
|
||||||
searchValue: newValue,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
searchTermFinderRef.current?.focus();
|
|
||||||
}}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (event.key === 'Enter' || event.key === 'Escape') {
|
|
||||||
event.currentTarget.blur();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Button
|
|
||||||
icon={<CloseOutlined />}
|
|
||||||
onClick={() => {
|
|
||||||
setSearchExpression((prevSearchExpression) => {
|
setSearchExpression((prevSearchExpression) => {
|
||||||
if (prevSearchExpression[i]) {
|
if (prevSearchExpression[i]) {
|
||||||
return [
|
return [
|
||||||
@@ -142,8 +95,16 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
return prevSearchExpression;
|
return prevSearchExpression;
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
onFinalize={(finalSearchTerm) => {
|
||||||
|
setSearchExpression((prevSearchExpression) => {
|
||||||
|
return [
|
||||||
|
...prevSearchExpression.slice(0, -1),
|
||||||
|
finalSearchTerm,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
searchTermFinderRef.current?.focus();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Space.Compact>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Space>
|
</Space>
|
||||||
|
|||||||
Reference in New Issue
Block a user