@plumile/backoffice-react
v0.2.10
Published
React provider and pages for Kronex backoffice
Maintainers
Readme
@plumile/backoffice-react
React provider, auth screens, routing scaffolds, and Relay helpers for Kronex-style backoffice applications.
Status
Specialized public package. This package is best suited to teams building a Kronex-style backoffice with entity manifests, Relay, and the shared UI layer.
Purpose
@plumile/backoffice-react is the React integration layer on top of:
@plumile/backoffice-corefor manifests, facets, and shared types@plumile/uifor the visual system@plumile/routerfor internal routing and instrumentation
It contains:
BackofficeProvider- auth screens and login flow helpers
- routing and page scaffolds
- backoffice hooks
- Relay environment and mutation helpers
- entity loading helpers and related UI building blocks
It does not try to become:
- a generic React application framework
- a second standalone component library
- a container for product-specific business logic
Installation
npm install @plumile/backoffice-reactUse createBackofficeAuthHeaders({ basePath }) as the Relay
getAuthHeaders callback. It permits anonymous GraphQL requests only from the
backoffice authentication routes and rejects protected requests before the
network when the short-lived session has expired.
Peer dependencies:
npm install react react-dom react-i18next i18next react-relay relay-runtimeThis package also depends on the Kronex router, UI, and backoffice-core packages.
Main Public Surface
Provider and configuration
BackofficeProvideruseBackofficeConfigcreateBackofficeLazyValue- config types such as
BackofficeAuthConfigandBackofficeGraphQLConfig
Auth and session flows
LoginFlowAcceptInvitationScreenPasswordResetRequestScreenPasswordResetCompleteScreenVerifyEmailScreencreateUseAuthAuthRefreshNoticekeeps the backoffice session-refresh subscription and fixed positioning in this package, while delegating its visual notice surface toInlineBannerfrom@plumile/ui.TotpQrCoderequires a localizedtitleso the generated QR image has an accessible name. The surrounding enrollment flow must also display the TOTP secret as a manual alternative for users who cannot scan the image.
Hooks and backoffice helpers
BackofficeRouterBoundarycomposes the existing error boundary and error surface. It resets on location changes, accepts an optionalonErrorcallback, and invokesonRetryso the caller can replace rejected prepared resources withuseAuthenticatedRouter().retry.useAuthenticatedRouter({ routes, createOptions, access })owns a browser router and returns{ router, retry, error }.createOptionsis a stable callback creating fresh router options and disposable instrumentations for each effect setup;accesssuppliesloginPathandisPublicPath(pathname). It waits for initial short-token authentication before protected route preparation, preserves an established session during a temporary refresh failure, follows browser and router navigation, and replaces an expired protected URL with the configured login path.routeris null while blocked or changing ownership.errorreports construction failures;retryrecreates the router at the current URL. Consumers supply their own pending and error UI and retain ownership of Relay session/store rotation.useBackofficeListUrlStateuseConditionalSubscriptionuseCopyToClipboarduseRefetchNeededReloaduploadFilesSequentiallyruns browser file upload preparation one file at a time, reports per-file progress, preserves partial failures, and lets applications map descriptors into their own uploaded-file shape.
List navigation is driven by the synchronous listNavigation contract from
each entity manifest. Internal list targets keep where and sort structured;
BackofficeLink, dashboard widgets, relation links, and list filter actions
convert them to router filters and query only at the Link boundary. This
keeps the rendered href, preload, modified click, and normal navigation aligned
without loading the list facet.
Relay and mutation helpers
useInfiniteConnectionis the required connection lifecycle for generic and application lists. Callers provide a telemetrysurface, a variable-derivedresetKey, and adapt RelayloadNext(count, { onComplete })throughrunLoadMore; the hook owns deduplication, timeout, incremental error, and retry behavior.resolveMutationOutcomeresolveAgentStartOutcomerequireFieldrequireLinkedRecordId
Generic Relay environment, provider, transport, and operation-activity helpers
are owned by @plumile/relay. Import them from that package; this package keeps
only helpers tied to backoffice mutations, connections, and typed data.
Backoffice-specific UI scaffolds
BackofficeOverviewLayoutBackofficeTabbedDetailShellBackofficeContentBoundary,BackofficeContentFallback, and related route fallbacks remain backoffice-specific because they encode Suspense, error-boundary reset, and routing behavior. Their error display composes the sharedInlineBannervisual primitive from@plumile/ui.- backoffice-specific detail components such as
BackofficeLifecycleTimelineSectionandBackofficeEntityLink EntityIdPickerDialog, which remains the backoffice picker integration for manifests, picker facets, Relay loading, scope, search, and selected IDs. It debounces search, paginates the manifest connection, and observes the modal content scroll root while preserving local incremental retry. The reusable picker visuals live in@plumile/uiasBackofficePickerShell,BackofficePickerList, andBackofficePickerRow.
Backoffice React no longer exports generic toolbar or detail-header wrappers.
Use BackofficeToolbar, BackofficeListFilterToolbar,
BackofficeListFooter, and PageHeader from @plumile/ui for
visual composition. The entity-list scaffold delegates its filter trigger,
active chips, searchable drawer, reset behavior, and session-scoped drawer
state to BackofficeListFilterToolbar; this package keeps the backoffice
integration layer focused on manifests, routing, permissions, Relay, filters,
and i18n. The scaffold places its manual BackofficeListFooter inside the
active record-list or virtualized-table scroll viewport and keeps the automatic
IntersectionObserver sentinel separate, non-interactive, and hidden from the
accessibility tree.
Backoffice React also no longer exports the old generic detail wrappers and
aliases: BackofficeDetailField, BackofficeDetailSection,
BackofficeScopeStack, BackofficeContextPanel,
BackofficeAuditMetadataPanel,
BackofficeDetailPage, BackofficeCopyButton, BackofficeDetailTable,
BackofficeDetailActionBar, BackofficeDetailBlock,
BackofficeEmptyValue, BackofficeTechnicalFacts,
BackofficeEntityRefLink, BackofficeFieldSet,
BackofficeMetricGrid, BackofficeKpiStrip, BackofficeTimeline,
BackofficeAuditTrail, and BackofficePayloadViewer. The timeline aliases
were removed without compatibility wrappers; use AuditTimeline and
TimelineEventRow from @plumile/ui for visual timelines. Use the canonical
components instead: CopyableText, DataTable, MetricCard,
MetricTileGroup, DashboardPanel, DashboardMetricGroup,
DashboardQuickActions, DashboardStatusList, PropertyList,
BackofficeDetailField, BackofficeDetailSection, BackofficeScopeStack,
BackofficeAuditMetadataPanel, and AuditTimeline from @plumile/ui; direct
React composition for empty/action/block wrappers; and
BackofficeLifecycleTimelineSection and BackofficeEntityLink from
@plumile/backoffice-react.
Backoffice React no longer exports generic payload viewers:
BackofficeDetailPayload, BackofficePayloadInspectorSection, the legacy
BackofficePayloadViewer alias, and formatJsonPayload were removed. Compose
BackofficeDetailSection with BackofficePayloadViewer from @plumile/ui for
payload, JSON, markdown, text, and code display.
For the complete export list, see src/index.ts.
Quick Start
import { BackofficeProvider } from '@plumile/backoffice-react';
export function App(): JSX.Element {
return (
<BackofficeProvider
entityManifest={entityManifest}
auth={auth}
graphql={graphql}
theme={{ density: 'compact', defaultMode: 'system' }}
/>
);
}theme configures the single BackofficeThemeProvider owned by
BackofficeProvider. It forwards mode, storage, theme classes, and density;
applications should not wrap the provider in a second backoffice theme scope.
Instrumentation
BackofficeProvider forwards router instrumentations to the internal
createRouter(...) call. This is useful when you want to expose:
- the Kronex Router DevTools bridge
- Performance Timeline marks and measures in Chrome DevTools
- custom router instrumentation for local diagnostics
Example:
import {
createDevtoolsBridgeInstrumentation,
createPerformanceTimelineInstrumentation,
} from '@plumile/router';
import { BackofficeProvider } from '@plumile/backoffice-react';
const instrumentations = [
createDevtoolsBridgeInstrumentation(),
createPerformanceTimelineInstrumentation(),
];
<BackofficeProvider
entityManifest={entityManifest}
auth={auth}
graphql={graphql}
instrumentations={instrumentations}
/>;If instrumentations is omitted, routing still works normally.
The provider uses the same authenticated-router lifecycle as public application
consumers. Its route error surface retries by recreating the current router;
it also preserves the optional auth.session.authStatusQuery mode. The
GraphQL configuration forwards fetchImpl explicitly for auth-aware transport,
and getAuthHeaders may accept an operation AbortSignal. The backoffice
header adapter delegates token/cancellation behavior to @plumile/auth and
only owns the base-path-aware classification of authentication URLs.
Validation Notes
- public helpers that are pure or mostly pure should have focused unit tests
- provider behavior should remain covered by React tests
- package documentation should describe the main composition flows rather than every low-level implementation detail
Limitations
- this package assumes Kronex entity manifests and backoffice routing concepts
- Relay integration is built around Kronex conventions, not every possible Relay application architecture
- consumers should keep domain-specific business components outside this package
