Skip to content
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

feat: folder creation #1053

Merged
merged 9 commits into from
Nov 25, 2024
Merged

feat: folder creation #1053

merged 9 commits into from
Nov 25, 2024

Conversation

DhaaraniCIT
Copy link
Contributor

@DhaaraniCIT DhaaraniCIT commented Oct 30, 2024

Description

fead: folder creation

Clickup

https://app.clickup.com/t/86cwzcd5g

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced multiple new standalone components:
      • QbdDirectOnboardingPreRequisiteComponent for onboarding prerequisites with a stepper interface and dynamic loading states.
      • QbdDirectDataSyncComponent for data synchronization with clear field displays and loading indicators.
      • QbdDirectDownloadFileComponent for downloading integration files, featuring user prompts and error handling.
      • QbdDirectSetupConnectionComponent for setting up QuickBooks connections with enhanced user instructions and visibility toggles.
      • CheckboxButtonComponent for improved checkbox functionality with dynamic text updates.
    • Each component enhances user experience through improved interfaces, conditional rendering, and better onboarding processes.
  • Tests

    • Added test specifications for all new components, ensuring proper instantiation and functionality.

Copy link
Contributor

coderabbitai bot commented Oct 30, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

This pull request introduces several new components and their corresponding test specifications in an Angular application. The components include QbdDirectOnboardingPreRequisiteComponent, QbdDirectDataSyncComponent, QbdDirectDownloadFileComponent, QbdDirectSetupConnectionComponent, and CheckboxButtonComponent. Each component is standalone and features enhanced functionality for onboarding processes related to QuickBooks Desktop integration. Additionally, a service named QbdDirectConnectorService is introduced, along with its test suite. The changes enhance the application's structure by adding modular components and associated tests.

Changes

File Change Summary
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html Updated to include onboarding stepper, loader, and dynamic content for prerequisite steps.
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts Introduced QbdDirectOnboardingPreRequisiteComponent with properties for onboarding steps and state management.
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts Created a test specification file for QbdDirectOnboardingPreRequisiteComponent.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html Enhanced UI for data synchronization with loading state and dynamic field list.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts Introduced QbdDirectDataSyncComponent with input properties for data sync management.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts Created a test specification file for QbdDirectDataSyncComponent.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html Updated to manage download file interactions and user prompts.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts Introduced QbdDirectDownloadFileComponent with properties for file download management.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.spec.ts Created a test specification file for QbdDirectDownloadFileComponent.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html Enhanced UI for setup connection with dynamic instructions and loading states.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts Introduced QbdDirectSetupConnectionComponent managing connection setup states.
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts Created a test specification file for QbdDirectSetupConnectionComponent.
src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts Introduced QbdDirectConnectorService for managing API interactions related to connector settings.
src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts Created a test specification file for QbdDirectConnectorService.
src/app/shared/components/input/checkbox-button/checkbox-button.component.html Updated to include conditional rendering for checkbox states.
src/app/shared/components/input/checkbox-button/checkbox-button.component.ts Introduced CheckboxButtonComponent with properties for checkbox state management.
src/app/shared/components/input/checkbox-button/checkbox-button.component.spec.ts Created a test specification file for CheckboxButtonComponent.

Possibly related PRs

Suggested labels

size/M

Suggested reviewers

  • ashwin1111

🐇 In the code, we hop and play,
New components come to light today!
With tests to check each little part,
Our app grows strong, a work of art!
So let’s rejoice and give a cheer,
For every change that brings us near! 🎉

Warning

Rate limit exceeded

@DhaaraniCIT has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 55 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e1dc67e and dd6f7e0.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the size/M Medium PR label Oct 30, 2024
Copy link

PR title must start with "fix:", "feat:", "chore:", "refactor", or "test:" (case-insensitive)

Copy link

PR description must contain a link to a ClickUp (case-insensitive)

Copy link

PR title must start with "fix:", "feat:", "chore:", "refactor", or "test:" (case-insensitive)

Copy link

PR description must contain a link to a ClickUp (case-insensitive)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Outside diff range and nitpick comments (3)
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1)

10-12: Implement core data sync functionality.

The component is currently empty. Consider implementing:

  • Properties to track sync status and progress
  • Methods to initiate and handle sync operations
  • Error handling mechanisms
  • ngOnInit for initialization logic
  • Service injection for data operations

Example structure:

export class QbdDirectDataSyncComponent implements OnInit {
  syncStatus: 'idle' | 'syncing' | 'completed' | 'error' = 'idle';
  syncProgress = 0;
  errorMessage?: string;

  constructor(private qbdService: QbdDirectConnectorServiceTsService) {}

  ngOnInit(): void {
    // Initialize component
  }

  async startSync(): Promise<void> {
    // Implement sync logic
  }

  private handleError(error: any): void {
    // Handle errors
  }
}

Would you like me to help implement these features or create a GitHub issue to track this task?

src/app/shared/components/input/chechbox-button/chechbox-button.component.spec.ts (1)

1-4: Consider adding necessary testing utilities

Depending on the component's functionality, you might need additional testing utilities like:

  • FormsModule if the component uses forms
  • By from '@angular/platform-browser' for element querying
  • MockProvider for service dependencies
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts (1)

20-22: Enhance test coverage with additional test cases.

While the basic component creation test is good, consider adding more test cases to ensure robust component behavior:

  1. Verify component initialization state
  2. Test data synchronization functionality
  3. Test error handling scenarios
  4. Verify component interactions with QuickBooks Desktop

Would you like me to help generate additional test cases? Here's an example structure:

it('should initialize with default state', () => {
  expect(component.isLoading).toBeFalsy();
  expect(component.syncStatus).toBeUndefined();
});

it('should handle sync initiation', () => {
  // Test sync start logic
});

it('should handle sync errors gracefully', () => {
  // Test error scenarios
});

