Skip to content

Commit 9f24114

Browse files
authored
ref(issues-onboarding): Reduce code duplication (#95222)
Remove duplicated code for rendering onboarding steps.
1 parent a9b3fa1 commit 9f24114

File tree

1 file changed

+77
-204
lines changed

1 file changed

+77
-204
lines changed

static/app/components/updatedEmptyState.tsx

Lines changed: 77 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Fragment, useEffect} from 'react';
1+
import {useEffect} from 'react';
22
import styled from '@emotion/styled';
33

44
import waitingForEventImg from 'sentry-images/spot/waiting-for-event.svg';
@@ -11,7 +11,11 @@ import {
1111
OnboardingCodeSnippet,
1212
TabbedCodeSnippet,
1313
} from 'sentry/components/onboarding/gettingStartedDoc/onboardingCodeSnippet';
14-
import type {DocsParams} from 'sentry/components/onboarding/gettingStartedDoc/types';
14+
import {StepTitles} from 'sentry/components/onboarding/gettingStartedDoc/step';
15+
import type {
16+
Configuration,
17+
DocsParams,
18+
} from 'sentry/components/onboarding/gettingStartedDoc/types';
1519
import {useSourcePackageRegistries} from 'sentry/components/onboarding/gettingStartedDoc/useSourcePackageRegistries';
1620
import {useLoadGettingStarted} from 'sentry/components/onboarding/gettingStartedDoc/utils/useLoadGettingStarted';
1721
import platforms from 'sentry/data/platforms';
@@ -42,6 +46,34 @@ export function SetupTitle({project}: {project: Project}) {
4246
);
4347
}
4448

49+
function ConfigurationRenderer({configuration}: {configuration: Configuration}) {
50+
const subConfigurations = configuration.configurations ?? [];
51+
52+
return (
53+
<ConfigurationWrapper>
54+
{configuration.description && (
55+
<DescriptionWrapper>{configuration.description}</DescriptionWrapper>
56+
)}
57+
{typeof configuration.code === 'string' ||
58+
(Array.isArray(configuration.code) && configuration.code.length > 0) ? (
59+
Array.isArray(configuration.code) ? (
60+
<TabbedCodeSnippet tabs={configuration.code} />
61+
) : (
62+
<OnboardingCodeSnippet language={configuration.language}>
63+
{configuration.code}
64+
</OnboardingCodeSnippet>
65+
)
66+
) : null}
67+
{subConfigurations.map((subConfiguration, index) => (
68+
<ConfigurationRenderer key={index} configuration={subConfiguration} />
69+
))}
70+
{configuration.additionalInfo && (
71+
<AdditionalInfo>{configuration.additionalInfo}</AdditionalInfo>
72+
)}
73+
</ConfigurationWrapper>
74+
);
75+
}
76+
4577
export default function UpdatedEmptyState({project}: {project?: Project}) {
4678
const api = useApi();
4779
const organization = useOrganization();
@@ -113,23 +145,12 @@ export default function UpdatedEmptyState({project}: {project?: Project}) {
113145
};
114146
}
115147

116-
const install = loadGettingStarted.docs.onboarding.install(docParams)[0]!;
148+
const install = loadGettingStarted.docs.onboarding.install(docParams);
117149
const configure = loadGettingStarted.docs.onboarding.configure(docParams);
118150
const verify = loadGettingStarted.docs.onboarding.verify(docParams);
119151

120-
const {description: installDescription, additionalInfo: installInfo} = install;
121-
122-
const installConfigurations = install.configurations ?? [];
123-
124-
const {configurations, description: configureDescription} = configure[0] ?? {};
125-
const {
126-
configurations: extraConfigurations,
127-
description: extraConfigDescription,
128-
title: extraConfigTitle,
129-
} = configure[1] ?? {};
130-
131-
const {description: verifyDescription, configurations: verifyConfigurations} =
132-
verify[0] ?? {};
152+
// TODO: Is there a reason why we are only selecting a few steps?
153+
const steps = [install[0], configure[0], configure[1], verify[0]].filter(Boolean);
133154

