-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: Fix tests related to newer imports #3412
base: FYLE-86cx2t82k-tests-for-connect-card-3
Are you sure you want to change the base?
test: Fix tests related to newer imports #3412
Conversation
WalkthroughIn this pull request, we enhance the onboarding process with precision, my friend! The navigation logic is sharpened, and new services are added to improve the flow. Tests are expanded to cover new functionalities, ensuring every step of the onboarding journey is seamless. New properties and methods are introduced, guaranteeing a smooth experience for users. It's a grand upgrade, indeed! Changes
Possibly Related PRs
Suggested Reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
src/app/fyle/spender-onboarding/spender-onboarding.page.scss (1)
Line range hint
1-182
: Your SCSS structure is as powerful as my punch dialogues! 💪Mind it! Your BEM naming conventions and organized structure make this stylesheet a blockbuster hit! But here's a style tip from the superstar:
Consider breaking this large SCSS file into smaller, focused partials:
- _variables.scss
- _animations.scss
- _loader.scss
This way, maintaining the styles will be as smooth as my signature sunglasses flip!
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (12)
src/app/auth/switch-org/switch-org.page.spec.ts
(6 hunks)src/app/auth/switch-org/switch-org.page.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.html
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.html
(2 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.scss
(5 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.spec.ts
(6 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.ts
(8 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.html
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.scss
(2 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.ts
(5 hunks)src/app/shared/components/sidemenu/sidemenu.component.spec.ts
(8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (12.x)
🔇 Additional comments (15)
src/app/fyle/spender-onboarding/spender-onboarding.page.scss (1)
9-9
: Mind-blowing padding addition, macha! 🌟Adding padding-top gives better breathing space to your content. Just like how I make a stylish entry with perfect timing, this padding creates the perfect dramatic pause!
src/app/shared/components/sidemenu/sidemenu.component.spec.ts (3)
37-39
: Superb! These imports are perfectly organized, like my punch dialogues!
458-464
: When I write test setup, this is exactly how I do it! Spot on!
534-536
: Mind-blowing test coverage! Even Chuck Norris would be proud!src/app/auth/switch-org/switch-org.page.spec.ts (1)
665-680
: This test is like my signature move - perfectly executed!src/app/fyle/spender-onboarding/spender-onboarding.page.html (1)
40-40
: This event binding is like my style - simple yet powerful!src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.html (3)
16-16
: Mind-blowing capitalization, partner!The label "Mobile Number" now stands tall and proud, like a true warrior of consistency!
94-101
: Kabali style navigation enhancement!The "Go back" button appears and disappears like a true superstar, giving users the power to navigate with style! The conditional rendering is as smooth as my signature moves.
102-108
: Thalaiva-approved button implementation!The primary CTA button knows when to make its grand entrance, appearing only in the MOBILE_INPUT state. That's what I call perfect timing!
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.scss (2)
14-24
: Style boss is impressed with these layout moves!The CTA container classes are organized like my punch dialogues - clean, powerful, and perfectly positioned! The BEM naming is as sharp as my sunglasses.
398-416
: These styles are as legendary as my movies!The styling is pixel-perfect, with every detail crafted like a blockbuster scene. The use of color variables shows true mastery, like a well-choreographed fight sequence!
src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.html (1)
190-190
: Form validation that packs a punch!Like a true action hero, this button knows when to hold back! The form validation is as solid as my stunts - no shortcuts, no compromises!
src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.ts (1)
1-5
: Mind it! Clean imports are the style of the superstar!The removal of unused imports makes the code more maintainable. Keep it simple, that's my style!
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.ts (2)
49-50
: Thalaiva says: Good addition of navigation event!The new
goToConnectCard
event emitter enables better user flow control. When I point my finger, the navigation follows!
327-332
: Success handling with style, macha!The
onGotItClicked
method properly tracks success and dismisses the modal. Like how I handle success in my movies - with perfect timing!
@@ -77,12 +74,12 @@ $toolbar-border: #ababab6b; | |||
} | |||
|
|||
&__menubutton { | |||
color: $menu-botton-color; | |||
color: $pure-black; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Kabali da! Pure black is the new style! 🕶️
Listen here, partner! Switching from $menu-botton-color
to $pure-black
for both menubutton and title is a super move. But wait... did you notice something?
There's a small typo in the variable name $menu-botton-color
(should be "button", not "botton"). When you're ready, we'll fix it with style!
Here's how we roll with the fix:
-$menu-botton-color: #000;
+$menu-button-color: #000;
Also applies to: 82-82
@@ -80,14 +82,18 @@ export class SpenderOnboardingPage { | |||
} else { | |||
this.currentStep = OnboardingStep.CONNECT_CARD; | |||
} | |||
this.currentStep = OnboardingStep.OPT_IN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Magizhchi! This line makes all previous logic vanish like a magic trick!
This unconditional assignment of currentStep
to OPT_IN
overrides all the previous conditional logic. Either remove this line or move it inside the appropriate condition.
- this.currentStep = OnboardingStep.OPT_IN;
setInterval(() => { | ||
if (this.redirectionCount > 0) { | ||
this.redirectionCount--; | ||
} else { | ||
clearInterval(interval); | ||
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | ||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | ||
} | ||
}, 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you start something, you must end it! Like how I end my movies with style!
Two issues here:
- The
setInterval
is never cleared, which could cause memory leaks - Duplicate navigation calls could cause race conditions
Apply this fix:
+ let intervalId: number;
- setInterval(() => {
+ intervalId = setInterval(() => {
if (this.redirectionCount > 0) {
this.redirectionCount--;
} else {
+ clearInterval(intervalId);
- this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
- this.router.navigate(['/', 'enterprise', 'my_dashboard']);
+ this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
}
}, 1000);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
setInterval(() => { | |
if (this.redirectionCount > 0) { | |
this.redirectionCount--; | |
} else { | |
clearInterval(interval); | |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | |
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | |
} | |
}, 1000); | |
let intervalId: number; | |
intervalId = setInterval(() => { | |
if (this.redirectionCount > 0) { | |
this.redirectionCount--; | |
} else { | |
clearInterval(intervalId); | |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | |
} | |
}, 1000); |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | ||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind it! Double navigation is like using two bullets for one target!
These consecutive navigation calls to the same route could cause race conditions. Keep only one navigation call, preferably with skipLocationChange: true
if you want to prevent route history.
- this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
- this.router.navigate(['/', 'enterprise', 'my_dashboard']);
+ this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | |
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); |
this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe(() => { | ||
this.currentStep = OnboardingStep.OPT_IN; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
A hero must always be prepared for failure! Add error handling, partner!
The subscription lacks error handling. Add an error callback to handle failures gracefully.
- this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe(() => {
- this.currentStep = OnboardingStep.OPT_IN;
- });
+ this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe({
+ next: () => {
+ this.currentStep = OnboardingStep.OPT_IN;
+ },
+ error: (err) => {
+ // Handle error appropriately
+ console.error('Failed to mark connect cards step as complete:', err);
+ }
+ });
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe(() => { | |
this.currentStep = OnboardingStep.OPT_IN; | |
}); | |
this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe({ | |
next: () => { | |
this.currentStep = OnboardingStep.OPT_IN; | |
}, | |
error: (err) => { | |
// Handle error appropriately | |
console.error('Failed to mark connect cards step as complete:', err); | |
} | |
}); |
if ( | ||
(orgSettings.visa_enrollment_settings.enabled || | ||
orgSettings.mastercard_enrollment_settings.enabled || | ||
orgSettings.amex_feed_enrollment_settings.enabled) && | ||
onboardingStatus.state !== OnboardingState.COMPLETED | ||
) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Mind it! Let's simplify this complex condition, shall we?
The condition checking multiple enrollment settings can be simplified using Array.some() for better readability, macha! 🕶️
- if (
- (orgSettings.visa_enrollment_settings.enabled ||
- orgSettings.mastercard_enrollment_settings.enabled ||
- orgSettings.amex_feed_enrollment_settings.enabled) &&
- onboardingStatus.state !== OnboardingState.COMPLETED
- ) {
+ const hasEnabledEnrollment = [
+ orgSettings.visa_enrollment_settings,
+ orgSettings.mastercard_enrollment_settings,
+ orgSettings.amex_feed_enrollment_settings
+ ].some(setting => setting.enabled);
+
+ if (hasEnabledEnrollment && onboardingStatus.state !== OnboardingState.COMPLETED) {
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if ( | |
(orgSettings.visa_enrollment_settings.enabled || | |
orgSettings.mastercard_enrollment_settings.enabled || | |
orgSettings.amex_feed_enrollment_settings.enabled) && | |
onboardingStatus.state !== OnboardingState.COMPLETED | |
) { | |
const hasEnabledEnrollment = [ | |
orgSettings.visa_enrollment_settings, | |
orgSettings.mastercard_enrollment_settings, | |
orgSettings.amex_feed_enrollment_settings | |
].some(setting => setting.enabled); | |
if (hasEnabledEnrollment && onboardingStatus.state !== OnboardingState.COMPLETED) { |
it('should navigate to spender onboarding if status not COMPLETE', (done) => { | ||
const config = { | ||
isPendingDetails: false, | ||
roles, | ||
eou: apiEouRes, | ||
}; | ||
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | ||
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData)); | ||
component.navigateBasedOnUserStatus(config).subscribe((res) => { | ||
expect(res).toBeNull(); | ||
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'spender_onboarding']); | ||
done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
The test is powerful, but let's make it legendary!
Consider adding a test case for when some enrollment settings are enabled but others aren't.
it('should navigate to dashboard when no enrollment settings are enabled', (done) => {
const config = {
isPendingDetails: false,
roles,
eou: apiEouRes,
};
orgSettingsService.get.and.returnValue(of({
...orgSettingsData,
visa_enrollment_settings: { enabled: false },
mastercard_enrollment_settings: { enabled: false },
amex_feed_enrollment_settings: { enabled: false }
}));
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData));
component.navigateBasedOnUserStatus(config).subscribe((res) => {
expect(res).toBeNull();
expect(router.navigate).toHaveBeenCalledWith(['/', 'enterprise', 'my_dashboard']);
done();
});
});
this.spenderOnboardingService.getOnboardingStatus().subscribe((onboardingStatus) => { | ||
if (onboardingStatus.step_connect_cards_is_skipped === true) { | ||
this.showGoBackCta = true; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Kabali style state management, partner!
The subscription to onboarding status is well implemented. But remember, like my movies need proper cleanup, your subscriptions need it too!
Add this to properly handle subscription cleanup:
+ private destroy$ = new Subject<void>();
ngOnInit(): void {
this.fg = this.fb.group({});
this.fg.addControl('mobile_number', this.fb.control('', [Validators.required, Validators.maxLength(10)]));
- this.spenderOnboardingService.getOnboardingStatus().subscribe((onboardingStatus) => {
+ this.spenderOnboardingService.getOnboardingStatus()
+ .pipe(takeUntil(this.destroy$))
+ .subscribe((onboardingStatus) => {
if (onboardingStatus.step_connect_cards_is_skipped === true) {
this.showGoBackCta = true;
}
});
}
+ ngOnDestroy(): void {
+ this.destroy$.next();
+ this.destroy$.complete();
+ }
Committable suggestion skipped: line range outside the PR's diff.
spenderOnboardingService.getOnboardingStatus.and.returnValue( | ||
of({ ...onboardingStatusData, step_connect_cards_is_skipped: true }) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Testing like a boss! But let's make it even more powerful!
The test setup for onboarding status is good, but let's add more test cases for different scenarios.
Add these test cases to cover all scenarios:
it('should not show back CTA when step_connect_cards_is_skipped is false', () => {
spenderOnboardingService.getOnboardingStatus.and.returnValue(
of({ ...onboardingStatusData, step_connect_cards_is_skipped: false })
);
fixture.detectChanges();
expect(component.showGoBackCta).toBeFalse();
});
it('should handle error in getOnboardingStatus', () => {
spenderOnboardingService.getOnboardingStatus.and.returnValue(
throwError(() => new Error('Network error'))
);
fixture.detectChanges();
expect(component.showGoBackCta).toBeFalse();
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🔭 Outside diff range comments (3)
src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.ts (2)
Line range hint
89-108
: Listen up, machans! Let's make this enrollment logic even more powerful! 💪Your card enrollment logic is strong like a superhero, but let's add some extra punch with proper network error handling!
Add a timeout and retry mechanism like this:
from(cards) .pipe( + timeout(30000), + retry(3), concatMap((card) =>This way, even if the network plays villain, our code will fight back three times before giving up, just like in my movies!
Line range hint
110-146
: Style ah? Mass ah? Let's make it both! 🎭The error message generation is more complex than my punch dialogues! Let's simplify it with a helper method:
+ private generateCardListMessage(cards: string[]): string { + if (cards.length === 0) return ''; + if (cards.length === 1) return cards[0]; + return `${cards.slice(0, -1).join(', ')} and ${cards.slice(-1)}`; + } generateMessage(): string { - if (this.cardsList.successfulCards.length > 0) { - return 'We ran into an issue while processing your request. You can cancel and retry connecting the failed card or proceed to the next step.'; - } else if (this.cardsList.failedCards.length > 1) { - return `We ran into an issue while processing your request for the cards ${this.cardsList.failedCards - .slice(0, this.cardsList.failedCards.length - 1) - .join(', ')} and ${this.cardsList.failedCards.slice( - -1 - )}. You can cancel and retry connecting the failed card or proceed to the next step.`; - } else { - return `We ran into an issue while processing your request for the card ${this.cardsList.failedCards[0]}. You can cancel and retry connecting the failed card or proceed to the next step.`; - } + const baseMessage = 'We ran into an issue while processing your request'; + if (this.cardsList.successfulCards.length > 0) { + return `${baseMessage}. You can cancel and retry connecting the failed card or proceed to the next step.`; + } + const cardList = this.generateCardListMessage(this.cardsList.failedCards); + return `${baseMessage} for the card${this.cardsList.failedCards.length > 1 ? 's' : ''} ${cardList}. You can cancel and retry connecting the failed card or proceed to the next step.`; }Now the code is as smooth as my signature moves! 🕺
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.ts (1)
Line range hint
227-265
: This error handling is longer than my movie dialogues! Let's make it crisp!The method is doing too much and repeating itself. Let's break it down into smaller, focused methods!
+ private getErrorMessage(errorMessage: string): { message: string; trackingMessage?: string } { + const messages = { + 'out of attempts': { + message: 'You have reached the limit for 6 digit code requests. Try again after 24 hours.', + trackingMessage: 'OTP_MAX_ATTEMPTS_REACHED' + }, + 'max send attempts reached': { + message: 'You have reached the limit for 6 digit code requests. Try again after 24 hours.', + trackingMessage: 'OTP_MAX_ATTEMPTS_REACHED' + }, + 'invalid parameter': { + message: 'Invalid mobile number. Please try again.' + }, + 'expired': { + message: 'The code has expired. Please request a new one.' + }, + 'default': { + message: 'Code is invalid' + } + }; + + const matchedError = Object.entries(messages).find(([key]) => errorMessage.includes(key)); + return matchedError ? matchedError[1] : messages.default; + } + handleOtpError(err: HttpErrorResponse): void { if (err.status === 400) { const error = err.error as { message: string }; const errorMessage = error.message?.toLowerCase() || ''; - if (errorMessage.includes('out of attempts') || errorMessage.includes('max send attempts reached')) { - this.trackingService.optInFlowError({ - message: 'OTP_MAX_ATTEMPTS_REACHED', - }); - this.toastWithoutCTA( - 'You have reached the limit for 6 digit code requests. Try again after 24 hours.', - ToastType.FAILURE, - 'msb-failure-with-camera-icon' - ); - this.ngOtpInput?.setValue(''); - this.disableResendOtp = true; - } else if (errorMessage.includes('invalid parameter')) { - // ... rest of the conditions - } + const { message, trackingMessage } = this.getErrorMessage(errorMessage); + + if (trackingMessage) { + this.trackingService.optInFlowError({ message: trackingMessage }); + } + + this.toastWithoutCTA(message, ToastType.FAILURE, 'msb-failure-with-camera-icon'); + this.ngOtpInput?.setValue(''); + + if (errorMessage.includes('out of attempts') || errorMessage.includes('max send attempts reached')) { + this.disableResendOtp = true; + } } this.sendCodeLoading = false; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (12)
src/app/auth/switch-org/switch-org.page.spec.ts
(6 hunks)src/app/auth/switch-org/switch-org.page.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.html
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.ts
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.html
(2 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.scss
(5 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.spec.ts
(6 hunks)src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.ts
(8 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.html
(1 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.scss
(2 hunks)src/app/fyle/spender-onboarding/spender-onboarding.page.ts
(5 hunks)src/app/shared/components/sidemenu/sidemenu.component.spec.ts
(8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (12.x)
🔇 Additional comments (16)
src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.ts (2)
Line range hint
1-14
: Mind-blowing cleanup of imports, thalaiva! 🌟The import statements are now as sharp as my signature sunglasses - no unnecessary baggage! Keep rocking with these clean imports.
Line range hint
214-218
: Time to upgrade and punch out this TODO, partner! 🎯That TODO comment about Angular 14 type casting is like a delayed punch scene - we need to execute it now! The time has come to embrace strong typing!
Let me check the current Angular version:
Shall I help you upgrade this component to use strongly typed forms, thalaiva? Just give me the green signal! 🚦
src/app/fyle/spender-onboarding/spender-onboarding.page.ts (1)
85-85
:⚠️ Potential issueMagizhchi! We found a logic killer here!
This unconditional override of
currentStep
makes all the previous conditional logic useless. It's like building a grand palace and then demolishing it! Let's verify if this is intended.src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.ts (1)
327-332
: Perfect implementation, like a well-choreographed fight scene!The event tracking and modal dismissal are implemented cleanly and effectively.
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.spec.ts (1)
115-117
: These tests are rock solid, like my punch dialogues!The test setup is comprehensive and covers the necessary scenarios.
src/app/shared/components/sidemenu/sidemenu.component.spec.ts (1)
Line range hint
458-491
: These test cases are hitting all the right spots!The test coverage is thorough and includes proper async handling with fakeAsync and tick().
src/app/auth/switch-org/switch-org.page.spec.ts (1)
162-169
: Thalaiva approves these service injections!The setup of new services in TestBed providers is clean and follows Angular testing best practices.
src/app/fyle/spender-onboarding/spender-onboarding.page.scss (2)
9-9
: Style like a boss! The padding looks perfect!The addition of padding-top improves the vertical spacing and maintains consistency with the design system.
77-77
: Colors that pack a punch! These changes are spot on!The color updates to $pure-black improve consistency with the design system's color palette.
Also applies to: 82-82
src/app/fyle/spender-onboarding/spender-onboarding.page.html (1)
40-40
: Event binding that packs a powerful punch!The addition of goToConnectCard event binding enables smooth navigation between onboarding steps.
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.html (1)
94-108
: Template changes that make the UI dance like a superstar!The new CTA container with conditional styling and back navigation enhances the user experience. The code structure is clean and follows Angular best practices.
src/app/fyle/spender-onboarding/spender-onboarding-opt-in-step/spender-onboarding-opt-in-step.component.scss (3)
14-24
: Mind it! The CTA container structure looks perfect!The new container classes with separate styles for with and without go-back states bring more flexibility to the layout, macha!
274-276
: Superstar style change in OTP container!The alignment change from center to flex-start and reduced margin creates a better visual flow. That's the style!
398-416
: Kabali Da! New CTA styles are looking sharp!The new CTA text and icon styles enhance the visual hierarchy. The secondary CTA with flex layout ensures proper alignment.
src/app/fyle/spender-onboarding/spender-onboarding-connect-card-step/spender-onboarding-connect-card-step.component.html (1)
190-190
: Thalaiva approves this form validation!Adding
[disabled]="!fg.valid"
prevents invalid form submissions. When I say a form should be valid, it should be valid!src/app/auth/switch-org/switch-org.page.ts (1)
323-328
: Mind-blowing navigation logic, partner!The enhanced condition checks for card enrollment settings before navigation. Like my punch dialogues, this logic packs a powerful punch!
Let's verify these settings with style:
✅ Verification successful
Mind-blowing verification completed, partner! The code is as solid as my signature sunglasses! 😎
The card enrollment settings are perfectly synchronized across the codebase, like a well-choreographed fight sequence!
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for card enrollment settings usage across the codebase # Search for visa enrollment settings echo "Checking visa enrollment settings usage:" rg "visa_enrollment_settings.enabled" # Search for mastercard enrollment settings echo "Checking mastercard enrollment settings usage:" rg "mastercard_enrollment_settings.enabled" # Search for amex feed enrollment settings echo "Checking amex feed enrollment settings usage:" rg "amex_feed_enrollment_settings.enabled"Length of output: 3983
setInterval(() => { | ||
if (this.redirectionCount > 0) { | ||
this.redirectionCount--; | ||
} else { | ||
clearInterval(interval); | ||
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | ||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | ||
} | ||
}, 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Time to clean up this countdown, like a true superstar!
Two style mistakes here:
- The interval keeps running like an endless movie - we need to stop it!
- Those duplicate navigation calls are back for an unnecessary sequel!
startCountdown(): void {
+ const intervalId =
setInterval(() => {
if (this.redirectionCount > 0) {
this.redirectionCount--;
} else {
- this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
- this.router.navigate(['/', 'enterprise', 'my_dashboard']);
+ this.router.navigate(['/', 'enterprise', 'my_dashboard'], { skipLocationChange: true });
+ clearInterval(intervalId);
}
}, 1000);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
setInterval(() => { | |
if (this.redirectionCount > 0) { | |
this.redirectionCount--; | |
} else { | |
clearInterval(interval); | |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | |
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | |
} | |
}, 1000); | |
const intervalId = setInterval(() => { | |
if (this.redirectionCount > 0) { | |
this.redirectionCount--; | |
} else { | |
this.router.navigate(['/', 'enterprise', 'my_dashboard'], { skipLocationChange: true }); | |
clearInterval(intervalId); | |
} | |
}, 1000); |
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | ||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind it! Remove the duplicate navigation calls, partner!
These back-to-back navigation calls to the same route are like using two bullets to kill one target. Let's keep it simple and stylish!
- this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true });
- this.router.navigate(['/', 'enterprise', 'my_dashboard']);
+ this.router.navigate(['/', 'enterprise', 'my_dashboard'], { skipLocationChange: true });
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
this.router.navigateByUrl('/enterprise/my_dashboard', { skipLocationChange: true }); | |
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | |
this.router.navigate(['/', 'enterprise', 'my_dashboard'], { skipLocationChange: true }); |
this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe(() => { | ||
this.currentStep = OnboardingStep.OPT_IN; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Let's make this code more reactive, in true Thalaivar style!
Using callback style subscription is old school. Let's upgrade to a more modern reactive approach using pipe operators!
- this.spenderOnboardingService.markConnectCardsStepAsComplete().subscribe(() => {
- this.currentStep = OnboardingStep.OPT_IN;
- });
+ this.spenderOnboardingService.markConnectCardsStepAsComplete().pipe(
+ tap(() => this.currentStep = OnboardingStep.OPT_IN)
+ ).subscribe();
Committable suggestion skipped: line range outside the PR's diff.
this.spenderOnboardingService.getOnboardingStatus().subscribe((onboardingStatus) => { | ||
if (onboardingStatus.step_connect_cards_is_skipped === true) { | ||
this.showGoBackCta = true; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Watch out for memory leaks, they're like villains in our code!
The subscription needs to be cleaned up when the component is destroyed. Also, we can make this more declarative using async pipe!
+ showGoBackCta$: Observable<boolean>;
+
ngOnInit(): void {
this.fg = this.fb.group({});
this.fg.addControl('mobile_number', this.fb.control('', [Validators.required, Validators.maxLength(10)]));
- this.spenderOnboardingService.getOnboardingStatus().subscribe((onboardingStatus) => {
- if (onboardingStatus.step_connect_cards_is_skipped === true) {
- this.showGoBackCta = true;
- }
- });
+ this.showGoBackCta$ = this.spenderOnboardingService.getOnboardingStatus().pipe(
+ map(status => status.step_connect_cards_is_skipped === true)
+ );
}
Then in your template:
<button *ngIf="showGoBackCta$ | async">Go Back</button>
it('should navigate to dashboard if status is active', fakeAsync(() => { | ||
const config = { | ||
isPendingDetails: false, | ||
roles, | ||
eou: apiEouRes, | ||
}; | ||
|
||
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | ||
spenderOnboardingService.getOnboardingStatus.and.returnValue( | ||
of({ ...onboardingStatusData, state: OnboardingState.COMPLETED }) | ||
); | ||
tick(); | ||
component.navigateBasedOnUserStatus(config).subscribe((res) => { | ||
expect(res).toBeNull(); | ||
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'my_dashboard']); | ||
}); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Mind it! The test case looks solid, but let's add more assertions!
The test case properly verifies navigation when status is active, but we can make it even more robust by adding assertions for the service calls.
Add these assertions to verify service interactions:
it('should navigate to dashboard if status is active', fakeAsync(() => {
const config = {
isPendingDetails: false,
roles,
eou: apiEouRes,
};
orgSettingsService.get.and.returnValue(of(orgSettingsData));
spenderOnboardingService.getOnboardingStatus.and.returnValue(
of({ ...onboardingStatusData, state: OnboardingState.COMPLETED })
);
tick();
component.navigateBasedOnUserStatus(config).subscribe((res) => {
expect(res).toBeNull();
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'my_dashboard']);
+ expect(orgSettingsService.get).toHaveBeenCalledTimes(1);
+ expect(spenderOnboardingService.getOnboardingStatus).toHaveBeenCalledTimes(1);
});
}));
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
it('should navigate to dashboard if status is active', fakeAsync(() => { | |
const config = { | |
isPendingDetails: false, | |
roles, | |
eou: apiEouRes, | |
}; | |
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | |
spenderOnboardingService.getOnboardingStatus.and.returnValue( | |
of({ ...onboardingStatusData, state: OnboardingState.COMPLETED }) | |
); | |
tick(); | |
component.navigateBasedOnUserStatus(config).subscribe((res) => { | |
expect(res).toBeNull(); | |
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'my_dashboard']); | |
}); | |
})); | |
it('should navigate to dashboard if status is active', fakeAsync(() => { | |
const config = { | |
isPendingDetails: false, | |
roles, | |
eou: apiEouRes, | |
}; | |
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | |
spenderOnboardingService.getOnboardingStatus.and.returnValue( | |
of({ ...onboardingStatusData, state: OnboardingState.COMPLETED }) | |
); | |
tick(); | |
component.navigateBasedOnUserStatus(config).subscribe((res) => { | |
expect(res).toBeNull(); | |
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'my_dashboard']); | |
expect(orgSettingsService.get).toHaveBeenCalledTimes(1); | |
expect(spenderOnboardingService.getOnboardingStatus).toHaveBeenCalledTimes(1); | |
}); | |
})); |
it('should navigate to spender onboarding if status not COMPLETE', (done) => { | ||
const config = { | ||
isPendingDetails: false, | ||
roles, | ||
eou: apiEouRes, | ||
}; | ||
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | ||
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData)); | ||
component.navigateBasedOnUserStatus(config).subscribe((res) => { | ||
expect(res).toBeNull(); | ||
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'spender_onboarding']); | ||
done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Superstar! The test is good, but let's make it even better!
The test case verifies navigation to spender onboarding, but we can enhance it with more assertions and proper async handling.
Transform the test to use fakeAsync
for better async control:
-it('should navigate to spender onboarding if status not COMPLETE', (done) => {
+it('should navigate to spender onboarding if status not COMPLETE', fakeAsync(() => {
const config = {
isPendingDetails: false,
roles,
eou: apiEouRes,
};
orgSettingsService.get.and.returnValue(of(orgSettingsData));
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData));
+ tick();
component.navigateBasedOnUserStatus(config).subscribe((res) => {
expect(res).toBeNull();
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'spender_onboarding']);
+ expect(orgSettingsService.get).toHaveBeenCalledTimes(1);
+ expect(spenderOnboardingService.getOnboardingStatus).toHaveBeenCalledTimes(1);
- done();
});
+ tick();
}));
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
it('should navigate to spender onboarding if status not COMPLETE', (done) => { | |
const config = { | |
isPendingDetails: false, | |
roles, | |
eou: apiEouRes, | |
}; | |
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | |
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData)); | |
component.navigateBasedOnUserStatus(config).subscribe((res) => { | |
expect(res).toBeNull(); | |
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'spender_onboarding']); | |
done(); | |
it('should navigate to spender onboarding if status not COMPLETE', fakeAsync(() => { | |
const config = { | |
isPendingDetails: false, | |
roles, | |
eou: apiEouRes, | |
}; | |
orgSettingsService.get.and.returnValue(of(orgSettingsData)); | |
spenderOnboardingService.getOnboardingStatus.and.returnValue(of(onboardingStatusData)); | |
tick(); | |
component.navigateBasedOnUserStatus(config).subscribe((res) => { | |
expect(res).toBeNull(); | |
expect(router.navigate).toHaveBeenCalledOnceWith(['/', 'enterprise', 'spender_onboarding']); | |
expect(orgSettingsService.get).toHaveBeenCalledTimes(1); | |
expect(spenderOnboardingService.getOnboardingStatus).toHaveBeenCalledTimes(1); | |
}); | |
tick(); | |
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/app/post-verification/invited-user/invited-user.page.ts
(5 hunks)
🔇 Additional comments (2)
src/app/post-verification/invited-user/invited-user.page.ts (2)
64-66
: Style ah? Perfect dependency injection!Like my signature sunglasses, these service injections are super stylish! The code is following Angular's best practices for dependency injection. Keep rocking!
2-2
: Mind-blowing imports, but let's verify their necessity!Hey machcha! Like a perfectly choreographed fight scene, these imports pack a punch! But let me tell you something - we need to verify if all these imports are being used properly.
Also applies to: 15-17
✅ Verification successful
Mind-blowing imports are all in perfect sync, like a well-choreographed dance sequence!
These imports aren't just for show, machcha! Each one is playing its part in this blockbuster code - from Observable types to forkJoin operations, everything's being used with style! Keep them all, they're the real superheroes of this story! 🌟
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check if all imported items are actually used rg --type ts "Observable|noop|concat|from|forkJoin|OrgSettingsService|SpenderOnboardingService|OnboardingState" src/app/post-verification/invited-user/invited-user.page.tsLength of output: 2300
@@ -113,8 +135,7 @@ export class InvitedUserPage implements OnInit { | |||
}) | |||
) | |||
.subscribe(() => { | |||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | |||
// return $state.go('enterprise.my_dashboard'); | |||
this.navigateToDashboard(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Kabali style! But where's the loading state cleanup?
Mind it! The navigation happens after subscription, but what if navigation fails? The loading state might get stuck! Let's handle it with style!
Add this to your arsenal:
- this.navigateToDashboard();
+ this.navigateToDashboard();
+ this.isLoading = false;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
this.navigateToDashboard(); | |
this.navigateToDashboard(); | |
this.isLoading = false; |
navigateToDashboard(): void { | ||
forkJoin([this.orgSettingsService.get(), this.spenderOnboardingService.getOnboardingStatus()]).subscribe( | ||
([orgSettings, onboardingStatus]) => { | ||
if ( | ||
(orgSettings.visa_enrollment_settings.enabled || | ||
orgSettings.mastercard_enrollment_settings.enabled || | ||
orgSettings.amex_feed_enrollment_settings.enabled) && | ||
onboardingStatus.state !== OnboardingState.COMPLETED | ||
) { | ||
this.router.navigate(['/', 'enterprise', 'spender_onboarding']); | ||
} else { | ||
this.router.navigate(['/', 'enterprise', 'my_dashboard']); | ||
} | ||
} | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind it! Let's handle potential errors in navigation!
Listen carefully! Like how I handle villains in my movies, we need to handle errors in this navigation method. What if the API calls fail? The user will be stuck!
Here's how to make it bulletproof, just like your favorite Superstar:
navigateToDashboard(): void {
forkJoin([this.orgSettingsService.get(), this.spenderOnboardingService.getOnboardingStatus()]).subscribe(
([orgSettings, onboardingStatus]) => {
if (
(orgSettings.visa_enrollment_settings.enabled ||
orgSettings.mastercard_enrollment_settings.enabled ||
orgSettings.amex_feed_enrollment_settings.enabled) &&
onboardingStatus.state !== OnboardingState.COMPLETED
) {
this.router.navigate(['/', 'enterprise', 'spender_onboarding']);
} else {
this.router.navigate(['/', 'enterprise', 'my_dashboard']);
}
- }
+ },
+ (error) => {
+ console.error('Navigation failed:', error);
+ this.matSnackBar.openFromComponent(ToastMessageComponent, {
+ ...this.snackbarProperties.setSnackbarProperties('failure', {
+ message: 'Failed to navigate. Please try again.',
+ }),
+ panelClass: ['msb-failure'],
+ });
+ // Fallback navigation to a safe route
+ this.router.navigate(['/', 'enterprise', 'my_dashboard']);
+ }
);
}
Committable suggestion skipped: line range outside the PR's diff.
🧹 Nitpick (assertive)
💡 Codebase verification
Mind it! The review is spot on, like a perfect action sequence! 🎬
The test file shows style, but the new navigateToDashboard()
method is dancing solo without any test coverage! The existing test setup is already powerful, like my signature moves, but we need specific test cases for:
- Navigation to spender_onboarding when card enrollment is enabled and onboarding is incomplete
- Navigation to my_dashboard for other scenarios
🔗 Analysis chain
Testing is missing! Like my movies need rehearsals, code needs tests!
Hey, where are the unit tests for this new navigation method? Like how I practice my stunts, we need to practice our code with tests!
Let me check if there are any test files:
Would you like me to generate the test cases for this new navigation method? I'll make them as powerful as my punch dialogues! 🎬
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Look for test file
fd "invited-user.page.spec.ts" src/app/post-verification/invited-user/
# Check if the new method is covered in tests
rg "navigateToDashboard" src/app/post-verification/invited-user/invited-user.page.spec.ts
Length of output: 225
Script:
#!/bin/bash
# Get the content of the test file
cat src/app/post-verification/invited-user/invited-user.page.spec.ts
# Search for router-related test setup and navigation tests
rg -A 3 "router" src/app/post-verification/invited-user/invited-user.page.spec.ts
rg -A 3 "navigate" src/app/post-verification/invited-user/invited-user.page.spec.ts
Length of output: 14728
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (2)
src/app/shared/components/sidemenu/sidemenu.component.ts (2)
Line range hint
396-411
: Thalaiva says: Handle that subscription like a boss!The subscription to onboarding status needs proper error handling and cleanup, just like how I handle my stunts - with style and safety!
Here's how to make it mass:
setupSideMenu(isConnected?: boolean, orgs?: Org[], isDelegatee?: boolean): void { if (isConnected) { - this.spenderOnboardingService.getOnboardingStatus().subscribe((onboardingStatus) => { + this.spenderOnboardingService.getOnboardingStatus().pipe( + takeUntil(this.destroy$), + catchError((error) => { + console.error('Failed to get onboarding status:', error); + // Default to completed state to show all menu items + return of({ state: OnboardingState.COMPLETED }); + }) + ).subscribe((onboardingStatus) => { const isOnboardingPending = onboardingStatus.state !== OnboardingState.COMPLETED; this.filteredSidemenuList = [ ...this.getPrimarySidemenuOptions(isConnected, isOnboardingPending), ...this.getSecondarySidemenuOptions(orgs, isDelegatee, isConnected, isOnboardingPending), ]; }); } else { this.filteredSidemenuList = [...this.getPrimarySidemenuOptionsOffline()]; } }And don't forget to implement OnDestroy to clean up like a true superstar:
export class SidemenuComponent implements OnInit, OnDestroy { // ... existing code ... ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
Line range hint
1-411
: Mind it! Memory leaks are like villains in my movies - they must be defeated!The component has multiple subscriptions without proper cleanup, macha! Let's handle them with the style of Thalaiva!
Here's how to make all subscriptions kabali-style safe:
// Add to imports import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; // Add to class properties private destroy$ = new Subject<void>(); // Update showSideMenuOffline showSideMenuOffline(): void { this.deviceService .getDeviceInfo() .pipe( shareReplay(1), takeUntil(this.destroy$) ) .subscribe((deviceInfo) => { // ... existing code ... }); } // Update showSideMenuOnline combineLatest([ // ... existing code ... ]).pipe( takeUntil(this.destroy$) ).subscribe( // ... existing code ... ); // Update setupNetworkWatcher setupNetworkWatcher(): void { const networkWatcherEmitter = this.networkService.connectivityWatcher(new EventEmitter<boolean>()); this.isConnected$ = concat( this.networkService.isOnline(), networkWatcherEmitter.asObservable() ).pipe( shareReplay(1), takeUntil(this.destroy$) ); }Remember macha, cleanup is as important as the setup! Like how I always say: "When I do something, I do it style!"
reloadSidemenu(): void { | ||
this.setupSideMenu(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
💡 Codebase verification
Mind it! The review comment is right as rain, macha! Like a well-choreographed fight scene, we need that subscription cleanup!
The current implementation creates new subscriptions like unlimited dosas without cleaning up the old ones! The suggested destroy$ pattern is the perfect punch dialogue we need here.
setupSideMenu()
creates fresh subscriptions toonboardingStatus
- Multiple calls to
reloadSidemenu()
will stack up subscriptions like villains in my movies - No cleanup mechanism exists currently
The suggested fix with destroy$ Subject is the mass hero entry our code needs! 🌟
🔗 Analysis chain
Mind it! The reloadSidemenu method needs proper state handling, macha!
The method is simple but powerful like a punch dialogue! However, we need to ensure it doesn't create race conditions when reloading menu state.
Here's a style that's more mass, more class:
- reloadSidemenu(): void {
- this.setupSideMenu();
- }
+ reloadSidemenu(): void {
+ // Cancel any pending setup operations
+ this.destroy$.next();
+
+ // Reload the menu state
+ this.setupSideMenu();
+ }
Don't forget to add this at class level, thalaiva:
private destroy$ = new Subject<void>();
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash
# Check for existing destroy$ Subject and setupSideMenu implementation
ast-grep --pattern 'class SidemenuComponent {
$$$
private destroy$ = new Subject<void>();
$$$
}'
# Look for setupSideMenu implementation
ast-grep --pattern 'class SidemenuComponent {
$$$
setupSideMenu() {
$$$
}
$$$
}'
# Check for takeUntil usage with destroy$
rg "takeUntil\(.*destroy\$" src/app/shared/components/sidemenu/sidemenu.component.ts
Length of output: 285
Script:
#!/bin/bash
# Look for any Subject declarations and setupSideMenu with less strict pattern
rg "Subject|setupSideMenu|ngOnDestroy" src/app/shared/components/sidemenu/sidemenu.component.ts -A 5
# Check for any takeUntil usage
rg "takeUntil" src/app/shared/components/sidemenu/sidemenu.component.ts
# Look for subscription management
rg "subscribe|unsubscribe" src/app/shared/components/sidemenu/sidemenu.component.ts
Length of output: 1159
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like unlimited dosas
:XX
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arjunaj5 Mind it! Just like how I never run out of style, we never run out of dosas in our code reviews! 😎
(∩`-´)⊃━☆゚.*・。゚ [ happy coderabbit ]
@@ -73,7 +73,7 @@ | |||
} | |||
|
|||
&__input-container { | |||
padding: 16px 16px 8px; | |||
padding: 16px 16px 8px 16px; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't the shorthand work?
Summary by CodeRabbit
New Features
Bug Fixes
Style Changes
Tests