[251025] feat: usePanelHistory
🕐 커밋 시간: 2025. 10. 25. 05:33:22 📊 변경 통계: • 총 파일: 8개 • 추가: +83줄 • 삭제: -217줄 📁 추가된 파일: + com.twin.app.shoptime/src/actions/panelHistoryActions.js + com.twin.app.shoptime/src/hooks/usePanelHistory/index.js + com.twin.app.shoptime/src/hooks/usePanelHistory/usePanelHistory.js + com.twin.app.shoptime/src/middleware/panelHistoryMiddleware.js + com.twin.app.shoptime/src/reducers/panelHistoryReducer.js 📝 수정된 파일: ~ com.twin.app.shoptime/package-lock.json ~ com.twin.app.shoptime/src/actions/actionTypes.js ~ com.twin.app.shoptime/src/store/store.js 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/src/reducers/panelHistoryReducer.js (javascript): ✅ Added: enqueuePanel() 🔧 주요 변경 내용: • 타입 시스템 안정성 강화 • 핵심 비즈니스 로직 개선 Performance: 코드 최적화로 성능 개선 기대
This commit is contained in:
290
com.twin.app.shoptime/package-lock.json
generated
290
com.twin.app.shoptime/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,11 @@ export const types = {
|
|||||||
UPDATE_PANEL: 'UPDATE_PANEL',
|
UPDATE_PANEL: 'UPDATE_PANEL',
|
||||||
RESET_PANELS: 'RESET_PANELS',
|
RESET_PANELS: 'RESET_PANELS',
|
||||||
|
|
||||||
|
// 🔽 [신규] panel history actions
|
||||||
|
ENQUEUE_PANEL_HISTORY: 'ENQUEUE_PANEL_HISTORY',
|
||||||
|
CLEAR_PANEL_HISTORY: 'CLEAR_PANEL_HISTORY',
|
||||||
|
RESET_PANEL_HISTORY: 'RESET_PANEL_HISTORY',
|
||||||
|
|
||||||
// device actions
|
// device actions
|
||||||
GET_AUTHENTICATION_CODE: 'GET_AUTHENTICATION_CODE',
|
GET_AUTHENTICATION_CODE: 'GET_AUTHENTICATION_CODE',
|
||||||
REGISTER_DEVICE: 'REGISTER_DEVICE',
|
REGISTER_DEVICE: 'REGISTER_DEVICE',
|
||||||
|
|||||||
39
com.twin.app.shoptime/src/actions/panelHistoryActions.js
Normal file
39
com.twin.app.shoptime/src/actions/panelHistoryActions.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* src/actions/panelHistoryActions.js
|
||||||
|
* Panel history 액션 크리에이터
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { types } from './actionTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel을 히스토리에 추가
|
||||||
|
* @param {string} panelName - Panel 이름
|
||||||
|
* @param {Object} panelInfo - Panel 상태 정보
|
||||||
|
* @param {string} action - 발생한 Redux 액션 ('PUSH' | 'POP' | 'UPDATE' | 'RESET')
|
||||||
|
* @returns {Object} Redux action
|
||||||
|
*/
|
||||||
|
export const enqueuePanelHistory = (panelName, panelInfo = {}, action = 'PUSH') => ({
|
||||||
|
type: types.ENQUEUE_PANEL_HISTORY,
|
||||||
|
payload: {
|
||||||
|
panelName,
|
||||||
|
panelInfo,
|
||||||
|
action,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel history 초기화
|
||||||
|
* @returns {Object} Redux action
|
||||||
|
*/
|
||||||
|
export const clearPanelHistory = () => ({
|
||||||
|
type: types.CLEAR_PANEL_HISTORY,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel history 리셋 (로그아웃 등)
|
||||||
|
* @returns {Object} Redux action
|
||||||
|
*/
|
||||||
|
export const resetPanelHistory = () => ({
|
||||||
|
type: types.RESET_PANEL_HISTORY,
|
||||||
|
});
|
||||||
1
com.twin.app.shoptime/src/hooks/usePanelHistory/index.js
Normal file
1
com.twin.app.shoptime/src/hooks/usePanelHistory/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { usePanelHistory, default } from './usePanelHistory';
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/**
|
||||||
|
* src/hooks/usePanelHistory/usePanelHistory.js
|
||||||
|
* Panel history를 조회하는 hook
|
||||||
|
*
|
||||||
|
* Redux의 panelHistory state를 useSelector로 조회하고
|
||||||
|
* 편리한 API로 변환하여 제공합니다.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel history를 조회하는 hook
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const panelHistory = usePanelHistory();
|
||||||
|
* console.log(panelHistory.currentPanel); // 현재 panel
|
||||||
|
* console.log(panelHistory.previousPanel); // 이전 panel
|
||||||
|
* console.log(panelHistory.history); // 전체 히스토리
|
||||||
|
* console.log(panelHistory.detectPattern()); // 네비게이션 패턴
|
||||||
|
*
|
||||||
|
* @returns {Object} Panel history API
|
||||||
|
*/
|
||||||
|
export const usePanelHistory = () => {
|
||||||
|
// Redux state에서 panelHistory 조회
|
||||||
|
const panelHistory = useSelector((state) => state.panelHistory);
|
||||||
|
|
||||||
|
// 편의 선택자
|
||||||
|
const currentPanel = useSelector((state) => state.panelHistory.current);
|
||||||
|
const previousPanel = useSelector((state) => state.panelHistory.previous);
|
||||||
|
const hasTransition = useSelector((state) => state.panelHistory.hasTransition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 히스토리를 최신순 배열로 반환
|
||||||
|
* [current, previous, older, oldest, ...]
|
||||||
|
*/
|
||||||
|
const getHistory = useCallback(() => {
|
||||||
|
const { history, head, size } = panelHistory;
|
||||||
|
if (size === 0) return [];
|
||||||
|
|
||||||
|
const sorted = [];
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
const index = (head - i + 10) % 10;
|
||||||
|
if (history[index]) {
|
||||||
|
sorted.push(history[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sorted;
|
||||||
|
}, [panelHistory]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 거리의 panel 조회
|
||||||
|
* @param {number} distance - 거리 (0=current, 1=previous, 2=older, ...)
|
||||||
|
* @returns {Object|null} Panel entry 또는 null
|
||||||
|
*/
|
||||||
|
const getHistoryAt = useCallback(
|
||||||
|
(distance) => {
|
||||||
|
const { history, head, size } = panelHistory;
|
||||||
|
if (distance >= size || distance < 0) return null;
|
||||||
|
|
||||||
|
const index = (head - distance + 10) % 10;
|
||||||
|
return history[index] || null;
|
||||||
|
},
|
||||||
|
[panelHistory]
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 네비게이션 패턴 감지
|
||||||
|
* 사용자의 네비게이션 행동을 분석하여 패턴을 반환
|
||||||
|
*/
|
||||||
|
const detectPattern = useCallback(() => {
|
||||||
|
const history = getHistory();
|
||||||
|
const [current, previous, older] = history;
|
||||||
|
|
||||||
|
if (!current) {
|
||||||
|
return { pattern: 'no-panel', confidence: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Back navigation: A → B → A
|
||||||
|
if (
|
||||||
|
current &&
|
||||||
|
older &&
|
||||||
|
current.panelName === older.panelName &&
|
||||||
|
previous &&
|
||||||
|
previous.panelName !== current.panelName
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
pattern: 'back-navigation',
|
||||||
|
from: previous.panelName,
|
||||||
|
to: current.panelName,
|
||||||
|
confidence: 0.95,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Detail flow: Search/Home → Detail
|
||||||
|
if (current.panelName === 'detailpanel' && previous) {
|
||||||
|
if (previous.panelName === 'searchpanel') {
|
||||||
|
return {
|
||||||
|
pattern: 'search-to-detail',
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (previous.panelName === 'homepanel') {
|
||||||
|
return {
|
||||||
|
pattern: 'home-to-detail',
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Modal overlay: base → modal
|
||||||
|
const modalPanels = ['imagepanel', 'mediapanel', 'playerpanel'];
|
||||||
|
if (modalPanels.includes(current.panelName) && previous) {
|
||||||
|
return {
|
||||||
|
pattern: 'modal-overlay',
|
||||||
|
basePanel: previous.panelName,
|
||||||
|
modalPanel: current.panelName,
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Search flow: Home → Search
|
||||||
|
if (current.panelName === 'searchpanel' && previous?.panelName === 'homepanel') {
|
||||||
|
return {
|
||||||
|
pattern: 'home-to-search',
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Cart flow: Product → Cart
|
||||||
|
if (current.panelName === 'cartpanel' && previous) {
|
||||||
|
return {
|
||||||
|
pattern: 'product-to-cart',
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Checkout flow: Cart → Checkout
|
||||||
|
if (current.panelName === 'checkoutpanel' && previous?.panelName === 'cartpanel') {
|
||||||
|
return {
|
||||||
|
pattern: 'cart-to-checkout',
|
||||||
|
confidence: 1.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: 순차 네비게이션
|
||||||
|
return {
|
||||||
|
pattern: 'sequential-navigation',
|
||||||
|
from: previous?.panelName,
|
||||||
|
to: current.panelName,
|
||||||
|
confidence: 0.5,
|
||||||
|
};
|
||||||
|
}, [getHistory]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 디버그 정보
|
||||||
|
*/
|
||||||
|
const getDebugInfo = useCallback(() => {
|
||||||
|
const history = getHistory();
|
||||||
|
const pattern = detectPattern();
|
||||||
|
|
||||||
|
return {
|
||||||
|
state: panelHistory,
|
||||||
|
history: history,
|
||||||
|
historyLabeled: {
|
||||||
|
current: history[0] || null,
|
||||||
|
previous: history[1] || null,
|
||||||
|
older: history[2] || null,
|
||||||
|
oldest: history[3] || null,
|
||||||
|
},
|
||||||
|
pattern,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
}, [panelHistory, getHistory, detectPattern]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메모이제이션된 히스토리 배열
|
||||||
|
* useCallback의 의존성 변경 시에만 재계산
|
||||||
|
*/
|
||||||
|
const memoizedHistory = useMemo(() => getHistory(), [getHistory]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API 반환
|
||||||
|
*/
|
||||||
|
return {
|
||||||
|
// 현재 상태
|
||||||
|
currentPanel,
|
||||||
|
previousPanel,
|
||||||
|
hasTransition,
|
||||||
|
|
||||||
|
// 배열 형태
|
||||||
|
history: memoizedHistory,
|
||||||
|
panelTransition:
|
||||||
|
previousPanel && currentPanel
|
||||||
|
? [previousPanel.panelName, currentPanel.panelName]
|
||||||
|
: currentPanel
|
||||||
|
? [null, currentPanel.panelName]
|
||||||
|
: [null, null],
|
||||||
|
|
||||||
|
// 조회 메서드
|
||||||
|
getHistory,
|
||||||
|
getHistoryAt,
|
||||||
|
detectPattern,
|
||||||
|
getDebugInfo,
|
||||||
|
|
||||||
|
// 전체 상태 (필요시)
|
||||||
|
panelHistory,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default usePanelHistory;
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* src/middleware/panelHistoryMiddleware.js
|
||||||
|
* Panel history 자동 추적 middleware
|
||||||
|
*
|
||||||
|
* Panel action (PUSH, POP, UPDATE, RESET)을 감지하고
|
||||||
|
* 자동으로 panel history에 기록합니다.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { types } from '../actions/actionTypes';
|
||||||
|
import { enqueuePanelHistory, clearPanelHistory } from '../actions/panelHistoryActions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel history middleware
|
||||||
|
* 모든 panel action을 감지하여 panelHistory reducer로 자동 기록
|
||||||
|
*
|
||||||
|
* @param {Object} store - Redux store
|
||||||
|
* @returns {Function} middleware function
|
||||||
|
*/
|
||||||
|
export const panelHistoryMiddleware = (store) => (next) => (action) => {
|
||||||
|
// 원래 액션 실행
|
||||||
|
const result = next(action);
|
||||||
|
|
||||||
|
// Panel action 후 history 업데이트
|
||||||
|
const state = store.getState();
|
||||||
|
const panels = state.panels?.panels || [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (action.type) {
|
||||||
|
// PUSH_PANEL: 새 panel 추가
|
||||||
|
case types.PUSH_PANEL: {
|
||||||
|
if (action.payload) {
|
||||||
|
const { name: panelName, panelInfo = {} } = action.payload;
|
||||||
|
|
||||||
|
if (panelName) {
|
||||||
|
store.dispatch(enqueuePanelHistory(panelName, panelInfo, 'PUSH'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POP_PANEL: panel 제거 후 이전 panel 기록
|
||||||
|
case types.POP_PANEL: {
|
||||||
|
// POP 후 top panel을 기록 (이전 패널로 돌아감)
|
||||||
|
if (panels.length > 0) {
|
||||||
|
const topPanel = panels[panels.length - 1];
|
||||||
|
if (topPanel && topPanel.name) {
|
||||||
|
store.dispatch(enqueuePanelHistory(topPanel.name, topPanel.panelInfo || {}, 'POP'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE_PANEL: panel 정보 업데이트 기록
|
||||||
|
case types.UPDATE_PANEL: {
|
||||||
|
if (action.payload) {
|
||||||
|
const { name: panelName, panelInfo = {} } = action.payload;
|
||||||
|
|
||||||
|
if (panelName) {
|
||||||
|
store.dispatch(enqueuePanelHistory(panelName, panelInfo, 'UPDATE'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RESET_PANELS: 히스토리 초기화
|
||||||
|
case types.RESET_PANELS: {
|
||||||
|
store.dispatch(clearPanelHistory());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Other actions are ignored
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[panelHistoryMiddleware] 오류:', error);
|
||||||
|
// Middleware 오류가 앱 전체에 영향 주지 않도록 처리
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default panelHistoryMiddleware;
|
||||||
137
com.twin.app.shoptime/src/reducers/panelHistoryReducer.js
Normal file
137
com.twin.app.shoptime/src/reducers/panelHistoryReducer.js
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* src/reducers/panelHistoryReducer.js
|
||||||
|
* Panel history Ring Buffer reducer
|
||||||
|
*
|
||||||
|
* 10개의 panel entry를 저장하는 ring buffer 구현
|
||||||
|
* 각 entry는 { panelName, panelInfo, timestamp, action } 객체
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { types } from '../actions/actionTypes';
|
||||||
|
|
||||||
|
// 초기 상태
|
||||||
|
const initialState = {
|
||||||
|
history: new Array(10).fill(null), // 10개 ring buffer
|
||||||
|
head: -1, // 현재 위치 (-1 ~ 9)
|
||||||
|
size: 0, // 현재 저장된 개수 (0 ~ 10)
|
||||||
|
current: null, // 현재 panel entry
|
||||||
|
previous: null, // 이전 panel entry
|
||||||
|
hasTransition: false, // panel 전환 여부
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel을 Ring buffer에 추가
|
||||||
|
* @param {Object} state - 현재 상태
|
||||||
|
* @param {string} panelName - 추가할 panel 이름
|
||||||
|
* @param {Object} panelInfo - panel 정보
|
||||||
|
* @param {string} action - Redux 액션 타입 ('PUSH' | 'POP' | 'UPDATE')
|
||||||
|
* @param {string} timestamp - ISO 8601 timestamp
|
||||||
|
* @returns {Object} 새로운 상태
|
||||||
|
*/
|
||||||
|
const enqueuePanel = (state, panelName, panelInfo, action, timestamp) => {
|
||||||
|
// State 불변성 유지
|
||||||
|
const newHistory = state.history.map((item) => item);
|
||||||
|
|
||||||
|
// 다음 위치 계산 (ring buffer 순환)
|
||||||
|
const newHead = (state.head + 1) % 10;
|
||||||
|
|
||||||
|
// 새 entry 생성
|
||||||
|
const newEntry = {
|
||||||
|
panelName,
|
||||||
|
panelInfo: { ...panelInfo }, // Deep copy
|
||||||
|
timestamp,
|
||||||
|
action,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ring buffer에 저장
|
||||||
|
newHistory[newHead] = newEntry;
|
||||||
|
|
||||||
|
// Size 업데이트 (최대 10)
|
||||||
|
const newSize = Math.min(state.size + 1, 10);
|
||||||
|
|
||||||
|
// 이전 panel 추출
|
||||||
|
const previousEntry = state.current;
|
||||||
|
|
||||||
|
return {
|
||||||
|
history: newHistory,
|
||||||
|
head: newHead,
|
||||||
|
size: newSize,
|
||||||
|
current: newEntry,
|
||||||
|
previous: previousEntry,
|
||||||
|
hasTransition: previousEntry !== null && previousEntry.panelName !== newEntry.panelName,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reducer - Panel history 상태 관리
|
||||||
|
*/
|
||||||
|
export const panelHistoryReducer = (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
// 🔽 Panel history에 새 entry 추가
|
||||||
|
case types.ENQUEUE_PANEL_HISTORY: {
|
||||||
|
const { panelName, panelInfo = {}, action: actionType, timestamp } = action.payload;
|
||||||
|
|
||||||
|
// 입력값 검증
|
||||||
|
if (!panelName || typeof panelName !== 'string') {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 [중요] 동일한 panelName이 들어오면 panelInfo만 업데이트
|
||||||
|
// PUSH/POP/UPDATE 모두 같은 방식으로 처리
|
||||||
|
if (state.current && state.current.panelName === panelName) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
current: {
|
||||||
|
...state.current,
|
||||||
|
panelInfo: { ...panelInfo }, // panelInfo만 업데이트
|
||||||
|
timestamp,
|
||||||
|
action: actionType, // 최신 action 기록
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 다른 panelName이면 새로운 버퍼 항목 추가
|
||||||
|
return enqueuePanel(state, panelName, panelInfo, actionType, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 History 초기화
|
||||||
|
case types.CLEAR_PANEL_HISTORY: {
|
||||||
|
return { ...initialState };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Panel reset 시 history도 리셋
|
||||||
|
case types.RESET_PANELS: {
|
||||||
|
return { ...initialState };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔽 Panel history 명시적 리셋
|
||||||
|
case types.RESET_PANEL_HISTORY: {
|
||||||
|
return { ...initialState };
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector 헬퍼 함수들
|
||||||
|
*/
|
||||||
|
export const selectPanelHistory = (state) => state.panelHistory;
|
||||||
|
export const selectCurrentPanel = (state) => state.panelHistory.current;
|
||||||
|
export const selectPreviousPanel = (state) => state.panelHistory.previous;
|
||||||
|
export const selectPanelHistoryList = (state) => {
|
||||||
|
const { history, head, size } = state.panelHistory;
|
||||||
|
if (size === 0) return [];
|
||||||
|
|
||||||
|
// 최신순으로 정렬된 히스토리 반환
|
||||||
|
const sorted = [];
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
const index = (head - i + 10) % 10;
|
||||||
|
if (history[index]) {
|
||||||
|
sorted.push(history[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sorted;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default panelHistoryReducer;
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
import {
|
import { applyMiddleware, combineReducers, createStore } from 'redux';
|
||||||
applyMiddleware,
|
|
||||||
combineReducers,
|
|
||||||
createStore,
|
|
||||||
} from 'redux';
|
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
|
|
||||||
import { autoCloseMiddleware } from '../middleware/autoCloseMiddleware';
|
import { autoCloseMiddleware } from '../middleware/autoCloseMiddleware';
|
||||||
|
import { panelHistoryMiddleware } from '../middleware/panelHistoryMiddleware';
|
||||||
import { appDataReducer } from '../reducers/appDataReducer';
|
import { appDataReducer } from '../reducers/appDataReducer';
|
||||||
import { billingReducer } from '../reducers/billingReducer';
|
import { billingReducer } from '../reducers/billingReducer';
|
||||||
import { brandReducer } from '../reducers/brandReducer';
|
import { brandReducer } from '../reducers/brandReducer';
|
||||||
@@ -29,6 +26,7 @@ import { myPageReducer } from '../reducers/myPageReducer';
|
|||||||
import { onSaleReducer } from '../reducers/onSaleReducer';
|
import { onSaleReducer } from '../reducers/onSaleReducer';
|
||||||
import { orderReducer } from '../reducers/orderReducer';
|
import { orderReducer } from '../reducers/orderReducer';
|
||||||
import { panelsReducer } from '../reducers/panelReducer';
|
import { panelsReducer } from '../reducers/panelReducer';
|
||||||
|
import { panelHistoryReducer } from '../reducers/panelHistoryReducer';
|
||||||
import { pinCodeReducer } from '../reducers/pinCodeReducer';
|
import { pinCodeReducer } from '../reducers/pinCodeReducer';
|
||||||
import { playReducer } from '../reducers/playReducer';
|
import { playReducer } from '../reducers/playReducer';
|
||||||
import { productReducer } from '../reducers/productReducer';
|
import { productReducer } from '../reducers/productReducer';
|
||||||
@@ -41,6 +39,7 @@ import { voiceReducer } from '../reducers/voiceReducer';
|
|||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
panels: panelsReducer,
|
panels: panelsReducer,
|
||||||
|
panelHistory: panelHistoryReducer,
|
||||||
device: deviceReducer,
|
device: deviceReducer,
|
||||||
common: commonReducer,
|
common: commonReducer,
|
||||||
localSettings: localSettingsReducer,
|
localSettings: localSettingsReducer,
|
||||||
@@ -74,5 +73,5 @@ const rootReducer = combineReducers({
|
|||||||
|
|
||||||
export const store = createStore(
|
export const store = createStore(
|
||||||
rootReducer,
|
rootReducer,
|
||||||
applyMiddleware(thunk, autoCloseMiddleware)
|
applyMiddleware(thunk, panelHistoryMiddleware, autoCloseMiddleware)
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user