Files
sam-react-prod/src/lib/dashboard-invalidation.ts

113 lines
4.2 KiB
TypeScript
Raw Normal View History

/**
* CEO targeted refetch
*
* CUD sessionStorage + CustomEvent로
*
* :
* - ERP
* - registerDashboardDomain()
*/
// 대시보드 섹션 키 (useCEODashboard의 refetchMap과 1:1 매핑)
export type DashboardSectionKey =
| 'dailyReport'
| 'receivable'
| 'debtCollection'
| 'monthlyExpense'
| 'cardManagement'
| 'statusBoard'
| 'salesStatus'
| 'purchaseStatus'
| 'dailyProduction'
| 'unshipped'
| 'construction'
| 'dailyAttendance'
| 'entertainment'
| 'welfare';
// 동적 도메인→섹션 레지스트리
const domainSectionRegistry = new Map<string, DashboardSectionKey[]>();
/**
* ( )
*
* @example
* // 생산 모듈 초기화 시
* registerDashboardDomain('production', ['statusBoard', 'dailyProduction']);
*
* // 건설 모듈 초기화 시
* registerDashboardDomain('construction', ['statusBoard', 'construction']);
*/
export function registerDashboardDomain(domain: string, sections: DashboardSectionKey[]): void {
domainSectionRegistry.set(domain, sections);
}
// ===== 공통 ERP 도메인 (테넌트 무관, 항상 등록) =====
registerDashboardDomain('deposit', ['dailyReport', 'receivable']);
registerDashboardDomain('withdrawal', ['dailyReport', 'monthlyExpense']);
registerDashboardDomain('sales', ['dailyReport', 'salesStatus', 'receivable']);
registerDashboardDomain('purchase', ['dailyReport', 'purchaseStatus', 'monthlyExpense']);
registerDashboardDomain('badDebt', ['debtCollection', 'receivable']);
registerDashboardDomain('expectedExpense', ['monthlyExpense']);
registerDashboardDomain('bill', ['dailyReport', 'receivable']);
registerDashboardDomain('giftCertificate', ['entertainment', 'cardManagement']);
registerDashboardDomain('journalEntry', ['entertainment', 'welfare', 'monthlyExpense']);
registerDashboardDomain('order', ['statusBoard', 'salesStatus']);
registerDashboardDomain('stock', ['statusBoard']);
registerDashboardDomain('schedule', ['statusBoard']);
registerDashboardDomain('client', ['statusBoard']);
registerDashboardDomain('leave', ['statusBoard', 'dailyAttendance']);
registerDashboardDomain('approval', ['statusBoard']);
registerDashboardDomain('attendance', ['statusBoard', 'dailyAttendance']);
registerDashboardDomain('shipment', ['statusBoard', 'unshipped']);
// ===== 테넌트 전용 도메인 (각 모듈에서 등록 — 현재는 하위 호환을 위해 여기서도 등록) =====
// TODO: Phase 1 완료 후 각 모듈의 초기화 코드로 이동
registerDashboardDomain('production', ['statusBoard', 'dailyProduction']);
registerDashboardDomain('construction', ['statusBoard', 'construction']);
const STORAGE_KEY = 'dashboard:stale-sections';
const EVENT_NAME = 'dashboard:invalidate';
/**
* CUD stale
*/
export function invalidateDashboard(domain: string): void {
const sections = domainSectionRegistry.get(domain);
if (!sections || sections.length === 0) return;
// 1. sessionStorage에 stale 섹션 저장 (navigation 사이 유지)
try {
const existing = sessionStorage.getItem(STORAGE_KEY);
const current: string[] = existing ? JSON.parse(existing) : [];
const merged = Array.from(new Set([...current, ...sections]));
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(merged));
} catch {
// sessionStorage 접근 불가 시 무시
}
// 2. CustomEvent 발행 (대시보드가 마운트 중이면 즉시 처리)
if (typeof window !== 'undefined') {
window.dispatchEvent(
new CustomEvent(EVENT_NAME, { detail: { sections } }),
);
}
}
/**
* stale
*/
export function consumeStaleSections(): DashboardSectionKey[] {
try {
const raw = sessionStorage.getItem(STORAGE_KEY);
if (!raw) return [];
sessionStorage.removeItem(STORAGE_KEY);
return JSON.parse(raw) as DashboardSectionKey[];
} catch {
return [];
}
}
/** CustomEvent 이름 (리스너 등록용) */
export const DASHBOARD_INVALIDATE_EVENT = EVENT_NAME;