1
0
forked from baron/baron-sso

style: apply backend go fmt and frontend biome auto-fixes

This commit is contained in:
2026-03-27 17:52:39 +09:00
parent 2383c6a6be
commit 5ae0e19e31
6 changed files with 142 additions and 61 deletions

View File

@@ -83,16 +83,27 @@ export function TenantAdminsAndOwnersTab() {
const addOwnerMutation = useMutation({
mutationFn: (userId: string) => addTenantOwner(tenantId, userId),
onMutate: async (userId) => {
await queryClient.cancelQueries({ queryKey: ["tenant-owners", tenantId] });
const previousOwners = queryClient.getQueryData<any[]>(["tenant-owners", tenantId]);
await queryClient.cancelQueries({
queryKey: ["tenant-owners", tenantId],
});
const previousOwners = queryClient.getQueryData<any[]>([
"tenant-owners",
tenantId,
]);
// Optimistically add to the list to prevent immediate double clicks
const addedUser = searchResults.find(u => u.id === userId);
const addedUser = searchResults.find((u) => u.id === userId);
if (addedUser) {
queryClient.setQueryData<any[]>(["tenant-owners", tenantId], old => {
if (!old) return [{ id: userId, name: addedUser.name, email: addedUser.email }];
if (old.some(o => o.id === userId)) return old;
return [...old, { id: userId, name: addedUser.name, email: addedUser.email }];
queryClient.setQueryData<any[]>(["tenant-owners", tenantId], (old) => {
if (!old)
return [
{ id: userId, name: addedUser.name, email: addedUser.email },
];
if (old.some((o) => o.id === userId)) return old;
return [
...old,
{ id: userId, name: addedUser.name, email: addedUser.email },
];
});
}
return { previousOwners };
@@ -100,7 +111,9 @@ export function TenantAdminsAndOwnersTab() {
onSuccess: () => {
// Delay invalidation slightly to give the backend outbox time to process
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ["tenant-owners", tenantId] });
queryClient.invalidateQueries({
queryKey: ["tenant-owners", tenantId],
});
}, 1000);
toast.success(
t("msg.admin.tenants.owners.add_success", "소유자가 추가되었습니다."),
@@ -109,7 +122,10 @@ export function TenantAdminsAndOwnersTab() {
},
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
if (context?.previousOwners) {
queryClient.setQueryData(["tenant-owners", tenantId], context.previousOwners);
queryClient.setQueryData(
["tenant-owners", tenantId],
context.previousOwners,
);
}
toast.error(
err.response?.data?.error ||
@@ -121,16 +137,23 @@ export function TenantAdminsAndOwnersTab() {
const removeOwnerMutation = useMutation({
mutationFn: (userId: string) => removeTenantOwner(tenantId, userId),
onMutate: async (userId) => {
await queryClient.cancelQueries({ queryKey: ["tenant-owners", tenantId] });
const previousOwners = queryClient.getQueryData<any[]>(["tenant-owners", tenantId]);
queryClient.setQueryData<any[]>(["tenant-owners", tenantId], old =>
old ? old.filter(o => o.id !== userId) : []
await queryClient.cancelQueries({
queryKey: ["tenant-owners", tenantId],
});
const previousOwners = queryClient.getQueryData<any[]>([
"tenant-owners",
tenantId,
]);
queryClient.setQueryData<any[]>(["tenant-owners", tenantId], (old) =>
old ? old.filter((o) => o.id !== userId) : [],
);
return { previousOwners };
},
onSuccess: () => {
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ["tenant-owners", tenantId] });
queryClient.invalidateQueries({
queryKey: ["tenant-owners", tenantId],
});
}, 1000);
toast.success(
t(
@@ -141,7 +164,10 @@ export function TenantAdminsAndOwnersTab() {
},
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
if (context?.previousOwners) {
queryClient.setQueryData(["tenant-owners", tenantId], context.previousOwners);
queryClient.setQueryData(
["tenant-owners", tenantId],
context.previousOwners,
);
}
toast.error(
err.response?.data?.error ||
@@ -153,22 +179,35 @@ export function TenantAdminsAndOwnersTab() {
const addAdminMutation = useMutation({
mutationFn: (userId: string) => addTenantAdmin(tenantId, userId),
onMutate: async (userId) => {
await queryClient.cancelQueries({ queryKey: ["tenant-admins", tenantId] });
const previousAdmins = queryClient.getQueryData<any[]>(["tenant-admins", tenantId]);
const addedUser = searchResults.find(u => u.id === userId);
await queryClient.cancelQueries({
queryKey: ["tenant-admins", tenantId],
});
const previousAdmins = queryClient.getQueryData<any[]>([
"tenant-admins",
tenantId,
]);
const addedUser = searchResults.find((u) => u.id === userId);
if (addedUser) {
queryClient.setQueryData<any[]>(["tenant-admins", tenantId], old => {
if (!old) return [{ id: userId, name: addedUser.name, email: addedUser.email }];
if (old.some(a => a.id === userId)) return old;
return [...old, { id: userId, name: addedUser.name, email: addedUser.email }];
queryClient.setQueryData<any[]>(["tenant-admins", tenantId], (old) => {
if (!old)
return [
{ id: userId, name: addedUser.name, email: addedUser.email },
];
if (old.some((a) => a.id === userId)) return old;
return [
...old,
{ id: userId, name: addedUser.name, email: addedUser.email },
];
});
}
return { previousAdmins };
},
onSuccess: () => {
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ["tenant-admins", tenantId] });
queryClient.invalidateQueries({
queryKey: ["tenant-admins", tenantId],
});
}, 1000);
toast.success(
t("msg.admin.tenants.admins.add_success", "관리자가 추가되었습니다."),
@@ -177,7 +216,10 @@ export function TenantAdminsAndOwnersTab() {
},
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
if (context?.previousAdmins) {
queryClient.setQueryData(["tenant-admins", tenantId], context.previousAdmins);
queryClient.setQueryData(
["tenant-admins", tenantId],
context.previousAdmins,
);
}
toast.error(
err.response?.data?.error ||
@@ -189,16 +231,23 @@ export function TenantAdminsAndOwnersTab() {
const removeAdminMutation = useMutation({
mutationFn: (userId: string) => removeTenantAdmin(tenantId, userId),
onMutate: async (userId) => {
await queryClient.cancelQueries({ queryKey: ["tenant-admins", tenantId] });
const previousAdmins = queryClient.getQueryData<any[]>(["tenant-admins", tenantId]);
queryClient.setQueryData<any[]>(["tenant-admins", tenantId], old =>
old ? old.filter(a => a.id !== userId) : []
await queryClient.cancelQueries({
queryKey: ["tenant-admins", tenantId],
});
const previousAdmins = queryClient.getQueryData<any[]>([
"tenant-admins",
tenantId,
]);
queryClient.setQueryData<any[]>(["tenant-admins", tenantId], (old) =>
old ? old.filter((a) => a.id !== userId) : [],
);
return { previousAdmins };
},
onSuccess: () => {
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ["tenant-admins", tenantId] });
queryClient.invalidateQueries({
queryKey: ["tenant-admins", tenantId],
});
}, 1000);
toast.success(
t("msg.admin.tenants.admins.remove_success", "권한이 회수되었습니다."),
@@ -206,7 +255,10 @@ export function TenantAdminsAndOwnersTab() {
},
onError: (err: AxiosError<{ error?: string }>, userId, context) => {
if (context?.previousAdmins) {
queryClient.setQueryData(["tenant-admins", tenantId], context.previousAdmins);
queryClient.setQueryData(
["tenant-admins", tenantId],
context.previousAdmins,
);
}
toast.error(
err.response?.data?.error ||

View File

@@ -161,7 +161,9 @@ function UserDetailPage() {
const [error, setError] = React.useState<string | null>(null);
const [successMsg, setSuccessMsg] = React.useState<string | null>(null);
const [isPasswordResetOpen, setIsPasswordResetOpen] = React.useState(false);
const [generatedPassword, setGeneratedPassword] = React.useState<string | null>(null);
const [generatedPassword, setGeneratedPassword] = React.useState<
string | null
>(null);
const { data: profile } = useQuery({
queryKey: ["me"],
@@ -470,7 +472,8 @@ function UserDetailPage() {
</div>
)}
<p className="text-[10px] text-muted-foreground">
* .
*
.
</p>
</div>
@@ -571,7 +574,10 @@ function UserDetailPage() {
{...register("role")}
>
<option value="user">
{t("ui.admin.users.detail.form.role_user", "일반 사용자")}
{t(
"ui.admin.users.detail.form.role_user",
"일반 사용자",
)}
</option>
<option value="tenant_admin">
{t(
@@ -601,7 +607,10 @@ function UserDetailPage() {
{t("ui.admin.users.detail.form.status_active", "활성")}
</option>
<option value="inactive">
{t("ui.admin.users.detail.form.status_inactive", "비활성")}
{t(
"ui.admin.users.detail.form.status_inactive",
"비활성",
)}
</option>
</select>
</div>
@@ -661,7 +670,9 @@ function UserDetailPage() {
</div>
<div className="grid gap-4">
{userAffiliatedTenants.map((t) => {
const tDetail = tenants.find((tenant) => tenant.id === t.id);
const tDetail = tenants.find(
(tenant) => tenant.id === t.id,
);
const schema = (tDetail?.config?.userSchema ||
[]) as UserSchemaField[];
return (
@@ -707,7 +718,8 @@ function UserDetailPage() {
)}
</p>
<p className="text-xs text-muted-foreground">
.
.
</p>
</div>
<Button variant="outline" onClick={handleGeneratePassword}>
@@ -725,12 +737,26 @@ function UserDetailPage() {
)}
</p>
<div className="flex justify-end gap-2">
<Button variant="ghost" size="sm" onClick={() => setIsPasswordResetOpen(false)}>
<Button
variant="ghost"
size="sm"
onClick={() => setIsPasswordResetOpen(false)}
>
{t("ui.common.cancel", "취소")}
</Button>
<Button variant="destructive" size="sm" onClick={confirmGeneratePassword} disabled={resetPasswordMutation.isPending}>
{resetPasswordMutation.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{t("ui.admin.users.detail.reset_password", "초기화 및 생성")}
<Button
variant="destructive"
size="sm"
onClick={confirmGeneratePassword}
disabled={resetPasswordMutation.isPending}
>
{resetPasswordMutation.isPending && (
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
)}
{t(
"ui.admin.users.detail.reset_password",
"초기화 및 생성",
)}
</Button>
</div>
</div>
@@ -746,7 +772,11 @@ function UserDetailPage() {
{generatedPassword}
</p>
</div>
<Button size="sm" variant="secondary" onClick={handleCopyPassword}>
<Button
size="sm"
variant="secondary"
onClick={handleCopyPassword}
>
<Copy className="mr-2 h-4 w-4" />
{t("ui.common.copy", "복사")}
</Button>
@@ -770,7 +800,11 @@ function UserDetailPage() {
</div>
<div>
<div className="flex items-center gap-2">
<Badge variant={user.status === "active" ? "default" : "secondary"}>
<Badge
variant={
user.status === "active" ? "default" : "secondary"
}
>
{user.status === "active" ? "Active" : "Inactive"}
</Badge>
<Badge variant="outline">{user.role}</Badge>