From 5e6240e657317ffce9be043f1c1c635d75f5e3e4 Mon Sep 17 00:00:00 2001 From: Viswas Haridas <37623357+JustARatherRidiculouslyLongUsername@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:54:10 +0530 Subject: [PATCH] feat: add sync dimensions polling to netsuite onboarding (#917) * refactor: extract poll dimension sync status into a global helper function * feat: add dimensions sync status polling to netsuite onboarding (cherry picked from commit 8a4c06c45ed7327cd91e61962b565efcbbd7eed0) --- .../core/services/common/helper.service.ts | 41 ++++++++++++++++ .../netsuite-subsidiary-mapping.component.ts | 17 +++++-- .../intacct-location-entity.component.ts | 48 ++++--------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/app/core/services/common/helper.service.ts b/src/app/core/services/common/helper.service.ts index 1df42eb4e..e84d36050 100644 --- a/src/app/core/services/common/helper.service.ts +++ b/src/app/core/services/common/helper.service.ts @@ -13,6 +13,12 @@ import { brandingConfig } from 'src/app/branding/branding-config'; import { SentenceCasePipe } from 'src/app/shared/pipes/sentence-case.pipe'; import { TitleCasePipe } from '@angular/common'; import { DefaultDestinationAttribute, DestinationAttribute } from '../../models/db/destination-attribute.model'; +import { Observable, interval, take } from 'rxjs'; + +type PollDimensionsSyncStatusParams = { + onPollingComplete: () => void + getWorkspacesObserver: () => Observable<{destination_synced_at: any}[]> +} @Injectable({ providedIn: 'root' @@ -286,4 +292,39 @@ export class HelperService { options.sort((a, b) => (a.name || '').localeCompare(b.name || '')); } + + /** + * Checks every `DIMENSIONS_POLLING_INTERVAL` ms whether dimensions have been refreshed + * for a maximum of `DIMENSIONS_POLLING_TIMEOUT` ms. + * + * Terminates either when dimensions have been refreshed, when refresh dimensions fails, + * or when polling times out - whichever occurs first. + */ + pollDimensionsSyncStatus({onPollingComplete, getWorkspacesObserver}: PollDimensionsSyncStatusParams) { + + /** Time (in ms) to wait before each request while polling for refresh dimensions status */ + const DIMENSIONS_POLLING_INTERVAL = 3000; + + /** Maximum time (in ms) to wait before terminating the poll for refresh dimensions status */ + const DIMENSIONS_POLLING_TIMEOUT = 60_000; + + const ticks = Math.floor(DIMENSIONS_POLLING_TIMEOUT / DIMENSIONS_POLLING_INTERVAL); + + const pollingSubscription = interval(DIMENSIONS_POLLING_INTERVAL).pipe(take(ticks)).subscribe( + { + next: (_tick) => { + getWorkspacesObserver().subscribe(workspaces => { + const {destination_synced_at} = workspaces[0]; + if (destination_synced_at !== null) { + onPollingComplete(); + pollingSubscription.unsubscribe(); + } + }); + }, + + complete: () => { + onPollingComplete(); + } + }); + } } diff --git a/src/app/shared/components/netsuite/core/netsuite-subsidiary-mapping/netsuite-subsidiary-mapping.component.ts b/src/app/shared/components/netsuite/core/netsuite-subsidiary-mapping/netsuite-subsidiary-mapping.component.ts index 273bc8fa4..9ee0b7045 100644 --- a/src/app/shared/components/netsuite/core/netsuite-subsidiary-mapping/netsuite-subsidiary-mapping.component.ts +++ b/src/app/shared/components/netsuite/core/netsuite-subsidiary-mapping/netsuite-subsidiary-mapping.component.ts @@ -6,6 +6,7 @@ import { AppName, ConfigurationCta, NetsuiteOnboardingState, ToastSeverity, Trac import { NetsuiteDestinationAttribute } from 'src/app/core/models/netsuite/db/destination-attribute.model'; import { NetsuiteSubsidiaryMappingModel, SubsidiaryMapping } from 'src/app/core/models/netsuite/db/subsidiary-mapping.model'; import { NetsuiteSubsidiaryMappingPost } from 'src/app/core/models/netsuite/netsuite-configuration/netsuite-connector.model'; +import { HelperService } from 'src/app/core/services/common/helper.service'; import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service'; import { MappingService } from 'src/app/core/services/common/mapping.service'; import { StorageService } from 'src/app/core/services/common/storage.service'; @@ -66,7 +67,8 @@ export class NetsuiteSubsidiaryMappingComponent implements OnInit { private router: Router, private workspaceService: WorkspaceService, private toastService: IntegrationsToastService, - private trackingService: TrackingService + private trackingService: TrackingService, + private helperService: HelperService ) { } @@ -114,10 +116,15 @@ export class NetsuiteSubsidiaryMappingComponent implements OnInit { private handleSuccess(netsuiteSubsidiaryMappingPayload: NetsuiteSubsidiaryMappingPost): void { this.isRefreshDimensionInProgress = true; - this.netsuiteMappingsService.refreshNetsuiteDimensions().subscribe(() => { - this.setOnboardingStateAndRedirect(netsuiteSubsidiaryMappingPayload); - }, () => { - this.setOnboardingStateAndRedirect(netsuiteSubsidiaryMappingPayload); + + this.netsuiteMappingsService.refreshNetsuiteDimensions().subscribe(); + + const fyleOrgId = this.storageService.get('org').fyle_org_id; + this.helperService.pollDimensionsSyncStatus({ + onPollingComplete: () => { + this.setOnboardingStateAndRedirect(netsuiteSubsidiaryMappingPayload); + }, + getWorkspacesObserver: () => this.workspaceService.getWorkspace(fyleOrgId) }); } diff --git a/src/app/shared/components/si/core/intacct-location-entity/intacct-location-entity.component.ts b/src/app/shared/components/si/core/intacct-location-entity/intacct-location-entity.component.ts index c10ae277c..79a8b1d5f 100644 --- a/src/app/shared/components/si/core/intacct-location-entity/intacct-location-entity.component.ts +++ b/src/app/shared/components/si/core/intacct-location-entity/intacct-location-entity.component.ts @@ -14,12 +14,7 @@ import { SiMappingsService } from 'src/app/core/services/si/si-core/si-mappings. import { IntacctDestinationAttribute } from 'src/app/core/models/intacct/db/destination-attribute.model'; import { brandingConfig, brandingContent, brandingFeatureConfig, brandingKbArticles } from 'src/app/branding/branding-config'; import { interval, take } from 'rxjs'; - -/** Time (in ms) to wait before each request while polling for refresh dimensions status */ -const DIMENSIONS_POLLING_INTERVAL = 3000; - -/** Maximum time (in ms) to wait before terminating the poll for refresh dimensions status */ -const DIMENSIONS_POLLING_TIMEOUT = 60_000; +import { HelperService } from 'src/app/core/services/common/helper.service'; @Component({ selector: 'app-intacct-location-entity', @@ -67,7 +62,8 @@ export class IntacctLocationEntityComponent implements OnInit { private router: Router, private workspaceService: SiWorkspaceService, private toastService: IntegrationsToastService, - private trackingService: TrackingService + private trackingService: TrackingService, + private helperService: HelperService ) { } patchFormValue(event: any): void { @@ -133,41 +129,13 @@ export class IntacctLocationEntityComponent implements OnInit { this.isRefreshDimensionInProgress = true; this.mappingsService.refreshSageIntacctDimensions().subscribe(); - this.pollDimensionsSyncStatus({ - onPollingComplete: () => { - this.setOnboardingStateAndRedirect(locationEntityMappingPayload); - } - }); - } - - /** - * Checks every `DIMENSIONS_POLLING_INTERVAL` ms whether dimensions have been refreshed - * for a maximum of `DIMENSIONS_POLLING_TIMEOUT` ms. - * - * Terminates either when dimensions have been refreshed, when refresh dimensions fails, - * or when polling times out - whichever occurs first. - */ - private pollDimensionsSyncStatus({onPollingComplete}: {onPollingComplete: () => void}) { - const ticks = Math.floor(DIMENSIONS_POLLING_TIMEOUT / DIMENSIONS_POLLING_INTERVAL); const fyleOrgId = this.storageService.get('org').fyle_org_id; - - const pollingSubscription = interval(DIMENSIONS_POLLING_INTERVAL).pipe(take(ticks)).subscribe( - { - next: (_tick) => { - this.workspaceService.getWorkspaceWithoutCache(fyleOrgId, true).subscribe(workspaces => { - const {destination_synced_at} = workspaces[0]; - - if (destination_synced_at !== null) { - onPollingComplete(); - pollingSubscription.unsubscribe(); - } - }); - }, - - complete: () => { - onPollingComplete(); - } + this.helperService.pollDimensionsSyncStatus({ + onPollingComplete: () => { + this.setOnboardingStateAndRedirect(locationEntityMappingPayload); + }, + getWorkspacesObserver: () => this.workspaceService.getWorkspaceWithoutCache(fyleOrgId, true) }); }