feat: popover is added in the trace tag search (#2118)

* feat: popover is updated

* chore: arrow is removed and padding is removed

* chore: width is updated
This commit is contained in:
Palash Gupta 2023-01-25 18:56:15 +05:30 committed by GitHub
parent d7a65ba689
commit f766435acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 132 deletions

View File

@ -16,7 +16,6 @@ import {
Container, Container,
CurrentTagsContainer, CurrentTagsContainer,
ErrorContainer, ErrorContainer,
Wrapper,
} from './styles'; } from './styles';
import Tags from './Tag'; import Tags from './Tag';
@ -90,33 +89,30 @@ function AllTags({
return ( return (
<Container> <Container>
<Wrapper> <Typography>Tags</Typography>
<Typography>Tags</Typography>
<CurrentTagsContainer> <CurrentTagsContainer>
{localSelectedTags.map((tags, index) => ( {localSelectedTags.map((tags, index) => (
<Tags <Tags
key={tags.Key.join(',')} key={tags.Key.join(',')}
tag={tags} tag={tags}
index={index} index={index}
onCloseHandler={(): void => onCloseHandler(index)} onCloseHandler={(): void => onCloseHandler(index)}
setLocalSelectedTags={setLocalSelectedTags} setLocalSelectedTags={setLocalSelectedTags}
localSelectedTags={localSelectedTags} localSelectedTags={localSelectedTags}
/> />
))} ))}
</CurrentTagsContainer> </CurrentTagsContainer>
<Space wrap direction="horizontal"> <Space wrap direction="horizontal">
<Button type="primary" onClick={onTagAddHandler} icon={<PlusOutlined />}> <Button type="primary" onClick={onTagAddHandler} icon={<PlusOutlined />}>
Add Tags Filter Add Tags Filter
</Button> </Button>
<Text ellipsis> <Text ellipsis>
Results will include spans with ALL the specified tags ( Rows are `ANDed` Results will include spans with ALL the specified tags ( Rows are `ANDed` )
) </Text>
</Text> </Space>
</Space>
</Wrapper>
<ButtonContainer> <ButtonContainer>
<Space align="start"> <Space align="start">

View File

@ -2,25 +2,15 @@ import { Card } from 'antd';
import styled from 'styled-components'; import styled from 'styled-components';
export const Container = styled(Card)` export const Container = styled(Card)`
top: 120%;
min-height: 20vh; min-height: 20vh;
width: 100%; width: 100%;
z-index: 2; min-width: 81.5vw;
position: absolute !important;
.ant-card-body {
padding-bottom: 0;
padding-right: 0;
padding-left: 0;
}
`; `;
export const ErrorContainer = styled(Card)` export const ErrorContainer = styled(Card)`
top: 120%;
min-height: 20vh; min-height: 20vh;
width: 100%; width: 100%;
z-index: 2; z-index: 2;
position: absolute;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -28,13 +18,6 @@ export const ErrorContainer = styled(Card)`
flex-direction: column; flex-direction: column;
`; `;
export const Wrapper = styled.div`
&&& {
padding-right: 2rem;
padding-left: 2rem;
}
`;
export const ButtonContainer = styled(Card)` export const ButtonContainer = styled(Card)`
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@ -45,6 +28,10 @@ export const ButtonContainer = styled(Card)`
padding-right: 38.01px !important; padding-right: 38.01px !important;
margin-top: 1rem !important; margin-top: 1rem !important;
.ant-card-body {
padding: 0;
}
`; `;
export const CurrentTagsContainer = styled.div` export const CurrentTagsContainer = styled.div`

View File

@ -0,0 +1 @@
export const contentStyle = { padding: 0 };

View File

@ -1,5 +1,5 @@
import { CaretRightFilled } from '@ant-design/icons'; import { CaretRightFilled } from '@ant-design/icons';
import useClickOutside from 'hooks/useClickOutside'; import { Popover } from 'antd';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { connect, useDispatch, useSelector } from 'react-redux'; import { connect, useDispatch, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';
@ -13,6 +13,7 @@ import { UPDATE_ALL_FILTERS } from 'types/actions/trace';
import { TraceReducer } from 'types/reducer/trace'; import { TraceReducer } from 'types/reducer/trace';
import Tags from './AllTags'; import Tags from './AllTags';
import { contentStyle } from './config';
import { Container, SearchComponent } from './styles'; import { Container, SearchComponent } from './styles';
import { parseQueryToTags, parseTagsToQuery } from './util'; import { parseQueryToTags, parseTagsToQuery } from './util';
@ -42,33 +43,6 @@ function Search({
const tagRef = useRef<HTMLDivElement>(null); const tagRef = useRef<HTMLDivElement>(null);
useClickOutside(tagRef, (e: HTMLElement) => {
// using this hack as overlay span is voilating this condition
if (
e.nodeName === 'svg' ||
e.nodeName === 'path' ||
e.nodeName === 'span' ||
e.nodeName === 'button'
) {
return;
}
if (
e.nodeName === 'DIV' &&
![
'ant-select-item-option-content',
'ant-empty-image',
'ant-select-item',
'ant-col',
'ant-select-item-option-active',
].find((p) => p.indexOf(e.className) !== -1) &&
!(e.ariaSelected === 'true') &&
traces.isTagModalOpen
) {
updateTagVisibility(false);
}
});
const onChangeHandler = (search: string): void => { const onChangeHandler = (search: string): void => {
setValue(search); setValue(search);
}; };
@ -77,11 +51,6 @@ function Search({
updateTagVisibility(value); updateTagVisibility(value);
}; };
const onFocusHandler: React.FocusEventHandler<HTMLInputElement> = (e) => {
e.preventDefault();
setIsTagsModalHandler(true);
};
const updateFilters = async ( const updateFilters = async (
selectedTags: TraceReducer['selectedTags'], selectedTags: TraceReducer['selectedTags'],
): Promise<void> => { ): Promise<void> => {
@ -116,37 +85,45 @@ function Search({
return ( return (
<Container ref={tagRef}> <Container ref={tagRef}>
<SearchComponent <Popover
onChange={(event): void => onChangeHandler(event.target.value)} placement="bottomLeft"
value={value} destroyTooltipOnHide
allowClear open={traces.isTagModalOpen}
disabled={traces.filterLoading} trigger="click"
onFocus={onFocusHandler} onOpenChange={setIsTagsModalHandler}
placeholder="Click to filter by tags" showArrow={false}
type="search" overlayInnerStyle={contentStyle}
enterButton={<CaretRightFilled />} content={
onSearch={(string): void => { <Tags updateFilters={updateFilters} onChangeHandler={onChangeHandler} />
if (string.length === 0) { }
updateTagVisibility(false); >
updateFilters([]); <SearchComponent
return; onChange={(event): void => onChangeHandler(event.target.value)}
} value={value}
allowClear
disabled={traces.filterLoading}
placeholder="Click to filter by tags"
type="search"
enterButton={<CaretRightFilled />}
onSearch={(string): void => {
if (string.length === 0) {
updateTagVisibility(false);
updateFilters([]);
return;
}
const { isError, payload } = parseQueryToTags(string); const { isError, payload } = parseQueryToTags(string);
if (isError) { if (isError) {
updateTagIsError(true); updateTagIsError(true);
} else { } else {
updateTagIsError(false); updateTagIsError(false);
updateTagVisibility(false); updateTagVisibility(false);
updateFilters(payload); updateFilters(payload);
} }
}} }}
/> />
</Popover>
{traces.isTagModalOpen && (
<Tags updateFilters={updateFilters} onChangeHandler={onChangeHandler} />
)}
</Container> </Container>
); );
} }

View File

@ -1,27 +0,0 @@
import React, { useCallback, useEffect } from 'react';
const useClickOutside = (
ref: React.RefObject<HTMLElement>,
callback: (e: HTMLElement) => void | null,
): void => {
const listener = useCallback(
(e: Event) => {
const node = e?.target as HTMLElement;
if (ref.current && !ref.current.contains(node) && callback) {
callback(node);
}
},
[callback, ref],
);
useEffect(() => {
document.addEventListener('click', listener);
return (): void => {
document.removeEventListener('click', listener);
};
}, [ref, callback, listener]);
};
export default useClickOutside;