1
0
forked from baron/baron-sso

Merge branch 'dev' into feature/issue-917-sub-email-support

This commit is contained in:
2026-05-29 13:23:06 +09:00
186 changed files with 11084 additions and 2370 deletions

View File

@@ -60,10 +60,8 @@ import {
TabsTrigger,
} from "../../components/ui/tabs";
import { toast } from "../../components/ui/use-toast";
import type { PasswordPolicyResponse } from "../../lib/adminApi";
import {
type TenantSummary,
type UserAppointment,
type UserUpdateRequest,
deleteUser,
fetchAllTenants,
fetchMe,
@@ -71,18 +69,20 @@ import {
fetchTenant,
fetchUser,
fetchUserRpHistory,
type TenantSummary,
type UserAppointment,
type UserUpdateRequest,
updateUser,
} from "../../lib/adminApi";
import type { PasswordPolicyResponse } from "../../lib/adminApi";
import { t } from "../../lib/i18n";
import { normalizeAdminRole } from "../../lib/roles";
import { generateSecurePassword } from "../../lib/utils";
import {
type OrgChartTenantSelection,
buildAuthenticatedOrgChartTenantPickerUrl,
filterNonHanmacFamilyTenants,
isHanmacFamilyTenant,
isHanmacFamilyUser,
type OrgChartTenantSelection,
parseOrgChartTenantSelection,
} from "./orgChartPicker";
import type { UserSchemaField } from "./userSchemaFields";
@@ -142,6 +142,8 @@ function createEmptyAppointment(): AppointmentDraft {
tenantSlug: "",
isPrimary: false,
isOwner: false,
isAdmin: false,
isManager: false,
grade: "",
jobTitle: "",
position: "",
@@ -579,8 +581,8 @@ function UserDetailPage() {
if (currentIndex === index) {
return { ...appointment, ...patch };
}
if (patch.isOwner === true) {
return { ...appointment, isOwner: false };
if (patch.isPrimary === true) {
return { ...appointment, isPrimary: false };
}
return appointment;
}),
@@ -701,6 +703,9 @@ function UserDetailPage() {
isPrimary:
appointment.isPrimary === true ||
appointment.tenantId === primaryFromMetadata?.id,
isOwner: appointment.isOwner === true,
isAdmin: appointment.isAdmin === true,
isManager: appointment.isManager === true,
draftId: createDraftId(),
}))
: isUserHanmacFamily
@@ -714,6 +719,8 @@ function UserDetailPage() {
isOwner:
metadata.primaryTenantIsOwner === true &&
tenant.id === fallbackAppointment?.id,
isAdmin: false,
isManager: false,
grade: user.grade,
jobTitle: user.jobTitle,
position: user.position,
@@ -727,6 +734,8 @@ function UserDetailPage() {
tenantSlug: fallbackAppointment.slug,
isPrimary: true,
isOwner: metadata.primaryTenantIsOwner === true,
isAdmin: false,
isManager: false,
grade: user.grade,
jobTitle: user.jobTitle,
position: user.position,
@@ -836,23 +845,23 @@ function UserDetailPage() {
tenantId: appointment.tenantId,
tenantSlug: appointment.tenantSlug,
tenantName: appointment.tenantName,
isPrimary: appointment.isOwner,
isOwner: appointment.isOwner,
isPrimary: appointment.isPrimary === true,
...(appointment.isOwner === true ? { isOwner: true } : {}),
...(appointment.isAdmin === true ? { isAdmin: true } : {}),
...(appointment.isManager === true ? { isManager: true } : {}),
grade: appointment.grade,
jobTitle: appointment.jobTitle,
position: appointment.position,
}));
const primary = appointments.find((a) => a.isOwner);
const primary = appointments.find((a) => a.isPrimary);
if (primary) {
payload.tenantSlug = primary.tenantSlug;
payload.primaryTenantId = primary.tenantId;
payload.primaryTenantName = primary.tenantName;
payload.primaryTenantIsOwner = true;
metadata.primaryTenantId = primary.tenantId;
metadata.primaryTenantSlug = primary.tenantSlug;
metadata.primaryTenantName = primary.tenantName;
metadata.primaryTenantIsOwner = true;
} else {
payload.tenantSlug = undefined;
}
@@ -868,12 +877,10 @@ function UserDetailPage() {
primaryTenantId: primary?.tenantId,
primaryTenantName: primary?.tenantName,
primaryTenantSlug: primary?.tenantSlug,
primaryTenantIsOwner: primary?.isOwner ?? false,
};
payload.tenantSlug = primary?.tenantSlug;
payload.primaryTenantId = primary?.tenantId;
payload.primaryTenantName = primary?.tenantName;
payload.primaryTenantIsOwner = primary?.isOwner ?? false;
}
mutation.mutate(payload);
@@ -1362,13 +1369,13 @@ function UserDetailPage() {
)}
<label className="flex items-center gap-3 text-sm">
<Switch
checked={appointment.isOwner}
checked={appointment.isPrimary === true}
onCheckedChange={(checked) =>
updateAppointment(index, {
isOwner: checked === true,
isPrimary: checked === true,
})
}
disabled={appointment.isPrimary}
disabled={appointment.isPrimary === true}
aria-label={t(
"ui.admin.users.detail.form.appointment_owner",
"대표 조직",
@@ -1379,6 +1386,24 @@ function UserDetailPage() {
"대표 조직",
)}
</label>
<label className="flex items-center gap-3 text-sm">
<Switch
checked={appointment.isManager === true}
onCheckedChange={(checked) =>
updateAppointment(index, {
isManager: checked === true,
})
}
aria-label={t(
"ui.admin.users.detail.form.appointment_manager",
"조직장",
)}
/>
{t(
"ui.admin.users.detail.form.appointment_manager",
"조직장",
)}
</label>
</div>
</div>