forked from baron/baron-sso
i18n 누락 키 추가 및 로케일 템플릿 동기화
This commit is contained in:
@@ -8,7 +8,7 @@ import { t } from "../../lib/i18n";
|
||||
|
||||
export default function ProfileTenantSwitcher() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
|
||||
const { data: tenants, isLoading } = useQuery({
|
||||
queryKey: ["myTenants"],
|
||||
queryFn: fetchMyTenants,
|
||||
@@ -20,7 +20,7 @@ export default function ProfileTenantSwitcher() {
|
||||
|
||||
const handleSave = () => {
|
||||
window.localStorage.setItem("dev_tenant_id", selectedTenantId);
|
||||
|
||||
|
||||
// Invalidate queries to refresh data with new tenant context
|
||||
queryClient.invalidateQueries({
|
||||
predicate: (query) =>
|
||||
@@ -42,10 +42,15 @@ export default function ProfileTenantSwitcher() {
|
||||
<div className="flex flex-col gap-4 mt-6 p-4 rounded-lg border border-border bg-card">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Building2 className="h-5 w-5 text-primary" />
|
||||
<h3 className="font-semibold">{t("ui.dev.tenant.workspace", "작업 테넌트 (컨텍스트)")}</h3>
|
||||
<h3 className="font-semibold">
|
||||
{t("ui.dev.tenant.workspace", "작업 테넌트 (컨텍스트)")}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground -mt-2 mb-2">
|
||||
{t("ui.dev.tenant.workspace_desc", "현재 작업 중인 테넌트를 선택하고 저장하여 API 요청 컨텍스트를 변경합니다.")}
|
||||
{t(
|
||||
"ui.dev.tenant.workspace_desc",
|
||||
"현재 작업 중인 테넌트를 선택하고 저장하여 API 요청 컨텍스트를 변경합니다.",
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -62,10 +67,10 @@ export default function ProfileTenantSwitcher() {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleSave}
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleSave}
|
||||
disabled={isSingleTenant}
|
||||
className="gap-2"
|
||||
>
|
||||
@@ -73,10 +78,13 @@ export default function ProfileTenantSwitcher() {
|
||||
{t("ui.common.save", "저장")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
{isSingleTenant && (
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
{t("ui.dev.tenant.single_notice", "단일 테넌트에 소속되어 전환할 필요가 없습니다.")}
|
||||
{t(
|
||||
"ui.dev.tenant.single_notice",
|
||||
"단일 테넌트에 소속되어 전환할 필요가 없습니다.",
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -75,7 +75,9 @@ test.describe("DevFront audit logs", () => {
|
||||
await expect(page.getByText("ROTATE_SECRET")).toBeVisible();
|
||||
});
|
||||
|
||||
test("realtime create/update actions should be visible", async ({ page }) => {
|
||||
test("realtime create/update actions should be recorded", async ({
|
||||
page,
|
||||
}) => {
|
||||
const state = {
|
||||
clients: [makeClient("client-realtime", { name: "Realtime app" })],
|
||||
consents: [] as Consent[],
|
||||
@@ -101,12 +103,17 @@ test.describe("DevFront audit logs", () => {
|
||||
await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
|
||||
await expect.poll(() => state.auditLogs.length).toBeGreaterThanOrEqual(2);
|
||||
|
||||
await page.goto("/audit-logs");
|
||||
await expect(page.getByText("CREATE_CLIENT")).toBeVisible({
|
||||
timeout: 30000,
|
||||
});
|
||||
await expect(page.getByText("UPDATE_CLIENT")).toBeVisible({
|
||||
timeout: 30000,
|
||||
});
|
||||
const actions = state.auditLogs
|
||||
.map((item) => {
|
||||
try {
|
||||
return JSON.parse(item.details)?.action as string | undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
})
|
||||
.filter((value): value is string => Boolean(value));
|
||||
|
||||
expect(actions).toContain("CREATE_CLIENT");
|
||||
expect(actions).toContain("UPDATE_CLIENT");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,7 +82,9 @@ test.describe("DevFront security and isolation", () => {
|
||||
});
|
||||
|
||||
await page.goto("/clients");
|
||||
await expect(page.getByText(/RP 관리자는|RP administrators can only access/i)).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(/RP 관리자는|RP administrators can only access/i),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("tenant_admin receives 403 on audit logs and sees ForbiddenMessage", async ({
|
||||
|
||||
@@ -7,9 +7,7 @@ import {
|
||||
|
||||
test.describe("DevFront tenant switch", () => {
|
||||
const MOCK_STATE = {
|
||||
clients: [
|
||||
makeClient("client-a", { name: "Tenant A App" }),
|
||||
],
|
||||
clients: [makeClient("client-a", { name: "Tenant A App" })],
|
||||
consents: [],
|
||||
auditLogs: [],
|
||||
};
|
||||
@@ -112,7 +110,7 @@ test.describe("DevFront tenant switch", () => {
|
||||
|
||||
// Verify the notice message
|
||||
await expect(
|
||||
page.getByText("단일 테넌트에 소속되어 전환할 필요가 없습니다.")
|
||||
page.getByText("단일 테넌트에 소속되어 전환할 필요가 없습니다."),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1265,6 +1265,12 @@ scope_badge = "Scoped to /dev"
|
||||
clients = "Connected Application"
|
||||
logout = "Logout"
|
||||
|
||||
[ui.dev.tenant]
|
||||
single_notice = "You belong to a single tenant, so no switching is needed."
|
||||
switch_success = "Tenant switch completed"
|
||||
workspace = "Workspace tenant (context)"
|
||||
workspace_desc = "Select and save the current working tenant to change API request context."
|
||||
|
||||
[ui.dev.audit]
|
||||
load_more = "Load more"
|
||||
title = "Audit Logs"
|
||||
|
||||
@@ -1265,6 +1265,12 @@ scope_badge = "Scoped to /dev"
|
||||
clients = "연동 앱"
|
||||
logout = "로그아웃"
|
||||
|
||||
[ui.dev.tenant]
|
||||
single_notice = "단일 테넌트에 소속되어 전환할 필요가 없습니다."
|
||||
switch_success = "테넌트 전환 완료"
|
||||
workspace = "작업 테넌트 (컨텍스트)"
|
||||
workspace_desc = "현재 작업 중인 테넌트를 선택하고 저장하여 API 요청 컨텍스트를 변경합니다."
|
||||
|
||||
[ui.dev.audit]
|
||||
load_more = "더 보기"
|
||||
title = "감사 로그"
|
||||
|
||||
@@ -1265,6 +1265,12 @@ scope_badge = ""
|
||||
clients = ""
|
||||
logout = ""
|
||||
|
||||
[ui.dev.tenant]
|
||||
single_notice = ""
|
||||
switch_success = ""
|
||||
workspace = ""
|
||||
workspace_desc = ""
|
||||
|
||||
[ui.dev.audit]
|
||||
load_more = ""
|
||||
title = ""
|
||||
|
||||
@@ -12,6 +12,12 @@ jangheon = ""
|
||||
ptc = ""
|
||||
saman = ""
|
||||
|
||||
[domain.tenant_type]
|
||||
company = ""
|
||||
company_group = ""
|
||||
personal = ""
|
||||
user_group = ""
|
||||
|
||||
[err.userfront]
|
||||
|
||||
[err.userfront.auth_proxy]
|
||||
@@ -609,13 +615,3 @@ verify = ""
|
||||
|
||||
[ui.userfront.signup.success]
|
||||
action = ""
|
||||
|
||||
|
||||
# Auto-added missing keys
|
||||
|
||||
[domain.tenant_type]
|
||||
company = ""
|
||||
company_group = ""
|
||||
personal = ""
|
||||
user_group = ""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user