@@ -13,23 +13,27 @@ import partition from 'lodash/partition';
1313
1414import { navigateTo } from 'sentry/actionCreators/navigation' ;
1515import { updateOnboardingTask } from 'sentry/actionCreators/onboardingTasks' ;
16+ import { Button } from 'sentry/components/button' ;
1617import { Chevron } from 'sentry/components/chevron' ;
1718import InteractionStateLayer from 'sentry/components/interactionStateLayer' ;
1819import {
1920 OnboardingContext ,
2021 type OnboardingContextProps ,
2122} from 'sentry/components/onboarding/onboardingContext' ;
23+ import SkipConfirm from 'sentry/components/onboardingWizard/skipConfirm' ;
2224import { findCompleteTasks , taskIsDone } from 'sentry/components/onboardingWizard/utils' ;
2325import ProgressRing from 'sentry/components/progressRing' ;
2426import SidebarPanel from 'sentry/components/sidebar/sidebarPanel' ;
2527import type { CommonSidebarProps } from 'sentry/components/sidebar/types' ;
26- import { Tooltip } from 'sentry/components/tooltip' ;
27- import { IconCheckmark } from 'sentry/icons' ;
28+ import { IconCheckmark , IconClose } from 'sentry/icons' ;
2829import { t , tct } from 'sentry/locale' ;
2930import DemoWalkthroughStore from 'sentry/stores/demoWalkthroughStore' ;
30- import pulsingIndicatorStyles from 'sentry/styles/pulsingIndicator' ;
3131import { space } from 'sentry/styles/space' ;
32- import { type OnboardingTask , OnboardingTaskGroup } from 'sentry/types/onboarding' ;
32+ import {
33+ type OnboardingTask ,
34+ OnboardingTaskGroup ,
35+ type OnboardingTaskKey ,
36+ } from 'sentry/types/onboarding' ;
3337import type { Organization } from 'sentry/types/organization' ;
3438import type { Project } from 'sentry/types/project' ;
3539import { trackAnalytics } from 'sentry/utils/analytics' ;
@@ -85,10 +89,11 @@ function getPanelDescription(walkthrough: boolean) {
8589interface TaskProps {
8690 hidePanel : ( ) => void ;
8791 task : OnboardingTask ;
88- status ?: 'waiting' | 'completed' ;
92+ completed ?: boolean ;
8993}
9094
91- function Task ( { task, status, hidePanel} : TaskProps ) {
95+ function Task ( { task, completed, hidePanel} : TaskProps ) {
96+ const api = useApi ( ) ;
9297 const organization = useOrganization ( ) ;
9398 const router = useRouter ( ) ;
9499
@@ -129,7 +134,35 @@ function Task({task, status, hidePanel}: TaskProps) {
129134 [ task , organization , router , hidePanel ]
130135 ) ;
131136
132- if ( status === 'completed' ) {
137+ const handleMarkComplete = useCallback (
138+ ( taskKey : OnboardingTaskKey ) => {
139+ updateOnboardingTask ( api , organization , {
140+ task : taskKey ,
141+ status : 'complete' ,
142+ completionSeen : true ,
143+ } ) ;
144+ } ,
145+ [ api , organization ]
146+ ) ;
147+
148+ const handleMarkSkipped = useCallback (
149+ ( taskKey : OnboardingTaskKey ) => {
150+ trackAnalytics ( 'quick_start.task_card_clicked' , {
151+ organization,
152+ todo_id : task . task ,
153+ todo_title : task . title ,
154+ action : 'skipped' ,
155+ } ) ;
156+ updateOnboardingTask ( api , organization , {
157+ task : taskKey ,
158+ status : 'skipped' ,
159+ completionSeen : true ,
160+ } ) ;
161+ } ,
162+ [ task , organization , api ]
163+ ) ;
164+
165+ if ( completed ) {
133166 return (
134167 < TaskWrapper completed >
135168 < strong > { task . title } </ strong >
@@ -138,28 +171,36 @@ function Task({task, status, hidePanel}: TaskProps) {
138171 ) ;
139172 }
140173
141- if ( status === 'waiting' ) {
142- return (
143- < TaskWrapper onClick = { handleClick } >
144- < InteractionStateLayer />
145- < div >
146- < strong > { task . title } </ strong >
147- < p > { task . description } </ p >
148- </ div >
149- < Tooltip title = { t ( 'Waiting for event' ) } >
150- < PulsingIndicator />
151- </ Tooltip >
152- </ TaskWrapper >
153- ) ;
154- }
155-
156174 return (
157175 < TaskWrapper onClick = { handleClick } >
158176 < InteractionStateLayer />
159177 < div >
160178 < strong > { task . title } </ strong >
161179 < p > { task . description } </ p >
162180 </ div >
181+ { task . requisiteTasks . length === 0 && (
182+ < Fragment >
183+ { task . skippable && (
184+ < SkipConfirm onSkip = { ( ) => handleMarkSkipped ( task . task ) } >
185+ { ( { skip} ) => (
186+ < Button
187+ borderless
188+ size = "zero"
189+ aria-label = { t ( 'Close' ) }
190+ icon = { < IconClose size = "xs" color = "gray300" /> }
191+ onClick = { skip }
192+ />
193+ ) }
194+ </ SkipConfirm >
195+ ) }
196+ { task . SupplementComponent && (
197+ < task . SupplementComponent
198+ task = { task }
199+ onCompleteTask = { ( ) => handleMarkComplete ( task . task ) }
200+ />
201+ ) }
202+ </ Fragment >
203+ ) }
163204 </ TaskWrapper >
164205 ) ;
165206}
@@ -215,12 +256,7 @@ function TaskGroup({title, description, tasks, expanded, hidePanel}: TaskGroupPr
215256 < Fragment >
216257 < TaskGroupProgress completed > { t ( 'Completed' ) } </ TaskGroupProgress >
217258 { completedTasks . map ( task => (
218- < Task
219- key = { task . task }
220- task = { task }
221- hidePanel = { hidePanel }
222- status = "completed"
223- />
259+ < Task key = { task . task } task = { task } hidePanel = { hidePanel } completed />
224260 ) ) }
225261 </ Fragment >
226262 ) }
@@ -398,7 +434,6 @@ const TaskWrapper = styled('div')<{completed?: boolean}>`
398434 border-radius: ${ p => p . theme . borderRadius } ;
399435 display: grid;
400436 grid-template-columns: 1fr max-content;
401- align-items: center;
402437 gap: ${ space ( 1 ) } ;
403438
404439 p {
@@ -413,14 +448,11 @@ const TaskWrapper = styled('div')<{completed?: boolean}>`
413448 strong {
414449 opacity : 0.5 ;
415450 }
451+ align-items : center;
416452 `
417453 : css `
418454 position : relative;
419455 cursor : pointer;
456+ align-items : flex-start;
420457 ` }
421458` ;
422-
423- const PulsingIndicator = styled ( 'div' ) `
424- ${ pulsingIndicatorStyles } ;
425- margin: 0 ${ space ( 0.5 ) } ;
426- ` ;
0 commit comments