diff --git a/ecosystem.config.js b/ecosystem.config.js index 97676e2e..295b7871 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -2,7 +2,7 @@ module.exports = { apps: [ { name: 'qcast-front-production', - script: 'npm run start', + script: 'npm run start:dev', instance: 2, exec_mode: 'cluster', }, diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx index cd8b9e2b..eec45f41 100644 --- a/src/components/common/context-menu/QContextMenu.jsx +++ b/src/components/common/context-menu/QContextMenu.jsx @@ -6,29 +6,19 @@ import { contextMenuListState, contextMenuState } from '@/store/contextMenu' import { useTempGrid } from '@/hooks/useTempGrid' import { useContextMenu } from '@/hooks/useContextMenu' import { useEvent } from '@/hooks/useEvent' -import { canvasState } from '@/store/canvasAtom' +import { canvasState, currentObjectState } from '@/store/canvasAtom' export default function QContextMenu(props) { const canvas = useRecoilValue(canvasState) const { contextRef, canvasProps } = props const [contextMenu, setContextMenu] = useRecoilState(contextMenuState) const contextMenuList = useRecoilValue(contextMenuListState) - const activeObject = canvasProps?.getActiveObject() //액티브된 객체를 가져옴 + const currentObject = useRecoilValue(currentObjectState) const { tempGridMode, setTempGridMode } = useTempGrid() const { handleKeyup } = useContextMenu() const { addDocumentEventListener, removeDocumentEvent } = useEvent() // const { addDocumentEventListener, removeDocumentEvent } = useContext(EventContext) - let contextType = '' - - if (activeObject) { - if (activeObject.initOptions && activeObject.initOptions.name) { - //이건 바뀔 가능성이 있음 - if (activeObject.initOptions?.name?.indexOf('guide') > -1) { - contextType = 'surface' //면형상 - } - } - } const getYPosition = (e) => { const contextLength = contextMenuList.reduce((acc, cur, index) => { return acc + cur.length @@ -36,11 +26,13 @@ export default function QContextMenu(props) { return e?.clientY - (contextLength * 25 + contextMenuList.length * 2 * 17) } - useEffect(() => { - if (!contextRef.current) return + const handleContextMenu = (e) => { + // e.preventDefault() //기존 contextmenu 막고 + + if (currentObject) { + const isArray = currentObject.hasOwnProperty('arrayData') + if (isArray && currentObject.arrayData.length === 0) return - const handleContextMenu = (e) => { - e.preventDefault() //기존 contextmenu 막고 if (tempGridMode) return const position = { x: window.innerWidth / 2 < e.pageX ? e.pageX - 240 : e.pageX, @@ -48,21 +40,24 @@ export default function QContextMenu(props) { } setContextMenu({ visible: true, ...position, currentMousePos: canvasProps.getPointer(e) }) addDocumentEventListener('keyup', document, handleKeyup) - canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 } + } - const handleClick = (e) => { - // e.preventDefault() + const handleClick = (e) => { + // e.preventDefault() + setContextMenu({ ...contextMenu, visible: false }) + } + + const handleOutsideClick = (e) => { + // e.preventDefault() + if (contextMenu.visible) { setContextMenu({ ...contextMenu, visible: false }) + removeDocumentEvent('keyup') } + } - const handleOutsideClick = (e) => { - // e.preventDefault() - if (contextMenu.visible) { - setContextMenu({ ...contextMenu, visible: false }) - removeDocumentEvent('keyup') - } - } + useEffect(() => { + if (!contextRef.current) return canvasProps?.upperCanvasEl.addEventListener('contextmenu', handleContextMenu) document.addEventListener('click', handleClick) @@ -72,43 +67,9 @@ export default function QContextMenu(props) { removeDocumentEvent('keyup') document.removeEventListener('click', handleClick) document.removeEventListener('click', handleOutsideClick) + canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제 } - }, [contextRef, contextMenuList]) - - const handleObjectMove = () => { - activeObject.set({ - lockMovementX: false, // X 축 이동 잠금 - lockMovementY: false, // Y 축 이동 잠금 - }) - - canvasProps?.on('object:modified', function (e) { - activeObject.set({ - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - }) - }) - } - - const handleObjectDelete = () => { - if (confirm('삭제하실거?')) { - canvasProps.remove(activeObject) - } - } - - const handleObjectCopy = () => { - activeObject.clone((cloned) => { - cloned.set({ - left: activeObject.left + activeObject.width + 20, - initOptions: { ...activeObject.initOptions }, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - lockScalingX: true, // X 축 크기 조정 잠금 - lockScalingY: true, // Y 축 크기 조정 잠금 - }) - canvasProps?.add(cloned) - }) - } + }, [contextRef, contextMenuList, currentObject]) return ( <> diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 06df265d..532d6364 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -387,6 +387,8 @@ export default function Estimate({}) { if (isNotEmptyArray(res?.data)) { setStorePriceList(res.data) } + + setItemChangeYn(true) }) if (estimateContextState.estimateType === 'YJSS') { @@ -416,8 +418,6 @@ export default function Estimate({}) { handlePricing('UNIT_PRICE') } } - - setItemChangeYn(true) } }, [estimateContextState?.estimateType]) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index f19687aa..396ae6af 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -119,10 +119,12 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { this.addLengthText() this.on('moving', () => { + this.initLines() this.addLengthText() }) this.on('modified', (e) => { + this.initLines() this.addLengthText() }) @@ -183,8 +185,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { this.lines = [] - this.points.forEach((point, i) => { - const nextPoint = this.points[(i + 1) % this.points.length] + this.getCurrentPoints().forEach((point, i) => { + const nextPoint = this.getCurrentPoints()[(i + 1) % this.points.length] const line = new QLine([point.x, point.y, nextPoint.x, nextPoint.y], { stroke: this.stroke, strokeWidth: this.strokeWidth, diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index ddce32a6..4f957598 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -30,6 +30,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' import { useEvent } from '@/hooks/useEvent' import { compasDegAtom } from '@/store/orientationAtom' +import { hotkeyStore } from '@/store/hotkeyAtom' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -110,6 +111,38 @@ export default function CanvasFrame() { resetPcsCheckState() } + /** + * 캔버스가 있을 경우 핫키 이벤트 처리 + * hotkeyStore에 핫키 이벤트 리스너 추가 + * + * const hotkeys = [ + { key: 'c', fn: () => asdf() }, + { key: 'v', fn: () => qwer() }, + ] + setHotkeyStore(hotkeys) + */ + const hotkeyState = useRecoilValue(hotkeyStore) + const hotkeyHandlerRef = useRef(null) + + useEffect(() => { + hotkeyHandlerRef.current = (e) => { + hotkeyState.forEach((hotkey) => { + if (e.key === hotkey.key) { + hotkey.fn() + } + }) + } + + document.addEventListener('keyup', hotkeyHandlerRef.current) + + return () => { + if (hotkeyHandlerRef.current) { + document.removeEventListener('keyup', hotkeyHandlerRef.current) + } + } + }, [hotkeyState]) + /** 핫키 이벤트 처리 끝 */ + return (
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 0d9ddc0a..a268604e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -634,7 +634,7 @@ export default function CanvasMenu(props) { onClick={() => setEstimatePopupOpen(true)} > - {getMessage('plan.menu.estimate.docDown')} + {getMessage('plan.menu.estimate.docDownload')}