diff --git a/devfront/src/features/clients/ClientGeneralPage.tsx b/devfront/src/features/clients/ClientGeneralPage.tsx index b20cfb80..a2b384ee 100644 --- a/devfront/src/features/clients/ClientGeneralPage.tsx +++ b/devfront/src/features/clients/ClientGeneralPage.tsx @@ -34,7 +34,7 @@ import { createClient, deleteClient, fetchClient, - fetchTenants, + fetchMyTenants, refreshHeadlessJwksCache, revokeHeadlessJwksCache, updateClient, @@ -44,6 +44,7 @@ import type { ClientStatus, ClientType, ClientUpsertRequest, + MyTenantSummary, TenantSummary, } from "../../lib/devApi"; import { t } from "../../lib/i18n"; @@ -138,8 +139,8 @@ function ClientGeneralPage() { enabled: !isCreate, }); const { data: tenantData } = useQuery({ - queryKey: ["tenants"], - queryFn: () => fetchTenants(1000, 0), + queryKey: ["my-tenants"], + queryFn: fetchMyTenants, }); const [name, setName] = useState(""); @@ -172,18 +173,6 @@ function ClientGeneralPage() { }, { id: "2", - name: "profile", - description: t("msg.dev.clients.scopes.profile", "기본 프로필 정보 접근"), - mandatory: false, - }, - { - id: "3", - name: "email", - description: t("msg.dev.clients.scopes.email", "이메일 주소 접근"), - mandatory: false, - }, - { - id: "4", name: "tenant", description: t( "msg.dev.clients.scopes.tenant", @@ -191,6 +180,18 @@ function ClientGeneralPage() { ), mandatory: false, }, + { + id: "3", + name: "profile", + description: t("msg.dev.clients.scopes.profile", "기본 프로필 정보 접근"), + mandatory: false, + }, + { + id: "4", + name: "email", + description: t("msg.dev.clients.scopes.email", "이메일 주소 접근"), + mandatory: false, + }, ]); useEffect(() => { @@ -355,7 +356,18 @@ function ClientGeneralPage() { normalized.push(buildTenantScope(`tenant-${Date.now()}`)); } - return normalized; + const openidScopes = normalized.filter( + (scope) => scope.name.trim() === "openid", + ); + const tenantScopes = normalized.filter( + (scope) => scope.name.trim() === "tenant", + ); + const remainingScopes = normalized.filter((scope) => { + const name = scope.name.trim(); + return name !== "openid" && name !== "tenant"; + }); + + return [...openidScopes, ...tenantScopes, ...remainingScopes]; } const handleTenantAccessToggle = (enabled: boolean) => { @@ -514,12 +526,13 @@ function ClientGeneralPage() { const hasValidationErrors = validationErrors.length > 0; const normalizedTenantSearch = tenantSearch.trim().toLowerCase(); - const tenantOptions: TenantSummary[] = tenantData?.items ?? []; + const tenantOptions: Array = tenantData ?? []; const filteredTenants = tenantOptions.filter((tenant) => { if (!normalizedTenantSearch) { return true; } - const searchable = `${tenant.name} ${tenant.slug} ${tenant.description} ${tenant.type}`.toLowerCase(); + const searchable = + `${tenant.name} ${tenant.slug} ${tenant.description ?? ""} ${tenant.type ?? ""}`.toLowerCase(); return searchable.includes(normalizedTenantSearch); }); const tenantSuggestions = filteredTenants @@ -527,7 +540,9 @@ function ClientGeneralPage() { .slice(0, 8); const selectedAllowedTenants = allowedTenantIds .map((tenantId) => tenantOptions.find((item) => item.id === tenantId)) - .filter((tenant): tenant is TenantSummary => tenant != null); + .filter( + (tenant): tenant is TenantSummary | MyTenantSummary => tenant != null, + ); const refreshHeadlessJwksCacheMutation = useMutation({ mutationFn: async () => { diff --git a/devfront/src/lib/devApi.ts b/devfront/src/lib/devApi.ts index c31cba26..0a6574f2 100644 --- a/devfront/src/lib/devApi.ts +++ b/devfront/src/lib/devApi.ts @@ -409,11 +409,8 @@ export async function fetchDevAuditLogs( return data; } -export type MyTenantSummary = { - id: string; - name: string; - slug: string; -}; +export type MyTenantSummary = Pick & + Partial; export async function fetchMyTenants() { const { data } = await apiClient.get("/dev/my-tenants");