Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('AddFilter', () => {
await userEvent.click(screen.getByText('Errors'));

// Should see filter key options for the dataset
expect(screen.getByText('Select Filter Tag')).toBeInTheDocument();
expect(screen.getByText('Select Errors Tag')).toBeInTheDocument();
expect(screen.getByText(mockFilterKeys['browser.name']!.key)).toBeInTheDocument();
expect(screen.getByText(mockFilterKeys.environment!.key)).toBeInTheDocument();

Expand Down
15 changes: 14 additions & 1 deletion static/app/views/dashboards/globalFilter/addFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,14 @@ function AddFilter({globalFilters, getSearchBarData, onAddFilter}: AddFilterProp
size="md"
menuWidth="300px"
menuTitle={
isSelectingFilterKey ? t('Select Filter Tag') : t('Select Filter Dataset')
<MenuTitleWrapper>
{isSelectingFilterKey
? t(
'Select %s Tag',
selectedDataset ? getDatasetLabel(selectedDataset) : 'Filter'
)
: t('Select Filter Dataset')}
</MenuTitleWrapper>
}
menuFooter={isSelectingFilterKey && filterOptionsMenuFooter}
trigger={triggerProps => (
Expand All @@ -204,3 +211,9 @@ const FooterWrap = styled('div')`
margin-top: ${space(1)};
}
`;

const MenuTitleWrapper = styled('span')`
display: inline-block;
padding-top: ${space(0.5)};
padding-bottom: ${space(0.5)};
`;
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('FilterSelector', () => {
/>
);

const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ':'});
const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ' :'});
await userEvent.click(button);

expect(screen.getByText('chrome')).toBeInTheDocument();
Expand All @@ -53,7 +53,7 @@ describe('FilterSelector', () => {
/>
);

const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ':'});
const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ' :'});
await userEvent.click(button);

await userEvent.click(screen.getByRole('checkbox', {name: 'Select firefox'}));
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('FilterSelector', () => {
/>
);

const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ':'});
const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ' :'});
await userEvent.click(button);

expect(screen.getByRole('checkbox', {name: 'Select firefox'})).toBeChecked();
Expand All @@ -101,7 +101,7 @@ describe('FilterSelector', () => {
/>
);

const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ':'});
const button = screen.getByRole('button', {name: mockGlobalFilter.tag.key + ' :'});
await userEvent.click(button);
await userEvent.click(screen.getByRole('button', {name: 'Remove Filter'}));

