@voyantjs/availability-react 0.106.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +161 -1
  2. package/dist/admin/availability-index-host.d.ts +12 -0
  3. package/dist/admin/availability-index-host.d.ts.map +1 -0
  4. package/dist/admin/availability-index-host.js +125 -0
  5. package/dist/admin/availability-page-data.d.ts +9 -0
  6. package/dist/admin/availability-page-data.d.ts.map +1 -0
  7. package/dist/admin/availability-page-data.js +25 -0
  8. package/dist/admin/index.d.ts +69 -0
  9. package/dist/admin/index.d.ts.map +1 -0
  10. package/dist/admin/index.js +73 -0
  11. package/dist/admin/option-resource-templates-panel.d.ts +22 -0
  12. package/dist/admin/option-resource-templates-panel.d.ts.map +1 -0
  13. package/dist/admin/option-resource-templates-panel.js +251 -0
  14. package/dist/admin/rule-detail-host.d.ts +14 -0
  15. package/dist/admin/rule-detail-host.d.ts.map +1 -0
  16. package/dist/admin/rule-detail-host.js +27 -0
  17. package/dist/admin/slot-detail-host.d.ts +29 -0
  18. package/dist/admin/slot-detail-host.d.ts.map +1 -0
  19. package/dist/admin/slot-detail-host.js +110 -0
  20. package/dist/admin/start-time-detail-host.d.ts +15 -0
  21. package/dist/admin/start-time-detail-host.d.ts.map +1 -0
  22. package/dist/admin/start-time-detail-host.js +37 -0
  23. package/dist/components/availability-columns.d.ts +42 -0
  24. package/dist/components/availability-columns.d.ts.map +1 -0
  25. package/dist/components/availability-columns.js +182 -0
  26. package/dist/components/availability-dialogs.d.ts +236 -0
  27. package/dist/components/availability-dialogs.d.ts.map +1 -0
  28. package/dist/components/availability-dialogs.js +369 -0
  29. package/dist/components/availability-overview.d.ts +54 -0
  30. package/dist/components/availability-overview.d.ts.map +1 -0
  31. package/dist/components/availability-overview.js +50 -0
  32. package/dist/components/availability-page.d.ts +32 -0
  33. package/dist/components/availability-page.d.ts.map +1 -0
  34. package/dist/components/availability-page.js +128 -0
  35. package/dist/components/availability-rule-detail-page.d.ts +251 -0
  36. package/dist/components/availability-rule-detail-page.d.ts.map +1 -0
  37. package/dist/components/availability-rule-detail-page.js +74 -0
  38. package/dist/components/availability-section-header.d.ts +8 -0
  39. package/dist/components/availability-section-header.d.ts.map +1 -0
  40. package/dist/components/availability-section-header.js +7 -0
  41. package/dist/components/availability-skeletons.d.ts +6 -0
  42. package/dist/components/availability-skeletons.d.ts.map +1 -0
  43. package/dist/components/availability-skeletons.js +34 -0
  44. package/dist/components/availability-slot-detail-page.d.ts +974 -0
  45. package/dist/components/availability-slot-detail-page.d.ts.map +1 -0
  46. package/dist/components/availability-slot-detail-page.js +383 -0
  47. package/dist/components/availability-start-time-detail-page.d.ts +246 -0
  48. package/dist/components/availability-start-time-detail-page.d.ts.map +1 -0
  49. package/dist/components/availability-start-time-detail-page.js +83 -0
  50. package/dist/components/availability-tabs.d.ts +152 -0
  51. package/dist/components/availability-tabs.d.ts.map +1 -0
  52. package/dist/components/availability-tabs.js +192 -0
  53. package/dist/components/slot-status-tone.d.ts +15 -0
  54. package/dist/components/slot-status-tone.d.ts.map +1 -0
  55. package/dist/components/slot-status-tone.js +18 -0
  56. package/dist/form-resolver.d.ts +4 -0
  57. package/dist/form-resolver.d.ts.map +1 -0
  58. package/dist/form-resolver.js +40 -0
  59. package/dist/i18n/index.d.ts +2 -0
  60. package/dist/i18n/index.d.ts.map +1 -0
  61. package/dist/i18n/index.js +1 -0
  62. package/dist/i18n/provider.d.ts +2003 -0
  63. package/dist/i18n/provider.d.ts.map +1 -0
  64. package/dist/i18n/provider.js +102 -0
  65. package/dist/ui.d.ts +13 -0
  66. package/dist/ui.d.ts.map +1 -0
  67. package/dist/ui.js +12 -0
  68. package/dist/utils.d.ts +1 -0
  69. package/dist/utils.d.ts.map +1 -1
  70. package/dist/utils.js +3 -0
  71. package/package.json +92 -9
  72. package/src/styles.css +11 -0
