feat: add the options menu (#2832)

Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
dnazarenkosignoz 2023-06-08 12:20:39 +03:00 committed by GitHub
parent e5bb125a55
commit 7415de4751
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,11 @@
{
"options_menu": {
"options": "Options",
"format": "Format",
"row": "Row",
"default": "Default",
"column": "Column",
"maxLines": "Max lines per Row",
"addColumn": "Add a column"
}
}

View File

@ -0,0 +1,11 @@
{
"options_menu": {
"options": "Options",
"format": "Format",
"row": "Row",
"default": "Default",
"column": "Column",
"maxLines": "Max lines per Row",
"addColumn": "Add a column"
}
}

View File

@ -0,0 +1,43 @@
import { SearchOutlined } from '@ant-design/icons';
import { Input } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useTranslation } from 'react-i18next';
import { OptionsMenuConfig } from '..';
import { FieldTitle } from '../styles';
import { AddColumnSelect, AddColumnWrapper, SearchIconWrapper } from './styles';
function AddColumnField({ config }: AddColumnFieldProps): JSX.Element | null {
const { t } = useTranslation(['trace']);
const isDarkMode = useIsDarkMode();
if (!config) return null;
return (
<AddColumnWrapper direction="vertical">
<FieldTitle>{t('options_menu.addColumn')}</FieldTitle>
<Input.Group compact>
<AddColumnSelect
allowClear
maxTagCount={0}
size="small"
mode="multiple"
placeholder="Search"
options={config.options}
value={config.value}
onChange={config.onChange}
/>
<SearchIconWrapper $isDarkMode={isDarkMode}>
<SearchOutlined />
</SearchIconWrapper>
</Input.Group>
</AddColumnWrapper>
);
}
interface AddColumnFieldProps {
config: OptionsMenuConfig['addColumn'];
}
export default AddColumnField;

View File

@ -0,0 +1,28 @@
import { Card, Select, SelectProps, Space } from 'antd';
import { themeColors } from 'constants/theme';
import { FunctionComponent } from 'react';
import styled from 'styled-components';
export const SearchIconWrapper = styled(Card)<{ $isDarkMode: boolean }>`
width: 15%;
border-color: ${({ $isDarkMode }): string =>
$isDarkMode ? themeColors.borderDarkGrey : themeColors.borderLightGrey};
.ant-card-body {
display: flex;
justify-content: center;
align-items: center;
padding: 0.25rem;
font-size: 0.875rem;
}
`;
export const AddColumnSelect: FunctionComponent<SelectProps> = styled(
Select,
)<SelectProps>`
width: 85%;
`;
export const AddColumnWrapper = styled(Space)`
width: 100%;
`;

View File

@ -0,0 +1,33 @@
import { useTranslation } from 'react-i18next';
import { OptionsMenuConfig } from '..';
import { FieldTitle } from '../styles';
import { FormatFieldWrapper, RadioButton, RadioGroup } from './styles';
function FormatField({ config }: FormatFieldProps): JSX.Element | null {
const { t } = useTranslation(['trace']);
if (!config) return null;
return (
<FormatFieldWrapper direction="vertical">
<FieldTitle>{t('options_menu.format')}</FieldTitle>
<RadioGroup
size="small"
buttonStyle="solid"
value={config.value}
onChange={config.onChange}
>
<RadioButton value="row">{t('options_menu.row')}</RadioButton>
<RadioButton value="default">{t('options_menu.default')}</RadioButton>
<RadioButton value="column">{t('options_menu.column')}</RadioButton>
</RadioGroup>
</FormatFieldWrapper>
);
}
interface FormatFieldProps {
config: OptionsMenuConfig['format'];
}
export default FormatField;

View File

@ -0,0 +1,17 @@
import { Radio, Space } from 'antd';
import styled from 'styled-components';
export const FormatFieldWrapper = styled(Space)`
width: 100%;
margin-bottom: 1.125rem;
`;
export const RadioGroup = styled(Radio.Group)`
display: flex;
text-align: center;
`;
export const RadioButton = styled(Radio.Button)`
font-size: 0.75rem;
flex: 1;
`;

View File

@ -0,0 +1,29 @@
import { useTranslation } from 'react-i18next';
import { OptionsMenuConfig } from '..';
import { FieldTitle } from '../styles';
import { MaxLinesFieldWrapper, MaxLinesInput } from './styles';
function MaxLinesField({ config }: MaxLinesFieldProps): JSX.Element | null {
const { t } = useTranslation(['trace']);
if (!config) return null;
return (
<MaxLinesFieldWrapper>
<FieldTitle>{t('options_menu.maxLines')}</FieldTitle>
<MaxLinesInput
controls
size="small"
value={config.value}
onChange={config.onChange}
/>
</MaxLinesFieldWrapper>
);
}
interface MaxLinesFieldProps {
config: OptionsMenuConfig['maxLines'];
}
export default MaxLinesField;

View File

@ -0,0 +1,12 @@
import { InputNumber } from 'antd';
import styled from 'styled-components';
export const MaxLinesFieldWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;
export const MaxLinesInput = styled(InputNumber)`
max-width: 46px;
`;

View File

@ -0,0 +1,57 @@
import { SettingFilled, SettingOutlined } from '@ant-design/icons';
import {
InputNumberProps,
Popover,
RadioProps,
SelectProps,
Space,
} from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import AddColumnField from './AddColumnField';
import FormatField from './FormatField';
import MaxLinesField from './MaxLinesField';
import { OptionsContainer, OptionsContentWrapper } from './styles';
function OptionsMenu({ config }: OptionsMenuProps): JSX.Element {
const { t } = useTranslation(['trace']);
const isDarkMode = useIsDarkMode();
const OptionsContent = useMemo(
() => (
<OptionsContentWrapper direction="vertical">
{config?.format && <FormatField config={config.format} />}
{config?.maxLines && <MaxLinesField config={config.maxLines} />}
{config?.addColumn && <AddColumnField config={config.addColumn} />}
</OptionsContentWrapper>
),
[config],
);
const SettingIcon = isDarkMode ? SettingOutlined : SettingFilled;
return (
<OptionsContainer>
<Popover placement="bottom" trigger="click" content={OptionsContent}>
<Space align="center">
{t('options_menu.options')}
<SettingIcon />
</Space>
</Popover>
</OptionsContainer>
);
}
export type OptionsMenuConfig = {
format?: Pick<RadioProps, 'value' | 'onChange'>;
maxLines?: Pick<InputNumberProps, 'value' | 'onChange'>;
addColumn?: Pick<SelectProps, 'options' | 'value' | 'onChange'>;
};
interface OptionsMenuProps {
config: OptionsMenuConfig;
}
export default OptionsMenu;

View File

@ -0,0 +1,19 @@
import { Card, Space, Typography } from 'antd';
import styled from 'styled-components';
export const OptionsContainer = styled(Card)`
.ant-card-body {
display: flex;
padding: 0.25rem 0.938rem;
cursor: pointer;
}
`;
export const OptionsContentWrapper = styled(Space)`
min-width: 11rem;
padding: 0.25rem 0.5rem;
`;
export const FieldTitle = styled(Typography.Text)`
font-size: 0.75rem;
`;