|
| 1 | +import {Fragment, useMemo} from 'react'; |
| 2 | +import styled from '@emotion/styled'; |
| 3 | + |
| 4 | +import waitingForEventImg from 'sentry-images/spot/waiting-for-event.svg'; |
| 5 | +import devkitCrashesStep1 from 'sentry-images/tempest/devkit-crashes-step1.png'; |
| 6 | +import devkitCrashesStep2 from 'sentry-images/tempest/devkit-crashes-step2.png'; |
| 7 | +import devkitCrashesStep3 from 'sentry-images/tempest/devkit-crashes-step3.png'; |
| 8 | +import windowToolImg from 'sentry-images/tempest/windows-tool-devkit.png'; |
| 9 | + |
| 10 | +import {Button} from 'sentry/components/core/button'; |
| 11 | +import {ButtonBar} from 'sentry/components/core/button/buttonBar'; |
| 12 | +import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton'; |
| 13 | +import {GuidedSteps} from 'sentry/components/guidedSteps/guidedSteps'; |
| 14 | +import LoadingIndicator from 'sentry/components/loadingIndicator'; |
| 15 | +import {OnboardingCodeSnippet} from 'sentry/components/onboarding/gettingStartedDoc/onboardingCodeSnippet'; |
| 16 | +import Panel from 'sentry/components/panels/panel'; |
| 17 | +import PanelBody from 'sentry/components/panels/panelBody'; |
| 18 | +import {t} from 'sentry/locale'; |
| 19 | +import {space} from 'sentry/styles/space'; |
| 20 | +import type {Organization} from 'sentry/types/organization'; |
| 21 | +import type {Project} from 'sentry/types/project'; |
| 22 | +import {decodeInteger} from 'sentry/utils/queryString'; |
| 23 | +import {useLocation} from 'sentry/utils/useLocation'; |
| 24 | +import {useNavigate} from 'sentry/utils/useNavigate'; |
| 25 | +import {useProjectKeys} from 'sentry/utils/useProjectKeys'; |
| 26 | + |
| 27 | +interface Props { |
| 28 | + organization: Organization; |
| 29 | + project: Project; |
| 30 | +} |
| 31 | + |
| 32 | +export default function DevKitSettings({organization, project}: Props) { |
| 33 | + const navigate = useNavigate(); |
| 34 | + const location = useLocation(); |
| 35 | + |
| 36 | + const {data: projectKeys, isPending: isLoadingKeys} = useProjectKeys({ |
| 37 | + orgSlug: organization.slug, |
| 38 | + projSlug: project.slug, |
| 39 | + }); |
| 40 | + |
| 41 | + const playstationURL = useMemo(() => { |
| 42 | + if (!projectKeys) { |
| 43 | + return null; |
| 44 | + } |
| 45 | + |
| 46 | + // xxx (vgrozdanic): this is a temporary hack since the playstation URL is almost the same as for the minidump |
| 47 | + const primaryKey = projectKeys[0]; |
| 48 | + return primaryKey?.dsn?.minidump.replace('minidump', 'playstation'); |
| 49 | + }, [projectKeys]); |
| 50 | + |
| 51 | + if (isLoadingKeys) { |
| 52 | + return <LoadingIndicator />; |
| 53 | + } |
| 54 | + |
| 55 | + return ( |
| 56 | + <Fragment> |
| 57 | + <Panel> |
| 58 | + <PanelBody> |
| 59 | + <div> |
| 60 | + <HeaderWrapper> |
| 61 | + <Title>{t('Get Started with DevKit Crash Monitoring')}</Title> |
| 62 | + <Description> |
| 63 | + {t( |
| 64 | + 'Set up your PlayStation development kit to send crash reports to Sentry.' |
| 65 | + )} |
| 66 | + </Description> |
| 67 | + <Image src={waitingForEventImg} /> |
| 68 | + </HeaderWrapper> |
| 69 | + <Divider /> |
| 70 | + <Body> |
| 71 | + <Setup> |
| 72 | + <BodyTitle>{t('Setup Instructions')}</BodyTitle> |
| 73 | + <GuidedSteps |
| 74 | + initialStep={decodeInteger(location.query.guidedStep)} |
| 75 | + onStepChange={step => { |
| 76 | + navigate({ |
| 77 | + pathname: location.pathname, |
| 78 | + query: { |
| 79 | + ...location.query, |
| 80 | + guidedStep: step, |
| 81 | + }, |
| 82 | + }); |
| 83 | + }} |
| 84 | + > |
| 85 | + <GuidedSteps.Step |
| 86 | + stepKey="step-1" |
| 87 | + title={t('Copy Playstation Ingestion URL')} |
| 88 | + > |
| 89 | + <DescriptionWrapper> |
| 90 | + <p> |
| 91 | + {t('This is the URL where your crash reports will be sent. ')} |
| 92 | + </p> |
| 93 | + <CodeSnippetWrapper> |
| 94 | + <OnboardingCodeSnippet> |
| 95 | + {playstationURL || ''} |
| 96 | + </OnboardingCodeSnippet> |
| 97 | + </CodeSnippetWrapper> |
| 98 | + </DescriptionWrapper> |
| 99 | + <GuidedSteps.StepButtons /> |
| 100 | + </GuidedSteps.Step> |
| 101 | + |
| 102 | + <GuidedSteps.Step |
| 103 | + stepKey="step-2" |
| 104 | + title={t('Using Windows tool set up Upload URL')} |
| 105 | + > |
| 106 | + <DescriptionWrapper> |
| 107 | + <StepContentColumn> |
| 108 | + <StepTextSection> |
| 109 | + <p> |
| 110 | + {t( |
| 111 | + 'Using Windows tool enter that link into the DevKit as the URL to the Recap Server.' |
| 112 | + )} |
| 113 | + </p> |
| 114 | + </StepTextSection> |
| 115 | + <StepImageSection> |
| 116 | + <CardIllustration |
| 117 | + src={windowToolImg} |
| 118 | + alt="Setup Configuration" |
| 119 | + /> |
| 120 | + </StepImageSection> |
| 121 | + </StepContentColumn> |
| 122 | + </DescriptionWrapper> |
| 123 | + <GuidedSteps.StepButtons /> |
| 124 | + </GuidedSteps.Step> |
| 125 | + |
| 126 | + <GuidedSteps.Step |
| 127 | + stepKey="step-3" |
| 128 | + title={t('Using DevKit Directly set up Upload URL')} |
| 129 | + > |
| 130 | + <DescriptionWrapper> |
| 131 | + <StepContentColumn> |
| 132 | + <StepTextSection> |
| 133 | + <p> |
| 134 | + {t( |
| 135 | + `If you haven't done it via Windows tool, you can set up the Upload URL directly in the DevKit. It is under 'Debug Settings' > 'Core Dump' > 'Upload' > 'Upload URL'.` |
| 136 | + )} |
| 137 | + </p> |
| 138 | + </StepTextSection> |
| 139 | + <StepImageSection> |
| 140 | + <CardIllustration |
| 141 | + src={devkitCrashesStep1} |
| 142 | + alt="Setup Configuration" |
| 143 | + /> |
| 144 | + </StepImageSection> |
| 145 | + <StepImageSection> |
| 146 | + <CardIllustration |
| 147 | + src={devkitCrashesStep2} |
| 148 | + alt="Setup Configuration" |
| 149 | + /> |
| 150 | + </StepImageSection> |
| 151 | + <StepImageSection> |
| 152 | + <CardIllustration |
| 153 | + src={devkitCrashesStep3} |
| 154 | + alt="Setup Configuration" |
| 155 | + /> |
| 156 | + </StepImageSection> |
| 157 | + </StepContentColumn> |
| 158 | + </DescriptionWrapper> |
| 159 | + <GuidedSteps.StepButtons /> |
| 160 | + </GuidedSteps.Step> |
| 161 | + |
| 162 | + <GuidedSteps.Step stepKey="step-4" title={t('Important Notes')}> |
| 163 | + <DescriptionWrapper> |
| 164 | + <p> |
| 165 | + {t( |
| 166 | + 'If you are trying to re-attempt the upload of a failed crash that occurred before entering the URL it might be that the DevKit still tries to send the crash to the previously specified URL.' |
| 167 | + )} |
| 168 | + </p> |
| 169 | + |
| 170 | + <p> |
| 171 | + {t( |
| 172 | + 'There is currently a limit on the size of files we support, as such, uploading large dumps or long videos may fail. Short videos should be supposed so configuring the DevKit to keep them short is a temporary solution.' |
| 173 | + )} |
| 174 | + </p> |
| 175 | + </DescriptionWrapper> |
| 176 | + <GuidedSteps.StepButtons> |
| 177 | + <Button |
| 178 | + size="sm" |
| 179 | + priority="primary" |
| 180 | + onClick={() => { |
| 181 | + navigate({ |
| 182 | + pathname: '/issues/', |
| 183 | + query: { |
| 184 | + query: 'os.name:PlayStation', |
| 185 | + }, |
| 186 | + }); |
| 187 | + }} |
| 188 | + > |
| 189 | + {t('View DevKit Issues')} |
| 190 | + </Button> |
| 191 | + </GuidedSteps.StepButtons> |
| 192 | + </GuidedSteps.Step> |
| 193 | + </GuidedSteps> |
| 194 | + </Setup> |
| 195 | + </Body> |
| 196 | + </div> |
| 197 | + </PanelBody> |
| 198 | + </Panel> |
| 199 | + </Fragment> |
| 200 | + ); |
| 201 | +} |
| 202 | + |
| 203 | +export const getDevKitHeaderAction = () => { |
| 204 | + return ( |
| 205 | + <ButtonBar gap={1.5}> |
| 206 | + <FeedbackWidgetButton /> |
| 207 | + </ButtonBar> |
| 208 | + ); |
| 209 | +}; |
| 210 | + |
| 211 | +const Title = styled('div')` |
| 212 | + font-size: 26px; |
| 213 | + font-weight: ${p => p.theme.fontWeightBold}; |
| 214 | +`; |
| 215 | + |
| 216 | +const Description = styled('div')``; |
| 217 | + |
| 218 | +const HeaderWrapper = styled('div')` |
| 219 | + border-radius: ${p => p.theme.borderRadius}; |
| 220 | + padding: ${space(4)}; |
| 221 | +`; |
| 222 | + |
| 223 | +const BodyTitle = styled('div')` |
| 224 | + font-size: ${p => p.theme.fontSizeExtraLarge}; |
| 225 | + font-weight: ${p => p.theme.fontWeightBold}; |
| 226 | + margin-bottom: ${space(1)}; |
| 227 | +`; |
| 228 | + |
| 229 | +const Setup = styled('div')` |
| 230 | + padding: ${space(4)}; |
| 231 | +`; |
| 232 | + |
| 233 | +const Body = styled('div')``; |
| 234 | + |
| 235 | +const Image = styled('img')` |
| 236 | + position: absolute; |
| 237 | + display: block; |
| 238 | + top: 0px; |
| 239 | + right: 20px; |
| 240 | + pointer-events: none; |
| 241 | + height: 120px; |
| 242 | + overflow: hidden; |
| 243 | +
|
| 244 | + @media (max-width: ${p => p.theme.breakpoints.small}) { |
| 245 | + display: none; |
| 246 | + } |
| 247 | +`; |
| 248 | + |
| 249 | +const Divider = styled('hr')` |
| 250 | + height: 1px; |
| 251 | + width: 95%; |
| 252 | + background: ${p => p.theme.border}; |
| 253 | + border: none; |
| 254 | + margin-top: 0; |
| 255 | + margin-bottom: 0; |
| 256 | +`; |
| 257 | + |
| 258 | +const CodeSnippetWrapper = styled('div')` |
| 259 | + margin-bottom: ${space(2)}; |
| 260 | + margin-top: ${space(2)}; |
| 261 | +`; |
| 262 | + |
| 263 | +const DescriptionWrapper = styled('div')` |
| 264 | + margin-bottom: ${space(1)}; |
| 265 | +`; |
| 266 | + |
| 267 | +const StepContentColumn = styled('div')` |
| 268 | + display: flex; |
| 269 | + flex-direction: column; |
| 270 | + width: 100%; |
| 271 | + gap: ${space(3)}; |
| 272 | +`; |
| 273 | + |
| 274 | +const StepTextSection = styled('div')` |
| 275 | + display: flex; |
| 276 | + flex-direction: column; |
| 277 | + gap: ${space(1)}; |
| 278 | +`; |
| 279 | + |
| 280 | +const StepImageSection = styled('div')` |
| 281 | + display: flex; |
| 282 | + justify-content: center; |
| 283 | + align-items: center; |
| 284 | + width: 100%; |
| 285 | +`; |
| 286 | + |
| 287 | +const CardIllustration = styled('img')` |
| 288 | + width: 100%; |
| 289 | + max-width: 600px; |
| 290 | + height: auto; |
| 291 | + object-fit: contain; |
| 292 | + border: 1px solid ${p => p.theme.border}; |
| 293 | + border-radius: ${p => p.theme.borderRadius}; |
| 294 | + box-shadow: ${p => p.theme.dropShadowLight}; |
| 295 | +`; |
0 commit comments