Skip to content

PFM Manager

Personal Financial Management (PFM) GUID retrieval and registration application for client onboarding.

Overview

  • Route: /feature/pfm-manager
  • Framework: Angular 19 (NgModule-based)
  • Main Component: PfmLoginGuidComponent

Features

Client GUID Retrieval

Primary function: Retrieve or register PFM GUID for clients:

typescript
async fetchPfmGuid() {
  this.isLoadingPfmGuid = true;
  this.message = 'Retrieving PFM GUID...';
  
  await this.performHttpService.pfmLoginGuidStatus(this.activeSearchedClient);
  
  this.isLoadingPfmGuid = false;
}

Client Context Integration

Automatic client change detection:

typescript
this.performHttpService.activeSearchedClient.pipe(
  takeUntil(this.unsubscribe$)
).subscribe(async (gcn: string) => {
  if (gcn && gcn !== this.activeSearchedClient) {
    this.activeSearchedClient = gcn;
    await this.fetchPfmGuid();
  }
});

Top Feature Integration

Client Search Button

Opens Client Search in top feature with event-driven state management:

typescript
searchClient() {
  this.isTopFeatureOpen = true;
  
  ipaSdk.platform.sideload.topFeature({
    active: true,
    src: '/feature/one-place-client-search',
    height: 200
  });
  
  // Primary: Listen for client context changes
  const subscription = ipaSdk.data.listenForActiveClientContextChanges()
    .pipe(takeUntil(this.unsubscribe$))
    .subscribe(() => {
      this.isTopFeatureOpen = false;
      subscription.unsubscribe();
    });
  
  // Secondary: Listen for custom close events
  const messageListener = (event: MessageEvent) => {
    if (event.data?.type === 'client-search-closed') {
      this.isTopFeatureOpen = false;
      window.removeEventListener('message', messageListener);
    }
  };
  window.addEventListener('message', messageListener);
}

Event-Driven State

No timeouts - uses reliable event-based approach:

  • Primary reset: listenForActiveClientContextChanges() - when user selects client
  • Secondary reset: MessageEvent listener - when user closes without selection
  • Cleanup: unsubscribe$ pattern prevents memory leaks

Loading Coordination

Parent Loading State

typescript
@Input() parentLoading: boolean = false;
@Input() parentMessage: string = '';

Displays full-page loader while parent component initializes.

Child Loading State

typescript
isLoadingPfmGuid = false;
message = 'Loading...';

Shows loading state during GUID retrieval operations.

Parent Notification

typescript
if (!this.initialSearchDone) {
  this.initialSearchDone = true;
  this.performHttpService.notifyInitialSearchCompleted();
}

Notifies parent when initial search completes so parent can hide its loader.

Parent-Child Communication

Parent Component

typescript
export class PfmManagerComponent {
  isLoading: boolean = true;
  loadingMessage: string = 'Loading page...';
  
  constructor(private performHttpService: PerformHttpService) {
    this.performHttpService.initialSearchCompleted$
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(() => {
        this.isLoading = false;
      });
  }
}

Service Layer

typescript
export class PerformHttpService {
  private initialSearchCompletedSubject = new Subject<void>();
  initialSearchCompleted$ = this.initialSearchCompletedSubject.asObservable();
  
  notifyInitialSearchCompleted(): void {
    this.initialSearchCompletedSubject.next();
  }
}

Data Flow

  1. Component Mount: Shows parent loader ("Loading page...")
  2. Client Selection: User clicks search button → opens Client Search
  3. Context Update: IPA updates active client context
  4. Button Re-enable: Event listener detects change, re-enables button
  5. GUID Fetch: Automatic GUID retrieval starts
  6. Completion: Child notifies parent → hides parent loader
  7. Display: Shows GUID data or registration prompt

Service Integration

PerformHttpService

Provides:

  • activeSearchedClient: Observable for GCN changes
  • pfmLoginGuidStatus(gcn): Fetch or register PFM GUID
  • notifyInitialSearchCompleted(): Loading coordination
  • initialSearchCompleted$: Observable for parent components

Usage Example

typescript
// Set active client
ipaSdk.data.setActiveClient({ gcn: '12345678' });

// Load PFM Manager
ipaSdk.platform.sideload.rightFeature({
  active: true,
  src: '/feature/pfm-manager',
  cols: 12
});

The application will automatically:

  1. Show loading state
  2. Fetch PFM GUID for the client
  3. Display results
  4. Hide parent loader when ready

Error Handling

Graceful error handling with user-friendly messages:

typescript
if (error) {
  this.message = 'Error retrieving PFM GUID';
  // Display error details to user
}