@@ -12,9 +12,11 @@ import type RouterService from '@ember/routing/router-service';
1212import type AnalyticsEventTrackerService from 'codecrafters-frontend/services/analytics-event-tracker' ;
1313import type FeatureFlagsService from 'codecrafters-frontend/services/feature-flags' ;
1414import type LanguageModel from 'codecrafters-frontend/models/language' ;
15+ import type RepositoryModel from 'codecrafters-frontend/models/repository' ;
1516import type { ModelType } from 'codecrafters-frontend/routes/course' ;
1617import type { StepDefinition } from 'codecrafters-frontend/utils/course-page-step-list' ;
1718import type { StepStatus , StepType } from 'codecrafters-frontend/utils/course-page-step-list/step' ;
19+ import { StepListDefinition } from 'codecrafters-frontend/utils/course-page-step-list' ;
1820import * as Sentry from '@sentry/ember' ;
1921import { task } from 'ember-concurrency' ;
2022
@@ -36,6 +38,9 @@ export default class CourseController extends Controller {
3638 @tracked repo : string | undefined = undefined ;
3739 @tracked track : string | undefined = undefined ;
3840
41+ /** When set, used instead of model.activeRepository (avoids model refresh on QP change). */
42+ @tracked activeRepositoryOverride : RepositoryModel | null = null ;
43+
3944 @tracked configureGithubIntegrationModalIsOpen = false ;
4045 @tracked sidebarIsExpandedOnDesktop = true ;
4146 @tracked sidebarIsExpandedOnMobile = false ;
@@ -48,6 +53,10 @@ export default class CourseController extends Controller {
4853
4954 @tracked repositoryCreationErrorMessage : string | undefined ;
5055
56+ get activeRepository ( ) : RepositoryModel {
57+ return this . activeRepositoryOverride ?? this . model . activeRepository ;
58+ }
59+
5160 get currentUser ( ) {
5261 return this . authenticator . currentUser ;
5362 }
@@ -83,7 +92,7 @@ export default class CourseController extends Controller {
8392 this . configureGithubIntegrationModalIsOpen = true ;
8493
8594 next ( ( ) => {
86- this . router . transitionTo ( { queryParams : { action : null } } ) ; // reset param
95+ this . action = undefined ;
8796 } ) ;
8897 }
8998 }
@@ -109,20 +118,22 @@ export default class CourseController extends Controller {
109118 @action
110119 async handleLanguageSelection ( language : LanguageModel ) : Promise < boolean > {
111120 this . repositoryCreationErrorMessage = undefined ;
112- this . model . activeRepository . language = language ;
121+ this . activeRepository . language = language ;
113122
114123 try {
115- await this . model . activeRepository . save ( ) ;
124+ await this . activeRepository . save ( ) ;
116125 } catch ( error ) {
117- this . model . activeRepository . language = undefined ;
126+ this . activeRepository . language = undefined ;
118127 this . repositoryCreationErrorMessage =
119128 'Failed to create repository, please try again? Contact us at hello@codecrafters.io if this error persists.' ;
120129 Sentry . captureException ( error ) ;
121130
122131 return false ;
123132 }
124133
125- this . router . transitionTo ( { queryParams : { repo : this . model . activeRepository . id , track : null } } ) ;
134+ this . repo = this . activeRepository . id ;
135+ this . track = undefined ;
136+ this . activeRepositoryOverride = null ;
126137
127138 return true ;
128139 }
@@ -132,30 +143,71 @@ export default class CourseController extends Controller {
132143 // Nothing to do at the moment
133144 }
134145
146+ @action
147+ handleRetryWithSameLanguage ( dropdownActions : { close : ( ) => void } ) {
148+ const trackSlug = this . activeRepository . language ?. slug ?? undefined ;
149+ this . handleTryOtherLanguage ( trackSlug ?? null ) ;
150+ dropdownActions . close ( ) ;
151+ }
152+
135153 @action
136154 async handleRouteChanged ( ) {
137155 this . sidebarIsExpandedOnMobile = false ;
138156 }
139157
158+ @action
159+ handleSelectRepository ( repository : RepositoryModel , dropdownActions : { close : ( ) => void } ) {
160+ this . activeRepositoryOverride = repository ;
161+ this . repo = repository . id ;
162+ this . track = undefined ;
163+ this . coursePageState . setStepList ( new StepListDefinition ( repository ) ) ;
164+ dropdownActions . close ( ) ;
165+ }
166+
140167 @action
141168 handleToggleTestResultsBar ( ) {
142169 this . coursePageState . testResultsBarIsExpanded = ! this . coursePageState . testResultsBarIsExpanded ;
143170 }
144171
172+ @action
173+ handleTryOtherLanguage ( track : string | null ) {
174+ const course = this . model . course ;
175+ const existingNew = this . store . peekAll ( 'repository' ) . find ( ( repository ) => repository . isNew ) ;
176+
177+ let newRepository : RepositoryModel ;
178+
179+ if ( existingNew ) {
180+ ( existingNew as RepositoryModel ) . course = course ;
181+ ( existingNew as RepositoryModel ) . user = this . authenticator . currentUser ! ;
182+ newRepository = existingNew as RepositoryModel ;
183+ } else {
184+ newRepository = this . store . createRecord ( 'repository' , {
185+ course,
186+ user : this . authenticator . currentUser ,
187+ } ) as RepositoryModel ;
188+ }
189+
190+ this . activeRepositoryOverride = newRepository ;
191+ this . repo = 'new' ;
192+ this . track = track ?? undefined ;
193+ this . coursePageState . setStepList ( new StepListDefinition ( newRepository ) ) ;
194+ }
195+
145196 @action
146197 async handleWillDestroyContainer ( ) {
147198 this . teardownRouteChangeListeners ( ) ;
148199 }
149200
150201 pollRepositoryTask = task ( { keepLatest : true } , async ( ) : Promise < void > => {
151- await new RepositoryPoller ( this . model . activeRepository ) . doPoll ( ) ;
202+ await new RepositoryPoller ( this . activeRepository ) . doPoll ( ) ;
152203 } ) ;
153204
154205 @action
155206 resetController ( _controller : unknown , isExiting : boolean , _transition : unknown ) {
156207 if ( isExiting ) {
157208 this . repo = undefined ;
158209 this . track = undefined ;
210+ this . activeRepositoryOverride = null ;
159211 }
160212 }
161213
0 commit comments