From 130698cd51c266f4bab22f9ee5b9092656924bb6 Mon Sep 17 00:00:00 2001 From: Priscila Oliveira Date: Wed, 16 Oct 2024 12:47:15 +0200 Subject: [PATCH] feat(quick-start): Add new design skeleton (#79102) --- .../onboardingWizard/newSidebar.tsx | 270 ++++++++++++++++++ .../app/components/onboardingWizard/utils.tsx | 5 + .../components/sidebar/onboardingStatus.tsx | 23 +- 3 files changed, 291 insertions(+), 7 deletions(-) create mode 100644 static/app/components/onboardingWizard/newSidebar.tsx diff --git a/static/app/components/onboardingWizard/newSidebar.tsx b/static/app/components/onboardingWizard/newSidebar.tsx new file mode 100644 index 0000000000000..0c945e6ba3cee --- /dev/null +++ b/static/app/components/onboardingWizard/newSidebar.tsx @@ -0,0 +1,270 @@ +import {Fragment, useState} from 'react'; +import {css} from '@emotion/react'; +import styled from '@emotion/styled'; + +import {Chevron} from 'sentry/components/chevron'; +import InteractionStateLayer from 'sentry/components/interactionStateLayer'; +import ProgressRing from 'sentry/components/progressRing'; +import SidebarPanel from 'sentry/components/sidebar/sidebarPanel'; +import type {CommonSidebarProps} from 'sentry/components/sidebar/types'; +import {Tooltip} from 'sentry/components/tooltip'; +import {IconCheckmark} from 'sentry/icons'; +import {t, tct} from 'sentry/locale'; +import pulsingIndicatorStyles from 'sentry/styles/pulsingIndicator'; +import {space} from 'sentry/styles/space'; +import {isDemoWalkthrough} from 'sentry/utils/demoMode'; + +function getPanelDescription(walkthrough: boolean) { + if (walkthrough) { + return { + title: t('Guided Tours'), + description: t('Take a guided tour to see what Sentry can do for you'), + }; + } + return { + title: t('Quick Start'), + description: t('Walk through this guide to get the most out of Sentry right away.'), + }; +} + +interface TaskProps { + description: string; + title: string; + status?: 'waiting' | 'completed'; +} + +function Task({title, description, status}: TaskProps) { + if (status === 'completed') { + return ( + + {title} + + + ); + } + + if (status === 'waiting') { + return ( + + +
+ {title} +

{description}

+
+ + + +
+ ); + } + + return ( + + +
+ {title} +

{description}

+
+
+ ); +} + +interface TaskGroupProps { + description: string; + title: string; + totalCompletedTasks: number; + totalTasks: number; + expanded?: boolean; +} + +function TaskGroup({ + title, + description, + totalCompletedTasks, + totalTasks, + expanded, +}: TaskGroupProps) { + const [isExpanded, setIsExpanded] = useState(expanded); + return ( + + setIsExpanded(!isExpanded)}> + + + {title} +

{description}

+
+ +
+ {isExpanded && ( + +
+ + + {tct('[totalCompletedTasks] out of [totalTasks] tasks completed', { + totalCompletedTasks, + totalTasks, + })} + + + + + + {t('Completed')} + + + +
+ )} +
+ ); +} + +interface NewSidebarProps extends Pick { + onClose: () => void; +} + +export function NewOnboardingSidebar({onClose, orientation, collapsed}: NewSidebarProps) { + const walkthrough = isDemoWalkthrough(); + const {title, description} = getPanelDescription(walkthrough); + + return ( + + +

{description}

+ + + +
+
+ ); +} + +const Wrapper = styled(SidebarPanel)` + width: 100%; + @media (min-width: ${p => p.theme.breakpoints.xsmall}) { + width: 450px; + } +`; + +const Content = styled('div')` + padding: ${space(3)}; + display: flex; + flex-direction: column; + gap: ${space(1)}; + + p { + margin-bottom: ${space(1)}; + } +`; + +const TaskGroupWrapper = styled('div')` + border: 1px solid ${p => p.theme.border}; + border-radius: ${p => p.theme.borderRadius}; + padding: ${space(1)}; + + hr { + border-color: ${p => p.theme.translucentBorder}; + margin: ${space(1)} -${space(1)}; + } +`; + +const TaskGroupHeader = styled('div')` + cursor: pointer; + display: grid; + grid-template-columns: 1fr max-content; + padding: ${space(1)} ${space(1.5)}; + gap: ${space(1.5)}; + position: relative; + border-radius: ${p => p.theme.borderRadius}; + align-items: center; + + p { + margin: 0; + font-size: ${p => p.theme.fontSizeSmall}; + color: ${p => p.theme.subText}; + } +`; + +const TaskGroupBody = styled('div')` + border-radius: ${p => p.theme.borderRadius}; +`; + +const TaskGroupProgress = styled('div')<{completed?: boolean}>` + font-size: ${p => p.theme.fontSizeSmall}; + font-weight: ${p => p.theme.fontWeightBold}; + padding: ${space(0.75)} ${space(1.5)}; + ${p => + p.completed + ? css` + color: ${p.theme.green300}; + ` + : css` + color: ${p.theme.subText}; + display: grid; + grid-template-columns: 1fr max-content; + align-items: center; + gap: ${space(1)}; + `} +`; + +const TaskWrapper = styled('div')<{completed?: boolean}>` + padding: ${space(1)} ${space(1.5)}; + border-radius: ${p => p.theme.borderRadius}; + display: grid; + grid-template-columns: 1fr max-content; + align-items: center; + gap: ${space(1)}; + + p { + margin: 0; + font-size: ${p => p.theme.fontSizeSmall}; + color: ${p => p.theme.subText}; + } + + ${p => + p.completed + ? css` + strong { + opacity: 0.5; + } + ` + : css` + position: relative; + cursor: pointer; + `} +`; + +const PulsingIndicator = styled('div')` + ${pulsingIndicatorStyles}; + margin: 0 ${space(0.5)}; +`; diff --git a/static/app/components/onboardingWizard/utils.tsx b/static/app/components/onboardingWizard/utils.tsx index 10935b1ca44ea..38c1e9b921335 100644 --- a/static/app/components/onboardingWizard/utils.tsx +++ b/static/app/components/onboardingWizard/utils.tsx @@ -1,4 +1,5 @@ import type {OnboardingTask} from 'sentry/types/onboarding'; +import type {Organization} from 'sentry/types/organization'; export const taskIsDone = (task: OnboardingTask) => ['complete', 'skipped'].includes(task.status); @@ -11,3 +12,7 @@ export const findActiveTasks = (task: OnboardingTask) => export const findUpcomingTasks = (task: OnboardingTask) => task.requisiteTasks.length > 0 && !findCompleteTasks(task); + +export function hasQuickStartUpdatesFeature(organization: Organization) { + return organization.features.includes('quick-start-updates'); +} diff --git a/static/app/components/sidebar/onboardingStatus.tsx b/static/app/components/sidebar/onboardingStatus.tsx index 38271838e600c..04f08ae00286c 100644 --- a/static/app/components/sidebar/onboardingStatus.tsx +++ b/static/app/components/sidebar/onboardingStatus.tsx @@ -4,8 +4,10 @@ import {css} from '@emotion/react'; import styled from '@emotion/styled'; import {OnboardingContext} from 'sentry/components/onboarding/onboardingContext'; +import {NewOnboardingSidebar} from 'sentry/components/onboardingWizard/newSidebar'; import OnboardingSidebar from 'sentry/components/onboardingWizard/sidebar'; import {getMergedTasks} from 'sentry/components/onboardingWizard/taskConfig'; +import {hasQuickStartUpdatesFeature} from 'sentry/components/onboardingWizard/utils'; import ProgressRing, { RingBackground, RingBar, @@ -125,13 +127,20 @@ export default function OnboardingStatus({ )} - {isActive && ( - - )} + {isActive && + (hasQuickStartUpdatesFeature(org) ? ( + + ) : ( + + ))} ); }