Skip to content

@presencelearning/documentation

Angular library for the clinical-documentation workflow shared across Presence frontends — session notes, appointment management, IEP-goal metrics tracking, evaluation recording, and the cross-window pop-out documentation surface.

  • Standalone Angular componentsDocumentationPanelComponent, DocumentationWindowComponent, DocumentationTabsComponent, session-notes editor, tracked metrics, appointment selection, evaluation recording, session-events timeline
  • Abstract service contract — Consumer apps provide a concrete DocumentationService implementation for backend operations (fetch appointments, save records, IEP metric mutations, etc.); the library handles UI state, signal stores, and the NgRx pipeline
  • Pop-out documentation window — Open a session in its own browser window via /documentation/window/:instanceId; survives parent-tab refresh and signs off back to the parent via BroadcastChannel
  • Signal stores and NgRxDocumentationAppointmentStore, DocumentationGlobalStore, DocumentationPolishNotesStore, AppointmentTabsStore, DocumentationAmendmentsStore, plus a full NgRx slice (documentationReducer, DocumentationActions, DocumentationEffects, selectors)
  • AI note polishing — Polished SOAP-note suggestions surface in SessionNotesSuggestionComponent; consumers wire up the backend call
  • Tracked metrics — IEP-goal metrics with score tracking, percent-correct computation, and dropdown/dialog selection UIs
  • Evaluations — Evaluation documents, concern areas, assessment components, and report upload/delete, driven by DocumentationService’s evaluation members
  • AmendmentsAmendmentsComponent and DocumentationAmendmentsStore for amending a signed-off note
  • Cross-window broadcastDocumentationBroadcastService and SessionEventsBroadcastService keep multiple open windows in sync
Terminal window
npm install @presencelearning/documentation

Install these in your application:

Terminal window
npm install @angular/common @angular/core @angular/forms @angular/animations @angular/router
npm install @angular/cdk @angular/material
npm install @ngrx/store @ngrx/effects @ngrx/signals @ngrx/entity
npm install rxjs @presencelearning/styles

Angular and NgRx peers are >=19.0.0 <22.0.0; @presencelearning/styles is ^1.0.0 and is not optional.

@lottiefiles/dotlottie-web is flagged optional in package.json, but DocumentationPanelComponent imports it statically — so any app rendering the main panel needs it:

Terminal window
npm install @lottiefiles/dotlottie-web

The library requires a concrete implementation of the abstract DocumentationService. This is the bulk of the integration work: the class declares roughly 55 abstract members covering appointments, billing, notes, evaluations, metrics, session events, notifications and dialogs, analytics (trackEvent), URL builders, and the DocumentationState persistence layer, plus the eventStream$ and admissionEventsChanged$ observables. Check the shipped .d.ts for the authoritative list.

import { Injectable, signal } from '@angular/core';
import { Observable, of } from 'rxjs';
import { DocumentationService, DocumentationAppointment } from '@presencelearning/documentation';
@Injectable({ providedIn: 'root' })
export class MyDocumentationService extends DocumentationService {
isReady = signal(false);
isRefreshing = signal(false);
readonlyMode = signal(false);
refreshAppointments(): void {
// Your backend call
}
loadAppointmentData(appointment: DocumentationAppointment): void {
// Your backend call
}
// …implement every abstract member
}

The three abstract signal members are isReady, isRefreshing, and readonlyMode. Recording is a separate contract — see EvaluationRecordingService below.

import { ApplicationConfig } from '@angular/core';
import { provideStore } from '@ngrx/store';
import { provideEffects } from '@ngrx/effects';
import {
DocumentationEffects,
documentationReducer,
provideDocumentation,
} from '@presencelearning/documentation';
import { MyDocumentationService } from './my-documentation.service';
export const appConfig: ApplicationConfig = {
providers: [
provideDocumentation(MyDocumentationService, {
// Optional — defaults shown:
// registerIcons: true,
// windowUrlBase: '/documentation/window',
// source: 'room',
// recordingService: MyEvaluationRecordingService,
}),
provideStore({ documentation: documentationReducer }),
provideEffects(DocumentationEffects),
],
};

provideDocumentation() wires the abstract DocumentationService binding and registers the library’s SVG icons with MatIconRegistry. ProvideDocumentationOptions:

| Option | Default | Description | | ------------------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | registerIcons | true | Register the library’s SVG icons. Opt out if your app registers its own | | windowUrlBase | '/documentation/window' | Base path for the pop-out window URL. Must match the route you register in step 4 | | source | 'room' | Analytics namespace. Composed with the current surface into <namespace>_<surface> for log and tracking values | | recordingService | — | Concrete EvaluationRecordingService implementation. Without it the recording UI is silently hidden, because the component injects it as optional |

import { Component } from '@angular/core';
import { DocumentationPanelComponent } from '@presencelearning/documentation';
@Component({
selector: 'app-session',
standalone: true,
imports: [DocumentationPanelComponent],
template: `
<div #container>
<pl-documentation-panel [parentElement]="container" (signOffChange)="onSignOff($event)" />
</div>
`,
})
export class SessionComponent {
onSignOff(signedOff: boolean): void {
// React to sign-off
}
}

The panel does not take an appointment input — it reads the current selection from the stores. Its inputs are parentElement (required, Element), tabMode, and windowMode. Outputs: openInNew, switchToDrawer, minimize, close, openInTab, signOffChange, closeDrawer, billingCodeChange.

