merge: 정보 화면 공통 버튼 통일을 main에 반영
This commit is contained in:
@@ -2,6 +2,7 @@ import { mkdir, writeFile } from 'node:fs/promises';
|
|||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
import { expect, test, type Page, type Route } from '@playwright/test';
|
import { expect, test, type Page, type Route } from '@playwright/test';
|
||||||
|
import { expectLumenButtonStates } from './lumenButton.js';
|
||||||
|
|
||||||
const basePath = `/${(process.env.PLAYWRIGHT_GAME_BASE_PATH ?? 'che').replace(/^\/+|\/+$/g, '')}`;
|
const basePath = `/${(process.env.PLAYWRIGHT_GAME_BASE_PATH ?? 'che').replace(/^\/+|\/+$/g, '')}`;
|
||||||
const artifactRoot = process.env.DIPLOMACY_ARTIFACT_DIR ? resolve(process.env.DIPLOMACY_ARTIFACT_DIR) : null;
|
const artifactRoot = process.env.DIPLOMACY_ARTIFACT_DIR ? resolve(process.env.DIPLOMACY_ARTIFACT_DIR) : null;
|
||||||
@@ -103,7 +104,9 @@ for (const viewport of [
|
|||||||
await expect(card.getByRole('link', { name: '자료' })).toHaveAttribute('href', 'https://example.com');
|
await expect(card.getByRole('link', { name: '자료' })).toHaveAttribute('href', 'https://example.com');
|
||||||
await expect(card.getByRole('link', { name: '자료' })).toHaveAttribute('rel', 'noopener noreferrer nofollow');
|
await expect(card.getByRole('link', { name: '자료' })).toHaveAttribute('rel', 'noopener noreferrer nofollow');
|
||||||
await expect(card.locator('.letter-text script, .letter-text svg, .letter-text math')).toHaveCount(0);
|
await expect(card.locator('.letter-text script, .letter-text svg, .letter-text math')).toHaveCount(0);
|
||||||
await expect(card.locator('.letter-text [onerror], .letter-text [onclick], .letter-text [style]')).toHaveCount(0);
|
await expect(card.locator('.letter-text [onerror], .letter-text [onclick], .letter-text [style]')).toHaveCount(
|
||||||
|
0
|
||||||
|
);
|
||||||
expect(await page.evaluate(() => (globalThis as Record<string, unknown>).__diplomacyXss)).toBeUndefined();
|
expect(await page.evaluate(() => (globalThis as Record<string, unknown>).__diplomacyXss)).toBeUndefined();
|
||||||
|
|
||||||
const geometry = await card.evaluate((element) => {
|
const geometry = await card.evaluate((element) => {
|
||||||
@@ -142,9 +145,7 @@ for (const viewport of [
|
|||||||
}
|
}
|
||||||
|
|
||||||
const send = page.getByRole('button', { name: '전송' });
|
const send = page.getByRole('button', { name: '전송' });
|
||||||
await send.focus();
|
await expectLumenButtonStates(page, send, 'rgb(55, 90, 127)');
|
||||||
await expect(send).toBeFocused();
|
|
||||||
await send.hover();
|
|
||||||
await screenshot(page, `diplomacy-html-${basePath.slice(1)}-${viewport.name}.png`);
|
await screenshot(page, `diplomacy-html-${basePath.slice(1)}-${viewport.name}.png`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { expect, test, type Page, type Route } from '@playwright/test';
|
|||||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||||
import { dirname, resolve } from 'node:path';
|
import { dirname, resolve } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { expectLumenButtonStates } from './lumenButton.js';
|
||||||
|
|
||||||
const response = (data: unknown) => ({ result: { data } });
|
const response = (data: unknown) => ({ result: { data } });
|
||||||
const artifactRoot = process.env.CITY_PARITY_ARTIFACT_DIR;
|
const artifactRoot = process.env.CITY_PARITY_ARTIFACT_DIR;
|
||||||
@@ -493,6 +494,13 @@ test('four legacy menu pages keep the 1000px desktop table contract', async ({ p
|
|||||||
.first()
|
.first()
|
||||||
.evaluate((el) => getComputedStyle(el).borderCollapse)
|
.evaluate((el) => getComputedStyle(el).borderCollapse)
|
||||||
).toBe(borderCollapse);
|
).toBe(borderCollapse);
|
||||||
|
if (path === 'nation/info' || path === 'current-city') {
|
||||||
|
await expectLumenButtonStates(
|
||||||
|
page,
|
||||||
|
page.getByRole('button', { name: '돌아가기' }).first(),
|
||||||
|
'rgb(0, 88, 44)'
|
||||||
|
);
|
||||||
|
}
|
||||||
if (path === 'nation/info') {
|
if (path === 'nation/info') {
|
||||||
await expect(page.locator(selector)).toContainText('작 위호족');
|
await expect(page.locator(selector)).toContainText('작 위호족');
|
||||||
await expect(page.locator(selector)).not.toContainText('작 위1');
|
await expect(page.locator(selector)).not.toContainText('작 위1');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|||||||
import { basename, resolve } from 'node:path';
|
import { basename, resolve } from 'node:path';
|
||||||
import { expect, test, type Locator, type Page, type Route } from '@playwright/test';
|
import { expect, test, type Locator, type Page, type Route } from '@playwright/test';
|
||||||
import { gameBasePath, gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
import { gameBasePath, gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
||||||
|
import { expectLumenButtonStates } from './lumenButton.js';
|
||||||
import { touchDrag } from './touchDrag.js';
|
import { touchDrag } from './touchDrag.js';
|
||||||
|
|
||||||
const response = (data: unknown) => ({ result: { data } });
|
const response = (data: unknown) => ({ result: { data } });
|
||||||
@@ -1320,6 +1321,7 @@ test('내 정보&설정 keeps desktop density and becomes a 390px horizontal-ide
|
|||||||
expect(desktop.customCssHeight).toBe(150);
|
expect(desktop.customCssHeight).toBe(150);
|
||||||
expect(desktop.backgroundImage).toContain('back_walnut.jpg');
|
expect(desktop.backgroundImage).toContain('back_walnut.jpg');
|
||||||
expect(desktop.sectionBackgroundImage).toContain('back_green.jpg');
|
expect(desktop.sectionBackgroundImage).toContain('back_green.jpg');
|
||||||
|
await expectLumenButtonStates(page, page.locator('#set_my_setting'), 'rgb(34, 85, 0)');
|
||||||
await persistParityArtifact(page, 'core-my-page-desktop', desktop);
|
await persistParityArtifact(page, 'core-my-page-desktop', desktop);
|
||||||
|
|
||||||
const defenceSelect = page.locator('select').filter({ has: page.locator('option[value="999"]') });
|
const defenceSelect = page.locator('select').filter({ has: page.locator('option[value="999"]') });
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
|
|
||||||
|
type ButtonGeometry = {
|
||||||
|
top: number;
|
||||||
|
bottom: number;
|
||||||
|
height: number;
|
||||||
|
marginTop: string;
|
||||||
|
borderBottomWidth: string;
|
||||||
|
borderRadius: string;
|
||||||
|
backgroundColor: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const measure = (control: Locator): Promise<ButtonGeometry> =>
|
||||||
|
control.evaluate((element) => {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const style = getComputedStyle(element);
|
||||||
|
return {
|
||||||
|
top: rect.top,
|
||||||
|
bottom: rect.bottom,
|
||||||
|
height: rect.height,
|
||||||
|
marginTop: style.marginTop,
|
||||||
|
borderBottomWidth: style.borderBottomWidth,
|
||||||
|
borderRadius: style.borderRadius,
|
||||||
|
backgroundColor: style.backgroundColor,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export const expectLumenButtonStates = async (
|
||||||
|
page: Page,
|
||||||
|
control: Locator,
|
||||||
|
expectedBackground: string
|
||||||
|
): Promise<{ base: ButtonGeometry; hover: ButtonGeometry; active: ButtonGeometry }> => {
|
||||||
|
await expect(control).toBeVisible();
|
||||||
|
await page.mouse.move(0, 0);
|
||||||
|
const base = await measure(control);
|
||||||
|
expect(base).toMatchObject({
|
||||||
|
marginTop: '0px',
|
||||||
|
borderBottomWidth: '4px',
|
||||||
|
borderRadius: '5.25px',
|
||||||
|
backgroundColor: expectedBackground,
|
||||||
|
});
|
||||||
|
|
||||||
|
await control.hover();
|
||||||
|
const hover = await measure(control);
|
||||||
|
expect(hover).toMatchObject({ marginTop: '1px', borderBottomWidth: '3px' });
|
||||||
|
expect(hover.top).toBeCloseTo(base.top + 1, 1);
|
||||||
|
expect(hover.bottom).toBeCloseTo(base.bottom, 1);
|
||||||
|
|
||||||
|
const box = await control.boundingBox();
|
||||||
|
if (!box) throw new Error('Lumen button is not measurable');
|
||||||
|
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||||
|
await page.mouse.down();
|
||||||
|
const active = await measure(control);
|
||||||
|
expect(active).toMatchObject({ marginTop: '2px', borderBottomWidth: '2px' });
|
||||||
|
expect(active.top).toBeCloseTo(base.top + 2, 1);
|
||||||
|
expect(active.bottom).toBeCloseTo(base.bottom, 1);
|
||||||
|
await page.mouse.move(0, 0);
|
||||||
|
await page.mouse.up();
|
||||||
|
|
||||||
|
await page.keyboard.press('Tab');
|
||||||
|
await control.focus();
|
||||||
|
await expect(control).toBeFocused();
|
||||||
|
await expect.poll(() => control.evaluate((element) => getComputedStyle(element).boxShadow)).not.toBe('none');
|
||||||
|
|
||||||
|
return { base, hover, active };
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { expect, test, type Page, type Route } from '@playwright/test';
|
import { expect, test, type Page, type Route } from '@playwright/test';
|
||||||
|
|
||||||
import { gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
import { gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
||||||
|
import { expectLumenButtonStates } from './lumenButton.js';
|
||||||
|
|
||||||
type Role = 'head' | 'member';
|
type Role = 'head' | 'member';
|
||||||
type AppointmentInput = { destGeneralId: number; destCityId: number; officerLevel: number };
|
type AppointmentInput = { destGeneralId: number; destCityId: number; officerLevel: number };
|
||||||
@@ -352,6 +353,7 @@ test('암행부 행을 도시별로 나누고 수뇌의 인사부 즉시 임명
|
|||||||
await expect(page.locator('.nation-cities-page')).toBeVisible();
|
await expect(page.locator('.nation-cities-page')).toBeVisible();
|
||||||
await expect(page.locator('.city-user-table')).toHaveCount(0);
|
await expect(page.locator('.city-user-table')).toHaveCount(0);
|
||||||
await expect(page.getByRole('button', { name: '인사부 연동' })).toHaveCount(0);
|
await expect(page.getByRole('button', { name: '인사부 연동' })).toHaveCount(0);
|
||||||
|
await expectLumenButtonStates(page, page.getByRole('button', { name: '암행부 연동' }), 'rgb(55, 90, 127)');
|
||||||
|
|
||||||
const citySort = page.locator('#nation-city-sort');
|
const citySort = page.locator('#nation-city-sort');
|
||||||
await expect(citySort).toHaveCSS('background-color', 'rgb(24, 35, 29)');
|
await expect(citySort).toHaveCSS('background-color', 'rgb(24, 35, 29)');
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { mkdir, readFile } from 'node:fs/promises';
|
|||||||
import { dirname, resolve } from 'node:path';
|
import { dirname, resolve } from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
import { gameProfile, gameTrpcRoute } from './gameTestPaths.js';
|
||||||
|
import { expectLumenButtonStates } from './lumenButton.js';
|
||||||
|
|
||||||
type Role = 'leader' | 'head' | 'member';
|
type Role = 'leader' | 'head' | 'member';
|
||||||
type FixtureState = {
|
type FixtureState = {
|
||||||
@@ -290,6 +291,7 @@ test('personnel keeps the desktop frame while exposing row-level appointment con
|
|||||||
await page.setViewportSize({ width: 1000, height: 900 });
|
await page.setViewportSize({ width: 1000, height: 900 });
|
||||||
await gotoOffice(page, 'nation/personnel');
|
await gotoOffice(page, 'nation/personnel');
|
||||||
await expect(page.getByText('작위검증국')).toBeVisible();
|
await expect(page.getByText('작위검증국')).toBeVisible();
|
||||||
|
await expectLumenButtonStates(page, page.locator('.personnel-change-button').first(), 'rgb(49, 91, 61)');
|
||||||
|
|
||||||
const computed = await page.locator('#personnel-container').evaluate((container) => {
|
const computed = await page.locator('#personnel-container').evaluate((container) => {
|
||||||
const box = (selector?: string) => {
|
const box = (selector?: string) => {
|
||||||
@@ -339,7 +341,7 @@ test('personnel keeps the desktop frame while exposing row-level appointment con
|
|||||||
await changeButton.hover();
|
await changeButton.hover();
|
||||||
expect(await changeButton.evaluate((button) => getComputedStyle(button).cursor)).toBe('pointer');
|
expect(await changeButton.evaluate((button) => getComputedStyle(button).cursor)).toBe('pointer');
|
||||||
await changeButton.focus();
|
await changeButton.focus();
|
||||||
expect(await changeButton.evaluate((button) => getComputedStyle(button).outlineStyle)).not.toBe('none');
|
expect(await changeButton.evaluate((button) => getComputedStyle(button).boxShadow)).not.toBe('none');
|
||||||
await expect(page.getByRole('button', { name: '허창 태수 변경하기', exact: true })).toBeVisible();
|
await expect(page.getByRole('button', { name: '허창 태수 변경하기', exact: true })).toBeVisible();
|
||||||
await expect(page.getByRole('button', { name: '허창 군사 변경하기', exact: true })).toHaveCount(0);
|
await expect(page.getByRole('button', { name: '허창 군사 변경하기', exact: true })).toHaveCount(0);
|
||||||
await screenshot(page, 'core-personnel-desktop-leader.png');
|
await screenshot(page, 'core-personnel-desktop-leader.png');
|
||||||
|
|||||||
@@ -92,7 +92,11 @@ const commandBrief = (command: ReservedCommand): string =>
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
도 시 정 보<br /><button class="back-link" type="button" @click="router.push('/')">
|
도 시 정 보<br /><button
|
||||||
|
class="legacy-button legacy-button--navigation back-link"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
돌아가기
|
돌아가기
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -129,7 +133,15 @@ const commandBrief = (command: ReservedCommand): string =>
|
|||||||
<table class="legacy-table legacy-bg0 back-row">
|
<table class="legacy-table legacy-bg0 back-row">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button class="back-link" type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--navigation back-link"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -310,7 +322,15 @@ const commandBrief = (command: ReservedCommand): string =>
|
|||||||
<table class="legacy-table legacy-bg0 footer">
|
<table class="legacy-table legacy-bg0 footer">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button class="back-link" type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--navigation back-link"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="legacy-banner">
|
<td class="legacy-banner">
|
||||||
@@ -457,23 +477,8 @@ const commandBrief = (command: ReservedCommand): string =>
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
.back-link {
|
.back-link {
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #6c757d;
|
|
||||||
border-radius: 0.2rem;
|
|
||||||
background: #6c757d;
|
|
||||||
color: #fff;
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
font-family: var(--sammo-font-sans);
|
font-family: var(--sammo-font-sans);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.back-link:hover,
|
|
||||||
.back-link:focus,
|
|
||||||
.back-link:active {
|
|
||||||
border-color: #565e64;
|
|
||||||
background: #5c636a;
|
|
||||||
color: #fff;
|
|
||||||
}
|
}
|
||||||
.legacy-banner a {
|
.legacy-banner a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|||||||
@@ -260,7 +260,11 @@ onBeforeUnmount(() => {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
외 교 부<br /><button class="legacy-button legacy-button--primary" type="button" @click="router.push('/')">
|
외 교 부<br /><button
|
||||||
|
class="legacy-button legacy-button--navigation"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
돌아가기
|
돌아가기
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -390,7 +394,7 @@ onBeforeUnmount(() => {
|
|||||||
<div class="document-row action-row">
|
<div class="document-row action-row">
|
||||||
<div class="row-label">동작</div>
|
<div class="row-label">동작</div>
|
||||||
<div class="row-content">
|
<div class="row-content">
|
||||||
<button type="button" @click="sendLetter">전송</button>
|
<button class="legacy-button legacy-button--primary" type="button" @click="sendLetter">전송</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input ref="fileInputRef" type="file" accept="image/*" class="hidden" @change="onSelectImage" />
|
<input ref="fileInputRef" type="file" accept="image/*" class="hidden" @change="onSelectImage" />
|
||||||
@@ -577,22 +581,41 @@ onBeforeUnmount(() => {
|
|||||||
<footer class="document-row letter-actions">
|
<footer class="document-row letter-actions">
|
||||||
<div class="row-label">동작</div>
|
<div class="row-label">동작</div>
|
||||||
<div class="row-content">
|
<div class="row-content">
|
||||||
<button v-if="canRespond(letter)" type="button" @click="respondLetter(letter.id, true)">
|
<button
|
||||||
|
v-if="canRespond(letter)"
|
||||||
|
class="legacy-button legacy-button--primary"
|
||||||
|
type="button"
|
||||||
|
@click="respondLetter(letter.id, true)"
|
||||||
|
>
|
||||||
승인
|
승인
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="canRespond(letter)"
|
v-if="canRespond(letter)"
|
||||||
|
class="legacy-button legacy-button--danger"
|
||||||
type="button"
|
type="button"
|
||||||
@click="respondLetter(letter.id, false, '거부')"
|
@click="respondLetter(letter.id, false, '거부')"
|
||||||
>
|
>
|
||||||
거부
|
거부
|
||||||
</button>
|
</button>
|
||||||
<button v-if="canRollback(letter)" type="button" @click="rollbackLetter(letter.id)">
|
<button
|
||||||
|
v-if="canRollback(letter)"
|
||||||
|
class="legacy-button legacy-button--secondary"
|
||||||
|
type="button"
|
||||||
|
@click="rollbackLetter(letter.id)"
|
||||||
|
>
|
||||||
회수
|
회수
|
||||||
</button>
|
</button>
|
||||||
<button v-if="canDestroy(letter)" type="button" @click="destroyLetter(letter.id)">파기</button>
|
<button
|
||||||
|
v-if="canDestroy(letter)"
|
||||||
|
class="legacy-button legacy-button--danger"
|
||||||
|
type="button"
|
||||||
|
@click="destroyLetter(letter.id)"
|
||||||
|
>
|
||||||
|
파기
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="canRenew(letter)"
|
v-if="canRenew(letter)"
|
||||||
|
class="legacy-button legacy-button--secondary"
|
||||||
type="button"
|
type="button"
|
||||||
@click="
|
@click="
|
||||||
selectedPrevId = letter.id;
|
selectedPrevId = letter.id;
|
||||||
@@ -611,10 +634,11 @@ onBeforeUnmount(() => {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<button class="legacy-button legacy-button--primary" type="button" @click="router.push('/')">돌아가기</button
|
<button class="legacy-button legacy-button--navigation" type="button" @click="router.push('/')">
|
||||||
|
돌아가기</button
|
||||||
><br /><br />
|
><br /><br />
|
||||||
삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용, 응용하였습니다 / 제작 :
|
삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용, 응용하였습니다 / 제작 : HideD(hided62@gmail.com)
|
||||||
HideD(hided62@gmail.com) /
|
/
|
||||||
<a href="https://github.com/hided/SamK" target="_blank" rel="noopener noreferrer">Credit</a>
|
<a href="https://github.com/hided/SamK" target="_blank" rel="noopener noreferrer">Credit</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -659,17 +683,6 @@ onBeforeUnmount(() => {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legacy-button {
|
|
||||||
min-height: 34px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border: 1px solid #2d5d7f;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #315f86;
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 700;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
width: 1000px;
|
width: 1000px;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
@@ -749,7 +762,7 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button,
|
.editor-toolbar button,
|
||||||
.diplomacy-view button {
|
.diplomacy-view button:not(.legacy-button) {
|
||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background: #666;
|
background: #666;
|
||||||
@@ -758,16 +771,6 @@ onBeforeUnmount(() => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diplomacy-view .legacy-button {
|
|
||||||
border: 0;
|
|
||||||
border-radius: 5.25px;
|
|
||||||
padding: 5.25px 10.5px;
|
|
||||||
background-color: rgb(55 90 127);
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-toolbar button.active {
|
.editor-toolbar button.active {
|
||||||
background: #315f86;
|
background: #315f86;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,10 +399,14 @@ onMounted(() => {
|
|||||||
<span>내 정 보</span>
|
<span>내 정 보</span>
|
||||||
<div class="title-actions">
|
<div class="title-actions">
|
||||||
<div class="navigation-actions">
|
<div class="navigation-actions">
|
||||||
<RouterLink class="legacy-button" to="/">돌아가기</RouterLink>
|
<RouterLink class="legacy-button legacy-button--navigation" to="/">돌아가기</RouterLink>
|
||||||
<button class="legacy-button" type="button" @click="() => loadPage()">새로고침</button>
|
<button class="legacy-button legacy-button--navigation" type="button" @click="() => loadPage()">
|
||||||
|
새로고침
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<RouterLink class="legacy-button past-plays-link" to="/past-plays">지난 플레이</RouterLink>
|
<RouterLink class="legacy-button legacy-button--secondary past-plays-link" to="/past-plays">
|
||||||
|
지난 플레이
|
||||||
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -491,7 +495,7 @@ onMounted(() => {
|
|||||||
</label>
|
</label>
|
||||||
<button
|
<button
|
||||||
id="set_my_setting"
|
id="set_my_setting"
|
||||||
class="action-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button"
|
||||||
type="button"
|
type="button"
|
||||||
:hidden="!canSave"
|
:hidden="!canSave"
|
||||||
@click="saveSettings"
|
@click="saveSettings"
|
||||||
@@ -508,7 +512,7 @@ onMounted(() => {
|
|||||||
<div v-if="showVacation" class="action-line">
|
<div v-if="showVacation" class="action-line">
|
||||||
휴 가 신 청<br />
|
휴 가 신 청<br />
|
||||||
<button
|
<button
|
||||||
class="action-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button"
|
||||||
type="button"
|
type="button"
|
||||||
@click="confirmMutation('휴가 기능을 신청할까요?', () => trpc.general.vacation.mutate())"
|
@click="confirmMutation('휴가 기능을 신청할까요?', () => trpc.general.vacation.mutate())"
|
||||||
>
|
>
|
||||||
@@ -542,16 +546,27 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="action-button" type="button" @click="changeGeneralIcon">아이콘 변경</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button"
|
||||||
|
type="button"
|
||||||
|
@click="changeGeneralIcon"
|
||||||
|
>
|
||||||
|
아이콘 변경
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="actionAvailability.dieOnPrestart" class="action-line">
|
<div v-if="actionAvailability.dieOnPrestart" class="action-line">
|
||||||
가오픈 기간 내 장수 삭제 ({{ formatDieOnPrestartAvailableAt }} 부터)<br />
|
가오픈 기간 내 장수 삭제 ({{ formatDieOnPrestartAvailableAt }} 부터)<br />
|
||||||
<button class="action-button" @click="dieOnPrestart">장수 삭제</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--danger legacy-button--fixed-height action-button"
|
||||||
|
@click="dieOnPrestart"
|
||||||
|
>
|
||||||
|
장수 삭제
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="actionAvailability.buildNationCandidate" class="action-line">
|
<div v-if="actionAvailability.buildNationCandidate" class="action-line">
|
||||||
서버 개시 이전 거병(2턴부터 건국 가능)<br />
|
서버 개시 이전 거병(2턴부터 건국 가능)<br />
|
||||||
<button
|
<button
|
||||||
class="action-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button"
|
||||||
@click="
|
@click="
|
||||||
confirmMutation(
|
confirmMutation(
|
||||||
'거병 이후 장수를 삭제할 수 없게됩니다. 거병하시겠습니까?',
|
'거병 이후 장수를 삭제할 수 없게됩니다. 거병하시겠습니까?',
|
||||||
@@ -569,7 +584,7 @@ onMounted(() => {
|
|||||||
<div v-if="actionAvailability.instantRetreat" class="action-line">
|
<div v-if="actionAvailability.instantRetreat" class="action-line">
|
||||||
거리 3칸 이내 아국 도시로 즉시 이동<br />
|
거리 3칸 이내 아국 도시로 즉시 이동<br />
|
||||||
<button
|
<button
|
||||||
class="action-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button"
|
||||||
@click="
|
@click="
|
||||||
confirmMutation(
|
confirmMutation(
|
||||||
'아군 접경으로 이동할까요?',
|
'아군 접경으로 이동할까요?',
|
||||||
@@ -588,7 +603,10 @@ onMounted(() => {
|
|||||||
다른 장수 선택
|
다른 장수 선택
|
||||||
<template v-if="formatSelectionAvailableAt"> ({{ formatSelectionAvailableAt }} 부터) </template>
|
<template v-if="formatSelectionAvailableAt"> ({{ formatSelectionAvailableAt }} 부터) </template>
|
||||||
<br />
|
<br />
|
||||||
<RouterLink class="action-button select-general-link" to="/select-general">
|
<RouterLink
|
||||||
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height action-button select-general-link"
|
||||||
|
to="/select-general"
|
||||||
|
>
|
||||||
다른 장수 선택
|
다른 장수 선택
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
@@ -608,7 +626,11 @@ onMounted(() => {
|
|||||||
모바일 레이아웃 순서 바꾸기<br />
|
모바일 레이아웃 순서 바꾸기<br />
|
||||||
<small>500px 메인 화면의 패널 순서를 이 기기에 저장합니다.</small>
|
<small>500px 메인 화면의 패널 순서를 이 기기에 저장합니다.</small>
|
||||||
</span>
|
</span>
|
||||||
<button class="mobile-layout-open" type="button" @click="openMobileLayoutDialog">
|
<button
|
||||||
|
class="legacy-button legacy-button--primary mobile-layout-open"
|
||||||
|
type="button"
|
||||||
|
@click="openMobileLayoutDialog"
|
||||||
|
>
|
||||||
순서 바꾸기
|
순서 바꾸기
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -618,6 +640,7 @@ onMounted(() => {
|
|||||||
<button
|
<button
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
|
class="legacy-button legacy-button--secondary item-button"
|
||||||
type="button"
|
type="button"
|
||||||
:disabled="!item.code"
|
:disabled="!item.code"
|
||||||
@click="dropItem(item)"
|
@click="dropItem(item)"
|
||||||
@@ -654,7 +677,7 @@ onMounted(() => {
|
|||||||
<div v-if="logs[type].length === 0" class="empty">기록이 없습니다.</div>
|
<div v-if="logs[type].length === 0" class="empty">기록이 없습니다.</div>
|
||||||
<button
|
<button
|
||||||
v-if="logHasMore[type]"
|
v-if="logHasMore[type]"
|
||||||
class="load-old"
|
class="legacy-button legacy-button--secondary load-old"
|
||||||
type="button"
|
type="button"
|
||||||
@click="loadLog(type, logs[type].at(-1)?.id)"
|
@click="loadLog(type, logs[type].at(-1)?.id)"
|
||||||
>
|
>
|
||||||
@@ -667,23 +690,21 @@ onMounted(() => {
|
|||||||
삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용, 응용하였습니다 / 제작: HideD / Credit
|
삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용, 응용하였습니다 / 제작: HideD / Credit
|
||||||
</footer>
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
<dialog
|
<dialog ref="mobileLayoutDialog" class="mobile-layout-dialog" aria-labelledby="mobile-layout-dialog-title">
|
||||||
ref="mobileLayoutDialog"
|
|
||||||
class="mobile-layout-dialog"
|
|
||||||
aria-labelledby="mobile-layout-dialog-title"
|
|
||||||
>
|
|
||||||
<div class="mobile-layout-dialog__header">
|
<div class="mobile-layout-dialog__header">
|
||||||
<h2 id="mobile-layout-dialog-title">모바일 레이아웃 순서 바꾸기</h2>
|
<h2 id="mobile-layout-dialog-title">모바일 레이아웃 순서 바꾸기</h2>
|
||||||
<form method="dialog">
|
<form method="dialog">
|
||||||
<button type="submit" aria-label="모바일 레이아웃 순서 창 닫기">×</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary"
|
||||||
|
type="submit"
|
||||||
|
aria-label="모바일 레이아웃 순서 창 닫기"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<p>항목을 끌어 놓거나 위·아래 버튼으로 상대 순서를 바꿉니다.</p>
|
<p>항목을 끌어 놓거나 위·아래 버튼으로 상대 순서를 바꿉니다.</p>
|
||||||
<SortableStringList
|
<SortableStringList v-model:list="mobileLayoutOrder" tag="ol" class="mobile-layout-list">
|
||||||
v-model:list="mobileLayoutOrder"
|
|
||||||
tag="ol"
|
|
||||||
class="mobile-layout-list"
|
|
||||||
>
|
|
||||||
<template #item="{ element: panelId, index }">
|
<template #item="{ element: panelId, index }">
|
||||||
<li :data-mobile-layout-id="panelId">
|
<li :data-mobile-layout-id="panelId">
|
||||||
<span class="mobile-layout-handle" aria-hidden="true">≡</span>
|
<span class="mobile-layout-handle" aria-hidden="true">≡</span>
|
||||||
@@ -693,6 +714,7 @@ onMounted(() => {
|
|||||||
</span>
|
</span>
|
||||||
<span class="mobile-layout-move-buttons">
|
<span class="mobile-layout-move-buttons">
|
||||||
<button
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary"
|
||||||
type="button"
|
type="button"
|
||||||
:aria-label="`${mobileLayoutLabels[panelId]} 위로`"
|
:aria-label="`${mobileLayoutLabels[panelId]} 위로`"
|
||||||
:disabled="index === 0"
|
:disabled="index === 0"
|
||||||
@@ -701,6 +723,7 @@ onMounted(() => {
|
|||||||
↑
|
↑
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary"
|
||||||
type="button"
|
type="button"
|
||||||
:aria-label="`${mobileLayoutLabels[panelId]} 아래로`"
|
:aria-label="`${mobileLayoutLabels[panelId]} 아래로`"
|
||||||
:disabled="index === mobileLayoutOrder.length - 1"
|
:disabled="index === mobileLayoutOrder.length - 1"
|
||||||
@@ -713,9 +736,19 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</SortableStringList>
|
</SortableStringList>
|
||||||
<div class="mobile-layout-dialog__actions">
|
<div class="mobile-layout-dialog__actions">
|
||||||
<button type="button" @click="resetMobileLayoutOrder">기본값</button>
|
<button class="legacy-button legacy-button--secondary" type="button" @click="resetMobileLayoutOrder">
|
||||||
<form method="dialog"><button type="submit">취소</button></form>
|
기본값
|
||||||
<button class="mobile-layout-apply" type="button" @click="applyMobileLayoutOrder">적용</button>
|
</button>
|
||||||
|
<form method="dialog">
|
||||||
|
<button class="legacy-button legacy-button--secondary" type="submit">취소</button>
|
||||||
|
</form>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--primary mobile-layout-apply"
|
||||||
|
type="button"
|
||||||
|
@click="applyMobileLayoutOrder"
|
||||||
|
>
|
||||||
|
적용
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
<div class="my-page-mobile-scroll-spacer" aria-hidden="true"></div>
|
<div class="my-page-mobile-scroll-spacer" aria-hidden="true"></div>
|
||||||
@@ -772,8 +805,7 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
.legacy-button,
|
button:not(.legacy-button),
|
||||||
button,
|
|
||||||
select,
|
select,
|
||||||
textarea {
|
textarea {
|
||||||
border: 1px solid #777;
|
border: 1px solid #777;
|
||||||
@@ -782,15 +814,8 @@ textarea {
|
|||||||
background: #6b6b6b;
|
background: #6b6b6b;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
}
|
}
|
||||||
.legacy-button {
|
.legacy-page .legacy-button,
|
||||||
min-height: 34px;
|
.mobile-layout-dialog .legacy-button {
|
||||||
padding: 5px 10px;
|
|
||||||
border-color: #2d5d7f;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #315f86;
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 700;
|
|
||||||
text-decoration: none;
|
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
@@ -871,10 +896,17 @@ button:disabled {
|
|||||||
color: orange;
|
color: orange;
|
||||||
}
|
}
|
||||||
.action-button {
|
.action-button {
|
||||||
|
--legacy-button-height: 30px;
|
||||||
|
--legacy-button-bg: #225500;
|
||||||
|
--legacy-button-border: #1f4d00;
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: 30px;
|
margin-bottom: 8px;
|
||||||
margin: 4px 0;
|
}
|
||||||
background: #225500;
|
.action-button.legacy-button--danger {
|
||||||
|
--legacy-button-bg: var(--sammo-button-danger-bg);
|
||||||
|
--legacy-button-border: var(--sammo-button-danger-border);
|
||||||
}
|
}
|
||||||
.select-general-link {
|
.select-general-link {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@@ -909,7 +941,6 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
.mobile-layout-open {
|
.mobile-layout-open {
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
background: #315f86;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.mobile-layout-dialog {
|
.mobile-layout-dialog {
|
||||||
@@ -1000,7 +1031,6 @@ button:disabled {
|
|||||||
.mobile-layout-move-buttons button {
|
.mobile-layout-move-buttons button {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
background: #315f86;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.mobile-layout-dialog__actions {
|
.mobile-layout-dialog__actions {
|
||||||
@@ -1013,7 +1043,6 @@ button:disabled {
|
|||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
}
|
}
|
||||||
.mobile-layout-dialog__actions .mobile-layout-apply {
|
.mobile-layout-dialog__actions .mobile-layout-apply {
|
||||||
background: #225500;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.button-group {
|
.button-group {
|
||||||
|
|||||||
@@ -294,7 +294,11 @@ onMounted(async () => {
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
세 력 도 시<br /><button class="back-button" type="button" @click="router.push('/')">
|
세 력 도 시<br /><button
|
||||||
|
class="legacy-button legacy-button--navigation back-button"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
돌아가기
|
돌아가기
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -309,12 +313,18 @@ onMounted(async () => {
|
|||||||
@update:model-value="updateSelectedSort"
|
@update:model-value="updateSelectedSort"
|
||||||
@submit="applySelectedSort"
|
@submit="applySelectedSort"
|
||||||
/>
|
/>
|
||||||
<button type="button" :aria-busy="secretLoading" @click="loadSecretIntegration">
|
<button
|
||||||
|
class="legacy-button legacy-button--primary integration-button"
|
||||||
|
type="button"
|
||||||
|
:aria-busy="secretLoading"
|
||||||
|
@click="loadSecretIntegration"
|
||||||
|
>
|
||||||
암행부 연동
|
암행부 연동
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="secretData"
|
v-if="secretData"
|
||||||
id="load-duty-button"
|
id="load-duty-button"
|
||||||
|
class="legacy-button legacy-button--primary integration-button"
|
||||||
type="button"
|
type="button"
|
||||||
:aria-busy="personnelLoading"
|
:aria-busy="personnelLoading"
|
||||||
@click="loadPersonnelIntegration"
|
@click="loadPersonnelIntegration"
|
||||||
@@ -327,15 +337,69 @@ onMounted(async () => {
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="sort-more">
|
<td class="sort-more">
|
||||||
재 정렬 순서 :
|
재 정렬 순서 :
|
||||||
<button type="button" @click="setExtraSort('name')">도시명</button>
|
<button
|
||||||
<button type="button" @click="setExtraSort('populationRate')">인구율</button>
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
<button type="button" @click="setExtraSort('populationRemain')">남은 주민</button>
|
type="button"
|
||||||
<button type="button" @click="setExtraSort('agricultureRemain')">남은 농업</button>
|
@click="setExtraSort('name')"
|
||||||
<button type="button" @click="setExtraSort('commerceRemain')">남은 상업</button>
|
>
|
||||||
<button type="button" @click="setExtraSort('securityRemain')">남은 치안</button>
|
도시명
|
||||||
<button type="button" @click="setExtraSort('defenceRemain')">남은 수비</button>
|
</button>
|
||||||
<button type="button" @click="setExtraSort('wallRemain')">남은 성벽</button>
|
<button
|
||||||
<button type="button" @click="setExtraSort('generalCount')">배치 장수 수</button>
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('populationRate')"
|
||||||
|
>
|
||||||
|
인구율
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('populationRemain')"
|
||||||
|
>
|
||||||
|
남은 주민
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('agricultureRemain')"
|
||||||
|
>
|
||||||
|
남은 농업
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('commerceRemain')"
|
||||||
|
>
|
||||||
|
남은 상업
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('securityRemain')"
|
||||||
|
>
|
||||||
|
남은 치안
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('defenceRemain')"
|
||||||
|
>
|
||||||
|
남은 수비
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('wallRemain')"
|
||||||
|
>
|
||||||
|
남은 성벽
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--secondary extra-sort-button"
|
||||||
|
type="button"
|
||||||
|
@click="setExtraSort('generalCount')"
|
||||||
|
>
|
||||||
|
배치 장수 수
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -583,7 +647,7 @@ onMounted(async () => {
|
|||||||
v-for="level in [4, 3, 2] as const"
|
v-for="level in [4, 3, 2] as const"
|
||||||
:key="level"
|
:key="level"
|
||||||
type="button"
|
type="button"
|
||||||
class="appointment-button for-duty"
|
class="legacy-button legacy-button--primary appointment-button for-duty"
|
||||||
:class="[`mode-${level}`, { 'chief-target': isChief(general.id) }]"
|
:class="[`mode-${level}`, { 'chief-target': isChief(general.id) }]"
|
||||||
:disabled="
|
:disabled="
|
||||||
!canAppoint(city.id, general.id, level) || pendingAppointment !== ''
|
!canAppoint(city.id, general.id, level) || pendingAppointment !== ''
|
||||||
@@ -642,7 +706,15 @@ onMounted(async () => {
|
|||||||
<table class="legacy-table legacy-bg0 title footer">
|
<table class="legacy-table legacy-bg0 title footer">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button class="back-button" type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--navigation back-button"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="legacy-banner">
|
<td class="legacy-banner">
|
||||||
@@ -786,7 +858,7 @@ onMounted(async () => {
|
|||||||
.footer {
|
.footer {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
.nation-cities-page button:not(.legacy-sort-submit, .legacy-sort-header),
|
.nation-cities-page button:not(.legacy-button, .legacy-sort-submit, .legacy-sort-header),
|
||||||
.nation-cities-page input[type='submit'] {
|
.nation-cities-page input[type='submit'] {
|
||||||
border: 2px outset #fff;
|
border: 2px outset #fff;
|
||||||
background-color: buttonface;
|
background-color: buttonface;
|
||||||
@@ -795,15 +867,16 @@ onMounted(async () => {
|
|||||||
padding: 1px 6px;
|
padding: 1px 6px;
|
||||||
}
|
}
|
||||||
.nation-cities-page .back-button {
|
.nation-cities-page .back-button {
|
||||||
border: 0;
|
margin-bottom: 0;
|
||||||
padding: 5.25px 10.5px;
|
}
|
||||||
background-color: rgb(55 90 127);
|
.nation-cities-page .integration-button,
|
||||||
color: #fff;
|
.nation-cities-page .extra-sort-button,
|
||||||
font-weight: 700;
|
.nation-cities-page .appointment-button {
|
||||||
|
padding: 1px 6px;
|
||||||
line-height: 21px;
|
line-height: 21px;
|
||||||
}
|
}
|
||||||
.sort-more button {
|
.sort-more .extra-sort-button {
|
||||||
margin: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.development-high {
|
.development-high {
|
||||||
color: lightgreen;
|
color: lightgreen;
|
||||||
|
|||||||
@@ -27,7 +27,15 @@ onMounted(async () => {
|
|||||||
<table class="legacy-table title-table legacy-bg0">
|
<table class="legacy-table title-table legacy-bg0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>세 력 정 보<br /><button type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
세 력 정 보<br /><button
|
||||||
|
class="legacy-button legacy-button--navigation"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -110,7 +118,11 @@ onMounted(async () => {
|
|||||||
<table class="legacy-table footer-table legacy-bg0">
|
<table class="legacy-table footer-table legacy-bg0">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
<button class="legacy-button legacy-button--navigation" type="button" @click="router.push('/')">
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="credit">삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용했습니다 / 제작: Hide.D</td>
|
<td class="credit">삼국지 모의전투 HiDCHe / KOEI의 이미지를 사용했습니다 / 제작: Hide.D</td>
|
||||||
@@ -167,15 +179,6 @@ onMounted(async () => {
|
|||||||
.history {
|
.history {
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
.title-table button,
|
|
||||||
.footer-table button {
|
|
||||||
border: 0;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
background: #345c85;
|
|
||||||
color: #fff;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.credit {
|
.credit {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,7 +282,11 @@ onMounted(() => void loadPersonnel());
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
인 사 부<br /><button class="legacy-button" type="button" @click="router.push('/')">
|
인 사 부<br /><button
|
||||||
|
class="legacy-button legacy-button--navigation"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
돌아가기
|
돌아가기
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -338,7 +342,7 @@ onMounted(() => void loadPersonnel());
|
|||||||
<button
|
<button
|
||||||
v-if="canManage && level !== 12 && !chiefLocked(level)"
|
v-if="canManage && level !== 12 && !chiefLocked(level)"
|
||||||
type="button"
|
type="button"
|
||||||
class="personnel-change-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height personnel-change-button"
|
||||||
:aria-label="`${formatOfficerLevelText(level, nationLevel)} 변경하기`"
|
:aria-label="`${formatOfficerLevelText(level, nationLevel)} 변경하기`"
|
||||||
aria-haspopup="dialog"
|
aria-haspopup="dialog"
|
||||||
@click="selectionContext = { kind: 'chief-general', level }"
|
@click="selectionContext = { kind: 'chief-general', level }"
|
||||||
@@ -398,7 +402,13 @@ onMounted(() => void loadPersonnel());
|
|||||||
{{ candidate.name }}
|
{{ candidate.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" @click="changePermissions(true)">임명</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--primary"
|
||||||
|
type="button"
|
||||||
|
@click="changePermissions(true)"
|
||||||
|
>
|
||||||
|
임명
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td class="green-cell permission-label">조언자</td>
|
<td class="green-cell permission-label">조언자</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -416,7 +426,13 @@ onMounted(() => void loadPersonnel());
|
|||||||
{{ candidate.name }}
|
{{ candidate.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" @click="changePermissions(false)">임명</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--primary"
|
||||||
|
type="button"
|
||||||
|
@click="changePermissions(false)"
|
||||||
|
>
|
||||||
|
임명
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -477,7 +493,7 @@ onMounted(() => void loadPersonnel());
|
|||||||
<button
|
<button
|
||||||
v-if="canManage && !cityOfficerLocked(city, level)"
|
v-if="canManage && !cityOfficerLocked(city, level)"
|
||||||
type="button"
|
type="button"
|
||||||
class="personnel-change-button city-change-button"
|
class="legacy-button legacy-button--lumen legacy-button--fixed-height personnel-change-button city-change-button"
|
||||||
:aria-label="`${city.name} ${officerLabels[level]} 변경하기`"
|
:aria-label="`${city.name} ${officerLabels[level]} 변경하기`"
|
||||||
aria-haspopup="dialog"
|
aria-haspopup="dialog"
|
||||||
@click="selectionContext = { kind: 'city-general', level, cityId: city.id }"
|
@click="selectionContext = { kind: 'city-general', level, cityId: city.id }"
|
||||||
@@ -528,7 +544,14 @@ onMounted(() => void loadPersonnel());
|
|||||||
}}/{{ candidate.stats.intelligence }})
|
}}/{{ candidate.stats.intelligence }})
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" :disabled="kickTargetId === 0" @click="kickGeneral">추방</button>
|
<button
|
||||||
|
class="legacy-button legacy-button--danger"
|
||||||
|
type="button"
|
||||||
|
:disabled="kickTargetId === 0"
|
||||||
|
@click="kickGeneral"
|
||||||
|
>
|
||||||
|
추방
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -538,7 +561,15 @@ onMounted(() => void loadPersonnel());
|
|||||||
<table class="legacy-table footer-table">
|
<table class="legacy-table footer-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><button class="legacy-button" type="button" @click="router.push('/')">돌아가기</button></td>
|
<td>
|
||||||
|
<button
|
||||||
|
class="legacy-button legacy-button--navigation"
|
||||||
|
type="button"
|
||||||
|
@click="router.push('/')"
|
||||||
|
>
|
||||||
|
돌아가기
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="legacy-banner">
|
<td class="legacy-banner">
|
||||||
@@ -601,7 +632,7 @@ onMounted(() => void loadPersonnel());
|
|||||||
.heading-table td {
|
.heading-table td {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
button {
|
button:not(.legacy-button) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: 1px solid #6c757d;
|
border: 1px solid #6c757d;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -613,24 +644,10 @@ button {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.legacy-button {
|
button:not(.legacy-button):hover {
|
||||||
display: inline-block;
|
|
||||||
border: 1px solid #325172;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 5.25px 10.5px;
|
|
||||||
color: #fff;
|
|
||||||
background: #375a7f;
|
|
||||||
font: inherit;
|
|
||||||
line-height: 21px;
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
button:hover,
|
|
||||||
.legacy-button:hover {
|
|
||||||
filter: brightness(1.16);
|
filter: brightness(1.16);
|
||||||
}
|
}
|
||||||
button:focus-visible,
|
button:not(.legacy-button):focus-visible,
|
||||||
.legacy-button:focus-visible,
|
|
||||||
select:focus-visible {
|
select:focus-visible {
|
||||||
outline: 2px solid #fff;
|
outline: 2px solid #fff;
|
||||||
outline-offset: 1px;
|
outline-offset: 1px;
|
||||||
@@ -736,18 +753,13 @@ select[multiple] {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.personnel-change-button {
|
.personnel-change-button {
|
||||||
|
--legacy-button-bg: #315b3d;
|
||||||
|
--legacy-button-border: #557d5e;
|
||||||
|
--legacy-button-height: 34px;
|
||||||
grid-area: action;
|
grid-area: action;
|
||||||
min-height: 34px;
|
|
||||||
border-color: #557d5e;
|
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
background: #315b3d;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.personnel-change-button:hover {
|
|
||||||
filter: none;
|
|
||||||
background: #3c704a;
|
|
||||||
border-color: #7ba286;
|
|
||||||
}
|
|
||||||
.personnel-lock-label {
|
.personnel-lock-label {
|
||||||
grid-area: action;
|
grid-area: action;
|
||||||
color: #e7b64c;
|
color: #e7b64c;
|
||||||
|
|||||||
@@ -68,4 +68,31 @@ void describe('shared Lumen button family', () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
void it('connects the information and office page actions to semantic Lumen variants', async () => {
|
||||||
|
const files = {
|
||||||
|
nationCities: await source('views/NationCitiesView.vue'),
|
||||||
|
nationInfo: await source('views/NationInfoView.vue'),
|
||||||
|
currentCity: await source('views/CurrentCityView.vue'),
|
||||||
|
myPage: await source('views/MyPageView.vue'),
|
||||||
|
personnel: await source('views/NationPersonnelView.vue'),
|
||||||
|
diplomacy: await source('views/DiplomacyView.vue'),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.match(files.nationCities, /legacy-button legacy-button--navigation back-button/u);
|
||||||
|
assert.match(files.nationCities, /legacy-button legacy-button--primary integration-button/u);
|
||||||
|
assert.match(files.nationCities, /legacy-button legacy-button--secondary extra-sort-button/u);
|
||||||
|
assert.match(files.nationCities, /legacy-button legacy-button--primary appointment-button/u);
|
||||||
|
assert.match(files.nationInfo, /legacy-button legacy-button--navigation/u);
|
||||||
|
assert.match(files.currentCity, /legacy-button legacy-button--navigation back-link/u);
|
||||||
|
assert.match(files.myPage, /legacy-button legacy-button--navigation/u);
|
||||||
|
assert.match(files.myPage, /legacy-button legacy-button--lumen legacy-button--fixed-height action-button/u);
|
||||||
|
assert.match(files.myPage, /legacy-button legacy-button--secondary item-button/u);
|
||||||
|
assert.match(
|
||||||
|
files.personnel,
|
||||||
|
/legacy-button legacy-button--lumen legacy-button--fixed-height personnel-change-button/u
|
||||||
|
);
|
||||||
|
assert.match(files.personnel, /legacy-button legacy-button--danger/u);
|
||||||
|
assert.match(files.diplomacy, /legacy-button legacy-button--primary[^>]*[\s\S]{0,80}전송/u);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user