Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
@@ -0,0 +1,26 @@
import styled from '@emotion/styled';

import {SimpleTable} from 'sentry/components/tables/simpleTable';
import {t} from 'sentry/locale';

export function CustomFilters() {
return (
<CustomFiltersTable>
<SimpleTable.Header>
<SimpleTable.HeaderCell divider={false}>{t('Active')}</SimpleTable.HeaderCell>
<SimpleTable.HeaderCell divider={false}>{t('Name')}</SimpleTable.HeaderCell>
<SimpleTable.HeaderCell divider={false}>{t('Conditions')}</SimpleTable.HeaderCell>
<SimpleTable.HeaderCell divider={false}>{t('Created')}</SimpleTable.HeaderCell>
<SimpleTable.HeaderCell divider={false}>{t('Edited')}</SimpleTable.HeaderCell>
<SimpleTable.HeaderCell divider={false}>{t('Action')}</SimpleTable.HeaderCell>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be Actions?

</SimpleTable.Header>
<SimpleTable.Empty>{t('No inbound filters found')}</SimpleTable.Empty>
</CustomFiltersTable>
);
}

const CustomFiltersTable = styled(SimpleTable)`
grid-template-columns:
max-content minmax(0, 1fr) minmax(0, 2fr) max-content max-content
max-content;
`;
40 changes: 40 additions & 0 deletions static/app/views/settings/project/projectFilters/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,46 @@ describe('ProjectFilters', () => {
);
});

it('shows inbound filters v2 tab between data filters and discarded issues', () => {
const organizationWithFlag = OrganizationFixture({
...organization,
features: ['inbound-filters-v2'],
});
const projectWithDiscardGroups = ProjectFixture({
...project,
features: ['discard-groups'],
});

render(<ProjectFilters />, {
organization: organizationWithFlag,
outletContext: {project: projectWithDiscardGroups},
initialRouterConfig: {
location: {
pathname: `/settings/${organizationWithFlag.slug}/projects/${projectWithDiscardGroups.slug}/filters/inbound-filters/`,
},
route: '/settings/:orgId/projects/:projectId/filters/:filterType/',
},
});

expect(screen.getAllByRole('tab').map(tab => tab.textContent)).toEqual([
'Data Filters',
'Custom Filters',
'Discarded Issues',
]);
expect(screen.getByRole('table')).toBeInTheDocument();
for (const column of [
'Active',
'Name',
'Conditions',
'Created',
'Edited',
'Action',
]) {
expect(screen.getByRole('columnheader', {name: column})).toBeInTheDocument();
}
expect(screen.getByText('No inbound filters found')).toBeInTheDocument();
});

it('disables configuration for non project:write users', async () => {
render(<ProjectFilters />, {
organization: OrganizationFixture({access: []}),
Expand Down
23 changes: 22 additions & 1 deletion static/app/views/settings/project/projectFilters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {TabList, Tabs} from '@sentry/scraps/tabs';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
import {t} from 'sentry/locale';
import {recreateRoute} from 'sentry/utils/recreateRoute';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import {useRoutes} from 'sentry/utils/useRoutes';
import {SettingsPageHeader} from 'sentry/views/settings/components/settingsPageHeader';
Expand All @@ -15,17 +16,23 @@ import {ProjectFiltersSettings} from 'sentry/views/settings/project/projectFilte
import {ProjectPermissionAlert} from 'sentry/views/settings/project/projectPermissionAlert';
import {useProjectSettingsOutlet} from 'sentry/views/settings/project/projectSettingsLayout';

import {CustomFilters} from './customFilters';

export default function ProjectFilters() {
const routes = useRoutes();
const params = useParams<{filterType: string; projectId: string}>();
const {projectId, filterType} = params;
const {project} = useProjectSettingsOutlet();
const organization = useOrganization();

if (!project) {
return null;
}

const features = new Set(project.features);
const hasInboundFiltersV2 = organization.features.includes('inbound-filters-v2');
const hasDiscardGroups = features.has('discard-groups');
const showTabs = hasDiscardGroups || hasInboundFiltersV2;

return (
<Fragment>
Expand All @@ -42,7 +49,7 @@ export default function ProjectFilters() {
<div>
<ProjectFiltersChart project={project} />

{features.has('discard-groups') && (
{showTabs && (
<TabsContainer>
<Tabs value={filterType}>
<TabList>
Expand All @@ -52,8 +59,20 @@ export default function ProjectFilters() {
>
{t('Data Filters')}
</TabList.Item>
<TabList.Item
key="inbound-filters"
hidden={!hasInboundFiltersV2}
to={recreateRoute('inbound-filters/', {
routes,
params,
stepBack: -1,
})}
>
{t('Custom Filters')}
</TabList.Item>
<TabList.Item
key="discarded-groups"
hidden={!hasDiscardGroups}
to={recreateRoute('discarded-groups/', {routes, params, stepBack: -1})}
>
{t('Discarded Issues')}
Expand All @@ -65,6 +84,8 @@ export default function ProjectFilters() {

{filterType === 'discarded-groups' ? (
<GroupTombstones project={project} />
) : hasInboundFiltersV2 && filterType === 'inbound-filters' ? (
<CustomFilters />
) : (
<ProjectFiltersSettings project={project} params={params} />
)}
Expand Down
Loading