1
0
forked from baron/baron-sso

ci: enforce flutter/biome format checks and fix front lint violations

This commit is contained in:
Lectom C Han
2026-02-20 10:25:45 +09:00
parent 226a236bf2
commit c117e10f48
31 changed files with 472 additions and 709 deletions

View File

@@ -19,7 +19,11 @@ import {
TableHeader,
TableRow,
} from "../../../components/ui/table";
import { fetchGroups, fetchTenants } from "../../../lib/adminApi";
import {
fetchGroups,
fetchTenants,
type TenantSummary,
} from "../../../lib/adminApi";
export default function GlobalUserGroupListPage() {
const { data: tenantList, isLoading: isTenantsLoading } = useQuery({
@@ -51,7 +55,7 @@ export default function GlobalUserGroupListPage() {
);
}
function TenantGroupCard({ tenant }: { tenant: any }) {
function TenantGroupCard({ tenant }: { tenant: TenantSummary }) {
const { data: groups, isLoading } = useQuery({
queryKey: ["tenant-user-groups", tenant.id],
queryFn: () => fetchGroups(tenant.id),

View File

@@ -31,6 +31,21 @@ import {
} from "../../../components/ui/table";
import { createGroup, deleteGroup, fetchGroups } from "../../../lib/adminApi";
function getErrorMessage(error: unknown, fallback: string): string {
if (error instanceof Error && error.message) {
return error.message;
}
if (
typeof error === "object" &&
error !== null &&
"message" in error &&
typeof (error as { message?: unknown }).message === "string"
) {
return (error as { message: string }).message;
}
return fallback;
}
export function TenantUserGroupsTab() {
const { tenantId } = useParams<{ tenantId: string }>();
const queryClient = useQueryClient();
@@ -40,13 +55,25 @@ export function TenantUserGroupsTab() {
const { data: groups, isLoading } = useQuery({
queryKey: ["tenant-user-groups", tenantId],
queryFn: () => fetchGroups(tenantId!),
queryFn: () => {
if (!tenantId) {
throw new Error("tenantId is required");
}
return fetchGroups(tenantId);
},
enabled: !!tenantId,
});
const createMutation = useMutation({
mutationFn: () =>
createGroup(tenantId!, { name: newGroupName, description: newGroupDesc }),
mutationFn: () => {
if (!tenantId) {
throw new Error("tenantId is required");
}
return createGroup(tenantId, {
name: newGroupName,
description: newGroupDesc,
});
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["tenant-user-groups", tenantId],
@@ -56,13 +83,18 @@ export function TenantUserGroupsTab() {
setNewGroupDesc("");
alert("User group created successfully");
},
onError: (error: any) => {
alert(error.message || "Failed to create user group");
onError: (error: unknown) => {
alert(getErrorMessage(error, "Failed to create user group"));
},
});
const deleteMutation = useMutation({
mutationFn: (groupId: string) => deleteGroup(tenantId!, groupId),
mutationFn: (groupId: string) => {
if (!tenantId) {
throw new Error("tenantId is required");
}
return deleteGroup(tenantId, groupId);
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["tenant-user-groups", tenantId],

View File

@@ -48,6 +48,28 @@ import {
removeGroupRole,
} from "../../../lib/adminApi";
function getErrorMessage(error: unknown, fallback: string): string {
if (typeof error === "object" && error !== null) {
const response = (error as { response?: { data?: { error?: unknown } } })
.response;
const responseError = response?.data?.error;
if (typeof responseError === "string" && responseError.length > 0) {
return responseError;
}
const message = (error as { message?: unknown }).message;
if (typeof message === "string" && message.length > 0) {
return message;
}
}
if (error instanceof Error && error.message) {
return error.message;
}
return fallback;
}
export function UserGroupDetailPage() {
const { tenantId, id } = useParams<{ tenantId: string; id: string }>();
const queryClient = useQueryClient();
@@ -67,7 +89,12 @@ export function UserGroupDetailPage() {
error,
} = useQuery({
queryKey: ["user-group-detail", id],
queryFn: () => fetchGroup(tenantId!, id!),
queryFn: () => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return fetchGroup(tenantId, id);
},
enabled: !!id && !!tenantId,
retry: false,
});
@@ -75,7 +102,12 @@ export function UserGroupDetailPage() {
// Fetch assigned roles
const { data: groupRoles, isLoading: isRolesLoading } = useQuery({
queryKey: ["user-group-roles", id],
queryFn: () => fetchGroupRoles(tenantId!, id!),
queryFn: () => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return fetchGroupRoles(tenantId, id);
},
enabled: !!id && !!tenantId,
});
@@ -94,20 +126,30 @@ export function UserGroupDetailPage() {
});
const addMemberMutation = useMutation({
mutationFn: (userId: string) => addGroupMember(tenantId!, id!, userId),
mutationFn: (userId: string) => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return addGroupMember(tenantId, id, userId);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user-group-detail", id] });
setIsAddMemberOpen(false);
setSelectedUserId("");
alert("Member added successfully");
},
onError: (error: any) => {
alert(error.message || "Failed to add member");
onError: (error: unknown) => {
alert(getErrorMessage(error, "Failed to add member"));
},
});
const removeMemberMutation = useMutation({
mutationFn: (userId: string) => removeGroupMember(tenantId!, id!, userId),
mutationFn: (userId: string) => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return removeGroupMember(tenantId, id, userId);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user-group-detail", id] });
alert("Member removed successfully");
@@ -115,21 +157,34 @@ export function UserGroupDetailPage() {
});
const assignRoleMutation = useMutation({
mutationFn: () =>
assignGroupRole(tenantId!, id!, selectedTargetTenantId, selectedRelation),
mutationFn: () => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return assignGroupRole(
tenantId,
id,
selectedTargetTenantId,
selectedRelation,
);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user-group-roles", id] });
setIsAddRoleOpen(false);
alert(`Role '${selectedRelation}' assigned successfully`);
},
onError: (error: any) => {
alert(error.message || "Failed to assign role");
onError: (error: unknown) => {
alert(getErrorMessage(error, "Failed to assign role"));
},
});
const removeRoleMutation = useMutation({
mutationFn: (role: { targetTenantId: string; relation: string }) =>
removeGroupRole(tenantId!, id!, role.targetTenantId, role.relation),
mutationFn: (role: { targetTenantId: string; relation: string }) => {
if (!tenantId || !id) {
throw new Error("tenantId and id are required");
}
return removeGroupRole(tenantId, id, role.targetTenantId, role.relation);
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user-group-roles", id] });
alert("Role removed successfully");
@@ -139,7 +194,7 @@ export function UserGroupDetailPage() {
if (isGroupLoading)
return (
<div className="flex items-center justify-center p-12">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
<span className="ml-3 text-muted-foreground">
Loading group details...
</span>
@@ -153,12 +208,7 @@ export function UserGroupDetailPage() {
Could not load group
</h3>
<div className="p-4 bg-red-50 text-red-700 rounded-md text-left text-sm font-mono overflow-auto max-w-xl mx-auto border border-red-100">
<p>
Error:{" "}
{(error as any)?.response?.data?.error ||
(error as any)?.message ||
"Not found"}
</p>
<p>Error: {getErrorMessage(error, "Not found")}</p>
<p className="mt-2 text-red-500 opacity-70">
Path: /admin/tenants/{tenantId}/user-groups/{id}
</p>