package/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # @voyantjs/availability-react
2
2
 
3
- React runtime package for Voyant availability. Provides the shared availability provider, typed fetch client, query keys, constants, and TanStack Query hooks that power availability-focused frontend experiences.
3
+ The availability client tier: headless data hooks/clients plus the styled UI
4
+ primitives and page-level compositions (formerly `@voyantjs/availability-ui`).
5
+
6
+ Headless consumers (storefronts, portals) import from the root, `./hooks`,
7
+ `./client`, or `./query-keys` — these pull no styling peers. Styled surfaces
8
+ live under `./ui`, `./components/*`, `./admin`, `./i18n`, `./utils`, and
9
+ `./styles.css`, whose heavier peers (`@voyantjs/ui`, `@voyantjs/admin`,
10
+ `@tanstack/react-table`, `sonner`, `lucide-react`) are optional and only
11
+ needed when you import those subpaths.
4
12
 
5
13
  ## Install
6
14
 
@@ -27,6 +35,158 @@ function SlotsList() {
27
35
  }
28
36
  ```
29
37
 
38
+ ## UI components
39
+
40
+ Reusable availability UI primitives and page compositions for Voyant
41
+ operator/admin apps.
42
+
43
+ ### Exports
44
+
45
+ | Entry | Description |
46
+ | --- | --- |
47
+ | `./ui` | Barrel re-exports |
48
+ | `./i18n` | Availability UI message provider, defaults, and helpers |
49
+ | `./components/*` | Availability UI components |
50
+ | `./utils` | Small formatting helpers |
51
+
52
+ ### Surface
53
+
54
+ The package exports reusable pieces that keep app-owned routing and the
55
+ availability batch mutations injected through props:
56
+
57
+ - `AvailabilityPage`
58
+ - `AvailabilityRuleDetailPage`, `AvailabilitySlotDetailPage`,
59
+ `AvailabilityStartTimeDetailPage`
60
+ - `AvailabilityOverview`
61
+ - `AvailabilitySlotsTab`, `AvailabilityRulesTab`, `AvailabilityStartTimesTab`
62
+ - `AvailabilityCloseoutsTab`, `AvailabilityPickupPointsTab`
63
+ - `AvailabilityRuleDialog`, `AvailabilityStartTimeDialog`, `AvailabilitySlotDialog`
64
+ - `AvailabilityCloseoutDialog`, `AvailabilityPickupPointDialog`
65
+ - `AvailabilityPageSkeleton`, `AvailabilityBodySkeleton`, detail skeletons
66
+ - `availability*Columns` table column builders
67
+ - `AvailabilitySectionHeader`
68
+ - `AvailabilityUiMessagesProvider` and i18n helpers from `./i18n`
69
+ - `formatLocalizedSelectionLabel`
70
+
71
+ ### Usage
72
+
73
+ `AvailabilityPage` owns the common operator availability shell, data hooks,
74
+ filters, overview metrics, table tabs, calendar tab, and rule/slot/start-time
75
+ dialogs. Route navigation and batch mutations stay app-specific:
76
+
77
+ ```tsx
78
+ import { AvailabilityPage } from "@voyantjs/availability-react/ui"
79
+
80
+ <AvailabilityPage
81
+ onSlotOpen={(id) => navigate({ to: "/availability/$id", params: { id } })}
82
+ onRuleOpen={(id) => navigate({ to: "/availability/rules/$id", params: { id } })}
83
+ onStartTimeOpen={(id) =>
84
+ navigate({ to: "/availability/start-times/$id", params: { id } })
85
+ }
86
+ onProductOpen={(id) => navigate({ to: "/products/$id", params: { id } })}
87
+ onBulkUpdate={handleAvailabilityBulkUpdate}
88
+ onBulkDelete={handleAvailabilityBulkDelete}
89
+ />
90
+ ```
91
+
92
+ Closeout and pickup-point mutations are not owned by the headless tier yet.
93
+ Pass `onCloseoutSubmit` and `onPickupPointSubmit` to use the package dialogs, or
94
+ use the `slots.dialogs` escape hatch to render app-owned dialogs.
95
+
96
+ Detail pages expose query/loader helpers that accept the app's API client:
97
+
98
+ ```tsx
99
+ import { defaultFetcher } from "@voyantjs/availability-react"
100
+ import {
101
+ AvailabilitySlotDetailPage,
102
+ loadAvailabilitySlotDetailPage,
103
+ } from "@voyantjs/availability-react/ui"
104
+
105
+ const client = { baseUrl: getApiUrl(), fetcher: defaultFetcher }
106
+
107
+ export const Route = createFileRoute("/_workspace/availability/$id")({
108
+ loader: ({ context, params }) =>
109
+ loadAvailabilitySlotDetailPage(context.queryClient, client, params.id),
110
+ component: () => {
111
+ const { id } = Route.useParams()
112
+ return (
113
+ <AvailabilitySlotDetailPage
114
+ id={id}
115
+ onBack={() => navigate({ to: "/availability" })}
116
+ onOpenProduct={(productId) =>
117
+ navigate({ to: "/products/$id", params: { id: productId } })
118
+ }
119
+ onOpenStartTime={(startTimeId) =>
120
+ navigate({ to: "/availability/start-times/$id", params: { id: startTimeId } })
121
+ }
122
+ />
123
+ )
124
+ },
125
+ })
126
+ ```
127
+
128
+ Wrap consumers in `AvailabilityUiMessagesProvider` for package-level copy and
129
+ locale-aware formatting. Without a provider the package falls back to English.
130
+
131
+ ```tsx
132
+ import { AvailabilityUiMessagesProvider } from "@voyantjs/availability-react/i18n"
133
+
134
+ <AvailabilityUiMessagesProvider locale={resolvedLocale}>
135
+ <AvailabilityPage onBulkUpdate={handleBulkUpdate} onBulkDelete={handleBulkDelete} />
136
+ </AvailabilityUiMessagesProvider>
137
+ ```
138
+
139
+ Leaf components remain available for custom page shells:
140
+
141
+ ```tsx
142
+ import { AvailabilitySectionHeader } from "@voyantjs/availability-react/ui"
143
+
144
+ function SlotsHeader() {
145
+ return (
146
+ <AvailabilitySectionHeader
147
+ title="Slots"
148
+ description="Manage generated capacity."
149
+ actionLabel="Create slot"
150
+ onAction={() => setOpen(true)}
151
+ />
152
+ )
153
+ }
154
+ ```
155
+
156
+ Table column builders are available for apps that use `@voyantjs/ui`'s
157
+ `DataTable` and keep routing behavior app-owned:
158
+
159
+ ```tsx
160
+ import { availabilitySlotColumns } from "@voyantjs/availability-react/ui"
161
+
162
+ <DataTable
163
+ columns={availabilitySlotColumns(products, openSlotRoute, messages.availability)}
164
+ data={slots}
165
+ />
166
+ ```
167
+
168
+ Dialogs expose the reusable form UI and validation while the app decides how
169
+ to persist the payload:
170
+
171
+ ```tsx
172
+ import { AvailabilitySlotDialog } from "@voyantjs/availability-react/ui"
173
+
174
+ <AvailabilitySlotDialog
175
+ messages={messages.availability}
176
+ open={open}
177
+ onOpenChange={setOpen}
178
+ products={products}
179
+ rules={rules}
180
+ startTimes={startTimes}
181
+ onSubmit={(payload, context) =>
182
+ context.isEditing
183
+ ? api.patch(`/v1/availability/slots/${context.id}`, payload)
184
+ : api.post("/v1/availability/slots", payload)
185
+ }
186
+ onSuccess={refresh}
187
+ />
188
+ ```
189
+
30
190
  ## License
31
191
 
32
192
  Apache-2.0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Packaged admin host for the availability index page (packaged-admin RFC
3
+ * Phase 3). Zero-prop: list/filter state stays component-local (no URL
4
+ * search contract), opening a slot resolves through the
5
+ * `availabilitySlot.detail` semantic destination, and the bulk
6
+ * update/delete handlers run through the typed batch mutation pairs from
7
+ * `@voyantjs/availability-react` (the `batch-update`/`batch-delete`
8
+ * endpoints) instead of an app RPC client. Slot create/edit submits through
9
+ * the package default (`useAvailabilitySlotMutation`).
10
+ */
11
+ export declare function AvailabilityIndexHost(): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=availability-index-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"availability-index-host.d.ts","sourceRoot":"","sources":["../../src/admin/availability-index-host.tsx"],"names":[],"mappings":"AA0BA;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,4CA2KpC"}
@@ -0,0 +1,125 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useQueryClient } from "@tanstack/react-query";
4
+ import { formatMessage, useAdminNavigate, useOperatorAdminMessages } from "@voyantjs/admin";
5
+ import { useState } from "react";
6
+ import { toast } from "sonner";
7
+ import { AvailabilityPage, } from "../components/availability-page.js";
8
+ import { availabilityQueryKeys, useAvailabilityCloseoutBatchMutation, useAvailabilityPickupPointBatchMutation, useAvailabilityRuleBatchMutation, useAvailabilitySlotBatchMutation, useAvailabilityStartTimeBatchMutation, } from "../index.js";
9
+ import { formatLocalizedSelectionLabel } from "../utils.js";
10
+ /**
11
+ * Packaged admin host for the availability index page (packaged-admin RFC
12
+ * Phase 3). Zero-prop: list/filter state stays component-local (no URL
13
+ * search contract), opening a slot resolves through the
14
+ * `availabilitySlot.detail` semantic destination, and the bulk
15
+ * update/delete handlers run through the typed batch mutation pairs from
16
+ * `@voyantjs/availability-react` (the `batch-update`/`batch-delete`
17
+ * endpoints) instead of an app RPC client. Slot create/edit submits through
18
+ * the package default (`useAvailabilitySlotMutation`).
19
+ */
20
+ export function AvailabilityIndexHost() {
21
+ const messages = useOperatorAdminMessages();
22
+ const navigateTo = useAdminNavigate();
23
+ const queryClient = useQueryClient();
24
+ const [bulkActionTarget, setBulkActionTarget] = useState(null);
25
+ const ruleBatch = useAvailabilityRuleBatchMutation();
26
+ const startTimeBatch = useAvailabilityStartTimeBatchMutation();
27
+ const slotBatch = useAvailabilitySlotBatchMutation();
28
+ const closeoutBatch = useAvailabilityCloseoutBatchMutation();
29
+ const pickupPointBatch = useAvailabilityPickupPointBatchMutation();
30
+ const refreshAvailability = () => queryClient.invalidateQueries({ queryKey: availabilityQueryKeys.all });
31
+ // The tabs identify their batch endpoints by REST path; resolve each to
32
+ // the matching typed batch mutation pair. The page currently only emits
33
+ // the slots endpoint, but every availability list entity is covered so
34
+ // additional tabs slot in without touching the host.
35
+ const runBatchUpdate = (endpoint, ids, payload) => {
36
+ switch (endpoint) {
37
+ case "/v1/availability/rules":
38
+ return ruleBatch.batchUpdate.mutateAsync({
39
+ ids,
40
+ patch: payload,
41
+ });
42
+ case "/v1/availability/start-times":
43
+ return startTimeBatch.batchUpdate.mutateAsync({
44
+ ids,
45
+ patch: payload,
46
+ });
47
+ case "/v1/availability/closeouts":
48
+ return closeoutBatch.batchUpdate.mutateAsync({
49
+ ids,
50
+ patch: payload,
51
+ });
52
+ case "/v1/availability/pickup-points":
53
+ return pickupPointBatch.batchUpdate.mutateAsync({
54
+ ids,
55
+ patch: payload,
56
+ });
57
+ default:
58
+ return slotBatch.batchUpdate.mutateAsync({
59
+ ids,
60
+ patch: payload,
61
+ });
62
+ }
63
+ };
64
+ const runBatchDelete = (endpoint, ids) => {
65
+ switch (endpoint) {
66
+ case "/v1/availability/rules":
67
+ return ruleBatch.batchDelete.mutateAsync({ ids });
68
+ case "/v1/availability/start-times":
69
+ return startTimeBatch.batchDelete.mutateAsync({ ids });
70
+ case "/v1/availability/closeouts":
71
+ return closeoutBatch.batchDelete.mutateAsync({ ids });
72
+ case "/v1/availability/pickup-points":
73
+ return pickupPointBatch.batchDelete.mutateAsync({ ids });
74
+ default:
75
+ return slotBatch.batchDelete.mutateAsync({ ids });
76
+ }
77
+ };
78
+ const slotsNounSingular = messages.availability.tabs.slots.title;
79
+ const slotsNounPlural = messages.availability.tabs.slots.title;
80
+ const handleBulkUpdate = async ({ ids, endpoint, target, nounSingular, nounPlural, payload, successVerb, clearSelection, }) => {
81
+ if (ids.length === 0)
82
+ return;
83
+ setBulkActionTarget(target);
84
+ const result = await runBatchUpdate(endpoint, ids, payload);
85
+ await refreshAvailability();
86
+ clearSelection();
87
+ setBulkActionTarget(null);
88
+ const succeededSelection = formatLocalizedSelectionLabel(result.succeeded, nounSingular ?? slotsNounSingular, nounPlural ?? slotsNounPlural);
89
+ const totalSelection = formatLocalizedSelectionLabel(result.total, nounSingular ?? slotsNounSingular, nounPlural ?? slotsNounPlural);
90
+ if (result.failed.length === 0) {
91
+ toast.success(formatMessage(messages.availability.toasts.bulkUpdated, {
92
+ verb: successVerb,
93
+ selection: succeededSelection,
94
+ }));
95
+ return;
96
+ }
97
+ toast.error(formatMessage(messages.availability.toasts.bulkUpdatedPartial, {
98
+ verb: successVerb,
99
+ succeeded: result.succeeded,
100
+ selection: totalSelection,
101
+ }));
102
+ };
103
+ const handleBulkDelete = async ({ ids, endpoint, target, nounSingular, nounPlural, clearSelection, }) => {
104
+ if (ids.length === 0)
105
+ return;
106
+ setBulkActionTarget(target);
107
+ const result = await runBatchDelete(endpoint, ids);
108
+ await refreshAvailability();
109
+ clearSelection();
110
+ setBulkActionTarget(null);
111
+ const succeededSelection = formatLocalizedSelectionLabel(result.succeeded, nounSingular ?? slotsNounSingular, nounPlural ?? slotsNounPlural);
112
+ const totalSelection = formatLocalizedSelectionLabel(result.total, nounSingular ?? slotsNounSingular, nounPlural ?? slotsNounPlural);
113
+ if (result.failed.length === 0) {
114
+ toast.success(formatMessage(messages.availability.toasts.bulkDeleted, {
115
+ selection: succeededSelection,
116
+ }));
117
+ return;
118
+ }
119
+ toast.error(formatMessage(messages.availability.toasts.bulkDeletedPartial, {
120
+ succeeded: result.succeeded,
121
+ selection: totalSelection,
122
+ }));
123
+ };
124
+ return (_jsx(AvailabilityPage, { bulkActionTarget: bulkActionTarget, onBulkUpdate: handleBulkUpdate, onBulkDelete: handleBulkDelete, onSlotOpen: (slotId) => navigateTo("availabilitySlot.detail", { slotId }) }));
125
+ }
@@ -0,0 +1,9 @@
1
+ import type { QueryClient } from "@tanstack/react-query";
2
+ import { type VoyantAvailabilityContextValue } from "../index.js";
3
+ /**
4
+ * Index page loader: await only what the slots tab + the products picker
5
+ * (top of page) need for first paint; the rules/start-times dimensions that
6
+ * back the slot create/edit dialog prefetch in the background.
7
+ */
8
+ export declare function ensureAvailabilityPageData(queryClient: QueryClient, client: VoyantAvailabilityContextValue): Promise<void>;
9
+ //# sourceMappingURL=availability-page-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"availability-page-data.d.ts","sourceRoot":"","sources":["../../src/admin/availability-page-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAKL,KAAK,8BAA8B,EACpC,MAAM,aAAa,CAAA;AAcpB;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,IAAI,CAAC,CAYf"}
@@ -0,0 +1,25 @@
1
+ import { getProductsQueryOptions, getRulesQueryOptions, getSlotsQueryOptions, getStartTimesQueryOptions, } from "../index.js";
2
+ /**
3
+ * Canonical first-page list filters for the availability index page.
4
+ * `AvailabilityPage` hard-codes the same filters in its hooks, so the
5
+ * loader-seeded cache entries line up with the page's query keys.
6
+ */
7
+ const availabilityPageQueryFilters = {
8
+ products: { limit: 25, offset: 0 },
9
+ slots: { limit: 25, offset: 0 },
10
+ rules: { limit: 25, offset: 0 },
11
+ startTimes: { limit: 25, offset: 0 },
12
+ };
13
+ /**
14
+ * Index page loader: await only what the slots tab + the products picker
15
+ * (top of page) need for first paint; the rules/start-times dimensions that
16
+ * back the slot create/edit dialog prefetch in the background.
17
+ */
18
+ export async function ensureAvailabilityPageData(queryClient, client) {
19
+ await Promise.all([
20
+ queryClient.ensureQueryData(getSlotsQueryOptions(client, availabilityPageQueryFilters.slots)),
21
+ queryClient.ensureQueryData(getProductsQueryOptions(client, availabilityPageQueryFilters.products)),
22
+ ]);
23
+ void queryClient.prefetchQuery(getRulesQueryOptions(client, availabilityPageQueryFilters.rules));
24
+ void queryClient.prefetchQuery(getStartTimesQueryOptions(client, availabilityPageQueryFilters.startTimes));
25
+ }
@@ -0,0 +1,69 @@
1
+ import { type AdminExtension } from "@voyantjs/admin";
2
+ /**
3
+ * Semantic destinations the availability admin surfaces navigate to
4
+ * (packaged-admin RFC §4.7). Keys shared with other domains
5
+ * (`availabilitySlot.detail`, `booking.detail`, `product.detail`) come from
6
+ * the bookings-ui augmentation bound above; declared here are the
7
+ * availability-owned targets the packaged pages and breadcrumbs resolve
8
+ * through `useAdminHref`/`useAdminNavigate`.
9
+ */
10
+ declare module "@voyantjs/admin" {
11
+ interface AdminDestinations {
12
+ /** The availability landing page (slots list + calendar). */
13
+ "availabilitySlot.list": Record<string, never>;
14
+ /** An availability start time's detail page. */
15
+ "availabilityStartTime.detail": {
16
+ startTimeId: string;
17
+ };
18
+ }
19
+ }
20
+ export { AvailabilityIndexHost } from "./availability-index-host.js";
21
+ export { ensureAvailabilityPageData } from "./availability-page-data.js";
22
+ export { OptionResourceTemplatesPanel, type OptionResourceTemplatesPanelProps, } from "./option-resource-templates-panel.js";
23
+ export { AvailabilityRuleDetailHost, type AvailabilityRuleDetailHostProps, } from "./rule-detail-host.js";
24
+ export { AvailabilitySlotDetailHost, type AvailabilitySlotDetailHostProps, } from "./slot-detail-host.js";
25
+ export { AvailabilityStartTimeDetailHost, type AvailabilityStartTimeDetailHostProps, } from "./start-time-detail-host.js";
26
+ export interface CreateAvailabilityAdminExtensionOptions {
27
+ /** Mount path of the availability pages inside the admin workspace. Default `/availability`. */
28
+ basePath?: string;
29
+ /** Localized page titles. Defaults are the English operator nav labels. */
30
+ labels?: {
31
+ availability?: string;
32
+ };
33
+ }
34
+ /**
35
+ * The availability admin contribution (packaged-admin RFC Phase 3,
36
+ * `@voyantjs/<domain>-ui/admin` convention).
37
+ *
38
+ * NAVIGATION: deliberately none. The Availability nav item is part of the
39
+ * BASE operator navigation — see `createOperatorAdminNavigation` in
40
+ * `@voyantjs/admin` — so contributing a nav entry here would duplicate it.
41
+ * If the base nav ever drops the availability item, this extension is where
42
+ * the entry moves.
43
+ *
44
+ * ROUTES: contributions are metadata only — the availability pages keep
45
+ * their filter state component-local, so there are no URL search contracts.
46
+ * The PAGES are package-owned: {@link AvailabilityIndexHost} (the slots
47
+ * list + calendar landing page, with bulk update/delete running through
48
+ * the typed batch mutation hooks in `@voyantjs/availability-react`) plus
49
+ * the detail hosts {@link AvailabilitySlotDetailHost},
50
+ * {@link AvailabilityRuleDetailHost} and
51
+ * {@link AvailabilityStartTimeDetailHost} bind the operator-grade pages to
52
+ * their data wiring (the shared availability provider context) and resolve
53
+ * every cross-route link through the semantic destinations declared above.
54
+ * `component:` is intentionally NOT attached to these contributions: the
55
+ * contribution contract renders zero-prop pages (route components read
56
+ * params via the router, per RFC §4.2), while the detail hosts take the
57
+ * record id as a prop — host route files stay the thin binding layer
58
+ * (`Route.useParams()` → host props) until the §4.2 code-based route
59
+ * assembly lands. The index host's SSR loader binding stays app-side
60
+ * ({@link ensureAvailabilityPageData} takes the app's cookie-forwarding
61
+ * client), per the packaged-host recipe.
62
+ *
63
+ * WIDGETS: none. {@link OptionResourceTemplatesPanel} (the per-option
64
+ * resource templates editor the product editor embeds) ships from this
65
+ * entry as a directly importable component — the products admin host owns
66
+ * where it mounts.
67
+ */
68
+ export declare function createAvailabilityAdminExtension(options?: CreateAvailabilityAdminExtensionOptions): AdminExtension;
69
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,iBAAiB,CAAA;AAW3E;;;;;;;GAOG;AACH,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,iBAAiB;QACzB,6DAA6D;QAC7D,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC9C,gDAAgD;QAChD,8BAA8B,EAAE;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;KACxD;CACF;AAKD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAA;AACxE,OAAO,EACL,4BAA4B,EAC5B,KAAK,iCAAiC,GACvC,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EACL,0BAA0B,EAC1B,KAAK,+BAA+B,GACrC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,0BAA0B,EAC1B,KAAK,+BAA+B,GACrC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,+BAA+B,EAC/B,KAAK,oCAAoC,GAC1C,MAAM,6BAA6B,CAAA;AAEpC,MAAM,WAAW,uCAAuC;IACtD,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE;QACP,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,uCAA4C,GACpD,cAAc,CA6BhB"}
@@ -0,0 +1,73 @@
1
+ import { defineAdminExtension } from "@voyantjs/admin";
2
+ // Packaged admin hosts (packaged-admin RFC Phase 3): the operator-grade
3
+ // availability pages bound to their data wiring + semantic-destination
4
+ // navigation. Host route files only bind route params onto these.
5
+ export { AvailabilityIndexHost } from "./availability-index-host.js";
6
+ export { ensureAvailabilityPageData } from "./availability-page-data.js";
7
+ export { OptionResourceTemplatesPanel, } from "./option-resource-templates-panel.js";
8
+ export { AvailabilityRuleDetailHost, } from "./rule-detail-host.js";
9
+ export { AvailabilitySlotDetailHost, } from "./slot-detail-host.js";
10
+ export { AvailabilityStartTimeDetailHost, } from "./start-time-detail-host.js";
11
+ /**
12
+ * The availability admin contribution (packaged-admin RFC Phase 3,
13
+ * `@voyantjs/<domain>-ui/admin` convention).
14
+ *
15
+ * NAVIGATION: deliberately none. The Availability nav item is part of the
16
+ * BASE operator navigation — see `createOperatorAdminNavigation` in
17
+ * `@voyantjs/admin` — so contributing a nav entry here would duplicate it.
18
+ * If the base nav ever drops the availability item, this extension is where
19
+ * the entry moves.
20
+ *
21
+ * ROUTES: contributions are metadata only — the availability pages keep
22
+ * their filter state component-local, so there are no URL search contracts.
23
+ * The PAGES are package-owned: {@link AvailabilityIndexHost} (the slots
24
+ * list + calendar landing page, with bulk update/delete running through
25
+ * the typed batch mutation hooks in `@voyantjs/availability-react`) plus
26
+ * the detail hosts {@link AvailabilitySlotDetailHost},
27
+ * {@link AvailabilityRuleDetailHost} and
28
+ * {@link AvailabilityStartTimeDetailHost} bind the operator-grade pages to
29
+ * their data wiring (the shared availability provider context) and resolve
30
+ * every cross-route link through the semantic destinations declared above.
31
+ * `component:` is intentionally NOT attached to these contributions: the
32
+ * contribution contract renders zero-prop pages (route components read
33
+ * params via the router, per RFC §4.2), while the detail hosts take the
34
+ * record id as a prop — host route files stay the thin binding layer
35
+ * (`Route.useParams()` → host props) until the §4.2 code-based route
36
+ * assembly lands. The index host's SSR loader binding stays app-side
37
+ * ({@link ensureAvailabilityPageData} takes the app's cookie-forwarding
38
+ * client), per the packaged-host recipe.
39
+ *
40
+ * WIDGETS: none. {@link OptionResourceTemplatesPanel} (the per-option
41
+ * resource templates editor the product editor embeds) ships from this
42
+ * entry as a directly importable component — the products admin host owns
43
+ * where it mounts.
44
+ */
45
+ export function createAvailabilityAdminExtension(options = {}) {
46
+ const { basePath = "/availability", labels = {} } = options;
47
+ const { availability = "Availability" } = labels;
48
+ return defineAdminExtension({
49
+ id: "availability",
50
+ routes: [
51
+ {
52
+ id: "availability-index",
53
+ path: basePath,
54
+ title: availability,
55
+ },
56
+ {
57
+ id: "availability-slot-detail",
58
+ path: `${basePath}/$id`,
59
+ title: availability,
60
+ },
61
+ {
62
+ id: "availability-rule-detail",
63
+ path: `${basePath}/rules/$id`,
64
+ title: availability,
65
+ },
66
+ {
67
+ id: "availability-start-time-detail",
68
+ path: `${basePath}/start-times/$id`,
69
+ title: availability,
70
+ },
71
+ ],
72
+ });
73
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Per-option Resource templates editor. Templates drive the Allocation
3
+ * tab's "Generate resources" automation — without a template configured
4
+ * for an option, no rooms/seats/etc. are materialized when bookings hit
5
+ * a slot.
6
+ *
7
+ * Each template is identified by `(optionId, kind, refId)` — an option can
8
+ * hold several templates of the same kind, one per `option_unit` (e.g. a
9
+ * "room" template per room type), distinguished by `refId`. Common kinds:
10
+ * - `room` — accommodation rooms (default capacity 2)
11
+ * - `vehicle_seat` — coach/van seats (capacity 1)
12
+ * - `cabin` — cruise cabins
13
+ *
14
+ * The kind field is a free-form string on the server; we constrain the
15
+ * picker to the known set for UX, but operators can extend by typing.
16
+ */
17
+ export interface OptionResourceTemplatesPanelProps {
18
+ productId: string;
19
+ optionId: string;
20
+ }
21
+ export declare function OptionResourceTemplatesPanel({ productId, optionId, }: OptionResourceTemplatesPanelProps): import("react/jsx-runtime").JSX.Element;
22
+ //# sourceMappingURL=option-resource-templates-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"option-resource-templates-panel.d.ts","sourceRoot":"","sources":["../../src/admin/option-resource-templates-panel.tsx"],"names":[],"mappings":"AA+CA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iCAAiC;IAChD,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAiBD,wBAAgB,4BAA4B,CAAC,EAC3C,SAAS,EACT,QAAQ,GACT,EAAE,iCAAiC,2CAqenC"}