it('should update sync status correctly', () => {
  // Test status updates
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0186a44 and 6a75359.

📒 Files selected for processing (17)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts.service.spec.ts (1 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts.service.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (1 hunks)
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.html (1 hunks)
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.spec.ts (1 hunks)
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.ts (1 hunks)
✅ Files skipped from review due to trivial changes (8)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.html
🧰 Additional context used
🪛 Biome
src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts.service.ts

[error] 8-8: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (8)
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1)

1-2: Consider adding necessary imports for data sync functionality.

As a data sync component, you might need additional imports:

  • CommonModule for basic Angular directives
  • FormsModule or ReactiveFormsModule if form handling is required
  • HTTP-related imports for API communication
src/app/shared/components/input/chechbox-button/chechbox-button.component.spec.ts (1)

9-18: LGTM: Test setup follows Angular testing best practices

The test setup correctly configures TestBed with the standalone component and follows the standard Angular testing patterns.

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts (1)

9-18: LGTM! TestBed configuration follows Angular best practices.

The test setup properly configures the TestBed for a standalone component and follows the recommended async/await pattern.

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.spec.ts (2)

9-18: LGTM! Proper TestBed configuration for standalone component.

The TestBed is correctly configured using the imports array for the standalone component, following Angular's recommended testing practices.


20-22: 🛠️ Refactor suggestion

Enhance test coverage beyond basic component creation.

The current test suite only verifies component creation. Consider adding tests for:

  • Component initialization and lifecycle hooks
  • User interactions (if any UI elements exist)
  • Component methods and business logic
  • Error scenarios and edge cases
  • Input/Output bindings (if any)

Let me help verify what functionality needs testing:

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts (2)

1-3: LGTM!

The import statements are correct and include the necessary Angular testing utilities.


5-18: 🛠️ Refactor suggestion

Consider adding service dependencies to TestBed configuration.

The test setup looks good, but since this is a connection setup component, it likely needs to interact with services for handling QuickBooks Desktop connection setup. Consider adding and mocking necessary services in the TestBed configuration.

Let's check for any service dependencies:

Example structure for adding service dependencies:

beforeEach(async () => {
  await TestBed.configureTestingModule({
    imports: [QbdDirectSetupConnectionComponent],
    providers: [
      {
        provide: QbdDirectConnectorService,
        useValue: {
          // Add mock methods here
        }
      }
    ]
  }).compileComponents();
});
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts (1)

11-11: Consider adding necessary testing modules.

The current setup only imports the component itself. Depending on the component's dependencies, you might need to import additional testing modules:

Let's check the component's dependencies:

@@ -0,0 +1,12 @@
import { Component } from '@angular/core';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix typo in component name and selector

There's a typo in the component name and selector: "chechbox" should be "checkbox".

Apply these changes:

import { Component } from '@angular/core';

@Component({
-  selector: 'app-chechbox-button',
+  selector: 'app-checkbox-button',
  standalone: true,
  imports: [],
  templateUrl: './chechbox-button.component.html',
  styleUrl: './chechbox-button.component.scss'
})
-export class ChechboxButtonComponent {
+export class CheckboxButtonComponent {

Note: This will require renaming the component files as well.

Also applies to: 4-4, 10-10

Comment on lines 3 to 9
@Component({
selector: 'app-chechbox-button',
standalone: true,
imports: [],
templateUrl: './chechbox-button.component.html',
styleUrl: './chechbox-button.component.scss'
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add accessibility support

The component lacks accessibility attributes which are crucial for checkbox inputs.

Consider implementing:

  1. ARIA attributes
  2. Keyboard navigation
  3. Focus management

Example template implementation:

<div class="checkbox-container">
  <input
    type="checkbox"
    [id]="id"
    [checked]="checked"
    [disabled]="disabled"
    (change)="onValueChange($event)"
    role="checkbox"
    [attr.aria-checked]="checked"
    [attr.aria-disabled]="disabled"
  />
  <label [for]="id">
    <ng-content></ng-content>
  </label>
</div>

And add to the component:

@Input() id: string = `checkbox-${Math.random().toString(36).substr(2, 9)}`;

Comment on lines 10 to 12
export class ChechboxButtonComponent {

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Implement core checkbox functionality

The component is currently empty and missing essential checkbox functionality. Consider implementing:

  • Two-way binding for checkbox state
  • Change event handling
  • Disabled state support

Here's a suggested implementation:

+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-checkbox-button',
  standalone: true,
-  imports: [],
+  imports: [FormsModule],
  templateUrl: './chechbox-button.component.html',
  styleUrl: './chechbox-button.component.scss'
})
export class CheckboxButtonComponent {
+  @Input() checked: boolean = false;
+  @Input() disabled: boolean = false;
+  @Output() checkedChange = new EventEmitter<boolean>();
+
+  onValueChange(event: Event): void {
+    const checkbox = event.target as HTMLInputElement;
+    this.checked = checkbox.checked;
+    this.checkedChange.emit(this.checked);
+  }
}

Committable suggestion was skipped due to low confidence.

@Component({
selector: 'app-chechbox-button',
standalone: true,
imports: [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding common Angular dependencies

The component might need additional imports for common functionality.

Consider adding:

  • CommonModule for basic Angular directives
  • ReactiveFormsModule if you plan to use reactive forms
@Component({
  selector: 'app-checkbox-button',
  standalone: true,
-  imports: [],
+  imports: [
+    CommonModule,
+    FormsModule,
+    ReactiveFormsModule
+  ],
  templateUrl: './chechbox-button.component.html',
  styleUrl: './chechbox-button.component.scss'
})

Committable suggestion was skipped due to low confidence.

Comment on lines 3 to 9
@Component({
selector: 'app-qbd-direct-data-sync',
standalone: true,
imports: [],
templateUrl: './qbd-direct-data-sync.component.html',
styleUrl: './qbd-direct-data-sync.component.scss'
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add required imports to the standalone component.

The empty imports array needs to be populated with necessary dependencies:

@Component({
  selector: 'app-qbd-direct-data-sync',
  standalone: true,
-  imports: [],
+  imports: [
+    CommonModule,
+    // Add other required modules based on your data sync implementation
+  ],
  templateUrl: './qbd-direct-data-sync.component.html',
  styleUrl: './qbd-direct-data-sync.component.scss'
})

Committable suggestion was skipped due to low confidence.

Comment on lines 4 to 15
describe('QbdDirectConnectorServiceTsService', () => {
let service: QbdDirectConnectorServiceTsService;

beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(QbdDirectConnectorServiceTsService);
});

it('should be created', () => {
expect(service).toBeTruthy();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Naming inconsistency and duplicate service detected

There are two QBD Direct Connector services in the codebase with inconsistent naming:

  • QbdDirectConnectorService in qbd-direct-core/qbd-direct-connector.service.ts
  • QbdDirectConnectorServiceTsService in qbd-direct-configuration/qbd-direct-connector.service.ts.service.ts (with redundant .ts.service in filename)

Issues:

  • Duplicate service implementation with different names
  • Inconsistent file naming (.ts.service.ts)
  • Redundant "ServiceTs" and "Service" suffix in the class name
🔗 Analysis chain

Verify service class name consistency across codebase.

The service class name is quite verbose with both "Direct" and "Service" in the name. Let's verify its usage across the codebase to ensure consistency.


Let me check the actual service implementation to better understand the naming issue.


Let me check the actual implementation of the QBD Direct Connector service in the core directory to compare naming patterns.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all occurrences of the service name to verify naming consistency
echo "Searching for service class usage..."
rg -l "QbdDirectConnectorServiceTs"

# Search for similar service naming patterns
echo "Checking for similar service naming patterns..."
rg -l "ServiceTs.*Service"

Length of output: 666


Script:

#!/bin/bash
# Check the service implementation file content
cat src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts.service.ts

# Also check if there are other QBD-related services for naming pattern comparison
rg -l "qbd.*service"

Length of output: 4149


Script:

#!/bin/bash
# Check the implementation of the core connector service
cat src/app/core/services/qbd-direct/qbd-direct-core/qbd-direct-connector.service.ts

# Also check if there are any imports of these services
rg "QbdDirectConnector" -A 2 -B 2

Length of output: 4294

Comment on lines 20 to 22
it('should create', () => {
expect(component).toBeTruthy();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance test coverage with additional test cases

The current test suite only verifies component creation. Consider adding tests for:

  1. Input property bindings
  2. Output event emissions
  3. UI element interactions
  4. Component state changes
  5. Component methods and business logic

Would you like me to help generate additional test cases for comprehensive coverage?

Example test structure:

it('should emit selection change when checkbox is clicked', () => {
  // Setup
  const selectionSpy = jasmine.createSpy('selectionChange');
  component.selectionChange.subscribe(selectionSpy);
  
  // Action
  component.toggle();
  
  // Assert
  expect(selectionSpy).toHaveBeenCalled();
});

Comment on lines 1 to 23
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ChechboxButtonComponent } from './chechbox-button.component';

describe('ChechboxButtonComponent', () => {
let component: ChechboxButtonComponent;
let fixture: ComponentFixture<ChechboxButtonComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ChechboxButtonComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ChechboxButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Rename component and its files to fix the "chechbox" typo

The component files contain a spelling error that needs to be corrected. The typo appears to be isolated to the component's own directory as there are no external references to this component found in the codebase. This makes the renaming process straightforward with minimal impact.

Files to be renamed:

  • src/app/shared/components/input/chechbox-button/checkbox-button/
  • All component files within the directory need "chechbox" replaced with "checkbox"

Additionally, update all internal references:

  • Component class name to CheckboxButtonComponent
  • Component selector to app-checkbox-button
  • Import statements and references within the spec file
🔗 Analysis chain

Fix typo in component name: "chechbox" should be "checkbox"

The component name contains a spelling error that should be corrected throughout the codebase. This includes file names, class names, and import statements.

Let's verify if this typo exists in other files:


Rename component and its files to fix the "chechbox" typo

The typo "chechbox" is consistently present across multiple files in the component's directory:

  • src/app/shared/components/input/chechbox-button/chechbox-button.component.ts
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.html
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.scss
  • src/app/shared/components/input/chechbox-button/chechbox-button.component.spec.ts

Let's verify if this component is referenced elsewhere in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for files and code containing the misspelling
echo "Files with 'chechbox' in their names:"
fd "chechbox"

echo "\nCode containing 'chechbox':"
rg -i "chechbox"

Length of output: 1963


Script:

#!/bin/bash
# Search for imports or usage of the component in other files
rg -l "ChechboxButtonComponent" | grep -v "chechbox-button.component"

# Search for selector usage in templates
rg -l "app-chechbox-button" | grep -v "chechbox-button.component"

Length of output: 131

Comment on lines +20 to +22
it('should create', () => {
expect(component).toBeTruthy();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance test coverage with additional test cases.

The basic component creation test is good, but for a connection setup component, consider adding these critical test scenarios:

  1. Connection success flow
  2. Connection error handling
  3. Validation of connection parameters
  4. UI state management during connection setup
  5. Integration with QuickBooks Desktop connector service

Example test structure:

it('should handle successful connection setup', () => {
  // Test connection success scenario
});

it('should handle connection errors gracefully', () => {
  // Test error scenarios
});

it('should validate connection parameters', () => {
  // Test validation logic
});

it('should update UI state during connection process', () => {
  // Test loading states, success/error messages
});

Comment on lines 1 to 23
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { QbdDirectOnboardingPreRequisiteComponent } from './qbd-direct-onboarding-pre-requisite.component';

describe('QbdDirectOnboardingPreRequisiteComponent', () => {
let component: QbdDirectOnboardingPreRequisiteComponent;
let fixture: ComponentFixture<QbdDirectOnboardingPreRequisiteComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [QbdDirectOnboardingPreRequisiteComponent]
})
.compileComponents();

fixture = TestBed.createComponent(QbdDirectOnboardingPreRequisiteComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance test coverage with additional test scenarios.

While the basic test structure is correct, the test suite would benefit from more comprehensive coverage:

  1. Test component's lifecycle hooks (ngOnInit, ngOnDestroy)
  2. Test component's public methods and properties
  3. Test component's input/output bindings
  4. Test error scenarios and edge cases
  5. Test component's UI interactions

Here's a suggested structure to enhance the test suite:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { QbdDirectOnboardingPreRequisiteComponent } from './qbd-direct-onboarding-pre-requisite.component';

describe('QbdDirectOnboardingPreRequisiteComponent', () => {
  let component: QbdDirectOnboardingPreRequisiteComponent;
  let fixture: ComponentFixture<QbdDirectOnboardingPreRequisiteComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [QbdDirectOnboardingPreRequisiteComponent]
    }).compileComponents();

    fixture = TestBed.createComponent(QbdDirectOnboardingPreRequisiteComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  describe('Lifecycle Hooks', () => {
    it('should initialize component properties on ngOnInit', () => {
      // Test initialization logic
    });

    it('should clean up resources on ngOnDestroy', () => {
      // Test cleanup logic
    });
  });

  describe('Component Methods', () => {
    // Add tests for each public method
  });

  describe('Input/Output Bindings', () => {
    // Test @Input() properties
    // Test @Output() EventEmitter
  });

  describe('Error Handling', () => {
    // Test error scenarios
  });

  describe('UI Interactions', () => {
    // Test button clicks, form submissions, etc.
  });
});

@ashwin1111 ashwin1111 changed the title fead: folder creation feat: folder creation Nov 4, 2024
Copy link

github-actions bot commented Nov 4, 2024

PR description must contain a link to a ClickUp (case-insensitive)

Comment on lines 1 to 2
import { TestBed } from '@angular/core/testing';
import { QbdDirectConnectorServiceTsService } from './qbd-direct-connector.service.ts.service';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 @DhaaraniCIT, filename seems off

@@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filename needs fixing

Copy link

github-actions bot commented Nov 5, 2024

PR description must contain a link to a ClickUp (case-insensitive)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1)

1-12: Consider enhancing component documentation and integration.

As this is a shared component, consider the following improvements:

  1. Add JSDoc documentation describing the component's purpose, inputs, outputs, and usage examples
  2. Implement ControlValueAccessor interface for seamless integration with Angular forms
  3. Consider creating a shared form components module for better organization
  4. Add unit tests covering various states and interactions

Would you like me to help with implementing any of these suggestions or creating comprehensive test cases?

src/app/shared/components/input/checkbox-button/checkbox-button.component.spec.ts (2)

1-23: Add essential test coverage for checkbox functionality.

While the basic test setup is correct, the test suite needs additional coverage for core checkbox functionality:

it('should toggle checkbox state when clicked', () => {
  // Test state changes
});

it('should emit change event with correct value', () => {
  // Test value emission
});

it('should handle disabled state correctly', () => {
  // Test disabled behavior
});

it('should properly bind to form controls', () => {
  // Test form integration
});

1-23: Add accessibility testing.

Consider adding tests to verify accessibility requirements:

it('should have proper ARIA attributes', () => {
  const checkboxEl = fixture.debugElement.query(By.css('input[type="checkbox"]'));
  expect(checkboxEl.nativeElement.getAttribute('role')).toBe('checkbox');
  expect(checkboxEl.nativeElement.getAttribute('aria-checked')).toBeDefined();
});

it('should be keyboard accessible', () => {
  // Test keyboard interactions (space/enter)
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6a75359 and 80c9b48.

📒 Files selected for processing (5)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts (1 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.spec.ts (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html
🧰 Additional context used
🪛 Biome
src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts

[error] 8-8: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

Comment on lines 3 to 9
@Component({
selector: 'app-checkbox-button',
standalone: true,
imports: [],
templateUrl: './checkbox-button.component.html',
styleUrl: './checkbox-button.component.scss'
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add required imports and implement checkbox functionality.

The component metadata is missing essential modules required for checkbox functionality:

  • CommonModule for common directives
  • FormsModule or ReactiveFormsModule for form controls

Apply this diff to add the required imports:

 import { Component } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
 
 @Component({
   selector: 'app-checkbox-button',
   standalone: true,
-  imports: [],
+  imports: [CommonModule, FormsModule],
   templateUrl: './checkbox-button.component.html',
   styleUrl: './checkbox-button.component.scss'
 })
📝 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.

Suggested change
@Component({
selector: 'app-checkbox-button',
standalone: true,
imports: [],
templateUrl: './checkbox-button.component.html',
styleUrl: './checkbox-button.component.scss'
})
@Component({
selector: 'app-checkbox-button',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './checkbox-button.component.html',
styleUrl: './checkbox-button.component.scss'
})

Comment on lines 10 to 12
export class CheckboxButtonComponent {

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Implement core checkbox functionality and accessibility features.

The component is missing essential checkbox functionality:

  • Input properties for checked state and disabled state
  • Output event for value changes
  • Accessibility attributes

Here's a suggested implementation:

-export class CheckboxButtonComponent {
+export class CheckboxButtonComponent {
+  @Input() checked: boolean = false;
+  @Input() disabled: boolean = false;
+  @Input() label: string = '';
+  @Input() ariaLabel: string = '';
+
+  @Output() checkedChange = new EventEmitter<boolean>();
+
+  toggleChecked(): void {
+    if (!this.disabled) {
+      this.checked = !this.checked;
+      this.checkedChange.emit(this.checked);
+    }
+  }
 }

Don't forget to add the corresponding imports:

-import { Component } from '@angular/core';
+import { Component, Input, Output, EventEmitter } from '@angular/core';
📝 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.

Suggested change
export class CheckboxButtonComponent {
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
export class CheckboxButtonComponent {
@Input() checked: boolean = false;
@Input() disabled: boolean = false;
@Input() label: string = '';
@Input() ariaLabel: string = '';
@Output() checkedChange = new EventEmitter<boolean>();
toggleChecked(): void {
if (!this.disabled) {
this.checked = !this.checked;
this.checkedChange.emit(this.checked);
}
}
}

* feat: checkbox button creation

* PR comments fix

* feat: onboarding basic setup (#1055)

* feat: onboarding basic setup

* feat: qbd direct onboarding landing page (#1056)

* feat: qbd direct onboarding landing page

* feat: qbd-direct-onboarding-pre-requisite implementation

* PR comments fix

* PR fix

* updateWorkspaceOnboardingState service return type update

* qbd direct logo update

* feat: qbd-direct onboarding prerequisite UI implementation (#1058)

* feat: qbd-direct-onboarding-pre-requisite implementation

* styling changes

* unit test fix

* step footer contentt fix

* pre requisite Ui updation

* PR comments fix

* PR comments fix

* feat: Download qwd file UI changes (#1059)

* feat: Download qwd file UI changes

* download file Ui updation

* download file Ui updation

* download file Ui updation

* download file Ui updation

* feat: qbd connector setup UI changes (#1060)

* feat: qbd connector setup UI changes

* Merge branch qbd-direct-onboarding-download-file-UI into qbd-direct-step-connector-UI

* feat: Qbd direct connection data sync UI changes (#1061)

* feat: Qbd direct connection data sync UI changes

* input made required

* svg update

* feat: qbd direct pre requisite ts changes (#1062)

* feat: qbd direct pre requisite ts changes

* feat: qbd direct pre requisite ts changes

* feat: qbd direct connector download file ts changes (#1063)

* feat: qbd direct connector download file ts changes

* feat: qbd direct connector setup connector ts changes (#1064)

* feat: qbd direct connector setup connector ts changes

* feat: qbd direct connector data sync up ts changes (#1065)

* PR comment fix

* PR comment fix

* Qbd direct connector data sync up ts (#1070)

* feat: qbd direct pre requisite ts changes

* feat: qbd direct pre requisite ts changes

* feat: qbd direct connector download file ts changes

* feat: qbd direct connector setup connector ts changes

* feat: qbd direct connector data sync up ts changes

* feat: QBD direct main connection page business logic (#1066)

* feat: QBD direct main connection page business logic

* onboarding connection ts changes

* onboarding connection ts changes

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>

---------

Co-authored-by: ashwin1111 <[email protected]>
@github-actions github-actions bot added size/XL Extra Large PR and removed size/M Medium PR labels Nov 13, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 43

🧹 Outside diff range and nitpick comments (46)
src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.html (1)

3-5: LGTM! Consider adding ARIA attributes for better accessibility.

The conditional rendering of the icon is well-implemented and follows Angular best practices. The component remains flexible and reusable.

Consider adding ARIA attributes to improve accessibility:

-<div *ngIf="showIcon">
+<div *ngIf="showIcon" role="img" aria-label="Information">
     <app-svg-icon [svgSource]="'info-circle-fill-medium'" [width]="'20px'" [height]="'20px'" [styleClasses]="'tw-text-info'"></app-svg-icon>
 </div>
src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1)

Line range hint 16-18: Consider removing empty lifecycle hook.

The ngOnInit method is currently empty and can be removed along with the OnInit interface implementation since it's not being used.

-import { Component, Input, OnInit } from '@angular/core';
+import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-configuration-info-label',
  templateUrl: './configuration-info-label.component.html',
  styleUrls: ['./configuration-info-label.component.scss']
})
-export class ConfigurationInfoLabelComponent implements OnInit {
+export class ConfigurationInfoLabelComponent {
  @Input() infoText: string;
  @Input() showIcon: boolean = true;

  constructor() { }
-
-  ngOnInit(): void {
-  }
}
🧰 Tools
🪛 Biome

[error] 14-14: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

src/app/integrations/qbd-direct/qbd-direct.module.ts (1)

Line range hint 5-5: Remove unused import statement

The QbdDirectComponent is imported but not used in the module declarations. This creates unnecessary code that should be removed.

- import { QbdDirectComponent } from './qbd-direct.component';
src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (1)

28-31: Fix inconsistent indentation

The indentation in SyncDataType is inconsistent with the rest of the file. The closing brace uses 2 spaces while the rest of the file uses 4 spaces.

 export type SyncDataType = {
     attribute_type: string;
     count: null | number
-  };
+};
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.html (2)

6-6: Move SVG path construction to component

The SVG path construction logic should be handled in the component rather than in the template:

[svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'"

This would improve maintainability and allow for better error handling.


1-8: Add semantic HTML structure

The current template uses generic div elements. Consider adding semantic HTML elements and ARIA attributes to improve accessibility.

- <div>
+ <main role="main" class="qbd-onboarding-landing">
-     <div>
+     <header>
          <app-landing-page-header...></app-landing-page-header>
-     </div>
+     </header>
-     <div>
+     <section class="guide-content">
          <app-landing-page-body...></app-landing-page-body>
-     </div>
+ </section>
- </div>
+ </main>
src/app/core/models/common/helper.model.ts (2)

3-6: Consider following TypeScript best practices for type definitions

The type definition looks functionally correct, but could be improved by following TypeScript conventions:

Consider these improvements:

  1. Use an interface instead of a type alias for object definitions
  2. Follow TypeScript naming conventions (either ICheckboxUpdate for interface or checkboxUpdate for type)
  3. Consider a more descriptive name that reflects its specific use case
-export type CheckBoxUpdate = {
+export interface ICheckboxUpdate {
     id: number;
     value: boolean;
-}
+}

3-6: Consider relocating the checkbox-specific type

The CheckBoxUpdate type seems to be specifically related to checkbox functionality, yet it's placed in a general helper model file. Consider moving it to a more appropriate location:

  1. If it's specific to the CheckboxButtonComponent, consider moving it to a models file within the component's directory
  2. If it's used across multiple checkbox-related components, consider creating a dedicated checkbox models file

This would improve code organization and make the codebase more maintainable.

src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1)

1-24: Consider architectural improvements

To enhance maintainability and documentation:

  1. Add JSDoc comments to describe the service's purpose and methods
  2. Extract API endpoints to a constants file
  3. Consider adding retry logic for network failures

Example JSDoc documentation:

/**
 * Service responsible for managing QuickBooks Desktop direct integration configuration
 * and synchronization operations.
 */

For each method:

/**
 * Posts QuickBooks Desktop connector settings for the current workspace
 * @param payload - The connector configuration settings
 * @returns Observable of the saved connector settings
 */
src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1)

1-13: LGTM! Consider organizing imports.

The component is properly configured as standalone with all necessary imports.

Consider organizing imports by grouping them:

 import { CommonModule } from '@angular/common';
 import { Component, EventEmitter, Input, Output } from '@angular/core';
+
 import { ButtonModule } from 'primeng/button';
+
 import { brandingConfig } from 'src/app/branding/branding-config';
 import { CheckBoxUpdate } from 'src/app/core/models/common/helper.model';
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (2)

26-26: Add type annotation for fieldLength property.

For better type safety and code clarity, explicitly declare the type of the fieldLength property.

- fieldLength: number;
+ private fieldLength: number;

14-14: Add component documentation.

Consider adding JSDoc documentation to describe the component's purpose, usage, and input/output properties. This will improve maintainability and help other developers understand how to use this component.

+ /**
+  * Component responsible for displaying QuickBooks Direct data sync information.
+  * Shows sync fields and their status, with loading states and continuation controls.
+  *
+  * @example
+  * <app-qbd-direct-data-sync
+  *   [qbdFields]="fields"
+  *   [isLoading]="loading"
+  *   [isCTAEnabled]="enabled"
+  *   [showSection]="visible"
+  *   (continueClick)="handleContinue()">
+  * </app-qbd-direct-data-sync>
+  */
src/app/shared/components/helper/onboarding-stepper/onboarding-stepper.component.scss (2)

17-25: LGTM! Minor formatting suggestion.

The implementation follows the established pattern consistently. Consider removing the extra blank line between the nested elements to maintain consistent spacing with other step classes.

  .step-name-pre-requisite {
    &--text {
      @apply tw-relative tw-left-[-18px] ;
    }
-
    &--icon {
      @apply tw-w-24-px tw-h-24-px ;
    }
  }

17-25: Consider extracting common icon dimensions.

Several step classes use the same icon dimensions (24x24px). Consider extracting this into a shared class to reduce repetition and improve maintainability.

+ .step-icon-default {
+   @apply tw-w-24-px tw-h-24-px;
+ }
+
  .step-name-pre-requisite {
    &--text {
      @apply tw-relative tw-left-[-18px] ;
    }
    &--icon {
-     @apply tw-w-24-px tw-h-24-px ;
+     @extend .step-icon-default;
    }
  }

  .step-name-connector {
    &--text {
      @apply tw-relative tw-left-[-50px] ;
    }
    &--icon {
-     @apply tw-w-24-px tw-h-24-px ;
+     @extend .step-icon-default;
    }
  }

Also applies to: 26-73

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (1)

37-37: Consider improving brandIcon initialization

The current implementation could be more readable and maintainable.

Consider this refactor:

-  brandIcon: string;
+  readonly BRAND_ICON_PATH = 'assets';
+  readonly BRAND_ICON_FILE = 'favicon.png';
+  brandIcon: string;

   ngOnInit(): void {
-    this.brandIcon = `assets/${brandingConfig.brandId === 'co' ? 'co' : 'fyle'}/favicon.png`;
+    const brandFolder = brandingConfig.brandId === 'co' ? 'co' : 'fyle';
+    this.brandIcon = `${this.BRAND_ICON_PATH}/${brandFolder}/${this.BRAND_ICON_FILE}`;
   }

Also applies to: 46-46

src/app/shared/components/input/checkbox-button/checkbox-button.component.scss (1)

1-7: Consider improving text styles for better maintainability and responsiveness.

The current implementation has some potential issues:

  1. Hard-coded widths might cause text overflow issues
  2. Duplicate styles between checked/unchecked states
  3. Excessive use of !important flags

Consider this refactoring:

+.checkbox-text-base {
+    @apply tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color;
+}
+
 .checkedText {
-    @apply tw-w-[95px] tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
+    @extend .checkbox-text-base;
+    @apply tw-min-w-[95px] tw-max-w-fit;
 }
 
 .unCheckedText {
-    @apply tw-w-[148px] tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
+    @extend .checkbox-text-base;
+    @apply tw-min-w-[148px] tw-max-w-fit;
 }
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (2)

1-15: LGTM! Consider organizing imports by category.

The component setup follows Angular's standalone component best practices. For better maintainability, consider organizing imports into these categories:

  1. Angular core
  2. Application modules/components
  3. Third-party libraries (PrimeNG)
  4. Models/enums
 import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
 import { SharedModule } from "../../../../shared/shared.module";
 import { QbdDirectSharedComponent } from '../qbd-direct-shared.component';
+
 import { CardModule } from 'primeng/card';
-import { ConfigurationCta } from 'src/app/core/models/enum/enum.model';
-import { CommonModule } from '@angular/common';
 import { ProgressSpinnerModule } from 'primeng/progressspinner';
+
+import { ConfigurationCta } from 'src/app/core/models/enum/enum.model';

16-16: Add component documentation.

Consider adding JSDoc comments to document:

  1. The component's purpose in the QBD onboarding flow
  2. The different download scenarios (automatic vs manual)
  3. Usage examples and required parent component setup
+/**
+ * Component for handling QuickBooks Desktop file downloads during onboarding.
+ * 
+ * @description
+ * This component manages both automatic and manual download scenarios for QBD files.
+ * It provides feedback about the download status and company file path validation.
+ * 
+ * @example
+ * <app-qbd-direct-download-file
+ *   [isLoading]="loading"
+ *   [showDownloadLink]="canDownload"
+ *   [isStepCompleted]="completed"
+ *   [isCompanyPathInvalid]="invalid"
+ *   (nextStep)="handleNextStep()"
+ *   (downloadClick)="handleDownload($event)"
+ *   (retryClick)="handleRetry()"
+ *   (manualDownload)="handleManualDownload()">
+ * </app-qbd-direct-download-file>
+ */
 export class QbdDirectDownloadFileComponent {
src/app/shared/components/configuration/configuration-step-footer/configuration-step-footer.component.html (2)

1-1: Consider simplifying the complex conditional classes

The conditional class logic could be made more maintainable by:

  1. Moving the border classes to a constant in the component
  2. Making the border condition more explicit

Consider this refactor:

-<div class="tw-flex tw-py-16-px tw-px-24-px" [ngClass]="[!showBackButton ? 'tw-justify-end': 'tw-justify-between', ctaText === 'Next' ? '' : 'tw-border-t tw-border-t-border-tertiary']">
+<div class="tw-flex tw-py-16-px tw-px-24-px" 
+     [ngClass]="{
+       'tw-justify-end': !showBackButton,
+       'tw-justify-between': showBackButton,
+       'tw-border-t tw-border-t-border-tertiary': ctaText !== 'Next'
+     }">

Line range hint 18-23: Consider extracting branding-specific text formatting logic

The template contains brand-specific text casing logic that could be better handled at a service level.

Consider:

  1. Creating a text formatting service that handles brand-specific requirements
  2. Using a custom pipe or directive instead of template conditions
  3. Moving this logic out of the template to improve maintainability

Example approach:

@Pipe({
  name: 'brandText',
  standalone: true
})
export class BrandTextPipe implements PipeTransform {
  constructor(private brandingConfig: BrandingConfig) {}

  transform(value: string): string {
    return this.brandingConfig.brandId === 'co' 
      ? value.charAt(0).toUpperCase() + value.slice(1).toLowerCase()
      : value;
  }
}

Then in template:

-<span *ngIf="brandingConfig.brandId === 'co'">
-    {{ ctaText | sentenceCase}}
-</span>
-<span *ngIf="brandingConfig.brandId === 'fyle'">
-    {{ ctaText }}
-</span>
+{{ ctaText | brandText }}
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-routing.module.ts (1)

22-22: Consider using kebab-case for route paths

Angular's style guide recommends using kebab-case for URL segments. Consider changing 'pre_requisite' to 'pre-requisite' for consistency with Angular conventions.

-        path: 'pre_requisite',
+        path: 'pre-requisite',
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (3)

7-7: Consider moving complex class logic to component

The template contains complex conditional styling logic. Consider moving this to a component method for better maintainability.

-<div *ngIf="!isLoading" class="configuration--contents tw-border-border-tertiary tw-mt-24-px" [ngClass]="{'tw-mx-120-px tw-shadow-app-card': brandingConfig.brandId === 'fyle', 'tw-mx-60-px tw-shadow-shadow-level-1': brandingConfig.brandId === 'co'}">
+<div *ngIf="!isLoading" class="configuration--contents tw-border-border-tertiary tw-mt-24-px" [ngClass]="getConfigurationClass()">

Add to component:

getConfigurationClass(): Record<string, boolean> {
  return {
    'tw-mx-120-px tw-shadow-app-card': this.brandingConfig.brandId === 'fyle',
    'tw-mx-60-px tw-shadow-shadow-level-1': this.brandingConfig.brandId === 'co'
  };
}

16-36: Consider extracting step item into a separate component

The step item structure is complex and repeated. Consider extracting it into a dedicated component for better maintainability and reusability.

Example component structure:

@Component({
  selector: 'app-prerequisite-step-item',
  standalone: true,
  template: `
    <div class="tw-flex tw-items-center tw-justify-between tw-py-24-px">
      <!-- ... existing step item template ... -->
    </div>
  `
})
export class PrerequisiteStepItemComponent {
  @Input() step!: PreRequisiteStep;
  @Output() statusUpdate = new EventEmitter<boolean>();
}

38-38: Consider moving CTA text logic to component

The ternary operation for ctaText could be moved to a component method for better readability.

-<app-configuration-step-footer [ctaText]="!saveInProgress ? ConfigurationCtaText.CONTINUE : ConfigurationCtaText.SAVING" [isButtonDisabled]="isContinueDisabled" (save)="continueToNextStep()">
+<app-configuration-step-footer [ctaText]="getCtaText()" [isButtonDisabled]="isContinueDisabled" (save)="continueToNextStep()">

Add to component:

getCtaText(): string {
  return !this.saveInProgress 
    ? this.ConfigurationCtaText.CONTINUE 
    : this.ConfigurationCtaText.SAVING;
}
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html (5)

5-7: Consider making the step number dynamic

The hardcoded number "3" should be made configurable through a component property to maintain flexibility if the step sequence changes.

-                    3
+                    {{stepNumber}}

14-14: Simplify border styling logic

The border condition i < fieldLength-1 could be simplified using :not(:last-child) CSS selector for better maintainability.

-<div *ngFor="let field of qbdFields; let i = index" class="tw-flex tw-items-center tw-justify-between tw-p-14-px" [ngClass]=" i < fieldLength-1 ? 'tw-border-b tw-border-b-divider-border-color' : '' ">
+<div *ngFor="let field of qbdFields" class="tw-flex tw-items-center tw-justify-between tw-p-14-px [&:not(:last-child)]:tw-border-b [&:not(:last-child)]:tw-border-b-divider-border-color">

20-22: Improve loading icon semantics

The loading icon should use proper ARIA attributes for better accessibility.

-                    <div class="spin-icon tw-text-text-tertiary tw-font-400 tw-text-14-px">
-                        <app-svg-icon *ngIf="field.count === null" [svgSource]="'arrow-rotate-sync'" [width]="'14px'" [height]="'14px'" [isTextColorAllowed]="true" [styleClasses]="'tw-text-icon-tertiary'"></app-svg-icon>
-                    </div>
+                    <div class="spin-icon tw-text-text-tertiary tw-font-400 tw-text-14-px" *ngIf="field.count === null" role="status" aria-label="Loading count">
+                        <app-svg-icon [svgSource]="'arrow-rotate-sync'" [width]="'14px'" [height]="'14px'" [isTextColorAllowed]="true" [styleClasses]="'tw-text-icon-tertiary'"></app-svg-icon>
+                    </div>

27-27: Externalize text content for i18n

The informational text should be moved to a translation file for better maintainability and future internationalization support.

-            <app-configuration-info-label [infoText]="'The values displayed here are synced from QuickBooks Desktop to Fyle. If you notice discrepancies in the synced values, you can continue onboarding; the sync will refresh automatically in 5 minutes to capture any missed values.'" [showIcon]="false"></app-configuration-info-label>
+            <app-configuration-info-label [infoText]="'QBD_DIRECT.DATA_SYNC.INFO_TEXT' | translate" [showIcon]="false"></app-configuration-info-label>

1-37: Consider breaking down the template into smaller components

The template contains multiple logical sections (header, data display, info label, loading state, footer) that could be extracted into separate components for better maintainability and reusability. This would also make testing easier and reduce the complexity of the main component.

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.html (1)

6-11: Optimize conditional icon rendering

The current implementation has duplicate conditions and similar div structures. Consider refactoring to reduce duplication and maintain consistent icon sizes.

-    <div *ngIf="appName!==AppName.QBD_DIRECT" class="tw-p-8-px tw-bg-bg-warning-lighter tw-mr-10-px">
-        <app-svg-icon [svgSource]="'warning-outline'" [width]="'16px'" [height]="'16px'" [styleClasses]="'tw-text-icon-warning'"></app-svg-icon>
-    </div>
-    <div *ngIf="appName===AppName.QBD_DIRECT" class="tw-p-8-px tw-bg-bg-danger-lighter tw-mr-10-px">
-        <app-svg-icon [svgSource]="'danger-outline'" [width]="'18px'" [height]="'18px'" [styleClasses]="'tw-text-alert-toast'"></app-svg-icon>
-    </div>
+    <div class="tw-p-8-px tw-mr-10-px" [ngClass]="appName === AppName.QBD_DIRECT ? 'tw-bg-bg-danger-lighter' : 'tw-bg-bg-warning-lighter'">
+        <app-svg-icon 
+            [svgSource]="appName === AppName.QBD_DIRECT ? 'danger-outline' : 'warning-outline'"
+            [width]="'16px'"
+            [height]="'16px'"
+            [styleClasses]="appName === AppName.QBD_DIRECT ? 'tw-text-alert-toast' : 'tw-text-icon-warning'">
+        </app-svg-icon>
+    </div>
src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.ts (1)

93-93: Consider using strict equality instead of includes()

The use of includes() for comparing app names could lead to unintended matches if AppName.QBD_DIRECT is a substring of other app names. Consider using strict equality for more precise control:

-    if (this.appName === AppName.TRAVELPERK || this.appName === AppName.BUSINESS_CENTRAL || this.appName === AppName.BAMBOO_HR || this.appName === AppName.XERO || this.appName.includes(AppName.QBD_DIRECT)) {
+    if (this.appName === AppName.TRAVELPERK || this.appName === AppName.BUSINESS_CENTRAL || this.appName === AppName.BAMBOO_HR || this.appName === AppName.XERO || this.appName === AppName.QBD_DIRECT) {
src/app/shared/components/core/svg-icon/svg-icon.component.ts (1)

Line range hint 1-120: Consider adding icon documentation.

Since the icon set is growing, it would be beneficial to add documentation that:

  1. Lists all available icons with their visual representation
  2. Provides usage guidelines
  3. Explains the naming conventions (e.g., size suffixes)

This could be implemented as:

  • A markdown file in the component directory
  • A Storybook story showcasing all icons
  • An internal documentation page using these icons

Would you like me to help create a template for the icon documentation?

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1)

31-31: Add type safety for boolean properties.

For better type safety and maintainability, explicitly declare the types of boolean properties.

- isLoading: boolean;
+ isLoading: boolean = false;
- saveInProgress: boolean = false;
+ saveInProgress: boolean = false;
- isContinueDisabled: boolean = true;
+ isContinueDisabled: boolean = true;

Also applies to: 39-41

src/app/integrations/qbd-direct/qbd-direct.component.ts (1)

48-51: Consider separating concerns for different onboarding states

Multiple states (INCORRECT_PASSWORD, SYNC states) are mapped to the same '/connector' route. This might lead to complex conditional rendering logic in the connector component.

Consider:

  1. Creating separate routes for error states and sync states
  2. Using route parameters or query parameters to handle different states
  3. Implementing a state machine pattern for cleaner state management

Example refactor:

- [QbdDirectOnboardingState.INCORRECT_PASSWORD]: '/integrations/qbd_direct/onboarding/connector',
- [QbdDirectOnboardingState.DESTINATION_SYNC_IN_PROGRESS]: '/integrations/qbd_direct/onboarding/connector',
- [QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE]: '/integrations/qbd_direct/onboarding/connector',
+ [QbdDirectOnboardingState.INCORRECT_PASSWORD]: '/integrations/qbd_direct/onboarding/error',
+ [QbdDirectOnboardingState.DESTINATION_SYNC_IN_PROGRESS]: '/integrations/qbd_direct/onboarding/sync',
+ [QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE]: '/integrations/qbd_direct/onboarding/sync-complete',
.eslintrc.json (1)

68-68: Document the rationale for disabling the rule

Consider adding a comment explaining why this rule needs to be disabled. This helps future maintainers understand the decision and potentially re-evaluate it when the conditions change.

+        // Disabled to allow input property renaming for [specific reason]
         "@angular-eslint/no-input-rename": "off",
src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.ts (1)

38-38: Review the use of Tailwind's important modifier

The use of !tw- important modifier in the style class suggests potential CSS specificity issues. Consider refactoring the CSS architecture to avoid relying on important modifiers.

src/app/shared/shared.module.ts (1)

Line range hint 159-161: Remove duplicate component declarations

The following components are declared multiple times in the declarations array:

  • SvgIconComponent
  • NetsuiteConnectorComponent
  • NetsuiteSubsidiaryMappingComponent

This can lead to runtime errors. Each component should be declared exactly once.

    SvgIconComponent,
-   NetsuiteConnectorComponent,
-   NetsuiteSubsidiaryMappingComponent,
    ConfigurationMappingFieldsComponent,
-   SvgIconComponent,
-   NetsuiteConnectorComponent,
-   NetsuiteSubsidiaryMappingComponent,
    SearchComponent,
src/app/core/models/branding/content-configuration.model.ts (1)

9-13: Add JSDoc comments to document the preRequisite structure.

The addition of the preRequisite object follows the established pattern and aligns with the onboarding flow. Consider adding JSDoc comments to document the purpose and usage of these configuration properties.

 configuration: {
+    /**
+     * Configuration for the prerequisite step in QBD Direct onboarding
+     * @property stepName - Identifies the step in the onboarding flow
+     * @property configurationHeaderText - Main header text displayed in the prerequisite step
+     * @property configurationSubHeaderText - Supporting text displayed below the header
+     */
     preRequisite: {
         stepName: string;
         configurationHeaderText: string;
         configurationSubHeaderText: string;
     }
src/app/branding/c1-contents-config.ts (2)

9-9: Improve content text clarity and consistency.

The content text combines multiple actions with "and" which may be harder to scan. Consider breaking it into bullet points for better readability.

-            contentText: 'Import data from QuickBooks Desktop to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop',
+            contentText: [
+                'Import data from QuickBooks Desktop to ' + brandingConfig.brandName,
+                'Export expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop'
+            ].join('\n• '),

Line range hint 1-1024: Consider implementing type safety for configuration objects.

The configuration object is quite large and complex. Consider adding TypeScript interfaces to ensure type safety and better maintainability.

interface IntegrationContent {
  landing: {
    contentText: string;
    guideHeaderText: string;
  };
  configuration: {
    preRequisite?: {
      stepName: string;
      configurationHeaderText: string;
      configurationSubHeaderText: string;
    };
    connector: {
      configurationHeaderText: string;
      configurationSubHeaderText: string;
      stepName: string;
      subLabel: string;
    };
    // ... other configuration properties
  };
  // ... other properties
}

interface C1Contents {
  qbd_direct: IntegrationContent;
  netsuite: IntegrationContent;
  xero: IntegrationContent;
  intacct: IntegrationContent;
  configuration: IntegrationContent;
  // ... other properties
}

export const c1Contents: C1Contents = {
  // ... existing configuration
};
src/app/branding/fyle-contents-config.ts (2)

13-17: Improve indentation for better readability.

The indentation in the preRequisite object is inconsistent with the rest of the configuration.

Apply this diff to fix the indentation:

     preRequisite: {
-                stepName: 'Prerequisites',
-                configurationHeaderText: 'Getting started',
-                configurationSubHeaderText: 'Begin your QuickBooks integration by completing the following steps.'
-            },
+        stepName: 'Prerequisites',
+        configurationHeaderText: 'Getting started',
+        configurationSubHeaderText: 'Begin your QuickBooks integration by completing the following steps.'
+    },

Line range hint 1-1024: Consider splitting configuration into separate files per integration.

The configuration file is quite large and contains settings for multiple integrations. Consider:

  1. Creating separate files for each integration's configuration
  2. Extracting common patterns into shared interfaces
  3. Using a configuration registry pattern

This would improve:

  • Maintainability: Easier to manage changes per integration
  • Code organization: Better separation of concerns
  • Type safety: Shared interfaces ensure consistency

Example structure:

// src/app/branding/interfaces/integration-config.interface.ts
interface IntegrationConfig {
  landing: {
    contentText: string;
    guideHeaderText: string;
  };
  configuration: {
    // ... common configuration structure
  };
}

// src/app/branding/configs/qbd-direct.config.ts
export const qbdDirectConfig: IntegrationConfig = {
  // QBD specific config
};

// src/app/branding/configs/index.ts
export const fyleContents = {
  qbd_direct: qbdDirectConfig,
  // ... other imports
};
tailwind.config.js (1)

Line range hint 1134-1267: Consider organizing dimension values in strict numerical order.

While the new additions are functionally correct, the dimension values could be better organized. Consider sorting all pixel-based values numerically for better maintainability.

Example reorganization:

height: {
  '1-px': '1px',
  '2-px': '2px',
  '6-px': '6px',
  '8-px': '8px',
  '10-px': '10px',
+  // ... (other values in order)
+  '44-px': '44px',
+  '45-px': '45px',
+  '46-px': '46px',
-  '45-px': '45px',
-  '46-px': '46px',
  // ... (remaining values)
}

Also applies to: 1200-1334

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (3)

45-45: Fix typo in property name 'isDownloadfileLoading'

The property isDownloadfileLoading should be isDownloadFileLoading to maintain consistent camelCase naming conventions.

Apply this change:

- isDownloadfileLoading: boolean;
+ isDownloadFileLoading: boolean;

And update all references to this property throughout the file.


57-57: Initialize 'isCompanyPathInvalid' to 'false'

By default, the company path should not be considered invalid. Initializing isCompanyPathInvalid to true may lead to incorrect UI states.

Change the initialization:

- isCompanyPathInvalid: boolean = true;
+ isCompanyPathInvalid: boolean = false;

142-142: Simplify boolean assignment

Unnecessary use of a ternary operator for boolean assignment.

Simplify the code by directly assigning the negation:

- this.isDataSyncCTADisabled = onboardingState === QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE ? false : true;
+ this.isDataSyncCTADisabled = onboardingState !== QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE;

This enhances code readability and conciseness.

🧰 Tools
🪛 Biome

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 80c9b48 and 024398f.

⛔ Files ignored due to path filters (14)
  • src/assets/flow-charts/fyle-qbd-direct-flow-chart.svg is excluded by !**/*.svg
  • src/assets/fyle/favicon.png is excluded by !**/*.png
  • src/assets/icons/co/grv-lock.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-show-hide-medium.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-show-medium.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-upload.svg is excluded by !**/*.svg
  • src/assets/icons/download-medium.svg is excluded by !**/*.svg
  • src/assets/icons/expand.svg is excluded by !**/*.svg
  • src/assets/icons/eye-medium.svg is excluded by !**/*.svg
  • src/assets/icons/eye-slash-medium.svg is excluded by !**/*.svg
  • src/assets/icons/lock.svg is excluded by !**/*.svg
  • src/assets/icons/upload.svg is excluded by !**/*.svg
  • src/assets/logos/qbd-direct-logo.svg is excluded by !**/*.svg
  • src/assets/sprites/sprite.svg is excluded by !**/*.svg
📒 Files selected for processing (50)
  • .eslintrc.json (1 hunks)
  • src/app/branding/c1-contents-config.ts (3 hunks)
  • src/app/branding/fyle-contents-config.ts (1 hunks)
  • src/app/core/models/branding/content-configuration.model.ts (1 hunks)
  • src/app/core/models/common/helper.model.ts (1 hunks)
  • src/app/core/models/db/workspaces.model.ts (1 hunks)
  • src/app/core/models/enum/enum.model.ts (3 hunks)
  • src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (1 hunks)
  • src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.ts (1 hunks)
  • src/app/core/services/common/workspace.service.ts (2 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts (0 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-core/qbd-direct-connector.service.ts (0 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-routing.module.ts (2 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-shared.module.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct.module.ts (1 hunks)
  • src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.html (1 hunks)
  • src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (2 hunks)
  • src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.html (1 hunks)
  • src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1 hunks)
  • src/app/shared/components/configuration/configuration-step-footer/configuration-step-footer.component.html (2 hunks)
  • src/app/shared/components/core/svg-icon/svg-icon.component.ts (1 hunks)
  • src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.html (1 hunks)
  • src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.ts (1 hunks)
  • src/app/shared/components/helper/onboarding-stepper/onboarding-stepper.component.scss (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.scss (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1 hunks)
  • src/app/shared/shared.module.ts (3 hunks)
  • src/styles.scss (1 hunks)
  • tailwind.config.js (2 hunks)
💤 Files with no reviewable changes (2)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts
  • src/app/core/services/qbd-direct/qbd-direct-core/qbd-direct-connector.service.ts
✅ Files skipped from review due to trivial changes (3)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.scss
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.scss
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.scss
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html
🧰 Additional context used
🪛 Biome
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts

[error] 39-39: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (37)
src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1)

12-12: LGTM! Clean input property implementation.

The new showIcon input property follows Angular's best practices with proper type definition and a sensible default value.

src/app/integrations/qbd-direct/qbd-direct.module.ts (1)

Line range hint 7-13: Verify component declaration location

The module's declarations array is empty, and QbdDirectComponent has been removed. Please ensure this component is properly declared in another module or converted to a standalone component.

✅ Verification successful

Component is properly configured as standalone

The QbdDirectComponent has been correctly converted to a standalone component, as evidenced by:

  1. The @Component decorator explicitly sets standalone: true
  2. Required dependencies are properly imported via the imports: [RouterModule] array
  3. The test file confirms this by importing the component directly in the TestBed configuration

The empty declarations array in the module file is correct since the component is now standalone and doesn't need to be declared in any module.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify QbdDirectComponent's new declaration location

# Search for QbdDirectComponent's definition to check if it's marked as standalone
echo "Checking if component is standalone:"
ast-grep --pattern 'class QbdDirectComponent {
  $$$
}' -l ts

# Search for any module declarations of QbdDirectComponent
echo -e "\nChecking for module declarations:"
rg "declarations.*QbdDirectComponent" --type ts

Length of output: 279


Script:

#!/bin/bash
# Let's first check if the component file exists and its content
echo "Searching for QbdDirectComponent file:"
fd "qbd-direct.component" --type f

# If file exists, let's examine its content to check standalone decorator
echo -e "\nChecking component definition and decorators:"
rg -l "QbdDirectComponent" --type ts | xargs cat

# Let's also check all module files for any references to this component
echo -e "\nChecking all module files for component references:"
fd "\.module\.ts$" --type f --exec cat {}

Length of output: 144833


Script:

#!/bin/bash
# Let's check if the component is marked as standalone in its definition
echo "Checking QbdDirectComponent's standalone status:"
rg -A 5 "@Component.*QbdDirectComponent" --type ts

# Let's also check if there are any other module declarations for this component
echo -e "\nChecking for any module declarations:"
rg "declarations.*QbdDirectComponent" --type ts

Length of output: 303


Script:

#!/bin/bash
# Let's check the component file content directly
echo "Checking QbdDirectComponent file content:"
cat src/app/integrations/qbd-direct/qbd-direct.component.ts

# Let's also check the test file for any clues about the component's configuration
echo -e "\nChecking test file content:"
cat src/app/integrations/qbd-direct/qbd-direct.component.spec.ts

Length of output: 5032

src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (1)

7-17: Review security implications of exposing sensitive data in type definition

The QbdConnectorGet type includes sensitive fields like username and password. Consider:

  1. Ensuring these fields are properly encrypted in transit and at rest
  2. Implementing proper data masking when logging or displaying this type
  3. Following security best practices for handling credentials

Let's check for any potential credential exposure in logs:

✅ Verification successful

No security concerns found with credential handling

Based on the code analysis:

  1. The QbdConnectorGet type is only used in a secure manner through API services
  2. Credentials are:
    • Only transmitted via HTTPS (through apiService)
    • Not logged to console
    • Properly masked in UI (shown as asterisks by default)
  3. The password field is only displayed in a controlled setup component with proper toggling mechanism for visibility

The implementation follows security best practices for handling credentials, with proper data masking and controlled exposure.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for instances where QbdConnectorGet might be logged
rg -A 2 "console\.(log|debug|info|warn|error)" | grep -i "QbdConnectorGet"

# Search for instances where these fields might be displayed in templates
rg "password|username" --type html

Length of output: 3142


Script:

#!/bin/bash
# Let's check how QbdConnectorGet is used in the codebase
rg -A 5 "QbdConnectorGet" --type ts

# Also check for any logging or error handling related to QBD connector
rg -A 5 "qbd.*connector" --type ts | grep -i "console\|log\|error"

# Check for any API endpoints or services handling this data
ast-grep --pattern 'class $_ {
  $$$
  get$$$Connector($$$) {
    $$$
  }
  $$$
}'

Length of output: 5260

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-shared.module.ts (2)

12-16: LGTM! Correct handling of standalone components.

The module configuration correctly imports the standalone components without declaring them. The inclusion of CommonModule and SharedModule provides the necessary dependencies.


4-20: Consider optimizing the module organization.

Since all components are standalone, wrapping them in a shared module might be redundant. Consider these alternatives:

  1. If these components are truly independent, they could be directly imported where needed without the shared module.
  2. If they share common dependencies or services, consider moving the shared dependencies to a separate service module and keep the components standalone.

This would simplify the architecture and reduce the module boilerplate.

Let's verify the component dependencies and usage:

✅ Verification successful

The results show that:

  1. All components are marked as standalone: true
  2. They share some common imports (CommonModule, SharedModule)
  3. Components are only referenced in their own files, spec files, and the shared module
  4. Each component has its own specific additional imports (e.g., CardModule, ProgressSpinnerModule)

Let's verify if these components are used together or separately by checking their usage in the actual application:


Let's try a different approach to find the usage patterns and routing configuration:


Let's check the onboarding component that imports the shared module to understand how these components are actually used:


Let's check the template file to see how these components are actually used in the onboarding connector:


The shared module is indeed redundant and should be removed

The verification shows that:

  1. All components are properly configured as standalone components with their own imports
  2. The components are only used together in the QbdDirectOnboardingConnectorComponent, which already imports them through the QbdDirectSharedModule
  3. No other parts of the application use these components or the shared module
  4. The onboarding component is also standalone, so it could directly import these components

Recommendations:

  • Remove the QbdDirectSharedModule
  • Update the QbdDirectOnboardingConnectorComponent to import the three components directly:
imports: [
  QbdDirectDownloadFileComponent,
  QbdDirectSetupConnectionComponent,
  QbdDirectDataSyncComponent,
  SharedModule,
  CommonModule
]
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check component dependencies and usage patterns

# Check if components share common imports or services
for component in "qbd-direct-download-file" "qbd-direct-setup-connection" "qbd-direct-data-sync"; do
  echo "Analyzing $component dependencies:"
  rg -A 5 "constructor|@Injectable|@Component" "./src/app/integrations/qbd-direct/qbd-direct-shared/$component"
done

# Check where these components are being used
echo "Component usage patterns:"
rg -l "QbdDirectDownloadFileComponent|QbdDirectSetupConnectionComponent|QbdDirectDataSyncComponent"

Length of output: 5609


Script:

#!/bin/bash
# Check where these components are actually used in the application
rg -B 2 -A 2 "import.*QbdDirect(DownloadFile|SetupConnection|DataSync)Component" --type ts --glob '!*.spec.ts' --glob '!**/qbd-direct-shared/**'

# Check if there are any routes or lazy loading configurations
rg -B 2 -A 2 "loadComponent.*QbdDirect|path.*qbd-direct" --type ts

Length of output: 215


Script:

#!/bin/bash
# Search for any references to these components in the entire codebase
# excluding the component files themselves and their tests
rg -l "QbdDirect(DownloadFile|SetupConnection|DataSync)" \
  --type ts \
  --glob '!**/qbd-direct-shared/**/*.{ts,spec.ts}' \
  --glob '!**/*.d.ts'

# Look for routing configurations related to qbd-direct
rg -A 5 "path:.*['\"](qbd|quickbooks).*['\"]" \
  --type ts \
  --glob '!**/*.{spec,d}.ts'

# Check if the shared module itself is imported somewhere
rg -l "QbdDirectSharedModule" \
  --type ts \
  --glob '!**/qbd-direct-shared/**/*.{ts,spec.ts}'

Length of output: 1463


Script:

#!/bin/bash
# Check how the shared module is used in the onboarding component
rg -B 5 -A 10 "QbdDirectSharedModule" src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

# Check if components are used individually anywhere in the onboarding flow
rg -A 5 "@Component" src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

Length of output: 2413


Script:

#!/bin/bash
# Check the template file to see component usage
cat src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.html

# Also check if there are any other components using these standalone components directly
rg -l "<app-qbd-direct-(download-file|setup-connection|data-sync)" --type html --glob '!**/qbd-direct-shared/**'

Length of output: 3391

src/app/core/models/common/helper.model.ts (1)

3-6: Verify type usage and potential duplicates

Let's ensure consistent usage of this type and check for potential duplicate definitions.

✅ Verification successful

Based on the results, I can now generate the final response:

Type is consistently used across the codebase

The CheckBoxUpdate type is properly defined and used consistently in the codebase:

  • Used in checkbox-button component (shared/components/input/checkbox-button/checkbox-button.component.ts)
  • Implemented in QBD Direct onboarding and setup components
  • No duplicate or similar checkbox-related types found in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all potential usages of CheckBoxUpdate type
echo "=== Searching for CheckBoxUpdate type usage ==="
rg "CheckBoxUpdate" --type ts

# Look for similar checkbox-related types that might cause duplication
echo -e "\n=== Searching for similar checkbox-related types ==="
rg "type.*checkbox|interface.*checkbox" --type ts -i

# Look for similar event handling patterns
echo -e "\n=== Searching for similar checkbox event handling patterns ==="
ast-grep --pattern 'interface $_ {
  $$$
  value: boolean
  $$$
}'

Length of output: 1928

src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1)

12-15: LGTM! Constructor follows Angular DI best practices

The constructor properly injects the required services with appropriate access modifiers.

src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1)

1-33: Verify integration with parent components.

Since this component is used in the onboarding flow, ensure:

  1. Parent components handle the checkBoxUpdated event correctly
  2. The component's state reflects the onboarding progress accurately
✅ Verification successful

Component integration is properly implemented

The verification shows that:

  • The CheckBoxUpdate interface is correctly defined and used
  • Parent components properly handle the checkBoxUpdated event:
    • QbdDirectSetupConnectionComponent forwards the event through doneClick emit
    • QbdDirectOnboardingPreRequisiteComponent updates prerequisite steps state and enables/disables continue button based on checkbox states
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of this component and verify event handling
rg -t typescript "app-checkbox-button" -A 5

Length of output: 78


Script:

#!/bin/bash
# Search for usage of checkbox-button component in HTML files
rg "<app-checkbox-button"

# Search for imports of CheckboxButtonComponent
rg "CheckboxButtonComponent"

# Search for files containing checkBoxUpdated event handling
rg "checkBoxUpdated"

Length of output: 1976


Script:

#!/bin/bash
# Check the implementation of event handlers in parent components
rg -A 10 "onDoneClick\($event\)" src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts

rg -A 10 "updateConnectorStatus\($event\)" src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts

# Check the CheckBoxUpdate model definition
rg -A 5 "interface CheckBoxUpdate" src/app/core/models/common/helper.model.ts

Length of output: 405


Script:

#!/bin/bash
# Search for the files content without regex escape characters
rg -A 10 "onDoneClick" src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts

rg -A 10 "updateConnectorStatus" src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts

# Get the content of helper.model.ts
cat src/app/core/models/common/helper.model.ts

Length of output: 2249

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (2)

1-5: LGTM! All necessary imports are present.

The imports section is well-organized and includes all required dependencies for the component's functionality.


7-13: LGTM! Component decorator follows Angular best practices.

The standalone component is properly configured with necessary imports and follows Angular naming conventions.

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (3)

3-3: LGTM!

The import statement is correctly organized and the imported enum is properly utilized in the component.


35-35: LGTM!

The AppName property is correctly exposed for template usage, following Angular best practices.


25-29: ⚠️ Potential issue

Fix typo in input property name

The property name 'subLable' contains a typo and should be 'subLabel' to follow proper naming conventions.

Apply this fix:

-  @Input() subLable: string;
+  @Input() subLabel: string;
✅ Verification successful

Fix typo in input property name

The property subLable is only declared in the component file but not used in the template or anywhere else in the codebase. You can safely rename it to subLabel to follow proper naming conventions.

-  @Input() subLable: string;
+  @Input() subLabel: string;
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if this property is used in templates or other components
rg "subLable" --type html

Length of output: 25


Script:

#!/bin/bash
# Search for 'subLable' across all files to check its usage
rg "subLable" -l

# Also check template file in the same directory
fd "configuration-confirmation-dialog.component.html" --exec cat {}

Length of output: 3345

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.ts (3)

1-8: LGTM! Well-structured component setup

The component is properly configured as standalone with necessary imports and follows Angular best practices.

Also applies to: 13-16


19-29: Consider enhancing error handling for connection state

While the properties are well-structured, the isQbdConnectionInProgress flag should be properly reset in case of errors during the connection process.

Consider wrapping the connection state in a more comprehensive error handling mechanism:

-  isQbdConnectionInProgress = false;
+  private connectionState = {
+    inProgress: false,
+    error: null as Error | null
+  };

31-34: LGTM! Proper dependency injection

Dependencies are correctly injected with appropriate access modifiers.

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-routing.module.ts (1)

21-24: Verify routing sequence and consider adding route guards

The placement of the pre-requisite route between 'landing' and 'connector' suggests this sequence:

  1. landing
  2. pre-requisite
  3. connector
  4. settings
  5. done

Please verify:

  1. Is this the intended user journey sequence?
  2. Should we prevent direct URL access to these routes without completing previous steps?

Consider implementing route guards (CanActivate) to:

  • Ensure routes are accessed in the correct sequence
  • Verify authentication/authorization
  • Validate that prerequisites are met before proceeding

Example implementation:

@Injectable({
  providedIn: 'root'
})
export class OnboardingGuard implements CanActivate {
  canActivate(route: ActivatedRouteSnapshot): boolean {
    // Add logic to check if previous steps are completed
    return true;
  }
}

Then apply to routes:

{
  path: 'pre_requisite',
  component: QbdDirectOnboardingPreRequisiteComponent,
  canActivate: [OnboardingGuard]
}
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (3)

1-16: LGTM! Component setup follows Angular best practices.

The component is properly configured as standalone with appropriate imports and metadata.


35-41: LGTM! Well-structured property declarations.

Good use of TypeScript features and readonly modifier.


1-74: Verify template security for password display.

Since this component handles sensitive data (password), ensure that the template properly sanitizes the password display and implements secure password visibility toggle.

✅ Verification successful

Password handling appears secure with appropriate masking and controlled visibility

The template implementation shows secure password handling:

  • Password is masked by default, showing only last 4 characters
  • Uses Angular's built-in template interpolation which automatically escapes content
  • Proper visibility toggle mechanism with eye/eye-slash icons
  • No direct DOM manipulation of password in template

The clipboard copy implementation in the component could be improved to use the modern Clipboard API instead of document.execCommand, but this doesn't pose a security risk.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check template for potential XSS vulnerabilities in password display
rg -A 5 "password" ./src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html

# Check for other instances of password handling in the codebase
ast-grep --pattern 'password'

Length of output: 1510

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (2)

1-6: LGTM: Clean implementation of loading state

The loading state implementation follows Angular best practices with proper conditional rendering.


8-14: LGTM: Well-structured header implementation

Good use of component composition with clear input properties.

src/app/core/services/common/workspace.service.ts (2)

8-9: LGTM! Import changes align with the new functionality.

The new imports for WorkspaceOnboardingState and QbdDirectWorkspace are correctly specified and properly support the new workspace onboarding state management feature.


78-80: LGTM! Consider verifying error handling in ApiService.

The new method is well-structured with proper typing and follows service patterns. The implementation is clean and focused.

Let's verify the error handling implementation in ApiService:

✅ Verification successful

Error handling in ApiService is well-implemented and consistent

The ApiService has comprehensive error handling:

  • All HTTP methods including patch() use consistent error handling through catchError operator
  • Errors are processed through a centralized handleError method that:
    • Handles both client-side (ErrorEvent) and server-side errors
    • Includes method type and URL information for better debugging
    • Returns errors through RxJS throwError
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling implementation in ApiService
# Expected: Find error handling patterns in the ApiService patch method

# Search for ApiService implementation
ast-grep --pattern 'class ApiService {
  $$$
  patch($$$) {
    $$$
  }
  $$$
}'

# Look for error handling patterns
rg -A 5 'catch|throwError|handleError' src/app/core/services/common/api.service.ts

Length of output: 1882

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1)

1-24: LGTM! Component setup and imports are well-structured.

The component is properly configured as standalone with necessary imports and dependencies.

src/app/integrations/qbd-direct/qbd-direct.component.ts (1)

44-44: Verify the navigation flow changes

The navigation path and pre-requisite route changes indicate a new step in the onboarding flow. Please ensure that:

  1. Existing users in the middle of onboarding won't be affected
  2. The new pre-requisite step is properly integrated into the flow

Also applies to: 47-47

✅ Verification successful

Let me gather more specific information about the routing configuration and pre-requisite component.


Let me correct the command syntax and try again.


Let me try one final verification to check the routing configuration.


Based on the verification results, I can now provide a final response:

Navigation changes are properly implemented

The changes are safe because:

  • A dedicated QbdDirectOnboardingPreRequisiteComponent exists as a standalone component
  • The path change from '/integrations/qbo' to '/integrations/qbd_direct' is isolated to QBD Direct integration
  • The pre-requisite component is properly set up with necessary imports and branding content
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining references to old paths and potential conflicts
rg -l "integrations/qbo|/connector" --type ts

# Look for route definitions to verify the new pre_requisite route exists
ast-grep --pattern 'path: "pre_requisite"'

Length of output: 5158


Script:

#!/bin/bash
# Check the routing configuration in QBD Direct component
rg -A 5 "const routes.*qbd.*direct" --type ts

# Look for the pre-requisite component and its usage
fd "qbd.*pre.*requisite" --type ts --exec rg -l "component:|@Component"

Length of output: 291


Script:

#!/bin/bash
# Check the routing configuration in QBD Direct component
rg -A 5 "const routes.*qbd.*direct"

# Look for the pre-requisite component and its usage
fd -e ts "qbd.*pre.*requisite" -x rg -l "component:|@Component" {}

# Check for route configurations containing pre_requisite
rg -A 3 "path:.*pre_requisite" --type typescript

Length of output: 481


Script:

#!/bin/bash
# Check the content of the pre-requisite component to understand the routing setup
rg -A 10 "@Component|@NgModule" src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts

# Look for route definitions in the QBD direct component
rg -A 10 "const.*routes.*=|path.*:.*pre_requisite" src/app/integrations/qbd-direct/qbd-direct.component.ts

Length of output: 684

.eslintrc.json (1)

68-68: Verify the necessity of disabling no-input-rename rule

Disabling this rule could impact code maintainability by allowing inconsistencies between template bindings and component properties. Let's verify if this change is necessary for the new components.

src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.html (1)

43-46: 🛠️ Refactor suggestion

Review the string-based app name comparison approach.

The use of includes() for checking AppName.QBD_DIRECT could be fragile:

  1. It might cause false positives if QBD_DIRECT is a substring of another app name
  2. String comparison is less type-safe than direct enum comparison

Let's verify the AppName enum structure and usage:

Consider these improvements:

  1. Use direct enum comparison instead of includes():
-appName.includes(AppName.QBD_DIRECT)
+appName === AppName.QBD_DIRECT
  1. Extract the condition into a component method for better maintainability:
get showConnectButton(): boolean {
  return !this.isIntegrationConnected && 
    [AppName.QBD, AppName.NETSUITE, AppName.INTACCT, 
     AppName.SAGE300, AppName.BUSINESS_CENTRAL, 
     AppName.QBD_DIRECT].includes(this.appName);
}
  1. Add a default value for buttonText to ensure graceful fallback:
get buttonText(): string {
  return this.customButtonText || 'Connect';
}
src/app/shared/shared.module.ts (2)

Line range hint 1-1: Clarify PR objective vs implementation

The PR objective mentions "folder creation" but the changes appear to be related to adding a checkbox button component for QuickBooks onboarding. Please update the PR description to accurately reflect the changes being made.

#!/bin/bash
# Search for folder-related changes that might be missing from this PR
rg -g '!node_modules' -l 'folder|directory|dir' --type ts --type html

95-95: Verify standalone component configuration

The CheckboxButtonComponent is imported and added to the imports array, suggesting it's a standalone component. This is the correct setup for standalone components in Angular, but please ensure that:

  1. The component is properly decorated with @Component({ standalone: true })
  2. All its dependencies are properly imported in the component itself

Also applies to: 196-196, 272-272

✅ Verification successful

Standalone component setup is correctly configured

The CheckboxButtonComponent is properly configured as a standalone component:

  1. It has the @Component({ standalone: true }) decorator
  2. Required dependencies (ButtonModule, CommonModule) are imported in the component itself
  3. It's correctly registered in the SharedModule's imports array and exports array
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if CheckboxButtonComponent is properly configured as standalone
ast-grep --pattern 'Component({
  standalone: true,
  $$$
})
class CheckboxButtonComponent' src/app/shared/components/input/checkbox-button/checkbox-button.component.ts

Length of output: 20831


Script:

#!/bin/bash
# Let's check the CheckboxButtonComponent file content to verify its configuration
rg -g 'checkbox-button.component.ts' -l ''

Length of output: 119


Script:

#!/bin/bash
# Let's check if the component is registered in declarations array
ast-grep --pattern 'declarations: [
  $$$
  CheckboxButtonComponent,
  $$$
]' src/app/shared/shared.module.ts

Length of output: 111


Script:

#!/bin/bash
# Let's check if the component is registered in imports array
ast-grep --pattern 'imports: [
  $$$
  CheckboxButtonComponent,
  $$$
]' src/app/shared/shared.module.ts

Length of output: 106


Script:

#!/bin/bash
# Let's check if the component is registered in exports array
ast-grep --pattern 'exports: [
  $$$
  CheckboxButtonComponent,
  $$$
]' src/app/shared/shared.module.ts

Length of output: 106


Script:

#!/bin/bash
# Let's check the content of the CheckboxButtonComponent file
cat src/app/shared/components/input/checkbox-button/checkbox-button.component.ts

Length of output: 1165


Script:

#!/bin/bash
# Let's check the shared module content to see the arrays configuration
cat src/app/shared/shared.module.ts

Length of output: 14941

src/app/core/models/enum/enum.model.ts (2)

351-352: LGTM! Configuration CTA values added

The new CTA values follow consistent naming patterns and represent common UI actions.


888-891: LGTM! QBDPreRequisiteState enum is well-defined

The enum provides clear states for tracking prerequisite completion status.

src/styles.scss (1)

493-495: LGTM! The new spinner class follows established patterns.

The implementation of .spinner-30 is clean, consistent with existing spinner classes, and properly utilizes the spinner mixin.

src/app/branding/c1-contents-config.ts (3)

13-17: LGTM! Clear and well-structured prerequisites section.

The prerequisites section is well-organized with clear step name, header text, and subheader text that guides users through the initial setup process.


81-81: Consistent use of brandingConfig.brandName in text content.

Good use of dynamic branding in the customization and auto-create merchants text. This ensures consistent branding throughout the application.

Also applies to: 96-96


19-21: ⚠️ Potential issue

Inconsistent subLabel content.

The subLabel property still references NetSuite instead of QuickBooks Desktop, which appears to be an oversight.

-                subLabel: 'Provide your credentials to establish a secure connection between your Expense Management and NetSuite account'
+                subLabel: 'Provide your credentials to establish a secure connection between your Expense Management and QuickBooks Desktop account'

Likely invalid or redundant comment.

tailwind.config.js (1)

1134-1134: LGTM! The new dimension values maintain consistency.

The addition of '45-px' to both height and width configurations follows the established patterns and naming conventions.

Also applies to: 1200-1200

Comment on lines +11 to +13
export type WorkspaceOnboardingState = {
onboarding_state: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

🛠️ Refactor suggestion

Consider using a union type of specific onboarding states

The onboarding_state property should be constrained to valid states based on the integration type. For example:

export type WorkspaceOnboardingState = {
  onboarding_state: IntacctOnboardingState | QBOOnboardingState | XeroOnboardingState | NetsuiteOnboardingState | Sage300OnboardingState | QBDOnboardingState | QbdDirectOnboardingState | BusinessCentralOnboardingState | TravelPerkOnboardingState;
}

This provides type safety by ensuring only valid onboarding states can be assigned based on the integration being used.

🔗 Analysis chain

Consider using a union type or enum for better type safety

The onboarding_state property using a plain string type is too permissive and could lead to runtime errors if invalid states are used. Consider:

  1. Using a union type or enum to explicitly define valid states
  2. Adding documentation to describe the purpose and valid states

Here's a suggested improvement:

+/**
+ * Represents the onboarding progress state of a workspace
+ * Used in QuickBooks integration flow to track setup progress
+ */
+export type OnboardingState = 
+  | 'NOT_STARTED'
+  | 'FOLDER_SETUP'
+  | 'CONNECTION_IN_PROGRESS'
+  | 'COMPLETED';
+
 export type WorkspaceOnboardingState = {
-  onboarding_state: string;
+  onboarding_state: OnboardingState;
 }

Let's verify the current usage of onboarding states:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for string literals being assigned to onboarding_state
# to understand current valid states and ensure we don't miss any
rg -g '*.ts' -g '*.html' "onboarding_state.*['\"].*['\"]"

Length of output: 1036


Script:

#!/bin/bash
# Let's check for any enum or type definitions related to onboarding states
ast-grep --pattern 'enum $_ {
  $$$
}'

# Also check for any union type definitions
ast-grep --pattern 'type $_ = $$$'

# And let's see the full context of the workspaces model file
cat src/app/core/models/db/workspaces.model.ts

Length of output: 335454


Script:

#!/bin/bash
# Let's check for all the places where onboarding_state is being used to understand valid states
rg -g '*.ts' "onboarding_state.*=.*" -A 2 -B 2

Length of output: 9793


Script:

#!/bin/bash
# Let's check for any enum definitions of onboarding states
rg -g '*.ts' "enum.*OnboardingState" -A 10

Length of output: 6278

<p>qbd-direct-onboarding-landing works!</p>
<div>
<div>
<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Move hardcoded strings to constants and standardize quotes

The header section contains several hardcoded values that should be moved to constants:

  • Button text "Start"
  • Icon path "assets/logos/qbo.png"
  • Integration name "QuickBooks Desktop - Direct Integration"

Also, there's inconsistent usage of single and double quotes which should be standardized.

- <app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'"
+ <app-landing-page-header [buttonText]="constants.START_BUTTON_TEXT" [iconPath]="constants.QBD_ICON_PATH" [appName]="constants.QBD_INTEGRATION_NAME"

Committable suggestion skipped: line range outside the PR's diff.


💡 Codebase verification

⚠️ Potential issue

Use QuickBooks Desktop icon instead of QBO icon

The codebase has dedicated QuickBooks Desktop icons available at:

  • assets/logos/quickbooks-desktop.svg
  • assets/logos/qbd-direct-logo.svg

Please update the iconPath in the landing page header to use the QuickBooks Desktop icon instead of the QBO icon (assets/logos/qbo.png).

🔗 Analysis chain

Verify QBO icon usage in QBD integration

The template is using a QBO (QuickBooks Online) icon for what appears to be a QBD (QuickBooks Desktop) integration. This seems incorrect and might confuse users.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there's a dedicated QBD icon
fd "qbd" assets/logos

Length of output: 121


Script:

#!/bin/bash
# Let's first check if we can find the assets directory and any logo files
fd "logos"

# Also search for any QBD or QuickBooks related assets
fd "quickbooks|qb[od]" -I

Length of output: 42772


Script:

#!/bin/bash
# Let's check the contents of the logos directory to see available icons
ls -la src/assets/logos/

# Also check if there's a dedicated QBD icon in other image formats
fd "quickbooks-desktop|qbd" src/assets/logos

Length of output: 1745

<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
</div>
<div>
<app-landing-page-body [headlineText]="brandingContent.guideHeaderText" [headerText]="'A quick guide to help you set up your QuickBooks Online integration.'" [embedVideo]="embedVideoLink" [embedImage]="'assets/co/coQBOLanding.svg'" [svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'" [appName]="appName"></app-landing-page-body>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix inconsistent product naming in guide header

The header text mentions "QuickBooks Online integration" but this is a QuickBooks Desktop component. This inconsistency could confuse users.

- [headerText]="'A quick guide to help you set up your QuickBooks Online integration.'"
+ [headerText]="'A quick guide to help you set up your QuickBooks Desktop integration.'"
📝 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.

Suggested change
<app-landing-page-body [headlineText]="brandingContent.guideHeaderText" [headerText]="'A quick guide to help you set up your QuickBooks Online integration.'" [embedVideo]="embedVideoLink" [embedImage]="'assets/co/coQBOLanding.svg'" [svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'" [appName]="appName"></app-landing-page-body>
<app-landing-page-body [headlineText]="brandingContent.guideHeaderText" [headerText]="'A quick guide to help you set up your QuickBooks Desktop integration.'" [embedVideo]="embedVideoLink" [embedImage]="'assets/co/coQBOLanding.svg'" [svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'" [appName]="appName"></app-landing-page-body>

Comment on lines +21 to +23
syncAttribuites(): Observable<SyncDataType[]> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix method name typo and improve implementation

The current implementation has several issues:

  1. Method name has a typo ('Attribuites' should be 'Attributes')
  2. Empty object parameter is unnecessary
  3. Missing error handling

Here's the suggested implementation:

-  syncAttribuites(): Observable<SyncDataType[]> {
-    return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
+  syncAttributes(): Observable<SyncDataType[]> {
+    return this.apiService.get(
+      `/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`
+    ).pipe(
+      catchError((error: any) => {
+        console.error('Error fetching QBD attribute stats:', error);
+        throw error;
+      })
+    );
   }
📝 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.

Suggested change
syncAttribuites(): Observable<SyncDataType[]> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
}
syncAttributes(): Observable<SyncDataType[]> {
return this.apiService.get(
`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`
).pipe(
catchError((error: any) => {
console.error('Error fetching QBD attribute stats:', error);
throw error;
})
);
}

Comment on lines +17 to +19
postQbdDirectConntion(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, payload);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and fix method name

While the implementation is functional, consider these improvements:

  1. Rename the method to postQbdDirectConnection
  2. Add error handling for failed API requests

Here's the suggested implementation:

-  postQbdDirectConntion(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
-    return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, payload);
+  postQbdDirectConnection(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
+    return this.apiService.post(
+      `/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`,
+      payload
+    ).pipe(
+      catchError((error: any) => {
+        console.error('Error posting QBD connector settings:', error);
+        throw error;
+      })
+    );
   }
📝 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.

Suggested change
postQbdDirectConntion(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, payload);
}
postQbdDirectConnection(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
return this.apiService.post(
`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`,
payload
).pipe(
catchError((error: any) => {
console.error('Error posting QBD connector settings:', error);
throw error;
})
);
}


@Component({
selector: 'app-qbd-direct-onboarding-connector',
standalone: true,
imports: [],
imports: [QbdDirectSharedModule, SharedModule, CommonModule],
templateUrl: './qbd-direct-onboarding-connector.component.html',
styleUrl: './qbd-direct-onboarding-connector.component.scss'
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the property name 'styleUrl' to 'styleUrls'

The Component decorator property should be styleUrls (plural) instead of styleUrl to properly apply styles to the component.

Apply this diff to fix the property name:

- styleUrl: './qbd-direct-onboarding-connector.component.scss'
+ styleUrls: ['./qbd-direct-onboarding-connector.component.scss']

Committable suggestion skipped: line range outside the PR's diff.

this.isCompanyPathInvalid = filePathRegex.test(normalizedPath);
if (this.isCompanyPathInvalid) {
this.isDownloadfileLoading = true;
this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct typo in method name 'postQbdDirectConntion'

The method name postQbdDirectConntion has a typo. It should be postQbdDirectConnection.

Apply this diff to fix the method name:

- this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {
+ this.qbdDirectConnectorService.postQbdDirectConnection({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {

Ensure that the QbdDirectConnectorService has the method postQbdDirectConnection implemented.

Committable suggestion skipped: line range outside the PR's diff.


handleDataSyncState(status: QbdDirectWorkspace) {
const onboardingState = status.onboarding_state;
this.qbdDirectConnectorService.syncAttribuites().subscribe((qbdAttribuites: SyncDataType[]) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct typo in method name 'syncAttribuites'

The method syncAttribuites has a typo and should be syncAttributes.

Apply this correction:

- this.qbdDirectConnectorService.syncAttribuites().subscribe((qbdAttribuites: SyncDataType[]) => {
+ this.qbdDirectConnectorService.syncAttributes().subscribe((qbdAttributes: SyncDataType[]) => {

Ensure that the service method and variable names are updated accordingly.

Committable suggestion skipped: line range outside the PR's diff.


brandingContent = brandingContent.qbd_direct.configuration.connector;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid variable shadowing for 'brandingContent'

Assigning the class property brandingContent with the imported brandingContent can lead to confusion due to variable shadowing.

Consider renaming the imported variable or the class property to avoid shadowing. For example:

- brandingContent = brandingContent.qbd_direct.configuration.connector;
+ brandingContent = importedBrandingContent.qbd_direct.configuration.connector;

And adjust the import accordingly:

- import { brandingConfig, brandingContent, brandingKbArticles } from 'src/app/branding/branding-config';
+ import { brandingConfig, brandingContent as importedBrandingContent, brandingKbArticles } from 'src/app/branding/branding-config';

Committable suggestion skipped: line range outside the PR's diff.


redirectLink: string = brandingKbArticles.onboardingArticles.QBD_DIRECT.CONNECTOR;

brandingConfig: BrandingConfiguration = brandingConfig;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid variable shadowing for 'brandingConfig'

Similarly, assigning brandingConfig to itself may cause confusion. Variable shadowing can lead to unexpected behaviors.

Rename the imported brandingConfig or the class property:

- brandingConfig: BrandingConfiguration = brandingConfig;
+ brandingConfig: BrandingConfiguration = importedBrandingConfig;

And update the import statement:

- import { brandingConfig, brandingContent, brandingKbArticles } from 'src/app/branding/branding-config';
+ import { brandingConfig as importedBrandingConfig, brandingContent, brandingKbArticles } from 'src/app/branding/branding-config';

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 42

🧹 Outside diff range and nitpick comments (51)
src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.html (1)

3-5: LGTM! Consider adding ARIA attributes for better accessibility.

The conditional rendering of the icon is well-implemented and provides good component flexibility.

Consider enhancing accessibility by adding appropriate ARIA attributes:

-        <div *ngIf="showIcon">
+        <div *ngIf="showIcon" role="img" aria-label="Information">
             <app-svg-icon [svgSource]="'info-circle-fill-medium'" [width]="'20px'" [height]="'20px'" [styleClasses]="'tw-text-info'"></app-svg-icon>
         </div>
src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1)

12-12: Consider adding JSDoc documentation for the input property.

Adding documentation would improve code maintainability by clearly describing the purpose and usage of the showIcon property.

+  /**
+   * Controls the visibility of the information icon
+   * @default true
+   */
   @Input() showIcon: boolean = true;
src/app/integrations/qbd-direct/qbd-direct.module.ts (1)

Line range hint 5-5: Remove unused import statement

The QbdDirectComponent is imported but not used in the module. This aligns with the changes mentioned in the summary where it was removed from the imports array.

-import { QbdDirectComponent } from './qbd-direct.component';
src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (1)

28-31: Fix indentation for consistency

The indentation of this type definition differs from others in the file.

 export type SyncDataType = {
     attribute_type: string;
     count: null | number
-  };
+};
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.html (1)

1-2: Enhance structure with semantic HTML and styling classes.

The current structure uses generic div elements without proper styling or semantic meaning. Consider using semantic HTML elements and Tailwind classes for better accessibility and maintainability.

-<div>
-    <div>
+<main class="tw-container tw-mx-auto">
+    <header class="tw-mb-6">
         <app-landing-page-header ...></app-landing-page-header>
-    </div>
-    <div>
+    </header>
+    <section class="tw-mb-6">
         <app-landing-page-body ...></app-landing-page-body>
-    </div>
-</div>
+    </section>
+</main>

Also applies to: 4-5, 7-8

src/app/core/models/common/helper.model.ts (2)

3-6: Consider a more specific type name and add documentation.

While the type structure is correct, consider:

  1. Renaming to something more specific like CheckboxStateUpdate or OnboardingCheckboxUpdate to better reflect its purpose
  2. Adding JSDoc comments to document the type's purpose and properties
+/**
+ * Represents a checkbox state update event
+ * @property id - Unique identifier of the checkbox
+ * @property value - New state of the checkbox
+ */
 export type CheckBoxUpdate = {
     id: number;
     value: boolean;
 }

Line range hint 9-24: Consider refactoring the existing utility methods.

While not part of the current changes, there are opportunities to improve the existing code:

  1. The "temporary hack" comment suggests technical debt that should be addressed
  2. Consider using an enum or constant array for the excluded field names
  3. The method name markControllerAsRequired should be markControlAsRequired to match Angular terminology

Example refactor:

export const PRESERVED_FORM_FIELDS = [
  'accountsPayable',
  'defaultCCCAccount',
  'bankAccount',
  'creditCardAccount',
  'defaultCreditCardVendor',
  'nameInJournalEntry',
  'exportScheduleFrequency'
] as const;

export class HelperUtility {
  static markControlAsRequired(form: FormGroup, controlName: string): void {
    form.controls[controlName].setValidators(Validators.required);
  }

  static clearValidatorAndResetValue(form: FormGroup, controlName: string): void {
    form.controls[controlName].clearValidators();
    
    if (!PRESERVED_FORM_FIELDS.includes(controlName)) {
      form.controls[controlName].setValue(null);
    }
  }
}
src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1)

17-19: Consider adding input validation for the payload

While the implementation is correct, consider adding input validation for the payload before making the API call to ensure data integrity and provide better error messages.

Example implementation:

 postQbdDirectConntion(payload: QbdConnectorPost): Observable<QbdConnectorGet> {
+  if (!payload || !this.isValidPayload(payload)) {
+    throw new Error('Invalid QBD connector configuration payload');
+  }
   return this.apiService.post(`/workspaces/${this.workspaceService.getWorkspaceId()}/connector_settings/`, payload);
 }

+ private isValidPayload(payload: QbdConnectorPost): boolean {
+   // Add validation logic based on your requirements
+   return true;
+ }
src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1)

14-27: Enhance accessibility and type safety.

While the core functionality is well implemented, consider these improvements:

  1. Add aria attributes for better screen reader support
  2. Add proper type for brandingConfig instead of implicit any

Apply this diff:

 export class CheckboxButtonComponent {
+  // Add proper type for brandingConfig
+  brandingConfig: BrandingConfig = brandingConfig;
 
   @Input({required: true}) unCheckedText: string;
   @Input({required: true}) checkedText: string;
   @Input({required: true}) id: number;
+  @Input() ariaLabel?: string;
 
   @Output() checkBoxUpdated: EventEmitter<CheckBoxUpdate> = new EventEmitter();
 
   isCheckboxSelected: boolean = false;
-
-  brandingConfig = brandingConfig;
+
+  // Add keyboard interaction
+  onKeyPress(event: KeyboardEvent): void {
+    if (event.key === 'Enter' || event.key === ' ') {
+      event.preventDefault();
+      this.toggleCheckbox();
+    }
+  }
+
+  private toggleCheckbox(): void {
+    this.isCheckboxSelected = !this.isCheckboxSelected;
+    this.checkBoxUpdated.emit({id: this.id, value: this.isCheckboxSelected});
+  }
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (4)

26-26: Add type annotation for fieldLength property.

For better type safety and code clarity, add a type annotation to the fieldLength property.

- fieldLength: number;
+ fieldLength: number = 0;

16-23: Consider initializing required inputs in constructor.

The inputs are marked as required but there's no initialization in the constructor. While Angular will handle the initialization, it's a good practice to set default values for better type safety and to prevent undefined behavior during component initialization.

+ constructor() {
+   this.qbdFields = [];
+   this.isLoading = false;
+   this.isCTAEnabled = false;
+   this.showSection = false;
+ }

34-36: Remove optional chaining operator for required input.

Since qbdFields is marked as required, the optional chaining operator (?.) is unnecessary. This also helps catch potential initialization issues early.

- this.fieldLength = this.qbdFields?.length;
+ this.fieldLength = this.qbdFields.length;

24-24: Add type safety to EventEmitter.

Consider adding a type to the EventEmitter for better type safety and documentation.

- @Output() continueClick = new EventEmitter();
+ @Output() continueClick = new EventEmitter<void>();

Also applies to: 30-32

src/app/shared/components/helper/onboarding-stepper/onboarding-stepper.component.scss (1)

17-25: Consider consolidating common styles to improve maintainability.

Several step classes share identical styles:

  • Left positioning of -18px (pre-requisite, import, field)
  • Icon dimensions of 24x24px (pre-requisite, connector, import)

Consider extracting these common values into CSS variables or shared classes to reduce duplication.

Example refactor:

+ :root {
+   --step-offset-default: -18px;
+   --icon-size-default: 24px;
+ }
+
+ .step-icon-default {
+   @apply tw-w-24-px tw-h-24-px;
+ }
+
  .step-name-pre-requisite {
    &--text {
-     @apply tw-relative tw-left-[-18px];
+     @apply tw-relative;
+     left: var(--step-offset-default);
    }

    &--icon {
-     @apply tw-w-24-px tw-h-24-px;
+     @extend .step-icon-default;
    }
  }
src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (1)

46-46: Consider adding null check for brandingConfig

The initialization of brandIcon could be more robust with a null check for brandingConfig.

Apply this diff:

-    this.brandIcon = `assets/${brandingConfig.brandId === 'co' ? 'co' : 'fyle'}/favicon.png`;
+    this.brandIcon = `assets/${brandingConfig?.brandId === 'co' ? 'co' : 'fyle'}/favicon.png`;
src/app/shared/components/input/checkbox-button/checkbox-button.component.scss (1)

1-7: Consider using flexible widths for better responsiveness

The fixed widths (95px and 148px) might cause issues with:

  • Text overflow for longer content
  • Internationalization/localization
  • Different screen sizes

Consider using min-width instead of fixed width, or a more flexible approach:

.checkedText {
-    @apply tw-w-[95px] tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
+    @apply tw-min-w-[95px] tw-w-fit tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
}

.unCheckedText {
-    @apply tw-w-[148px] tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
+    @apply tw-min-w-[148px] tw-w-fit tw-border tw-rounded-sm tw-border-btn-outline-secondary-border-color #{!important};
}
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (2)

34-34: Add type safety for downloadFilePath

The downloadFilePath property lacks type definition. Consider adding string type for better type safety.

-  downloadFilePath: string;
+  downloadFilePath: string = '';

9-16: Add component documentation

Consider adding JSDoc comments to document the component's purpose, usage, and expected behavior. This will help other developers understand how to use this component correctly.

+/**
+ * A standalone component that handles the QuickBooks Desktop file download process.
+ * 
+ * @example
+ * <app-qbd-direct-download-file
+ *   [isLoading]="loading"
+ *   [showDownloadLink]="showLink"
+ *   [isStepCompleted]="completed"
+ *   [isCompanyPathInvalid]="invalid"
+ *   (nextStep)="onNextStep()"
+ *   (downloadClick)="onDownload($event)"
+ * ></app-qbd-direct-download-file>
+ */
 @Component({
   selector: 'app-qbd-direct-download-file',
   standalone: true,
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.ts (1)

19-29: Consider organizing properties by their purpose.

While the properties are well-typed and appropriately configured, consider grouping them by their purpose for better maintainability:

-  appName: AppName = AppName.QBD_DIRECT;
-
-  brandingConfig = brandingConfig;
-
-  redirectLink = brandingKbArticles.topLevelArticles.QBD_DIRECT;
-
-  embedVideoLink = brandingDemoVideoLinks.onboarding.QBD_DIRECT;
-
-  isQbdConnectionInProgress = false;
-
-  readonly brandingContent = brandingContent.qbd_direct.landing;

+  // App configuration
+  readonly appName: AppName = AppName.QBD_DIRECT;
+  readonly brandingConfig = brandingConfig;
+  readonly brandingContent = brandingContent.qbd_direct.landing;
+
+  // External links
+  readonly redirectLink = brandingKbArticles.topLevelArticles.QBD_DIRECT;
+  readonly embedVideoLink = brandingDemoVideoLinks.onboarding.QBD_DIRECT;
+
+  // State flags
+  isQbdConnectionInProgress = false;
src/app/shared/components/configuration/configuration-step-footer/configuration-step-footer.component.html (2)

1-1: Consider simplifying complex conditional styling logic

The current implementation combines multiple conditions in a single line, making it harder to read and maintain. Additionally, tying the border styling to ctaText === 'Next' seems counterintuitive and could lead to confusion.

Consider breaking down the conditions and moving the styling logic to the component's TypeScript file:

-<div class="tw-flex tw-py-16-px tw-px-24-px" [ngClass]="[!showBackButton ? 'tw-justify-end': 'tw-justify-between', ctaText === 'Next' ? '' : 'tw-border-t tw-border-t-border-tertiary']">
+<div class="tw-flex tw-py-16-px tw-px-24-px" 
+     [ngClass]="{
+       'tw-justify-end': !showBackButton,
+       'tw-justify-between': showBackButton,
+       'tw-border-t tw-border-t-border-tertiary': shouldShowBorder
+     }">

And in the component:

get shouldShowBorder(): boolean {
  return this.ctaText !== 'Next';
}

Line range hint 1-30: Consider breaking down the component for better maintainability

The component currently handles multiple responsibilities including navigation, configuration reset, progress indication, and brand-specific formatting. This could make it harder to maintain and test.

Consider breaking it down into smaller, more focused components:

  1. NavigationButtons - Handle back button and reset configuration
  2. ActionButton - Handle the main CTA button with loading states
  3. BrandText - Handle brand-specific text formatting

This would improve:

  • Testability: Each component can be tested in isolation
  • Reusability: Components can be reused in other contexts
  • Maintainability: Changes to one feature won't affect others
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-routing.module.ts (2)

21-24: Consider adding route metadata for step tracking.

The route configuration looks good, but consider adding route data to help with step tracking and navigation state management.

       {
         path: 'pre_requisite',
-        component: QbdDirectOnboardingPreRequisiteComponent
+        component: QbdDirectOnboardingPreRequisiteComponent,
+        data: {
+          step: 2,
+          title: 'Pre-requisites',
+          showBack: true
+        }
       },

Line range hint 13-45: Consider adding route guards for sequential navigation.

To ensure users complete each step in the correct order and prevent direct URL access to later steps, consider implementing route guards.

Here's a suggested implementation approach:

// qbd-direct-onboarding.guard.ts
@Injectable({
  providedIn: 'root'
})
export class QbdDirectOnboardingGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot): boolean {
    const currentStep = route.data['step'];
    // Add your step validation logic here
    // Return false and redirect if prerequisites aren't met
    return true;
  }
}

Then apply it to the routes:

       {
         path: 'pre_requisite',
         component: QbdDirectOnboardingPreRequisiteComponent,
+        canActivate: [QbdDirectOnboardingGuard],
+        data: { step: 2 }
       },
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (2)

31-33: Enhance type safety for event emissions

The event emitters could benefit from stronger typing to ensure type safety at compile time.

-  @Output() doneClick: EventEmitter<CheckBoxUpdate> = new EventEmitter();
-  @Output() nextClick = new EventEmitter();
+  @Output() doneClick = new EventEmitter<CheckBoxUpdate>();
+  @Output() nextClick = new EventEmitter<void>();

10-17: Add JSDoc documentation for the component

Consider adding comprehensive JSDoc documentation to describe:

  • Component's purpose and usage
  • Input/Output contract
  • Expected behavior for different connection states

Example:

/**
 * Component for setting up QuickBooks Desktop connection.
 * Handles password management and connection status visualization.
 *
 * @example
 * <app-qbd-direct-setup-connection
 *   [password]="password"
 *   [isLoading]="loading"
 *   [connectionStatus]="status"
 *   (doneClick)="onDone($event)"
 * ></app-qbd-direct-setup-connection>
 */
@Component({
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (2)

4-6: Add aria-live region for better accessibility.

Consider adding aria-live attribute to improve the loading state announcement for screen readers.

-<div *ngIf="isLoading" class="tw-flex tw-justify-center tw-items-center tw-pt-80-px">
+<div *ngIf="isLoading" class="tw-flex tw-justify-center tw-items-center tw-pt-80-px" aria-live="polite">

38-38: Simplify CTA text binding.

The current implementation uses a ternary operation directly in the template. Consider moving this logic to the component class for better readability and maintainability.

-<app-configuration-step-footer [ctaText]="!saveInProgress ? ConfigurationCtaText.CONTINUE : ConfigurationCtaText.SAVING" [isButtonDisabled]="isContinueDisabled" (save)="continueToNextStep()">
+<app-configuration-step-footer [ctaText]="getCtaText()" [isButtonDisabled]="isContinueDisabled" (save)="continueToNextStep()">

Add to your component class:

getCtaText(): string {
  return !this.saveInProgress 
    ? this.ConfigurationCtaText.CONTINUE 
    : this.ConfigurationCtaText.SAVING;
}
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html (2)

1-12: Consider improving accessibility and maintainability of the header section

A few suggestions to enhance this section:

  1. The opacity-60 might make content hard to read. Consider using a different visual indication for inactive sections.
  2. The step number "3" should be managed through a variable to make it more maintainable.
-<div class="tw-border tw-border-border-info-lighter" [ngClass]="{'tw-bg-border-info-lighter tw-opacity-60': !showSection}">
+<div class="tw-border tw-border-border-info-lighter" [ngClass]="{'tw-bg-border-info-lighter tw-pointer-events-none': !showSection}">
   <div class="tw-p-24-px">
     <div class="tw-flex tw-items-center tw-justify-between">
       <div class="tw-flex tw-items-center tw-justify-start">
         <div class="tw-w-20-px tw-h-20-px tw-rounded-sm tw-bg-bg-secondary tw-text-white tw-text-14-px tw-font-500 tw-text-center tw-mr-8-px">
-          3
+          {{stepNumber}}
         </div>

29-32: Improve loading state responsiveness and maintainability

Consider these improvements:

  1. Replace fixed height with min-height or responsive classes
  2. Externalize the "Loading" text for i18n support
-<div *ngIf="isLoading && showSection" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]">
+<div *ngIf="isLoading && showSection" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-min-h-[200px] md:tw-min-h-[400px]">
   <app-loader styleClass="spinner-30 tw-top-2-px"></app-loader>
-  <span class="tw-text-14-px tw-font-400 tw-text-text-primary">Loading</span>
+  <span class="tw-text-14-px tw-font-400 tw-text-text-primary">{{ 'COMMON.LOADING' | translate }}</span>
src/app/shared/components/core/svg-icon/svg-icon.component.ts (2)

59-63: LGTM! Consider adding documentation for icon usage.

The new icon mappings follow the existing pattern and are well-structured. However, since these icons seem to be part of a new folder creation feature, it would be helpful to add documentation comments describing their intended usage contexts.

Consider adding JSDoc comments above the ICON_MAPPING constant to document the purpose of each icon, for example:

/**
 * Icon mapping constant
 * 
 * upload: Used in file upload dialogs
 * lock: Indicates secure/restricted operations
 * eye-slash-medium: Toggle password visibility (hidden state)
 * eye-medium: Toggle password visibility (visible state)
 * ...
 */
const ICON_MAPPING = {

Line range hint 4-63: Consider improving type safety.

The current implementation could benefit from stronger typing to prevent runtime errors and improve maintainability.

Consider these type-safety improvements:

// Define allowed icon names as string literal types
type IconName = 'upload' | 'lock' | 'eye-slash-medium' | 'eye-medium' | /* ... other icons ... */;
type IconValue = 'grv-upload' | 'grv-lock' | 'grv-show-hide-medium' | 'grv-show-medium' | /* ... other values ... */;

// Type the mapping object
const ICON_MAPPING: Record<IconName, IconValue> = {
  'upload': 'grv-upload',
  'lock': 'grv-lock',
  // ...
};

// Update the input property
@Input() svgSource: IconName;

This would:

  • Catch typos in icon names at compile time
  • Provide better IDE autocompletion
  • Remove the need for @ts-ignore in setupProperties
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1)

31-31: Add type annotations for boolean properties.

For better type safety and code clarity, explicitly declare types for boolean properties:

- isLoading: boolean;
+ isLoading: boolean = false;
- saveInProgress: boolean = false;
+ saveInProgress: boolean = false;
- isContinueDisabled: boolean = true;
+ isContinueDisabled: boolean = true;

Also applies to: 39-39, 41-41

src/app/integrations/qbd-direct/qbd-direct.component.ts (1)

Line range hint 44-61: Consider refactoring for improved maintainability

The navigation logic could be improved in the following ways:

  1. Move the onboardingStateComponentMap to a constant or configuration file to improve maintainability
  2. Add error handling in the workspace setup process

Consider extracting the state mapping:

// qbd-direct.constants.ts
export const QBD_DIRECT_ONBOARDING_ROUTES = {
  [QbdDirectOnboardingState.YET_TO_START]: '/integrations/qbd_direct/onboarding/landing',
  // ... other mappings
};

// In component
import { QBD_DIRECT_ONBOARDING_ROUTES } from './qbd-direct.constants';
// ...
this.router.navigateByUrl(QBD_DIRECT_ONBOARDING_ROUTES[this.workspace.onboarding_state]);
src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.ts (1)

81-95: Consider improving state management and readability

The current implementation has a few potential issues:

  1. Direct mutation of the private onboardingSteps array could cause side effects
  2. The completion logic using a counter loop is less readable

Consider this more functional approach:

-    getOnboardingSteps(currentStep: string, onboardingState: QbdDirectOnboardingState): OnboardingStepper[] {
-        this.onboardingSteps.forEach(step => {
-          if (step.step.toLowerCase() === currentStep.toLowerCase()) {
-            step.active = true;
-          } else {
-            step.active = false;
-          }
-        });
-
-        for (let index = this.onboardingStateStepMap[onboardingState] - 1; index > 0; index--) {
-          this.onboardingSteps[index - 1].completed = true;
-        }
-
-        return this.onboardingSteps;
-    }
+    getOnboardingSteps(currentStep: string, onboardingState: QbdDirectOnboardingState): OnboardingStepper[] {
+        const currentStepNumber = this.onboardingStateStepMap[onboardingState];
+        
+        return this.onboardingSteps.map((step, index) => ({
+            ...step,
+            active: step.step.toLowerCase() === currentStep.toLowerCase(),
+            completed: index < currentStepNumber - 1
+        }));
+    }

This approach:

  • Returns a new array instead of mutating the original
  • Uses more declarative logic for setting completed states
  • Improves readability and maintainability
src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.html (1)

43-46: Consider refactoring the application name condition

The current condition for displaying the button includes a long list of application names. Consider extracting this logic to a component method or constant for better maintainability.

Here's a suggested approach:

// In the component class
private readonly INTEGRATION_APPS = [
  AppName.QBD,
  AppName.NETSUITE,
  AppName.INTACCT,
  AppName.SAGE300,
  AppName.BUSINESS_CENTRAL
];

isIntegrationApp(appName: string): boolean {
  return this.INTEGRATION_APPS.includes(appName) || appName.includes(AppName.QBD_DIRECT);
}

Then in the template:

-<button *ngIf="!isIntegrationConnected && (appName === AppName.QBD || appName === AppName.NETSUITE || appName === AppName.INTACCT || appName === AppName.SAGE300 || appName === AppName.BUSINESS_CENTRAL || appName.includes(AppName.QBD_DIRECT))"
+<button *ngIf="!isIntegrationConnected && isIntegrationApp(appName)"
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (3)

39-52: Enhance password security and user feedback

The password handling in the UI could be improved for better security and user experience:

  1. Consider showing only the last few characters instead of most of the password
  2. Add user feedback for clipboard operations

Consider these improvements:

- <p *ngIf="!isPasswordShown" class="tw-text-16-px tw-text-text-tertiary tw-font-400">****{{password.slice(4)}}</p>
+ <p *ngIf="!isPasswordShown" class="tw-text-16-px tw-text-text-tertiary tw-font-400">••••••{{password.slice(-4)}}</p>

- <app-svg-icon [svgSource]="'duplicate'" [width]="'22px'" [height]="'22px'" [isTextColorAllowed]="true" [styleClasses]="'tw-text-icon-muted tw-cursor-pointer'" (iconClick)="onClipboardCopy()"></app-svg-icon>
+ <app-svg-icon 
+   [svgSource]="'duplicate'" 
+   [width]="'22px'" 
+   [height]="'22px'" 
+   [isTextColorAllowed]="true" 
+   [styleClasses]="'tw-text-icon-muted tw-cursor-pointer'" 
+   (iconClick)="onClipboardCopy()"
+   [matTooltip]="'Copy to clipboard'"
+   aria-label="Copy password to clipboard">
+ </app-svg-icon>

84-96: Enhance loading and success state presentation

Consider these improvements for better user experience:

  1. Use min-height instead of fixed height for better responsiveness
  2. Add more context to the success message

Apply these changes:

- <div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]">
+ <div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-min-h-[200px]">

- <span class="tw-text-14-px tw-font-400 tw-text-text-primary">Connecting to QuickBooks Desktop...</span>
+ <span class="tw-text-14-px tw-font-400 tw-text-text-primary">Establishing secure connection to QuickBooks Desktop...</span>

- <span class="tw-pt-8-px tw-text-text-muted tw-text-12-px tw-font-400">You're now connected to QuickBooks Desktop.</span>
+ <span class="tw-pt-8-px tw-text-text-muted tw-text-12-px tw-font-400">You're now securely connected to QuickBooks Desktop. You can proceed to the next step.</span>

98-100: Add component documentation

Consider adding a comment block to document the footer component's purpose and configuration options.

Add this documentation above the footer:

+ <!-- 
+  Configuration step footer
+  Shows a next button that is enabled when the connection is successfully established
+  @param ctaText - Text to show on the button, from ConfigurationCtaText enum
+  @param isButtonDisabled - Whether the button should be disabled
+  @param save - Event emitted when the button is clicked
+ -->
<app-configuration-step-footer 
    [ctaText]="ConfigurationCtaText.NEXT" 
    [isButtonDisabled]="!isCTAEnabled" 
    (save)="onNextClick()">
</app-configuration-step-footer>
src/app/shared/shared.module.ts (1)

Line range hint 156-158: Critical: Remove duplicate component declarations

The following components are declared twice in the declarations array:

  • SvgIconComponent
  • NetsuiteConnectorComponent
  • NetsuiteSubsidiaryMappingComponent

This will cause runtime errors as Angular modules don't allow duplicate declarations.

Apply this diff to remove the duplicates:

    SvgIconComponent,
    NetsuiteConnectorComponent,
    NetsuiteSubsidiaryMappingComponent,
-   SvgIconComponent,
-   NetsuiteConnectorComponent,
-   NetsuiteSubsidiaryMappingComponent,
    SearchComponent,

Also applies to: 159-161

src/app/branding/c1-contents-config.ts (3)

9-9: Improve string concatenation for better maintainability.

The string concatenation using + operator makes the text harder to read and maintain.

Consider using template literals for better readability:

-            contentText: 'Import data from QuickBooks Desktop to ' + brandingConfig.brandName + ' and export expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop',
+            contentText: `Import data from QuickBooks Desktop to ${brandingConfig.brandName} and export expenses from ${brandingConfig.brandName} to QuickBooks Desktop`,

81-81: Improve string concatenation in advanced settings section.

Similar to the landing section, the string concatenation makes the text harder to maintain.

Consider using template literals for better readability:

-                customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from ' + brandingConfig.brandName + ' to QuickBooks Desktop You can choose what data points need to be exported and what shouldn\'t be.',
+                customizeSectionSubLabel: `In this section, you can customize the data that you'd like to export from ${brandingConfig.brandName} to QuickBooks Desktop. You can choose what data points need to be exported and what shouldn't be.`,

-                autoCreateMerchantsAsVendorsSubLabel: '' + brandingConfig.brandName + ' will auto-create a new vendor in QuickBooks Desktop if a merchant added by an employee does not have a corresponding match in QuickBooks Desktop. ',
+                autoCreateMerchantsAsVendorsSubLabel: `${brandingConfig.brandName} will auto-create a new vendor in QuickBooks Desktop if a merchant added by an employee does not have a corresponding match in QuickBooks Desktop.`,

-                skipExportLabel: 'Skip export of specific expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop',
-                skipExportSubLabel: 'You could choose to skip expenses from ' + brandingConfig.brandName + ' to QuickBooks Desktop by setting up a conditional rule. ',
+                skipExportLabel: `Skip export of specific expenses from ${brandingConfig.brandName} to QuickBooks Desktop`,
+                skipExportSubLabel: `You could choose to skip expenses from ${brandingConfig.brandName} to QuickBooks Desktop by setting up a conditional rule.`,

Also applies to: 96-98


81-81: Fix typo in customization section text.

There's a missing period after "QuickBooks Desktop" which affects readability.

Add the missing period:

-                customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from ' + brandingConfig.brandName + ' to QuickBooks Desktop You can choose what data points need to be exported and what shouldn\'t be.',
+                customizeSectionSubLabel: 'In this section, you can customize the data that you\'d like to export from ' + brandingConfig.brandName + ' to QuickBooks Desktop. You can choose what data points need to be exported and what shouldn\'t be.',
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.html (3)

7-7: Use constants or enums for brand IDs in ngClass binding

The ngClass binding on line 7 uses hardcoded strings 'fyle' and 'co' for brandingConfig.brandId. To improve maintainability and reduce potential typos or errors, consider defining these brand IDs as constants or enums.


55-55: Simplify static text binding for headerText

The [headerText] property on line 55 is bound to a static string 'Connection failed'. Since it's a static value, you can simplify it by removing the property binding brackets:

headerText="Connection failed"

57-57: Simplify static text binding for confirmBtnText

Similarly, the [confirmBtnText] property on line 57 is bound to a static string 'Got it'. Simplify it by removing the binding:

confirmBtnText="Got it"
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html (2)

24-36: Enhance validation feedback and improve variable naming

Consider providing specific error messages based on the validation errors to improve user experience. For example, display "This field is required." when the input is empty and "Enter a valid company file path." when the path is invalid. Additionally, renaming the variable isCompanyPathInvalid to isCompanyPathValid can enhance code readability by avoiding double negatives.

Apply this diff to implement the changes:

<input type="text" pInputText id="downloadFilePath" name="downloadFilePath" [(ngModel)]="downloadFilePath" 
placeholder="Example: C:\Users\[Username]\Documents\QuickBooks" 
class="tw-w-full tw-border tw-border-input-default-border tw-rounded-sm tw-px-8-px tw-py-12-px" 
required
#downloadFilePathField="ngModel"
[ngClass]="{
-   'error-box': (downloadFilePathField.invalid && downloadFilePathField.touched) || !isCompanyPathInvalid
+   'error-box': (downloadFilePathField.invalid && downloadFilePathField.touched) || !isCompanyPathValid
 }">
<div *ngIf="(downloadFilePathField.invalid && downloadFilePathField.touched) || !isCompanyPathValid" class="tw-text-alert-toast">
   <small *ngIf="downloadFilePathField.errors?.required" class="tw-flex">
       <app-svg-icon [svgSource]="'info-circle-fill'" [isTextColorAllowed]="true" [width]="'16px'" [height]="'16px'" [styleClasses]="'tw-text-form-error-help-text-color'"></app-svg-icon>
-      Enter a valid company file path.</small>
+      This field is required.</small>
+  <small *ngIf="!isCompanyPathValid" class="tw-flex tw-mt-4-px">
+      <app-svg-icon [svgSource]="'info-circle-fill'" [isTextColorAllowed]="true" [width]="'16px'" [height]="'16px'" [styleClasses]="'tw-text-form-error-help-text-color'"></app-svg-icon>
+      Enter a valid company file path.</small>
</div>

46-46: Make the embedded video responsive

The iframe currently has fixed width and height attributes, which may not render well on different screen sizes. To enhance responsiveness, consider using CSS to make the video adapt to various devices.

Apply this diff to make the iframe responsive:

<div class="tw-flex tw-justify-center">
-    <iframe width="427" height="259" src="https://www.youtube.com/embed/2oYdc8KcQnk" frameborder="0"></iframe>
+    <div class="video-container">
+        <iframe src="https://www.youtube.com/embed/2oYdc8KcQnk" frameborder="0" allowfullscreen></iframe>
+    </div>
</div>

And add the following CSS styles (outside the selected lines):

.video-container {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 aspect ratio */
    height: 0;
    overflow: hidden;
    max-width: 100%;
}

.video-container iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (3)

102-105: Redundant creation of object URLs for the same blob.

Within triggerManualDownload(), two object URLs are created for the same blob, and the variable url is declared but not used.

Simplify the code by removing the unnecessary url variable and using a single object URL:

- const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  const objectUrl = URL.createObjectURL(blob);
+ const objectUrl = window.URL.createObjectURL(blob);

Alternatively, use the url variable consistently:

  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
- const objectUrl = URL.createObjectURL(blob);
- a.href = objectUrl;
+ a.href = url;

This ensures efficient use of resources and improves code clarity.


142-142: Simplify boolean assignment for isDataSyncCTADisabled.

The assignment uses a ternary operator to assign boolean values, which can be simplified for better readability.

Apply this diff to simplify the assignment:

- this.isDataSyncCTADisabled = onboardingState === QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE ? false : true;
+ this.isDataSyncCTADisabled = onboardingState !== QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE;

This direct assignment makes the code cleaner and easier to understand.

🧰 Tools
🪛 Biome

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


194-194: Unused parameter event in closeDialog method.

The closeDialog method includes a parameter event: any that is not used within the method, which could lead to confusion.

Remove the unused parameter to improve code cleanliness:

- closeDialog(event: any) {
+ closeDialog() {

If the event parameter might be needed in the future, consider adding a comment explaining its intended use.

src/app/branding/fyle-contents-config.ts (1)

15-16: Ensure consistent terminology: use 'QuickBooks Desktop' instead of 'QuickBooks'.

For consistency and clarity, replace 'QuickBooks' with 'QuickBooks Desktop' in the configurationSubHeaderText.

Apply this diff to improve consistency:

-configurationSubHeaderText: 'Begin your QuickBooks integration by completing the following steps.'
+configurationSubHeaderText: 'Begin your QuickBooks Desktop integration by completing the following steps.'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 80c9b48 and 024398f.

⛔ Files ignored due to path filters (14)
  • src/assets/flow-charts/fyle-qbd-direct-flow-chart.svg is excluded by !**/*.svg
  • src/assets/fyle/favicon.png is excluded by !**/*.png
  • src/assets/icons/co/grv-lock.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-show-hide-medium.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-show-medium.svg is excluded by !**/*.svg
  • src/assets/icons/co/grv-upload.svg is excluded by !**/*.svg
  • src/assets/icons/download-medium.svg is excluded by !**/*.svg
  • src/assets/icons/expand.svg is excluded by !**/*.svg
  • src/assets/icons/eye-medium.svg is excluded by !**/*.svg
  • src/assets/icons/eye-slash-medium.svg is excluded by !**/*.svg
  • src/assets/icons/lock.svg is excluded by !**/*.svg
  • src/assets/icons/upload.svg is excluded by !**/*.svg
  • src/assets/logos/qbd-direct-logo.svg is excluded by !**/*.svg
  • src/assets/sprites/sprite.svg is excluded by !**/*.svg
📒 Files selected for processing (50)
  • .eslintrc.json (1 hunks)
  • src/app/branding/c1-contents-config.ts (3 hunks)
  • src/app/branding/fyle-contents-config.ts (1 hunks)
  • src/app/core/models/branding/content-configuration.model.ts (1 hunks)
  • src/app/core/models/common/helper.model.ts (1 hunks)
  • src/app/core/models/db/workspaces.model.ts (1 hunks)
  • src/app/core/models/enum/enum.model.ts (3 hunks)
  • src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (1 hunks)
  • src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.ts (1 hunks)
  • src/app/core/services/common/workspace.service.ts (2 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts (0 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (1 hunks)
  • src/app/core/services/qbd-direct/qbd-direct-core/qbd-direct-connector.service.ts (0 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-routing.module.ts (2 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.scss (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-shared.module.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct.module.ts (1 hunks)
  • src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.html (1 hunks)
  • src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (2 hunks)
  • src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.html (1 hunks)
  • src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1 hunks)
  • src/app/shared/components/configuration/configuration-step-footer/configuration-step-footer.component.html (2 hunks)
  • src/app/shared/components/core/svg-icon/svg-icon.component.ts (1 hunks)
  • src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.html (1 hunks)
  • src/app/shared/components/helper/app-landing-page-header/app-landing-page-header.component.ts (1 hunks)
  • src/app/shared/components/helper/onboarding-stepper/onboarding-stepper.component.scss (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.scss (1 hunks)
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1 hunks)
  • src/app/shared/shared.module.ts (3 hunks)
  • src/styles.scss (1 hunks)
  • tailwind.config.js (2 hunks)
💤 Files with no reviewable changes (2)
  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.spec.ts
  • src/app/core/services/qbd-direct/qbd-direct-core/qbd-direct-connector.service.ts
✅ Files skipped from review due to trivial changes (3)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.scss
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.scss
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.scss
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.spec.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.spec.ts
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.spec.ts
  • src/app/shared/components/input/checkbox-button/checkbox-button.component.html
🧰 Additional context used
🪛 Biome
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts

[error] 39-39: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (40)
src/app/core/models/db/workspaces.model.ts (1)

11-13: Verify the integration with QBD onboarding flow

Since this type is used in the QuickBooks Desktop integration onboarding process, let's verify its usage across the codebase.

✅ Verification successful

The WorkspaceOnboardingState type is correctly integrated with QBD onboarding flow

Based on the search results, the WorkspaceOnboardingState type is properly integrated and used throughout the QBD (QuickBooks Desktop) onboarding flow. Specifically:

  • It's used in QBD Direct onboarding components to track and update onboarding states:
    • qbd-direct-onboarding-landing
    • qbd-direct-onboarding-pre-requisite
    • qbd-direct-onboarding-connector
  • The type is also used by other integrations (Xero, Business Central, TravelPerk, etc.) following the same pattern
  • The workspace service correctly implements the state updates via the updateWorkspaceOnboardingState method
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how WorkspaceOnboardingState is used in the codebase
# Expected: Find usages in QBD onboarding components and workspace service

echo "Checking WorkspaceOnboardingState usage in components:"
rg -t typescript "WorkspaceOnboardingState" --glob "!*.spec.ts"

echo -e "\nChecking onboarding state updates:"
ast-grep --pattern 'onboarding_state = $_' 

echo -e "\nChecking state transitions in QBD components:"
rg -t typescript "updateWorkspaceOnboardingState" -A 3

Length of output: 544


Script:

#!/bin/bash
# Let's try different commands to check the usage

# Check for WorkspaceOnboardingState type usage
echo "Checking WorkspaceOnboardingState usage:"
rg "WorkspaceOnboardingState"

# Look for files containing onboarding_state
echo -e "\nChecking files with onboarding_state:"
rg "onboarding_state"

# Search for QBD (QuickBooks Desktop) related files
echo -e "\nChecking QBD related files:"
rg -l "QuickBooks.*Desktop|QBD"

# Check workspace related service files
echo -e "\nChecking workspace service files:"
fd -e ts workspace

Length of output: 21721

src/app/shared/components/configuration/configuration-info-label/configuration-info-label.component.ts (1)

12-12: LGTM! Clean implementation of the new input property.

The addition of the showIcon input property with a default value of true is well-implemented and maintains backward compatibility.

src/app/integrations/qbd-direct/qbd-direct.module.ts (1)

Line range hint 7-13: Verify component declarations in QbdDirectSharedModule

The module has an empty declarations array, which is fine if all components are declared in QbdDirectSharedModule. Let's verify that the new components mentioned in the summary are properly declared there.

✅ Verification successful

Empty declarations array is correct - all components are standalone

The empty declarations array in the QbdDirectModule is correct since all QBD Direct components are using the standalone component pattern with standalone: true. This is verified by finding all components in the QBD Direct feature:

  • QbdDirectComponent
  • QbdDirectMainComponent
  • QbdDirectMappingComponent
  • QbdDirectExportLogComponent
  • QbdDirectSkippedExportLogComponent
  • QbdDirectConfigurationComponent
  • QbdDirectDashboardComponent
  • QbdDirectCompleteExportLogComponent
  • QbdDirectBaseMappingComponent
  • QbdDirectAdvancedSettingsComponent
  • QbdDirectImportSettingsComponent
  • QbdDirectExportSettingsComponent
  • QbdDirectDownloadFileComponent
  • QbdDirectSetupConnectionComponent
  • QbdDirectSharedComponent

All of these components have the standalone: true decorator configuration, meaning they don't need to be declared in any NgModule's declarations array.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all QBD Direct components are properly declared in QbdDirectSharedModule

# Search for QbdDirectSharedModule declaration and its components
ast-grep --pattern 'NgModule({
  declarations: [$$$],
  $$$
})
export class QbdDirectSharedModule'

# Also check for standalone component declarations
rg "standalone: true" -A 5 -B 5

Length of output: 41993

src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-connector.model.ts (2)

19-26: LGTM! Well-structured type definition

The type is well-designed with:

  • Clear and descriptive property names
  • Proper use of optional properties
  • Strong typing with enum for state

3-5: Consider adding validation constraints for file_location

The file_location property might benefit from additional validation to ensure it contains a valid path or URL format.

Let's check how file_location is validated across the codebase:

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-shared.module.ts (2)

13-15: ⚠️ Potential issue

Fix standalone components configuration

The standalone components should not be added to both declarations and imports arrays. Since these are standalone components (as indicated by their presence in the imports array), they should only be in the imports array.

Apply this fix:

@NgModule({
-  declarations: [],
+  declarations: [], // Remove if not needed for non-standalone components
  imports: [
    CommonModule,
    SharedModule,
    QbdDirectDownloadFileComponent,
    QbdDirectSetupConnectionComponent,
    QbdDirectDataSyncComponent
  ],
  exports: [
    QbdDirectDownloadFileComponent,
    QbdDirectSetupConnectionComponent,
    QbdDirectDataSyncComponent
  ]
})

Likely invalid or redundant comment.


Line range hint 1-24: Consider module organization strategy

The module appears to be transitioning to use standalone components. Consider the following architectural recommendations:

  1. If all components are standalone, you might not need this shared module at all. Standalone components can be imported directly where needed.
  2. If you need to keep the shared module for other shared features:
    • Document the purpose of keeping an empty declarations array
    • Consider moving the standalone components to a separate organizational unit

Let's verify if there are any non-standalone components that might need this shared module:

src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts (2)

12-15: LGTM! Dependency injection follows best practices

The constructor properly injects the required services with appropriate access modifiers.


1-10: ⚠️ Potential issue

Fix typo in method name throughout the codebase

The service is well-structured, but there's a typo in the method name that should be fixed for consistency and maintainability.

Apply this change throughout the codebase:

- postQbdDirectConntion
+ postQbdDirectConnection

Let's verify all occurrences of this method name in the codebase:

#!/bin/bash
# Search for all occurrences of the misspelled method name
rg "postQbdDirectConntion" --type ts
src/app/shared/components/input/checkbox-button/checkbox-button.component.ts (1)

1-13: LGTM! Component setup and imports are well structured.

The component is properly configured as standalone with all necessary imports and metadata.

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-data-sync/qbd-direct-data-sync.component.ts (1)

1-13: LGTM! Component setup and imports are well structured.

The component is properly configured as standalone with all necessary imports and modules.

src/app/shared/components/helper/onboarding-stepper/onboarding-stepper.component.scss (1)

17-25: LGTM! The new styles follow established patterns.

The .step-name-pre-requisite implementation maintains consistency with other step styles and correctly uses the existing BEM-like naming convention.

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.ts (2)

3-3: LGTM: Import statement is correctly updated

The AppName enum is properly imported alongside the existing ConfigurationWarningEvent.


35-37: LGTM: Class properties are well-defined

The AppName enum assignment enables type-safe enum usage in the template, and brandIcon is properly declared.

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts (1)

14-14: Verify Angular version compatibility for styleUrl

The styleUrl property was introduced in Angular 16.1. Ensure your project's Angular version is compatible with this syntax. For broader compatibility, consider using styleUrls instead.

✅ Verification successful

styleUrl usage is compatible with Angular version

The project is using Angular 17.3.10, which fully supports the styleUrl property introduced in Angular 16.1. The current implementation is following the recommended syntax.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check Angular version in package.json
jq -r '.dependencies["@angular/core"]' package.json

Length of output: 62

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-landing/qbd-direct-onboarding-landing.component.ts (2)

1-16: LGTM! Well-structured imports and component configuration.

The imports are properly organized, and the component is correctly configured as standalone with necessary module imports.


31-34: LGTM! Proper dependency injection.

The constructor follows Angular's dependency injection best practices with appropriate access modifiers.

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.ts (1)

1-16: LGTM! Component setup follows Angular best practices

The component is properly configured as standalone with appropriate imports and module declarations.

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (2)

1-2: LGTM! Clean implementation of the stepper component.


9-13: Verify redirect link handling.

Please ensure that the redirectLink is properly sanitized and validated before being used in the template to prevent potential security issues.

src/app/shared/components/configuration/configuration-confirmation-dialog/configuration-confirmation-dialog.component.html (2)

6-11: Verify intentional icon size difference

The danger icon (18px) is slightly larger than the warning icon (16px). While this might be intentional for emphasis, please confirm if this difference aligns with the design specifications.


18-18: Security: Verify innerHTML sanitization

The use of [innerHTML] could potentially expose the application to XSS attacks if the contextText content isn't properly sanitized.

Run the following script to check for sanitization in the component:

src/app/core/services/common/workspace.service.ts (1)

8-9: LGTM! Imports are properly structured.

The new imports are correctly added and align with the new functionality being introduced.

src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1)

1-24: LGTM! Component configuration follows Angular best practices.

The component is properly configured as standalone with necessary imports and follows Angular's recommended patterns.

src/app/integrations/qbd-direct/qbd-direct.component.ts (3)

44-44: LGTM: Path condition correctly updated for QBD Direct integration

The path condition has been appropriately updated to match the QBD Direct integration route.


51-51: Verify consistent usage of INCORRECT_PASSWORD state

The state name has been corrected from IN_CORRECT_PASSWORD to INCORRECT_PASSWORD.

Let's verify consistent usage across the codebase:


47-47: Verify the pre-requisite component setup

The route for CONFIRM_PRE_REQUISITES state has been updated to point to a new pre-requisite component.

Let's verify the component setup:

✅ Verification successful

Pre-requisite component and route are properly configured

The verification confirms that:

  • The pre-requisite component exists with all necessary files (.ts, .html, .scss, .spec.ts)
  • The route /integrations/qbd_direct/onboarding/pre_requisite is correctly configured in the routing module
  • The CONFIRM_PRE_REQUISITES state is properly defined in the QbdDirectOnboardingState enum
  • The component is properly imported and used in the onboarding flow

The route change is valid and all necessary components are in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and setup of the pre-requisite component

# Check if the component exists
echo "Checking for pre-requisite component..."
fd -e ts "pre-requisite.component.ts" src/app/integrations/qbd-direct

# Check if the route is properly configured in the routing module
echo "Checking route configuration..."
rg -A 5 "pre_requisite" src/app/integrations/qbd-direct

Length of output: 1747


Script:

#!/bin/bash
# Let's verify the pre-requisite component and routing setup with more specific searches

# Check for pre-requisite component in the qbd-direct directory
echo "Checking for pre-requisite component files..."
fd "pre.?requisite" src/app/integrations/qbd-direct

# Check routing configuration
echo "Checking routing module for pre-requisite route..."
rg -l "RouterModule" src/app/integrations/qbd-direct

# Check for any references to pre-requisite in the routing
echo "Checking for pre-requisite route configuration..."
rg "pre.?requisite" src/app/integrations/qbd-direct

# Check the onboarding states enum
echo "Checking onboarding states..."
rg "QbdDirectOnboardingState" src/app/core/models/enum/enum.model.ts -A 10

Length of output: 4643

src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.ts (1)

66-79: LGTM! Well-structured state mapping

The state-to-step mapping is comprehensive and logically organized, covering all possible states in the onboarding flow.

src/app/shared/shared.module.ts (2)

95-95: LGTM: Import statement follows conventions

The import statement for CheckboxButtonComponent is properly placed and follows Angular's module organization conventions.


Line range hint 1-273: Verify: Changes seem unrelated to PR objective

The PR objective mentions "folder creation", but the changes are about adding a checkbox button component to the shared module. Please clarify the relationship between these changes and the folder creation feature, or update the PR description to accurately reflect the changes.

Let's check for any folder-related changes that might have been missed:

src/app/core/models/branding/content-configuration.model.ts (1)

9-13: LGTM: Type definition for prerequisite content is well-structured

The new preRequisite property follows the established pattern of configuration objects in the codebase and properly defines the required text content fields for the QBD Direct onboarding UI.

src/app/core/models/enum/enum.model.ts (3)

351-352: LGTM: ConfigurationCta enum update

The addition of NEXT and the trailing comma after UPDATE follow TypeScript best practices.


888-891: LGTM: QBDPreRequisiteState enum

The new enum follows consistent naming conventions and has clear, descriptive values.


893-897: 🛠️ Refactor suggestion

Consider consolidating duplicate status definitions

There's duplication between QBDConnectionStatus and QbdDirectOnboardingState enums for status values like INCORRECT_COMPANY_PATH and INCORRECT_PASSWORD. Consider consolidating these status values to maintain a single source of truth.

Also applies to: 339-341

src/styles.scss (1)

493-495: LGTM! The new spinner class follows established patterns.

The implementation of .spinner-30 follows the existing spinner class pattern and correctly uses the spinner mixin with appropriate parameters.

src/app/branding/c1-contents-config.ts (2)

13-17: LGTM! Well-structured prerequisites section.

The prerequisites section is well-organized with clear step name, header text, and subheader text.


19-21: ⚠️ Potential issue

Inconsistency in connector configuration text.

The subLabel property still references NetSuite while the header texts have been updated for QuickBooks Desktop.

Apply this fix:

-                subLabel: 'Provide your credentials to establish a secure connection between your Expense Management and NetSuite account'
+                subLabel: 'Provide your credentials to establish a secure connection between your Expense Management and QuickBooks Desktop account'

Likely invalid or redundant comment.

tailwind.config.js (1)

1134-1134: LGTM! Consistent dimension additions

The addition of '45-px': '45px' to both height and width properties maintains symmetry and follows the existing naming convention. These additions provide more granular control over element dimensions while filling logical gaps in the size scale.

Also applies to: 1200-1200

src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html (1)

70-70: Verify the condition for enabling the 'Next' button

The 'Next' button is disabled until showDownloadLink is true. Please verify if this aligns with the intended user flow. If the button should be enabled after the download is complete, and considering isStepCompleted indicates completion, you might want to adjust the condition.

Run the following script to search for references of showDownloadLink and isStepCompleted in the component files to verify their usage:

✅ Verification successful

The condition for enabling the 'Next' button is correctly implemented

The current implementation is correct and aligns with the intended user flow. Here's why:

  • The component shows a multi-step process where users need to:
    1. Enter a company file path and download the integration file
    2. Wait for the download to complete
  • The showDownloadLink becomes true only after a successful download generation
  • The 'Next' button is appropriately disabled until showDownloadLink is true, ensuring users can't proceed without completing the download step
  • Once the step is completed (isStepCompleted), the footer with the 'Next' button is hidden entirely, as shown by the *ngIf="!isStepCompleted" condition
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of 'showDownloadLink' and 'isStepCompleted' in component TypeScript files.

# Search for 'showDownloadLink' in component files
fd -e ts 'qbd-direct-download-file.component' --exec grep -Hn 'showDownloadLink' {}

# Search for 'isStepCompleted' in component files
fd -e ts 'qbd-direct-download-file.component' --exec grep -Hn 'isStepCompleted' {}

Length of output: 509


Script:

#!/bin/bash
# Let's examine the component implementation to understand the usage context
cat ./src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.ts

# Also check the parent component to see how these inputs are set
rg -l "qbd-direct-download-file" --type ts

Length of output: 2007


Script:

#!/bin/bash
# Let's check the template file to understand the complete usage context
cat ./src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-download-file/qbd-direct-download-file.component.html

# Also check how this component is used in parent components
rg -A 5 -B 5 "<app-qbd-direct-download-file" --type html

Length of output: 7428

src/app/branding/fyle-contents-config.ts (1)

9-9: Content correctly updated for QuickBooks Desktop integration.

The contentText accurately reflects the integration with QuickBooks Desktop.

Comment on lines +11 to +13
export type WorkspaceOnboardingState = {
onboarding_state: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using string literal union type for better type safety

The onboarding_state property currently accepts any string value, which could lead to inconsistencies and potential bugs. Consider defining the valid states explicitly using a string literal union type.

+// Define possible onboarding states
+export type OnboardingState = 'INITIAL' | 'FOLDER_CREATION' | 'CONNECTION_IN_PROGRESS' | 'COMPLETE';
+
 export type WorkspaceOnboardingState = {
-  onboarding_state: string;
+  onboarding_state: OnboardingState;
 }

Additionally, please add JSDoc comments to document the purpose of this type and the meaning of each possible state.

📝 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.

Suggested change
export type WorkspaceOnboardingState = {
onboarding_state: string;
}
// Define possible onboarding states
export type OnboardingState = 'INITIAL' | 'FOLDER_CREATION' | 'CONNECTION_IN_PROGRESS' | 'COMPLETE';
export type WorkspaceOnboardingState = {
onboarding_state: OnboardingState;
}

Comment on lines +7 to +17
export type QbdConnectorGet = {
id: number,
workspace_id: number,
username: string,
password: string,
ticket_id: string,
file_location: string,
qwc: string,
created_at: Date,
updated_at: Date
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add security annotations for sensitive fields

The type contains sensitive information (username, password) without any security annotations or handling indicators. Consider:

  1. Adding JSDoc comments to mark sensitive fields
  2. Using a more secure type for password (e.g., never exposing it in plaintext)

Example improvement:

 export type QbdConnectorGet = {
     id: number,
     workspace_id: number,
+    /** @security username should be handled securely */
     username: string,
+    /** @security password should never be exposed in plaintext */
     password: string,
     ticket_id: string,
     file_location: string,
     qwc: string,
     created_at: Date,
     updated_at: Date
 }

Committable suggestion skipped: line range outside the PR's diff.

<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
</div>
<div>
<app-landing-page-body [headlineText]="brandingContent.guideHeaderText" [headerText]="'A quick guide to help you set up your QuickBooks Online integration.'" [embedVideo]="embedVideoLink" [embedImage]="'assets/co/coQBOLanding.svg'" [svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'" [appName]="appName"></app-landing-page-body>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix content inconsistencies and improve maintainability.

  1. The header text mentions "QuickBooks Online" but this is a QuickBooks Desktop integration.
  2. The header text is hardcoded instead of using a property from the component.
  3. The SVG path construction should be moved to the component.
-<app-landing-page-body [headlineText]="brandingContent.guideHeaderText" [headerText]="'A quick guide to help you set up your QuickBooks Online integration.'" [embedVideo]="embedVideoLink" [embedImage]="'assets/co/coQBOLanding.svg'" [svgPath]="'assets/flow-charts/' + brandingConfig.brandId +'-qbd-direct-flow-chart.svg'" [appName]="appName"></app-landing-page-body>
+<app-landing-page-body
+    [headlineText]="brandingContent.guideHeaderText"
+    [headerText]="brandingContent.integrationGuideText"
+    [embedVideo]="embedVideoLink"
+    [embedImage]="'assets/co/coQBDLanding.svg'"
+    [svgPath]="flowChartPath"
+    [appName]="appName">
+</app-landing-page-body>

Consider adding these properties to your component:

integrationGuideText = 'A quick guide to help you set up your QuickBooks Desktop integration.';
flowChartPath = `assets/flow-charts/${this.brandingConfig.brandId}-qbd-direct-flow-chart.svg`;

@@ -2,0 +1,8 @@
<div>
<div>
<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect logo path and non-standard Tailwind class.

  1. The iconPath points to "qbo.png" (QuickBooks Online) but this is a QuickBooks Desktop integration.
  2. The Tailwind class tw-p-16-px doesn't follow the standard format.
-<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
+<app-landing-page-header
+    [buttonText]="'Start'"
+    [iconPath]="'assets/logos/qbd.png'"
+    [appName]="'QuickBooks Desktop - Direct Integration'"
+    [appDescription]="brandingContent.contentText"
+    [isConnectionInProgress]="isQbdConnectionInProgress"
+    [isLoading]="false"
+    [isIntegrationConnected]="false"
+    [redirectLink]="redirectLink"
+    (connectIntegration)="connectQbdDirect()"
+    [logoStyleClasses]="'tw-p-4'">
+</app-landing-page-header>
📝 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.

Suggested change
<app-landing-page-header [buttonText]="'Start'" [iconPath]="'assets/logos/qbo.png'" [appName]="'QuickBooks Desktop - Direct Integration'" [appDescription]="brandingContent.contentText" [isConnectionInProgress]="isQbdConnectionInProgress" [isLoading]="false" [isIntegrationConnected]="false" [redirectLink]="redirectLink" (connectIntegration)="connectQbdDirect()" [logoStyleClasses]="'tw-p-16-px'"></app-landing-page-header>
<app-landing-page-header
[buttonText]="'Start'"
[iconPath]="'assets/logos/qbd.png'"
[appName]="'QuickBooks Desktop - Direct Integration'"
[appDescription]="brandingContent.contentText"
[isConnectionInProgress]="isQbdConnectionInProgress"
[isLoading]="false"
[isIntegrationConnected]="false"
[redirectLink]="redirectLink"
(connectIntegration)="connectQbdDirect()"
[logoStyleClasses]="'tw-p-4'">
</app-landing-page-header>

Comment on lines +21 to +23
syncAttribuites(): Observable<SyncDataType[]> {
return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Fix method name typo and remove unnecessary empty parameters

The method syncAttribuites is used in two locations:

  • src/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-connector.service.ts
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

Both locations need to be updated:

  • Rename syncAttribuites to syncAttributes in the service
  • Update the method call in the component
  • Remove the unnecessary empty object parameter in the service method
// qbd-direct-connector.service.ts
- syncAttribuites(): Observable<SyncDataType[]> {
-   return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
+ syncAttributes(): Observable<SyncDataType[]> {
+   return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`);

// qbd-direct-onboarding-connector.component.ts
- this.qbdDirectConnectorService.syncAttribuites().subscribe((qbdAttribuites: SyncDataType[]) => {
+ this.qbdDirectConnectorService.syncAttributes().subscribe((qbdAttributes: SyncDataType[]) => {
🔗 Analysis chain

Fix method name typo and remove unnecessary empty parameters

Two issues to address:

  1. The method name has a typo ('Attribuites' should be 'Attributes')
  2. The empty object parameter in the GET request is unnecessary

Apply these changes:

- syncAttribuites(): Observable<SyncDataType[]> {
-   return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`, {});
+ syncAttributes(): Observable<SyncDataType[]> {
+   return this.apiService.get(`/workspaces/${this.workspaceService.getWorkspaceId()}/qbd/attribute_stats/`);

Let's verify all occurrences of this method name in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all occurrences of the misspelled method name
rg "syncAttribuites" --type ts

Length of output: 484


Script:

#!/bin/bash
# Search for all occurrences of the misspelled method name (correcting the previous search)
rg "syncAttribuites" --type ts -A 2

# Also search for potential correct spelling to ensure we don't break existing calls
rg "syncAttributes" --type ts -A 2

Length of output: 1082

<app-qbd-direct-data-sync
[isLoading]="isDataSyncLoading"
[qbdFields]="qbdFields"
[isCTAEnabled]="isDataSyncCTADisabled"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the logical inconsistency in isCTAEnabled binding

The [isCTAEnabled] input on line 42 is bound to isDataSyncCTADisabled. Since isDataSyncCTADisabled indicates when the CTA is disabled, binding it directly to isCTAEnabled may cause incorrect behavior.

Consider inverting the value:

[isCTAEnabled]="!isDataSyncCTADisabled"

or renaming the variable to isDataSyncCTAEnabled to accurately reflect its purpose.

Comment on lines +88 to +89
this.isCompanyPathInvalid = filePathRegex.test(normalizedPath);
if (this.isCompanyPathInvalid) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Logical error in variable naming and condition check.

The variable isCompanyPathInvalid suggests that it indicates whether the company path is invalid. However, it is assigned the result of filePathRegex.test(normalizedPath), which returns true when the path matches the regex (i.e., when it's valid). This could cause confusion and lead to incorrect logic in the if statement.

To fix this issue, consider renaming the variable to isCompanyPathValid and updating the condition accordingly:

- this.isCompanyPathInvalid = filePathRegex.test(normalizedPath);
- if (this.isCompanyPathInvalid) {
+ this.isCompanyPathValid = filePathRegex.test(normalizedPath);
+ if (this.isCompanyPathValid) {

This ensures that the variable name accurately reflects its purpose and the condition check aligns with the intended logic.

📝 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.

Suggested change
this.isCompanyPathInvalid = filePathRegex.test(normalizedPath);
if (this.isCompanyPathInvalid) {
this.isCompanyPathValid = filePathRegex.test(normalizedPath);
if (this.isCompanyPathValid) {

this.isCompanyPathInvalid = filePathRegex.test(normalizedPath);
if (this.isCompanyPathInvalid) {
this.isDownloadfileLoading = true;
this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Typographical error in method name postQbdDirectConntion.

There appears to be a typo in the method name postQbdDirectConntion. The correct spelling should likely be postQbdDirectConnection.

Apply this diff to correct the method name:

- this.qbdDirectConnectorService.postQbdDirectConntion({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {
+ this.qbdDirectConnectorService.postQbdDirectConnection({file_location: normalizedPath}).subscribe((connectionResponse: QbdConnectorGet) => {

Additionally, ensure that the QbdDirectConnectorService has the method postQbdDirectConnection properly defined.

Committable suggestion skipped: line range outside the PR's diff.

this.triggerManualDownload();
this.showDownloadLink = true;
});
this.isDownloadfileLoading = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Asynchronous operation may not correctly update isDownloadfileLoading.

The statement this.isDownloadfileLoading = false; is placed immediately after setting up the subscription, which might not accurately reflect the loading state since the HTTP request is asynchronous.

Consider moving this.isDownloadfileLoading = false; inside the subscribe callback to ensure it is set after the asynchronous operation completes:

          });
-         this.isDownloadfileLoading = false;
+         },
+         (error) => {
+           // Handle error
+           this.isDownloadfileLoading = false;
+         },
+         () => {
+           // On completion
+           this.isDownloadfileLoading = false;
+         });

This adjustment ensures that the loading indicator accurately represents the current state of the asynchronous operation.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +19 to +21
configurationHeaderText: 'Connect to QuickBooks desktop',
configurationSubHeaderText: 'Connect to QuickBooks desktop by completing the following steps.',
stepName: 'Connect to QuickBooks Desktop',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct capitalization and update outdated references to NetSuite.

In the connector section:

  • 'QuickBooks desktop' should be capitalized as 'QuickBooks Desktop' for consistency.
  • The subLabel incorrectly references 'NetSuite Tenant Mapping' instead of 'QuickBooks Desktop', which may cause confusion.

Apply this diff to fix the capitalization and update the references:

-configurationHeaderText: 'Connect to QuickBooks desktop',
-configurationSubHeaderText: 'Connect to QuickBooks desktop by completing the following steps.',
-subLabel: 'Expenses will be posted to the NetSuite Tenant Mapping selected here. Once configured, you can not change ' + brandingConfig.brandName + ' organization or Tenant Mapping.'
+configurationHeaderText: 'Connect to QuickBooks Desktop',
+configurationSubHeaderText: 'Connect to QuickBooks Desktop by completing the following steps.',
+subLabel: 'Expenses will be posted to QuickBooks Desktop as selected here. Once configured, you cannot change the ' + brandingConfig.brandName + ' organization or QuickBooks Desktop connection.'

Committable suggestion skipped: line range outside the PR's diff.

@DhaaraniCIT DhaaraniCIT added the deploy Triggers deployment of active branch to Staging label Nov 18, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 and nitpick comments (6)
src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (2)

5-7: Consider making the step number configurable

The step number "2" is hardcoded in the template. Consider making it a configurable input property to improve reusability and maintainability.

+ @Input() stepNumber: number = 2;
- 2
+ {{ stepNumber }}

88-96: Improve success state accessibility and UX

Add ARIA attributes and enhance the success message presentation.

- <div *ngIf="!isLoading && !isStepCompleted && connectionStatus === qbdConnectionStatus.SUCCESS && showSection && !isStepCompleted" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px] tw-text-center">
+ <div *ngIf="!isLoading && !isStepCompleted && connectionStatus === qbdConnectionStatus.SUCCESS && showSection" 
+   class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px] tw-text-center"
+   role="alert"
+   aria-live="polite">
    <div class="tw-text-center">
-     <app-svg-icon svgSource="check-circle-outline" [width]="'24px'" [height]="'24px'" [isTextColorAllowed]="true" [styleClasses]="'tw-text-success-toast tw-pr-6-px'"></app-svg-icon>
+     <app-svg-icon 
+       svgSource="check-circle-outline" 
+       [width]="'24px'" 
+       [height]="'24px'" 
+       [isTextColorAllowed]="true" 
+       [styleClasses]="'tw-text-success-toast tw-pr-6-px'"
+       aria-hidden="true">
+     </app-svg-icon>
    </div>
    <div>
-     <p class="tw-pt-4-px tw-text-text-tertiary tw-text-16-px tw-font-500">Success!</p>
+     <h2 class="tw-pt-4-px tw-text-text-tertiary tw-text-16-px tw-font-500">Connection Successful!</h2>
      <span class="tw-pt-8-px tw-text-text-muted tw-text-12-px tw-font-400">You're now connected to QuickBooks Desktop.</span>
    </div>
</div>
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (4)

55-55: Add type annotations for string properties

Properties xmlFileContent and warningDialogText should have explicit type annotations for better type safety.

- xmlFileContent: string;
+ xmlFileContent: string = '';
- warningDialogText: string;
+ warningDialogText: string = '';

Also applies to: 73-73


43-70: Consider using a state enum instead of multiple boolean flags

The component uses numerous boolean flags to track different states, which could lead to invalid state combinations. Consider using an enum or state machine pattern.

Example approach:

enum OnboardingStep {
  INITIAL,
  DOWNLOADING,
  DOWNLOAD_COMPLETE,
  CONNECTING,
  CONNECTION_COMPLETE,
  DATA_SYNCING,
  DATA_SYNC_COMPLETE
}

private currentStep: OnboardingStep = OnboardingStep.INITIAL;

142-142: Simplify boolean expression

The ternary operator is unnecessary when directly assigning a boolean result.

- this.isDataSyncCTADisabled = onboardingState === QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE ? false : true;
+ this.isDataSyncCTADisabled = onboardingState !== QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE;
🧰 Tools
🪛 Biome

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


209-211: Show success toast before navigation

The success toast might not be visible if shown after navigation. Consider showing it before navigating.

- this.router.navigate([`/integrations/qbd_direct/onboarding/export_settings`]);
- this.isLoading = false;
- this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'QuickBooks Desktop connection successful');
+ this.toastService.displayToastMessage(ToastSeverity.SUCCESS, 'QuickBooks Desktop connection successful');
+ this.isLoading = false;
+ this.router.navigate([`/integrations/qbd_direct/onboarding/export_settings`]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 024398f and e1dc67e.

📒 Files selected for processing (4)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts (1 hunks)
  • src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-setup-connection/qbd-direct-setup-connection.component.html (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.html
  • src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-pre-requisite/qbd-direct-onboarding-pre-requisite.component.ts
🧰 Additional context used
🪛 Biome
src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts

[error] 142-142: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

Comment on lines 39 to 42
<div class="tw-pr-30-px">
<p *ngIf="!isPasswordShown" class="tw-text-16-px tw-text-text-tertiary tw-font-400">****{{password.slice(4)}}</p>
<p *ngIf="isPasswordShown" class="tw-text-16-px tw-text-text-tertiary tw-font-400">{{password}}</p>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance password security implementation

The current password display implementation might be vulnerable to DOM inspection. Consider:

  1. Using a secure password field component
  2. Implementing timing attack protection for visibility toggle
  3. Adding auto-hide timeout for visible password

Would you like me to provide a secure implementation example?

Comment on lines 84 to 87
<div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]">
<app-loader styleClass="spinner-30 tw-top-2-px"></app-loader>
<span class="tw-text-14-px tw-font-400 tw-text-text-primary">Connecting to QuickBooks Desktop...</span>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance loading state accessibility

Add ARIA attributes to improve screen reader support and provide more descriptive loading message.

- <div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]">
+ <div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]" role="status" aria-live="polite">
-   <app-loader styleClass="spinner-30 tw-top-2-px"></app-loader>
+   <app-loader styleClass="spinner-30 tw-top-2-px" aria-label="Connection in progress"></app-loader>
-   <span class="tw-text-14-px tw-font-400 tw-text-text-primary">Connecting to QuickBooks Desktop...</span>
+   <span class="tw-text-14-px tw-font-400 tw-text-text-primary">Establishing secure connection to QuickBooks Desktop. This may take a few moments...</span>
</div>
📝 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.

Suggested change
<div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]">
<app-loader styleClass="spinner-30 tw-top-2-px"></app-loader>
<span class="tw-text-14-px tw-font-400 tw-text-text-primary">Connecting to QuickBooks Desktop...</span>
</div>
<div *ngIf="isLoading" class="tw-flex tw-flex-col tw-justify-center tw-items-center tw-h-[400px]" role="status" aria-live="polite">
<app-loader styleClass="spinner-30 tw-top-2-px" aria-label="Connection in progress"></app-loader>
<span class="tw-text-14-px tw-font-400 tw-text-text-primary">Establishing secure connection to QuickBooks Desktop. This may take a few moments...</span>
</div>

Comment on lines 124 to 135
onConnectionDone(event: CheckBoxUpdate) {
if (event.value) {
interval(3000).pipe(
switchMap(() => this.workspaceService.getWorkspace(this.user.org_id)), // Make HTTP request
takeWhile((status: any) => !this.isTerminalStatus(status[0].onboarding_state as QbdDirectOnboardingState), true) // Stop if terminal status is reached
)
.subscribe(
(status) => this.handleStatus(status[0]),
(error) => console.error('Error polling workspace status:', error)
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance polling implementation with proper error handling and cleanup

The polling implementation should:

  1. Handle errors with user feedback
  2. Clean up subscription on component destruction
  3. Add timeout mechanism
private pollingSubscription?: Subscription;

onConnectionDone(event: CheckBoxUpdate) {
  if (event.value) {
    this.pollingSubscription = interval(3000).pipe(
      switchMap(() => this.workspaceService.getWorkspace(this.user.org_id)),
      takeWhile((status: any) => !this.isTerminalStatus(status[0].onboarding_state as QbdDirectOnboardingState), true),
      timeout(300000) // 5 minutes timeout
    ).subscribe({
      next: (status) => this.handleStatus(status[0]),
      error: (error) => {
        this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Failed to check connection status');
        console.error('Error polling workspace status:', error);
      }
    });
  }
}

ngOnDestroy() {
  this.pollingSubscription?.unsubscribe();
}


proceedToExportSetting() {
this.isLoading = true;
this.workspaceService.updateWorkspaceOnboardingState({onboarding_state: "EXPORT_SETTING"}).subscribe((workspaceResponse: QbdDirectWorkspace) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use enum value instead of hardcoded string

Replace the hardcoded string with the corresponding enum value for type safety.

- this.workspaceService.updateWorkspaceOnboardingState({onboarding_state: "EXPORT_SETTING"})
+ this.workspaceService.updateWorkspaceOnboardingState({onboarding_state: QbdDirectOnboardingState.EXPORT_SETTING})

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +101 to +110
triggerManualDownload() {
const blob = new Blob([this.xmlFileContent], { type: 'text/xml' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
const objectUrl = URL.createObjectURL(blob);
a.href = objectUrl;
a.download = 'fyle_quickbooks.qwc';
a.click();
URL.revokeObjectURL(objectUrl);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix potential memory leak in object URL management

The method creates two object URLs (url and objectUrl) but only revokes one. Additionally, the first URL creation is unused.

 triggerManualDownload() {
   const blob = new Blob([this.xmlFileContent], { type: 'text/xml' });
-  const url = window.URL.createObjectURL(blob);
   const a = document.createElement('a');
   const objectUrl = URL.createObjectURL(blob);
   a.href = objectUrl;
   a.download = 'fyle_quickbooks.qwc';
   a.click();
   URL.revokeObjectURL(objectUrl);
+  a.remove(); // Clean up the DOM
 }
📝 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.

Suggested change
triggerManualDownload() {
const blob = new Blob([this.xmlFileContent], { type: 'text/xml' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
const objectUrl = URL.createObjectURL(blob);
a.href = objectUrl;
a.download = 'fyle_quickbooks.qwc';
a.click();
URL.revokeObjectURL(objectUrl);
}
triggerManualDownload() {
const blob = new Blob([this.xmlFileContent], { type: 'text/xml' });
const a = document.createElement('a');
const objectUrl = URL.createObjectURL(blob);
a.href = objectUrl;
a.download = 'fyle_quickbooks.qwc';
a.click();
URL.revokeObjectURL(objectUrl);
a.remove(); // Clean up the DOM
}

Comment on lines 216 to 230
setupPage() {
this.workspaceService.getWorkspace(this.user.org_id).subscribe((workspaceResponse: QbdDirectWorkspace[]) => {
if (workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.PENDING_QWC_UPLOAD) {
this.isDownloadStepCompleted = true;
this.isDownloadfileLoading = false;
} else if (workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.DESTINATION_SYNC_IN_PROGRESS || workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE) {
this.isDownloadStepCompleted = true;
this.isConnectionStepCompleted = true;
this.isConnectionLoading = false;
this.isDownloadfileLoading = false;
this.proceedToSyncData();
}
this.isLoading = false;
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling to initialization

The setupPage method should handle errors and provide user feedback.

 setupPage() {
   this.workspaceService.getWorkspace(this.user.org_id).subscribe({
+    next: (workspaceResponse: QbdDirectWorkspace[]) => {
       if (workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.PENDING_QWC_UPLOAD) {
         this.isDownloadStepCompleted = true;
         this.isDownloadfileLoading = false;
       } else if (workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.DESTINATION_SYNC_IN_PROGRESS || workspaceResponse[0].onboarding_state === QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE) {
         this.isDownloadStepCompleted = true;
         this.isConnectionStepCompleted = true;
         this.isConnectionLoading = false;
         this.isDownloadfileLoading = false;
         this.proceedToSyncData();
       }
       this.isLoading = false;
+    },
+    error: (error) => {
+      this.isLoading = false;
+      this.toastService.displayToastMessage(ToastSeverity.ERROR, 'Failed to load workspace configuration');
+      console.error('Error loading workspace:', error);
+    }
   });
 }

Committable suggestion skipped: line range outside the PR's diff.

* QA fixes

* qa fixes

* qa fixes

* fix: qbd direct export settings onboarding changes and content changes (#1082)

* qbd direct export settings onboarding changes and content changes

* fix: qbd direct import settings onboarding changes and content changes (#1083)

* qbd direct import settings onboarding changes and content changes

* qbd direct advanced settings onboarding changes and content changes (#1084)

* QA fixes

* fix: QBD direct bug fixes (#1085)

* QBD direct bug fixes

* QBD direct bug fixes

* QBD direct bug fixes
@github-actions github-actions bot added the size/L Large PR label Nov 25, 2024
@github-actions github-actions bot removed the size/XL Extra Large PR label Nov 25, 2024
Copy link

Unit Test Coverage % values
Statements 34.83% ( 4248 / 12195 )
Branches 28.72% ( 1229 / 4279 )
Functions 27.47% ( 939 / 3418 )
Lines 34.97% ( 4178 / 11945 )

@DhaaraniCIT DhaaraniCIT merged commit ec1144a into master Nov 25, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deploy Triggers deployment of active branch to Staging size/L Large PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants