@odla-ai/chapter 0.21.0 → 0.22.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.
- package/README.md +79 -10
- package/dist/{chunk-AOTWFOH4.js → chunk-IWW5VAAC.js} +275 -90
- package/dist/chunk-IWW5VAAC.js.map +1 -0
- package/dist/{chunk-3JG5X2LT.js → chunk-VZPBTTO3.js} +13 -2
- package/dist/chunk-VZPBTTO3.js.map +1 -0
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-CXDiDj_s.d.ts → types-CgWUQ2MH.d.ts} +14 -0
- package/dist/ui/admin/index.d.ts +77 -11
- package/dist/ui/admin/index.js +8 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +8 -2
- package/dist/ui/member/index.d.ts +1 -1
- package/dist/ui/member/index.js +1 -1
- package/dist/worker/index.d.cts +14 -0
- package/dist/worker/index.d.ts +14 -0
- package/package.json +3 -3
- package/runbooks/adopt-existing.md +13 -4
- package/runbooks/greenfield.md +4 -4
- package/dist/chunk-3JG5X2LT.js.map +0 -1
- package/dist/chunk-AOTWFOH4.js.map +0 -1
|
@@ -50,8 +50,22 @@ interface ChapterBrandTokens {
|
|
|
50
50
|
danger?: string;
|
|
51
51
|
chart1?: string;
|
|
52
52
|
chart2?: string;
|
|
53
|
+
chart3?: string;
|
|
54
|
+
chart4?: string;
|
|
55
|
+
chart5?: string;
|
|
56
|
+
chart6?: string;
|
|
53
57
|
chartPositive?: string;
|
|
54
58
|
chartNegative?: string;
|
|
59
|
+
/** Admin/application content width, e.g. `"960px"`. */
|
|
60
|
+
contentWidth?: string;
|
|
61
|
+
panelRadius?: string;
|
|
62
|
+
panelShadow?: string;
|
|
63
|
+
masterDetailColumns?: string;
|
|
64
|
+
masterDetailMinHeight?: string;
|
|
65
|
+
/** Chapter-admin page padding shorthand. */
|
|
66
|
+
pagePadding?: string;
|
|
67
|
+
/** Chapter-admin workspace-tab padding shorthand. */
|
|
68
|
+
workspacePadding?: string;
|
|
55
69
|
}
|
|
56
70
|
/** Brand tokens that theme the site: theme, semantic roles, fonts, and logos. */
|
|
57
71
|
interface ChapterBrand {
|
package/dist/ui/admin/index.d.ts
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
|
|
4
|
-
import { C as Chapter } from '../../types-
|
|
5
|
-
import {
|
|
4
|
+
import { C as Chapter } from '../../types-CgWUQ2MH.js';
|
|
5
|
+
import { CrmLifecycleAdapter, CrmWorkspaceMasterContext, CrmWorkspaceRecordContext, RecordPanelTab } from '@odla-ai/crm/ui';
|
|
6
|
+
|
|
7
|
+
/** Normalized public auth configuration consumed by the Clerk gate. */
|
|
8
|
+
interface ChapterAdminAuthConfig {
|
|
9
|
+
publishableKey: string | null;
|
|
10
|
+
}
|
|
11
|
+
/** Normalized current-user data retained for workspace visibility decisions. */
|
|
12
|
+
interface ChapterAdminUser extends Record<string, unknown> {
|
|
13
|
+
authorized?: boolean;
|
|
14
|
+
email?: string | null;
|
|
15
|
+
}
|
|
16
|
+
/** Inputs supplied to custom admin configuration and current-user loaders. */
|
|
17
|
+
interface ChapterAdminAuthLoadContext {
|
|
18
|
+
apiBase: string;
|
|
19
|
+
getToken?: () => Promise<string | null>;
|
|
20
|
+
}
|
|
21
|
+
/** Existing-site adapter for auth endpoint names and response shapes. */
|
|
22
|
+
interface ChapterAdminAuthAdapter {
|
|
23
|
+
configPath?: string;
|
|
24
|
+
currentUserPath?: string;
|
|
25
|
+
loadConfig?: (context: ChapterAdminAuthLoadContext) => Promise<ChapterAdminAuthConfig>;
|
|
26
|
+
loadCurrentUser?: (context: Required<ChapterAdminAuthLoadContext>) => Promise<ChapterAdminUser>;
|
|
27
|
+
mapConfig?: (body: Record<string, unknown>) => ChapterAdminAuthConfig;
|
|
28
|
+
mapCurrentUser?: (body: Record<string, unknown>) => ChapterAdminUser;
|
|
29
|
+
isAuthorized?: (user: ChapterAdminUser) => boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Load and normalize the public authentication configuration. */
|
|
32
|
+
declare function loadChapterAdminConfig(adapter: ChapterAdminAuthAdapter, apiBase: string): Promise<ChapterAdminAuthConfig>;
|
|
33
|
+
/** Load and normalize the authenticated user used by admin workspaces. */
|
|
34
|
+
declare function loadChapterAdminUser(adapter: ChapterAdminAuthAdapter, apiBase: string, getToken: () => Promise<string | null>): Promise<ChapterAdminUser>;
|
|
6
35
|
|
|
7
36
|
type Brand = {
|
|
8
37
|
name: string;
|
|
@@ -40,6 +69,7 @@ type AdminRouteTarget = string | {
|
|
|
40
69
|
interface AdminSectionContext {
|
|
41
70
|
client: CrmClient;
|
|
42
71
|
getToken: () => Promise<string | null>;
|
|
72
|
+
currentUser?: Record<string, unknown>;
|
|
43
73
|
route: AdminRouteState;
|
|
44
74
|
navigate: (target: AdminRouteTarget) => void;
|
|
45
75
|
href: (target: AdminRouteTarget) => string;
|
|
@@ -48,12 +78,28 @@ interface AdminSectionContext {
|
|
|
48
78
|
interface AdminWorkspace {
|
|
49
79
|
id: string;
|
|
50
80
|
label: string;
|
|
81
|
+
/** Canonical nested view used when a workspace is opened without one. */
|
|
82
|
+
defaultViewId?: string;
|
|
51
83
|
render: (ctx: AdminSectionContext) => ReactNode;
|
|
52
84
|
}
|
|
53
85
|
/** Legacy name for a top-level workspace. @deprecated Use AdminWorkspace. */
|
|
54
86
|
type AdminSection = AdminWorkspace;
|
|
55
|
-
/** Built-in shell presentation
|
|
56
|
-
type AdminChrome = "editorial" | "topbar" | "none";
|
|
87
|
+
/** Built-in shell presentation; embedded preserves site-owned chrome. */
|
|
88
|
+
type AdminChrome = "embedded" | "standalone" | "editorial" | "topbar" | "none";
|
|
89
|
+
/** Identity and sign-out services supplied to host-owned account controls. */
|
|
90
|
+
interface AdminAccountMenuProps {
|
|
91
|
+
brand: Brand;
|
|
92
|
+
email: string | null;
|
|
93
|
+
currentUser?: Record<string, unknown>;
|
|
94
|
+
signOut: () => void;
|
|
95
|
+
}
|
|
96
|
+
/** Workspace route and navigation services supplied to host-owned navigation. */
|
|
97
|
+
interface AdminWorkspaceNavProps {
|
|
98
|
+
workspaces: readonly AdminWorkspace[];
|
|
99
|
+
route: AdminRouteState;
|
|
100
|
+
navigate: (target: AdminRouteTarget) => void;
|
|
101
|
+
href: (target: AdminRouteTarget) => string;
|
|
102
|
+
}
|
|
57
103
|
interface AdminShellProps {
|
|
58
104
|
workspaces: AdminWorkspace[];
|
|
59
105
|
basePath: string;
|
|
@@ -62,13 +108,12 @@ interface AdminShellProps {
|
|
|
62
108
|
getToken: () => Promise<string | null>;
|
|
63
109
|
signOut: () => void;
|
|
64
110
|
email: string | null;
|
|
111
|
+
currentUser?: Record<string, unknown>;
|
|
65
112
|
routing?: AdminRouting;
|
|
66
113
|
chrome?: AdminChrome;
|
|
67
|
-
renderHeader?: (props:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
signOut: () => void;
|
|
71
|
-
}) => ReactNode;
|
|
114
|
+
renderHeader?: (props: AdminAccountMenuProps) => ReactNode;
|
|
115
|
+
renderAccountMenu?: (props: AdminAccountMenuProps) => ReactNode;
|
|
116
|
+
renderWorkspaceNav?: (props: AdminWorkspaceNavProps) => ReactNode;
|
|
72
117
|
}
|
|
73
118
|
|
|
74
119
|
/** Configuration for the Clerk-gated, brand-scoped Chapter admin console. */
|
|
@@ -84,9 +129,13 @@ interface ChapterAdminProps {
|
|
|
84
129
|
apiBase?: string;
|
|
85
130
|
/** Default fragment: `/admin/#people/person/record-id/profile`. */
|
|
86
131
|
routing?: AdminRouting;
|
|
87
|
-
/** Default
|
|
132
|
+
/** Default embedded. Standalone adds packaged global chrome. */
|
|
88
133
|
chrome?: AdminChrome;
|
|
89
134
|
renderHeader?: AdminShellProps["renderHeader"];
|
|
135
|
+
renderAccountMenu?: (props: AdminAccountMenuProps) => ReactNode;
|
|
136
|
+
renderWorkspaceNav?: (props: AdminWorkspaceNavProps) => ReactNode;
|
|
137
|
+
/** Adapt existing config/current-user endpoints without rewriting auth. */
|
|
138
|
+
auth?: ChapterAdminAuthAdapter;
|
|
90
139
|
}
|
|
91
140
|
/** Render the complete authenticated admin application from one Chapter config. */
|
|
92
141
|
declare function ChapterAdmin(props: ChapterAdminProps): react.JSX.Element;
|
|
@@ -97,6 +146,9 @@ declare function defaultAdminWorkspaces(chapter: Chapter): AdminWorkspace[];
|
|
|
97
146
|
/** Legacy default catalog. @deprecated Use defaultAdminWorkspaces. */
|
|
98
147
|
declare function defaultAdminSections(chapter: Chapter): AdminSection[];
|
|
99
148
|
|
|
149
|
+
/** Application-authoritative stage transitions used by Chapter collections. */
|
|
150
|
+
declare function applicationLifecycleAdapter(ctx: Pick<AdminSectionContext, "getToken">): CrmLifecycleAdapter;
|
|
151
|
+
|
|
100
152
|
/** Configuration for the person-collection compatibility preset. */
|
|
101
153
|
interface PeopleSectionOptions {
|
|
102
154
|
crm: Crm;
|
|
@@ -113,6 +165,13 @@ interface CollectionSectionOptions {
|
|
|
113
165
|
lifecycle?: boolean;
|
|
114
166
|
roles?: readonly string[];
|
|
115
167
|
networkSharing?: boolean;
|
|
168
|
+
lifecycleAdapter?: (CrmLifecycleAdapter | ((ctx: AdminSectionContext) => CrmLifecycleAdapter));
|
|
169
|
+
requireLifecycleAdapter?: boolean;
|
|
170
|
+
renderSummary?: (context: CrmWorkspaceMasterContext, ctx: AdminSectionContext) => ReactNode;
|
|
171
|
+
renderMaster?: (context: CrmWorkspaceMasterContext, ctx: AdminSectionContext) => ReactNode;
|
|
172
|
+
renderDetailHeader?: (context: CrmWorkspaceRecordContext, ctx: AdminSectionContext) => ReactNode;
|
|
173
|
+
renderEmptyDetail?: (context: CrmWorkspaceMasterContext, ctx: AdminSectionContext) => ReactNode;
|
|
174
|
+
hrefForRecord?: (record: CrmRecord, ctx: AdminSectionContext) => string;
|
|
116
175
|
extendRecordTabs?: (tabs: readonly RecordPanelTab[], context: CrmWorkspaceRecordContext) => readonly RecordPanelTab[];
|
|
117
176
|
}
|
|
118
177
|
/** Build one CRM collection as an admin workspace. */
|
|
@@ -121,6 +180,13 @@ declare function collectionSection(options: CollectionSectionOptions): AdminSect
|
|
|
121
180
|
declare function peopleSection(options: PeopleSectionOptions & {
|
|
122
181
|
roles?: readonly string[];
|
|
123
182
|
networkSharing?: boolean;
|
|
183
|
+
lifecycleAdapter?: CollectionSectionOptions["lifecycleAdapter"];
|
|
184
|
+
requireLifecycleAdapter?: boolean;
|
|
185
|
+
renderSummary?: CollectionSectionOptions["renderSummary"];
|
|
186
|
+
renderMaster?: CollectionSectionOptions["renderMaster"];
|
|
187
|
+
renderDetailHeader?: CollectionSectionOptions["renderDetailHeader"];
|
|
188
|
+
renderEmptyDetail?: CollectionSectionOptions["renderEmptyDetail"];
|
|
189
|
+
hrefForRecord?: CollectionSectionOptions["hrefForRecord"];
|
|
124
190
|
extendRecordTabs?: CollectionSectionOptions["extendRecordTabs"];
|
|
125
191
|
}): AdminSection;
|
|
126
192
|
|
|
@@ -223,4 +289,4 @@ declare function AdminNote({ children }: {
|
|
|
223
289
|
children: ReactNode;
|
|
224
290
|
}): react.JSX.Element;
|
|
225
291
|
|
|
226
|
-
export { type AdminChrome, AdminNote, AdminPage, type AdminResource, type AdminRouteState, type AdminRouteTarget, type AdminRouting, type AdminSection, type AdminSectionContext, type AdminWorkspace, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminProps, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, meetingsSection, peopleSection, useAdminResource };
|
|
292
|
+
export { type AdminAccountMenuProps, type AdminChrome, AdminNote, AdminPage, type AdminResource, type AdminRouteState, type AdminRouteTarget, type AdminRouting, type AdminSection, type AdminSectionContext, type AdminWorkspace, type AdminWorkspaceNavProps, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminAuthAdapter, type ChapterAdminAuthConfig, type ChapterAdminAuthLoadContext, type ChapterAdminProps, type ChapterAdminUser, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, applicationLifecycleAdapter, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, peopleSection, useAdminResource };
|
package/dist/ui/admin/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
adminRouteHref,
|
|
12
12
|
adminSectionFromUrl,
|
|
13
13
|
adminSectionHref,
|
|
14
|
+
applicationLifecycleAdapter,
|
|
14
15
|
availabilitySection,
|
|
15
16
|
billingSection,
|
|
16
17
|
collectionSection,
|
|
@@ -18,11 +19,13 @@ import {
|
|
|
18
19
|
defaultAdminSections,
|
|
19
20
|
defaultAdminWorkspaces,
|
|
20
21
|
emailSection,
|
|
22
|
+
loadChapterAdminConfig,
|
|
23
|
+
loadChapterAdminUser,
|
|
21
24
|
meetingsSection,
|
|
22
25
|
peopleSection,
|
|
23
26
|
useAdminResource
|
|
24
|
-
} from "../../chunk-
|
|
25
|
-
import "../../chunk-
|
|
27
|
+
} from "../../chunk-IWW5VAAC.js";
|
|
28
|
+
import "../../chunk-VZPBTTO3.js";
|
|
26
29
|
export {
|
|
27
30
|
AdminNote,
|
|
28
31
|
AdminPage,
|
|
@@ -36,6 +39,7 @@ export {
|
|
|
36
39
|
adminRouteHref,
|
|
37
40
|
adminSectionFromUrl,
|
|
38
41
|
adminSectionHref,
|
|
42
|
+
applicationLifecycleAdapter,
|
|
39
43
|
availabilitySection,
|
|
40
44
|
billingSection,
|
|
41
45
|
collectionSection,
|
|
@@ -43,6 +47,8 @@ export {
|
|
|
43
47
|
defaultAdminSections,
|
|
44
48
|
defaultAdminWorkspaces,
|
|
45
49
|
emailSection,
|
|
50
|
+
loadChapterAdminConfig,
|
|
51
|
+
loadChapterAdminUser,
|
|
46
52
|
meetingsSection,
|
|
47
53
|
peopleSection,
|
|
48
54
|
useAdminResource
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { AdminChrome, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminProps, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
|
|
1
|
+
export { AdminAccountMenuProps, AdminChrome, AdminNote, AdminPage, AdminResource, AdminRouteState, AdminRouteTarget, AdminRouting, AdminSection, AdminSectionContext, AdminWorkspace, AdminWorkspaceNavProps, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminAuthAdapter, ChapterAdminAuthConfig, ChapterAdminAuthLoadContext, ChapterAdminProps, ChapterAdminUser, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminRouteFromUrl, adminRouteHref, adminSectionFromUrl, adminSectionHref, applicationLifecycleAdapter, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, defaultAdminWorkspaces, emailSection, loadChapterAdminConfig, loadChapterAdminUser, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
|
|
2
2
|
export { ApiFn, BrandStyle, BrandStyleProps, JoinConfig, JoinIsland, JoinIslandProps, MembersArea, MembersAreaProps, PaymentStep, PaymentStepProps, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, timeLabel, tzShort } from './member/index.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '@odla-ai/crm';
|
|
5
|
-
import '../types-
|
|
5
|
+
import '../types-CgWUQ2MH.js';
|
|
6
6
|
import '@odla-ai/crm/ui';
|
package/dist/ui/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
adminRouteHref,
|
|
27
27
|
adminSectionFromUrl,
|
|
28
28
|
adminSectionHref,
|
|
29
|
+
applicationLifecycleAdapter,
|
|
29
30
|
availabilitySection,
|
|
30
31
|
billingSection,
|
|
31
32
|
collectionSection,
|
|
@@ -33,13 +34,15 @@ import {
|
|
|
33
34
|
defaultAdminSections,
|
|
34
35
|
defaultAdminWorkspaces,
|
|
35
36
|
emailSection,
|
|
37
|
+
loadChapterAdminConfig,
|
|
38
|
+
loadChapterAdminUser,
|
|
36
39
|
meetingsSection,
|
|
37
40
|
peopleSection,
|
|
38
41
|
useAdminResource
|
|
39
|
-
} from "../chunk-
|
|
42
|
+
} from "../chunk-IWW5VAAC.js";
|
|
40
43
|
import {
|
|
41
44
|
BrandStyle
|
|
42
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-VZPBTTO3.js";
|
|
43
46
|
export {
|
|
44
47
|
AdminNote,
|
|
45
48
|
AdminPage,
|
|
@@ -59,6 +62,7 @@ export {
|
|
|
59
62
|
adminRouteHref,
|
|
60
63
|
adminSectionFromUrl,
|
|
61
64
|
adminSectionHref,
|
|
65
|
+
applicationLifecycleAdapter,
|
|
62
66
|
availabilitySection,
|
|
63
67
|
billingSection,
|
|
64
68
|
collectionSection,
|
|
@@ -72,6 +76,8 @@ export {
|
|
|
72
76
|
fmtMoney,
|
|
73
77
|
fullLabel,
|
|
74
78
|
groupSlotsByDay,
|
|
79
|
+
loadChapterAdminConfig,
|
|
80
|
+
loadChapterAdminUser,
|
|
75
81
|
meetingsSection,
|
|
76
82
|
peopleSection,
|
|
77
83
|
timeLabel,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { a as ChapterBrand } from '../../types-
|
|
3
|
+
import { a as ChapterBrand } from '../../types-CgWUQ2MH.js';
|
|
4
4
|
import '@odla-ai/crm';
|
|
5
5
|
|
|
6
6
|
/** A bookable slot: a start instant in epoch milliseconds. */
|
package/dist/ui/member/index.js
CHANGED
package/dist/worker/index.d.cts
CHANGED
|
@@ -51,8 +51,22 @@ interface ChapterBrandTokens {
|
|
|
51
51
|
danger?: string;
|
|
52
52
|
chart1?: string;
|
|
53
53
|
chart2?: string;
|
|
54
|
+
chart3?: string;
|
|
55
|
+
chart4?: string;
|
|
56
|
+
chart5?: string;
|
|
57
|
+
chart6?: string;
|
|
54
58
|
chartPositive?: string;
|
|
55
59
|
chartNegative?: string;
|
|
60
|
+
/** Admin/application content width, e.g. `"960px"`. */
|
|
61
|
+
contentWidth?: string;
|
|
62
|
+
panelRadius?: string;
|
|
63
|
+
panelShadow?: string;
|
|
64
|
+
masterDetailColumns?: string;
|
|
65
|
+
masterDetailMinHeight?: string;
|
|
66
|
+
/** Chapter-admin page padding shorthand. */
|
|
67
|
+
pagePadding?: string;
|
|
68
|
+
/** Chapter-admin workspace-tab padding shorthand. */
|
|
69
|
+
workspacePadding?: string;
|
|
56
70
|
}
|
|
57
71
|
/** Brand tokens that theme the site: theme, semantic roles, fonts, and logos. */
|
|
58
72
|
interface ChapterBrand {
|
package/dist/worker/index.d.ts
CHANGED
|
@@ -51,8 +51,22 @@ interface ChapterBrandTokens {
|
|
|
51
51
|
danger?: string;
|
|
52
52
|
chart1?: string;
|
|
53
53
|
chart2?: string;
|
|
54
|
+
chart3?: string;
|
|
55
|
+
chart4?: string;
|
|
56
|
+
chart5?: string;
|
|
57
|
+
chart6?: string;
|
|
54
58
|
chartPositive?: string;
|
|
55
59
|
chartNegative?: string;
|
|
60
|
+
/** Admin/application content width, e.g. `"960px"`. */
|
|
61
|
+
contentWidth?: string;
|
|
62
|
+
panelRadius?: string;
|
|
63
|
+
panelShadow?: string;
|
|
64
|
+
masterDetailColumns?: string;
|
|
65
|
+
masterDetailMinHeight?: string;
|
|
66
|
+
/** Chapter-admin page padding shorthand. */
|
|
67
|
+
pagePadding?: string;
|
|
68
|
+
/** Chapter-admin workspace-tab padding shorthand. */
|
|
69
|
+
workspacePadding?: string;
|
|
56
70
|
}
|
|
57
71
|
/** Brand tokens that theme the site: theme, semantic roles, fonts, and logos. */
|
|
58
72
|
interface ChapterBrand {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odla-ai/chapter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "A leader/follower foundation for branded membership sites: shared CRM, admin, auth, payments, booking, and explicit record delivery from one defineChapter config.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://odla.ai/docs/packages/chapter",
|
|
@@ -70,13 +70,13 @@
|
|
|
70
70
|
"prepublishOnly": "npm run build && npm test"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@odla-ai/crm": "^0.
|
|
73
|
+
"@odla-ai/crm": "^0.3.0",
|
|
74
74
|
"jose": "^6.2.3"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"@odla-ai/calendar": ">=0.2.0 <1.0.0",
|
|
78
78
|
"@odla-ai/db": ">=0.6.0 <1.0.0",
|
|
79
|
-
"@odla-ai/ui": ">=0.
|
|
79
|
+
"@odla-ai/ui": ">=0.12.0 <1.0.0",
|
|
80
80
|
"react": ">=18"
|
|
81
81
|
},
|
|
82
82
|
"peerDependenciesMeta": {
|
|
@@ -118,7 +118,7 @@ npx @odla-ai/cli@0.17.1 capabilities --json
|
|
|
118
118
|
|
|
119
119
|
Pin the exact known-good package matrix from the installed Chapter README.
|
|
120
120
|
For this runbook, first require
|
|
121
|
-
`npm view @odla-ai/chapter@0.
|
|
121
|
+
`npm view @odla-ai/chapter@0.22.0 version` to succeed. Install every runtime,
|
|
122
122
|
toolchain, CLI, and security package with the exact versions in that README;
|
|
123
123
|
never use `latest`, a range, or `--legacy-peer-deps`.
|
|
124
124
|
|
|
@@ -356,9 +356,18 @@ fixture. Compare markup/behavior and the Phase 0 screenshots before deletion.
|
|
|
356
356
|
- Replace join orchestration with `JoinIsland`, member behavior with
|
|
357
357
|
`MembersArea`, and admin with `<ChapterAdmin chapter={chapter}/>` only after
|
|
358
358
|
field/auth/action parity.
|
|
359
|
-
- Preserve the site's global header with `chrome="
|
|
360
|
-
|
|
361
|
-
|
|
359
|
+
- Preserve the site's global header with the default `chrome="embedded"`;
|
|
360
|
+
use `chrome="standalone"` only when Chapter should supply the masthead, or
|
|
361
|
+
`renderHeader` when the header belongs inside the Chapter scope. Chapter mode
|
|
362
|
+
defaults to Dashboard, People, and Settings; move former global Billing,
|
|
363
|
+
Calendar, Email, and per-record operations into nested tabs.
|
|
364
|
+
- Preserve a distinctive People summary, rail, and record heading with
|
|
365
|
+
`collectionSection`'s `renderSummary`, `renderMaster`, and
|
|
366
|
+
`renderDetailHeader` slots. Replace specialized record tabs rather than
|
|
367
|
+
flattening them into global navigation.
|
|
368
|
+
- Application-backed pipeline changes must use a lifecycle adapter that invokes
|
|
369
|
+
the authoritative application endpoints. Prove approve/refund/manual
|
|
370
|
+
transition side effects; a raw CRM `setStage` is not parity.
|
|
362
371
|
- Accept old query/path admin links as inbound compatibility URLs, but generate
|
|
363
372
|
canonical fragment links such as
|
|
364
373
|
`/admin/#people/person/record-id/profile`. Prove refresh, back/forward, and
|
package/runbooks/greenfield.md
CHANGED
|
@@ -117,13 +117,13 @@ npx @odla-ai/cli@0.17.1 setup
|
|
|
117
117
|
|
|
118
118
|
Verify every release target exists, then install the exact known-good React
|
|
119
119
|
host matrix. Do not copy these commands into a pre-release branch where
|
|
120
|
-
`@odla-ai/chapter@0.
|
|
120
|
+
`@odla-ai/chapter@0.22.0` is not yet on npm.
|
|
121
121
|
|
|
122
122
|
```sh
|
|
123
|
-
npm view @odla-ai/chapter@0.
|
|
123
|
+
npm view @odla-ai/chapter@0.22.0 version
|
|
124
124
|
npm install --save-exact \
|
|
125
|
-
@odla-ai/chapter@0.
|
|
126
|
-
@odla-ai/crm@0.
|
|
125
|
+
@odla-ai/chapter@0.22.0 @odla-ai/ui@0.12.0 \
|
|
126
|
+
@odla-ai/crm@0.3.0 @odla-ai/db@0.6.6 \
|
|
127
127
|
@odla-ai/calendar@0.2.0 @odla-ai/email@0.3.1 \
|
|
128
128
|
@odla-ai/auth-clerk@0.4.0 @odla-ai/o11y@2.2.2 \
|
|
129
129
|
jose@6.2.3 react@19.2.7 react-dom@19.2.7
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/brand.ts","../src/ui/brand-style.tsx"],"sourcesContent":["// Brand tokens (H4). defineChapter accepts a `brand` block; this turns it into a\n// `:root { --…: … }` CSS block, so a chapter re-skins the WHOLE UI — the\n// @odla-ai/ui components, the admin shell, and the member islands, which all read\n// --ui-* design tokens — from one config instead of hand-writing inline CSS.\n//\n// Pure string generation, so it is unit-testable and can be emitted at\n// build/SSR time into the page <head> (no flash of unstyled content), or via the\n// <BrandStyle> component from @odla-ai/chapter/ui.\nimport type { ChapterBrand, ChapterBrandTokens } from \"./types\";\n\n// A palette entry is either a direct custom property (already `--…`, e.g.\n// `--ui-accent` to retheme components) or a bare name we expose as `--<name>`\n// (e.g. `moss` → `--moss`, for a site to reference in its own CSS).\nfunction paletteVar(key: string): string {\n return key.startsWith(\"--\") ? key : `--${key}`;\n}\n\n// Strip characters that could break out of a `--var: value;` declaration or the\n// surrounding <style>. Brand config is trusted author input, so this is a\n// belt-and-suspenders guard, not a security boundary.\nfunction cleanValue(value: string): string {\n return value.replace(/[<>{};]/g, \"\").trim();\n}\n\nfunction paletteDecls(palette: Record<string, string> | undefined): string[] {\n const decls: string[] = [];\n for (const [key, value] of Object.entries(palette ?? {})) {\n if (typeof value === \"string\" && value.trim()) decls.push(`${paletteVar(key)}: ${cleanValue(value)};`);\n }\n return decls;\n}\n\nconst TOKEN_VARS: Record<keyof ChapterBrandTokens, string> = {\n background: \"--ui-bg\",\n surface: \"--ui-surface\",\n surface2: \"--ui-surface-2\",\n text: \"--ui-text\",\n textMuted: \"--ui-text-muted\",\n textFaint: \"--ui-text-faint\",\n border: \"--ui-border\",\n borderStrong: \"--ui-border-strong\",\n accent: \"--ui-accent\",\n accentStrong: \"--ui-accent-strong\",\n accentSoft: \"--ui-accent-soft\",\n onAccent: \"--ui-on-accent\",\n good: \"--ui-good\",\n warn: \"--ui-warn\",\n danger: \"--ui-danger\",\n chart1: \"--ui-chart-1\",\n chart2: \"--ui-chart-2\",\n chartPositive: \"--ui-chart-pos\",\n chartNegative: \"--ui-chart-neg\",\n};\n\nfunction semanticDecls(tokens: ChapterBrandTokens | undefined): string[] {\n return Object.entries(tokens ?? {}).flatMap(([key, value]) =>\n typeof value === \"string\" && value.trim()\n ? [`${TOKEN_VARS[key as keyof ChapterBrandTokens]}: ${cleanValue(value)};`]\n : [],\n );\n}\n\n/**\n * Build the CSS that maps a chapter's brand onto the design tokens the UI reads:\n * each `palette` entry becomes a custom property (light, and dark unless\n * `paletteDark` overrides), and `fonts` (display/body/numeral) map to\n * `--ui-font-display` / `--ui-font-sans` / `--ui-font-numeral`. The dark block is\n * emitted under both `:root[data-theme=\"dark\"]` (the odla-ui theme toggle) and\n * `@media (prefers-color-scheme: dark)`. Returns \"\" when there is nothing to\n * theme. These are brand OVERRIDES on top of a base theme — they do not replace\n * the theme layer the components need (see {@link brandTokens} usage in the docs).\n */\nexport function brandTokens(\n brand: ChapterBrand | undefined,\n options: { selector?: string } = {},\n): string {\n if (!brand) return \"\";\n const light = [...paletteDecls(brand.palette), ...semanticDecls(brand.tokens)];\n const fonts = brand.fonts;\n if (fonts?.display) light.push(`--ui-font-display: ${cleanValue(fonts.display)};`);\n if (fonts?.body) light.push(`--ui-font-sans: ${cleanValue(fonts.body)};`);\n if (fonts?.numeral) light.push(`--ui-font-numeral: ${cleanValue(fonts.numeral)};`);\n const dark = [...paletteDecls(brand.paletteDark), ...semanticDecls(brand.tokensDark)];\n const selector = options.selector ?? \":root\";\n const darkSelector = selector === \":root\" ? ':root[data-theme=\"dark\"]' : `${selector}[data-theme=\"dark\"]`;\n const systemSelector = selector === \":root\"\n ? ':root:not([data-theme=\"light\"])'\n : `${selector}:not([data-theme=\"light\"])`;\n\n let css = light.length ? `${selector} {\\n ${light.join(\"\\n \")}\\n}\\n` : \"\";\n if (dark.length) {\n const block = `{\\n ${dark.join(\"\\n \")}\\n}`;\n css += `${darkSelector} ${block}\\n@media (prefers-color-scheme: dark) {\\n ${systemSelector} ${block}\\n}\\n`;\n }\n return css;\n}\n","// Client-side convenience for brand tokens: render the chapter's brand as a\n// <style> tag. Prefer emitting brandTokens() into the page <head> at build/SSR\n// time (no flash); use this when that isn't available (e.g. a pure SPA mount).\nimport { brandTokens } from \"../brand.js\";\nimport type { ChapterBrand } from \"../types\";\n\n/** Props for {@link BrandStyle}. */\nexport interface BrandStyleProps {\n brand: ChapterBrand | undefined;\n /** CSS selector receiving the variables. Default `:root`. */\n selector?: string;\n}\n\n/** Render a chapter's brand tokens as an inline <style> block (or nothing when\n * there is no brand to theme). */\nexport function BrandStyle(props: BrandStyleProps) {\n const css = brandTokens(props.brand, { selector: props.selector });\n if (!css) return null;\n return <style>{css}</style>;\n}\n"],"mappings":";AAaA,SAAS,WAAW,KAAqB;AACvC,SAAO,IAAI,WAAW,IAAI,IAAI,MAAM,KAAK,GAAG;AAC9C;AAKA,SAAS,WAAW,OAAuB;AACzC,SAAO,MAAM,QAAQ,YAAY,EAAE,EAAE,KAAK;AAC5C;AAEA,SAAS,aAAa,SAAuD;AAC3E,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,CAAC,CAAC,GAAG;AACxD,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAG,OAAM,KAAK,GAAG,WAAW,GAAG,CAAC,KAAK,WAAW,KAAK,CAAC,GAAG;AAAA,EACvG;AACA,SAAO;AACT;AAEA,IAAM,aAAuD;AAAA,EAC3D,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,eAAe;AACjB;AAEA,SAAS,cAAc,QAAkD;AACvE,SAAO,OAAO,QAAQ,UAAU,CAAC,CAAC,EAAE;AAAA,IAAQ,CAAC,CAAC,KAAK,KAAK,MACtD,OAAO,UAAU,YAAY,MAAM,KAAK,IACpC,CAAC,GAAG,WAAW,GAA+B,CAAC,KAAK,WAAW,KAAK,CAAC,GAAG,IACxE,CAAC;AAAA,EACP;AACF;AAYO,SAAS,YACd,OACA,UAAiC,CAAC,GAC1B;AACR,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,CAAC,GAAG,aAAa,MAAM,OAAO,GAAG,GAAG,cAAc,MAAM,MAAM,CAAC;AAC7E,QAAM,QAAQ,MAAM;AACpB,MAAI,OAAO,QAAS,OAAM,KAAK,sBAAsB,WAAW,MAAM,OAAO,CAAC,GAAG;AACjF,MAAI,OAAO,KAAM,OAAM,KAAK,mBAAmB,WAAW,MAAM,IAAI,CAAC,GAAG;AACxE,MAAI,OAAO,QAAS,OAAM,KAAK,sBAAsB,WAAW,MAAM,OAAO,CAAC,GAAG;AACjF,QAAM,OAAO,CAAC,GAAG,aAAa,MAAM,WAAW,GAAG,GAAG,cAAc,MAAM,UAAU,CAAC;AACpF,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,eAAe,aAAa,UAAU,6BAA6B,GAAG,QAAQ;AACpF,QAAM,iBAAiB,aAAa,UAChC,oCACA,GAAG,QAAQ;AAEf,MAAI,MAAM,MAAM,SAAS,GAAG,QAAQ;AAAA,IAAS,MAAM,KAAK,MAAM,CAAC;AAAA;AAAA,IAAU;AACzE,MAAI,KAAK,QAAQ;AACf,UAAM,QAAQ;AAAA,IAAQ,KAAK,KAAK,MAAM,CAAC;AAAA;AACvC,WAAO,GAAG,YAAY,IAAI,KAAK;AAAA;AAAA,IAA8C,cAAc,IAAI,KAAK;AAAA;AAAA;AAAA,EACtG;AACA,SAAO;AACT;;;AC7ES;AAHF,SAAS,WAAW,OAAwB;AACjD,QAAM,MAAM,YAAY,MAAM,OAAO,EAAE,UAAU,MAAM,SAAS,CAAC;AACjE,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,oBAAC,WAAO,eAAI;AACrB;","names":[]}
|