1
0
forked from baron/baron-sso

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	adminfront/src/features/tenants/routes/TenantListPage.tsx
#	adminfront/src/features/users/UserDetailPage.tsx
#	adminfront/tests/users_bulk_secondary.spec.ts
This commit is contained in:
2026-05-29 14:33:01 +09:00
6 changed files with 25 additions and 19 deletions

View File

@@ -276,18 +276,18 @@ code-check-front-lint:
@echo "==> adminfront biome lint/format check" @echo "==> adminfront biome lint/format check"
rm -rf adminfront/playwright-report adminfront/test-results rm -rf adminfront/playwright-report adminfront/test-results
cd adminfront && CI=true npx pnpm install --frozen-lockfile --ignore-scripts cd adminfront && CI=true npx pnpm install --frozen-lockfile --ignore-scripts
cd adminfront && npx biome check . --formatter-enabled=false --organize-imports-enabled=false cd adminfront && npx biome lint .
cd adminfront && npx biome check . --linter-enabled=false --organize-imports-enabled=false cd adminfront && npx biome format .
@echo "==> devfront biome lint/format check" @echo "==> devfront biome lint/format check"
rm -rf devfront/playwright-report devfront/test-results rm -rf devfront/playwright-report devfront/test-results
cd devfront && npm ci --ignore-scripts cd devfront && npm ci --ignore-scripts
cd devfront && npx biome check . --formatter-enabled=false --organize-imports-enabled=false cd devfront && npx biome lint .
cd devfront && npx biome check . --linter-enabled=false --organize-imports-enabled=false cd devfront && npx biome format .
@echo "==> orgfront biome lint/format check" @echo "==> orgfront biome lint/format check"
rm -rf orgfront/playwright-report orgfront/test-results rm -rf orgfront/playwright-report orgfront/test-results
cd orgfront && npm ci --ignore-scripts cd orgfront && npm ci --ignore-scripts
cd orgfront && npx biome check . --formatter-enabled=false --organize-imports-enabled=false cd orgfront && npx biome lint .
cd orgfront && npx biome check . --linter-enabled=false --organize-imports-enabled=false cd orgfront && npx biome format .
code-check-backend-tests: code-check-backend-tests:
@echo "==> backend tests" @echo "==> backend tests"

View File