134155
return (
135156
<AuthTokenGeneratorProvider projectSlug={project?.slug}>
@@ -157,201 +178,49 @@ export default function UpdatedEmptyState({project}: {project?: Project}) {
157178
});
158179
}}
159180
>
160-
<GuidedSteps.Step stepKey="install-sentry" title={t('Install Sentry')}>
161-
<div>
162-
<div>
163-
<DescriptionWrapper>{installDescription}</DescriptionWrapper>
164-
{installConfigurations.map((configuration, index) => (
165-
<div key={index}>
166-
<DescriptionWrapper>
167-
{configuration.description}
168-
</DescriptionWrapper>
169-
<CodeSnippetWrapper>
170-
{configuration.code ? (
171-
Array.isArray(configuration.code) ? (
172-
<TabbedCodeSnippet tabs={configuration.code} />
173-
) : (
174-
<OnboardingCodeSnippet language={configuration.language}>
175-
{configuration.code}
176-
</OnboardingCodeSnippet>
177-
)
178-
) : null}
179-
</CodeSnippetWrapper>
180-
</div>
181-
))}
182-
<DescriptionWrapper>{installInfo}</DescriptionWrapper>
183-
{!configurations &&
184-
!extraConfigDescription &&
185-
!verifyConfigurations && (
186-
<FirstEventIndicator
187-
organization={organization}
188-
project={project}
189-
eventType="error"
190-
>
191-
{({indicator, firstEventButton}) => (
192-
<FirstEventWrapper>
193-
<IndicatorWrapper>{indicator}</IndicatorWrapper>
194-
<StyledButtonBar gap={1}>
195-
<GuidedSteps.BackButton size="md" />
196-
{firstEventButton}
197-
</StyledButtonBar>
198-
</FirstEventWrapper>
199-
)}
200-
</FirstEventIndicator>
201-
)}
202-
</div>
203-
<GuidedSteps.ButtonWrapper>
204-
<GuidedSteps.BackButton size="md" />
205-
<GuidedSteps.NextButton size="md" />
206-
</GuidedSteps.ButtonWrapper>
207-
</div>
208-
</GuidedSteps.Step>
209-
{configurations ? (
210-
<GuidedSteps.Step
211-
stepKey="configure-sentry"
212-
title={t('Configure Sentry')}
213-
>
214-
<div>
215-
<div>
216-
<DescriptionWrapper>{configureDescription}</DescriptionWrapper>
217-
{configurations.map((configuration, index) => (
218-
<div key={index}>
219-
<DescriptionWrapper>
220-
{configuration.description}
221-
</DescriptionWrapper>
222-
<CodeSnippetWrapper>
223-
{configuration.code ? (
224-
Array.isArray(configuration.code) ? (
225-
<TabbedCodeSnippet tabs={configuration.code} />
226-
) : (
227-
<OnboardingCodeSnippet language={configuration.language}>
228-
{configuration.code}
229-
</OnboardingCodeSnippet>
230-
)
231-
) : null}
232-
</CodeSnippetWrapper>
233-
<CodeSnippetWrapper>
234-
{configuration.configurations &&
235-
configuration.configurations.length > 0 ? (
236-
Array.isArray(configuration.configurations[0]!.code) ? (
237-
<TabbedCodeSnippet
238-
tabs={configuration.configurations[0]!.code}
239-
/>
240-
) : null
241-
) : null}
242-
</CodeSnippetWrapper>
243-
<DescriptionWrapper>
244-
{configuration.additionalInfo}
245-
</DescriptionWrapper>
246-
</div>
247-
))}
248-
</div>
249-
<GuidedSteps.ButtonWrapper>
250-
<GuidedSteps.BackButton size="md" />
251-
<GuidedSteps.NextButton size="md" />
252-
</GuidedSteps.ButtonWrapper>
253-
</div>
254-
</GuidedSteps.Step>
255-
) : (
256-
<Fragment />
257-
)}
258-
{extraConfigDescription ? (
259-
<GuidedSteps.Step
260-
stepKey="extra-configuration-sentry"
261-
title={extraConfigTitle || t('Upload Source Maps')}
262-
>
263-
<div>
181+
{steps.map((step, index) => {
182+
const title = step?.title ?? StepTitles[step?.type ?? 'install'];
183+
return (
184+
<GuidedSteps.Step key={index} stepKey={title} title={title}>
264185
<div>
265-
<DescriptionWrapper>{extraConfigDescription}</DescriptionWrapper>
266-
{extraConfigurations?.map((configuration, index) => (
267-
<div key={index}>
268-
<DescriptionWrapper>
269-
{configuration.description}
270-
</DescriptionWrapper>
271-
<CodeSnippetWrapper>
272-
{configuration.code ? (
273-
Array.isArray(configuration.code) ? (
274-
<TabbedCodeSnippet tabs={configuration.code} />
275-
) : (
276-
<OnboardingCodeSnippet language={configuration.language}>
277-
{configuration.code}
278-
</OnboardingCodeSnippet>
279-
)
280-
) : null}
281-
</CodeSnippetWrapper>
282-
</div>
186+
{step?.description ? (
187+
<DescriptionWrapper>{step.description}</DescriptionWrapper>
188+
) : null}
189+
{step?.configurations?.map((configuration, configIndex) => (
190+
<ConfigurationRenderer
191+
key={configIndex}
192+
configuration={configuration}
193+
/>
283194
))}
284-
{!verifyConfigurations && !verifyDescription && (
285-
<FirstEventIndicator
286-
organization={organization}
287-
project={project}
288-
eventType="error"
289-
>
290-
{({indicator, firstEventButton}) => (
291-
<div>
292-
<IndicatorWrapper>{indicator}</IndicatorWrapper>
293-
<StyledButtonBar gap={1}>
294-
<GuidedSteps.BackButton size="md" />
295-
{firstEventButton}
296-
</StyledButtonBar>
297-
</div>
298-
)}
299-
</FirstEventIndicator>
300-
)}
195+
{step?.additionalInfo ? (
196+
<AdditionalInfo>{step.additionalInfo}</AdditionalInfo>
197+
) : null}
301198
</div>
302-
{(verifyConfigurations || verifyDescription) && (
199+
{index === steps.length - 1 ? (
200+
<FirstEventIndicator
201+
organization={organization}
202+
project={project}
203+
eventType="error"
204+
>
205+
{({indicator, firstEventButton}) => (
206+
<FirstEventWrapper>
207+
<IndicatorWrapper>{indicator}</IndicatorWrapper>
208+
<StyledButtonBar gap={1}>
209+
<GuidedSteps.BackButton size="md" />
210+
{firstEventButton}
211+
</StyledButtonBar>
212+
</FirstEventWrapper>
213+
)}
214+
</FirstEventIndicator>
215+
) : (
303216
<GuidedSteps.ButtonWrapper>
304217
<GuidedSteps.BackButton size="md" />
305218
<GuidedSteps.NextButton size="md" />
306219
</GuidedSteps.ButtonWrapper>
307220
)}
308-
</div>
309-
</GuidedSteps.Step>
310-
) : (
311-
<Fragment />
312-
)}
313-
{verifyConfigurations || verifyDescription ? (
314-
<GuidedSteps.Step stepKey="verify-sentry" title={t('Verify')}>
315-
<div>
316-
<DescriptionWrapper>{verifyDescription}</DescriptionWrapper>
317-
{verifyConfigurations?.map((configuration, index) => (
318-
<div key={index}>
319-
<DescriptionWrapper>
320-
{configuration.description}
321-
</DescriptionWrapper>
322-
<CodeSnippetWrapper>
323-
{configuration.code ? (
324-
Array.isArray(configuration.code) ? (
325-
<TabbedCodeSnippet tabs={configuration.code} />
326-
) : (
327-
<OnboardingCodeSnippet language={configuration.language}>
328-
{configuration.code}
329-
</OnboardingCodeSnippet>
330-
)
331-
) : null}
332-
</CodeSnippetWrapper>
333-
</div>
334-
))}
335-
<FirstEventIndicator
336-
organization={organization}
337-
project={project}
338-
eventType="error"
339-
>
340-
{({indicator, firstEventButton}) => (
341-
<FirstEventWrapper>
342-
<IndicatorWrapper>{indicator}</IndicatorWrapper>
343-
<StyledButtonBar gap={1}>
344-
<GuidedSteps.BackButton size="md" />
345-
{firstEventButton}
346-
</StyledButtonBar>
347-
</FirstEventWrapper>
348-
)}
349-
</FirstEventIndicator>
350-
</div>
351-
</GuidedSteps.Step>
352-
) : (
353-
<Fragment />
354-
)}
221+
</GuidedSteps.Step>
222+
);
223+
})}
355224
</GuidedSteps>
356225
</Setup>
357226
<Preview>
@@ -468,14 +337,18 @@ const IndicatorWrapper = styled('div')`
468337
margin-bottom: ${space(1)};
469338
`;
470339

471-
const CodeSnippetWrapper = styled('div')`
340+
const ConfigurationWrapper = styled('div')`
472341
margin-bottom: ${space(2)};
473342
`;
474343

475344
const DescriptionWrapper = styled('div')`
476345
margin-bottom: ${space(1)};
477346
`;
478347

348+
const AdditionalInfo = styled(DescriptionWrapper)`
349+
margin-top: ${space(2)};
350+
`;
351+
479352
const FirstEventWrapper = styled('div')`
480353
padding-top: ${space(1)};
481354
`;

0 commit comments

Comments
 (0)