forked from baron/baron-sso
RP 대시보드 기능 추가
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
Navigate,
|
||||
type RouteObject,
|
||||
createBrowserRouter,
|
||||
} from "react-router-dom";
|
||||
@@ -13,6 +12,7 @@ import ClientDetailsPage from "../features/clients/ClientDetailsPage";
|
||||
import ClientGeneralPage from "../features/clients/ClientGeneralPage";
|
||||
import ClientRelationsPage from "../features/clients/ClientRelationsPage";
|
||||
import ClientsPage from "../features/clients/ClientsPage";
|
||||
import DashboardPage from "../features/dashboard/DashboardPage";
|
||||
import DeveloperRequestPage from "../features/developer-request/DeveloperRequestPage";
|
||||
import ProfilePage from "../features/profile/ProfilePage";
|
||||
import { DEVFRONT_AUTH_CALLBACK_PATH } from "../lib/authConfig";
|
||||
@@ -33,7 +33,7 @@ export const devFrontRoutes: RouteObject[] = [
|
||||
{
|
||||
element: <AppLayout />,
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="/clients" replace /> },
|
||||
{ index: true, element: <DashboardPage /> },
|
||||
{ path: "clients", element: <ClientsPage /> },
|
||||
{ path: "clients/new", element: <ClientGeneralPage /> },
|
||||
{ path: "clients/:id", element: <ClientDetailsPage /> },
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
BadgeCheck,
|
||||
ChevronDown,
|
||||
ClipboardCheck,
|
||||
LayoutDashboard,
|
||||
LogOut,
|
||||
Moon,
|
||||
NotebookTabs,
|
||||
@@ -33,6 +34,12 @@ import LanguageSelector from "../common/LanguageSelector";
|
||||
import { Toaster } from "../ui/toaster";
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
labelKey: "ui.dev.nav.overview",
|
||||
labelFallback: "Overview",
|
||||
to: "/",
|
||||
icon: LayoutDashboard,
|
||||
},
|
||||
{
|
||||
labelKey: "ui.dev.nav.clients",
|
||||
labelFallback: "Clients",
|
||||
@@ -325,6 +332,7 @@ function AppLayout() {
|
||||
<NavLink
|
||||
key={to}
|
||||
to={to}
|
||||
end={to === "/"}
|
||||
className={({ isActive }) =>
|
||||
[
|
||||
shellLayoutClasses.navItemBase,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,27 @@ export type DevStats = {
|
||||
auth_failures_24h: number;
|
||||
};
|
||||
|
||||
export type RPUsageDailyMetric = {
|
||||
date: string;
|
||||
tenantId: string;
|
||||
tenantType: string;
|
||||
tenantName?: string;
|
||||
clientId: string;
|
||||
clientName: string;
|
||||
loginRequests: number;
|
||||
otherRequests: number;
|
||||
uniqueSubjects: number;
|
||||
};
|
||||
|
||||
export type RPUsagePeriod = "day" | "week" | "month";
|
||||
|
||||
export type RPUsageDailyResponse = {
|
||||
items: RPUsageDailyMetric[];
|
||||
days: number;
|
||||
period: RPUsagePeriod;
|
||||
tenantId?: string;
|
||||
};
|
||||
|
||||
export type DevAuditLog = {
|
||||
event_id: string;
|
||||
timestamp: string;
|
||||
@@ -214,6 +235,22 @@ export async function fetchDevStats() {
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchDevRPUsageDaily({
|
||||
days = 14,
|
||||
period = "day",
|
||||
}: {
|
||||
days?: number;
|
||||
period?: RPUsagePeriod;
|
||||
} = {}) {
|
||||
const { data } = await apiClient.get<RPUsageDailyResponse>(
|
||||
"/dev/rp-usage/daily",
|
||||
{
|
||||
params: { days, period },
|
||||
},
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function fetchTenants(
|
||||
limit = 1000,
|
||||
offset = 0,
|
||||
|
||||
@@ -500,6 +500,7 @@ openid = "Openid"
|
||||
profile = "Profile"
|
||||
|
||||
[msg.dev.dashboard]
|
||||
description = "View connected application composition and authentication operations metrics in one place."
|
||||
|
||||
[msg.dev.dashboard.hero]
|
||||
body = "Body"
|
||||
@@ -507,6 +508,29 @@ title_emphasis = "Title Emphasis"
|
||||
title_prefix = "Title Prefix"
|
||||
title_suffix = "Title Suffix"
|
||||
|
||||
[msg.dev.dashboard.distribution]
|
||||
description = "Quickly review application types and headless login usage."
|
||||
|
||||
[msg.dev.dashboard.chart]
|
||||
empty = "No RP usage aggregates to display."
|
||||
filter_description = "View the chart for all applications or only the ones you select."
|
||||
forbidden = "Your current account does not have permission to view RP usage statistics."
|
||||
server_error = "A server error occurred while loading RP usage statistics."
|
||||
service_unavailable = "The RP usage aggregation service is not ready yet."
|
||||
unavailable = "RP usage statistics API is unavailable. The chart will appear here once aggregate data is ready."
|
||||
unavailable_with_reason = "RP usage statistics API is unavailable. {{reason}}"
|
||||
|
||||
[msg.dev.dashboard.quick_links]
|
||||
audit = "Review RP configuration changes and operational history."
|
||||
clients = "Browse registered RPs and manage their status and type."
|
||||
description = "Jump directly to key operational screens."
|
||||
developer_request = "Review developer access requests or submit a new one."
|
||||
new_client = "Configure redirect URIs, grant types, and authentication methods."
|
||||
|
||||
[msg.dev.dashboard.recent]
|
||||
empty = "Review the relying parties this account can access."
|
||||
none = "No connected applications to display."
|
||||
|
||||
[msg.dev.dashboard.notice]
|
||||
consent_audit = "Consent Audit"
|
||||
dev_scope = "Dev Scope"
|
||||
@@ -1252,6 +1276,7 @@ audit_logs = "Audit Logs"
|
||||
clients = "Connected Application"
|
||||
developer_request = "Developer Access Request"
|
||||
logout = "Logout"
|
||||
overview = "Overview"
|
||||
|
||||
[ui.dev.audit]
|
||||
load_more = "Load more"
|
||||
@@ -1629,12 +1654,32 @@ private_headless = "Server side App (Headless Login)"
|
||||
|
||||
[ui.dev.dashboard]
|
||||
ready_badge = "devfront ready"
|
||||
title = "Dashboard"
|
||||
|
||||
[ui.dev.dashboard.badge]
|
||||
consent_guard = "Consent guard ready"
|
||||
oidc = "OIDC operations"
|
||||
policy_toggle = "Policy toggle enabled"
|
||||
registry = "RP registry"
|
||||
rp_synced = "RP registry synced"
|
||||
|
||||
[ui.dev.dashboard.distribution]
|
||||
headless = "Headless Login"
|
||||
pkce = "PKCE"
|
||||
private = "Server side App"
|
||||
title = "Application Distribution"
|
||||
|
||||
[ui.dev.dashboard.chart]
|
||||
aria = "RP request overview"
|
||||
filter_all = "All"
|
||||
login_requests = "Login requests"
|
||||
other_requests = "Other requests"
|
||||
period_day = "Day"
|
||||
period_month = "Month"
|
||||
period_week = "Week"
|
||||
series = "Login {{login}} / Other {{other}} / Users {{subjects}}"
|
||||
title = "Login and other requests by application"
|
||||
|
||||
[ui.dev.dashboard.next]
|
||||
subtitle = "Ship the RP controls"
|
||||
title = "Next actions"
|
||||
@@ -1652,11 +1697,25 @@ rp_requests = "Rp Requests"
|
||||
consent = "Consent grants"
|
||||
rp_status = "RP status"
|
||||
|
||||
[ui.dev.dashboard.quick_links]
|
||||
create_button = "Create RP"
|
||||
new_client = "New RP"
|
||||
title = "Quick links"
|
||||
|
||||
[ui.dev.dashboard.recent]
|
||||
title = "My Applications"
|
||||
|
||||
[ui.dev.dashboard.stack]
|
||||
notes = "Setup notes"
|
||||
subtitle = "Devfront baseline"
|
||||
title = "Stack readiness"
|
||||
|
||||
[ui.dev.dashboard.summary]
|
||||
active_clients = "Active RPs"
|
||||
active_sessions = "Active sessions"
|
||||
auth_failures_24h = "24h auth failures"
|
||||
total_clients = "Total RPs"
|
||||
|
||||
[ui.dev.header]
|
||||
plane = "Dev Plane"
|
||||
subtitle = "Manage your applications"
|
||||
|
||||
@@ -500,6 +500,7 @@ openid = "OIDC 인증 필수 스코프"
|
||||
profile = "기본 프로필 정보 접근"
|
||||
|
||||
[msg.dev.dashboard]
|
||||
description = "연동 앱 구성과 인증 운영 지표를 한 곳에서 확인합니다."
|
||||
|
||||
[msg.dev.dashboard.hero]
|
||||
body = "Hydra Admin API와 동기화된 RP 목록, 상태 토글, Consent 회수까지 devfront에서 처리하도록 준비합니다."
|
||||
@@ -507,6 +508,29 @@ title_emphasis = " 하나의 화면"
|
||||
title_prefix = "RP 등록 현황과 Consent 상태를"
|
||||
title_suffix = "에서 관리합니다."
|
||||
|
||||
[msg.dev.dashboard.distribution]
|
||||
description = "애플리케이션 유형과 headless login 사용 현황을 빠르게 확인합니다."
|
||||
|
||||
[msg.dev.dashboard.chart]
|
||||
empty = "표시할 RP 이용 집계가 없습니다."
|
||||
filter_description = "전체 또는 선택한 애플리케이션만 기준으로 그래프를 확인합니다."
|
||||
forbidden = "현재 계정에는 RP 이용 통계를 볼 권한이 없습니다."
|
||||
server_error = "RP 이용 통계 조회 중 서버 오류가 발생했습니다."
|
||||
service_unavailable = "RP 이용 통계 집계 서비스가 아직 준비되지 않았습니다."
|
||||
unavailable = "RP 이용 통계 API 응답을 확인할 수 없습니다. 집계 데이터가 준비되면 이 영역에 그래프가 표시됩니다."
|
||||
unavailable_with_reason = "RP 이용 통계 API 응답을 확인할 수 없습니다. {{reason}}"
|
||||
|
||||
[msg.dev.dashboard.quick_links]
|
||||
audit = "RP 설정 변경과 운영 이력을 확인합니다."
|
||||
clients = "등록된 RP를 조회하고 상태와 유형을 관리합니다."
|
||||
description = "주요 운영 화면으로 바로 이동합니다."
|
||||
developer_request = "개발자 권한 신청 내역을 확인하거나 새 요청을 등록합니다."
|
||||
new_client = "redirect URI, grant type, 인증 방식을 설정합니다."
|
||||
|
||||
[msg.dev.dashboard.recent]
|
||||
empty = "현재 계정이 접근할 수 있는 RP를 확인합니다."
|
||||
none = "표시할 연동 앱이 없습니다."
|
||||
|
||||
[msg.dev.dashboard.notice]
|
||||
consent_audit = "Consent 회수는 감사 로그와 연계"
|
||||
dev_scope = "RP 정책은 dev scope에서만 적용"
|
||||
@@ -1252,6 +1276,7 @@ audit_logs = "감사 로그"
|
||||
clients = "연동 앱"
|
||||
developer_request = "개발자 권한 신청"
|
||||
logout = "로그아웃"
|
||||
overview = "개요"
|
||||
|
||||
[ui.dev.audit]
|
||||
load_more = "더 보기"
|
||||
@@ -1628,12 +1653,32 @@ private_headless = "Server side App (Headless Login)"
|
||||
|
||||
[ui.dev.dashboard]
|
||||
ready_badge = "devfront ready"
|
||||
title = "대시보드"
|
||||
|
||||
[ui.dev.dashboard.badge]
|
||||
consent_guard = "Consent guard ready"
|
||||
oidc = "OIDC 운영"
|
||||
policy_toggle = "Policy toggle enabled"
|
||||
registry = "RP registry"
|
||||
rp_synced = "RP registry synced"
|
||||
|
||||
[ui.dev.dashboard.distribution]
|
||||
headless = "Headless Login"
|
||||
pkce = "PKCE"
|
||||
private = "Server side App"
|
||||
title = "애플리케이션 구성 요약"
|
||||
|
||||
[ui.dev.dashboard.chart]
|
||||
aria = "RP 요청 현황"
|
||||
filter_all = "전체"
|
||||
login_requests = "로그인 요청"
|
||||
other_requests = "기타 요청"
|
||||
period_day = "일"
|
||||
period_month = "월"
|
||||
period_week = "주"
|
||||
series = "로그인 {{login}} / 기타 {{other}} / 사용자 {{subjects}}"
|
||||
title = "애플리케이션별 로그인요청/기타 요청 현황"
|
||||
|
||||
[ui.dev.dashboard.next]
|
||||
subtitle = "Ship the RP controls"
|
||||
title = "Next actions"
|
||||
@@ -1651,11 +1696,25 @@ rp_requests = "RP 요청 추이"
|
||||
consent = "Consent grants"
|
||||
rp_status = "RP status"
|
||||
|
||||
[ui.dev.dashboard.quick_links]
|
||||
create_button = "새 RP 만들기"
|
||||
new_client = "새 RP 생성"
|
||||
title = "빠른 이동"
|
||||
|
||||
[ui.dev.dashboard.recent]
|
||||
title = "내 애플리케이션"
|
||||
|
||||
[ui.dev.dashboard.stack]
|
||||
notes = "Setup notes"
|
||||
subtitle = "Devfront baseline"
|
||||
title = "Stack readiness"
|
||||
|
||||
[ui.dev.dashboard.summary]
|
||||
active_clients = "활성 RP 수"
|
||||
active_sessions = "활성 세션 수"
|
||||
auth_failures_24h = "24시간 인증 실패 수"
|
||||
total_clients = "총 RP 수"
|
||||
|
||||
[ui.dev.header]
|
||||
plane = "Dev Plane"
|
||||
subtitle = "Manage your applications"
|
||||
|
||||
@@ -538,6 +538,7 @@ openid = ""
|
||||
profile = ""
|
||||
|
||||
[msg.dev.dashboard]
|
||||
description = ""
|
||||
|
||||
[msg.dev.dashboard.hero]
|
||||
body = ""
|
||||
@@ -545,6 +546,29 @@ title_emphasis = ""
|
||||
title_prefix = ""
|
||||
title_suffix = ""
|
||||
|
||||
[msg.dev.dashboard.distribution]
|
||||
description = ""
|
||||
|
||||
[msg.dev.dashboard.chart]
|
||||
empty = ""
|
||||
filter_description = ""
|
||||
forbidden = ""
|
||||
server_error = ""
|
||||
service_unavailable = ""
|
||||
unavailable = ""
|
||||
unavailable_with_reason = ""
|
||||
|
||||
[msg.dev.dashboard.quick_links]
|
||||
audit = ""
|
||||
clients = ""
|
||||
description = ""
|
||||
developer_request = ""
|
||||
new_client = ""
|
||||
|
||||
[msg.dev.dashboard.recent]
|
||||
empty = ""
|
||||
none = ""
|
||||
|
||||
[msg.dev.dashboard.notice]
|
||||
consent_audit = ""
|
||||
dev_scope = ""
|
||||
@@ -1303,8 +1327,9 @@ scope_badge = ""
|
||||
[ui.dev.nav]
|
||||
audit_logs = ""
|
||||
clients = ""
|
||||
logout = ""
|
||||
developer_request = ""
|
||||
logout = ""
|
||||
overview = ""
|
||||
|
||||
[ui.dev.welcome]
|
||||
btn_request = ""
|
||||
@@ -1685,12 +1710,32 @@ private_headless = ""
|
||||
|
||||
[ui.dev.dashboard]
|
||||
ready_badge = ""
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.badge]
|
||||
consent_guard = ""
|
||||
oidc = ""
|
||||
policy_toggle = ""
|
||||
registry = ""
|
||||
rp_synced = ""
|
||||
|
||||
[ui.dev.dashboard.distribution]
|
||||
headless = ""
|
||||
pkce = ""
|
||||
private = ""
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.chart]
|
||||
aria = ""
|
||||
filter_all = ""
|
||||
login_requests = ""
|
||||
other_requests = ""
|
||||
period_day = ""
|
||||
period_month = ""
|
||||
period_week = ""
|
||||
series = ""
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.next]
|
||||
subtitle = ""
|
||||
title = ""
|
||||
@@ -1708,11 +1753,25 @@ rp_requests = ""
|
||||
consent = ""
|
||||
rp_status = ""
|
||||
|
||||
[ui.dev.dashboard.quick_links]
|
||||
create_button = ""
|
||||
new_client = ""
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.recent]
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.stack]
|
||||
notes = ""
|
||||
subtitle = ""
|
||||
title = ""
|
||||
|
||||
[ui.dev.dashboard.summary]
|
||||
active_clients = ""
|
||||
active_sessions = ""
|
||||
auth_failures_24h = ""
|
||||
total_clients = ""
|
||||
|
||||
[ui.dev.header]
|
||||
plane = ""
|
||||
subtitle = ""
|
||||
|
||||
Reference in New Issue
Block a user