feat(admin): show deployed app version
This commit is contained in:
@@ -78,6 +78,8 @@ type MeResponse = {
|
||||
roles?: string[];
|
||||
plan?: "free" | "pro";
|
||||
entitlements?: { ai?: boolean; proThemes?: boolean };
|
||||
appVersion?: string;
|
||||
appCommitSha?: string;
|
||||
};
|
||||
|
||||
function breadcrumbsFor(path: string, t: (k: any) => string): string[] {
|
||||
@@ -348,6 +350,7 @@ function Shell({ jobPageSize, setJobPageSize, jobColumns, setJobColumns, themeMo
|
||||
onToggleDrawer={setMobileDrawerOpen}
|
||||
onNavigate={(to) => { setMobileDrawerOpen(false); navigate(to); }}
|
||||
user={{ email: me?.email, userName: me?.userName, displayName: me?.displayName || fullName || undefined, avatarImageDataUrl: me?.avatarImageDataUrl, roleLabel: isAdmin ? t("superAdmin") : t("user") }}
|
||||
buildMetadata={isAdmin && me?.appVersion ? { version: me.appVersion, commitSha: me.appCommitSha } : undefined}
|
||||
notificationsCount={notificationCount}
|
||||
onOpenNotifications={(anchor) => setNotificationAnchor(anchor)}
|
||||
onOpenSettings={() => navigate("/settings")}
|
||||
|
||||
@@ -36,3 +36,41 @@ test("notification bell exposes its unread count and keyboard-accessible action"
|
||||
expect(open).toHaveBeenCalledTimes(1);
|
||||
expect(open.mock.calls[0][0]).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
test("shows build metadata only when the caller supplies the admin-only badge", () => {
|
||||
const commonProps = {
|
||||
pageTitle: "Dashboard",
|
||||
breadcrumbs: ["Home"],
|
||||
pathname: "/dashboard",
|
||||
nav: [],
|
||||
navBottom: [],
|
||||
onNavigate: () => undefined,
|
||||
onToggleDrawer: () => undefined,
|
||||
drawerOpen: false,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<CssVarsProvider theme={getTheme("light") as any} defaultMode="light">
|
||||
<I18nProvider>
|
||||
<AppShell {...commonProps} buildMetadata={{ version: "2.4.1", commitSha: "abc1234" }}>
|
||||
<div>Content</div>
|
||||
</AppShell>
|
||||
</I18nProvider>
|
||||
</CssVarsProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId("admin-version-badge")).toHaveTextContent("v2.4.1");
|
||||
expect(screen.getByLabelText("Application version 2.4.1, commit abc1234")).toBeInTheDocument();
|
||||
|
||||
rerender(
|
||||
<CssVarsProvider theme={getTheme("light") as any} defaultMode="light">
|
||||
<I18nProvider>
|
||||
<AppShell {...commonProps}>
|
||||
<div>Content</div>
|
||||
</AppShell>
|
||||
</I18nProvider>
|
||||
</CssVarsProvider>,
|
||||
);
|
||||
|
||||
expect(screen.queryByTestId("admin-version-badge")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Badge,
|
||||
Box,
|
||||
Breadcrumbs,
|
||||
Chip,
|
||||
Divider,
|
||||
Drawer,
|
||||
IconButton,
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
Toolbar,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
@@ -82,6 +84,7 @@ export default function AppShell({
|
||||
onToggleDrawer,
|
||||
drawerOpen,
|
||||
user,
|
||||
buildMetadata,
|
||||
notificationsCount,
|
||||
onOpenNotifications,
|
||||
onOpenSettings,
|
||||
@@ -100,6 +103,7 @@ export default function AppShell({
|
||||
onToggleDrawer: (open: boolean) => void;
|
||||
drawerOpen: boolean;
|
||||
user?: { email?: string; userName?: string; displayName?: string; avatarImageDataUrl?: string; roleLabel?: string };
|
||||
buildMetadata?: { version: string; commitSha?: string };
|
||||
notificationsCount?: number;
|
||||
onOpenNotifications?: (anchorEl: HTMLElement) => void;
|
||||
onOpenSettings?: () => void;
|
||||
@@ -234,6 +238,26 @@ export default function AppShell({
|
||||
|
||||
const nameForAvatar = user?.userName || user?.displayName || user?.email;
|
||||
const initials = initialsFrom(nameForAvatar);
|
||||
const buildVersion = buildMetadata?.version.trim();
|
||||
const buildCommit = buildMetadata?.commitSha?.trim();
|
||||
const buildBadge = buildVersion ? (
|
||||
<Tooltip title={buildCommit ? `Version ${buildVersion} • commit ${buildCommit}` : `Version ${buildVersion}`}>
|
||||
<Chip
|
||||
data-testid="admin-version-badge"
|
||||
aria-label={`Application version ${buildVersion}${buildCommit ? `, commit ${buildCommit}` : ""}`}
|
||||
label={`v${buildVersion}`}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
sx={{
|
||||
maxWidth: 150,
|
||||
fontWeight: 700,
|
||||
fontVariantNumeric: "tabular-nums",
|
||||
bgcolor: "background.paper",
|
||||
"& .MuiChip-label": { overflow: "hidden", textOverflow: "ellipsis" },
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null;
|
||||
|
||||
const [userMenuAnchor, setUserMenuAnchor] = useState<null | HTMLElement>(null);
|
||||
const userMenuOpen = Boolean(userMenuAnchor);
|
||||
@@ -281,6 +305,7 @@ export default function AppShell({
|
||||
Jobbjakt
|
||||
</Typography>
|
||||
</Box>
|
||||
{buildBadge}
|
||||
</Box>
|
||||
|
||||
{user ? (
|
||||
@@ -358,6 +383,7 @@ export default function AppShell({
|
||||
flex: { xs: "1 1 100%", md: "0 1 auto" },
|
||||
}}
|
||||
>
|
||||
{buildBadge}
|
||||
<IconButton
|
||||
color="secondary"
|
||||
size="small"
|
||||
|
||||
Reference in New Issue
Block a user