diff --git a/devfront/src/features/clients/ClientsPage.tsx b/devfront/src/features/clients/ClientsPage.tsx index 037c08d6..e12df84e 100644 --- a/devfront/src/features/clients/ClientsPage.tsx +++ b/devfront/src/features/clients/ClientsPage.tsx @@ -92,14 +92,62 @@ const recentClientActions = new Set([ "DELETE_CLIENT", ]); +const recentChangeGuideItems = [ + { + titleKey: "ui.dev.clients.recent_changes.guide.create", + titleFallback: "앱 생성", + descriptionKey: "msg.dev.clients.recent_changes.guide.create_desc", + descriptionFallback: + "새 애플리케이션이 등록되면 이름, 유형, 기본 상태와 함께 표시됩니다.", + }, + { + titleKey: "ui.dev.clients.recent_changes.guide.settings", + titleFallback: "설정 변경", + descriptionKey: "msg.dev.clients.recent_changes.guide.settings_desc", + descriptionFallback: + "앱 이름, 스코프, 테넌트 접근 제한, 커스텀 클레임, 보안 설정, 로그아웃 URI, JWKS 변경이 포함됩니다.", + }, + { + titleKey: "ui.dev.clients.recent_changes.guide.status", + titleFallback: "상태 변경", + descriptionKey: "msg.dev.clients.recent_changes.guide.status_desc", + descriptionFallback: "Active / Inactive 전환이 여기에 포함됩니다.", + }, + { + titleKey: "ui.dev.clients.recent_changes.guide.relation", + titleFallback: "관계 변경", + descriptionKey: "msg.dev.clients.recent_changes.guide.relation_desc", + descriptionFallback: "관계 추가와 삭제가 함께 표시됩니다.", + }, + { + titleKey: "ui.dev.clients.recent_changes.guide.secret", + titleFallback: "클라이언트 시크릿 재발급", + descriptionKey: "msg.dev.clients.recent_changes.guide.secret_desc", + descriptionFallback: "시크릿 재발급 이력이 보입니다.", + }, + { + titleKey: "ui.dev.clients.recent_changes.guide.delete", + titleFallback: "앱 삭제", + descriptionKey: "msg.dev.clients.recent_changes.guide.delete_desc", + descriptionFallback: "앱 삭제도 최근 변경 이력에 포함됩니다.", + }, +] as const; + const recentClientFieldLabels: Record = { name: "이름", type: "유형", status: "상태", + scopes: "스코프", + tenant_access_restricted: "테넌트 접근 제한", + allowed_tenants: "허용 테넌트", + id_token_claims: "커스텀 클레임", token_endpoint_auth_method: "인증 방식", jwks_uri: "JWKS URI", backchannel_logout_uri: "Backchannel Logout URI", backchannel_logout_session_required: "세션 필수", + headless_login_enabled: "헤드리스 로그인", + headless_token_endpoint_auth_method: "헤드리스 인증 방식", + headless_jwks_uri: "헤드리스 JWKS URI", redirect_uri_count: "Redirect URI 수", scope_count: "Scope 수", relation: "관계", @@ -263,6 +311,8 @@ function ClientsPage() { const [statusFilter, setStatusFilter] = useState("all"); const [isAdvancedFilterOpen, setIsAdvancedFilterOpen] = useState(false); const [isRequestModalOpen, setIsRequestModalOpen] = useState(false); + const [isRecentChangesGuideOpen, setIsRecentChangesGuideOpen] = + useState(false); const [sortConfig, setSortConfig] = useState | null>({ key: "createdAt", @@ -921,12 +971,30 @@ function ClientsPage() { - +
- - {t("ui.dev.clients.recent_changes.title", "최근 변경된 앱")} - +
+ + {t("ui.dev.clients.recent_changes.title", "최근 변경된 앱")} + + +
{t( "msg.dev.clients.recent_changes.description", @@ -940,6 +1008,34 @@ function ClientsPage() { "'감사 로그 조회' 관계가 있어야 최근 변경된 앱을 볼 수 있습니다.", )}

+ {isRecentChangesGuideOpen && ( +
+

+ {t( + "ui.dev.clients.recent_changes.guide_title", + "최근 변경 항목 안내", + )} +

+
+ {recentChangeGuideItems.map((item) => ( +
+

+ {t(item.titleKey, item.titleFallback)} +

+

+ {t(item.descriptionKey, item.descriptionFallback)} +

+
+ ))} +

+ {t( + "msg.dev.clients.recent_changes.guide.audit_only", + "동의 철회는 최근 변경된 앱 카드에 포함하지 않고, 감사 로그에서 확인합니다.", + )} +

+
+
+ )}