From 3b56346c23eb98d8c5085ecef19fa3256343b1d1 Mon Sep 17 00:00:00 2001 From: kyy Date: Tue, 7 Apr 2026 16:03:35 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EC=BB=AC=20code-check=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/clients/ClientDetailsPage.tsx | 65 +++++++++++-------- locales/en.toml | 1 + locales/ko.toml | 3 + locales/template.toml | 5 +- userfront/assets/translations/en.toml | 15 ++--- userfront/assets/translations/ko.toml | 19 +++--- userfront/assets/translations/template.toml | 9 ++- 7 files changed, 67 insertions(+), 50 deletions(-) diff --git a/devfront/src/features/clients/ClientDetailsPage.tsx b/devfront/src/features/clients/ClientDetailsPage.tsx index 1fa793c6..f4a3550f 100644 --- a/devfront/src/features/clients/ClientDetailsPage.tsx +++ b/devfront/src/features/clients/ClientDetailsPage.tsx @@ -9,7 +9,7 @@ import { Save, Shield, } from "lucide-react"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { Link, useParams } from "react-router-dom"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; @@ -44,7 +44,7 @@ function ClientDetailsPage() { const queryClient = useQueryClient(); const clientId = params.id ?? ""; - const { data, isLoading, error } = useQuery({ + const { data, error } = useQuery({ queryKey: ["client", clientId], queryFn: () => fetchClient(clientId), enabled: clientId.length > 0, @@ -52,12 +52,18 @@ function ClientDetailsPage() { const [redirectUris, setRedirectUris] = useState(""); const [showSecret, setShowSecret] = useState(false); + const redirectUrisHydratedRef = useRef(false); useEffect(() => { - if (data?.client?.redirectUris) { + if ( + !redirectUrisHydratedRef.current && + data?.client?.redirectUris && + redirectUris === "" + ) { setRedirectUris(data.client.redirectUris.join(", ")); + redirectUrisHydratedRef.current = true; } - }, [data]); + }, [data, redirectUris]); const mutation = useMutation({ mutationFn: () => { @@ -129,15 +135,7 @@ function ClientDetailsPage() { ); } - if (isLoading) { - return ( -
- {t("msg.dev.clients.details.loading", "Loading app...")} -
- ); - } - - if (error || !data) { + if (error && !data) { const errMsg = (error as AxiosError<{ error?: string }>).response?.data?.error ?? (error as Error)?.message; @@ -152,37 +150,45 @@ function ClientDetailsPage() { ); } + const client = data?.client; + const endpointValues = data?.endpoints ?? { + discovery: "-", + issuer: "-", + authorization: "-", + token: "-", + userinfo: "-", + }; const endpoints = [ { labelKey: "ui.dev.clients.details.endpoint.discovery", labelFallback: "Discovery Endpoint", - value: data.endpoints.discovery, + value: endpointValues.discovery, }, { labelKey: "ui.dev.clients.details.endpoint.issuer", labelFallback: "Issuer URL", - value: data.endpoints.issuer, + value: endpointValues.issuer, }, { labelKey: "ui.dev.clients.details.endpoint.authorization", labelFallback: "Authorization Endpoint", - value: data.endpoints.authorization, + value: endpointValues.authorization, }, { labelKey: "ui.dev.clients.details.endpoint.token", labelFallback: "Token Endpoint", - value: data.endpoints.token, + value: endpointValues.token, }, { labelKey: "ui.dev.clients.details.endpoint.userinfo", labelFallback: "UserInfo Endpoint", - value: data.endpoints.userinfo, + value: endpointValues.userinfo, }, ]; // Client Secret from API const secretPlaceholder = "SECRET_NOT_AVAILABLE"; - const clientSecret = data.client.clientSecret || secretPlaceholder; + const clientSecret = client?.clientSecret || secretPlaceholder; const displaySecret = clientSecret === secretPlaceholder ? t("msg.dev.clients.details.secret_unavailable", "SECRET_NOT_AVAILABLE") @@ -200,7 +206,7 @@ function ClientDetailsPage() { {t("ui.dev.clients.consents.breadcrumb.clients", "Apps")} / - {data.client.name || clientId} + {client?.name || clientId} / {t("ui.dev.clients.details.tab.connection", "Federation")} @@ -215,7 +221,7 @@ function ClientDetailsPage() {

- {data.client.name || data.client.id} + {client?.name || client?.id || clientId}

{t( @@ -226,12 +232,14 @@ function ClientDetailsPage() {

- {data.client.status === "active" + {client?.status === "active" ? t("ui.common.status.active", "Active") - : t("ui.common.status.inactive", "Inactive")} + : client?.status === "inactive" + ? t("ui.common.status.inactive", "Inactive") + : t("msg.common.loading", "Loading...")}
@@ -276,10 +284,10 @@ function ClientDetailsPage() {

- {data.client.id} + {client?.id || clientId}

toast( t( @@ -461,7 +469,10 @@ function ClientDetailsPage() { )} rows={5} value={redirectUris} - onChange={(e) => setRedirectUris(e.target.value)} + onChange={(e) => { + redirectUrisHydratedRef.current = true; + setRedirectUris(e.target.value); + }} className="font-mono text-sm" />
diff --git a/locales/en.toml b/locales/en.toml index cbc9ab29..bc5d4d6a 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -513,6 +513,7 @@ browser = "Browser: {{value}}" date = "Date: {{value}}" device = "Device: {{value}}" end = "No more items to show." +filtered_empty = "No sign-in history matches the active session filter." ip = "IP address: {{value}}" load_more_error = "Could not load more history." result = "Result: {{value}}" diff --git a/locales/ko.toml b/locales/ko.toml index 6243c0af..680b34f8 100644 --- a/locales/ko.toml +++ b/locales/ko.toml @@ -175,6 +175,7 @@ browser = "브라우저: {{value}}" date = "접속일자: {{value}}" device = "접속환경: {{value}}" end = "더 이상 항목이 없습니다." +filtered_empty = "활성 세션으로 필터링된 접속 이력이 없습니다." ip = "접속 IP: {{value}}" load_more_error = "더 불러오지 못했습니다." result = "인증결과: {{value}}" @@ -905,9 +906,11 @@ saved_success = "저장이 완료되었습니다." greeting = "안녕하세요, {{name}}님" [msg.userfront.audit] +browser = "브라우저: {{value}}" date = "접속일자: {{value}}" device = "접속환경: {{value}}" end = "더 이상 항목이 없습니다." +filtered_empty = "활성 세션으로 필터링된 접속 이력이 없습니다." ip = "접속 IP: {{value}}" load_more_error = "더 불러오지 못했습니다." result = "인증결과: {{value}}" diff --git a/locales/template.toml b/locales/template.toml index d34c647e..2440c558 100644 --- a/locales/template.toml +++ b/locales/template.toml @@ -782,9 +782,11 @@ saved_success = "" greeting = "" [msg.userfront.audit] +browser = "" date = "" device = "" end = "" +filtered_empty = "" ip = "" load_more_error = "" result = "" @@ -2330,6 +2332,7 @@ dev_console = "" action = "" app = "" auth_method = "" +browser = "" date = "" device = "" ip = "" @@ -2557,4 +2560,4 @@ title = "" toggle_label = "" [msg.userfront.audit.filter] -description = "" \ No newline at end of file +description = "" diff --git a/userfront/assets/translations/en.toml b/userfront/assets/translations/en.toml index 5f5a3298..f7eafeb2 100644 --- a/userfront/assets/translations/en.toml +++ b/userfront/assets/translations/en.toml @@ -48,13 +48,12 @@ browser = "Browser: {value}" date = "Date: {value}" device = "Device: {value}" end = "No more items to show." -filtered_empty = "There are no active or current sessions to display." -filter.description = "Turn this on to show only active or current sessions." +filtered_empty = "No sign-in history matches the active session filter." ip = "IP address: {value}" load_more_error = "Could not load more history." result = "Result: {value}" session_id = "Session ID: {value}" -status = "Status: {value}" +status = "Status: pending" [msg.userfront.consent] accept_error = "Failed to process consent: {error}" @@ -286,7 +285,7 @@ uppercase = "At least one uppercase letter" [msg.userfront.sections] apps_subtitle = "Your linked apps and their latest sign-in status." -audit_subtitle = "Review current session status and recent sign-in history together." +audit_subtitle = "Recent access history for Baron sign-in." sessions_subtitle = "Your currently signed-in devices and browser sessions." [msg.userfront.settings] @@ -437,10 +436,6 @@ dev_console = "Dev Console" [ui.userfront.audit] -[ui.userfront.audit.filter] -title = "Session filter" -toggle_label = "Active only" - [ui.userfront.audit.table] action = "Action" app = "App" @@ -669,5 +664,9 @@ verify = "Verification" action = "Go to sign-in" +[ui.userfront.audit.filter] +title = "Manage My Activity" +toggle_label = "Show active sessions only" + [msg.userfront.audit.filter] description = "Toggle to view only active sessions." diff --git a/userfront/assets/translations/ko.toml b/userfront/assets/translations/ko.toml index eee97bbe..244414a5 100644 --- a/userfront/assets/translations/ko.toml +++ b/userfront/assets/translations/ko.toml @@ -45,13 +45,12 @@ browser = "브라우저: {value}" date = "접속일자: {value}" device = "접속환경: {value}" end = "더 이상 항목이 없습니다." -filtered_empty = "활성화 또는 접속중인 세션이 없습니다." -filter.description = "토글을 켜면 활성화 또는 접속중인 세션만 표시됩니다." +filtered_empty = "활성 세션으로 필터링된 접속 이력이 없습니다." ip = "접속 IP: {value}" load_more_error = "더 불러오지 못했습니다." result = "인증결과: {value}" session_id = "Session ID: {value}" -status = "현황: {value}" +status = "현황: (준비중)" [msg.userfront.dashboard] approved_device = "승인 기기: {device}" @@ -141,7 +140,7 @@ success = "비밀번호가 성공적으로 변경되었습니다. 다시 로그 [msg.userfront.sections] apps_subtitle = "현재 연결된 앱과 최근 인증 상태입니다." -audit_subtitle = "현재 세션 현황과 최근 접근 기록을 함께 확인할 수 있습니다." +audit_subtitle = "Baron 로그인 기준의 최근 접근 기록입니다." sessions_subtitle = "현재 로그인된 기기와 브라우저 세션입니다." [msg.userfront.settings] @@ -251,9 +250,11 @@ title = "회원가입" greeting = "안녕하세요, {name}님" [msg.userfront.audit] +browser = "브라우저: {value}" date = "접속일자: {value}" device = "접속환경: {value}" end = "더 이상 항목이 없습니다." +filtered_empty = "활성 세션으로 필터링된 접속 이력이 없습니다." ip = "접속 IP: {value}" load_more_error = "더 불러오지 못했습니다." result = "인증결과: {value}" @@ -490,7 +491,7 @@ uppercase = "대문자 1개 이상" [msg.userfront.sections] apps_subtitle = "현재 연결된 앱과 최근 인증 상태입니다." -audit_subtitle = "현재 세션 현황과 최근 접근 기록을 함께 확인할 수 있습니다." +audit_subtitle = "Baron 로그인 기준의 최근 접근 기록입니다." [msg.userfront.settings] disabled = "현재 계정 설정 화면은 준비 중입니다." @@ -640,10 +641,6 @@ dev_console = "Dev Console" [ui.userfront.audit] -[ui.userfront.audit.filter] -title = "세션 필터" -toggle_label = "활성 세션만" - [ui.userfront.audit.table] action = "관리" app = "애플리케이션" @@ -871,5 +868,9 @@ verify = "본인인증" action = "로그인하기" +[ui.userfront.audit.filter] +title = "내 활동 관리" +toggle_label = "활성 세션만 보기" + [msg.userfront.audit.filter] description = "활성화된 세션만 보려면 토글을 켜주세요." diff --git a/userfront/assets/translations/template.toml b/userfront/assets/translations/template.toml index f3d544ba..86653de2 100644 --- a/userfront/assets/translations/template.toml +++ b/userfront/assets/translations/template.toml @@ -228,7 +228,6 @@ date = "" device = "" end = "" filtered_empty = "" -filter.description = "" ip = "" load_more_error = "" result = "" @@ -615,10 +614,6 @@ dev_console = "" [ui.userfront.audit] -[ui.userfront.audit.filter] -title = "" -toggle_label = "" - [ui.userfront.audit.table] action = "" app = "" @@ -846,5 +841,9 @@ verify = "" action = "" +[ui.userfront.audit.filter] +title = "" +toggle_label = "" + [msg.userfront.audit.filter] description = ""