@@ -118,6 +118,10 @@ import {
const tenantCSVTemplate = const tenantCSVTemplate =
"name,type,parent_tenant_slug,slug,memo,email_domain,visibility,org_unit_type\n"; "name,type,parent_tenant_slug,slug,memo,email_domain,visibility,org_unit_type\n";
const tenantPageSize = 500; const tenantPageSize = 500;
const _tenantVirtualizationThreshold = 250;
const _tenantEstimatedRowHeight = 73;
const _tenantLoadAheadPx = 360;
const _tenantLoadAheadRows = 30;
type TenantSortKey = keyof TenantSummary | "recursiveMemberCount"; type TenantSortKey = keyof TenantSummary | "recursiveMemberCount";

View File

@@ -662,6 +662,7 @@ function UserCreatePage() {
variant="ghost" variant="ghost"
size="sm" size="sm"
className="absolute right-1 top-1 h-8 text-xs font-bold" className="absolute right-1 top-1 h-8 text-xs font-bold"
data-testid="add-sub-email-btn"
onClick={() => { onClick={() => {
const value = newSubEmail.trim().replace(/,/g, ""); const value = newSubEmail.trim().replace(/,/g, "");
if ( if (
@@ -678,7 +679,7 @@ function UserCreatePage() {
}} }}
> >
{t("ui.common.add", "추가")} {t("ui.common.add", "추가")}
</Button> </Button>{" "}
</div> </div>
<p className="text-[10px] text-muted-foreground mt-1"> <p className="text-[10px] text-muted-foreground mt-1">
* . . * . .
@@ -877,6 +878,7 @@ function UserCreatePage() {
variant="outline" variant="outline"
size="sm" size="sm"
onClick={addAppointment} onClick={addAppointment}
data-testid="add-appointment-btn"
> >
<Plus className="mr-2 h-4 w-4" /> <Plus className="mr-2 h-4 w-4" />
{t("ui.common.add", "추가")} {t("ui.common.add", "추가")}

View File

@@ -1020,15 +1020,14 @@ function UserDetailPage() {
<Mail size={14} className="text-primary/70" /> <Mail size={14} className="text-primary/70" />
{user.email} {user.email}
</div> </div>
{Array.isArray(user.metadata?.sub_email) && {normalizeSubEmails(user.metadata?.sub_email).length > 0 && (
user.metadata.sub_email.length > 0 && ( <div className="flex items-center gap-1.5 bg-background px-2.5 py-1 rounded-full border">
<div className="flex items-center gap-1.5 bg-background px-2.5 py-1 rounded-full border"> <Mail size={14} className="text-primary/40" />
<Mail size={14} className="text-primary/40" /> <span className="text-[10px] font-bold">
<span className="text-[10px] font-bold"> +{normalizeSubEmails(user.metadata?.sub_email).length}
+{user.metadata.sub_email.length} </span>
</span> </div>
</div> )}
)}
{user.phone && ( {user.phone && (
<div className="flex items-center gap-1.5 bg-background px-2.5 py-1 rounded-full border"> <div className="flex items-center gap-1.5 bg-background px-2.5 py-1 rounded-full border">
<Shield size={14} className="text-primary/70" /> <Shield size={14} className="text-primary/70" />
@@ -1194,6 +1193,7 @@ function UserDetailPage() {
variant="ghost" variant="ghost"
size="sm" size="sm"
className="absolute right-1 top-1 h-9 text-xs font-bold" className="absolute right-1 top-1 h-9 text-xs font-bold"
data-testid="add-sub-email-btn"
onClick={() => { onClick={() => {
const value = newSubEmail.trim().replace(/,/g, ""); const value = newSubEmail.trim().replace(/,/g, "");
if ( if (
@@ -1347,6 +1347,7 @@ function UserDetailPage() {
variant="outline" variant="outline"
size="sm" size="sm"
onClick={addAppointment} onClick={addAppointment}
data-testid="add-appointment-btn"
> >
<Plus className="mr-2 h-4 w-4" /> <Plus className="mr-2 h-4 w-4" />
{t("ui.common.add", "추가")} {t("ui.common.add", "추가")}

View File

@@ -141,8 +141,7 @@ primary@samaneng.com,Primary User,rnd-saman,EMP001,secondary@hanmaceng.co.kr`;
tenantSlug: "rnd-saman", tenantSlug: "rnd-saman",
metadata: { metadata: {
employee_id: "EMP001", employee_id: "EMP001",
sub_email: "secondary@hanmaceng.co.kr", sub_email: ["secondary@hanmaceng.co.kr"],
secondary_emails: ["secondary@hanmaceng.co.kr"],
aliasEmails: ["secondary@hanmaceng.co.kr"], aliasEmails: ["secondary@hanmaceng.co.kr"],
}, },
}); });

View File

@@ -721,7 +721,7 @@ test.describe("User Management", () => {
await expect(page.locator("input#department")).toHaveCount(0); await expect(page.locator("input#department")).toHaveCount(0);
await expect(page.getByText(/대표 소속/i)).toHaveCount(0); await expect(page.getByText(/대표 소속/i)).toHaveCount(0);
await page.getByRole("button", { name: /^추가$/i }).click(); await page.getByTestId("add-appointment-btn").click();
await expect(page.getByTestId("appointment-row-0")).toBeVisible(); await expect(page.getByTestId("appointment-row-0")).toBeVisible();
await expect( await expect(
page.getByTestId("appointment-tenant-owner-line-0"), page.getByTestId("appointment-tenant-owner-line-0"),