feat: QWC file regeneration - new file path flow#1762
feat: QWC file regeneration - new file path flow#1762JustARatherRidiculouslyLongUsername wants to merge 1 commit intoqwc-regen-prerequisitesfrom
Conversation
WalkthroughThis PR introduces QuickBooks Direct (QBD_DIRECT) regeneration flow support with new branding KB article links, a new onboarding state (COMPANY_NAME_MISMATCH), QWC workflow states, and a substantial refactor of the regenerate QWC component to implement a signal-based multi-step wizard with async download and connection handling. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Component as QBD Regenerate<br/>QWC Component
participant Service as QBD Direct<br/>Connector Service
participant Backend as Backend API
participant Workspace as Workspace Service
participant Storage as Storage Service
User->>Component: Click Download QWC
Component->>Service: handleDownloadClick(filePath)
Service->>Backend: Request QWC file & password
Backend-->>Service: Return XML content & password
Service-->>Component: Success (set state, content, password)
Component->>Storage: Store xmlFileContent & password
Component->>Component: Advance to DOWNLOAD_DONE state
User->>Component: Manual Download or Next Step
Component->>Component: handleManualDownload() / handleDownloadNextStepClick()
Component->>Component: Trigger XML file download
Component->>Component: Advance to SETUP_CONNECTION state
User->>Component: Connection established
Component->>Component: handleConnectionDone(event)
Component->>Workspace: Poll workspace status (interval/switchMap)
Workspace-->>Component: Connection status updates
Component->>Component: Check isTerminalStatus()
alt Terminal State Reached
Component->>Component: handleStatus(state)
Component->>Component: Show warning/success dialog
Component->>Component: Update onboarding state
Component->>Component: Navigate to DONE or error state
else Poll Continues
Workspace-->>Component: Continue polling
end
User->>Component: Confirm or Close Dialog
Component->>Component: handleConnectionNext() / closeDialog()
Component->>Component: Navigate to dashboard
Estimated code review effort🎯 4 (Complex) | ⏱️ ~70 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (9)
src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-qwc-file.model.ts (1)
12-19: Consider using string values for consistency withQwcRegenerationFlowType.
QwcFlowStateuses implicit numeric values while the co-locatedQwcRegenerationFlowTypeuses explicit string values. String enums produce more readable log output and eliminate potential issues with numeric comparisons if the enum order ever shifts.♻️ Proposed refactor
export enum QwcFlowState { - PREREQUISITES, - DOWNLOAD, - DOWNLOAD_IN_PROGRESS, - DOWNLOAD_DONE, - SETUP_CONNECTION, - CONNECTION_IN_PROGRESS, - CONNECTION_DONE + PREREQUISITES = 'PREREQUISITES', + DOWNLOAD = 'DOWNLOAD', + DOWNLOAD_IN_PROGRESS = 'DOWNLOAD_IN_PROGRESS', + DOWNLOAD_DONE = 'DOWNLOAD_DONE', + SETUP_CONNECTION = 'SETUP_CONNECTION', + CONNECTION_IN_PROGRESS = 'CONNECTION_IN_PROGRESS', + CONNECTION_DONE = 'CONNECTION_DONE' }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-qwc-file.model.ts` around lines 12 - 19, QwcFlowState currently uses implicit numeric enum members while the neighboring QwcRegenerationFlowType uses string values; change QwcFlowState to an explicit string enum by assigning each member its name as a string (e.g., PREREQUISITES = "PREREQUISITES", DOWNLOAD = "DOWNLOAD", etc.) so logs and comparisons are readable and stable, and then search for any runtime code that compares against numeric values of QwcFlowState (in switches, equality checks, or persisted data) and update those to compare against the new string values or the enum members (e.g., QwcFlowState.PREREQUISITES) to ensure behavior remains correct.src/app/core/util/downloadFile.ts (1)
16-18: LGTM — consistent with existingdownloadCSVFilepattern.The new
downloadXMLFileutility is clean. Note thatqbd-direct-onboarding-connector.component.ts(triggerManualDownload, lines 111-120) duplicates this logic manually instead of reusing this utility. Consider refactoring that method to usedownloadXMLFilefor consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/core/util/downloadFile.ts` around lines 16 - 18, Duplicate XML-download logic exists: refactor qbd-direct-onboarding-connector.component.ts's triggerManualDownload to call the shared utility downloadXMLFile(content, fileName) instead of reimplementing blob/mime handling. Import downloadXMLFile, remove the manual Blob/new URL/revokeObjectURL code in triggerManualDownload, pass the XML string and desired filename to downloadXMLFile, and ensure any related type/signature differences are adjusted (e.g., content as string and fileName variable) so behavior remains identical.src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts (2)
155-159: Pre-existing:onConnectionDonepolling uses deprecated subscribe signature and silently discards errors.Line 159 logs errors to console but provides no user-facing feedback, unlike the regenerate component which shows a toast message. This is a pre-existing concern.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts` around lines 155 - 159, The polling subscribe call uses the deprecated positional signature and only logs errors to console; change it to the object-style subscribe({ next, error }) so errors are handled properly, route the error into the same user-facing toast mechanism used in the regenerate component (e.g., call the component's toast/toaster service method) instead of console.error, and ensure the error handler stops further processing; locate the subscribe call that invokes handleStatus and isTerminalStatus (and uses takeWhile) to make this change.
111-120: Pre-existing:triggerManualDownloadcreates a redundant blob URL on line 113 that is never revoked.Line 113 creates
urlviacreateObjectURL, and line 115 creates a secondobjectUrlfrom the same blob. OnlyobjectUrlis used and revoked;urlleaks. Consider refactoring this method to use the newdownloadXMLFileutility fromsrc/app/core/util/downloadFile.ts, which would fix the leak and eliminate duplication with the regenerate component'shandleManualDownload.Proposed fix
+import { downloadXMLFile } from 'src/app/core/util/downloadFile'; 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 = 'sem_qbd_integration.qwc'; - a.click(); - URL.revokeObjectURL(objectUrl); + downloadXMLFile(this.xmlFileContent, 'sem_qbd_integration.qwc'); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts` around lines 111 - 120, triggerManualDownload currently creates a redundant blob URL (the local variable url) that is never used or revoked; replace the manual blob/createObjectURL/revoke logic by importing and calling the shared downloadXMLFile utility (same helper used by the regenerate component's handleManualDownload), remove the unused url and the manual revoke, and ensure the function calls downloadXMLFile passing this.xmlFileContent, the filename 'sem_qbd_integration.qwc' and MIME 'text/xml' and add the corresponding import for downloadXMLFile.src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.ts (1)
100-100:filePathparameter is typed asany— should be explicitly typed.Use
string(orstring | null | undefinedif needed) to take advantage of type checking and prevent accidental misuse.Proposed fix
- handleDownloadClick(filePath: any): void { + handleDownloadClick(filePath: string): void {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.ts` at line 100, The handleDownloadClick parameter filePath is currently typed as any; change its signature in qbd-direct-regenerate-qwc-file.component.ts from handleDownloadClick(filePath: any): void to use a stricter type (e.g., filePath: string or filePath: string | null | undefined depending on whether null/undefined is possible) and update any internal null-checks or callers accordingly so TypeScript can enforce correct usage for the handleDownloadClick method.src/app/branding/c1/branding-config.ts (1)
197-203: All fiveQBD_DIRECTpost-onboarding article keys resolve to the same URL.Is this intentional? If different sections of the article should be targeted (like the onboarding articles use
#h_anchors), consider adding distinct fragment identifiers. Otherwise, this is fine as a starting point with differentiation to follow.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/branding/c1/branding-config.ts` around lines 197 - 203, The five QBD_DIRECT keys (REGENERATE_QWC_FILE_LANDING_HEADER, TEAM_ACCESS_QWC_NOT_RECOMMENDED, REGENERATE_QWC_FILE_EXISTING_PATH_WARNING, REGENERATE_QWC_FILE_NEW_PATH_HEADER, REGENERATE_QWC_FILE_NEW_PATH_WARNING) all resolve to the same URL; update each key in branding-config.ts to point to distinct targets by appending appropriate fragment identifiers (e.g., `#h_`<section>) or different article paths on brandingConfig.helpArticleDomain so each UI section links to the correct anchor/section, or explicitly confirm and document that a single shared URL is intentional.src/app/shared/components/configuration/configuration-csv-upload-field/configuration-csv-upload-field.component.ts (1)
21-31: Complete the generic refactor —attributeTypeshould also be parameterized.The component was made generic over
CSVAppName(Line 21), andappResourceKeyanduploadDataare correctly parameterized. However,attributeTyperemains hardcoded toSage50AttributeType(Line 25), breaking the generic contract. SinceCSVImportAttributeTypeForApp<A>exists and resolves the correct attribute type per app, use it here:♻️ Suggested fix
-import { CSVAppName, CSVImportAttributesService } from 'src/app/core/models/db/csv-import-attributes.model'; +import { CSVAppName, CSVImportAttributesService, CSVImportAttributeTypeForApp } from 'src/app/core/models/db/csv-import-attributes.model'; ... - `@Input`({ required: true }) attributeType!: Sage50AttributeType; + `@Input`({ required: true }) attributeType!: CSVImportAttributeTypeForApp<A>;Additionally,
TrackingApp.SAGE50(Line 56) is hardcoded; parameterizing this would require a mapping fromCSVAppNametoTrackingApp.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/shared/components/configuration/configuration-csv-upload-field/configuration-csv-upload-field.component.ts` around lines 21 - 31, The component’s generic was incomplete: change the `@Input` type of attributeType on ConfigurationCsvUploadFieldComponent to use the app-specific type CSVImportAttributeTypeForApp<A> instead of the hardcoded Sage50AttributeType (so attributeType becomes CSVImportAttributeTypeForApp<A>), and update any usages that assume Sage50 types to use the generic type; additionally remove the hardcoded TrackingApp.SAGE50 usage and replace it with a mapping/deriver from the generic appResourceKey (e.g., a small function that maps CSVAppName to TrackingApp) and use that mapping wherever TrackingApp.SAGE50 was referenced so the component fully respects the A generic.src/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.ts (2)
33-39: Type correlation betweenappResourceKeyandattributeTypeis lost.Unlike
ConfigurationCsvImportFieldComponent<A>, this dialog usesCSVAppNamedirectly (not a generic parameter), soattributeTyperesolves to the union of all apps' attribute types. This means TypeScript won't catch a mismatch where, e.g., a SAGE50appResourceKeyis paired with a non-Sage50 attribute type.This is understandable given that
DynamicDialogConfigdata is inherently untyped, but worth noting as a known gap—especially if more apps are added later.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.ts` around lines 33 - 39, The data property loses the correlation between appResourceKey and attributeType because it uses CSVAppName directly; make the component generic (e.g., add a type parameter A extends CSVAppName on the component/class) and change the data shape to use that generic: attributeType: CSVImportAttributeTypeForApp<A>, appResourceKey: A, uploadData: CSVImportAttributesService<A>['importAttributes']; update any instantiation sites (DynamicDialogConfig data casts) to supply the concrete A so TypeScript can enforce matching types (see data, CSVImportAttributeTypeForApp, CSVAppName, CSVImportAttributesService and ConfigurationCsvImportFieldComponent<A> for reference).
162-165: Hardcoded Sage50 display-name lookup in an app-agnostic component.Line 164 uses
sage50AttributeDisplayNames[this.data.attributeType], which ties this dialog to Sage50 even though the rest of the refactor is making it app-agnostic viaCSVAppName. If another app is added toCSVImportAttributeTypeMap, this lookup will produceundefined.Consider passing
displayNamedirectly in the dialog data, or creating a per-app display-name map keyed byCSVAppName.Proposed approach: pass displayName via dialog data
data!: { attributeType: CSVImportAttributeTypeForApp<CSVAppName>, articleLink: string, videoURL: string, appResourceKey: CSVAppName, - uploadData: CSVImportAttributesService<CSVAppName>['importAttributes'] + uploadData: CSVImportAttributesService<CSVAppName>['importAttributes'], + displayName: string }; - displayName: string; ... ngOnInit(): void { this.data = this.config.data; - this.displayName = sage50AttributeDisplayNames[this.data.attributeType]; + this.displayName = this.data.displayName; }The caller (
configuration-csv-import-field) already knows the dimension display name and can pass it along.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.ts` around lines 162 - 165, ngOnInit currently reads displayName directly from sage50AttributeDisplayNames (sage50AttributeDisplayNames[this.data.attributeType]) which hardcodes Sage50 into an app-agnostic dialog; change it to use a caller-provided displayName if present (this.data.displayName) and otherwise perform a lookup from a per-app map keyed by this.data.CSVAppName (e.g., CSVAttributeDisplayNames[this.data.CSVAppName]?.[this.data.attributeType]); update callers (like configuration-csv-import-field) to pass displayName when they know it, or add entries to CSVAttributeDisplayNames for each app and ensure ngOnInit falls back gracefully (undefined-safe) to avoid returning the Sage50-only value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/core/models/enum/enum.model.ts`:
- Line 402: The onboarding connector's isTerminalStatus method in
qbd-direct-onboarding-connector.component.ts currently omits the enum value
COMPANY_NAME_MISMATCH, which causes polling to never stop if the backend returns
that state; update isTerminalStatus to include
QbdDirectOnboardingState.COMPANY_NAME_MISMATCH in the array of terminal states
(alongside DESTINATION_SYNC_IN_PROGRESS, INCORRECT_PASSWORD,
INCORRECT_COMPANY_PATH, DESTINATION_SYNC_COMPLETE) so the method treats
COMPANY_NAME_MISMATCH as a terminal status and polling will terminate.
In
`@src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.html`:
- Around line 23-25: The QwcFlowState enum relies on implicit numeric ordering
which can break if members are reordered; update the QwcFlowState enum
declaration to assign explicit numeric values (e.g., PREREQUISITES = 0,
DOWNLOAD_IN_PROGRESS = 1, DOWNLOAD_DONE = 2, etc.) so comparisons like state()
=== QwcFlowState.DOWNLOAD_IN_PROGRESS and state() > QwcFlowState.DOWNLOAD_DONE
remain stable; ensure every enum member in QwcFlowState has an explicit integer
value preserving the intended sequence used by state().
In
`@src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.ts`:
- Around line 194-205: The updateWorkspaceOnboardingState call in the
DESTINATION_SYNC_COMPLETE branch only logs errors to console so users get no
feedback and remain in CONNECTION_IN_PROGRESS; change the error handler on
workspaceService.updateWorkspaceOnboardingState (the subscription inside the if
branch handling QbdDirectOnboardingState.DESTINATION_SYNC_COMPLETE) to surface a
user-facing error (e.g., call your notification/toast service or set a UI error
state) and transition this.state to an error/retry flow (instead of leaving it
stuck) so the UI shows the failure and exposes a retry that re-invokes
workspaceService.updateWorkspaceOnboardingState and ultimately calls
this.state.set(QwcFlowState.CONNECTION_DONE) on success.
- Around line 48-55: The computed connectionStatus currently maps every
non-CONNECTION_DONE QwcFlowState to QBDConnectionStatus.INCORRECT_COMPANY_PATH
causing premature error UI; update the logic in connectionStatus (in
qbd-direct-regenerate-qwc-file.component.ts) to return a neutral/in-progress
value for non-terminal states (e.g., return QBDConnectionStatus.PENDING or
QBDConnectionStatus.UNKNOWN) and only map terminal states (e.g.,
QwcFlowState.CONNECTION_DONE -> QBDConnectionStatus.SUCCESS and a failure state
-> QBDConnectionStatus.INCORRECT_COMPANY_PATH) so the template sees an error
status only after a terminal failure.
- Around line 138-141: The handler handleConnectionDone currently sets
this.state.set(QwcFlowState.CONNECTION_IN_PROGRESS) unconditionally and then
only proceeds when event.value is true, leaving the component stuck when the
checkbox is unchecked; change the logic so the state transition is guarded or
the false branch is handled: either move the
this.state.set(QwcFlowState.CONNECTION_IN_PROGRESS) inside the if (event.value)
block, or add an explicit else that resets this.state to the idle/neutral state
(e.g., QwcFlowState.CONNECTION_IDLE or previousState) and aborts any started
work; ensure any user lookup (storageService.get('user')) and subsequent
processing only runs when event.value is true and that the false branch cancels
timers/polling and updates the UI state accordingly.
- Around line 138-158: The polling subscription created in handleConnectionDone
(interval(...).pipe(...).subscribe(...)) is never cleaned up; update the
component to store/teardown the subscription by adding a private destroy$ = new
Subject<void>() and piping takeUntil(this.destroy$) into the observable (before
subscribe) or capture the Subscription and unsubscribe it in ngOnDestroy; ensure
you reference handleConnectionDone, isTerminalStatus, handleStatus,
workspaceService and storageService correctly and call this.destroy$.next();
this.destroy$.complete() (or unsubscribe) in ngOnDestroy to prevent polling
after component destruction.
- Around line 129-136: The subscription to
workspaceService.updateWorkspaceOnboardingState in handleDownloadNextStepClick
currently has no error handler, so if the API fails the UI remains in
QwcFlowState.DOWNLOAD_IN_PROGRESS; update handleDownloadNextStepClick to add an
error callback to the subscribe call that resets or advances the flow (e.g., set
this.state.set(QwcFlowState.ERROR) or revert to a safe state), surface user
feedback (toast/processLogger) and optionally log the error; ensure you
reference the existing symbols: handleDownloadNextStepClick, this.state.set,
workspaceService.updateWorkspaceOnboardingState,
QwcFlowState.DOWNLOAD_IN_PROGRESS and QwcFlowState.SETUP_CONNECTION when making
the change.
In
`@src/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.ts`:
- Around line 157-159: The code unsafely casts this.data.appResourceKey (a
CSVAppName) to TrackingApp inside downloadErrorLog; instead create a safe
mapping from CSVAppName → TrackingApp (e.g., a const map keyed by
CSVImportAttributeTypeMap keys) and use it to look up the TrackingApp before
calling trackingService.onClickEvent, handling a missing mapping with a safe
default or early return and a warning; alternatively change the dialog input to
accept a TrackingApp directly so downloadErrorLog uses that value; update
references in downloadErrorLog to use the mapped/trusted TrackingApp rather than
using "as" on this.data.appResourceKey.
In `@src/assets/i18n/en.json`:
- Around line 2783-2796: Reorder the child keys inside the
qbdDirectRegenerateQwcFile object so they are alphabetically sorted as required
by the i18n guideline: companyNameMismatchMessage, connectionError,
connectionFailed, connectionSuccessToast, downloadError, gotIt,
headerSubTitleExistingPath, headerSubTitleNewPath, headerTitleExistingPath,
headerTitleNewPath, incorrectCompanyPathMessage, incorrectPasswordMessage;
locate the qbdDirectRegenerateQwcFile block in src/assets/i18n/en.json and
rearrange the existing key/value pairs accordingly without changing any string
values.
---
Nitpick comments:
In `@src/app/branding/c1/branding-config.ts`:
- Around line 197-203: The five QBD_DIRECT keys
(REGENERATE_QWC_FILE_LANDING_HEADER, TEAM_ACCESS_QWC_NOT_RECOMMENDED,
REGENERATE_QWC_FILE_EXISTING_PATH_WARNING, REGENERATE_QWC_FILE_NEW_PATH_HEADER,
REGENERATE_QWC_FILE_NEW_PATH_WARNING) all resolve to the same URL; update each
key in branding-config.ts to point to distinct targets by appending appropriate
fragment identifiers (e.g., `#h_`<section>) or different article paths on
brandingConfig.helpArticleDomain so each UI section links to the correct
anchor/section, or explicitly confirm and document that a single shared URL is
intentional.
In
`@src/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-qwc-file.model.ts`:
- Around line 12-19: QwcFlowState currently uses implicit numeric enum members
while the neighboring QwcRegenerationFlowType uses string values; change
QwcFlowState to an explicit string enum by assigning each member its name as a
string (e.g., PREREQUISITES = "PREREQUISITES", DOWNLOAD = "DOWNLOAD", etc.) so
logs and comparisons are readable and stable, and then search for any runtime
code that compares against numeric values of QwcFlowState (in switches, equality
checks, or persisted data) and update those to compare against the new string
values or the enum members (e.g., QwcFlowState.PREREQUISITES) to ensure behavior
remains correct.
In `@src/app/core/util/downloadFile.ts`:
- Around line 16-18: Duplicate XML-download logic exists: refactor
qbd-direct-onboarding-connector.component.ts's triggerManualDownload to call the
shared utility downloadXMLFile(content, fileName) instead of reimplementing
blob/mime handling. Import downloadXMLFile, remove the manual Blob/new
URL/revokeObjectURL code in triggerManualDownload, pass the XML string and
desired filename to downloadXMLFile, and ensure any related type/signature
differences are adjusted (e.g., content as string and fileName variable) so
behavior remains identical.
In
`@src/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.ts`:
- Around line 155-159: The polling subscribe call uses the deprecated positional
signature and only logs errors to console; change it to the object-style
subscribe({ next, error }) so errors are handled properly, route the error into
the same user-facing toast mechanism used in the regenerate component (e.g.,
call the component's toast/toaster service method) instead of console.error, and
ensure the error handler stops further processing; locate the subscribe call
that invokes handleStatus and isTerminalStatus (and uses takeWhile) to make this
change.
- Around line 111-120: triggerManualDownload currently creates a redundant blob
URL (the local variable url) that is never used or revoked; replace the manual
blob/createObjectURL/revoke logic by importing and calling the shared
downloadXMLFile utility (same helper used by the regenerate component's
handleManualDownload), remove the unused url and the manual revoke, and ensure
the function calls downloadXMLFile passing this.xmlFileContent, the filename
'sem_qbd_integration.qwc' and MIME 'text/xml' and add the corresponding import
for downloadXMLFile.
In
`@src/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.ts`:
- Line 100: The handleDownloadClick parameter filePath is currently typed as
any; change its signature in qbd-direct-regenerate-qwc-file.component.ts from
handleDownloadClick(filePath: any): void to use a stricter type (e.g., filePath:
string or filePath: string | null | undefined depending on whether
null/undefined is possible) and update any internal null-checks or callers
accordingly so TypeScript can enforce correct usage for the handleDownloadClick
method.
In
`@src/app/shared/components/configuration/configuration-csv-upload-field/configuration-csv-upload-field.component.ts`:
- Around line 21-31: The component’s generic was incomplete: change the `@Input`
type of attributeType on ConfigurationCsvUploadFieldComponent to use the
app-specific type CSVImportAttributeTypeForApp<A> instead of the hardcoded
Sage50AttributeType (so attributeType becomes CSVImportAttributeTypeForApp<A>),
and update any usages that assume Sage50 types to use the generic type;
additionally remove the hardcoded TrackingApp.SAGE50 usage and replace it with a
mapping/deriver from the generic appResourceKey (e.g., a small function that
maps CSVAppName to TrackingApp) and use that mapping wherever TrackingApp.SAGE50
was referenced so the component fully respects the A generic.
In
`@src/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.ts`:
- Around line 33-39: The data property loses the correlation between
appResourceKey and attributeType because it uses CSVAppName directly; make the
component generic (e.g., add a type parameter A extends CSVAppName on the
component/class) and change the data shape to use that generic: attributeType:
CSVImportAttributeTypeForApp<A>, appResourceKey: A, uploadData:
CSVImportAttributesService<A>['importAttributes']; update any instantiation
sites (DynamicDialogConfig data casts) to supply the concrete A so TypeScript
can enforce matching types (see data, CSVImportAttributeTypeForApp, CSVAppName,
CSVImportAttributesService and ConfigurationCsvImportFieldComponent<A> for
reference).
- Around line 162-165: ngOnInit currently reads displayName directly from
sage50AttributeDisplayNames
(sage50AttributeDisplayNames[this.data.attributeType]) which hardcodes Sage50
into an app-agnostic dialog; change it to use a caller-provided displayName if
present (this.data.displayName) and otherwise perform a lookup from a per-app
map keyed by this.data.CSVAppName (e.g.,
CSVAttributeDisplayNames[this.data.CSVAppName]?.[this.data.attributeType]);
update callers (like configuration-csv-import-field) to pass displayName when
they know it, or add entries to CSVAttributeDisplayNames for each app and ensure
ngOnInit falls back gracefully (undefined-safe) to avoid returning the
Sage50-only value.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
src/app/branding/c1/branding-config.tssrc/app/branding/fyle/branding-config.tssrc/app/core/models/branding/kb-article.model.tssrc/app/core/models/db/csv-import-attributes.model.tssrc/app/core/models/enum/enum.model.tssrc/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.model.tssrc/app/core/models/qbd-direct/qbd-direct-configuration/qbd-direct-qwc-file.model.tssrc/app/core/services/qbd-direct/qbd-direct-configuration/qbd-direct-onboarding.service.tssrc/app/core/services/sage50/sage50-configuration/sage50-import-attributes.service.tssrc/app/core/util/downloadFile.tssrc/app/integrations/qbd-direct/qbd-direct-onboarding/qbd-direct-onboarding-connector/qbd-direct-onboarding-connector.component.tssrc/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-qwc-file-landing/qbd-direct-qwc-file-landing.component.htmlsrc/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-qwc-file-landing/qbd-direct-qwc-file-landing.component.tssrc/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.htmlsrc/app/integrations/qbd-direct/qbd-direct-shared/qbd-direct-qwc-file/qbd-direct-regenerate-qwc-file/qbd-direct-regenerate-qwc-file.component.tssrc/app/integrations/qbd-direct/qbd-direct.component.tssrc/app/shared/components/configuration/configuration-csv-import-field/configuration-csv-import-field.component.tssrc/app/shared/components/configuration/configuration-csv-upload-field/configuration-csv-upload-field.component.tssrc/app/shared/components/configuration/configuration-step-header/configuration-step-header.component.tssrc/app/shared/components/dialog/csv-upload-dialog/csv-upload-dialog.component.tssrc/assets/i18n/en.json
Description
Clickup
https://app.clickup.com/t/86d1x6zz4
Summary by CodeRabbit
Release Notes
New Features
Documentation