-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(feedback): add spam detection to project settings (#66740)
Create a User Feedback section under the Processing header, to add a spam detection toggle in project settings. We already have a User Feedback section under SDK Setup, but I didn't think that spam fit in with SDK setup. The result is that we now have two User Feedback sections in the settings (open to ideas for consolidating or renaming): <img width="190" alt="SCR-20240311-nuse" src="https://github.com/getsentry/sentry/assets/56095982/d702ebe0-6b29-4f4f-bd16-b631bace6d26"> The new page looks like this: <img width="978" alt="SCR-20240311-numj" src="https://github.com/getsentry/sentry/assets/56095982/6cc13770-129e-40bb-b074-8a63b51eec8e"> Closes #66731
- Loading branch information
1 parent
3f7e560
commit 46e6377
Showing
5 changed files
with
141 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import type {JsonFormObject} from 'sentry/components/forms/types'; | ||
|
||
export const route = '/settings/:orgId/projects/:projectId/user-feedback-processing/'; | ||
|
||
const formGroups: JsonFormObject[] = [ | ||
{ | ||
title: 'Settings', | ||
fields: [ | ||
{ | ||
name: 'sentry:feedback_ai_spam_detection', | ||
type: 'boolean', | ||
|
||
// additional data/props that is related to rendering of form field rather than data | ||
label: 'Enable Spam Detection', | ||
help: 'Toggles whether or not to enable auto spam detection in User Feedback.', | ||
getData: data => ({options: data}), | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
export default formGroups; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
static/app/views/settings/project/projectUserFeedbackProcessing.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import {ProjectFixture} from 'sentry-fixture/project'; | ||
|
||
import {initializeOrg} from 'sentry-test/initializeOrg'; | ||
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary'; | ||
|
||
import ProjectUserFeedbackProcessing from 'sentry/views/settings/project/projectUserFeedbackProcessing'; | ||
|
||
describe('ProjectUserFeedbackProcessing', function () { | ||
const {routerProps, organization, project, routerContext} = initializeOrg(); | ||
const url = `/projects/${organization.slug}/${project.slug}/`; | ||
|
||
beforeEach(function () { | ||
MockApiClient.clearMockResponses(); | ||
MockApiClient.addMockResponse({ | ||
url, | ||
method: 'GET', | ||
body: ProjectFixture(), | ||
}); | ||
MockApiClient.addMockResponse({ | ||
url: `${url}keys/`, | ||
method: 'GET', | ||
body: [], | ||
}); | ||
}); | ||
|
||
it('can toggle spam detection', async function () { | ||
render( | ||
<ProjectUserFeedbackProcessing | ||
{...routerProps} | ||
organization={organization} | ||
project={project} | ||
/>, | ||
{ | ||
context: routerContext, | ||
} | ||
); | ||
|
||
const mock = MockApiClient.addMockResponse({ | ||
url, | ||
method: 'PUT', | ||
}); | ||
|
||
await userEvent.click(screen.getByRole('checkbox', {name: 'Enable Spam Detection'})); | ||
|
||
expect(mock).toHaveBeenCalledWith( | ||
url, | ||
expect.objectContaining({ | ||
method: 'PUT', | ||
data: { | ||
options: {'sentry:feedback_ai_spam_detection': true}, | ||
}, | ||
}) | ||
); | ||
}); | ||
}); |
52 changes: 52 additions & 0 deletions
52
static/app/views/settings/project/projectUserFeedbackProcessing.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import type {RouteComponentProps} from 'react-router'; | ||
|
||
import Access from 'sentry/components/acl/access'; | ||
import {Button} from 'sentry/components/button'; | ||
import Form from 'sentry/components/forms/form'; | ||
import JsonForm from 'sentry/components/forms/jsonForm'; | ||
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; | ||
import formGroups from 'sentry/data/forms/userFeedbackProcessing'; | ||
import {t} from 'sentry/locale'; | ||
import type {Organization, Project} from 'sentry/types'; | ||
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader'; | ||
import PermissionAlert from 'sentry/views/settings/project/permissionAlert'; | ||
|
||
type RouteParams = { | ||
projectId: string; | ||
}; | ||
type Props = RouteComponentProps<RouteParams, {}> & { | ||
organization: Organization; | ||
project: Project; | ||
}; | ||
|
||
function ProjectUserFeedbackProcessingSettings({ | ||
project, | ||
organization, | ||
params: {projectId}, | ||
}: Props) { | ||
return ( | ||
<SentryDocumentTitle title={t('User Feedback')} projectSlug={project.slug}> | ||
<SettingsPageHeader | ||
title={t('User Feedback')} | ||
action={ | ||
<Button external href="https://docs.sentry.io/product/user-feedback/"> | ||
{t('Read the docs')} | ||
</Button> | ||
} | ||
/> | ||
<PermissionAlert project={project} /> | ||
<Form | ||
saveOnBlur | ||
apiMethod="PUT" | ||
apiEndpoint={`/projects/${organization.slug}/${projectId}/`} | ||
initialData={project.options} | ||
> | ||
<Access access={['project:write']} project={project}> | ||
{({hasAccess}) => <JsonForm disabled={!hasAccess} forms={formGroups} />} | ||
</Access> | ||
</Form> | ||
</SentryDocumentTitle> | ||
); | ||
} | ||
|
||
export default ProjectUserFeedbackProcessingSettings; |