- codes.html, code-management.js 삭제 (tasks.html에서 동일 기능 제공) - 사이드바에서 코드 관리 링크 제거 - daily-work-report, tbm, workplace-management JS 모듈 분리 - common/security.js 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
285 lines
7.3 KiB
JavaScript
285 lines
7.3 KiB
JavaScript
/**
|
|
* Workplace Management - State Manager
|
|
* 작업장 관리 페이지의 전역 상태 관리
|
|
*/
|
|
|
|
class WorkplaceState {
|
|
constructor() {
|
|
// 마스터 데이터
|
|
this.categories = [];
|
|
this.workplaces = [];
|
|
this.allEquipments = [];
|
|
this.existingEquipments = [];
|
|
|
|
// 현재 상태
|
|
this.currentCategoryId = '';
|
|
this.currentEditingCategory = null;
|
|
this.currentEditingWorkplace = null;
|
|
this.currentWorkplaceMapId = null;
|
|
|
|
// 작업장 지도 관련
|
|
this.workplaceCanvas = null;
|
|
this.workplaceCtx = null;
|
|
this.workplaceImage = null;
|
|
this.workplaceIsDrawing = false;
|
|
this.workplaceStartX = 0;
|
|
this.workplaceStartY = 0;
|
|
this.workplaceCurrentRect = null;
|
|
this.workplaceEquipmentRegions = [];
|
|
|
|
// 전체화면 편집기 관련
|
|
this.fsCanvas = null;
|
|
this.fsCtx = null;
|
|
this.fsImage = null;
|
|
this.fsIsDrawing = false;
|
|
this.fsStartX = 0;
|
|
this.fsStartY = 0;
|
|
this.fsCurrentRect = null;
|
|
this.fsSidebarVisible = true;
|
|
|
|
// 리스너
|
|
this.listeners = new Map();
|
|
|
|
console.log('[WorkplaceState] 초기화 완료');
|
|
}
|
|
|
|
/**
|
|
* 상태 업데이트
|
|
*/
|
|
update(key, value) {
|
|
const prevValue = this[key];
|
|
this[key] = value;
|
|
this.notifyListeners(key, value, prevValue);
|
|
}
|
|
|
|
/**
|
|
* 리스너 등록
|
|
*/
|
|
subscribe(key, callback) {
|
|
if (!this.listeners.has(key)) {
|
|
this.listeners.set(key, []);
|
|
}
|
|
this.listeners.get(key).push(callback);
|
|
}
|
|
|
|
/**
|
|
* 리스너 알림
|
|
*/
|
|
notifyListeners(key, newValue, prevValue) {
|
|
const keyListeners = this.listeners.get(key) || [];
|
|
keyListeners.forEach(callback => {
|
|
try {
|
|
callback(newValue, prevValue);
|
|
} catch (error) {
|
|
console.error(`[WorkplaceState] 리스너 오류 (${key}):`, error);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 현재 카테고리 변경
|
|
*/
|
|
setCurrentCategory(categoryId) {
|
|
const prevId = this.currentCategoryId;
|
|
this.currentCategoryId = categoryId === '' ? '' : categoryId;
|
|
this.notifyListeners('currentCategoryId', this.currentCategoryId, prevId);
|
|
}
|
|
|
|
/**
|
|
* 현재 카테고리 정보 가져오기
|
|
*/
|
|
getCurrentCategory() {
|
|
if (!this.currentCategoryId) return null;
|
|
return this.categories.find(c => c.category_id == this.currentCategoryId);
|
|
}
|
|
|
|
/**
|
|
* 현재 카테고리별 작업장 가져오기
|
|
*/
|
|
getFilteredWorkplaces() {
|
|
if (this.currentCategoryId === '') {
|
|
return this.workplaces;
|
|
}
|
|
return this.workplaces.filter(w => w.category_id == this.currentCategoryId);
|
|
}
|
|
|
|
/**
|
|
* 작업장 지도 상태 초기화
|
|
*/
|
|
resetWorkplaceMapState() {
|
|
this.workplaceCanvas = null;
|
|
this.workplaceCtx = null;
|
|
this.workplaceImage = null;
|
|
this.workplaceIsDrawing = false;
|
|
this.workplaceCurrentRect = null;
|
|
}
|
|
|
|
/**
|
|
* 전체화면 편집기 상태 초기화
|
|
*/
|
|
resetFullscreenState() {
|
|
this.fsCanvas = null;
|
|
this.fsCtx = null;
|
|
this.fsImage = null;
|
|
this.fsIsDrawing = false;
|
|
this.fsCurrentRect = null;
|
|
}
|
|
|
|
/**
|
|
* 통계 계산
|
|
*/
|
|
getStatistics() {
|
|
const total = this.workplaces.length;
|
|
const active = this.workplaces.filter(w =>
|
|
w.is_active === 1 || w.is_active === true
|
|
).length;
|
|
const factoryTotal = this.categories.length;
|
|
|
|
const filtered = this.getFilteredWorkplaces();
|
|
const filteredActive = filtered.filter(w =>
|
|
w.is_active === 1 || w.is_active === true
|
|
).length;
|
|
|
|
return {
|
|
total,
|
|
active,
|
|
factoryTotal,
|
|
filteredTotal: filtered.length,
|
|
filteredActive
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 상태 초기화
|
|
*/
|
|
reset() {
|
|
this.currentEditingCategory = null;
|
|
this.currentEditingWorkplace = null;
|
|
this.currentWorkplaceMapId = null;
|
|
this.resetWorkplaceMapState();
|
|
this.resetFullscreenState();
|
|
}
|
|
|
|
/**
|
|
* 디버그 출력
|
|
*/
|
|
debug() {
|
|
console.log('[WorkplaceState] 현재 상태:', {
|
|
categories: this.categories.length,
|
|
workplaces: this.workplaces.length,
|
|
currentCategoryId: this.currentCategoryId,
|
|
allEquipments: this.allEquipments.length,
|
|
workplaceEquipmentRegions: this.workplaceEquipmentRegions.length
|
|
});
|
|
}
|
|
}
|
|
|
|
// 전역 인스턴스 생성
|
|
window.WorkplaceState = new WorkplaceState();
|
|
|
|
// 하위 호환성을 위한 전역 변수 프록시
|
|
const wpStateProxy = window.WorkplaceState;
|
|
|
|
Object.defineProperties(window, {
|
|
categories: {
|
|
get: () => wpStateProxy.categories,
|
|
set: (v) => { wpStateProxy.categories = v; }
|
|
},
|
|
workplaces: {
|
|
get: () => wpStateProxy.workplaces,
|
|
set: (v) => { wpStateProxy.workplaces = v; }
|
|
},
|
|
currentCategoryId: {
|
|
get: () => wpStateProxy.currentCategoryId,
|
|
set: (v) => { wpStateProxy.currentCategoryId = v; }
|
|
},
|
|
currentEditingCategory: {
|
|
get: () => wpStateProxy.currentEditingCategory,
|
|
set: (v) => { wpStateProxy.currentEditingCategory = v; }
|
|
},
|
|
currentEditingWorkplace: {
|
|
get: () => wpStateProxy.currentEditingWorkplace,
|
|
set: (v) => { wpStateProxy.currentEditingWorkplace = v; }
|
|
},
|
|
workplaceCanvas: {
|
|
get: () => wpStateProxy.workplaceCanvas,
|
|
set: (v) => { wpStateProxy.workplaceCanvas = v; }
|
|
},
|
|
workplaceCtx: {
|
|
get: () => wpStateProxy.workplaceCtx,
|
|
set: (v) => { wpStateProxy.workplaceCtx = v; }
|
|
},
|
|
workplaceImage: {
|
|
get: () => wpStateProxy.workplaceImage,
|
|
set: (v) => { wpStateProxy.workplaceImage = v; }
|
|
},
|
|
workplaceIsDrawing: {
|
|
get: () => wpStateProxy.workplaceIsDrawing,
|
|
set: (v) => { wpStateProxy.workplaceIsDrawing = v; }
|
|
},
|
|
workplaceStartX: {
|
|
get: () => wpStateProxy.workplaceStartX,
|
|
set: (v) => { wpStateProxy.workplaceStartX = v; }
|
|
},
|
|
workplaceStartY: {
|
|
get: () => wpStateProxy.workplaceStartY,
|
|
set: (v) => { wpStateProxy.workplaceStartY = v; }
|
|
},
|
|
workplaceCurrentRect: {
|
|
get: () => wpStateProxy.workplaceCurrentRect,
|
|
set: (v) => { wpStateProxy.workplaceCurrentRect = v; }
|
|
},
|
|
workplaceEquipmentRegions: {
|
|
get: () => wpStateProxy.workplaceEquipmentRegions,
|
|
set: (v) => { wpStateProxy.workplaceEquipmentRegions = v; }
|
|
},
|
|
existingEquipments: {
|
|
get: () => wpStateProxy.existingEquipments,
|
|
set: (v) => { wpStateProxy.existingEquipments = v; }
|
|
},
|
|
allEquipments: {
|
|
get: () => wpStateProxy.allEquipments,
|
|
set: (v) => { wpStateProxy.allEquipments = v; }
|
|
},
|
|
fsCanvas: {
|
|
get: () => wpStateProxy.fsCanvas,
|
|
set: (v) => { wpStateProxy.fsCanvas = v; }
|
|
},
|
|
fsCtx: {
|
|
get: () => wpStateProxy.fsCtx,
|
|
set: (v) => { wpStateProxy.fsCtx = v; }
|
|
},
|
|
fsImage: {
|
|
get: () => wpStateProxy.fsImage,
|
|
set: (v) => { wpStateProxy.fsImage = v; }
|
|
},
|
|
fsIsDrawing: {
|
|
get: () => wpStateProxy.fsIsDrawing,
|
|
set: (v) => { wpStateProxy.fsIsDrawing = v; }
|
|
},
|
|
fsStartX: {
|
|
get: () => wpStateProxy.fsStartX,
|
|
set: (v) => { wpStateProxy.fsStartX = v; }
|
|
},
|
|
fsStartY: {
|
|
get: () => wpStateProxy.fsStartY,
|
|
set: (v) => { wpStateProxy.fsStartY = v; }
|
|
},
|
|
fsCurrentRect: {
|
|
get: () => wpStateProxy.fsCurrentRect,
|
|
set: (v) => { wpStateProxy.fsCurrentRect = v; }
|
|
},
|
|
fsSidebarVisible: {
|
|
get: () => wpStateProxy.fsSidebarVisible,
|
|
set: (v) => { wpStateProxy.fsSidebarVisible = v; }
|
|
}
|
|
});
|
|
|
|
// currentWorkplaceMapId를 window에도 설정
|
|
Object.defineProperty(window, 'currentWorkplaceMapId', {
|
|
get: () => wpStateProxy.currentWorkplaceMapId,
|
|
set: (v) => { wpStateProxy.currentWorkplaceMapId = v; }
|
|
});
|
|
|
|
console.log('[Module] workplace-management/state.js 로드 완료');
|