# useDocyrusTenant URL: /docs/web/hooks/use-docyrus-tenant Single-line tenant integration that fetches tenant preferences, builds dateUtils + numberUtils, and wires DateFormatProvider + NumberFormatProvider so every UI component (data grids, calendars, filters, value renderers) picks up the tenant's configured date/time/number formats automatically. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/hooks-use-docyrus-tenant ``` **Dependencies:** - [@docyrus/app-utils](https://www.npmjs.com/package/@docyrus/app-utils) - [@docyrus/api-client](https://www.npmjs.com/package/@docyrus/api-client) - [@tanstack/react-query](https://tanstack.com/query/latest) This module ships two named exports: - ` ); } ``` From there, every UI component that reads `useDateFormat()` / `useNumberFormat()` — including [`useDocyrusDataGrid`](/docs/web/hooks/use-docyrus-data-grid), [`useDocyrusDataTable`](/docs/web/hooks/use-docyrus-data-table), [`useDocyrusDataGallery`](/docs/web/hooks/use-docyrus-data-gallery), calendar event cells, side-filter chips, and the standalone value renderers — picks up the tenant's configured formats automatically. **No per-page formatter wiring required.** For ad-hoc formatting (custom chart axes, header labels, etc.) read the same utils via the hook: ```tsx import { useDocyrusTenant } from '@docyrus/ui/library/hooks/use-docyrus-tenant'; function ChartHeader({ date }: { date: string }) { const { dateUtils, isLoading } = useDocyrusTenant(); if (isLoading || !dateUtils) return —; return {dateUtils.formatDateLong(date)}; } ``` ## Provider props | Prop | Type | Default | Description | |------|------|---------|-------------| | `client` | `RestApiClient \| null \| undefined` | — | The `@docyrus/api-client` instance used to fetch `/v1/tenant/preferences`. | | `enabled` | `boolean` | `Boolean(client)` | Defer the fetch until your auth flow is ready. Set to `false` (or leave `client` null) until the user is authenticated. | | `userTimezone` | `string` | `'UTC'` | IANA timezone id forwarded to `createDateUtils`. Typically the user profile's `timeZone.id`. | | `staleTime` | `number` | `1_800_000` (30 min) | TanStack Query stale window for the preferences query. | | `children` | `ReactNode` | — | App tree to wrap. | ## Hook return `useDocyrusTenant()` returns: | Field | Type | Description | |-------|------|-------------| | `preferences` | `TenantPreferences \| null` | Normalized tenant preferences (camelCase keys mirrored to snake_case). `null` until the fetch finishes. | | `dateUtils` | `DateUtils \| null` | Output of `createDateUtils({ preferences, userTimezone })`. Exposes `formatDate`, `formatDateTime`, `formatDateLong`, `toUserTimezone`. | | `numberUtils` | `NumberUtils \| null` | Output of `createNumberUtils({ preferences })`. Exposes `formatNumber`. | | `isLoading` | `boolean` | TanStack Query's loading flag for the preferences fetch. | ## Auto-wired contexts Internally `` mounts: ```text DocyrusTenantContext.Provider └── DateFormatProvider (formatDate / formatDateTime / formatTime) └── NumberFormatProvider (formatNumber) └── {children} ``` Every Docyrus UI component reads from these contexts: | Consumer | Context | Effect | |----------|---------|--------| | `useDocyrusDataGrid` / `useDocyrusDataTable` / `useDocyrusDataGallery` | `useDateFormat()` + `useNumberFormat()` | Date / datetime / number cells pick up tenant formatting unless a `formatDate` / `formatDateTime` / `formatNumber` prop is passed explicitly (props still win). | | Calendar event cells, side-filter chips | `useDateFormat()` | Same fallback chain. | | `DocyrusDateValue`, `DocyrusDateTimeValue`, `DocyrusNumberValue` value renderers | `useDateFormat()` / `useNumberFormat()` | Standalone display components inherit tenant formatting. | **Backwards compatible:** the data-grid / data-table hooks detect whether a real provider is mounted (vs. the no-provider sentinel) before injecting the context formatter. Apps that haven't adopted `` yet keep their previous behaviour byte-for-byte — the cells fall back to their internal `Intl.NumberFormat` / raw-string renderers exactly as before. ## Standalone `normalizeTenantPreferences` If you maintain your own provider stack (for example you also need to seed a non-Docyrus formatter), you can call the helper directly: ```tsx import { normalizeTenantPreferences, type DocyrusTenantContextValue } from '@docyrus/ui/library/hooks/use-docyrus-tenant'; import { createDateUtils, createNumberUtils, getTenantPreferences } from '@docyrus/app-utils'; const envelope = await getTenantPreferences(client); const preferences = normalizeTenantPreferences(envelope); if (preferences) { const dateUtils = createDateUtils({ preferences, userTimezone }); const numberUtils = createNumberUtils({ preferences }); // …wire them into your own context } ``` The helper accepts either the full envelope (`{ preferences, tenant, product, enums }`) or an already inner-shaped object and is safe to call with `null` / `undefined` (returns `null`). ## Type Exports | Type | Description | |------|-------------| | `DocyrusTenantContextValue` | Shape returned by `useDocyrusTenant()`. | | `DocyrusTenantProviderProps` | Props accepted by ``. |