4. (Optional) Add the pop-out window route

Section titled “4. (Optional) Add the pop-out window route”

DocumentationWindowComponent is what renders inside a pop-out window when the user opens documentation in its own browser window. Register a route for it so the URL built by DocumentationWindowService.openAppointmentWindow(apptId) resolves.

import { Routes } from '@angular/router';
import { DocumentationWindowComponent } from '@presencelearning/documentation';
export const routes: Routes = [
{ path: 'documentation/window/:instanceId', component: DocumentationWindowComponent },
];

| Component | Selector | Purpose | | ------------------------------- | -------------------------- | ----------------------------------------------------------------- | | DocumentationPanelComponent | pl-documentation-panel | Main documentation panel with tabs for notes, metrics, and events | | DocumentationWindowComponent | pl-documentation-window | Standalone pop-out window for a single appointment | | DocumentationTabsComponent | pl-documentation-tabs | Mini-window tab bar for multiple concurrent appointments | | AppointmentSelectionComponent | pl-appointment-selection | Appointment picker / list | | SessionNotesComponent | pl-session-notes | SOAP-notes editor (subjective, objective, assessment, plan) | | TrackedMetricsComponent | pl-tracked-metrics | IEP-goal metrics tracking | | SessionEventsComponent | pl-session-events | Timeline of session events | | AppointmentDetailsComponent | pl-appointment-details | Client info, billing code, service selection | | EvaluationRecordingComponent | pl-evaluation-recording | Evaluation-recording controls | | TimestampTrackingComponent | pl-timestamp-tracking | Client admission timestamps | | AmendmentsComponent | pl-amendments | Amend a signed-off note. Input: isNewEvent |

The package exports 26 components in total. The rest are the sub-components those surfaces compose — DocumentationPanelFooterComponent, DocumentationTabsWindowComponent, AppointmentSelectionItemComponent, AppointmentDetailsSelectComponent, AppointmentTabComponent, ClientCardComponent, NoteDictationComponent, SessionEventComponent, SessionNotesDialogComponent, SessionNotesFieldComponent, SessionNotesSuggestionComponent, TrackedMetricsDropdownComponent, TrackedMetricsItemComponent, TrackedMetricsItemScoreComponent, and TrackedMetricsSelectComponent — exported so consumers can compose their own layouts.

Live previews for every component (including states, controls, and design references) live in Storybook.

| Service | Purpose | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | DocumentationWindowService | Opens, closes, reconnects, and focuses pop-out windows — openAppointmentWindow, openAppointment, closeAppointment, reconnectAppointment, focusAppointmentWindow | | DocumentationBroadcastService | Cross-window sync for documentation state | | SessionEventsBroadcastService | Cross-window sync for the session-events timeline | | ResizeObserverService | Element resize observation used by the drawer | | BrowserService | Browser capability and window helpers | | LocalStorageService | Typed localStorage access, keyed by LocalStorageKey |

import {
AppointmentTabsStore,
DocumentationAmendmentsStore,
DocumentationAppointmentStore,
DocumentationGlobalStore,
DocumentationPolishNotesStore,
} from '@presencelearning/documentation';

| Store | Holds | | ------------------------------- | ---------------------------------------------------------- | | DocumentationAppointmentStore | Appointment entities, selection state | | DocumentationGlobalStore | Provider info, billing codes, note schemas, surface/source | | DocumentationPolishNotesStore | AI-generated note suggestions | | AppointmentTabsStore | Mini-window tab state | | DocumentationAmendmentsStore | Amendment drafts (AmendmentDraft) |

import {
DocumentationActions,
DocumentationEffects,
DocumentationState,
documentationReducer,
initialState,
selectCurrentTab,
selectCurrentTabForClientId,
selectDocumentation,
selectDrawerClientIds,
selectDrawerWidth,
selectTabClientIds,
selectTimestampTrackingEnabled,
} from '@presencelearning/documentation';

Evaluation support landed in 1.0.0 and is driven entirely through DocumentationService. The abstract members to implement are getEvaluationDocumentForAppointment, getEvaluationComponentsForAppointment, updateEvaluationComponentForAppointment, updateEvaluationComponentDetailForAppointment, removeEvaluationComponentFromAppointment, updateEvaluationForAppointment, uploadEvaluationReport, deleteEvaluationReport, and saveEvaluationReportForAppointment.

The evaluation UI components themselves are internal to the library — they render inside the panel and are not exported.

Breaking change in 1.0.0: ClientService.evaluation changed from an inline { type; dueDate; provider? } object to the ClientEvaluation interface. Consumers reading evaluation fields must update accordingly.

| Angular | Library version | | ------- | --------------- | | 19.x | 1.x | | 20.x | 1.x | | 21.x | 1.x |

Angular, CDK, Material, and NgRx peers are all >=19.0.0 <22.0.0. Node >=20.

The library ships a minimal theme as an asset alongside the JS entry point:

@use '@presencelearning/documentation/styles/theme/theme';

The compiled theme.css is available at the same path.

  • No bundled backend — every persistence call goes through the consumer’s DocumentationService implementation
  • No opinionated theming — the library ships a minimal theme.scss; consumers control palette and typography
  • No standalone routing — the pop-out window route must be registered by the consumer

Source: packages/documentation