1
0
forked from baron/baron-sso
This commit is contained in:
2026-05-20 17:59:37 +09:00
106 changed files with 7401 additions and 1122 deletions

View File

@@ -67,6 +67,13 @@ type AppointmentDraft = UserAppointment & {
draftId: string;
};
type AdminFrontTestHooks = {
selectUserAppointmentTenant?: (
selection: OrgChartTenantSelection,
index?: number,
) => Promise<void>;
};
function createDraftId() {
return globalThis.crypto?.randomUUID?.() ?? `appointment-${Date.now()}`;
}
@@ -276,6 +283,21 @@ function UserCreatePage() {
return () => window.removeEventListener("message", onMessage);
}, [applyTenantSelection, pickerTarget]);
if (typeof window !== "undefined") {
const testWindow = window as Window &
typeof globalThis & {
__adminfrontTestHooks?: AdminFrontTestHooks;
};
const hooks = testWindow.__adminfrontTestHooks ?? {};
hooks.selectUserAppointmentTenant = async (selection, index = 0) => {
await applyTenantSelection(selection, {
kind: "appointment",
index,
});
};
testWindow.__adminfrontTestHooks = hooks;
}
const addAppointment = () => {
setAdditionalAppointments((current) => [
...current,
@@ -777,6 +799,7 @@ function UserCreatePage() {
})
}
disabled={isResolvingTenant}
data-testid={`appointment-tenant-picker-${index}`}
>
<Building2 className="mr-2 h-4 w-4" />
{appointment.tenantName || "테넌트 선택"}
@@ -988,6 +1011,7 @@ function UserCreatePage() {
title={t("ui.admin.users.create.form.pick_tenant", "테넌트 선택")}
src={pickerUrl}
className="h-[600px] w-full rounded-md border"
data-testid="appointment-tenant-picker-frame"
/>
</DialogContent>
</Dialog>

View File

@@ -7,10 +7,10 @@ import {
ChevronDown,
ChevronLeft,
ChevronRight,
Users,
Download,
FileDown,
FileSpreadsheet,
LayoutDashboard,
Plus,
RefreshCw,
Search,
@@ -423,6 +423,7 @@ function UserListPage() {
<PageHeader
sticky
titleAs="h2"
icon={<Users size={20} />}
title={
<span data-testid="page-title">
{t("ui.admin.users.list.title", "사용자 관리")}
@@ -622,7 +623,7 @@ function UserListPage() {
<Card className="flex-1 flex flex-col min-h-0 bg-[var(--color-panel)] overflow-hidden">
<CardHeader className="flex flex-row items-center justify-between flex-shrink-0">
<div>
<CardTitle>
<CardTitle className="text-lg font-bold flex items-center gap-2">
{t("ui.admin.users.list.registry.title", "User Registry")}
</CardTitle>
<CardDescription>

View File

@@ -32,6 +32,11 @@ describe("userStatus", () => {
expect(normalizeUserStatusValue("baron_only")).toBe("baron_guest");
});
it("falls back to preboarding when status is missing", () => {
expect(normalizeUserStatusValue(undefined)).toBe("preboarding");
expect(normalizeUserStatusValue(null)).toBe("preboarding");
});
it("uses canonical labels for legacy status values", () => {
expect(userStatusLabel("baron_only")).toBe("baron_guest");
});

View File

@@ -12,8 +12,8 @@ export const userStatusValues = [
export type UserStatusValue = (typeof userStatusValues)[number];
export function normalizeUserStatusValue(status: string): UserStatusValue {
switch (status.trim().toLowerCase()) {
export function normalizeUserStatusValue(status?: string | null): UserStatusValue {
switch ((status ?? "").trim().toLowerCase()) {
case "active":
return "active";
case "temporary_leave":