feat(설정): 357-1·2 저장 버튼 [닫기]와 같은 크기 · 저장하면 바로 닫힘 · 단축키 탭 한 줄씩(입력 = 동작) · 키 칩

- 단추 → 버튼 (마우스 · 다른 곳 단축키 글)
- test_app_settings 저장 뒤 닫힘으로 고침

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013QyNXY2TUKXCFMwAca2APG
This commit is contained in:
2026-10-16 20:38:46 +09:00
co-authored by Claude Sonnet 5.5
parent ec02165954
commit cadff2af90
4 changed files with 93 additions and 43 deletions
+33
View File
@@ -51,3 +51,36 @@
.app-settings__error:empty {
display: none;
}
.app-settings__rules {
margin: 0 0 var(--spacing-8);
padding: 0;
list-style: none;
}
.app-settings__rules > li {
display: grid;
grid-template-columns: minmax(0, 15em) 1fr;
align-items: center;
gap: var(--spacing-12);
padding: var(--spacing-4) 0;
border-bottom: 1px solid var(--color-border);
white-space: nowrap;
}
.app-settings__keys {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-4);
}
.app-settings__keys > kbd {
padding: 0 var(--spacing-8);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-surface-raised);
color: var(--color-text);
font-family: var(--font-mono);
font-size: 0.85em;
line-height: 1.7;
}
+26 -11
View File
@@ -37,7 +37,7 @@ const MOUSE_RULES: LocaleKey[] = [
"App_Settings_Rule_Pinch",
];
/** ③ 안내표 줄 — [자리, 키] */
/** ③ 안내 — [자리, 키] */
const KEY_ROWS: [LocaleKey, LocaleKey][] = [
["App_Settings_Keys_All", "App_Settings_Keys_All_Keys"],
["App_Settings_Keys_Profile", "App_Settings_Keys_Profile_Keys"],
@@ -55,6 +55,26 @@ const normalize = (p: InputPrefs): InputPrefs => ({
});
const snapshot = (p: InputPrefs): string => JSON.stringify(normalize(p));
/** 규칙 목록 — 한 줄 = 「입력 = 동작」 · 입력은 키 칩(` · ` 로 여럿) · 동작 없는 줄은 칩만 */
function ruleList(keys: LocaleKey[]): HTMLElement {
const items = keys
.flatMap((key) => L(key).split("\n"))
.map((line) => {
const at = line.indexOf(" = ");
const input = at < 0 ? line : line.slice(0, at);
return el("li", {
children: [
el("span", {
className: "app-settings__keys",
children: input.split(" · ").map((text) => el("kbd", { text })),
}),
...(at < 0 ? [] : [el("span", { text: line.slice(at + 3) })]),
],
});
});
return el("ul", { className: "app-settings__rules", children: items });
}
function mouseTab(draft: InputPrefs): HTMLElement {
const group = el("div", {
className: "app-settings__radios",
@@ -73,18 +93,14 @@ function mouseTab(draft: InputPrefs): HTMLElement {
el("h4", { text: L("App_Settings_Wheel") }),
group,
el("h4", { text: L("App_Settings_Rules") }),
el("ul", { children: MOUSE_RULES.map((key) => el("li", { text: L(key) })) }),
ruleList(MOUSE_RULES),
],
});
}
function keysTab(): HTMLElement {
const rows = KEY_ROWS.map(([place, keys]) =>
el("tr", { children: [el("th", { text: L(place) }), el("td", { text: L(keys) })] }),
);
return el("table", {
className: "app-settings__table",
children: [el("tbody", { children: rows })],
return el("div", {
children: KEY_ROWS.flatMap(([place, keys]) => [el("h4", { text: L(place) }), ruleList([keys])]),
});
}
@@ -138,10 +154,9 @@ export function openAppSettings(): void {
const saveButton = createButton({
label: L("Common_Btn_Save"),
variant: "filled",
size: "sm",
onClick: () => void save(),
onClick: () => save() && modal.close(),
});
openModal({
const modal = openModal({
title: L("App_Settings"),
closeLabel: L("Common_Btn_Close"),
dialogClass: "app-settings",
+11 -10
View File
@@ -140,16 +140,16 @@ def test_설정_창_탭_저장_물음():
page.click(".ui-confirm button >> nth=0") # 취소
assert page.locator(".app-settings").count() == 1 and _writes(page) == []
# [저장] = 한 번 씀 · 읽기 층 방향 뒤집힘 · 닫을 때 안 물음
# [저장] = 한 번 씀 · 바로 닫힘(물음 없음) · 읽기 층 방향 뒤집힘
_save(page)
assert page.locator(".app-settings").count() == 0
assert page.locator(".ui-confirm").count() == 0
assert len(_writes(page)) == 1
assert json.loads(_writes(page)[0]) == {"wheelZoom": "pull", "cadAliases": {}}
assert page.evaluate(WHEEL_IN, 100) is True and page.evaluate(WHEEL_IN, -100) is False
_save(page) # 고친 것 없음 — 또 안 씀
assert len(_writes(page)) == 1
_close(page)
assert page.locator(".app-settings").count() == 0
assert page.locator(".ui-confirm").count() == 0
_open_settings(page)
_save(page) # 고친 것 없음 — 또 안 씀 · 닫힘
assert len(_writes(page)) == 1 and page.locator(".app-settings").count() == 0
# CAD 별칭 — 잘못이면 안 씀 · 칸 표시
_open_settings(page)
@@ -163,25 +163,26 @@ def test_설정_창_탭_저장_물음():
_save(page)
assert page.inner_text(".app-settings__error").strip(), (line_v, circle_v)
assert page.locator(".app-settings input[aria-invalid=true]").count() >= 1
assert len(_writes(page)) == 1
assert len(_writes(page)) == 1 and page.locator(".app-settings").count() == 1 # 창 남음
page.fill(line, "ll")
page.fill(circle, "")
_save(page)
assert page.inner_text(".app-settings__error").strip() == ""
assert page.locator(".app-settings").count() == 0 # 저장 성공 = 닫힘
assert len(_writes(page)) == 2
assert json.loads(_writes(page)[1]) == {"wheelZoom": "pull", "cadAliases": {"LINE": ["LL"]}}
# 닫을 때 물음 — 버림 = 안 씀 · 저장 = 한 번 더
_open_settings(page)
page.click("[data-settings-tab=mouse]")
page.check("input[name=app-settings-wheel][value=push]")
_close(page)
page.click(".ui-confirm button >> nth=1") # 버리고 넘어감
page.click(".ui-confirm button >> nth=1") # 폐기
assert page.locator(".app-settings").count() == 0 and len(_writes(page)) == 2
assert page.evaluate(WHEEL_IN, 100) is True
_open_settings(page)
page.check("input[name=app-settings-wheel][value=push]")
_close(page)
page.click(".ui-confirm button >> nth=2") # 저장 후 넘어감
page.click(".ui-confirm button >> nth=2") # 저장
assert page.locator(".app-settings").count() == 0 and len(_writes(page)) == 3
assert json.loads(_writes(page)[2])["wheelZoom"] == "push"
assert page.evaluate(WHEEL_IN, 100) is False
+23 -22
View File
@@ -40,7 +40,7 @@ export const ui_locales_common = {
* ------------------------------------------------------------------------ */
Common_Status_Loading: ["불러오는 중...", "Loading..."],
Common_Load_Failed: ["불러오지 못함", "Failed to load"],
Common_Reload: ["다시 불러오기", "Reload"],
Common_Reload: ["새로고침", "Reload"],
Common_Status_Saving: ["저장 중...", "Saving..."],
Common_Status_Processing: ["처리 중...", "Processing..."],
Common_Status_Success: ["완료되었습니다", "Completed"],
@@ -117,16 +117,17 @@ export const ui_locales_common = {
App_Settings_Wheel: ["휠 확대 방향(모든 화면)", "Wheel zoom-in direction (all views)"],
App_Settings_Wheel_Pull: ["당기면 확대(휠을 몸 쪽으로)", "Pull to zoom in (wheel toward you)"],
App_Settings_Wheel_Push: ["밀면 확대(휠을 앞으로)", "Push to zoom in (wheel away)"],
App_Settings_Rules: ["마우스 단추", "Mouse buttons"],
App_Settings_Rule_Pan: ["화면 옮기기 = 가운데 단추 끌기", "Pan = drag with the middle button"],
App_Settings_Rule_Pick: ["고르기 = 왼쪽 단추", "Select = left button"],
/* 아래 규칙 값 = 한 줄에 「입력 = 동작」 · 줄바꿈(\n)으로 줄 나눔 · ko · en 줄 수 같게 */
App_Settings_Rules: ["마우스 버튼", "Mouse buttons"],
App_Settings_Rule_Pan: ["가운데 버튼 끌기 = 화면 옮김", "Middle button drag = pan"],
App_Settings_Rule_Pick: ["왼쪽 버튼 = 고르기", "Left button = select"],
App_Settings_Rule_Right: [
"오른쪽 단추 = 메뉴 · CAD 에서는 명령 중 Enter · 쉴 때 반복 · Shift = 스냅 메뉴 · CAD 휠 두 번 = 범위",
"Right button = menu · in CAD Enter during a command · repeat when idle · Shift = snap menu · CAD wheel double-click = extents",
"오른쪽 버튼 = 메뉴\n오른쪽 버튼(CAD 명령 중) = Enter\n오른쪽 버튼(CAD 쉴 때) = 반복\nShift+오른쪽 버튼(CAD) = 스냅 메뉴\n휠 두 번 누름(CAD) = 범위",
"Right button = menu\nRight button (CAD, during a command) = Enter\nRight button (CAD, idle) = repeat\nShift+right button (CAD) = snap menu\nWheel double-click (CAD) = extents",
],
App_Settings_Rule_Pinch: [
"트랙패드 · 손가락 벌림 = 늘 확대(휠 방향과 상관없음)",
"Trackpad · finger spread = always zoom in (whatever the wheel direction)",
"트랙패드 손가락 벌림 = 늘 확대(휠 방향 무관)",
"Trackpad finger spread = always zoom in (any wheel direction)",
],
App_Settings_Cad_Help: [
"CAD 는 명령 이름 > 내 별칭 > 기본 별칭 차례로 찾음 · 영문 · 숫자만 · 여러 개는 쉼표로",
@@ -144,38 +145,38 @@ export const ui_locales_common = {
App_Settings_Leave: ["저장 안 한 설정이 있음", "You have unsaved settings"],
App_Settings_Keys_All: ["모든 화면", "All views"],
App_Settings_Keys_All_Keys: [
"Esc = ☰ · 창 닫기 · 고름 풀기 · Z 누른 채 또는 오른쪽 0.4초 누름 = 돋보기(휠 = 배율)",
"Esc = ☰ · close window · clear selection · hold Z or right button 0.4 s = loupe (wheel = zoom)",
"Esc = ☰ · 창 닫기 · 고름 풀기\nZ 누른 채 = 돋보기\n오른쪽 버튼 0.4초 누름 = 돋보기\n돋보기 중 휠 = 배율",
"Esc = ☰ · close window · clear selection\nHold Z = loupe\nRight button 0.4 s = loupe\nWheel in loupe = zoom",
],
App_Settings_Keys_Profile: ["B05 종단", "B05 profile"],
App_Settings_Keys_Profile_Keys: [
"Ctrl+Z 되돌림 · Ctrl+Shift+Z 다시 · 방향키 = 옮김 · 자유지정 Enter = 끝 · Esc · Backspace",
"Ctrl+Z undo · Ctrl+Shift+Z redo · arrows = move · free mode Enter = finish · Esc · Backspace",
"Ctrl+Z = 되돌림\nCtrl+Shift+Z = 다시\n방향키 = 옮김\nEnter(자유지정) = 끝\nEsc · Backspace",
"Ctrl+Z = undo\nCtrl+Shift+Z = redo\nArrows = move\nEnter (free mode) = finish\nEsc · Backspace",
],
App_Settings_Keys_RouteEdit: ["B05 노선 편집", "B05 route edit"],
App_Settings_Keys_RouteEdit_Keys: [
"Ctrl+Z 되돌림 · Ctrl+Y · Ctrl+Shift+Z 다시",
"Ctrl+Z undo · Ctrl+Y · Ctrl+Shift+Z redo",
"Ctrl+Z = 되돌림\nCtrl+Y = 다시\nCtrl+Shift+Z = 다시",
"Ctrl+Z = undo\nCtrl+Y = redo\nCtrl+Shift+Z = redo",
],
App_Settings_Keys_Section: ["B06 횡단", "B06 cross section"],
App_Settings_Keys_Section_Keys: [
"방향키 · ▲▼ = 측점 옮김 · Enter · Space = 고름 · Esc",
"Arrows · ▲▼ = move station · Enter · Space = pick · Esc",
"방향키 = 측점 옮김\n▲▼ = 측점 옮김\nEnter = 고름\nSpace = 고름\nEsc",
"Arrows = move station\n▲▼ = move station\nEnter = pick\nSpace = pick\nEsc",
],
App_Settings_Keys_Cad: ["CAD", "CAD"],
App_Settings_Keys_Cad_Keys: [
"F3 스냅 · F7 그리드 · F8 직교 · F10 45° · Ctrl+Z · Ctrl+Y · Ctrl+A · Ctrl+S(M02) · Delete · Esc · Enter · Space = Enter · ↑↓ = 기록 · 최근 값 · Ctrl+C · X · 1 · ← → · Shift+↑↓ = 화면 옮김 · 글자 = 명령",
"F3 snap · F7 grid · F8 ortho · F10 45° · Ctrl+Z · Ctrl+Y · Ctrl+A · Ctrl+S (M02) · Delete · Esc · Enter · Space = Enter · ↑↓ = history · recent values · Ctrl+C · X · 1 · ← → · Shift+↑↓ = pan · letters = command",
"F3 = 스냅\nF7 = 그리드\nF8 = 직교\nF10 = 45°\nCtrl+Z = 되돌림\nCtrl+Y = 다시\nCtrl+S(M02) = 저장\nSpace = Enter\n↑↓ = 기록 · 최근 값\nShift+↑↓ = 화면 옮김\n글자 = 명령\nCtrl+A · Delete · Esc · Enter · Ctrl+C · X · 1 · ← →",
"F3 = snap\nF7 = grid\nF8 = ortho\nF10 = 45°\nCtrl+Z = undo\nCtrl+Y = redo\nCtrl+S (M02) = save\nSpace = Enter\n↑↓ = history · recent values\nShift+↑↓ = pan\nLetters = command\nCtrl+A · Delete · Esc · Enter · Ctrl+C · X · 1 · ← →",
],
App_Settings_Keys_Table: ["B08 · B09 표", "B08 · B09 tables"],
App_Settings_Keys_Table_Keys: [
"Enter · F2 = 입력 · 방향키 = 칸 옮김 · Esc = 그만",
"Enter · F2 = edit · arrows = move cell · Esc = cancel",
"Enter = 입력\nF2 = 입력\n방향키 = 칸 옮김\nEsc = 그만",
"Enter = edit\nF2 = edit\nArrows = move cell\nEsc = cancel",
],
App_Settings_Keys_M02: ["M02 양식", "M02 templates"],
App_Settings_Keys_M02_Keys: [
"Ctrl+S 저장 · Ctrl+C · Ctrl+V · Delete · Esc · Space+끌기 = 화면 옮김 · Ctrl+휠 = 배율 · 시트 = 엑셀 키",
"Ctrl+S save · Ctrl+C · Ctrl+V · Delete · Esc · Space+drag = pan · Ctrl+wheel = zoom · sheet = Excel keys",
"Ctrl+S = 저장\nSpace+끌기 = 화면 옮김\nCtrl+휠 = 배율\n시트 안 = 엑셀 키 그대로\nCtrl+C · Ctrl+V · Delete · Esc",
"Ctrl+S = save\nSpace+drag = pan\nCtrl+wheel = zoom\nInside a sheet = Excel keys\nCtrl+C · Ctrl+V · Delete · Esc",
],
App_Footer_Copyright: [
"© 2026 임도설계 및 견적 자동화. All rights reserved.",