feat: add monthly history controls for organization view
This commit is contained in:
@@ -8,6 +8,7 @@ let emptyStateMessage = '서버에 조직 데이터가 없습니다. 상단의
|
||||
let photoPreviewObjectUrl = null;
|
||||
let seatMapLayoutCache = null;
|
||||
let activeAsOfDate = '';
|
||||
let isHistoricalSnapshot = false;
|
||||
const listViewState = {
|
||||
mode: 'current',
|
||||
snapshotDate: '',
|
||||
@@ -165,7 +166,7 @@ async function loadMembers(message) {
|
||||
if (message) {
|
||||
emptyStateMessage = message;
|
||||
}
|
||||
const payload = await apiFetch('/api/members');
|
||||
const payload = await apiFetch(withAsOf('/api/members'));
|
||||
setMembers(payload.items || []);
|
||||
if (!members.length) {
|
||||
emptyStateMessage = '서버에 조직 데이터가 없습니다. 상단의 업로드 버튼으로 초기 데이터를 넣어주세요.';
|
||||
@@ -185,7 +186,7 @@ async function loadSeatMapLayouts(force = false) {
|
||||
if (!seatMap?.id) {
|
||||
return null;
|
||||
}
|
||||
return await apiFetch(`/api/seat-maps/${seatMap.id}/layout`);
|
||||
return await apiFetch(withAsOf(`/api/seat-maps/${seatMap.id}/layout`));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
@@ -643,6 +644,10 @@ function render() {
|
||||
}
|
||||
|
||||
function toggleAdminMode(checked) {
|
||||
if (checked && isHistoricalSnapshot) {
|
||||
alert('월말 히스토리 조회 중에는 수정할 수 없습니다. 최신 월로 돌아간 뒤 수정해주세요.');
|
||||
return;
|
||||
}
|
||||
isAdmin = checked;
|
||||
const button = document.getElementById('admin-mode-btn');
|
||||
if (isAdmin) {
|
||||
@@ -670,7 +675,7 @@ function updateFabMenu() {
|
||||
let html = '<button class="fab-sub shadow-xl" data-label="리스트" onclick="openListViewModal(event)">📋</button>';
|
||||
html += '<button class="fab-sub shadow-xl" data-label="조직도 인쇄(A3)" onclick="printA3()">🖨️</button>';
|
||||
html += '<button class="fab-sub shadow-xl" data-label="자리배치도" onclick="openSeatMapView(event)">🪑</button>';
|
||||
if (isAdmin) {
|
||||
if (isAdmin && !isHistoricalSnapshot) {
|
||||
html += '<button class="fab-sub shadow-xl" data-label="조직현황 업로드" onclick="triggerUpload(event)">⬆️</button>';
|
||||
html += '<button class="fab-sub shadow-xl" data-label="신규 구성원" onclick="openAddModal(event)">👤</button>';
|
||||
html += '<button class="fab-sub shadow-xl" data-label="신규 팀/그룹/셀" onclick="openUnitAddModal(event)">🏢</button>';
|
||||
@@ -678,6 +683,19 @@ function updateFabMenu() {
|
||||
menu.innerHTML = html;
|
||||
}
|
||||
|
||||
async function openHistoryCompareModal(fromDate, toDate) {
|
||||
openListViewModal();
|
||||
const fromInput = document.getElementById('list-compare-from');
|
||||
const toInput = document.getElementById('list-compare-to');
|
||||
if (fromInput) {
|
||||
fromInput.value = fromDate || '';
|
||||
}
|
||||
if (toInput) {
|
||||
toInput.value = toDate || '';
|
||||
}
|
||||
await loadCompareListView();
|
||||
}
|
||||
|
||||
function openSeatMapView(event) {
|
||||
event.stopPropagation();
|
||||
document.getElementById('fab-container').classList.remove('active');
|
||||
@@ -695,6 +713,25 @@ window.addEventListener('message', (event) => {
|
||||
activeAsOfDate = String(data.endDate || '').slice(0, 10);
|
||||
return;
|
||||
}
|
||||
if (data.type === 'organization-history-view') {
|
||||
activeAsOfDate = String(data.asOfDate || '').slice(0, 10);
|
||||
isHistoricalSnapshot = Boolean(data.historical);
|
||||
if (isHistoricalSnapshot && isAdmin) {
|
||||
toggleAdminMode(false);
|
||||
} else {
|
||||
updateFabMenu();
|
||||
render();
|
||||
}
|
||||
seatMapLayoutCache = null;
|
||||
loadMembers().catch(() => { });
|
||||
return;
|
||||
}
|
||||
if (data.type === 'open-history-compare') {
|
||||
openHistoryCompareModal(String(data.fromDate || ''), String(data.toDate || '')).catch((error) => {
|
||||
alert(error.message || '변경 비교를 불러오지 못했습니다.');
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (data.type === 'seatmap-layout-updated') {
|
||||
handleSeatMapLayoutUpdated();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user