@broberg/app-shell 0.5.0 → 0.7.1
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 +52 -0
- package/css/app-shell.css +48 -0
- package/dist/index.cjs +124 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -1
- package/dist/index.d.ts +119 -1
- package/dist/index.js +117 -3
- package/dist/index.js.map +1 -1
- package/dist/preact.cjs +297 -3
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.cts +154 -1
- package/dist/preact.d.ts +154 -1
- package/dist/preact.js +288 -4
- package/dist/preact.js.map +1 -1
- package/package.json +3 -1
package/dist/preact.d.cts
CHANGED
|
@@ -153,6 +153,84 @@ declare function createFetchAccountAdapter(opts?: {
|
|
|
153
153
|
fetch?: typeof fetch;
|
|
154
154
|
credentials?: RequestCredentials;
|
|
155
155
|
}): AccountAdapter;
|
|
156
|
+
interface AnalyticsDay {
|
|
157
|
+
/** YYYY-MM-DD on the Europe/Copenhagen calendar (Upmetrics' own day key). */
|
|
158
|
+
day: string;
|
|
159
|
+
visitors: number;
|
|
160
|
+
pageviews: number;
|
|
161
|
+
}
|
|
162
|
+
interface AnalyticsData {
|
|
163
|
+
totals: {
|
|
164
|
+
visitors: number;
|
|
165
|
+
pageviews: number;
|
|
166
|
+
};
|
|
167
|
+
/** The same-length period just before this one. */
|
|
168
|
+
prev: {
|
|
169
|
+
visitors: number;
|
|
170
|
+
pageviews: number;
|
|
171
|
+
};
|
|
172
|
+
/** Only days that had visits — use fillDays() to draw the whole period. */
|
|
173
|
+
series: AnalyticsDay[];
|
|
174
|
+
topPages: {
|
|
175
|
+
value: string;
|
|
176
|
+
count: number;
|
|
177
|
+
}[];
|
|
178
|
+
}
|
|
179
|
+
interface AnalyticsAdapter {
|
|
180
|
+
load(days: number): Promise<AnalyticsData>;
|
|
181
|
+
}
|
|
182
|
+
/** A failed analytics call: HTTP status (0 = no answer) and the server's `error` code. */
|
|
183
|
+
declare class AnalyticsError extends Error {
|
|
184
|
+
readonly status: number;
|
|
185
|
+
readonly code?: string | undefined;
|
|
186
|
+
constructor(status: number, code?: string | undefined);
|
|
187
|
+
}
|
|
188
|
+
/** "unconfigured" only for the backend's explicit 503 analytics_unconfigured; anything else is "unavailable". */
|
|
189
|
+
declare function analyticsErrorKind(err: unknown): "unconfigured" | "unavailable";
|
|
190
|
+
/**
|
|
191
|
+
* The default adapter: `GET {url}?days=N` on the app's own backend (default
|
|
192
|
+
* /api/analytics, where `@upmetrics/sdk/hono`'s analyticsRoutes() answers).
|
|
193
|
+
* A non-2xx, an unreadable body or no answer at all THROWS — never zeros that
|
|
194
|
+
* look like a real, quiet month.
|
|
195
|
+
*/
|
|
196
|
+
declare function createFetchAnalyticsAdapter(opts?: {
|
|
197
|
+
url?: string;
|
|
198
|
+
fetch?: typeof fetch;
|
|
199
|
+
credentials?: RequestCredentials;
|
|
200
|
+
}): AnalyticsAdapter;
|
|
201
|
+
/** Today's YYYY-MM-DD on the Copenhagen calendar — the calendar Upmetrics buckets on. */
|
|
202
|
+
declare function copenhagenDay(at?: Date): string;
|
|
203
|
+
/**
|
|
204
|
+
* Exactly `days` entries ending today (Copenhagen calendar), with Upmetrics'
|
|
205
|
+
* values where it sent a day and zeros where it did not — Upmetrics only sends
|
|
206
|
+
* days that had visits. Calendar arithmetic, so a DST change never skips or
|
|
207
|
+
* repeats a day.
|
|
208
|
+
*/
|
|
209
|
+
declare function fillDays(series: AnalyticsDay[], days: number, now?: Date): AnalyticsDay[];
|
|
210
|
+
/** Whole-percent change against the previous period, or null when there is nothing to compare with. */
|
|
211
|
+
declare function changePct(now: number, before: number): number | null;
|
|
212
|
+
interface TenantMembershipRow {
|
|
213
|
+
tenant: {
|
|
214
|
+
id: string;
|
|
215
|
+
slug: string;
|
|
216
|
+
name: string;
|
|
217
|
+
status?: "active" | "suspended";
|
|
218
|
+
};
|
|
219
|
+
role: string;
|
|
220
|
+
}
|
|
221
|
+
interface TenantAdapter {
|
|
222
|
+
load(): Promise<TenantMembershipRow[]>;
|
|
223
|
+
}
|
|
224
|
+
declare class TenantLoadError extends Error {
|
|
225
|
+
readonly status: number;
|
|
226
|
+
constructor(status: number);
|
|
227
|
+
}
|
|
228
|
+
/** GET {url} (default /api/me/memberships) → the user's memberships. Non-2xx or a bad body THROWS. */
|
|
229
|
+
declare function createFetchTenantAdapter(opts?: {
|
|
230
|
+
url?: string;
|
|
231
|
+
fetch?: typeof fetch;
|
|
232
|
+
credentials?: RequestCredentials;
|
|
233
|
+
}): TenantAdapter;
|
|
156
234
|
declare const TEXT: {
|
|
157
235
|
readonly da: {
|
|
158
236
|
readonly openMenu: "Åbn menu";
|
|
@@ -201,6 +279,26 @@ declare const TEXT: {
|
|
|
201
279
|
readonly pictureTooLarge: "Billedet er for stort — højst 2 MB.";
|
|
202
280
|
readonly pictureWrongType: "Vælg et PNG-, JPEG- eller WebP-billede.";
|
|
203
281
|
readonly bidSecurity: "Sikkerhed i Broberg ID";
|
|
282
|
+
readonly analyticsPeriod: "Periode";
|
|
283
|
+
readonly analyticsDays: "{n} dage";
|
|
284
|
+
readonly analyticsVisitors: "Besøgende";
|
|
285
|
+
readonly analyticsPageviews: "Sidevisninger";
|
|
286
|
+
readonly analyticsVsPrev: "{pct} % mod forrige periode";
|
|
287
|
+
readonly analyticsNoPrev: "Ingen sammenligning";
|
|
288
|
+
readonly analyticsOverTime: "Sidevisninger pr. dag";
|
|
289
|
+
readonly analyticsTopPages: "Mest besøgte sider";
|
|
290
|
+
readonly analyticsDay: "Dag";
|
|
291
|
+
readonly analyticsPage: "Side";
|
|
292
|
+
readonly analyticsEmpty: "Ingen besøg i perioden.";
|
|
293
|
+
readonly analyticsLoading: "Henter tal…";
|
|
294
|
+
readonly analyticsUnconfigured: "Analytics er ikke sat op for denne app.";
|
|
295
|
+
readonly analyticsUnavailable: "Upmetrics svarer ikke lige nu. Prøv igen om lidt.";
|
|
296
|
+
readonly tenantSwitch: "Skift organisation";
|
|
297
|
+
readonly tenantLoadFailed: "Kunne ikke hente dine organisationer.";
|
|
298
|
+
readonly tenantSwitchFailed: "Kunne ikke skifte organisation. Du er stadig i {name}.";
|
|
299
|
+
readonly tenantRetry: "Prøv igen";
|
|
300
|
+
readonly tenantSuspended: "lukket";
|
|
301
|
+
readonly tenantActive: "aktiv";
|
|
204
302
|
};
|
|
205
303
|
readonly en: {
|
|
206
304
|
readonly openMenu: "Open menu";
|
|
@@ -249,6 +347,26 @@ declare const TEXT: {
|
|
|
249
347
|
readonly pictureTooLarge: "The picture is too large — 2 MB at most.";
|
|
250
348
|
readonly pictureWrongType: "Choose a PNG, JPEG or WebP image.";
|
|
251
349
|
readonly bidSecurity: "Security in Broberg ID";
|
|
350
|
+
readonly analyticsPeriod: "Period";
|
|
351
|
+
readonly analyticsDays: "{n} days";
|
|
352
|
+
readonly analyticsVisitors: "Visitors";
|
|
353
|
+
readonly analyticsPageviews: "Page views";
|
|
354
|
+
readonly analyticsVsPrev: "{pct}% vs previous period";
|
|
355
|
+
readonly analyticsNoPrev: "No comparison";
|
|
356
|
+
readonly analyticsOverTime: "Page views per day";
|
|
357
|
+
readonly analyticsTopPages: "Most visited pages";
|
|
358
|
+
readonly analyticsDay: "Day";
|
|
359
|
+
readonly analyticsPage: "Page";
|
|
360
|
+
readonly analyticsEmpty: "No visits in this period.";
|
|
361
|
+
readonly analyticsLoading: "Loading figures…";
|
|
362
|
+
readonly analyticsUnconfigured: "Analytics is not set up for this app.";
|
|
363
|
+
readonly analyticsUnavailable: "Upmetrics is not answering right now. Try again shortly.";
|
|
364
|
+
readonly tenantSwitch: "Switch organisation";
|
|
365
|
+
readonly tenantLoadFailed: "Could not load your organisations.";
|
|
366
|
+
readonly tenantSwitchFailed: "Could not switch organisation. You are still in {name}.";
|
|
367
|
+
readonly tenantRetry: "Try again";
|
|
368
|
+
readonly tenantSuspended: "suspended";
|
|
369
|
+
readonly tenantActive: "active";
|
|
252
370
|
};
|
|
253
371
|
};
|
|
254
372
|
type Lang = keyof typeof TEXT;
|
|
@@ -463,5 +581,40 @@ declare function defaultReauthHref(): string;
|
|
|
463
581
|
* typed text, so nothing is lost and the error says why.
|
|
464
582
|
*/
|
|
465
583
|
declare function AccountPage({ lang, adapter, reauthHref, onProfileChange }: AccountPageProps): JSX.Element;
|
|
584
|
+
interface AnalyticsPageProps {
|
|
585
|
+
lang: Lang;
|
|
586
|
+
/** Default: `createFetchAnalyticsAdapter()` → GET /api/analytics?days=N (@upmetrics/sdk/hono analyticsRoutes). */
|
|
587
|
+
adapter?: AnalyticsAdapter;
|
|
588
|
+
/** The period buttons, in days. Default 7 / 30 / 90. */
|
|
589
|
+
periods?: number[];
|
|
590
|
+
/** The period shown first. Default 30 (or the first of `periods` when 30 is not one of them). */
|
|
591
|
+
initialDays?: number;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* The app's own visitors, page views, page views per day and most visited
|
|
595
|
+
* pages, from Upmetrics through the app's backend (F097.1). A backend that is
|
|
596
|
+
* not set up or does not answer says so — it never shows zeros that would read
|
|
597
|
+
* as a quiet month.
|
|
598
|
+
*/
|
|
599
|
+
declare function AnalyticsPage({ lang, adapter, periods, initialDays }: AnalyticsPageProps): JSX.Element;
|
|
600
|
+
interface TenantSwitcherProps {
|
|
601
|
+
lang: Lang;
|
|
602
|
+
/** The slug the app is in right now — the app knows it (from tenantMiddleware). */
|
|
603
|
+
activeSlug: string;
|
|
604
|
+
/** Default: `createFetchTenantAdapter()` → GET /api/me/memberships (@broberg/tenant/hono tenantRoutes). */
|
|
605
|
+
adapter?: TenantAdapter;
|
|
606
|
+
/**
|
|
607
|
+
* Switch through the APP's own route — navigate to `/t/<slug>/…`, or set the
|
|
608
|
+
* preference and reload. A rejection keeps the current organisation and shows
|
|
609
|
+
* why; the switcher never pretends a switch happened.
|
|
610
|
+
*/
|
|
611
|
+
onSwitch: (slug: string) => Promise<void> | void;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* The user's own organisations, the active one marked, and a switch. Only the
|
|
615
|
+
* memberships the backend returns are listed — never a typed or guessed slug.
|
|
616
|
+
* With one organisation it is a plain label, not a menu.
|
|
617
|
+
*/
|
|
618
|
+
declare function TenantSwitcher({ lang, activeSlug, adapter, onSwitch }: TenantSwitcherProps): JSX.Element;
|
|
466
619
|
|
|
467
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, AppShell, type AppShellProps, Avatar, type Lang, type NavGroup, type NavItem, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, badgeLabel, checkAvatarFile, createFetchAccountAdapter, createFetchNotificationSource, createMemoryNotificationSource, defaultReauthHref, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
620
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, type Lang, type NavGroup, type NavItem, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
package/dist/preact.d.ts
CHANGED
|
@@ -153,6 +153,84 @@ declare function createFetchAccountAdapter(opts?: {
|
|
|
153
153
|
fetch?: typeof fetch;
|
|
154
154
|
credentials?: RequestCredentials;
|
|
155
155
|
}): AccountAdapter;
|
|
156
|
+
interface AnalyticsDay {
|
|
157
|
+
/** YYYY-MM-DD on the Europe/Copenhagen calendar (Upmetrics' own day key). */
|
|
158
|
+
day: string;
|
|
159
|
+
visitors: number;
|
|
160
|
+
pageviews: number;
|
|
161
|
+
}
|
|
162
|
+
interface AnalyticsData {
|
|
163
|
+
totals: {
|
|
164
|
+
visitors: number;
|
|
165
|
+
pageviews: number;
|
|
166
|
+
};
|
|
167
|
+
/** The same-length period just before this one. */
|
|
168
|
+
prev: {
|
|
169
|
+
visitors: number;
|
|
170
|
+
pageviews: number;
|
|
171
|
+
};
|
|
172
|
+
/** Only days that had visits — use fillDays() to draw the whole period. */
|
|
173
|
+
series: AnalyticsDay[];
|
|
174
|
+
topPages: {
|
|
175
|
+
value: string;
|
|
176
|
+
count: number;
|
|
177
|
+
}[];
|
|
178
|
+
}
|
|
179
|
+
interface AnalyticsAdapter {
|
|
180
|
+
load(days: number): Promise<AnalyticsData>;
|
|
181
|
+
}
|
|
182
|
+
/** A failed analytics call: HTTP status (0 = no answer) and the server's `error` code. */
|
|
183
|
+
declare class AnalyticsError extends Error {
|
|
184
|
+
readonly status: number;
|
|
185
|
+
readonly code?: string | undefined;
|
|
186
|
+
constructor(status: number, code?: string | undefined);
|
|
187
|
+
}
|
|
188
|
+
/** "unconfigured" only for the backend's explicit 503 analytics_unconfigured; anything else is "unavailable". */
|
|
189
|
+
declare function analyticsErrorKind(err: unknown): "unconfigured" | "unavailable";
|
|
190
|
+
/**
|
|
191
|
+
* The default adapter: `GET {url}?days=N` on the app's own backend (default
|
|
192
|
+
* /api/analytics, where `@upmetrics/sdk/hono`'s analyticsRoutes() answers).
|
|
193
|
+
* A non-2xx, an unreadable body or no answer at all THROWS — never zeros that
|
|
194
|
+
* look like a real, quiet month.
|
|
195
|
+
*/
|
|
196
|
+
declare function createFetchAnalyticsAdapter(opts?: {
|
|
197
|
+
url?: string;
|
|
198
|
+
fetch?: typeof fetch;
|
|
199
|
+
credentials?: RequestCredentials;
|
|
200
|
+
}): AnalyticsAdapter;
|
|
201
|
+
/** Today's YYYY-MM-DD on the Copenhagen calendar — the calendar Upmetrics buckets on. */
|
|
202
|
+
declare function copenhagenDay(at?: Date): string;
|
|
203
|
+
/**
|
|
204
|
+
* Exactly `days` entries ending today (Copenhagen calendar), with Upmetrics'
|
|
205
|
+
* values where it sent a day and zeros where it did not — Upmetrics only sends
|
|
206
|
+
* days that had visits. Calendar arithmetic, so a DST change never skips or
|
|
207
|
+
* repeats a day.
|
|
208
|
+
*/
|
|
209
|
+
declare function fillDays(series: AnalyticsDay[], days: number, now?: Date): AnalyticsDay[];
|
|
210
|
+
/** Whole-percent change against the previous period, or null when there is nothing to compare with. */
|
|
211
|
+
declare function changePct(now: number, before: number): number | null;
|
|
212
|
+
interface TenantMembershipRow {
|
|
213
|
+
tenant: {
|
|
214
|
+
id: string;
|
|
215
|
+
slug: string;
|
|
216
|
+
name: string;
|
|
217
|
+
status?: "active" | "suspended";
|
|
218
|
+
};
|
|
219
|
+
role: string;
|
|
220
|
+
}
|
|
221
|
+
interface TenantAdapter {
|
|
222
|
+
load(): Promise<TenantMembershipRow[]>;
|
|
223
|
+
}
|
|
224
|
+
declare class TenantLoadError extends Error {
|
|
225
|
+
readonly status: number;
|
|
226
|
+
constructor(status: number);
|
|
227
|
+
}
|
|
228
|
+
/** GET {url} (default /api/me/memberships) → the user's memberships. Non-2xx or a bad body THROWS. */
|
|
229
|
+
declare function createFetchTenantAdapter(opts?: {
|
|
230
|
+
url?: string;
|
|
231
|
+
fetch?: typeof fetch;
|
|
232
|
+
credentials?: RequestCredentials;
|
|
233
|
+
}): TenantAdapter;
|
|
156
234
|
declare const TEXT: {
|
|
157
235
|
readonly da: {
|
|
158
236
|
readonly openMenu: "Åbn menu";
|
|
@@ -201,6 +279,26 @@ declare const TEXT: {
|
|
|
201
279
|
readonly pictureTooLarge: "Billedet er for stort — højst 2 MB.";
|
|
202
280
|
readonly pictureWrongType: "Vælg et PNG-, JPEG- eller WebP-billede.";
|
|
203
281
|
readonly bidSecurity: "Sikkerhed i Broberg ID";
|
|
282
|
+
readonly analyticsPeriod: "Periode";
|
|
283
|
+
readonly analyticsDays: "{n} dage";
|
|
284
|
+
readonly analyticsVisitors: "Besøgende";
|
|
285
|
+
readonly analyticsPageviews: "Sidevisninger";
|
|
286
|
+
readonly analyticsVsPrev: "{pct} % mod forrige periode";
|
|
287
|
+
readonly analyticsNoPrev: "Ingen sammenligning";
|
|
288
|
+
readonly analyticsOverTime: "Sidevisninger pr. dag";
|
|
289
|
+
readonly analyticsTopPages: "Mest besøgte sider";
|
|
290
|
+
readonly analyticsDay: "Dag";
|
|
291
|
+
readonly analyticsPage: "Side";
|
|
292
|
+
readonly analyticsEmpty: "Ingen besøg i perioden.";
|
|
293
|
+
readonly analyticsLoading: "Henter tal…";
|
|
294
|
+
readonly analyticsUnconfigured: "Analytics er ikke sat op for denne app.";
|
|
295
|
+
readonly analyticsUnavailable: "Upmetrics svarer ikke lige nu. Prøv igen om lidt.";
|
|
296
|
+
readonly tenantSwitch: "Skift organisation";
|
|
297
|
+
readonly tenantLoadFailed: "Kunne ikke hente dine organisationer.";
|
|
298
|
+
readonly tenantSwitchFailed: "Kunne ikke skifte organisation. Du er stadig i {name}.";
|
|
299
|
+
readonly tenantRetry: "Prøv igen";
|
|
300
|
+
readonly tenantSuspended: "lukket";
|
|
301
|
+
readonly tenantActive: "aktiv";
|
|
204
302
|
};
|
|
205
303
|
readonly en: {
|
|
206
304
|
readonly openMenu: "Open menu";
|
|
@@ -249,6 +347,26 @@ declare const TEXT: {
|
|
|
249
347
|
readonly pictureTooLarge: "The picture is too large — 2 MB at most.";
|
|
250
348
|
readonly pictureWrongType: "Choose a PNG, JPEG or WebP image.";
|
|
251
349
|
readonly bidSecurity: "Security in Broberg ID";
|
|
350
|
+
readonly analyticsPeriod: "Period";
|
|
351
|
+
readonly analyticsDays: "{n} days";
|
|
352
|
+
readonly analyticsVisitors: "Visitors";
|
|
353
|
+
readonly analyticsPageviews: "Page views";
|
|
354
|
+
readonly analyticsVsPrev: "{pct}% vs previous period";
|
|
355
|
+
readonly analyticsNoPrev: "No comparison";
|
|
356
|
+
readonly analyticsOverTime: "Page views per day";
|
|
357
|
+
readonly analyticsTopPages: "Most visited pages";
|
|
358
|
+
readonly analyticsDay: "Day";
|
|
359
|
+
readonly analyticsPage: "Page";
|
|
360
|
+
readonly analyticsEmpty: "No visits in this period.";
|
|
361
|
+
readonly analyticsLoading: "Loading figures…";
|
|
362
|
+
readonly analyticsUnconfigured: "Analytics is not set up for this app.";
|
|
363
|
+
readonly analyticsUnavailable: "Upmetrics is not answering right now. Try again shortly.";
|
|
364
|
+
readonly tenantSwitch: "Switch organisation";
|
|
365
|
+
readonly tenantLoadFailed: "Could not load your organisations.";
|
|
366
|
+
readonly tenantSwitchFailed: "Could not switch organisation. You are still in {name}.";
|
|
367
|
+
readonly tenantRetry: "Try again";
|
|
368
|
+
readonly tenantSuspended: "suspended";
|
|
369
|
+
readonly tenantActive: "active";
|
|
252
370
|
};
|
|
253
371
|
};
|
|
254
372
|
type Lang = keyof typeof TEXT;
|
|
@@ -463,5 +581,40 @@ declare function defaultReauthHref(): string;
|
|
|
463
581
|
* typed text, so nothing is lost and the error says why.
|
|
464
582
|
*/
|
|
465
583
|
declare function AccountPage({ lang, adapter, reauthHref, onProfileChange }: AccountPageProps): JSX.Element;
|
|
584
|
+
interface AnalyticsPageProps {
|
|
585
|
+
lang: Lang;
|
|
586
|
+
/** Default: `createFetchAnalyticsAdapter()` → GET /api/analytics?days=N (@upmetrics/sdk/hono analyticsRoutes). */
|
|
587
|
+
adapter?: AnalyticsAdapter;
|
|
588
|
+
/** The period buttons, in days. Default 7 / 30 / 90. */
|
|
589
|
+
periods?: number[];
|
|
590
|
+
/** The period shown first. Default 30 (or the first of `periods` when 30 is not one of them). */
|
|
591
|
+
initialDays?: number;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* The app's own visitors, page views, page views per day and most visited
|
|
595
|
+
* pages, from Upmetrics through the app's backend (F097.1). A backend that is
|
|
596
|
+
* not set up or does not answer says so — it never shows zeros that would read
|
|
597
|
+
* as a quiet month.
|
|
598
|
+
*/
|
|
599
|
+
declare function AnalyticsPage({ lang, adapter, periods, initialDays }: AnalyticsPageProps): JSX.Element;
|
|
600
|
+
interface TenantSwitcherProps {
|
|
601
|
+
lang: Lang;
|
|
602
|
+
/** The slug the app is in right now — the app knows it (from tenantMiddleware). */
|
|
603
|
+
activeSlug: string;
|
|
604
|
+
/** Default: `createFetchTenantAdapter()` → GET /api/me/memberships (@broberg/tenant/hono tenantRoutes). */
|
|
605
|
+
adapter?: TenantAdapter;
|
|
606
|
+
/**
|
|
607
|
+
* Switch through the APP's own route — navigate to `/t/<slug>/…`, or set the
|
|
608
|
+
* preference and reload. A rejection keeps the current organisation and shows
|
|
609
|
+
* why; the switcher never pretends a switch happened.
|
|
610
|
+
*/
|
|
611
|
+
onSwitch: (slug: string) => Promise<void> | void;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* The user's own organisations, the active one marked, and a switch. Only the
|
|
615
|
+
* memberships the backend returns are listed — never a typed or guessed slug.
|
|
616
|
+
* With one organisation it is a plain label, not a menu.
|
|
617
|
+
*/
|
|
618
|
+
declare function TenantSwitcher({ lang, activeSlug, adapter, onSwitch }: TenantSwitcherProps): JSX.Element;
|
|
466
619
|
|
|
467
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, AppShell, type AppShellProps, Avatar, type Lang, type NavGroup, type NavItem, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, badgeLabel, checkAvatarFile, createFetchAccountAdapter, createFetchNotificationSource, createMemoryNotificationSource, defaultReauthHref, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
620
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, type AccountAdapter, AccountError, AccountPage, type AccountPageProps, type AccountProfile, type AnalyticsAdapter, type AnalyticsData, type AnalyticsDay, AnalyticsError, AnalyticsPage, type AnalyticsPageProps, AppShell, type AppShellProps, Avatar, type Lang, type NavGroup, type NavItem, type Navigate, NotificationBell, type NotificationBellProps, type NotificationSource, PageHeader, type PageTab, PageTabs, type PreactNavGroup, type PreactNavItem, type ShellUser, Sidebar, type SidebarProps, TEXT, type TenantAdapter, TenantLoadError, type TenantMembershipRow, TenantSwitcher, type TenantSwitcherProps, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|