@broberg/app-shell 0.6.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 +20 -0
- package/css/app-shell.css +18 -0
- package/dist/index.cjs +42 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +41 -3
- package/dist/index.js.map +1 -1
- package/dist/preact.cjs +132 -2
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.cts +54 -1
- package/dist/preact.d.ts +54 -1
- package/dist/preact.js +130 -3
- package/dist/preact.js.map +1 -1
- package/package.json +3 -1
package/dist/preact.d.cts
CHANGED
|
@@ -209,6 +209,28 @@ declare function copenhagenDay(at?: Date): string;
|
|
|
209
209
|
declare function fillDays(series: AnalyticsDay[], days: number, now?: Date): AnalyticsDay[];
|
|
210
210
|
/** Whole-percent change against the previous period, or null when there is nothing to compare with. */
|
|
211
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;
|
|
212
234
|
declare const TEXT: {
|
|
213
235
|
readonly da: {
|
|
214
236
|
readonly openMenu: "Åbn menu";
|
|
@@ -271,6 +293,12 @@ declare const TEXT: {
|
|
|
271
293
|
readonly analyticsLoading: "Henter tal…";
|
|
272
294
|
readonly analyticsUnconfigured: "Analytics er ikke sat op for denne app.";
|
|
273
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";
|
|
274
302
|
};
|
|
275
303
|
readonly en: {
|
|
276
304
|
readonly openMenu: "Open menu";
|
|
@@ -333,6 +361,12 @@ declare const TEXT: {
|
|
|
333
361
|
readonly analyticsLoading: "Loading figures…";
|
|
334
362
|
readonly analyticsUnconfigured: "Analytics is not set up for this app.";
|
|
335
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";
|
|
336
370
|
};
|
|
337
371
|
};
|
|
338
372
|
type Lang = keyof typeof TEXT;
|
|
@@ -563,5 +597,24 @@ interface AnalyticsPageProps {
|
|
|
563
597
|
* as a quiet month.
|
|
564
598
|
*/
|
|
565
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;
|
|
566
619
|
|
|
567
|
-
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, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createMemoryNotificationSource, defaultReauthHref, fillDays, 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
|
@@ -209,6 +209,28 @@ declare function copenhagenDay(at?: Date): string;
|
|
|
209
209
|
declare function fillDays(series: AnalyticsDay[], days: number, now?: Date): AnalyticsDay[];
|
|
210
210
|
/** Whole-percent change against the previous period, or null when there is nothing to compare with. */
|
|
211
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;
|
|
212
234
|
declare const TEXT: {
|
|
213
235
|
readonly da: {
|
|
214
236
|
readonly openMenu: "Åbn menu";
|
|
@@ -271,6 +293,12 @@ declare const TEXT: {
|
|
|
271
293
|
readonly analyticsLoading: "Henter tal…";
|
|
272
294
|
readonly analyticsUnconfigured: "Analytics er ikke sat op for denne app.";
|
|
273
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";
|
|
274
302
|
};
|
|
275
303
|
readonly en: {
|
|
276
304
|
readonly openMenu: "Open menu";
|
|
@@ -333,6 +361,12 @@ declare const TEXT: {
|
|
|
333
361
|
readonly analyticsLoading: "Loading figures…";
|
|
334
362
|
readonly analyticsUnconfigured: "Analytics is not set up for this app.";
|
|
335
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";
|
|
336
370
|
};
|
|
337
371
|
};
|
|
338
372
|
type Lang = keyof typeof TEXT;
|
|
@@ -563,5 +597,24 @@ interface AnalyticsPageProps {
|
|
|
563
597
|
* as a quiet month.
|
|
564
598
|
*/
|
|
565
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;
|
|
566
619
|
|
|
567
|
-
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, TopBar, type TopBarProps, UserMenu, type UserMenuItem, type UserMenuProps, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createMemoryNotificationSource, defaultReauthHref, fillDays, 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.js
CHANGED
|
@@ -272,6 +272,32 @@ function fillDays(series, days, now = /* @__PURE__ */ new Date()) {
|
|
|
272
272
|
function changePct(now, before) {
|
|
273
273
|
return before === 0 ? null : Math.round((now - before) / before * 100);
|
|
274
274
|
}
|
|
275
|
+
var TenantLoadError = class extends Error {
|
|
276
|
+
constructor(status) {
|
|
277
|
+
super(`HTTP ${status}`);
|
|
278
|
+
this.status = status;
|
|
279
|
+
this.name = "TenantLoadError";
|
|
280
|
+
}
|
|
281
|
+
status;
|
|
282
|
+
};
|
|
283
|
+
function createFetchTenantAdapter(opts = {}) {
|
|
284
|
+
return {
|
|
285
|
+
async load() {
|
|
286
|
+
let res;
|
|
287
|
+
try {
|
|
288
|
+
res = await (opts.fetch ?? fetch)(opts.url ?? "/api/me/memberships", { credentials: opts.credentials ?? "same-origin", headers: { accept: "application/json" } });
|
|
289
|
+
} catch {
|
|
290
|
+
throw new TenantLoadError(0);
|
|
291
|
+
}
|
|
292
|
+
const body = await res.json().catch(() => null);
|
|
293
|
+
if (!res.ok) throw new TenantLoadError(res.status);
|
|
294
|
+
if (!Array.isArray(body) || !body.every((r) => r && typeof r.role === "string" && r.tenant && typeof r.tenant.slug === "string")) {
|
|
295
|
+
throw new TenantLoadError(res.status);
|
|
296
|
+
}
|
|
297
|
+
return body;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
275
301
|
var TEXT = {
|
|
276
302
|
da: {
|
|
277
303
|
openMenu: "\xC5bn menu",
|
|
@@ -333,7 +359,13 @@ var TEXT = {
|
|
|
333
359
|
analyticsEmpty: "Ingen bes\xF8g i perioden.",
|
|
334
360
|
analyticsLoading: "Henter tal\u2026",
|
|
335
361
|
analyticsUnconfigured: "Analytics er ikke sat op for denne app.",
|
|
336
|
-
analyticsUnavailable: "Upmetrics svarer ikke lige nu. Pr\xF8v igen om lidt."
|
|
362
|
+
analyticsUnavailable: "Upmetrics svarer ikke lige nu. Pr\xF8v igen om lidt.",
|
|
363
|
+
tenantSwitch: "Skift organisation",
|
|
364
|
+
tenantLoadFailed: "Kunne ikke hente dine organisationer.",
|
|
365
|
+
tenantSwitchFailed: "Kunne ikke skifte organisation. Du er stadig i {name}.",
|
|
366
|
+
tenantRetry: "Pr\xF8v igen",
|
|
367
|
+
tenantSuspended: "lukket",
|
|
368
|
+
tenantActive: "aktiv"
|
|
337
369
|
},
|
|
338
370
|
en: {
|
|
339
371
|
openMenu: "Open menu",
|
|
@@ -395,7 +427,13 @@ var TEXT = {
|
|
|
395
427
|
analyticsEmpty: "No visits in this period.",
|
|
396
428
|
analyticsLoading: "Loading figures\u2026",
|
|
397
429
|
analyticsUnconfigured: "Analytics is not set up for this app.",
|
|
398
|
-
analyticsUnavailable: "Upmetrics is not answering right now. Try again shortly."
|
|
430
|
+
analyticsUnavailable: "Upmetrics is not answering right now. Try again shortly.",
|
|
431
|
+
tenantSwitch: "Switch organisation",
|
|
432
|
+
tenantLoadFailed: "Could not load your organisations.",
|
|
433
|
+
tenantSwitchFailed: "Could not switch organisation. You are still in {name}.",
|
|
434
|
+
tenantRetry: "Try again",
|
|
435
|
+
tenantSuspended: "suspended",
|
|
436
|
+
tenantActive: "active"
|
|
399
437
|
}
|
|
400
438
|
};
|
|
401
439
|
var MOBILE_QUERY = "(max-width: 767px)";
|
|
@@ -1312,7 +1350,96 @@ function AnalyticsSeries({ data, t, locale, num }) {
|
|
|
1312
1350
|
] })
|
|
1313
1351
|
] });
|
|
1314
1352
|
}
|
|
1353
|
+
function TenantSwitcher({ lang, activeSlug, adapter, onSwitch }) {
|
|
1354
|
+
const t = TEXT[lang];
|
|
1355
|
+
const api = useMemo(() => adapter ?? createFetchTenantAdapter(), [adapter]);
|
|
1356
|
+
const [rows, setRows] = useState(null);
|
|
1357
|
+
const [loadFailed, setLoadFailed] = useState(false);
|
|
1358
|
+
const [open, setOpen] = useState(false);
|
|
1359
|
+
const [busy, setBusy] = useState(null);
|
|
1360
|
+
const [switchFailed, setSwitchFailed] = useState(false);
|
|
1361
|
+
const root = useRef(null);
|
|
1362
|
+
const load = () => {
|
|
1363
|
+
setLoadFailed(false);
|
|
1364
|
+
api.load().then(setRows, () => setLoadFailed(true));
|
|
1365
|
+
};
|
|
1366
|
+
useEffect(load, [api]);
|
|
1367
|
+
useEffect(() => {
|
|
1368
|
+
if (!open) return;
|
|
1369
|
+
const onDown = (e) => {
|
|
1370
|
+
if (root.current && !root.current.contains(e.target)) setOpen(false);
|
|
1371
|
+
};
|
|
1372
|
+
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
|
1373
|
+
document.addEventListener("mousedown", onDown);
|
|
1374
|
+
document.addEventListener("keydown", onKey);
|
|
1375
|
+
return () => {
|
|
1376
|
+
document.removeEventListener("mousedown", onDown);
|
|
1377
|
+
document.removeEventListener("keydown", onKey);
|
|
1378
|
+
};
|
|
1379
|
+
}, [open]);
|
|
1380
|
+
const active = rows?.find((r) => r.tenant.slug === activeSlug);
|
|
1381
|
+
const label = active?.tenant.name ?? activeSlug;
|
|
1382
|
+
const pick = async (slug) => {
|
|
1383
|
+
if (slug === activeSlug || busy) return;
|
|
1384
|
+
setBusy(slug);
|
|
1385
|
+
setSwitchFailed(false);
|
|
1386
|
+
try {
|
|
1387
|
+
await onSwitch(slug);
|
|
1388
|
+
setOpen(false);
|
|
1389
|
+
} catch {
|
|
1390
|
+
setSwitchFailed(true);
|
|
1391
|
+
} finally {
|
|
1392
|
+
setBusy(null);
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
if (rows && rows.length <= 1 && !loadFailed) {
|
|
1396
|
+
return /* @__PURE__ */ jsx("div", { class: "bas-tenant", "data-testid": "tenant-switcher", children: /* @__PURE__ */ jsx("span", { class: "bas-tenant__label", "data-testid": "tenant-switcher-label", children: label }) });
|
|
1397
|
+
}
|
|
1398
|
+
return /* @__PURE__ */ jsxs("div", { class: "bas-tenant", ref: root, "data-testid": "tenant-switcher", children: [
|
|
1399
|
+
/* @__PURE__ */ jsx(
|
|
1400
|
+
"button",
|
|
1401
|
+
{
|
|
1402
|
+
type: "button",
|
|
1403
|
+
class: "bas-tenant__btn" + (open ? " is-open" : ""),
|
|
1404
|
+
"aria-haspopup": "menu",
|
|
1405
|
+
"aria-expanded": open,
|
|
1406
|
+
"aria-label": t.tenantSwitch,
|
|
1407
|
+
onClick: () => setOpen((v) => !v),
|
|
1408
|
+
"data-testid": "tenant-switcher-button",
|
|
1409
|
+
children: /* @__PURE__ */ jsx("span", { class: "bas-tenant__label", "data-testid": "tenant-switcher-label", children: label })
|
|
1410
|
+
}
|
|
1411
|
+
),
|
|
1412
|
+
open ? /* @__PURE__ */ jsxs("div", { class: "bas-menu bas-tenant__menu", role: "menu", "data-testid": "tenant-switcher-menu", children: [
|
|
1413
|
+
loadFailed ? /* @__PURE__ */ jsxs("div", { class: "bas-tenant__note", role: "alert", "data-testid": "tenant-switcher-load-error", children: [
|
|
1414
|
+
/* @__PURE__ */ jsx("span", { children: t.tenantLoadFailed }),
|
|
1415
|
+
/* @__PURE__ */ jsx("button", { type: "button", class: "bas-mi", onClick: load, "data-testid": "tenant-switcher-retry", children: t.tenantRetry })
|
|
1416
|
+
] }) : null,
|
|
1417
|
+
switchFailed ? /* @__PURE__ */ jsx("p", { class: "bas-tenant__note is-error", role: "alert", "data-testid": "tenant-switcher-switch-error", children: t.tenantSwitchFailed.replace("{name}", label) }) : null,
|
|
1418
|
+
(rows ?? []).map((r) => {
|
|
1419
|
+
const isActive = r.tenant.slug === activeSlug;
|
|
1420
|
+
const suspended = r.tenant.status === "suspended";
|
|
1421
|
+
return /* @__PURE__ */ jsxs(
|
|
1422
|
+
"button",
|
|
1423
|
+
{
|
|
1424
|
+
type: "button",
|
|
1425
|
+
role: "menuitemradio",
|
|
1426
|
+
"aria-checked": isActive,
|
|
1427
|
+
class: "bas-mi bas-tenant__item" + (isActive ? " is-active" : ""),
|
|
1428
|
+
disabled: suspended || busy !== null,
|
|
1429
|
+
onClick: () => void pick(r.tenant.slug),
|
|
1430
|
+
"data-testid": `tenant-switcher-item-${r.tenant.slug}`,
|
|
1431
|
+
children: [
|
|
1432
|
+
/* @__PURE__ */ jsx("span", { class: "bas-tenant__name", children: r.tenant.name }),
|
|
1433
|
+
/* @__PURE__ */ jsx("span", { class: "bas-tenant__role", children: suspended ? t.tenantSuspended : isActive ? t.tenantActive : r.role })
|
|
1434
|
+
]
|
|
1435
|
+
},
|
|
1436
|
+
r.tenant.id
|
|
1437
|
+
);
|
|
1438
|
+
})
|
|
1439
|
+
] }) : null
|
|
1440
|
+
] });
|
|
1441
|
+
}
|
|
1315
1442
|
|
|
1316
|
-
export { AVATAR_MAX_BYTES, AVATAR_TYPES, AccountError, AccountPage, AnalyticsError, AnalyticsPage, AppShell, Avatar, NotificationBell, PageHeader, PageTabs, Sidebar, TEXT, TopBar, UserMenu, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
1443
|
+
export { AVATAR_MAX_BYTES, AVATAR_TYPES, AccountError, AccountPage, AnalyticsError, AnalyticsPage, AppShell, Avatar, NotificationBell, PageHeader, PageTabs, Sidebar, TEXT, TenantLoadError, TenantSwitcher, TopBar, UserMenu, accountErrorKind, activeNavLabel, analyticsErrorKind, badgeLabel, changePct, checkAvatarFile, copenhagenDay, createFetchAccountAdapter, createFetchAnalyticsAdapter, createFetchNotificationSource, createFetchTenantAdapter, createMemoryNotificationSource, defaultReauthHref, fillDays, initials, isActivePath, isExternal, readFlag, readSet, relativeTime, safeNavigate, useIsMobile, writeFlag, writeSet };
|
|
1317
1444
|
//# sourceMappingURL=preact.js.map
|
|
1318
1445
|
//# sourceMappingURL=preact.js.map
|