feat(ui/ux): unify typography to Pretendard and enforce read-only view mode as default
- Set global font-family to Pretendard and letter-spacing to -0.02em. - Standardized table header font-size to var(--fs-sm). - Fixed table clipping and sticky header behavior at 1920x1080. - Implemented dynamic select options in search filters. - Enforced 'view' mode as default for all asset modals (PC, Server, SW, etc.). - Improved Modal logic to ensure all fields (including dynamic rows) are correctly locked. - Updated Location View detail button from 'Edit' to 'View'. - Updated design_rule.md to reflect new typography standards.
This commit is contained in:
@@ -9,6 +9,7 @@ export abstract class BaseModal {
|
||||
protected title: string;
|
||||
protected currentAsset: any | null = null;
|
||||
protected isEditMode: boolean = false;
|
||||
protected currentMode: 'view' | 'edit' | 'add' = 'view';
|
||||
protected modalEl: HTMLElement | null = null;
|
||||
protected formEl: HTMLFormElement | null = null;
|
||||
|
||||
@@ -53,16 +54,23 @@ export abstract class BaseModal {
|
||||
*/
|
||||
public open(asset: any, mode: 'view' | 'edit' | 'add' = 'view') {
|
||||
this.currentAsset = asset;
|
||||
this.currentMode = mode;
|
||||
this.isEditMode = (mode === 'add' || mode === 'edit');
|
||||
|
||||
// 폼 초기화 추가
|
||||
if (this.formEl) this.formEl.reset();
|
||||
|
||||
this.setEditLockMode(mode);
|
||||
// fillFormData를 먼저 호출하여 동적 요소들을 생성한 후 잠금 처리
|
||||
this.fillFormData(asset);
|
||||
this.setEditLockMode(mode);
|
||||
|
||||
if (this.modalEl) {
|
||||
this.modalEl.classList.remove('hidden');
|
||||
const content = this.modalEl.querySelector('.modal-content');
|
||||
if (content) {
|
||||
if (mode === 'view') content.classList.add('is-view-mode');
|
||||
else content.classList.remove('is-view-mode');
|
||||
}
|
||||
}
|
||||
|
||||
this.onAfterOpen(asset, mode);
|
||||
|
||||
@@ -237,14 +237,15 @@ class HwAssetModal extends BaseModal {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="btn-delete-hw-asset" class="btn btn-outline btn-danger">삭제</button>
|
||||
<div class="footer-actions">
|
||||
<button id="btn-cancel-hw-modal" class="btn btn-outline">닫기</button>
|
||||
<button id="btn-save-hw-asset" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="btn-delete-hw-asset" class="btn btn-outline btn-danger">삭제</button>
|
||||
<div class="footer-actions">
|
||||
<button id="btn-revert-hw-edit" class="btn btn-outline hidden">수정 취소</button>
|
||||
<button id="btn-cancel-hw-modal" class="btn btn-outline">닫기</button>
|
||||
<button id="btn-save-hw-asset" class="btn btn-primary">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.hidden {
|
||||
@@ -370,6 +371,12 @@ class HwAssetModal extends BaseModal {
|
||||
saveBtn.addEventListener('click', async () => {
|
||||
if (!this.currentAsset) return;
|
||||
|
||||
// [추가] 조회 모드인 경우 수정 모드로 전환
|
||||
if (!this.isEditMode) {
|
||||
this.open(this.currentAsset, 'edit');
|
||||
return;
|
||||
}
|
||||
|
||||
// 동적 볼륨 데이터 수집
|
||||
const vols: any[] = [];
|
||||
document.querySelectorAll('#hw-volume-container .volume-row').forEach((row, idx) => {
|
||||
|
||||
@@ -255,19 +255,13 @@ class JobSpecModal extends BaseModal {
|
||||
|
||||
deleteBtn.style.display = (mode === 'add') ? 'none' : 'block';
|
||||
|
||||
if (mode === 'add') {
|
||||
this.setEditLockMode('edit');
|
||||
this.isEditMode = true;
|
||||
saveBtn.textContent = '등록';
|
||||
if (mode === 'add' || mode === 'edit') {
|
||||
saveBtn.textContent = (mode === 'add') ? '등록' : '저장';
|
||||
saveBtn.style.display = 'block';
|
||||
} else {
|
||||
this.setEditLockMode('view');
|
||||
this.isEditMode = false;
|
||||
saveBtn.textContent = '수정';
|
||||
saveBtn.style.display = 'block';
|
||||
}
|
||||
|
||||
this.updateMinScore();
|
||||
this.updateHeaderIdentity(asset);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,42 +110,43 @@ export function setEditLock(
|
||||
const generateBtn = options.generateBtnId ? document.getElementById(options.generateBtnId) : null;
|
||||
const addLogBtn = options.addLogBtnId ? document.getElementById(options.addLogBtnId) : null;
|
||||
|
||||
if (!form || !saveBtn || !revertBtn) return;
|
||||
if (!form) return;
|
||||
|
||||
if (mode === 'add' || mode === 'edit') {
|
||||
const isEdit = (mode === 'add' || mode === 'edit');
|
||||
|
||||
if (isEdit) {
|
||||
// 편집 모드 활성화
|
||||
form.classList.remove('is-view-mode');
|
||||
form.classList.add('is-edit-mode');
|
||||
saveBtn.textContent = '저장';
|
||||
revertBtn.classList.toggle('hidden', mode === 'add');
|
||||
if (saveBtn) saveBtn.textContent = (mode === 'add' ? '등록' : '저장');
|
||||
if (revertBtn) revertBtn.classList.toggle('hidden', mode === 'add');
|
||||
|
||||
// 모든 필드 활성화
|
||||
const inputs = form.querySelectorAll('input, select, textarea');
|
||||
inputs.forEach(input => {
|
||||
const el = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
||||
if (el.name !== 'asset_code' && !el.id.includes('asset-id')) { // 자산번호 등 일부는 편집 모드에서도 잠금 유지
|
||||
// 자산번호 및 ID 필드는 편집 모드에서도 잠금 유지
|
||||
if (el.name !== 'asset_code' && !el.id.includes('asset-id') && !el.id.includes('id-hidden')) {
|
||||
el.disabled = false;
|
||||
if ('readOnly' in el) (el as HTMLInputElement).readOnly = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 번호 생성 버튼은 '추가(add)' 시에만 노출
|
||||
if (generateBtn) {
|
||||
generateBtn.style.display = mode === 'add' ? 'flex' : 'none';
|
||||
}
|
||||
if (generateBtn) generateBtn.style.display = (mode === 'add' ? 'flex' : 'none');
|
||||
if (addLogBtn) addLogBtn.style.display = 'flex';
|
||||
} else {
|
||||
// 조회 모드 (잠금)
|
||||
form.classList.remove('is-edit-mode');
|
||||
form.classList.add('is-view-mode');
|
||||
saveBtn.textContent = '수정';
|
||||
revertBtn.classList.add('hidden');
|
||||
if (saveBtn) saveBtn.textContent = '수정';
|
||||
if (revertBtn) revertBtn.classList.add('hidden');
|
||||
|
||||
// 모든 필드 잠금
|
||||
const inputs = form.querySelectorAll('input, select, textarea');
|
||||
inputs.forEach(input => {
|
||||
const el = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
||||
el.disabled = true; // select의 경우 disabled 필요
|
||||
el.disabled = true;
|
||||
if ('readOnly' in el) (el as HTMLInputElement).readOnly = true;
|
||||
});
|
||||
|
||||
if (generateBtn) generateBtn.style.display = 'none';
|
||||
|
||||
@@ -137,14 +137,10 @@ class PartsMasterModal extends BaseModal {
|
||||
|
||||
deleteBtn.style.display = (mode === 'add') ? 'none' : 'block';
|
||||
|
||||
if (mode === 'add') {
|
||||
this.setEditLockMode('edit');
|
||||
this.isEditMode = true;
|
||||
saveBtn.textContent = '등록';
|
||||
if (mode === 'add' || mode === 'edit') {
|
||||
saveBtn.textContent = (mode === 'add') ? '등록' : '저장';
|
||||
saveBtn.style.display = 'block';
|
||||
} else {
|
||||
this.setEditLockMode('view');
|
||||
this.isEditMode = false;
|
||||
saveBtn.textContent = '수정';
|
||||
saveBtn.style.display = 'block';
|
||||
}
|
||||
|
||||
@@ -144,14 +144,10 @@ class UserModal extends BaseModal {
|
||||
|
||||
deleteBtn.style.display = (mode === 'add') ? 'none' : 'block';
|
||||
|
||||
if (mode === 'add') {
|
||||
this.setEditLockMode('edit');
|
||||
this.isEditMode = true;
|
||||
saveBtn.textContent = '등록';
|
||||
if (mode === 'add' || mode === 'edit') {
|
||||
saveBtn.textContent = mode === 'add' ? '등록' : '저장';
|
||||
saveBtn.style.display = 'block';
|
||||
} else {
|
||||
this.setEditLockMode('view');
|
||||
this.isEditMode = false;
|
||||
saveBtn.textContent = '수정';
|
||||
saveBtn.style.display = 'block';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user