Expand Down
23 changes: 18 additions & 5 deletions static/app/views/dashboards/globalFilter/filterSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {MutableSearch} from 'sentry/components/searchSyntax/mutableSearch';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {keepPreviousData, useQuery} from 'sentry/utils/queryClient';
import {middleEllipsis} from 'sentry/utils/string/middleEllipsis';
import {useDebouncedValue} from 'sentry/utils/useDebouncedValue';
import usePageFilters from 'sentry/utils/usePageFilters';
import {type SearchBarData} from 'sentry/views/dashboards/datasetConfig/base';
Expand Down Expand Up @@ -124,7 +125,10 @@ function FilterSelector({
const optionMap = new Map<string, SelectOption<string>>();
const fixedOptionMap = new Map<string, SelectOption<string>>();
const addOption = (value: string, map: Map<string, SelectOption<string>>) =>
map.set(value, {label: value, value});
map.set(value, {
label: middleEllipsis(value, 70, /[\s-_:]/),
value,
});

// Filter values in the global filter
activeFilterValues.forEach(value => addOption(value, optionMap));
Expand Down Expand Up @@ -180,7 +184,7 @@ function FilterSelector({
};

const renderMenuHeaderTrailingItems = ({closeOverlay}: any) => (
<Flex gap="md">
<Flex gap="lg">
{activeFilterValues.length > 0 && (
<StyledButton
aria-label={t('Clear Selections')}
Expand Down Expand Up @@ -228,7 +232,9 @@ function FilterSelector({
onClose={() => {
setStagedFilterValues([]);
}}
menuTitle={t('%s Filter', getDatasetLabel(dataset))}
menuTitle={
<MenuTitleWrapper>{t('%s Filter', getDatasetLabel(dataset))}</MenuTitleWrapper>
}
menuHeaderTrailingItems={renderMenuHeaderTrailingItems}
triggerProps={{
children: renderFilterSelectorTrigger(),
Expand All @@ -252,7 +258,6 @@ function FilterSelector({
setStagedFilterValues(value);
}}
sizeLimit={30}
maxMenuWidth={500}
onClose={() => {
setSearchQuery('');
setStagedFilterValues([]);
Expand All @@ -261,7 +266,9 @@ function FilterSelector({
emptyMessage={
isFetching ? t('Loading filter values...') : t('No filter values found')
}
menuTitle={t('%s Filter', getDatasetLabel(dataset))}
menuTitle={
<MenuTitleWrapper>{t('%s Filter', getDatasetLabel(dataset))}</MenuTitleWrapper>
}
menuHeaderTrailingItems={renderMenuHeaderTrailingItems}
triggerProps={{
children: renderFilterSelectorTrigger(),
Expand All @@ -282,3 +289,9 @@ const StyledButton = styled(Button)`
? `-${space(0.5)} -${space(0.5)}`
: `-${space(0.25)} -${space(0.25)}`};
`;

const MenuTitleWrapper = styled('span')`
display: inline-block;
padding-top: ${space(0.5)};
padding-bottom: ${space(0.5)};
`;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import styled from '@emotion/styled';

import {Flex} from '@sentry/scraps/layout';

import {Badge} from 'sentry/components/core/badge';
import type {SelectOption} from 'sentry/components/core/compactSelect/types';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import TextOverflow from 'sentry/components/textOverflow';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import {prettifyTagKey} from 'sentry/utils/fields';
Expand Down Expand Up @@ -33,16 +34,23 @@ function FilterSelectorTrigger({
const isAllSelected =
activeFilterValues.length === 0 || activeFilterValues.length === options.length;

const tagKey = prettifyTagKey(tag.key);
const filterValue = activeFilterValues[0] ?? '';
const separator = <FilterValueSeparator>{':'}</FilterValueSeparator>;

return (
<ButtonLabelWrapper>
<TextOverflow>
{prettifyTagKey(tag.key)}:{' '}
{!isFetching && (
<span style={{fontWeight: 'normal'}}>
{isAllSelected ? t('All') : activeFilterValues[0]}
</span>
)}
</TextOverflow>
<FilterValueTruncated>{tagKey}</FilterValueTruncated>
{separator}
{!isFetching && (
<span style={{fontWeight: 'normal'}}>
{isAllSelected ? (
t('All')
) : (
<FilterValueTruncated>{filterValue}</FilterValueTruncated>
)}
</span>
)}
{isFetching && <StyledLoadingIndicator size={14} />}
{shouldShowBadge && (
<StyledBadge type="default">{`+${activeFilterValues.length - 1}`}</StyledBadge>
Expand Down Expand Up @@ -70,11 +78,16 @@ const StyledBadge = styled(Badge)`
padding: 0 ${space(0.5)};
`;

const ButtonLabelWrapper = styled('span')`
width: 100%;
text-align: left;
const ButtonLabelWrapper = styled(Flex)`
align-items: center;
display: inline-grid;
grid-template-columns: 1fr auto;
line-height: 1;
`;

const FilterValueSeparator = styled('span')`
margin-right: ${space(0.5)};
`;

const FilterValueTruncated = styled('div')`
${p => p.theme.overflowEllipsis};
max-width: 300px;
width: min-content;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function useNativeOperatorFilter(

const renderInputField = () => {
return (
<Input
<StyledInput
aria-label="Filter value"
value={stagedFilterValue}
onChange={e => {
Expand Down Expand Up @@ -287,7 +287,11 @@ function NumericFilterSelector({
filter.resetValues();
setStagedIsNativeOperator(isNativeOperator);
}}
menuTitle={t('%s Filter', getDatasetLabel(globalFilter.dataset))}
menuTitle={
<MenuTitleWrapper>
{t('%s Filter', getDatasetLabel(globalFilter.dataset))}
</MenuTitleWrapper>
}
menuHeaderTrailingItems={() => (
<StyledButton
aria-label={t('Remove Filter')}
Expand Down Expand Up @@ -350,7 +354,7 @@ function NumericFilterSelector({
export default NumericFilterSelector;

const MenuBodyWrap = styled('div')`
margin: 4px;
padding: 10px;
`;

const FooterWrap = styled('div')`
Expand Down Expand Up @@ -391,3 +395,13 @@ const StyledButton = styled(Button)`
? `-${space(0.5)} -${space(0.5)}`
: `-${space(0.25)} -${space(0.25)}`};
`;

const StyledInput = styled(Input)`
text-align: center;
`;

const MenuTitleWrapper = styled('span')`
display: inline-block;
padding-top: ${space(0.5)};
padding-bottom: ${space(0.5)};
`;
Loading