fix(ui): Gateway 관리자 메뉴와 로비 복귀 링크 겹침 수정
This commit is contained in:
@@ -8,7 +8,7 @@ const operationNames = (route: Route): string[] => {
|
|||||||
return decodeURIComponent(url.pathname.slice(url.pathname.lastIndexOf('/trpc/') + 6)).split(',');
|
return decodeURIComponent(url.pathname.slice(url.pathname.lastIndexOf('/trpc/') + 6)).split(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
const installGatewayFixture = async (page: Page, roles: string[]) => {
|
const installGatewayFixture = async (page: Page, roles: string[], manyProfiles = false) => {
|
||||||
const requests: Array<{ method: string; url: string; body: unknown }> = [];
|
const requests: Array<{ method: string; url: string; body: unknown }> = [];
|
||||||
await page.addInitScript(() => {
|
await page.addInitScript(() => {
|
||||||
window.localStorage.setItem('sammo-session-token', 'playwright-admin-session');
|
window.localStorage.setItem('sammo-session-token', 'playwright-admin-session');
|
||||||
@@ -62,6 +62,16 @@ const installGatewayFixture = async (page: Page, roles: string[]) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (operation === 'admin.profiles.listNavigation') {
|
if (operation === 'admin.profiles.listNavigation') {
|
||||||
|
if (manyProfiles)
|
||||||
|
return response(
|
||||||
|
['che', 'kwe', 'twe', 'hwe', 'nya', 'pwe', 'pya'].map((profile) => ({
|
||||||
|
profileName: `${profile}:default`,
|
||||||
|
profile,
|
||||||
|
instanceKey: 'default',
|
||||||
|
displayName: `${profile.toUpperCase()} 서버`,
|
||||||
|
currentScenario: '1010',
|
||||||
|
}))
|
||||||
|
);
|
||||||
return response(
|
return response(
|
||||||
roles.some((role) => role === 'superuser' || role.includes(':hwe:2'))
|
roles.some((role) => role === 'superuser' || role.includes(':hwe:2'))
|
||||||
? [
|
? [
|
||||||
@@ -378,3 +388,54 @@ test('scoped administrators see the same navigation while ordinary users do not'
|
|||||||
await expect(userPage.getByRole('link', { name: '관리자 페이지' })).toHaveCount(0);
|
await expect(userPage.getByRole('link', { name: '관리자 페이지' })).toHaveCount(0);
|
||||||
await userContext.close();
|
await userContext.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const viewport of [
|
||||||
|
{ width: 1280, height: 720 },
|
||||||
|
{ width: 1200, height: 500 },
|
||||||
|
{ width: 390, height: 844 },
|
||||||
|
]) {
|
||||||
|
test(`administrator exit stays separate from seven-profile navigation at ${viewport.width}x${viewport.height}`, async ({
|
||||||
|
page,
|
||||||
|
}, testInfo) => {
|
||||||
|
await page.setViewportSize(viewport);
|
||||||
|
await installGatewayFixture(page, ['superuser'], true);
|
||||||
|
await page.goto('admin');
|
||||||
|
if (viewport.width < 860) await page.getByRole('button', { name: '관리자 메뉴' }).click();
|
||||||
|
else await page.evaluate(() => window.scrollTo(0, 76));
|
||||||
|
const nav = page.getByRole('navigation', { name: '관리자 메뉴' });
|
||||||
|
await expect(nav.getByRole('link', { name: 'PYA 서버' })).toBeVisible();
|
||||||
|
const lastLink = nav.getByRole('link', { name: '감사 로그' });
|
||||||
|
await lastLink.scrollIntoViewIfNeeded();
|
||||||
|
await lastLink.focus();
|
||||||
|
await expect(lastLink).toBeFocused();
|
||||||
|
const exit = page.getByRole('link', { name: '← 로비로 돌아가기', exact: true });
|
||||||
|
await exit.scrollIntoViewIfNeeded();
|
||||||
|
const geometry = await page.locator('#admin-navigation').evaluate((sidebar) => {
|
||||||
|
const nav = sidebar.querySelector('nav')!;
|
||||||
|
const exit = sidebar.querySelector('.admin-exit')!;
|
||||||
|
const last = sidebar.querySelector('.admin-nav-group:last-child .admin-nav-link:last-child')!;
|
||||||
|
return {
|
||||||
|
navBottom: nav.getBoundingClientRect().bottom,
|
||||||
|
exitTop: exit.getBoundingClientRect().top,
|
||||||
|
lastBottom: last.getBoundingClientRect().bottom,
|
||||||
|
width: document.documentElement.scrollWidth,
|
||||||
|
navHeight: nav.clientHeight,
|
||||||
|
navScrollHeight: nav.scrollHeight,
|
||||||
|
exitPosition: getComputedStyle(exit).position,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
expect(geometry.navBottom).toBeLessThanOrEqual(geometry.exitTop);
|
||||||
|
expect(geometry.lastBottom).toBeLessThanOrEqual(geometry.exitTop);
|
||||||
|
expect(geometry.width).toBeLessThanOrEqual(viewport.width);
|
||||||
|
if (viewport.width >= 860) expect(geometry.navScrollHeight).toBeGreaterThan(geometry.navHeight);
|
||||||
|
await page.evaluate(() => document.fonts.ready);
|
||||||
|
await writeFile(testInfo.outputPath('sidebar-geometry.json'), JSON.stringify(geometry));
|
||||||
|
await writeFile(testInfo.outputPath('sidebar.html'), await page.content());
|
||||||
|
await page.screenshot({ path: testInfo.outputPath('sidebar.png'), fullPage: true });
|
||||||
|
await exit.hover();
|
||||||
|
await exit.focus();
|
||||||
|
await expect(exit).toBeFocused();
|
||||||
|
await exit.click();
|
||||||
|
await expect(page).toHaveURL(/\/gateway\/lobby$/);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -212,12 +212,22 @@ onMounted(async () => {
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
border-right: 1px solid #27272a;
|
border-right: 1px solid #27272a;
|
||||||
background: #111113;
|
background: #111113;
|
||||||
padding: 24px 16px;
|
padding: 24px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-sidebar > nav {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior-y: contain;
|
||||||
|
}
|
||||||
|
|
||||||
.admin-identity {
|
.admin-identity {
|
||||||
|
flex-shrink: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 11px;
|
gap: 11px;
|
||||||
@@ -317,10 +327,9 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.admin-exit {
|
.admin-exit {
|
||||||
position: absolute;
|
flex-shrink: 0;
|
||||||
right: 24px;
|
display: block;
|
||||||
bottom: 24px;
|
margin: 16px 8px 0;
|
||||||
left: 24px;
|
|
||||||
border-top: 1px solid #27272a;
|
border-top: 1px solid #27272a;
|
||||||
padding-top: 17px;
|
padding-top: 17px;
|
||||||
color: #71717a;
|
color: #71717a;
|
||||||
@@ -418,6 +427,10 @@ onMounted(async () => {
|
|||||||
padding: 18px 14px 14px;
|
padding: 18px 14px 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.admin-sidebar > nav {
|
||||||
|
overflow-y: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.admin-sidebar.open {
|
.admin-sidebar.open {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user