-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
feat: Add generic modal for requesting access to private gaming repository #96291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c6104ea
b2199fd
8b1ffdf
ac86751
9a120e9
bddc882
9abde2e
320d003
ea46a2a
067e567
7497608
9934891
de9fcaa
b9c2a51
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| import {Fragment, useState} from 'react'; | ||
| import {captureFeedback} from '@sentry/react'; | ||
|
|
||
| import {addSuccessMessage} from 'sentry/actionCreators/indicator'; | ||
| import {type ModalRenderProps} from 'sentry/actionCreators/modal'; | ||
| import {Button} from 'sentry/components/core/button'; | ||
| import {ButtonBar} from 'sentry/components/core/button/buttonBar'; | ||
| import SelectField from 'sentry/components/forms/fields/selectField'; | ||
| import TextField from 'sentry/components/forms/fields/textField'; | ||
| import {t, tct} from 'sentry/locale'; | ||
| import type {Organization} from 'sentry/types/organization'; | ||
| import {useUser} from 'sentry/utils/useUser'; | ||
|
|
||
| const PRIVATE_GAMING_SDK_OPTIONS = [ | ||
| {value: 'playstation', label: 'PlayStation'}, | ||
| {value: 'xbox', label: 'Xbox'}, | ||
| {value: 'nintendo-switch', label: 'Nintendo Switch'}, | ||
| ] as const; | ||
|
|
||
| type GamingPlatform = (typeof PRIVATE_GAMING_SDK_OPTIONS)[number]['value']; | ||
|
|
||
| export interface PrivateGamingSdkAccessModalProps { | ||
| organization: Organization; | ||
| projectSlug: string; | ||
| sdkName: string; | ||
| gamingPlatform?: GamingPlatform; | ||
| onSubmit?: () => void; | ||
| } | ||
|
|
||
| export function PrivateGamingSdkAccessModal({ | ||
| Header, | ||
| Body, | ||
| Footer, | ||
| closeModal, | ||
| organization, | ||
| projectSlug, | ||
| sdkName, | ||
| gamingPlatform, | ||
| onSubmit, | ||
| }: PrivateGamingSdkAccessModalProps & ModalRenderProps) { | ||
| const user = useUser(); | ||
| const [isSubmitting, setIsSubmitting] = useState(false); | ||
| const [githubProfile, setGithubProfile] = useState(''); | ||
| const [gamingPlatforms, setGamingPlatforms] = useState<string[]>( | ||
| gamingPlatform ? [gamingPlatform] : [] | ||
| ); | ||
|
|
||
| const isFormValid = !!githubProfile.trim() && gamingPlatforms.length > 0; | ||
|
|
||
| function handleSubmit() { | ||
| if (!isFormValid) { | ||
| return; | ||
| } | ||
|
|
||
| setIsSubmitting(true); | ||
|
|
||
| onSubmit?.(); | ||
|
|
||
| const messageBody = [ | ||
| `User: ${user.name}`, | ||
| `Email: ${user.email}`, | ||
| gamingPlatforms.length === 1 | ||
| ? `Platform: ${gamingPlatforms[0]}` | ||
| : `Platforms: ${gamingPlatforms | ||
| .map( | ||
| (platform: string) => | ||
| PRIVATE_GAMING_SDK_OPTIONS.find(option => option.value === platform) | ||
| ?.label || platform | ||
| ) | ||
| .join(', ')}`, | ||
| `Org Slug: ${organization.slug}`, | ||
| `Project: ${projectSlug}`, | ||
| `GitHub Profile: ${githubProfile}`, | ||
| ].join('\n'); | ||
|
|
||
| const source = `${sdkName.toLowerCase()}-sdk-access`; | ||
|
|
||
| // Use captureFeedback with proper user context instead of tags | ||
| captureFeedback( | ||
| { | ||
| message: messageBody, | ||
| name: user.name, | ||
| email: user.email, | ||
| source, | ||
| tags: { | ||
| feature: source, | ||
| }, | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }, | ||
| { | ||
| captureContext: { | ||
| user: { | ||
| id: user.id, | ||
| email: user.email, | ||
| username: user.username, | ||
| name: user.name, | ||
| }, | ||
| }, | ||
| } | ||
| ); | ||
|
|
||
| addSuccessMessage( | ||
| tct('Your [sdkName] SDK access request has been submitted.', { | ||
| sdkName, | ||
| }) | ||
| ); | ||
| setIsSubmitting(false); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m unsure how this should work. This This is part of the reason why merging something that has no usage is a bit counter productive imo because we can’t know how it works / what it does. I’m guessing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree - it would be great to use This modal will be removed in a future phase, but for now, we’re keeping it simple by reusing what we already have. |
||
| closeModal(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Feedback Formatting and Submission State IssuesThe
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Feedback Submission Timing and Formatting IssuesThe |
||
| } | ||
|
|
||
| return ( | ||
| <Fragment> | ||
| <Header closeButton> | ||
| <h3> | ||
| {tct('Request [sdkName] SDK Access', { | ||
| sdkName, | ||
| })} | ||
| </h3> | ||
| </Header> | ||
| <Body> | ||
| <p> | ||
| {gamingPlatform | ||
| ? tct( | ||
| 'Request access to our [sdkName] SDK. Please provide your GitHub profile.', | ||
| { | ||
| sdkName, | ||
| } | ||
| ) | ||
| : tct( | ||
| 'Request access to our [sdkName] SDK. Please provide your GitHub profile and the gaming platforms you work with.', | ||
| { | ||
| sdkName, | ||
| } | ||
| )} | ||
| </p> | ||
| <TextField | ||
| name="githubProfile" | ||
| label={t('Link to your GitHub profile')} | ||
| placeholder="https://github.com/username" | ||
| value={githubProfile} | ||
| onChange={setGithubProfile} | ||
| required | ||
| stacked | ||
| inline={false} | ||
| /> | ||
| {!gamingPlatform && ( | ||
| <SelectField | ||
| name="gamingPlatforms" | ||
| label={t('Select Gaming Platform')} | ||
| placeholder={t('Select one or more gaming platforms')} | ||
| options={PRIVATE_GAMING_SDK_OPTIONS} | ||
| value={gamingPlatforms} | ||
| onChange={setGamingPlatforms} | ||
| multiple | ||
| required | ||
| stacked | ||
| inline={false} | ||
| /> | ||
| )} | ||
| </Body> | ||
| <Footer> | ||
| <ButtonBar> | ||
| <Button onClick={closeModal}>{t('Cancel')}</Button> | ||
| <Button | ||
| priority="primary" | ||
| onClick={handleSubmit} | ||
| disabled={!isFormValid || isSubmitting} | ||
| > | ||
| {isSubmitting ? t('Submitting\u2026') : t('Submit Request')} | ||
| </Button> | ||
| </ButtonBar> | ||
| </Footer> | ||
| </Fragment> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function is unused, so I’d expect
knipto complain here (which it doesn’t). I’ll look into that, but can we make the function used somewhere?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes it did not complain which is weird, but this function will be used in 3 different places. Examples: #96300 and #96415