Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # src/styles/_contents.scss # src/styles/_main.scss # src/styles/_modal.scss # src/styles/_reset.scss
This commit is contained in:
commit
a4fb74df91
12
.env
12
.env
@ -1,12 +0,0 @@
|
||||
# Environment variables declared in this file are automatically made available to Prisma.
|
||||
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
|
||||
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
# DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
|
||||
# DATABASE_URL="mongodb://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/sample_mflix?retryWrites=true&w=majority"
|
||||
#DATABASE_URL = "mongodb%2Bsrv%3A%2F%2Fyoo32767%3AGuCtswjLGqUaNL0G%40cluster0.vsdtcnb.mongodb.net%2F%3FretryWrites%3Dtrue%26w%3Dmajority%26appName%3DCluster0"
|
||||
# DATABASE_URL = "mongodb+srv://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/Cluster0?retryWrites=true&w=majority"
|
||||
# DATABASE_URL="mongodb://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/sample_mflix?retryWrites=true&w=majority"
|
||||
DATABASE_URL="mongodb+srv://yoo32767:GuCtswjLGqUaNL0G@cluster0.vsdtcnb.mongodb.net/mytest"
|
||||
@ -1,14 +1,8 @@
|
||||
NEXT_PUBLIC_TEST="테스트변수입니다. development"
|
||||
|
||||
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
|
||||
# NEXT_PUBLIC_API_SERVER_PATH="http://localhost:8080"
|
||||
# NEXT_PUBLIC_API_SERVER_PATH="http://172.30.1.60:8080"
|
||||
|
||||
DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true"
|
||||
|
||||
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
||||
|
||||
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
|
||||
|
||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-qa.q-cells.jp:8120/eos/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-qa.q-cells.jp:8120/qm/login/autoLogin"
|
||||
@ -1,12 +1,8 @@
|
||||
NEXT_PUBLIC_TEST="테스트변수입니다. production"
|
||||
|
||||
NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080"
|
||||
|
||||
DATABASE_URL=""
|
||||
|
||||
SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y="
|
||||
|
||||
NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3"
|
||||
|
||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-local.q-cells.jp:8120/eos/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-local.q-cells.jp:8120/qm/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin"
|
||||
NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin"
|
||||
@ -44,7 +44,6 @@
|
||||
"prettier": "^3.3.3",
|
||||
"prisma": "^5.18.0",
|
||||
"react-color-palette": "^7.2.2",
|
||||
"react-dropdown-select": "^4.11.3",
|
||||
"react-select": "^5.8.1",
|
||||
"sass": "^1.77.8",
|
||||
"tailwindcss": "^3.4.1"
|
||||
|
||||
@ -1,27 +1,24 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
||||
import ServerError from './error'
|
||||
|
||||
import '@/styles/common.scss'
|
||||
|
||||
import KO from '@/locales/ko.json'
|
||||
import JA from '@/locales/ja.json'
|
||||
// import KO from '@/locales/ko.json'
|
||||
// import JA from '@/locales/ja.json'
|
||||
|
||||
export const QcastProvider = ({ children }) => {
|
||||
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
||||
// const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
// const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
||||
|
||||
useEffect(() => {
|
||||
if (globalLocale === 'ko') {
|
||||
setAppMessageState(KO)
|
||||
} else {
|
||||
setAppMessageState(JA)
|
||||
}
|
||||
}, [globalLocale])
|
||||
// useEffect(() => {
|
||||
// if (globalLocale === 'ko') {
|
||||
// setAppMessageState(KO)
|
||||
// } else {
|
||||
// setAppMessageState(JA)
|
||||
// }
|
||||
// }, [globalLocale])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
12
src/app/SessionProvider.js
Normal file
12
src/app/SessionProvider.js
Normal file
@ -0,0 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { createContext, useState } from 'react'
|
||||
|
||||
export const SessionContext = createContext({
|
||||
session: {},
|
||||
})
|
||||
|
||||
export default function SessionProvider({ useSession, children }) {
|
||||
const [session, setSession] = useState(useSession)
|
||||
return <SessionContext.Provider value={{ session }}>{children}</SessionContext.Provider>
|
||||
}
|
||||
@ -15,6 +15,8 @@ import './globals.css'
|
||||
import '../styles/style.scss'
|
||||
import '../styles/contents.scss'
|
||||
import Dimmed from '@/components/ui/Dimmed'
|
||||
import SessionProvider from './SessionProvider'
|
||||
import LocaleSwitch from '@/components/LocaleSwitch'
|
||||
|
||||
// const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
@ -70,11 +72,14 @@ export default async function RootLayout({ children }) {
|
||||
<Header userSession={sessionProps} />
|
||||
<div className="content">
|
||||
<Dimmed />
|
||||
<QcastProvider>{children}</QcastProvider>
|
||||
<QcastProvider>
|
||||
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
||||
</QcastProvider>
|
||||
</div>
|
||||
<footer>
|
||||
<div className="footer-inner">
|
||||
<div className="footer-inner flex justify-center">
|
||||
<span>COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</span>
|
||||
<LocaleSwitch />
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@ -66,8 +66,13 @@ export const LINE_TYPE = {
|
||||
},
|
||||
SUBLINE: {
|
||||
/**
|
||||
*
|
||||
* 추녀 / 마루 / 박공 / 지붕골 / 박공단
|
||||
*/
|
||||
HIP: 'hip',
|
||||
RIDGE: 'ridge',
|
||||
GABLE: 'gable',
|
||||
VALLEY: 'valley',
|
||||
VERGE: 'verge',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
23
src/components/LocaleSwitch.jsx
Normal file
23
src/components/LocaleSwitch.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { useRecoilState } from 'recoil'
|
||||
|
||||
export default function LocaleSwitch() {
|
||||
const [globalLocale, setGlobalLocale] = useRecoilState(globalLocaleStore)
|
||||
|
||||
return (
|
||||
<span
|
||||
className="locale-switch"
|
||||
onClick={() => {
|
||||
if (globalLocale === 'ko') {
|
||||
setGlobalLocale('ja')
|
||||
} else {
|
||||
setGlobalLocale('ko')
|
||||
}
|
||||
}}
|
||||
>
|
||||
{globalLocale.toUpperCase()}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
@ -30,7 +30,7 @@ export default function Playground() {
|
||||
const fileRef = useRef(null)
|
||||
const queryRef = useRef(null)
|
||||
const [zoom, setZoom] = useState(20)
|
||||
const { get, promisePost } = useAxios()
|
||||
const { get, promiseGet, promisePost } = useAxios()
|
||||
const testVar = process.env.NEXT_PUBLIC_TEST
|
||||
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
||||
const { getMessage } = useMessage()
|
||||
@ -43,6 +43,8 @@ export default function Playground() {
|
||||
const [checkboxInput, setCheckboxInput] = useState([])
|
||||
const [selectedValue, setSelectedValue] = useState('')
|
||||
|
||||
const [users, setUsers] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('textInput:', textInput)
|
||||
}, [textInput])
|
||||
@ -142,6 +144,10 @@ export default function Playground() {
|
||||
},
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('users:', users)
|
||||
}, [users])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="container mx-auto p-4 m-4 border">
|
||||
@ -305,6 +311,32 @@ export default function Playground() {
|
||||
<div className="my-2">
|
||||
<QPagination {...paginationProps} />
|
||||
</div>
|
||||
<div className="my-2">
|
||||
<Button
|
||||
onClick={() => {
|
||||
promiseGet({ url: 'http://localhost:8080/api/user' }).then((res) => setUsers(res.data))
|
||||
}}
|
||||
>
|
||||
axios get test
|
||||
</Button>
|
||||
</div>
|
||||
<div className="my-2">
|
||||
<Button
|
||||
onClick={() => {
|
||||
const result = promisePost({
|
||||
url: 'http://localhost:8080/api/user',
|
||||
data: {
|
||||
firstName: 'Yoo',
|
||||
lastName: 'Sangwook',
|
||||
email: 'yoo1757@naver.com',
|
||||
age: 46,
|
||||
},
|
||||
}).then((res) => console.log('res', res))
|
||||
}}
|
||||
>
|
||||
axios post test
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Button } from '@nextui-org/react'
|
||||
|
||||
import { get, post } from '@/lib/Axios'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { customSettingsState } from '@/store/canvasAtom'
|
||||
import { modalContent, modalState } from '@/store/modalAtom'
|
||||
@ -20,6 +21,8 @@ export default function Settings() {
|
||||
const [open, setOpen] = useRecoilState(modalState)
|
||||
const [contents, setContent] = useRecoilState(modalContent)
|
||||
|
||||
const { get, post } = useAxios()
|
||||
|
||||
const handleSavePopup = () => {
|
||||
console.log('color ', color)
|
||||
}
|
||||
|
||||
21
src/components/auth/AutoLogin.jsx
Normal file
21
src/components/auth/AutoLogin.jsx
Normal file
@ -0,0 +1,21 @@
|
||||
'use client'
|
||||
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
|
||||
export default function AutoLoginPage() {
|
||||
const { getMessage } = useMessage()
|
||||
|
||||
return (
|
||||
<div className="login-input-frame">
|
||||
<div className="login-frame-tit ">
|
||||
<span>{getMessage('site.name')}</span>
|
||||
{getMessage('site.sub_name')}
|
||||
</div>
|
||||
<div className="login-input-wrap">
|
||||
<div className="login-area id" style={{ fontWeight: 'bolder' }}>
|
||||
{getMessage('login.auto.page.text')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -15,6 +15,8 @@ import Cookies from 'js-cookie'
|
||||
|
||||
import { useSearchParams } from 'next/navigation'
|
||||
|
||||
import AutoLogin from './AutoLogin'
|
||||
|
||||
export default function Login() {
|
||||
// 자동 로그인
|
||||
const initParams = useSearchParams()
|
||||
@ -180,8 +182,7 @@ export default function Login() {
|
||||
<Link href={'/login'} className="login-logo">
|
||||
<Image src="/static/images/main/login-logo.svg" alt="react" width={236} height={43} styles={{ width: '236px', height: '43px' }} priority />
|
||||
</Link>
|
||||
|
||||
{passwordReset === 1 && (
|
||||
{!autoLoginParam && passwordReset === 1 && (
|
||||
<>
|
||||
<div className="login-input-frame">
|
||||
<form onSubmit={loginProcess} className="space-y-6">
|
||||
@ -266,7 +267,7 @@ export default function Login() {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{passwordReset === 2 && (
|
||||
{!autoLoginParam && passwordReset === 2 && (
|
||||
<>
|
||||
<div className="login-input-frame">
|
||||
<div className="login-frame-tit pw-reset">
|
||||
@ -328,6 +329,7 @@ export default function Login() {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{autoLoginParam && <AutoLogin />}
|
||||
</div>
|
||||
<div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div>
|
||||
</div>
|
||||
|
||||
@ -27,7 +27,7 @@ export default function QContextMenu(props) {
|
||||
const handleContextMenu = (e) => {
|
||||
// e.preventDefault() //기존 contextmenu 막고
|
||||
setContextMenu({ visible: true, x: e.pageX, y: e.pageY })
|
||||
console.log(111, canvasProps)
|
||||
// console.log(111, canvasProps)
|
||||
canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //한번 노출 후 이벤트 삭제
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ export default function Archive() {
|
||||
<div className="sub-content">
|
||||
<div className="sub-content-inner">
|
||||
<div className="sub-table-box">
|
||||
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={true} />
|
||||
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={false} />
|
||||
<ArchiveTable clsCode={boardType.clsCode} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -45,7 +45,7 @@ export default function ArchiveTable({ clsCode }) {
|
||||
}
|
||||
|
||||
fetchData()
|
||||
}, [search.searchValue])
|
||||
}, [search.searchValue, search.searchFlag])
|
||||
|
||||
// 상세 파일 목록 조회
|
||||
const handleDetailFileListDown = async (noticeNo) => {
|
||||
@ -74,30 +74,34 @@ export default function ArchiveTable({ clsCode }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="file-down-list">
|
||||
{boardList?.map((board) => (
|
||||
<div key={board.noticeNo} className="file-down-item">
|
||||
<div className="file-item-info">
|
||||
<div className="item-num">
|
||||
{/* 번호 */}
|
||||
{board.rowNumber}
|
||||
{boardList.length > 0 ? (
|
||||
<div className="file-down-list">
|
||||
{boardList?.map((board) => (
|
||||
<div key={board.noticeNo} className="file-down-item">
|
||||
<div className="file-item-info">
|
||||
<div className="item-num">
|
||||
{/* 번호 */}
|
||||
{board.rowNumber}
|
||||
</div>
|
||||
<div className="item-name">
|
||||
{/* 제목 */}
|
||||
{board.title}
|
||||
</div>
|
||||
<div className="item-date">
|
||||
{/* 등록일 */}
|
||||
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
|
||||
</div>
|
||||
</div>
|
||||
<div className="item-name">
|
||||
{/* 제목 */}
|
||||
{board.title}
|
||||
</div>
|
||||
<div className="item-date">
|
||||
{/* 등록일 */}
|
||||
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
|
||||
<div className="file-down-box">
|
||||
{/* 첨부파일 */}
|
||||
<button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="file-down-box">
|
||||
{/* 첨부파일 */}
|
||||
<button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="file-down-nodata">{getMessage('common.message.no.data')}</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
||||
const y2 = this.top + this.height * scaleY
|
||||
const dx = x2 - x1
|
||||
const dy = y2 - y1
|
||||
this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0))
|
||||
this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1))
|
||||
},
|
||||
|
||||
addLengthText() {
|
||||
@ -150,7 +150,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
||||
|
||||
getLength() {
|
||||
//10배 곱해진 값 return
|
||||
return Number(this.length.toFixed(1) * 10)
|
||||
return Number(this.length.toFixed(0) * 10)
|
||||
},
|
||||
|
||||
setViewLengthText(bool) {
|
||||
|
||||
@ -199,32 +199,16 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
const end = points[(i + 1) % points.length]
|
||||
const dx = end.x - start.x
|
||||
const dy = end.y - start.y
|
||||
const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10
|
||||
const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) * 10
|
||||
|
||||
let midPoint
|
||||
|
||||
switch (this.direction) {
|
||||
case 'north':
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 - 30)
|
||||
break
|
||||
case 'west':
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2 - 30, (start.y + end.y) / 2)
|
||||
break
|
||||
case 'south':
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2 + 30)
|
||||
break
|
||||
case 'east':
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2 + 30, (start.y + end.y) / 2)
|
||||
break
|
||||
default:
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
|
||||
break
|
||||
}
|
||||
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
|
||||
|
||||
const degree = (Math.atan2(dy, dx) * 180) / Math.PI
|
||||
|
||||
// Create new text object if it doesn't exist
|
||||
const text = new fabric.Text(length.toFixed(0), {
|
||||
const text = new fabric.Text(length.toString(), {
|
||||
left: midPoint.x,
|
||||
top: midPoint.y,
|
||||
fontSize: this.fontSize,
|
||||
|
||||
@ -13,11 +13,7 @@ export default function CanvasFrame({ plan }) {
|
||||
const canvasRef = useRef(null)
|
||||
const { canvas } = useCanvas('canvas')
|
||||
const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu()
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
|
||||
useEffect(() => {
|
||||
console.log(currentObject)
|
||||
}, [currentObject])
|
||||
useEvent()
|
||||
|
||||
const loadCanvas = () => {
|
||||
|
||||
@ -1,122 +1,25 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { useContext, useEffect, useState } from 'react'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import CanvasFrame from './CanvasFrame'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { usePlan } from '@/hooks/usePlan'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { currentCanvasPlanState, initCanvasPlansState, plansState } from '@/store/canvasAtom'
|
||||
import { sessionStore } from '@/store/commonAtom'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
|
||||
export default function CanvasLayout() {
|
||||
const { session } = useContext(SessionContext)
|
||||
const [objectNo, setObjectNo] = useState('test123240822001') // 이후 삭제 필요
|
||||
const [planNum, setPlanNum] = useState(0)
|
||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||
const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState)
|
||||
const [plans, setPlans] = useRecoilState(plansState)
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
const sessionState = useRecoilValue(sessionStore)
|
||||
|
||||
const { getMessage } = useMessage()
|
||||
const { swalFire } = useSwal()
|
||||
const { getCanvasByObjectNo, delCanvasById, checkModifiedCanvasPlan, saveCanvas, currentCanvasData } = usePlan()
|
||||
|
||||
const handleCurrentPlan = (newCurrentId) => {
|
||||
// console.log('currentPlan newCurrentId: ', newCurrentId)
|
||||
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
|
||||
if (currentCanvasPlan?.id && checkModifiedCanvasPlan()) {
|
||||
swalFire({
|
||||
html: getMessage('common.message.confirm.save') + `</br>${currentCanvasPlan.name}`,
|
||||
type: 'confirm',
|
||||
confirmFn: async () => {
|
||||
await saveCanvas(sessionState.userId)
|
||||
updateCurrentPlan(newCurrentId)
|
||||
},
|
||||
denyFn: () => {
|
||||
updateCurrentPlan(newCurrentId)
|
||||
},
|
||||
})
|
||||
} else {
|
||||
updateCurrentPlan(newCurrentId)
|
||||
}
|
||||
}
|
||||
}
|
||||
const updateCurrentPlan = (newCurrentId) => {
|
||||
setPlans((plans) =>
|
||||
plans.map((plan) => {
|
||||
return { ...plan, isCurrent: plan.id === newCurrentId }
|
||||
}),
|
||||
)
|
||||
}
|
||||
useEffect(() => {
|
||||
setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null)
|
||||
}, [plans])
|
||||
|
||||
const handleDeletePlan = (e, id) => {
|
||||
e.stopPropagation() // 이벤트 버블링 방지
|
||||
|
||||
if (initCanvasPlans.some((plan) => plan.id === id)) {
|
||||
delCanvasById(id)
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('common.message.delete') })
|
||||
// console.log('[DELETE] canvas-statuses res :::::::: %o', res)
|
||||
setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.filter((plan) => plan.id !== id))
|
||||
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
// console.error('[DELETE] canvas-statuses res error :::::::: %o', error)
|
||||
})
|
||||
} else {
|
||||
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
||||
swalFire({ text: getMessage('common.message.delete') })
|
||||
}
|
||||
|
||||
// 삭제 후 last 데이터에 포커싱
|
||||
const lastPlan = plans.filter((plan) => plan.id !== id).at(-1)
|
||||
if (!lastPlan) {
|
||||
setPlanNum(0)
|
||||
setCurrentCanvasPlan(null)
|
||||
} else if (id !== lastPlan.id) {
|
||||
handleCurrentPlan(lastPlan.id)
|
||||
}
|
||||
}
|
||||
|
||||
const addEmptyPlan = () => {
|
||||
setPlans([...plans, { id: planNum, name: `Plan ${planNum + 1}`, objectNo: `${objectNo}` }])
|
||||
handleCurrentPlan(planNum)
|
||||
setPlanNum(planNum + 1)
|
||||
}
|
||||
|
||||
const addCopyPlan = () => {
|
||||
const copyPlan = {
|
||||
id: planNum,
|
||||
name: `Plan ${planNum + 1}`,
|
||||
objectNo: `${objectNo}`,
|
||||
userId: sessionState.userId,
|
||||
canvasStatus: currentCanvasData(),
|
||||
}
|
||||
setPlans((plans) => [...plans, copyPlan])
|
||||
handleCurrentPlan(planNum)
|
||||
setPlanNum(planNum + 1)
|
||||
}
|
||||
const { plans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentCanvasPlan) {
|
||||
getCanvasByObjectNo(sessionState.userId, objectNo).then((res) => {
|
||||
// console.log('canvas 목록 ', res)
|
||||
if (res.length > 0) {
|
||||
setInitCanvasPlans(res)
|
||||
setPlans(res)
|
||||
handleCurrentPlan(res.at(-1).id) // last 데이터에 포커싱
|
||||
setPlanNum(res.length)
|
||||
} else {
|
||||
addEmptyPlan()
|
||||
}
|
||||
})
|
||||
}
|
||||
loadCanvasPlanData(session.userId, objectNo)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
@ -127,14 +30,14 @@ export default function CanvasLayout() {
|
||||
<button
|
||||
key={`plan-${plan.id}`}
|
||||
className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`}
|
||||
onClick={() => handleCurrentPlan(plan.id)}
|
||||
onClick={() => handleCurrentPlan(session.userId, plan.id)}
|
||||
>
|
||||
<span>{plan.name}</span>
|
||||
<i
|
||||
className="close"
|
||||
onClick={(e) =>
|
||||
swalFire({
|
||||
html: getMessage('common.message.confirm.delete') + `</br>${plan.name}`,
|
||||
text: `${plan.name} ` + getMessage('plan.message.confirm.delete'),
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
handleDeletePlan(e, plan.id)
|
||||
@ -146,23 +49,7 @@ export default function CanvasLayout() {
|
||||
))}
|
||||
</div>
|
||||
{plans.length < 10 && (
|
||||
<button
|
||||
className="plane-add"
|
||||
onClick={() =>
|
||||
JSON.parse(currentCanvasData()).objects.length > 0
|
||||
? swalFire({
|
||||
html: `${currentCanvasPlan.name} 을 복제하시겠습니까?`,
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
addCopyPlan()
|
||||
},
|
||||
denyFn: () => {
|
||||
addEmptyPlan()
|
||||
},
|
||||
})
|
||||
: addEmptyPlan()
|
||||
}
|
||||
>
|
||||
<button className="plane-add" onClick={() => handleAddPlan(session.userId, objectNo)}>
|
||||
<span></span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
@ -19,6 +19,7 @@ import { MENU } from '@/common/common'
|
||||
import KO from '@/locales/ko.json'
|
||||
import JA from '@/locales/ja.json'
|
||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||
|
||||
const canvasMenus = [
|
||||
{ index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
|
||||
@ -58,7 +59,8 @@ export default function CanvasMenu(props) {
|
||||
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
|
||||
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
||||
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
||||
const setPoints = useSetRecoilState(outerLinePointsState)
|
||||
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
|
||||
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
|
||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||
const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||
|
||||
@ -121,14 +123,14 @@ export default function CanvasMenu(props) {
|
||||
}, [menuNumber, type])
|
||||
|
||||
// 저장버튼(btn08) 클릭 시 호출되는 함수
|
||||
const handleSaveCanvas = () => {
|
||||
swalFire({
|
||||
html: getMessage('common.message.confirm.save') + `</br>${currentCanvasPlan.name}`,
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
saveCanvas(sessionState.userId)
|
||||
},
|
||||
})
|
||||
const handleSaveCanvas = async () => {
|
||||
// swalFire({
|
||||
// text: `${currentCanvasPlan.name} ` + getMessage('plan.message.confirm.save'),
|
||||
// type: 'confirm',
|
||||
// confirmFn: async () => {
|
||||
await saveCanvas(sessionState.userId)
|
||||
// },
|
||||
// })
|
||||
}
|
||||
|
||||
const onClickPlacementInitialMenu = () => {
|
||||
@ -140,7 +142,8 @@ export default function CanvasMenu(props) {
|
||||
}
|
||||
|
||||
const handleClear = () => {
|
||||
setPoints([])
|
||||
setOuterLinePoints([])
|
||||
setPlacementPoints([])
|
||||
canvas?.clear()
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import { globalPitchState } from '@/store/canvasAtom'
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { useRef } from 'react'
|
||||
|
||||
export default function Slope({ setShowSlopeSettingModal }) {
|
||||
const { getMessage } = useMessage()
|
||||
const [globalPitch, setGlobalPitch] = useRecoilState(globalPitchState)
|
||||
const inputRef = useRef()
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 50, y: -950 }}>
|
||||
<div className={`modal-pop-wrap xxxm`}>
|
||||
@ -19,13 +24,21 @@ export default function Slope({ setShowSlopeSettingModal }) {
|
||||
{getMessage('slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5">
|
||||
<input type="text" className="input-origin block" defaultValue={300} />
|
||||
<input type="text" className="input-origin block" defaultValue={globalPitch} ref={inputRef} />
|
||||
</div>
|
||||
<span className="thin">{getMessage('size.angle')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
|
||||
<button
|
||||
className="btn-frame modal act"
|
||||
onClick={() => {
|
||||
setGlobalPitch(inputRef.current.value)
|
||||
setShowSlopeSettingModal(false)
|
||||
}}
|
||||
>
|
||||
{getMessage('modal.common.save')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -7,7 +7,7 @@ import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState
|
||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||
import { fabric } from 'fabric'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
import { settingModalGridOptionsState } from '@/store/settingAtom'
|
||||
import { gridDisplaySelector, settingModalGridOptionsState } from '@/store/settingAtom'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
|
||||
@ -24,6 +24,7 @@ export default function DotLineGrid(props) {
|
||||
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
|
||||
const gridColor = useRecoilValue(gridColorState)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const isGridDisplay = useRecoilValue(gridDisplaySelector)
|
||||
|
||||
const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState)
|
||||
const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState)
|
||||
@ -179,6 +180,7 @@ export default function DotLineGrid(props) {
|
||||
fill: pattern,
|
||||
selectable: false,
|
||||
name: 'dotGrid',
|
||||
visible: isGridDisplay,
|
||||
},
|
||||
)
|
||||
|
||||
@ -209,6 +211,7 @@ export default function DotLineGrid(props) {
|
||||
strokeDashArray: [5, 2],
|
||||
opacity: 0.3,
|
||||
direction: 'horizontal',
|
||||
visible: isGridDisplay,
|
||||
},
|
||||
)
|
||||
canvas.add(horizontalLine)
|
||||
@ -235,6 +238,7 @@ export default function DotLineGrid(props) {
|
||||
strokeDashArray: [5, 2],
|
||||
opacity: 0.3,
|
||||
direction: 'vertical',
|
||||
visible: isGridDisplay,
|
||||
},
|
||||
)
|
||||
canvas.add(verticalLine)
|
||||
|
||||
@ -46,6 +46,7 @@ export default function ObjectSetting({ setShowObjectSettingModal }) {
|
||||
heightRef: useRef(null),
|
||||
pitchRef: useRef(null),
|
||||
offsetRef: useRef(null),
|
||||
offsetWidthRef: useRef(null),
|
||||
directionRef: useRef(null),
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,17 @@
|
||||
import Image from 'next/image'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { forwardRef, useState } from 'react'
|
||||
|
||||
export default function PentagonDormer() {
|
||||
const PentagonDormer = forwardRef((props, refs) => {
|
||||
const { getMessage } = useMessage()
|
||||
const [direction, setDirection] = useState('down')
|
||||
refs.directionRef.current = direction
|
||||
|
||||
const getDirection = (e) => {
|
||||
setDirection(e.target.value)
|
||||
refs.directionRef.current = e.target.value
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="discrimination-box mb10">
|
||||
@ -18,7 +27,7 @@ export default function PentagonDormer() {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={2000} />
|
||||
<input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={2000} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -29,7 +38,7 @@ export default function PentagonDormer() {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={1000} />
|
||||
<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -40,18 +49,18 @@ export default function PentagonDormer() {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={4000} />
|
||||
<input type="text" className="input-origin block" placeholder={0} ref={refs.widthRef} defaultValue={2000} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="eaves-keraba-item">
|
||||
<div className="eaves-keraba-th">{getMessage('modal.object.setting.offset.depth')}</div>
|
||||
<div className="eaves-keraba-th">{getMessage('modal.object.setting.offset.width')}</div>
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={500} />
|
||||
<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetWidthRef} />
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -62,7 +71,7 @@ export default function PentagonDormer() {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={4} />
|
||||
<input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />
|
||||
</div>
|
||||
<span className="thin">寸</span>
|
||||
</div>
|
||||
@ -80,13 +89,15 @@ export default function PentagonDormer() {
|
||||
<span className="right">{getMessage('commons.east')}</span>
|
||||
<span className="bottom">{getMessage('commons.south')}</span>
|
||||
<span className="left">{getMessage('commons.west')}</span>
|
||||
<button className="plane-btn up"></button>
|
||||
<button className="plane-btn right"></button>
|
||||
<button className="plane-btn down act"></button>
|
||||
<button className="plane-btn left"></button>
|
||||
<button className={`plane-btn up ${direction === 'up' ? ' act' : ''}`} value="up" onClick={getDirection}></button>
|
||||
<button className={`plane-btn right ${direction === 'right' ? ' act' : ''}`} value="right" onClick={getDirection}></button>
|
||||
<button className={`plane-btn down ${direction === 'down' ? ' act' : ''}`} value="down" onClick={getDirection}></button>
|
||||
<button className={`plane-btn left ${direction === 'left' ? ' act' : ''}`} value="left" onClick={getDirection}></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default PentagonDormer
|
||||
|
||||
@ -5,7 +5,6 @@ import { forwardRef, useState } from 'react'
|
||||
const TriangleDormer = forwardRef((props, refs) => {
|
||||
const { getMessage } = useMessage()
|
||||
const [direction, setDirection] = useState('down')
|
||||
|
||||
refs.directionRef.current = direction
|
||||
|
||||
const getDirection = (e) => {
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
||||
import { settingModalSecondOptionsState } from '@/store/settingAtom'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { adsorptionPointAddModeState } from '@/store/canvasAtom'
|
||||
import { useFirstOption } from '@/hooks/option/useFirstOption'
|
||||
|
||||
export default function FirstOption() {
|
||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||
const { settingModalFirstOptions, setSettingModalFirstOptions } = useFirstOption()
|
||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||
const { option3, option4 } = settingModalSecondOptions
|
||||
|
||||
@ -34,7 +34,6 @@ export default function MainContents({ objectList, businessCharger, businessChar
|
||||
startRow: 1,
|
||||
endRow: 1,
|
||||
}
|
||||
// const noticeApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=NOTICE&schTitle=&startRow=1&endRow=1`
|
||||
const noticeApiUrl = `api/board/list?${queryStringFormatter(param)}`
|
||||
const res = await get({ url: noticeApiUrl })
|
||||
//console.log('공지res::', res)
|
||||
@ -57,7 +56,6 @@ export default function MainContents({ objectList, businessCharger, businessChar
|
||||
startRow: 1,
|
||||
endRow: 3,
|
||||
}
|
||||
// const faqApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=FAQ&schTitle=&startRow=1&endRow=1`
|
||||
const faqApiUrl = `api/board/list?${queryStringFormatter(param)}`
|
||||
const res = await get({ url: faqApiUrl })
|
||||
//console.log('FAQres::', res)
|
||||
|
||||
@ -15,6 +15,7 @@ import { convertNumberToPriceDecimal } from '@/util/common-utils'
|
||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||
import KO from '@/locales/ko.json'
|
||||
import JA from '@/locales/ja.json'
|
||||
import QPagination from '../common/pagination/QPagination'
|
||||
import '@/styles/grid.scss'
|
||||
import { sessionStore } from '@/store/commonAtom'
|
||||
|
||||
@ -24,9 +25,9 @@ export default function Stuff() {
|
||||
const stuffSearchParams = useRecoilValue(stuffSearchState)
|
||||
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
||||
const { getMessage } = useMessage()
|
||||
const [curPage, setCurPage] = useState(1) //현재 페이지 번호
|
||||
const [defaultSize, setDefaultSize] = useState(100) //페이지 당 게시물 수
|
||||
const [gridCount, setGridCount] = useState(0) //총 갯수
|
||||
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
||||
const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수
|
||||
const [totalCount, setTotalCount] = useState(0) //총 갯수
|
||||
const [defaultSortType, setDefaultSortType] = useState('R')
|
||||
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
@ -62,13 +63,10 @@ export default function Stuff() {
|
||||
const [gridProps, setGridProps] = useState({
|
||||
gridData: [],
|
||||
isPageable: false,
|
||||
// sets 10 rows per page (default is 100)
|
||||
// paginationPageSize: 100,
|
||||
// allows the user to select the page size from a predefined list of page sizes
|
||||
// paginationPageSizeSelector: [100, 200, 300, 400],
|
||||
gridColumns: [
|
||||
{
|
||||
field: 'lastEditDatetime',
|
||||
minWidth: 200,
|
||||
headerName: getMessage('stuff.gridHeader.lastEditDatetime'),
|
||||
headerCheckboxSelection: true,
|
||||
headerCheckboxSelectionCurrentPageOnly: true, //페이징시 현재 페이지만 체크되도록
|
||||
@ -228,56 +226,40 @@ export default function Stuff() {
|
||||
// 진입시 그리드 데이터 조회
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(sessionState)) {
|
||||
//물건 메뉴 눌러서 최초 진입 sessionState
|
||||
if (stuffSearchParams?.code === 'S') {
|
||||
const params = {
|
||||
schObjectNo: '',
|
||||
schAddress: '',
|
||||
schObjectName: '',
|
||||
schSaleStoreName: '',
|
||||
schReceiveUser: '',
|
||||
schDispCompanyName: '',
|
||||
schDateType: 'U',
|
||||
schObjectNo: stuffSearchParams?.schObjectNo,
|
||||
schAddress: stuffSearchParams?.schAddress,
|
||||
schObjectName: stuffSearchParams?.schObjectName,
|
||||
schSaleStoreName: stuffSearchParams?.schSaleStoreName,
|
||||
schReceiveUser: stuffSearchParams?.schReceiveUser,
|
||||
schDispCompanyName: stuffSearchParams?.schDispCompanyName,
|
||||
schDateType: stuffSearchParams.schDateType,
|
||||
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
|
||||
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
|
||||
startRow: (curPage - 1) * defaultSize + 1,
|
||||
endRow: curPage * defaultSize,
|
||||
startRow: (pageNo - 1) * pageSize + 1,
|
||||
endRow: pageNo * pageSize,
|
||||
schSelSaleStoreId: '',
|
||||
schSortType: 'R',
|
||||
schSortType: stuffSearchParams.schSortType,
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
//api에 넘길값 startRow, endRow
|
||||
// let startRow
|
||||
// let endRow
|
||||
// startRow = (curPage - 1) * size + 1
|
||||
// endRow = curPage * size
|
||||
// console.log('startrow::', startRow)
|
||||
// console.log('endRow::', endRow)
|
||||
|
||||
// let curPage
|
||||
// let totalpage
|
||||
// let totalCount
|
||||
// let size
|
||||
// let pageCount
|
||||
|
||||
// console.log('화면진입 세션정보::::::::::', sessionState)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}`
|
||||
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}`
|
||||
|
||||
await get({
|
||||
url: apiUrl,
|
||||
}).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||
setGridCount(res[0].totCnt)
|
||||
setTotalCount(res[0].totCnt)
|
||||
}
|
||||
})
|
||||
}
|
||||
fetchData()
|
||||
} else {
|
||||
//메인화면에서 진입
|
||||
const params = {
|
||||
schObjectNo: '',
|
||||
schObjectNo: stuffSearchParams.schObjectNo,
|
||||
schAddress: '',
|
||||
schObjectName: '',
|
||||
schSaleStoreName: '',
|
||||
@ -286,30 +268,13 @@ export default function Stuff() {
|
||||
schDateType: 'U',
|
||||
schFromDt: dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'),
|
||||
schToDt: dayjs(new Date()).format('YYYY-MM-DD'),
|
||||
startRow: (curPage - 1) * defaultSize + 1,
|
||||
endRow: curPage * defaultSize,
|
||||
startRow: (pageNo - 1) * pageSize + 1,
|
||||
endRow: pageNo * pageSize,
|
||||
schSelSaleStoreId: '',
|
||||
schSortType: 'R',
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
//api에 넘길값 startRow, endRow
|
||||
// let startRow
|
||||
// let endRow
|
||||
// startRow = (curPage - 1) * size + 1
|
||||
// endRow = curPage * size
|
||||
// console.log('startrow::', startRow)
|
||||
// console.log('endRow::', endRow)
|
||||
|
||||
// let curPage
|
||||
// let totalpage
|
||||
// let totalCount
|
||||
// let size
|
||||
// let pageCount
|
||||
|
||||
// console.log('화면진입 세션정보::::::::::', sessionState)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(params)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(params)}`
|
||||
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}`
|
||||
|
||||
await get({
|
||||
@ -317,34 +282,33 @@ export default function Stuff() {
|
||||
}).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||
setGridCount(res[0].totCnt)
|
||||
setTotalCount(res[0].totCnt)
|
||||
}
|
||||
})
|
||||
}
|
||||
fetchData()
|
||||
}
|
||||
}
|
||||
}, [sessionState])
|
||||
}, [pageNo, sessionState])
|
||||
|
||||
useEffect(() => {
|
||||
if (stuffSearchParams?.code === 'E') {
|
||||
//console.log('조회누름::::::::', stuffSearchParams)
|
||||
stuffSearchParams.startRow = (curPage - 1) * defaultSize + 1
|
||||
stuffSearchParams.endRow = curPage * defaultSize
|
||||
stuffSearchParams.startRow = 1
|
||||
stuffSearchParams.endRow = 1 * pageSize
|
||||
stuffSearchParams.schSortType = defaultSortType
|
||||
|
||||
setPageNo(1)
|
||||
|
||||
async function fetchData() {
|
||||
// console.log('조회누름 세션정보:::::::::::::', sessionState)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
|
||||
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
||||
await get({ url: apiUrl }).then((res) => {
|
||||
// console.log('검색조건 변경 조회 API결과:::::::', res)
|
||||
if (!isEmptyArray(res)) {
|
||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||
setGridCount(res[0].totCnt)
|
||||
setTotalCount(res[0].totCnt)
|
||||
} else {
|
||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
||||
setGridCount(0)
|
||||
setTotalCount(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -354,53 +318,58 @@ export default function Stuff() {
|
||||
|
||||
//페이지 갯수 변경 이벤트
|
||||
const onChangePerPage = (e) => {
|
||||
let startRow = (curPage - 1) * e.target.value + 1
|
||||
let startRow = (1 - 1) * e.target.value + 1
|
||||
stuffSearchParams.startRow = startRow
|
||||
stuffSearchParams.endRow = curPage * e.target.value
|
||||
setDefaultSize(e.target.value)
|
||||
stuffSearchParams.endRow = 1 * e.target.value
|
||||
setPageSize(e.target.value)
|
||||
setStuffSearch({
|
||||
...stuffSearch,
|
||||
code: 'S',
|
||||
startRow: startRow,
|
||||
endRow: curPage * e.target.value,
|
||||
endRow: 1 * e.target.value,
|
||||
})
|
||||
// console.log('페이지 갯수 변경 때 셋팅된 검색조건:::', stuffSearchParams)
|
||||
// console.log('페이지 갯수 변경 때 sessionState:::', sessionState)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}`
|
||||
|
||||
setPageNo(1)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
|
||||
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
||||
get({ url: apiUrl }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||
setGridCount(res[0].totCnt)
|
||||
setTotalCount(res[0].totCnt)
|
||||
} else {
|
||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
||||
setGridCount(0)
|
||||
setTotalCount(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//최근 등록일 수정일 정렬 이벤트
|
||||
const onChangeSortType = (e) => {
|
||||
let startRow = (1 - 1) * pageSize + 1
|
||||
stuffSearchParams.startRow = startRow
|
||||
stuffSearchParams.endRow = 1 * pageSize
|
||||
|
||||
stuffSearchParams.schSortType = e.target.value
|
||||
// console.log('셋팅된 검색조건:::', stuffSearchParams)
|
||||
setDefaultSortType(e.target.value)
|
||||
setStuffSearch({
|
||||
...stuffSearch,
|
||||
code: 'S',
|
||||
startRow: startRow,
|
||||
endRow: 1 * pageSize,
|
||||
schSortType: e.target.value,
|
||||
})
|
||||
// console.log('정렬 변경시 세션정보::::::::::::', sessionState)
|
||||
// const apiUrl = `/api/object/list?saleStoreId=201TES01&${queryStringFormatter(stuffSearchParams)}`
|
||||
// const apiUrl = `/api/object/list?saleStoreId=X167&${queryStringFormatter(stuffSearchParams)}`
|
||||
|
||||
setPageNo(1)
|
||||
|
||||
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(stuffSearchParams)}`
|
||||
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(stuffSearchParams)}`
|
||||
get({ url: apiUrl }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
|
||||
setGridCount(res[0].totCnt)
|
||||
setTotalCount(res[0].totCnt)
|
||||
} else {
|
||||
setGridProps({ ...gridProps, gridData: [], count: 0 })
|
||||
setGridCount(0)
|
||||
setTotalCount(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -413,20 +382,34 @@ export default function Stuff() {
|
||||
}
|
||||
}, [globalLocaleState])
|
||||
|
||||
// 페이징 현재페이지 변경
|
||||
const handleChangePage = (page) => {
|
||||
stuffSearchParams.code = 'S'
|
||||
|
||||
setStuffSearch({
|
||||
...stuffSearch,
|
||||
code: 'S',
|
||||
startRow: (page - 1) * pageSize + 1,
|
||||
endRow: page * pageSize,
|
||||
})
|
||||
|
||||
setPageNo(page)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 퍼블시작 */}
|
||||
<div className="sub-table-box">
|
||||
<div className="table-box-title-wrap">
|
||||
<div className="title-wrap">
|
||||
<h3>물건목록</h3>
|
||||
<h3>{getMessage('stuff.search.grid.title')}</h3>
|
||||
<ul className="info-wrap">
|
||||
<li>
|
||||
전체
|
||||
<span>{convertNumberToPriceDecimal(gridCount)}</span>
|
||||
{getMessage('stuff.search.grid.all')}
|
||||
<span>{convertNumberToPriceDecimal(totalCount)}</span>
|
||||
</li>
|
||||
<li>
|
||||
선택
|
||||
{getMessage('stuff.search.grid.selected')}
|
||||
<span className="red">{convertNumberToPriceDecimal(selectedRowDataCount)}</span>
|
||||
</li>
|
||||
</ul>
|
||||
@ -434,8 +417,8 @@ export default function Stuff() {
|
||||
<div className="left-unit-box">
|
||||
<div className="select-box mr5" style={{ width: '110px' }}>
|
||||
<select className="select-light black" name="" id="" onChange={onChangeSortType}>
|
||||
<option value="R">최근 등록일</option>
|
||||
<option value="U">최근 수정일</option>
|
||||
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
|
||||
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="select-box" style={{ width: '80px' }}>
|
||||
@ -450,7 +433,9 @@ export default function Stuff() {
|
||||
<div className="grid-table-wrap">
|
||||
<div className="q-grid">
|
||||
<StuffQGrid {...gridProps} getSelectedRowdata={getSelectedRowdata} getCellDoubleClicked={getCellDoubleClicked} gridRef={gridRef} />
|
||||
<div className="pagination-wrap">페이징 컴포넌트예정</div>
|
||||
<div className="pagination-wrap">
|
||||
<QPagination pageNo={pageNo} pageSize={pageSize} pagePerBlock={10} totalCount={totalCount} handleChangePage={handleChangePage} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -16,6 +16,8 @@ import FindAddressPop from './popup/FindAddressPop'
|
||||
import PlanRequestPop from './popup/PlanRequestPop'
|
||||
import WindSelectPop from './popup/WindSelectPop'
|
||||
export default function StuffDetail() {
|
||||
const [selOptions, setSelOptions] = useState('')
|
||||
|
||||
const sessionState = useRecoilValue(sessionStore)
|
||||
|
||||
const router = useRouter()
|
||||
@ -79,7 +81,7 @@ export default function StuffDetail() {
|
||||
const [detailData, setDetailData] = useState({})
|
||||
|
||||
useEffect(() => {
|
||||
console.log('objectNo::', objectNo)
|
||||
// console.log('objectNo::', objectNo)
|
||||
|
||||
if (objectNo) {
|
||||
console.log('수정화면')
|
||||
@ -100,33 +102,34 @@ export default function StuffDetail() {
|
||||
// 도도부현API
|
||||
get({ url: '/api/object/prefecture/list' }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
// console.log('신규화면 도도부현API 결과:::', res)
|
||||
setPrefCodeList(res)
|
||||
}
|
||||
})
|
||||
|
||||
// 임시 1차점 판매점코드 saleStoreId=201TES01
|
||||
// T01
|
||||
//1차점 : X167
|
||||
get({ url: `/api/object/saleStore/T01/list` }).then((res) => {
|
||||
// get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
|
||||
//1차점 : X167 T01
|
||||
// get({ url: `/api/object/saleStore/TEMP02/list` }).then((res) => {
|
||||
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
const firstList = res.filter((row) => row.saleStoreLevel === '1')
|
||||
const otherList = res.filter((row) => row.saleStoreLevel !== '1')
|
||||
//1차점 셀렉트박스
|
||||
setSaleStoreList(firstList)
|
||||
setSelOptions(sessionState?.storeId)
|
||||
form.setValue('saleStoreId', sessionState?.storeId)
|
||||
form.setValue('saleStoreLevel', sessionState?.storeLvl)
|
||||
|
||||
//1차점 아닌 판매점 셀렉트박스
|
||||
setOriginOtherSaleStoreList(otherList)
|
||||
setOtherSaleStoreList(otherList)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [objectNo])
|
||||
}, [objectNo, sessionState])
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(detailData)) {
|
||||
console.log('상세데이타:::::::', detailData)
|
||||
|
||||
// 도도부현API
|
||||
get({ url: '/api/object/prefecture/list' }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
@ -151,6 +154,8 @@ export default function StuffDetail() {
|
||||
setOtherSaleStoreList(otherList)
|
||||
}
|
||||
})
|
||||
|
||||
console.log('상세데이타::세팅:::::', detailData)
|
||||
}
|
||||
}, [detailData])
|
||||
|
||||
@ -161,12 +166,14 @@ export default function StuffDetail() {
|
||||
form.setValue('saleStoreId', key.saleStoreId)
|
||||
form.setValue('saleStoreName', key.saleStoreName)
|
||||
form.setValue('saleStoreLevel', key.saleStoreLevel)
|
||||
setSelOptions(key.saleStoreId)
|
||||
//선택한 1차점 정보로 2차점 list 추리기
|
||||
//長府工産株式会社 大阪支社
|
||||
let newOtherSaleStoreList = originOtherSaleStoreList.filter((row) => row.firstAgentId === key.saleStoreId)
|
||||
setOtherSaleStoreList(newOtherSaleStoreList)
|
||||
} else {
|
||||
//X누름
|
||||
setSelOptions('')
|
||||
form.setValue('saleStoreId', '')
|
||||
form.setValue('saleStoreName', '')
|
||||
form.setValue('saleStoreLevel', '')
|
||||
@ -209,8 +216,17 @@ export default function StuffDetail() {
|
||||
form.setValue('zipNo', info.zipNo)
|
||||
}
|
||||
|
||||
//팝업에서 넘어온 설계의뢰 정보
|
||||
const setPlanReqInfo = (info) => {}
|
||||
//팝업에서 넘어온 설계의뢰 정보로 바꾸기
|
||||
const setPlanReqInfo = (info) => {
|
||||
console.log('팝업에서 넘어온 설계의뢰 정보::: ', info)
|
||||
//building : 신축 기축
|
||||
//planReqName : 물건명
|
||||
//zipNo : 우편번호
|
||||
//도도부현 :address1 주소 : address2 미세팅
|
||||
//기준풍속 팝업열려면 setPrefValue(info.prefId) 필요
|
||||
//기준풍속 :
|
||||
// form.setValue('dispCompanyName', info.planReqName)
|
||||
}
|
||||
|
||||
//팝업에서 넘어온 바람정보
|
||||
const setWindSppedInfo = (info) => {
|
||||
@ -286,7 +302,7 @@ export default function StuffDetail() {
|
||||
}
|
||||
|
||||
// console.log('임시저장용::', errors)
|
||||
setIsFormValid(Object.keys(errors).length === 0)
|
||||
setIsFormValid(Object.keys(errors).length === 0 ? true : false)
|
||||
} else {
|
||||
console.log('상세일때 폼체크')
|
||||
}
|
||||
@ -331,9 +347,8 @@ export default function StuffDetail() {
|
||||
// 발전량시뮬레이션 지역 목록
|
||||
get({ url: `/api/object/prefecture/${prefValue}/list` }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
// console.log('발전량 시뮬레이션::::::::', res)
|
||||
form.setValue('areaId', res[0].areaId)
|
||||
form.setValue('areaName', res[0].prefName)
|
||||
// form.setValue('areaId', res[0].areaId)
|
||||
// form.setValue('areaName', res[0].prefName)
|
||||
setAreaIdList(res)
|
||||
}
|
||||
})
|
||||
@ -342,28 +357,18 @@ export default function StuffDetail() {
|
||||
|
||||
// 발전량 시뮬레이션 변경
|
||||
const handleAreaIdOnChange = (e) => {
|
||||
form.setValue('areaId', e.target.value)
|
||||
form.setValue('areaId', e.areaId)
|
||||
form.setValue('areaName', e.prefName)
|
||||
}
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!isEmptyArray(areaIdList)) {
|
||||
// let _prefName = form.watch('prefName')
|
||||
// // console.log('기준풍속 가져오는 API', _prefName)
|
||||
// get({ url: `/api/object/windSpeed/${_prefName}/list` }).then((res) => {
|
||||
// // console.log('res::', res)
|
||||
// if (!isEmptyArray(res)) {
|
||||
// setWindSpeedList(res)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }, [areaIdList])
|
||||
|
||||
//필수값 다 입력했을때
|
||||
const onValid = (data) => {
|
||||
const onValid = (data, e) => {
|
||||
const formData = form.getValues()
|
||||
console.log('필수값 통과:::', data, formData)
|
||||
// console.log('필수값 formData:::', formData)
|
||||
// 수정모드일때는 PUT
|
||||
// console.log('필수값 다 있고 저장')
|
||||
// console.log('data::::::', data)
|
||||
const formData = form.getValues()
|
||||
// console.log('formData::::', formData)
|
||||
// const _dispCompanyName = watch('dispCompanyName')
|
||||
// const _objectStatusId = watch('objectStatusId')
|
||||
@ -391,6 +396,8 @@ export default function StuffDetail() {
|
||||
|
||||
// 임시저장
|
||||
const onTempSave = async () => {
|
||||
console.log('임시저장:::::')
|
||||
return
|
||||
const formData = form.getValues()
|
||||
// console.log('formData::', formData)
|
||||
const params = {
|
||||
@ -441,7 +448,7 @@ export default function StuffDetail() {
|
||||
let testobj = '10'
|
||||
|
||||
del({ url: `/api/object/${testobj}` }).then((res) => {
|
||||
// console.log('삭제 결과:::', res)
|
||||
console.log('삭제 결과:::', res)
|
||||
router.push('/management/stuff')
|
||||
})
|
||||
}
|
||||
@ -470,9 +477,9 @@ export default function StuffDetail() {
|
||||
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
||||
<input type="text" className="input-light" readOnly />
|
||||
</div>
|
||||
<button className="btn-origin grey" onClick={onSearchDesignRequestPopOpen}>
|
||||
<Button className="btn-origin grey" onClick={onSearchDesignRequestPopOpen}>
|
||||
{getMessage('stuff.planReqPopup.title')}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -536,13 +543,21 @@ export default function StuffDetail() {
|
||||
</th>
|
||||
<td>
|
||||
<div className="flx-box">
|
||||
<div style={{ width: '567px', marginRight: '5px' }}>
|
||||
<div className="select-wrap mr5" style={{ width: '567px' }}>
|
||||
<Select
|
||||
id="long-value-select1"
|
||||
instanceId="long-value-select1"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
placeholder="Select"
|
||||
options={saleStoreList}
|
||||
onChange={onSelectionChange}
|
||||
getOptionLabel={(x) => x.saleStoreName}
|
||||
getOptionValue={(x) => x.saleStoreId}
|
||||
isClearable={true}
|
||||
value={saleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -562,8 +577,13 @@ export default function StuffDetail() {
|
||||
</th>
|
||||
<td>
|
||||
<div className="flx-box">
|
||||
<div style={{ width: '567px', marginRight: '5px' }}>
|
||||
<div className="select-wrap mr5" style={{ width: '567px' }}>
|
||||
<Select
|
||||
id="long-value-select2"
|
||||
instanceId="long-value-select2"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
placeholder="Select"
|
||||
ref={ref}
|
||||
options={otherSaleStoreList}
|
||||
onChange={onSelectionChange2}
|
||||
@ -610,13 +630,28 @@ export default function StuffDetail() {
|
||||
<div className="flx-box">
|
||||
<div className="select-wrap" style={{ width: '200px' }}>
|
||||
{prefCodeList?.length > 0 && (
|
||||
<select className="select-light" name="prefName" {...register('prefId')} disabled>
|
||||
{prefCodeList.map((row) => (
|
||||
<option key={row.prefId} value={row.prefId}>
|
||||
{row.prefName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
// <select className="select-light" name="prefName" {...register('prefId')} disabled>
|
||||
// {prefCodeList.map((row) => (
|
||||
// <option key={row.prefId} value={row.prefId}>
|
||||
// {row.prefName}
|
||||
// </option>
|
||||
// ))}
|
||||
// </select>
|
||||
<Select
|
||||
id="long-value-select3"
|
||||
instanceId="long-value-select3"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
placeholder="Select"
|
||||
options={prefCodeList}
|
||||
getOptionLabel={(x) => x.prefName}
|
||||
getOptionValue={(x) => x.prefId}
|
||||
isSearchable={false}
|
||||
value={prefCodeList.filter(function (option) {
|
||||
return option.prefId === prefValue
|
||||
})}
|
||||
isDisabled={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="input-wrap mr5" style={{ width: '580px' }}>
|
||||
@ -631,7 +666,7 @@ export default function StuffDetail() {
|
||||
</th>
|
||||
<td>
|
||||
<div className="select-wrap" style={{ width: '200px' }}>
|
||||
<select
|
||||
{/* <select
|
||||
className="select-light"
|
||||
name="areaId"
|
||||
disabled={areaIdList?.length > 0 ? false : true}
|
||||
@ -643,8 +678,25 @@ export default function StuffDetail() {
|
||||
{row.prefName}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
*/}
|
||||
<Select
|
||||
id="long-value-select4"
|
||||
instanceId="long-value-select4"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
options={areaIdList}
|
||||
placeholder="Select"
|
||||
getOptionLabel={(x) => x.prefName}
|
||||
getOptionValue={(x) => x.areaId}
|
||||
isSearchable={false}
|
||||
onChange={handleAreaIdOnChange}
|
||||
value={areaIdList.filter(function (option) {
|
||||
return option.areaId === form.watch('areaId')
|
||||
})}
|
||||
</select>
|
||||
isDisabled={areaIdList.length > 0 ? false : true}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -669,9 +721,9 @@ export default function StuffDetail() {
|
||||
</select>
|
||||
</div> */}
|
||||
<span className="mr10">{getMessage('stuff.detail.windSpeedSpan')}</span>
|
||||
<button className="btn-origin grey" onClick={onSearchWindSpeedPopOpen}>
|
||||
<Button className="btn-origin grey" onClick={onSearchWindSpeedPopOpen}>
|
||||
{getMessage('stuff.detail.btn.windSpeedPop')}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -764,13 +816,13 @@ export default function StuffDetail() {
|
||||
</div>
|
||||
<div className="sub-table-footer">
|
||||
{!isFormValid ? (
|
||||
<button className="btn-origin grey mr5" onClick={onTempSave}>
|
||||
<Button className="btn-origin grey mr5" onClick={onTempSave}>
|
||||
New화면 임시저장
|
||||
</button>
|
||||
</Button>
|
||||
) : (
|
||||
<button type="submit" className="btn-origin navy mr5">
|
||||
<Button type="submit" className="btn-origin navy mr5">
|
||||
NEW 화면 저장
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
<Link href="/management/stuff">
|
||||
<button type="button" className="btn-origin grey">
|
||||
@ -801,9 +853,9 @@ export default function StuffDetail() {
|
||||
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
||||
<input type="text" className="input-light" readOnly />
|
||||
</div>
|
||||
<button className="btn-origin grey" onClick={onSearchDesignRequestPopOpen}>
|
||||
<Button className="btn-origin grey" onClick={onSearchDesignRequestPopOpen}>
|
||||
{getMessage('stuff.planReqPopup.title')}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -813,7 +865,7 @@ export default function StuffDetail() {
|
||||
</th>
|
||||
<td>
|
||||
<div className="input-wrap" style={{ width: '500px' }}>
|
||||
{/* <input type="text" className="input-light" {...form.register('dispCompanyName')} value={form.watch('dispCompanyName')} /> */}
|
||||
<input type="text" className="input-light" {...form.register('dispCompanyName')} value={form.watch('dispCompanyName')} />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -865,7 +917,7 @@ export default function StuffDetail() {
|
||||
</th>
|
||||
<td>
|
||||
<div className="flx-box">
|
||||
<div style={{ width: '567px', marginRight: '5px' }}>
|
||||
<div className="select-wrap mr5" style={{ width: '567px' }}>
|
||||
{/* <Select
|
||||
options={saleStoreList}
|
||||
value={form.watch('saleStoreId')}
|
||||
@ -890,27 +942,27 @@ export default function StuffDetail() {
|
||||
{objectNo.substring(0, 1) === 'R' ? (
|
||||
<>
|
||||
<Link href="/management/stuff">
|
||||
<button type="button" className="btn-origin grey">
|
||||
<button type="button" className="btn-origin grey mr5">
|
||||
R상세:물건목록
|
||||
</button>
|
||||
</Link>
|
||||
<button type="submit" className="btn-origin navy mr5">
|
||||
<Button type="submit" className="btn-origin navy mr5">
|
||||
R상세:저장
|
||||
</button>
|
||||
<button type="submit" className="btn-origin navy mr5" onClick={onDelete}>
|
||||
</Button>
|
||||
<Button type="submit" className="btn-origin navy" onClick={onDelete}>
|
||||
R상세:물건삭제
|
||||
</button>
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{!isFormValid ? (
|
||||
<button type="submit" className="btn-origin navy mr5" onClick={onTempSave}>
|
||||
<Button type="submit" className="btn-origin navy mr5" onClick={onTempSave}>
|
||||
TEMP상세:임시저장
|
||||
</button>
|
||||
</Button>
|
||||
) : (
|
||||
<button type="submit" className="btn-origin navy mr5">
|
||||
<Button type="submit" className="btn-origin navy mr5">
|
||||
TEMP상세:저장
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
<Link href="/management/stuff">
|
||||
<button type="button" className="btn-origin grey">
|
||||
@ -923,7 +975,14 @@ export default function StuffDetail() {
|
||||
)}
|
||||
{showAddressButtonValid && <FindAddressPop setShowAddressButtonValid={setShowAddressButtonValid} zipInfo={setZipInfo} />}
|
||||
{showDesignRequestButtonValid && (
|
||||
<PlanRequestPop setShowDesignRequestButtonValid={setShowDesignRequestButtonValid} planReqInfo={setPlanReqInfo} />
|
||||
<PlanRequestPop
|
||||
setShowDesignRequestButtonValid={setShowDesignRequestButtonValid}
|
||||
saleStoreId={form.watch('saleStoreId')}
|
||||
saleStoreLevel={form.watch('saleStoreLevel')}
|
||||
otherSaleStoreId={form.watch('otherSaleStoreId')}
|
||||
otherSaleStoreLevel={form.watch('otherSaleStoreLevel')}
|
||||
planReqInfo={setPlanReqInfo}
|
||||
/>
|
||||
)}
|
||||
{showWindSpeedButtonValid && (
|
||||
<WindSelectPop setShowWindSpeedButtonValid={setShowWindSpeedButtonValid} prefName={form.watch('prefName')} windSpeedInfo={setWindSppedInfo} />
|
||||
|
||||
@ -69,12 +69,6 @@ export default function StuffQGrid(props) {
|
||||
props.getCellDoubleClicked(event)
|
||||
}, [])
|
||||
|
||||
const autoSizeStrategy = useMemo(() => {
|
||||
return {
|
||||
type: 'fitCellContents',
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Fetch data & update rowData state
|
||||
useEffect(() => {
|
||||
gridData ? setRowData(gridData) : ''
|
||||
|
||||
@ -18,13 +18,19 @@ import { useMessage } from '@/hooks/useMessage'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
export default function StuffSearchCondition() {
|
||||
const sessionState = useRecoilValue(sessionStore)
|
||||
|
||||
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
const { getMessage } = useMessage()
|
||||
const ref = useRef()
|
||||
const { get } = useAxios(globalLocaleState)
|
||||
|
||||
const objectNoRef = useRef(null)
|
||||
const saleStoreNameRef = useRef(null)
|
||||
const addressRef = useRef(null)
|
||||
const objectNameRef = useRef(null)
|
||||
const dispCompanyNameRef = useRef(null)
|
||||
const receiveUserRef = useRef(null)
|
||||
|
||||
//달력 props 관련 날짜 셋팅
|
||||
const [startDate, setStartDate] = useState(dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'))
|
||||
const [endDate, setEndDate] = useState(dayjs(new Date()).format('YYYY-MM-DD'))
|
||||
@ -43,13 +49,13 @@ export default function StuffSearchCondition() {
|
||||
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
|
||||
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
||||
const [objectNo, setObjectNo] = useState('') //물건번호
|
||||
const [saleStoreName, setSaleStoreName] = useState('') //판매대리점명
|
||||
const [address, setAddress] = useState('') //물건주소
|
||||
const [objectName, setobjectName] = useState('') //물건명
|
||||
const [saleStoreName, setSaleStoreName] = useState('') //판매대리점명
|
||||
const [receiveUser, setReceiveUser] = useState('') //담당자
|
||||
const [dispCompanyName, setDispCompanyName] = useState('') //견적처
|
||||
const [dateType, setDateType] = useState('U') //갱신일(U)/등록일(R)
|
||||
const [schSelSaleStoreId, setSchSelSaleStoreId] = useState('') //판매대리점 선택
|
||||
const [receiveUser, setReceiveUser] = useState('') //담당자
|
||||
const [dateType, setDateType] = useState('U') //갱신일(U)/등록일(R)
|
||||
|
||||
const [schSelSaleStoreList, setSchSelSaleStoreList] = useState([]) //판매대리점 자동완성 SELECT
|
||||
// 조회
|
||||
@ -59,30 +65,52 @@ export default function StuffSearchCondition() {
|
||||
return alert(getMessage('stuff.message.periodError'))
|
||||
}
|
||||
|
||||
setStuffSearch({
|
||||
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
||||
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
||||
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
||||
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
||||
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
||||
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
||||
schDateType: stuffSearch?.schDateType ? stuffSearch.schDateType : dateType,
|
||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
||||
code: 'E',
|
||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : schSelSaleStoreId,
|
||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||
selObject: {
|
||||
label: stuffSearch.selObject.label,
|
||||
value: stuffSearch.selObject.value,
|
||||
},
|
||||
})
|
||||
if (stuffSearch.code === 'S') {
|
||||
setStuffSearch({
|
||||
schObjectNo: objectNo ? objectNo : stuffSearch?.schObjectNo,
|
||||
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch?.schSaleStoreName : saleStoreName,
|
||||
schAddress: address ? address : stuffSearch?.schAddress,
|
||||
schObjectName: objectName ? objectName : stuffSearch?.schObjectName,
|
||||
schDispCompanyName: dispCompanyName ? dispCompanyName : stuffSearch?.schDispCompanyName,
|
||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : schSelSaleStoreId,
|
||||
schReceiveUser: receiveUser ? receiveUser : stuffSearch?.schReceiveUser,
|
||||
schDateType: stuffSearch?.schDateType ? stuffSearch.schDateType : dateType,
|
||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
||||
code: 'E',
|
||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||
})
|
||||
} else {
|
||||
setStuffSearch({
|
||||
schObjectNo: objectNo ? objectNo : '',
|
||||
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
||||
schAddress: address ? address : '',
|
||||
schObjectName: objectName ? objectName : '',
|
||||
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
||||
schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : '',
|
||||
schReceiveUser: receiveUser ? receiveUser : '',
|
||||
schDateType: dateType,
|
||||
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
|
||||
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
|
||||
code: 'E',
|
||||
startRow: 1,
|
||||
endRow: 100,
|
||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//초기화
|
||||
const resetRecoil = () => {
|
||||
objectNoRef.current.value = ''
|
||||
saleStoreNameRef.current.value = ''
|
||||
addressRef.current.value = ''
|
||||
objectNameRef.current.value = ''
|
||||
dispCompanyNameRef.current.value = ''
|
||||
receiveUserRef.current.value = ''
|
||||
|
||||
setObjectNo('')
|
||||
setAddress('')
|
||||
setobjectName('')
|
||||
@ -99,9 +127,8 @@ export default function StuffSearchCondition() {
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(sessionState)) {
|
||||
// console.log('판매대리점 리스트 가져오기 위한 세션정보::::::::', sessionState)
|
||||
// storeId가 T01 이거나 1차점일때만 판매대리점 선택 활성화
|
||||
// get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => {
|
||||
// get({ url: `/api/object/saleStore/TEMP02/list` }).then((res) => {
|
||||
get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
res.map((row) => {
|
||||
@ -129,7 +156,6 @@ export default function StuffSearchCondition() {
|
||||
...stuffSearch,
|
||||
code: 'S',
|
||||
schSelSaleStoreId: key.saleStoreId,
|
||||
selObject: { value: key.saleStoreId, label: key.saleStoreName },
|
||||
})
|
||||
} else {
|
||||
setSchSelSaleStoreId('')
|
||||
@ -150,6 +176,13 @@ export default function StuffSearchCondition() {
|
||||
}
|
||||
}, [globalLocaleState])
|
||||
|
||||
// 엔터 이벤트
|
||||
const handleByOnKeyUp = (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
onSubmit()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 퍼블적용시작 */}
|
||||
@ -159,7 +192,7 @@ export default function StuffSearchCondition() {
|
||||
<h3>{getMessage('stuff.search.title')}</h3>
|
||||
</div>
|
||||
<div className="left-unit-box">
|
||||
<Link href="/management/stuff/tempdetail">
|
||||
<Link href="/management/stuff/tempdetail" scroll={false}>
|
||||
<button type="button" className="btn-origin navy mr5">
|
||||
{getMessage('stuff.search.btn1')}
|
||||
</button>
|
||||
@ -189,13 +222,13 @@ export default function StuffSearchCondition() {
|
||||
<div className="input-wrap">
|
||||
<input
|
||||
type="text"
|
||||
ref={objectNoRef}
|
||||
className="input-light"
|
||||
// placeholder="물건번호 입력"
|
||||
value={stuffSearch?.code === 'E' || stuffSearch?.code === 'M' ? stuffSearch.schObjectNo : objectNo}
|
||||
defaultValue={stuffSearch.code === 'E' || stuffSearch.code === 'M' ? stuffSearch?.schObjectNo : objectNo}
|
||||
onChange={(e) => {
|
||||
setObjectNo(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schObjectNo: e.target.value })
|
||||
setObjectNo(objectNoRef.current.value)
|
||||
}}
|
||||
onKeyUp={handleByOnKeyUp}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -204,12 +237,11 @@ export default function StuffSearchCondition() {
|
||||
<div className="input-wrap">
|
||||
<input
|
||||
type="text"
|
||||
ref={saleStoreNameRef}
|
||||
className="input-light"
|
||||
// placeholder="판매대리점명 입력"
|
||||
value={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
|
||||
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schSaleStoreName : saleStoreName}
|
||||
onChange={(e) => {
|
||||
setSaleStoreName(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schSaleStoreName: e.target.value })
|
||||
setSaleStoreName(saleStoreNameRef.current.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -219,12 +251,11 @@ export default function StuffSearchCondition() {
|
||||
<div className="input-wrap">
|
||||
<input
|
||||
type="text"
|
||||
ref={addressRef}
|
||||
className="input-light"
|
||||
// placeholder="물건주소 입력"
|
||||
value={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
|
||||
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schAddress : address}
|
||||
onChange={(e) => {
|
||||
setAddress(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schAddress: e.target.value })
|
||||
setAddress(addressRef.current.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -236,12 +267,11 @@ export default function StuffSearchCondition() {
|
||||
<div className="input-wrap">
|
||||
<input
|
||||
type="text"
|
||||
ref={objectNameRef}
|
||||
className="input-light"
|
||||
// placeholder="물건명 입력"
|
||||
value={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
|
||||
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schObjectName : objectName}
|
||||
onChange={(e) => {
|
||||
setobjectName(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schObjectName: e.target.value })
|
||||
setobjectName(objectNameRef.current.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -251,30 +281,50 @@ export default function StuffSearchCondition() {
|
||||
<div className="input-wrap">
|
||||
<input
|
||||
type="text"
|
||||
ref={dispCompanyNameRef}
|
||||
className="input-light"
|
||||
// placeholder="견적처 입력"
|
||||
value={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
|
||||
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schDispCompanyName : dispCompanyName}
|
||||
onChange={(e) => {
|
||||
setDispCompanyName(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schDispCompanyName: e.target.value })
|
||||
setDispCompanyName(dispCompanyNameRef.current.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<th>{getMessage('stuff.search.schSelSaleStoreId')}</th>
|
||||
<td>
|
||||
{schSelSaleStoreList?.length > 0 && (
|
||||
<Select
|
||||
ref={ref}
|
||||
options={schSelSaleStoreList}
|
||||
onChange={onSelectionChange}
|
||||
getOptionLabel={(x) => x.saleStoreName}
|
||||
getOptionValue={(x) => x.saleStoreId}
|
||||
defaultValue={stuffSearch?.selObject?.value ? stuffSearch?.selObject : null}
|
||||
isDisabled={sessionState?.storeLvl === '1' ? false : true}
|
||||
isClearable={true}
|
||||
/>
|
||||
)}
|
||||
<div className="select-wrap">
|
||||
{schSelSaleStoreList?.length > 0 && (
|
||||
<Select
|
||||
id="long-value-select1"
|
||||
instanceId="long-value-select1"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
placeholder="Select"
|
||||
ref={ref}
|
||||
options={schSelSaleStoreList}
|
||||
onChange={onSelectionChange}
|
||||
getOptionLabel={(x) => x.saleStoreName}
|
||||
getOptionValue={(x) => x.saleStoreId}
|
||||
value={schSelSaleStoreList.filter(function (option) {
|
||||
if (stuffSearch?.code === 'S' && schSelSaleStoreId === '') {
|
||||
return false
|
||||
} else if (stuffSearch?.code === 'S' && schSelSaleStoreId !== '') {
|
||||
return option.saleStoreId === schSelSaleStoreId
|
||||
} else if (stuffSearch?.code === 'E' && schSelSaleStoreId !== '') {
|
||||
return option.saleStoreId === schSelSaleStoreId
|
||||
} else {
|
||||
if (stuffSearch?.schSelSaleStoreId !== '') {
|
||||
return option.saleStoreId === stuffSearch.schSelSaleStoreId
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
})}
|
||||
isDisabled={sessionState?.storeLvl === '1' ? false : true}
|
||||
isClearable={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -284,11 +334,10 @@ export default function StuffSearchCondition() {
|
||||
<input
|
||||
type="text"
|
||||
className="input-light"
|
||||
// placeholder="담당자 입력"
|
||||
value={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser}
|
||||
ref={receiveUserRef}
|
||||
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schReceiveUser : receiveUser}
|
||||
onChange={(e) => {
|
||||
setReceiveUser(e.target.value)
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schReceiveUser: e.target.value })
|
||||
setReceiveUser(receiveUserRef.current.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@ -323,7 +372,7 @@ export default function StuffSearchCondition() {
|
||||
setStuffSearch({ ...stuffSearch, code: 'S', schDateType: e.target.value })
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="radio_r">{getMessage('stuff.search.schDateTypeR')}등록일</label>
|
||||
<label htmlFor="radio_r">{getMessage('stuff.search.schDateTypeR')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="date-picker-wrap">
|
||||
|
||||
@ -79,7 +79,6 @@ export default function FindAddressPop(props) {
|
||||
}
|
||||
// 주소적용 클릭
|
||||
const applyAddress = () => {
|
||||
// console.log('주소적용 클릭:::::::::', prefId, address1, address2, address3, zipNo)
|
||||
if (prefId == null) {
|
||||
alert(getMessage('stuff.addressPopup.error.message2'))
|
||||
} else {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { queryStringFormatter } from '@/util/common-utils'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||
@ -12,14 +11,24 @@ import dayjs from 'dayjs'
|
||||
import PlanRequestPopQGrid from './PlanRequestPopQGrid'
|
||||
import { sessionStore } from '@/store/commonAtom'
|
||||
import { planReqSearchState } from '@/store/planReqAtom'
|
||||
import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
||||
|
||||
import Select from 'react-select'
|
||||
import QPagination from '@/components/common/pagination/QPagination'
|
||||
export default function PlanRequestPop(props) {
|
||||
const sessionState = useRecoilValue(sessionStore)
|
||||
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
||||
const [pageSize, setPageSize] = useState(20) //페이지 당 게시물 개수
|
||||
const [totalCount, setTotalCount] = useState(0) //총 갯수
|
||||
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
|
||||
const { get } = useAxios(globalLocaleState)
|
||||
const [planReqObject, setPlanReqObject] = useState({})
|
||||
|
||||
const { get, promiseGet } = useAxios(globalLocaleState)
|
||||
|
||||
const { getMessage } = useMessage()
|
||||
//Select ref
|
||||
const ref = useRef()
|
||||
// 검색조건 달력 셋팅
|
||||
const [startDate, setStartDate] = useState(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD'))
|
||||
const [endDate, setEndDate] = useState(dayjs(new Date()).format('YYYY-MM-DD'))
|
||||
@ -34,7 +43,6 @@ export default function PlanRequestPop(props) {
|
||||
setStartDate: setEndDate,
|
||||
}
|
||||
|
||||
const ref = useRef()
|
||||
const resetPlanReqRecoil = useResetRecoilState(planReqSearchState)
|
||||
|
||||
const [planReqSearch, setPlanReqSearch] = useRecoilState(planReqSearchState)
|
||||
@ -47,14 +55,41 @@ export default function PlanRequestPop(props) {
|
||||
const [schDateGbn, setSchDateGbn] = useState('S') //기간구분코드(S/R)
|
||||
|
||||
//초기화
|
||||
const resetRecoil = () => {}
|
||||
const resetRecoil = () => {
|
||||
setSchPlanReqNo('')
|
||||
setSchTitle('')
|
||||
setSchAddress('')
|
||||
setSchSaleStoreName('')
|
||||
setSchPlanReqName('')
|
||||
setSchDateGbn('S')
|
||||
setStartDate(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD'))
|
||||
setEndDate(dayjs(new Date()).format('YYYY-MM-DD'))
|
||||
setSchPlanStatCd('')
|
||||
handleClear() //셀렉트 자동완성 초기화
|
||||
resetPlanReqRecoil()
|
||||
}
|
||||
|
||||
//초기화 눌렀을 때 자동완성도..
|
||||
//셀렉트 자동완성 초기화
|
||||
const handleClear = () => {
|
||||
if (ref.current.state.dropDown) {
|
||||
ref.current.methods.dropDown()
|
||||
if (ref.current) {
|
||||
ref.current.clearValue()
|
||||
}
|
||||
}
|
||||
|
||||
// 상태 검색조건 변경
|
||||
const onSelectionChange = (key) => {
|
||||
//임시작업
|
||||
// console.log('E::::::::', key)
|
||||
if (isObjectNotEmpty(key)) {
|
||||
setSchPlanStatCd(key.value)
|
||||
setPlanReqSearch({
|
||||
...planReqSearch,
|
||||
schPlanStatCd: key.value,
|
||||
})
|
||||
} else {
|
||||
ref.current.state.values = []
|
||||
//X누름
|
||||
setSchPlanStatCd('')
|
||||
setPlanReqSearch({ ...planReqSearch, schPlanStatCd: '' })
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +98,60 @@ export default function PlanRequestPop(props) {
|
||||
setEndDate(planReqSearch?.schEndDt ? planReqSearch.schEndDt : dayjs(new Date()).format('YYYY-MM-DD'))
|
||||
}, [planReqSearch])
|
||||
|
||||
// 조회
|
||||
const onSubmit = (page, type) => {
|
||||
const params = {
|
||||
// saleStoreId: 'T100',
|
||||
// saleStoreLevel: '1',
|
||||
saleStoreId: props?.otherSaleStoreId ? props.otherSaleStoreId : props.saleStoreId,
|
||||
saleStoreLevel: props?.otherSaleStoreLevel ? props.otherSaleStoreLevel : props.saleStoreLevel,
|
||||
schPlanReqNo: planReqSearch?.schPlanReqNo ? planReqSearch.schPlanReqNo : schPlanReqNo,
|
||||
schTitle: planReqSearch?.schTitle ? planReqSearch.schTitle : schTitle,
|
||||
schAddress: planReqSearch?.schAddress ? planReqSearch.schAddress : schAddress,
|
||||
schSaleStoreName: planReqSearch?.schSaleStoreName ? planReqSearch.schSaleStoreName : schSaleStoreName,
|
||||
schPlanReqName: planReqSearch?.schPlanReqName ? planReqSearch.schPlanReqName : schPlanReqName,
|
||||
schPlanStatCd: planReqSearch?.schPlanStatCd ? planReqSearch.schPlanStatCd : schPlanStatCd,
|
||||
schDateGbn: planReqSearch?.schDateGbn ? planReqSearch.schDateGbn : schDateGbn,
|
||||
schStartDt: dayjs(startDate).format('YYYY-MM-DD'),
|
||||
schEndDt: dayjs(endDate).format('YYYY-MM-DD'),
|
||||
startRow: type === 'S' ? (1 - 1) * pageSize + 1 : (page - 1) * pageSize + 1,
|
||||
endRow: type === 'S' ? 1 * pageSize : page * pageSize,
|
||||
}
|
||||
if (type === 'S') {
|
||||
setPageNo(1)
|
||||
} else {
|
||||
setPageNo(page)
|
||||
}
|
||||
// console.log(params)
|
||||
|
||||
const apiUrl = `/api/object/planReq/list?${queryStringFormatter(params)}`
|
||||
promiseGet({ url: apiUrl }).then((res) => {
|
||||
if (res.status === 200) {
|
||||
if (isNotEmptyArray(res.data.data)) {
|
||||
setGridProps({ ...gridProps, gridData: res.data.data, gridCount: res.data.data[0].totCnt })
|
||||
setTotalCount(res.data.data[0].totCnt)
|
||||
} else {
|
||||
setGridProps({ ...gridProps, gridData: [], gridCount: 0 })
|
||||
setTotalCount(0)
|
||||
}
|
||||
} else {
|
||||
setGridProps({ ...gridProps, gridData: [], gridCount: 0 })
|
||||
setTotalCount(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
// 페이징 현재페이지 변경
|
||||
const handleChangePage = (page) => {
|
||||
setPlanReqSearch({
|
||||
...planReqSearch,
|
||||
startRow: (page - 1) * pageSize + 1,
|
||||
endRow: page * pageSize,
|
||||
})
|
||||
setPageNo(page)
|
||||
|
||||
onSubmit(page, 'P')
|
||||
}
|
||||
|
||||
const [gridProps, setGridProps] = useState({
|
||||
gridData: [],
|
||||
isPageable: false,
|
||||
@ -117,6 +206,45 @@ export default function PlanRequestPop(props) {
|
||||
],
|
||||
})
|
||||
|
||||
//설계의뢰 그리드에서 선택한 설계의로 정보
|
||||
const getSelectedRowdata = (data) => {
|
||||
if (isNotEmptyArray(data)) {
|
||||
setPlanReqObject(data[0])
|
||||
} else {
|
||||
setPlanReqObject({})
|
||||
}
|
||||
}
|
||||
|
||||
// 설계의뢰 적용 클릭
|
||||
const applyPlanReq = () => {
|
||||
if (isObjectNotEmpty(planReqObject)) {
|
||||
props.planReqInfo(planReqObject)
|
||||
// 팝업닫기
|
||||
props.setShowDesignRequestButtonValid(false)
|
||||
} else {
|
||||
alert(getMessage('stuff.planReqPopup.error.message1'))
|
||||
}
|
||||
}
|
||||
|
||||
const tempList = [
|
||||
{
|
||||
label: '완료',
|
||||
value: 'C',
|
||||
},
|
||||
{
|
||||
label: '저장',
|
||||
value: 'I',
|
||||
},
|
||||
{
|
||||
label: '접수',
|
||||
value: 'R',
|
||||
},
|
||||
{
|
||||
label: '제출',
|
||||
value: 'S',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="modal-popup">
|
||||
<div className="modal-dialog big">
|
||||
@ -132,8 +260,17 @@ export default function PlanRequestPop(props) {
|
||||
<div className="design-tit-wrap">
|
||||
<h3>{getMessage('stuff.planReqPopup.popTitle')}</h3>
|
||||
<div className="design-search-wrap">
|
||||
<button className="btn-origin grey mr5">{getMessage('stuff.planReqPopup.btn1')}</button>
|
||||
<button className="btn-origin navy ">{getMessage('stuff.planReqPopup.btn2')}</button>
|
||||
<button
|
||||
className="btn-origin navy mr5"
|
||||
onClick={() => {
|
||||
onSubmit(pageNo, 'S')
|
||||
}}
|
||||
>
|
||||
{getMessage('stuff.planReqPopup.btn1')}
|
||||
</button>
|
||||
<button className="btn-origin grey" onClick={resetRecoil}>
|
||||
{getMessage('stuff.planReqPopup.btn2')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="design-request-table">
|
||||
@ -224,12 +361,18 @@ export default function PlanRequestPop(props) {
|
||||
<th>{getMessage('stuff.planReqPopup.search.planStatName')}</th>
|
||||
<td>
|
||||
<div className="select-wrap">
|
||||
<select className="select-light" name="" id="">
|
||||
<option value={''}>All</option>
|
||||
<option value={'SAVE'}>저장</option>
|
||||
<option value={'SUBMIT'}>제출</option>
|
||||
<option value={'RECEIPT'}>접수</option>
|
||||
</select>
|
||||
<Select
|
||||
id="long-value-select1"
|
||||
instanceId="long-value-select1"
|
||||
className="react-select-custom"
|
||||
classNamePrefix="custom"
|
||||
ref={ref}
|
||||
options={tempList}
|
||||
onChange={onSelectionChange}
|
||||
isSearchable={false}
|
||||
placeholder="Select"
|
||||
isClearable={true}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -285,14 +428,19 @@ export default function PlanRequestPop(props) {
|
||||
</div>
|
||||
<div className="design-request-grid">
|
||||
<div className="design-request-grid-tit">Plan List</div>
|
||||
<PlanRequestPopQGrid {...gridProps} />
|
||||
<PlanRequestPopQGrid {...gridProps} getSelectedRowdata={getSelectedRowdata} />
|
||||
<div className="pagination-wrap">
|
||||
<QPagination pageNo={pageNo} pageSize={pageSize} pagePerBlock={10} totalCount={totalCount} handleChangePage={handleChangePage} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="footer-btn-wrap">
|
||||
<button className="btn-origin grey mr5" onClick={() => props.setShowDesignRequestButtonValid(false)}>
|
||||
{getMessage('stuff.planReqPopup.btn3')}
|
||||
</button>
|
||||
<button className="btn-origin navy ">{getMessage('stuff.planReqPopup.btn4')}</button>
|
||||
<button className="btn-origin navy" onClick={applyPlanReq}>
|
||||
{getMessage('stuff.planReqPopup.btn4')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -39,8 +39,14 @@ export default function PlanRequestPopQGrid(props) {
|
||||
[gridData],
|
||||
)
|
||||
|
||||
//부모로 선택한 설계의뢰정보 보내기
|
||||
const onSelectionChanged = () => {
|
||||
const selectedData = gridApi.getSelectedRows()
|
||||
props.getSelectedRowdata(selectedData)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ag-theme-quartz" style={{ height: 500 }}>
|
||||
<div className="ag-theme-quartz" style={{ height: 350 }}>
|
||||
<AgGridReact
|
||||
onGridReady={onGridReady}
|
||||
rowBuffer={rowBuffer}
|
||||
@ -49,7 +55,7 @@ export default function PlanRequestPopQGrid(props) {
|
||||
defaultColDef={defaultColDef}
|
||||
rowSelection={'singleRow'}
|
||||
pagination={isPageable}
|
||||
// onSelectionChanged={onSelectionChanged}
|
||||
onSelectionChanged={onSelectionChanged}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -150,7 +150,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.userId')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={userId} readOnly />
|
||||
<input type="text" className="input-light" value={userId || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -158,7 +158,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.nameKana')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.nameKana} readOnly />
|
||||
<input type="text" className="input-light" value={info?.nameKana || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -166,7 +166,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.name')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.name} readOnly />
|
||||
<input type="text" className="input-light" value={info?.name || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -235,7 +235,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.category')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.groupName} readOnly />
|
||||
<input type="text" className="input-light" value={info?.groupName || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -243,7 +243,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.tel')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.tel} readOnly />
|
||||
<input type="text" className="input-light" value={info?.tel || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -251,7 +251,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.fax')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.fax} readOnly />
|
||||
<input type="text" className="input-light" value={info?.fax || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@ -259,7 +259,7 @@ export default function UserInfoModal({ userId, userInfoModal, setUserInfoModal
|
||||
<th>{getMessage('myinfo.info.mail')}</th>
|
||||
<td>
|
||||
<div className="input-wrap">
|
||||
<input type="text" className="input-light" value={info?.mail} readOnly />
|
||||
<input type="text" className="input-light" value={info?.mail || ''} readOnly />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -4,14 +4,7 @@ import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { INPUT_TYPE, BATCH_TYPE } from '@/common/common'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import {
|
||||
polygonToTurfPolygon,
|
||||
rectToPolygon,
|
||||
triangleToPolygon,
|
||||
pointsToTurfPolygon,
|
||||
splitDormerTriangle,
|
||||
setSurfaceShapePattern,
|
||||
} from '@/util/canvas-util'
|
||||
import { polygonToTurfPolygon, rectToPolygon, triangleToPolygon, pointsToTurfPolygon, setSurfaceShapePattern } from '@/util/canvas-util'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import * as turf from '@turf/turf'
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
@ -211,11 +204,13 @@ export function useObjectBatch() {
|
||||
const dormerName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER : BATCH_TYPE.PENTAGON_DORMER
|
||||
const dormerTempName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER_TEMP : BATCH_TYPE.PENTAGON_DORMER_TEMP
|
||||
const height = dormerPlacement.heightRef.current.value / 10
|
||||
const width = dormerPlacement.widthRef.current.value / 10
|
||||
const pitch = dormerPlacement.pitchRef.current.value
|
||||
const directionRef = dormerPlacement.directionRef.current
|
||||
const offsetRef = dormerPlacement.offsetRef.current.value === '' ? 0 : parseInt(dormerPlacement.offsetRef.current.value) / 10
|
||||
const offsetWidthRef = dormerPlacement.offsetWidthRef.current.value === '' ? 0 : parseInt(dormerPlacement.offsetWidthRef.current.value) / 10
|
||||
const directionRef = dormerPlacement.directionRef.current
|
||||
|
||||
let dormer, dormerOffset, isDown, selectedSurface
|
||||
let dormer, dormerOffset, isDown, selectedSurface, pentagonPoints, pentagonOffsetPoints
|
||||
|
||||
console.log('dormerPlacement', dormerPlacement)
|
||||
|
||||
@ -229,8 +224,6 @@ export function useObjectBatch() {
|
||||
const bottomLength = height / (pitch * 0.25)
|
||||
const bottomOffsetLength = (height + offsetRef) / (pitch * 0.25)
|
||||
|
||||
console.log(bottomOffsetLength)
|
||||
|
||||
addCanvasMouseEventListener('mouse:move', (e) => {
|
||||
isDown = true
|
||||
if (!isDown) return
|
||||
@ -305,16 +298,16 @@ export function useObjectBatch() {
|
||||
|
||||
addCanvasMouseEventListener('mouse:up', (e) => {
|
||||
if (dormer) {
|
||||
// const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
|
||||
// const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
|
||||
const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
|
||||
const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
|
||||
|
||||
// //지붕 밖으로 그렸을때
|
||||
// if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
|
||||
// swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
|
||||
// //일단 지워
|
||||
// deleteTempObjects()
|
||||
// return
|
||||
// }
|
||||
//지붕 밖으로 그렸을때
|
||||
if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
|
||||
swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
|
||||
//일단 지워
|
||||
deleteTempObjects()
|
||||
return
|
||||
}
|
||||
|
||||
//각도 추가
|
||||
let originAngle = 0 //기본 남쪽
|
||||
@ -387,6 +380,183 @@ export function useObjectBatch() {
|
||||
drawDirectionArrow(leftTriangle)
|
||||
drawDirectionArrow(rightTriangle)
|
||||
|
||||
isDown = false
|
||||
initEvent()
|
||||
}
|
||||
})
|
||||
} else if (buttonAct === 4) {
|
||||
const heightLength = height - (width / 2) * (pitch * 0.25)
|
||||
//(동의길이 깊이)+출폭(깊이)-[(입력한 폭값)/2+출폭(폭)]*(0.25*입력한 寸)
|
||||
const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25)
|
||||
|
||||
addCanvasMouseEventListener('mouse:move', (e) => {
|
||||
isDown = true
|
||||
if (!isDown) return
|
||||
|
||||
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === dormerTempName)) //움직일때 일단 지워가면서 움직임
|
||||
const pointer = canvas.getPointer(e.e)
|
||||
|
||||
surfaceShapePolygons.forEach((surface) => {
|
||||
if (surface.inPolygon({ x: pointer.x, y: pointer.y })) {
|
||||
selectedSurface = surface
|
||||
}
|
||||
})
|
||||
|
||||
let angle = 0
|
||||
if (directionRef === 'left') {
|
||||
//서
|
||||
angle = 90
|
||||
} else if (directionRef === 'right') {
|
||||
//동
|
||||
angle = 270
|
||||
} else if (directionRef === 'up') {
|
||||
//북
|
||||
angle = 180
|
||||
}
|
||||
|
||||
pentagonPoints = [
|
||||
{ x: pointer.x, y: pointer.y },
|
||||
{ x: pointer.x - width / 2, y: pointer.y + (height - heightLength) },
|
||||
{ x: pointer.x - width / 2, y: pointer.y + height },
|
||||
{ x: pointer.x + width / 2, y: pointer.y + height },
|
||||
{ x: pointer.x + width / 2, y: pointer.y + (height - heightLength) },
|
||||
]
|
||||
|
||||
pentagonOffsetPoints = [
|
||||
{ x: pointer.x, y: pointer.y },
|
||||
{ x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength },
|
||||
{ x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef },
|
||||
{ x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef },
|
||||
{ x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength },
|
||||
]
|
||||
|
||||
dormer = new QPolygon(pentagonPoints, {
|
||||
fill: 'white',
|
||||
stroke: 'red',
|
||||
strokeDashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true,
|
||||
lockMovementY: true,
|
||||
lockRotation: true,
|
||||
lockScalingX: true,
|
||||
lockScalingY: true,
|
||||
name: dormerTempName,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
angle: angle,
|
||||
})
|
||||
canvas?.add(dormer)
|
||||
|
||||
if (offsetRef > 0 || offsetWidthRef > 0) {
|
||||
dormerOffset = new QPolygon(pentagonOffsetPoints, {
|
||||
fill: 'gray',
|
||||
stroke: 'red',
|
||||
strokeDashArray: [5, 5],
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true,
|
||||
lockMovementY: true,
|
||||
lockRotation: true,
|
||||
lockScalingX: true,
|
||||
lockScalingY: true,
|
||||
name: dormerTempName,
|
||||
originX: 'center',
|
||||
originY: 'top',
|
||||
angle: angle,
|
||||
})
|
||||
canvas?.add(dormerOffset)
|
||||
}
|
||||
})
|
||||
|
||||
addCanvasMouseEventListener('mouse:up', (e) => {
|
||||
if (dormer) {
|
||||
// const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
|
||||
// const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
|
||||
|
||||
// //지붕 밖으로 그렸을때
|
||||
// if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
|
||||
// swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
|
||||
// //일단 지워
|
||||
// deleteTempObjects()
|
||||
// return
|
||||
// }
|
||||
|
||||
//각도 추가
|
||||
let originAngle = 0 //기본 남쪽
|
||||
let direction = 'south'
|
||||
|
||||
if (directionRef === 'left') {
|
||||
//서
|
||||
originAngle = 90
|
||||
direction = 'west'
|
||||
} else if (directionRef === 'right') {
|
||||
//동
|
||||
originAngle = 270
|
||||
direction = 'east'
|
||||
} else if (directionRef === 'up') {
|
||||
//북
|
||||
originAngle = 180
|
||||
direction = 'north'
|
||||
}
|
||||
|
||||
const offsetMode = offsetRef > 0 || offsetWidthRef > 0 ? 'offset' : 'normal'
|
||||
let splitedPentagon =
|
||||
offsetRef > 0 || offsetWidthRef > 0
|
||||
? splitDormerPentagon(dormerOffset, directionRef, offsetMode)
|
||||
: splitDormerPentagon(dormer, directionRef, offsetMode)
|
||||
canvas?.remove(offsetRef > 0 || offsetWidthRef > 0 ? dormerOffset : dormer)
|
||||
|
||||
if (offsetRef > 0)
|
||||
dormer.set({
|
||||
name: dormerName,
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [0],
|
||||
}) //오프셋이 있을땐 같이 도머로 만든다
|
||||
|
||||
const leftPentagon = new QPolygon(splitedPentagon[0], {
|
||||
fill: 'transparent',
|
||||
stroke: 'red',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
fontSize: 14,
|
||||
direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
})
|
||||
|
||||
const rightPentagon = new QPolygon(splitedPentagon[1], {
|
||||
fill: 'transparent',
|
||||
stroke: 'red',
|
||||
strokeWidth: 1,
|
||||
selectable: true,
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
viewLengthText: true,
|
||||
fontSize: 14,
|
||||
direction: direction,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
name: dormerName,
|
||||
})
|
||||
|
||||
canvas?.add(leftPentagon)
|
||||
canvas?.add(rightPentagon)
|
||||
|
||||
//패턴
|
||||
setSurfaceShapePattern(leftPentagon)
|
||||
setSurfaceShapePattern(rightPentagon)
|
||||
//방향
|
||||
drawDirectionArrow(leftPentagon)
|
||||
drawDirectionArrow(rightPentagon)
|
||||
|
||||
isDown = false
|
||||
initEvent()
|
||||
}
|
||||
@ -408,8 +578,140 @@ export function useObjectBatch() {
|
||||
initEvent() //이벤트 초기화
|
||||
}
|
||||
|
||||
const splitDormerTriangle = (triangle, direction) => {
|
||||
const halfWidth = triangle.width / 2
|
||||
|
||||
let leftPoints = []
|
||||
let rightPoints = []
|
||||
|
||||
if (direction === 'down') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - halfWidth, y: triangle.top + triangle.height },
|
||||
{ x: triangle.left, y: triangle.top + triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left, y: triangle.top + triangle.height },
|
||||
{ x: triangle.left + halfWidth, y: triangle.top + triangle.height },
|
||||
]
|
||||
} else if (direction === 'up') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - halfWidth, y: triangle.top - triangle.height },
|
||||
{ x: triangle.left, y: triangle.top - triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left, y: triangle.top - triangle.height },
|
||||
{ x: triangle.left + halfWidth, y: triangle.top - triangle.height },
|
||||
]
|
||||
} else if (direction === 'left') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top - halfWidth },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top + halfWidth },
|
||||
]
|
||||
} else if (direction === 'right') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top + triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top - triangle.height },
|
||||
]
|
||||
}
|
||||
|
||||
return [leftPoints, rightPoints]
|
||||
}
|
||||
|
||||
const splitDormerPentagon = (pentagon, direction, offsetMode) => {
|
||||
const points = pentagon.points
|
||||
|
||||
console.log(pentagon.points)
|
||||
|
||||
let leftPoints = []
|
||||
let rightPoints = []
|
||||
|
||||
if (direction === 'down') {
|
||||
leftPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[1].x, y: points[1].y },
|
||||
{ x: points[2].x, y: points[2].y },
|
||||
{ x: points[0].x, y: points[3].y },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[0].x, y: points[2].y },
|
||||
{ x: points[3].x, y: points[3].y },
|
||||
{ x: points[4].x, y: points[4].y },
|
||||
]
|
||||
} else if (direction === 'up') {
|
||||
leftPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[1].x, y: points[0].y - (points[1].y - points[0].y) },
|
||||
{ x: points[2].x, y: points[0].y - (points[2].y - points[0].y) },
|
||||
{ x: points[0].x, y: points[0].y - (points[2].y - points[0].y) },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[3].x, y: points[0].y - (points[1].y - points[0].y) },
|
||||
{ x: points[3].x, y: points[0].y - (points[2].y - points[0].y) },
|
||||
{ x: points[0].x, y: points[0].y - (points[2].y - points[0].y) },
|
||||
]
|
||||
} else if (direction === 'left') {
|
||||
leftPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[0].x - (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
|
||||
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) },
|
||||
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[0].x - (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
|
||||
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) },
|
||||
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
|
||||
]
|
||||
} else if (direction === 'right') {
|
||||
leftPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[0].x + (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
|
||||
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) },
|
||||
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: points[0].x, y: points[0].y },
|
||||
{ x: points[0].x + (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
|
||||
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) },
|
||||
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
|
||||
]
|
||||
}
|
||||
|
||||
console.log(leftPoints, rightPoints)
|
||||
|
||||
return [leftPoints, rightPoints]
|
||||
}
|
||||
|
||||
return {
|
||||
applyOpeningAndShadow,
|
||||
applyDormers,
|
||||
splitDormerTriangle,
|
||||
splitDormerPentagon,
|
||||
}
|
||||
}
|
||||
|
||||
23
src/hooks/option/useFirstOption.js
Normal file
23
src/hooks/option/useFirstOption.js
Normal file
@ -0,0 +1,23 @@
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { useEffect } from 'react'
|
||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||
|
||||
export function useFirstOption() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
|
||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||
|
||||
useEffect(() => {
|
||||
const option1 = settingModalFirstOptions.option1
|
||||
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === '')
|
||||
.forEach((obj) => {
|
||||
obj.set({ visible: !obj.visible })
|
||||
})
|
||||
}, [settingModalFirstOptions])
|
||||
|
||||
return { settingModalFirstOptions, setSettingModalFirstOptions }
|
||||
}
|
||||
@ -23,10 +23,11 @@ import {
|
||||
outerLineLength2State,
|
||||
outerLineTypeState,
|
||||
} from '@/store/outerLineAtom'
|
||||
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
|
||||
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||
import { fabric } from 'fabric'
|
||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { booleanPointInPolygon } from '@turf/turf'
|
||||
|
||||
// 보조선 작성
|
||||
export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
@ -76,6 +77,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
|
||||
useEffect(() => {
|
||||
typeRef.current = type
|
||||
clear()
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
}, [type])
|
||||
|
||||
useEffect(() => {
|
||||
@ -103,12 +106,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
clear()
|
||||
addDocumentEventListener('keydown', document, keydown[type])
|
||||
}, [type])
|
||||
|
||||
const clear = () => {
|
||||
addCanvasMouseEventListener('mouse:move', mouseMove)
|
||||
setLength1(0)
|
||||
setLength2(0)
|
||||
|
||||
@ -459,8 +458,9 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
}
|
||||
|
||||
const mouseDown = (e) => {
|
||||
addCanvasMouseEventListener('mouse:move', mouseMove)
|
||||
canvas.renderAll()
|
||||
const pointer = getIntersectMousePoint(e)
|
||||
console.log(pointer)
|
||||
|
||||
mousePointerArr.current.push(pointer)
|
||||
if (mousePointerArr.current.length === 2) {
|
||||
@ -538,59 +538,66 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
|
||||
// 보조선 절삭
|
||||
const cutAuxiliary = (e) => {
|
||||
const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isFixed)
|
||||
const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine')
|
||||
|
||||
if (auxiliaryLines.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
|
||||
const allLines = [...auxiliaryLines]
|
||||
|
||||
roofBases.forEach((roofBase) => {
|
||||
roofBase.lines.forEach((line) => {
|
||||
allLines.push(line)
|
||||
})
|
||||
})
|
||||
|
||||
auxiliaryLines.forEach((line1) => {
|
||||
auxiliaryLines.forEach((line2) => {
|
||||
const lines = [line1, line2]
|
||||
allLines.forEach((line2) => {
|
||||
if (line1 === line2) {
|
||||
return
|
||||
}
|
||||
|
||||
const intersectionPoint = calculateIntersection(line1, line2)
|
||||
if (!intersectionPoint || intersectionPoints.current.some((point) => point.x === intersectionPoint.x && point.y === intersectionPoint.y)) {
|
||||
if (!intersectionPoint) {
|
||||
return
|
||||
}
|
||||
roofAdsorptionPoints.current.push(intersectionPoint)
|
||||
intersectionPoints.current.push(intersectionPoint)
|
||||
lines.forEach((line) => {
|
||||
const distance1 = distanceBetweenPoints({ x: line.x1, y: line.y1 }, intersectionPoint)
|
||||
const distance2 = distanceBetweenPoints({ x: line.x2, y: line.y2 }, intersectionPoint)
|
||||
|
||||
if (distance1 === 0 || distance2 === 0) {
|
||||
return
|
||||
}
|
||||
//historyLine에서 기존 line을 제거한다.
|
||||
lineHistory.current = lineHistory.current.filter((history) => history !== line)
|
||||
const distance1 = distanceBetweenPoints({ x: line1.x1, y: line1.y1 }, intersectionPoint)
|
||||
const distance2 = distanceBetweenPoints({ x: line1.x2, y: line1.y2 }, intersectionPoint)
|
||||
|
||||
let newLine
|
||||
if (distance1 === 0 || distance2 === 0) {
|
||||
return
|
||||
}
|
||||
//historyLine에서 기존 line을 제거한다.
|
||||
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
|
||||
|
||||
if (distance1 >= distance2) {
|
||||
newLine = addLine([line.x1, line.y1, intersectionPoint.x, intersectionPoint.y], {
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'auxiliaryLine',
|
||||
isFixed: true,
|
||||
intersectionPoint,
|
||||
})
|
||||
} else {
|
||||
newLine = addLine([line.x2, line.y2, intersectionPoint.x, intersectionPoint.y], {
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'auxiliaryLine',
|
||||
isFixed: true,
|
||||
intersectionPoint,
|
||||
})
|
||||
}
|
||||
lineHistory.current.push(newLine)
|
||||
removeLine(line)
|
||||
})
|
||||
let newLine
|
||||
|
||||
if (distance1 >= distance2) {
|
||||
newLine = addLine([line1.x1, line1.y1, intersectionPoint.x, intersectionPoint.y], {
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'auxiliaryLine',
|
||||
isFixed: true,
|
||||
intersectionPoint,
|
||||
})
|
||||
} else {
|
||||
newLine = addLine([line1.x2, line1.y2, intersectionPoint.x, intersectionPoint.y], {
|
||||
stroke: 'black',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'auxiliaryLine',
|
||||
isFixed: true,
|
||||
intersectionPoint,
|
||||
})
|
||||
}
|
||||
lineHistory.current.push(newLine)
|
||||
removeLine(line1)
|
||||
})
|
||||
})
|
||||
addCanvasMouseEventListener('mouse:move', mouseMove)
|
||||
@ -600,10 +607,15 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
* 일변전으로 돌아가기
|
||||
*/
|
||||
const handleRollback = () => {
|
||||
const lastLine = lineHistory.current.pop()
|
||||
mousePointerArr.current = []
|
||||
canvas.remove(...canvas.getObjects().filter((obj) => obj.name === 'innerPoint'))
|
||||
const innerPoint = canvas.getObjects().find((obj) => obj.name === 'innerPoint')
|
||||
if (innerPoint) {
|
||||
mousePointerArr.current = []
|
||||
canvas.remove(innerPoint)
|
||||
canvas.renderAll()
|
||||
return
|
||||
}
|
||||
|
||||
const lastLine = lineHistory.current.pop()
|
||||
if (lastLine) {
|
||||
roofAdsorptionPoints.current = roofAdsorptionPoints.current.filter(
|
||||
(point) => point.x !== lastLine.intersectionPoint?.x && point.y !== lastLine.intersectionPoint?.y,
|
||||
@ -621,10 +633,25 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) {
|
||||
return
|
||||
}
|
||||
|
||||
const roofBases = canvas.getObjects().find((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const innerLines = [...lineHistory.current]
|
||||
|
||||
roofBases.innerLines = [...innerLines]
|
||||
roofBases.forEach((roofBase) => {
|
||||
const roofInnerLines = innerLines.filter((line) => {
|
||||
const turfPolygon = polygonToTurfPolygon(roofBase)
|
||||
|
||||
// innerLines의 두 점이 모두 polygon 안에 있는지 확인
|
||||
const inPolygon1 = booleanPointInPolygon([line.x1, line.y1], turfPolygon)
|
||||
const inPolygon2 = booleanPointInPolygon([line.x2, line.y2], turfPolygon)
|
||||
|
||||
if (inPolygon1 && inPolygon2) {
|
||||
line.attributes = { ...line.attributes, roofId: roofBase.id }
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
roofBase.innerLines = [...roofInnerLines]
|
||||
})
|
||||
|
||||
setShowAuxiliaryModal(false)
|
||||
}
|
||||
|
||||
@ -29,12 +29,20 @@ import {
|
||||
} from '@/store/outerLineAtom'
|
||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||
import { fabric } from 'fabric'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
import { outlineDisplaySelector } from '@/store/settingAtom'
|
||||
|
||||
//외벽선 그리기
|
||||
export function useOuterLineWall(setShowOutlineModal) {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } =
|
||||
useEvent()
|
||||
const {
|
||||
initEvent,
|
||||
addCanvasMouseEventListener,
|
||||
addDocumentEventListener,
|
||||
removeAllMouseEventListeners,
|
||||
removeAllDocumentEventListeners,
|
||||
removeMouseEvent,
|
||||
} = useEvent()
|
||||
const { getIntersectMousePoint } = useMouse()
|
||||
const { addLine, removeLine } = useLine()
|
||||
const { tempGridMode } = useTempGrid()
|
||||
@ -46,6 +54,8 @@ export function useOuterLineWall(setShowOutlineModal) {
|
||||
const adsorptionRange = useRecoilValue(adsorptionRangeState)
|
||||
const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격
|
||||
|
||||
const isOutlineDisplay = useRecoilValue(outlineDisplaySelector)
|
||||
|
||||
const length1Ref = useRef(null)
|
||||
const length2Ref = useRef(null)
|
||||
const angle1Ref = useRef(null)
|
||||
@ -75,6 +85,9 @@ export function useOuterLineWall(setShowOutlineModal) {
|
||||
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
clear()
|
||||
return () => {
|
||||
initEvent()
|
||||
}
|
||||
}, [verticalHorizontalMode, points, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, interval, tempGridMode])
|
||||
|
||||
useEffect(() => {
|
||||
@ -215,11 +228,11 @@ export function useOuterLineWall(setShowOutlineModal) {
|
||||
return
|
||||
}
|
||||
|
||||
/*if (lastPoint.x === firstPoint.x && lastPoint.y === firstPoint.y) {
|
||||
if (Math.abs(lastPoint.x - firstPoint.x) < 1 && Math.abs(lastPoint.y - firstPoint.y) < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (lastPoint.x === firstPoint.x || lastPoint.y === firstPoint.y) {
|
||||
if (Math.abs(lastPoint.x - firstPoint.x) < 1 || Math.abs(lastPoint.y - firstPoint.y) < 1) {
|
||||
let isAllRightAngle = true
|
||||
|
||||
const firstPoint = points[0]
|
||||
@ -238,38 +251,30 @@ export function useOuterLineWall(setShowOutlineModal) {
|
||||
if (isAllRightAngle) {
|
||||
return
|
||||
}
|
||||
const line = new QLine([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
||||
const line = addLine([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'helpGuideLine',
|
||||
visible: isOutlineDisplay,
|
||||
})
|
||||
|
||||
canvas?.add(line)
|
||||
addLineText(line)
|
||||
} else {
|
||||
const guideLine1 = new QLine([lastPoint.x, lastPoint.y, lastPoint.x, firstPoint.y], {
|
||||
const guideLine1 = addLine([lastPoint.x, lastPoint.y, lastPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [1, 1, 1],
|
||||
name: 'helpGuideLine',
|
||||
visible: isOutlineDisplay,
|
||||
})
|
||||
|
||||
const guideLine2 = new QLine([guideLine1.x2, guideLine1.y2, firstPoint.x, firstPoint.y], {
|
||||
const guideLine2 = addLine([guideLine1.x2, guideLine1.y2, firstPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [1, 1, 1],
|
||||
name: 'helpGuideLine',
|
||||
visible: isOutlineDisplay,
|
||||
})
|
||||
if (guideLine1.length > 0) {
|
||||
canvas?.add(guideLine1)
|
||||
addLineText(guideLine1)
|
||||
}
|
||||
|
||||
canvas?.add(guideLine2)
|
||||
|
||||
addLineText(guideLine2)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}, [points])
|
||||
|
||||
@ -284,6 +289,7 @@ export function useOuterLineWall(setShowOutlineModal) {
|
||||
y1: point1.y,
|
||||
x2: point2.x,
|
||||
y2: point2.y,
|
||||
visible: isOutlineDisplay,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,11 @@ export function useRoofAllocationSetting(setShowRoofAllocationSettingModal) {
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
roofBases.forEach((roofBase) => {
|
||||
splitPolygonWithLines(roofBase)
|
||||
try {
|
||||
splitPolygonWithLines(roofBase)
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
|
||||
roofBase.innerLines.forEach((line) => {
|
||||
canvas.remove(line)
|
||||
|
||||
@ -33,6 +33,11 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
|
||||
|
||||
const [type, setType] = useState(TYPES.EAVES)
|
||||
|
||||
const isFix = useRef(false)
|
||||
const initLines = useRef([])
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const buttons = [
|
||||
{ id: 1, name: getMessage('eaves'), type: TYPES.EAVES },
|
||||
{ id: 2, name: getMessage('gable'), type: TYPES.GABLE },
|
||||
@ -46,15 +51,20 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
|
||||
if (!outerLineFix || outerLines.length === 0) {
|
||||
swalFire({ text: '외벽선이 없습니다.' })
|
||||
setShowRoofShapePassivitySettingModal(false)
|
||||
return
|
||||
}
|
||||
setIsLoading(true)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading) return
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
canvas.remove(wallLines)
|
||||
|
||||
canvas?.remove(...wallLines)
|
||||
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
initLines.current = outerLines.map((line) => ({ ...line }))
|
||||
outerLines.forEach((outerLine, idx) => {
|
||||
if (idx === 0) {
|
||||
currentLineRef.current = outerLine
|
||||
@ -66,10 +76,11 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
|
||||
canvas?.renderAll()
|
||||
|
||||
return () => {
|
||||
handleLineToPolygon()
|
||||
canvas?.discardActiveObject()
|
||||
initEvent()
|
||||
}
|
||||
}, [])
|
||||
}, [isLoading])
|
||||
|
||||
useEffect(() => {
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
@ -166,6 +177,14 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
isFix.current = true
|
||||
handleLineToPolygon()
|
||||
|
||||
setShowRoofShapePassivitySettingModal(false)
|
||||
}
|
||||
|
||||
const handleLineToPolygon = () => {
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
exceptObjs.forEach((obj) => {
|
||||
@ -176,13 +195,28 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod
|
||||
hideLine(line)
|
||||
})
|
||||
|
||||
const wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
let wall
|
||||
|
||||
if (isFix.current) {
|
||||
wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
} else {
|
||||
// 그냥 닫을 경우 처리
|
||||
wall = addPolygonByLines([...initLines.current], { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
lines.forEach((line, idx) => {
|
||||
line.attributes = initLines.current[idx].attributes
|
||||
})
|
||||
}
|
||||
|
||||
wall.lines = [...lines]
|
||||
// 기존 그려진 지붕이 없다면
|
||||
|
||||
if (isFix.current) {
|
||||
// 완료 한 경우에는 지붕까지 그려줌
|
||||
const roof = drawRoofPolygon(wall)
|
||||
}
|
||||
|
||||
const roof = drawRoofPolygon(wall)
|
||||
canvas.renderAll()
|
||||
setShowRoofShapePassivitySettingModal(false)
|
||||
}
|
||||
|
||||
return { handleSave, handleConfirm, buttons, type, setType, TYPES, offsetRef, pitchRef, handleRollback }
|
||||
}
|
||||
|
||||
@ -244,8 +244,13 @@ export function useRoofShapeSetting(setShowRoofShapeSettingModal) {
|
||||
}
|
||||
}
|
||||
|
||||
// 기존 wallLine 제거
|
||||
canvas?.remove(canvas.getObjects().filter((obj) => obj.name === 'wallLine'))
|
||||
// 기존 wallLine, roofBase 제거
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === 'wallLine' || obj.name === 'roofBase')
|
||||
.forEach((line) => {
|
||||
canvas.remove(line)
|
||||
})
|
||||
|
||||
const polygon = addPolygonByLines(outerLines, { name: 'wallLine' })
|
||||
polygon.lines = [...outerLines]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
@ -21,6 +21,8 @@ export function useWallLineOffsetSetting(setShowWallLineOffsetSettingModal) {
|
||||
const arrow1Ref = useRef(null)
|
||||
const arrow2Ref = useRef(null)
|
||||
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const drawLine = (point1, point2, idx, direction = currentWallLineRef.current.direction) => {
|
||||
@ -87,6 +89,7 @@ export function useWallLineOffsetSetting(setShowWallLineOffsetSettingModal) {
|
||||
if (!isLoading) {
|
||||
return
|
||||
}
|
||||
canvas?.discardActiveObject()
|
||||
removeOuterLineEditCircle()
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
if (type === TYPES.WALL_LINE_EDIT) {
|
||||
@ -94,6 +97,20 @@ export function useWallLineOffsetSetting(setShowWallLineOffsetSettingModal) {
|
||||
}
|
||||
}, [type])
|
||||
|
||||
useEffect(() => {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === 'outerLine')
|
||||
.forEach((line) => {
|
||||
line.set({ stroke: 'black' })
|
||||
})
|
||||
|
||||
if (currentObject?.name === 'outerLine') {
|
||||
currentObject.set({ stroke: '#EA10AC' })
|
||||
canvas.renderAll()
|
||||
}
|
||||
}, [currentObject])
|
||||
|
||||
const removeOuterLineEditCircle = () => {
|
||||
canvas.remove(...canvas.getObjects().filter((obj) => obj.name === 'outerLineEditCircleStart' || obj.name === 'outerLineEditCircleEnd'))
|
||||
}
|
||||
@ -106,7 +123,6 @@ export function useWallLineOffsetSetting(setShowWallLineOffsetSettingModal) {
|
||||
}
|
||||
|
||||
currentWallLineRef.current = e.target
|
||||
console.log(currentWallLineRef.current.idx, currentWallLineRef.current.direction)
|
||||
if (type === TYPES.WALL_LINE_EDIT) {
|
||||
addCircleByLine(currentWallLineRef.current)
|
||||
}
|
||||
|
||||
@ -232,11 +232,11 @@ export function usePlacementShapeDrawing(setShowPlaceShapeDrawingModal) {
|
||||
return
|
||||
}
|
||||
|
||||
/*if (lastPoint.x === firstPoint.x && lastPoint.y === firstPoint.y) {
|
||||
if (Math.abs(lastPoint.x - firstPoint.x) < 1 && Math.abs(lastPoint.y - firstPoint.y) < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (lastPoint.x === firstPoint.x || lastPoint.y === firstPoint.y) {
|
||||
if (Math.abs(lastPoint.x - firstPoint.x) < 1 || Math.abs(lastPoint.y - firstPoint.y) < 1) {
|
||||
let isAllRightAngle = true
|
||||
|
||||
const firstPoint = points[0]
|
||||
@ -255,38 +255,27 @@ export function usePlacementShapeDrawing(setShowPlaceShapeDrawingModal) {
|
||||
if (isAllRightAngle) {
|
||||
return
|
||||
}
|
||||
const line = new QLine([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
||||
const line = addLine([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'helpGuideLine',
|
||||
})
|
||||
|
||||
canvas?.add(line)
|
||||
addLineText(line)
|
||||
} else {
|
||||
const guideLine1 = new QLine([lastPoint.x, lastPoint.y, lastPoint.x, firstPoint.y], {
|
||||
const guideLine1 = addLine([lastPoint.x, lastPoint.y, lastPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [1, 1, 1],
|
||||
name: 'helpGuideLine',
|
||||
})
|
||||
|
||||
const guideLine2 = new QLine([guideLine1.x2, guideLine1.y2, firstPoint.x, firstPoint.y], {
|
||||
const guideLine2 = addLine([guideLine1.x2, guideLine1.y2, firstPoint.x, firstPoint.y], {
|
||||
stroke: 'grey',
|
||||
strokeWidth: 1,
|
||||
strokeDashArray: [1, 1, 1],
|
||||
name: 'helpGuideLine',
|
||||
})
|
||||
if (guideLine1.length > 0) {
|
||||
canvas?.add(guideLine1)
|
||||
addLineText(guideLine1)
|
||||
}
|
||||
|
||||
canvas?.add(guideLine2)
|
||||
|
||||
addLineText(guideLine2)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}, [points])
|
||||
|
||||
|
||||
@ -2,13 +2,14 @@ import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { adsorptionPointAddModeState, adsorptionPointModeState, adsorptionRangeState, canvasState } from '@/store/canvasAtom'
|
||||
import { fabric } from 'fabric'
|
||||
import { useMouse } from '@/hooks/useMouse'
|
||||
import { gridDisplaySelector } from '@/store/settingAtom'
|
||||
|
||||
export function useAdsorptionPoint() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState)
|
||||
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
|
||||
const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState)
|
||||
|
||||
const isGridDisplay = useRecoilValue(gridDisplaySelector)
|
||||
const { getIntersectMousePoint } = useMouse()
|
||||
|
||||
const getAdsorptionPoints = () => {
|
||||
@ -28,6 +29,7 @@ export function useAdsorptionPoint() {
|
||||
y: pointer.y,
|
||||
selectable: true,
|
||||
name: 'adsorptionPoint',
|
||||
visible: isGridDisplay,
|
||||
})
|
||||
|
||||
canvas.add(adsorptionPoint)
|
||||
|
||||
@ -40,59 +40,59 @@ export function useAxios(lang = '') {
|
||||
// response 추가 로직
|
||||
axios.interceptors.request.use(undefined, (error) => {})
|
||||
|
||||
const get = async ({ url }) => {
|
||||
const get = async ({ url, option = {} }) => {
|
||||
return await getInstances(url)
|
||||
.get(url)
|
||||
.get(url, option)
|
||||
.then((res) => res.data)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
const promiseGet = async ({ url }) => {
|
||||
return await getInstances(url).get(url)
|
||||
const promiseGet = async ({ url, option = {} }) => {
|
||||
return await getInstances(url).get(url, option)
|
||||
}
|
||||
|
||||
const post = async ({ url, data }) => {
|
||||
const post = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url)
|
||||
.post(url, data)
|
||||
.post(url, data, option)
|
||||
.then((res) => res.data)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
const promisePost = async ({ url, data }) => {
|
||||
return await getInstances(url).post(url, data)
|
||||
const promisePost = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url).post(url, data, option)
|
||||
}
|
||||
|
||||
const put = async ({ url, data }) => {
|
||||
const put = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url)
|
||||
.put(url, data)
|
||||
.put(url, data, option)
|
||||
.then((res) => res.data)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
const promisePut = async ({ url, data }) => {
|
||||
return await getInstances(url).put(url, data)
|
||||
const promisePut = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url).put(url, data, option)
|
||||
}
|
||||
|
||||
const patch = async ({ url, data }) => {
|
||||
const patch = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url)
|
||||
.patch(url, data)
|
||||
.patch(url, data, option)
|
||||
.then((res) => res.data)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
const promisePatch = async ({ url, data }) => {
|
||||
return await getInstances(url).patch(url, data)
|
||||
const promisePatch = async ({ url, data, option = {} }) => {
|
||||
return await getInstances(url).patch(url, data, option)
|
||||
}
|
||||
|
||||
const del = async ({ url }) => {
|
||||
const del = async ({ url, option = {} }) => {
|
||||
return await getInstances(url)
|
||||
.delete(url)
|
||||
.delete(url, option)
|
||||
.then((res) => res.data)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
const promiseDel = async ({ url }) => {
|
||||
return await getInstances(url).delete(url)
|
||||
const promiseDel = async ({ url, option = {} }) => {
|
||||
return await getInstances(url).delete(url, option)
|
||||
}
|
||||
|
||||
return { get, promiseGet, post, promisePost, put, promisePut, patch, promisePatch, del, promiseDel }
|
||||
|
||||
@ -2,10 +2,11 @@ import { useEffect, useRef } from 'react'
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom'
|
||||
import { fabric } from 'fabric'
|
||||
import { calculateDistance, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
|
||||
import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||
import { useDotLineGrid } from '@/hooks/useDotLineGrid'
|
||||
import { useTempGrid } from '@/hooks/useTempGrid'
|
||||
import { gridDisplaySelector } from '@/store/settingAtom'
|
||||
|
||||
export function useEvent() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -43,7 +44,6 @@ export function useEvent() {
|
||||
//default Event 추가
|
||||
addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent)
|
||||
addCanvasMouseEventListener('mouse:out', defaultMouseOutEvent)
|
||||
addDocumentEventListener('keydown', document, defaultKeyboardEvent)
|
||||
addDocumentEventListener('contextmenu', document, defaultContextMenuEvent)
|
||||
if (adsorptionPointAddMode) {
|
||||
addCanvasMouseEventListener('mouse:down', adsorptionPointAddModeStateEvent)
|
||||
@ -152,6 +152,17 @@ export function useEvent() {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const helpGuideLines = canvas.getObjects().filter((obj) => obj.name === 'helpGuideLine')
|
||||
if (helpGuideLines.length === 2) {
|
||||
const guideIntersectionPoint = calculateIntersection(helpGuideLines[0], helpGuideLines[1])
|
||||
|
||||
if (guideIntersectionPoint && distanceBetweenPoints(guideIntersectionPoint, pointer) <= adsorptionRange) {
|
||||
arrivalPoint = guideIntersectionPoint
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const horizontalLine = new fabric.Line([-1 * canvas.width, arrivalPoint.y, 2 * canvas.width, arrivalPoint.y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 1,
|
||||
|
||||
@ -14,7 +14,7 @@ export const useLine = () => {
|
||||
fontFamily: fontFamily,
|
||||
})
|
||||
|
||||
if (line.length === 0) {
|
||||
if (line.length < 1) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { appMessageStore } from '@/store/localeAtom'
|
||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||
|
||||
// import KO from '@/locales/ko.json'
|
||||
// import JA from '@/locales/ja.json'
|
||||
import KO from '@/locales/ko.json'
|
||||
import JA from '@/locales/ja.json'
|
||||
|
||||
const SESSION_STORAGE_MESSAGE_KEY = 'QCAST_MESSAGE_STORAGE'
|
||||
|
||||
export const useMessage = () => {
|
||||
// const globalLocale = useRecoilValue(globalLocaleState)
|
||||
const appMessageState = useRecoilValue(appMessageStore)
|
||||
// const appMessageState = useRecoilValue(appMessageStore)
|
||||
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
const appMessageState = globalLocale === 'ko' ? KO : JA
|
||||
|
||||
const getMessage = (key, args = []) => {
|
||||
// if (sessionStorage.getItem(SESSION_STORAGE_MESSAGE_KEY) === null) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
/**
|
||||
* 페이지네이션 훅
|
||||
@ -14,6 +14,10 @@ const usePagination = ({ pageNo = 1, pageSize = 10, pagePerBlock = 10, totalCoun
|
||||
setCurrentPage(page)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(pageNo)
|
||||
}, [pageNo])
|
||||
|
||||
const pageGroup = Math.floor((currentPage - 1) / pagePerBlock) + 1
|
||||
const totalPages = Math.ceil(totalCount / pageSize)
|
||||
const pages = Array.from({ length: totalPages }, (_, i) => i + 1)
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { canvasState, currentCanvasPlanState, initCanvasPlansState, plansState } from '@/store/canvasAtom'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
|
||||
export function usePlan() {
|
||||
const [planNum, setPlanNum] = useState(0)
|
||||
|
||||
const [canvas, setCanvas] = useRecoilState(canvasState)
|
||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||
const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState)
|
||||
const [plans, setPlans] = useRecoilState(plansState)
|
||||
const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState) // DB에 저장된 plan
|
||||
const [plans, setPlans] = useRecoilState(plansState) // 전체 plan (DB에 저장된 plan + 저장 안된 새로운 plan)
|
||||
|
||||
const { swalFire } = useSwal()
|
||||
const { getMessage } = useMessage()
|
||||
const { get, promisePost, promisePut, promiseDel } = useAxios()
|
||||
@ -72,6 +77,9 @@ export function usePlan() {
|
||||
// }, 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 캔버스에 그려진 데이터를 추출
|
||||
*/
|
||||
const currentCanvasData = () => {
|
||||
removeMouseLines()
|
||||
return addCanvas()
|
||||
@ -81,8 +89,7 @@ export function usePlan() {
|
||||
* 실시간 캔버스 상태와 DB에 저장된 캔버스 상태를 비교하여 수정 여부를 판단
|
||||
*/
|
||||
const checkModifiedCanvasPlan = () => {
|
||||
removeMouseLines()
|
||||
const canvasStatus = addCanvas()
|
||||
const canvasStatus = currentCanvasData()
|
||||
const initPlanData = initCanvasPlans.find((plan) => plan.id === currentCanvasPlan.id)
|
||||
|
||||
if (!initPlanData) {
|
||||
@ -90,15 +97,10 @@ export function usePlan() {
|
||||
return JSON.parse(canvasStatus).objects.length > 0
|
||||
} else {
|
||||
// 저장된 캔버스
|
||||
if (canvasStatus === initPlanData.canvasStatus) {
|
||||
return false
|
||||
} else {
|
||||
// 각각 object들의 id 목록을 추출하여 비교
|
||||
const canvasObjsIds = getObjectIds(JSON.parse(canvasStatus).objects)
|
||||
const dbObjsIds = getObjectIds(JSON.parse(initPlanData.canvasStatus).objects)
|
||||
|
||||
return canvasObjsIds.length !== dbObjsIds.length || !canvasObjsIds.every((id, index) => id === dbObjsIds[index])
|
||||
}
|
||||
// 각각 object들의 id 목록을 추출하여 비교
|
||||
const canvasObjsIds = getObjectIds(JSON.parse(canvasStatus).objects)
|
||||
const dbObjsIds = getObjectIds(JSON.parse(initPlanData.canvasStatus).objects)
|
||||
return canvasObjsIds.length !== dbObjsIds.length || !canvasObjsIds.every((id, index) => id === dbObjsIds[index])
|
||||
}
|
||||
}
|
||||
const getObjectIds = (objects) => {
|
||||
@ -112,9 +114,6 @@ export function usePlan() {
|
||||
* DB에 저장된 데이터를 canvas에서 사용할 수 있도록 포맷화
|
||||
*/
|
||||
const dbToCanvasFormat = (cs) => {
|
||||
// return JSON.stringify(cs.replace(/##/g, '"')) //.replace(/\\/g, ''))//.slice(1, -1))
|
||||
// JSON.stringify()를 사용하면 "가 \"로 바뀐다. 따라서, JSON.stringify를 제거
|
||||
// canvasToDbFormat()에서 \\의 상황을 없앴으므로 replace(/\\/g, '')를 제거
|
||||
return cs.replace(/##/g, '"')
|
||||
}
|
||||
|
||||
@ -122,92 +121,24 @@ export function usePlan() {
|
||||
* canvas의 데이터를 DB에 저장할 수 있도록 포맷화
|
||||
*/
|
||||
const canvasToDbFormat = (cs) => {
|
||||
// return JSON.stringify(cs).replace(/"/g, '##')
|
||||
// addCanvas()에서 JSON.stringify()를 거쳐서 나오는데, 또 감싸버려서 \가 \\로 된다. 따라서, JSON.stringify를 제거
|
||||
return cs.replace(/"/g, '##')
|
||||
}
|
||||
|
||||
/**
|
||||
* 페이지 내 캔버스를 저장하는 함수
|
||||
*
|
||||
* 1. 신규 저장 : POST
|
||||
* param(body) : userId, objectNo, canvasStatus
|
||||
* 2. 수정 저장 : PUT
|
||||
* param(body) : id, canvasStatus
|
||||
* 페이지 내 캔버스를 저장
|
||||
*/
|
||||
const saveCanvas = async (userId) => {
|
||||
removeMouseLines()
|
||||
const canvasStatus = addCanvas()
|
||||
|
||||
if (initCanvasPlans.some((plan) => plan.id === currentCanvasPlan.id)) {
|
||||
// canvas 수정
|
||||
const planData = {
|
||||
id: currentCanvasPlan.id,
|
||||
canvasStatus: canvasToDbFormat(canvasStatus),
|
||||
}
|
||||
|
||||
return await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('common.message.save') })
|
||||
// console.log('[PUT] canvas-statuses res :::::::: %o', res)
|
||||
setInitCanvasPlans((initCanvasPlans) =>
|
||||
initCanvasPlans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)),
|
||||
)
|
||||
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
// console.error('[PUT] canvas-statuses error :::::::: %o', error)
|
||||
})
|
||||
} else {
|
||||
// canvas 신규 등록
|
||||
const planData = {
|
||||
userId: userId,
|
||||
imageName: 'image_name', // api 필수항목이여서 임시로 넣음, 이후 삭제 필요
|
||||
objectNo: currentCanvasPlan.objectNo,
|
||||
canvasStatus: canvasToDbFormat(canvasStatus),
|
||||
}
|
||||
|
||||
return await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('common.message.save') })
|
||||
// console.log('[POST] canvas-statuses response :::::::: %o', res)
|
||||
setInitCanvasPlans((initCanvasPlans) => [
|
||||
...initCanvasPlans,
|
||||
{
|
||||
id: res.data,
|
||||
name: currentCanvasPlan.objectNo + '-' + res.data,
|
||||
userId: userId,
|
||||
canvasStatus: canvasStatus,
|
||||
isNew: currentCanvasPlan.id,
|
||||
},
|
||||
])
|
||||
setPlans((plans) =>
|
||||
plans.map((plan) =>
|
||||
plan.id === currentCanvasPlan.id
|
||||
? {
|
||||
...plan,
|
||||
id: res.data,
|
||||
name: currentCanvasPlan.objectNo + '-' + res.data,
|
||||
userId: userId,
|
||||
canvasStatus: canvasStatus,
|
||||
isNew: currentCanvasPlan.id,
|
||||
}
|
||||
: plan,
|
||||
),
|
||||
)
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
// console.error('[POST] canvas-statuses res error :::::::: %o', error)
|
||||
})
|
||||
}
|
||||
const canvasStatus = currentCanvasData()
|
||||
initCanvasPlans.some((plan) => plan.id === currentCanvasPlan.id)
|
||||
? await putCanvasStatus(canvasStatus)
|
||||
: await postCanvasStatus(userId, canvasStatus)
|
||||
}
|
||||
|
||||
/**
|
||||
* objectNo에 해당하는 canvas 목록을 조회하는 함수
|
||||
* objectNo에 해당하는 canvas 목록을 조회
|
||||
*/
|
||||
const getCanvasByObjectNo = async (userId, objectNo) => {
|
||||
// console.log(`[GET] objectNo: ${objectNo} / userId: ${userId}`)
|
||||
return get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) =>
|
||||
res.map((item) => ({
|
||||
id: item.id,
|
||||
@ -220,27 +151,193 @@ export function usePlan() {
|
||||
}
|
||||
|
||||
/**
|
||||
* id에 해당하는 canvas 데이터를 삭제하는 함수
|
||||
* canvas 데이터를 추가
|
||||
*/
|
||||
const postCanvasStatus = async (userId, canvasStatus) => {
|
||||
const planData = {
|
||||
userId: userId,
|
||||
imageName: 'image_name', // api 필수항목이여서 임시로 넣음, 이후 삭제 필요
|
||||
objectNo: currentCanvasPlan.objectNo,
|
||||
canvasStatus: canvasToDbFormat(canvasStatus),
|
||||
}
|
||||
await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('plan.message.save') })
|
||||
setInitCanvasPlans((initCanvasPlans) => [...initCanvasPlans, { id: res.data, canvasStatus: canvasStatus }])
|
||||
setPlans((plans) =>
|
||||
plans.map((plan) =>
|
||||
plan.id === currentCanvasPlan.id
|
||||
? {
|
||||
...plan,
|
||||
id: res.data,
|
||||
name: currentCanvasPlan.objectNo + '-' + res.data,
|
||||
canvasStatus: canvasStatus,
|
||||
}
|
||||
: plan,
|
||||
),
|
||||
)
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* id에 해당하는 canvas 데이터를 수정
|
||||
*/
|
||||
const putCanvasStatus = async (canvasStatus) => {
|
||||
const planData = {
|
||||
id: currentCanvasPlan.id,
|
||||
canvasStatus: canvasToDbFormat(canvasStatus),
|
||||
}
|
||||
await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('plan.message.save') })
|
||||
setInitCanvasPlans((initCanvasPlans) =>
|
||||
initCanvasPlans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)),
|
||||
)
|
||||
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* id에 해당하는 canvas 데이터를 삭제
|
||||
*/
|
||||
const delCanvasById = (id) => {
|
||||
return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-id/${id}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* objectNo에 해당하는 canvas 데이터들을 삭제하는 함수
|
||||
* objectNo에 해당하는 canvas 데이터들을 삭제
|
||||
*/
|
||||
const delCanvasByObjectNo = (objectNo) => {
|
||||
return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* plan 이동
|
||||
* 현재 plan의 작업상태를 확인, 저장 후 이동
|
||||
*/
|
||||
const handleCurrentPlan = (userId, newCurrentId) => {
|
||||
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
|
||||
if (currentCanvasPlan?.id && checkModifiedCanvasPlan()) {
|
||||
swalFire({
|
||||
text: `${currentCanvasPlan.name} ` + getMessage('plan.message.confirm.save'),
|
||||
type: 'confirm',
|
||||
confirmFn: async () => {
|
||||
await saveCanvas(userId)
|
||||
updateCurrentPlan(newCurrentId)
|
||||
},
|
||||
denyFn: () => {
|
||||
updateCurrentPlan(newCurrentId)
|
||||
},
|
||||
})
|
||||
} else {
|
||||
updateCurrentPlan(newCurrentId)
|
||||
}
|
||||
}
|
||||
}
|
||||
const updateCurrentPlan = (newCurrentId) => {
|
||||
setPlans((plans) =>
|
||||
plans.map((plan) => {
|
||||
return { ...plan, isCurrent: plan.id === newCurrentId }
|
||||
}),
|
||||
)
|
||||
}
|
||||
useEffect(() => {
|
||||
setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null)
|
||||
}, [plans])
|
||||
|
||||
/**
|
||||
* 새로운 plan 생성
|
||||
* 현재 plan의 데이터가 있을 경우 복제 여부를 확인
|
||||
*/
|
||||
const handleAddPlan = (userId, objectNo) => {
|
||||
JSON.parse(currentCanvasData()).objects.length > 0
|
||||
? swalFire({
|
||||
text: `${currentCanvasPlan.name} ` + getMessage('plan.message.confirm.copy'),
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
addPlan(userId, objectNo, currentCanvasData())
|
||||
},
|
||||
denyFn: () => {
|
||||
addPlan(userId, objectNo)
|
||||
},
|
||||
})
|
||||
: addPlan(userId, objectNo)
|
||||
}
|
||||
const addPlan = (userId, objectNo, canvasStatus = '') => {
|
||||
const id = uuidv4()
|
||||
const newPlan = {
|
||||
id: id,
|
||||
name: `Plan ${planNum + 1}`,
|
||||
objectNo: objectNo,
|
||||
userId: userId,
|
||||
canvasStatus: canvasStatus,
|
||||
}
|
||||
setPlans([...plans, newPlan])
|
||||
handleCurrentPlan(userId, id)
|
||||
setPlanNum(planNum + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* plan 삭제
|
||||
*/
|
||||
const handleDeletePlan = (e, id) => {
|
||||
e.stopPropagation() // 이벤트 버블링 방지
|
||||
|
||||
if (initCanvasPlans.some((plan) => plan.id === id)) {
|
||||
delCanvasById(id)
|
||||
.then((res) => {
|
||||
swalFire({ text: getMessage('plan.message.delete') })
|
||||
setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.filter((plan) => plan.id !== id))
|
||||
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
||||
})
|
||||
.catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
})
|
||||
} else {
|
||||
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
||||
swalFire({ text: getMessage('plan.message.delete') })
|
||||
}
|
||||
|
||||
// 삭제 후 last 데이터에 포커싱
|
||||
const lastPlan = plans.filter((plan) => plan.id !== id).at(-1)
|
||||
if (!lastPlan) {
|
||||
setPlanNum(0)
|
||||
setCurrentCanvasPlan(null)
|
||||
} else if (id !== lastPlan.id) {
|
||||
updateCurrentPlan(lastPlan.id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* plan 조회
|
||||
*/
|
||||
const loadCanvasPlanData = (userId, objectNo) => {
|
||||
getCanvasByObjectNo(userId, objectNo).then((res) => {
|
||||
// console.log('canvas 목록 ', res)
|
||||
if (res.length > 0) {
|
||||
setInitCanvasPlans(res)
|
||||
setPlans(res)
|
||||
updateCurrentPlan(res.at(-1).id) // last 데이터에 포커싱
|
||||
setPlanNum(res.length)
|
||||
} else {
|
||||
addPlan(userId, objectNo)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
canvas,
|
||||
removeMouseLines,
|
||||
currentCanvasData,
|
||||
plans,
|
||||
saveCanvas,
|
||||
addCanvas,
|
||||
checkModifiedCanvasPlan,
|
||||
getCanvasByObjectNo,
|
||||
delCanvasById,
|
||||
handleCurrentPlan,
|
||||
handleAddPlan,
|
||||
handleDeletePlan,
|
||||
loadCanvasPlanData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { canvasState, tempGridModeState } from '@/store/canvasAtom'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
import { gridDisplaySelector } from '@/store/settingAtom'
|
||||
|
||||
export function useTempGrid() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const gridColor = useRecoilValue(gridColorState)
|
||||
const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState)
|
||||
const isGridDisplay = useRecoilValue(gridDisplaySelector)
|
||||
const tempGridModeStateLeftClickEvent = (e) => {
|
||||
//임의 그리드 모드일 경우
|
||||
let pointer = canvas.getPointer(e.e)
|
||||
@ -22,6 +24,7 @@ export function useTempGrid() {
|
||||
strokeDashArray: [5, 2],
|
||||
opacity: 0.3,
|
||||
direction: 'vertical',
|
||||
visible: isGridDisplay,
|
||||
name: 'tempGrid',
|
||||
})
|
||||
|
||||
@ -48,6 +51,7 @@ export function useTempGrid() {
|
||||
strokeDashArray: [5, 2],
|
||||
opacity: 0.3,
|
||||
name: 'tempGrid',
|
||||
visible: isGridDisplay,
|
||||
direction: 'horizontal',
|
||||
})
|
||||
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { createI18nClient } from 'next-international/client'
|
||||
|
||||
export const { useI18n, useScopedI18n, I18nProviderClient, useChangeLocale, defineLocale, useCurrentLocale } = createI18nClient(
|
||||
{
|
||||
ko: () => import('./ko'),
|
||||
ja: () => import('./ja'),
|
||||
},
|
||||
{
|
||||
// Uncomment to set base path
|
||||
// basePath: '/base',
|
||||
// Uncomment to use custom segment name
|
||||
// segmentName: 'locale',
|
||||
// Uncomment to set fallback locale
|
||||
// fallbackLocale: en,
|
||||
},
|
||||
)
|
||||
@ -1,90 +0,0 @@
|
||||
console.log('Loaded JA')
|
||||
|
||||
export default {
|
||||
hello: 'こんにちは',
|
||||
welcome: 'こんにちは {name}!',
|
||||
locale: '現在のロケールは {locale} です。',
|
||||
common: {
|
||||
require: '필수',
|
||||
},
|
||||
site: {
|
||||
name: 'Q.CAST III',
|
||||
sub_name: '태양광 발전 시스템 도면관리 사이트',
|
||||
},
|
||||
login: {
|
||||
login: 'Login',
|
||||
init_password: {
|
||||
btn: '비밀번호 초기화',
|
||||
title: '비밀번호 초기화',
|
||||
sub_title: '비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.',
|
||||
},
|
||||
},
|
||||
join: {
|
||||
title: 'Q.CAST3 로그인ID 발행 신청',
|
||||
sub1: {
|
||||
title: '판매대리점 정보',
|
||||
comment: '※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점:××설비주식회사)」로 기입해 주세요.)',
|
||||
storeQcastNm: '판매대리점명',
|
||||
storeQcastNm_placeholder: '株式会社エネルギア・ソリューション・アンド・サービス(2次店:山口住機販売有限会社)',
|
||||
storeQcastNmKana: '판매대리점명 후리가나',
|
||||
storeQcastNmKana_placeholder: 'カブシキガイシャエネルギア・ソリューション・アン',
|
||||
postCd: '우편번호',
|
||||
postCd_placeholder: '숫자 7자리',
|
||||
addr: '주소',
|
||||
addr_placeholder: '전각50자이내',
|
||||
telNo: '전화번호',
|
||||
telNo_placeholder: '00-0000-0000',
|
||||
fax: 'FAX 번호',
|
||||
fax_placeholder: '00-0000-0000',
|
||||
},
|
||||
sub2: {
|
||||
title: '담당자 정보',
|
||||
userNm: '담당자명',
|
||||
userNmKana: '담당자명 후리가나',
|
||||
userId: '신청 ID',
|
||||
email: '이메일 주소',
|
||||
telNo: '전화번호',
|
||||
telNo_placeholder: '00-0000-0000',
|
||||
fax: 'FAX 번호',
|
||||
fax_placeholder: '00-0000-0000',
|
||||
category: '부서명',
|
||||
},
|
||||
sub3: {
|
||||
title: '견적서 제출용 회사정보',
|
||||
qtCompNm: '회사명',
|
||||
qtPostCd: '우편번호',
|
||||
qtPostCd_placeholder: '숫자 7자리',
|
||||
qtAddr: '주소',
|
||||
qtAddr_placeholder: '전각50자이내',
|
||||
qtEmail: '이메일 주소',
|
||||
qtTelNo: '전화번호',
|
||||
qtTelNo_placeholder: '00-0000-0000',
|
||||
qtFax: 'FAX 번호',
|
||||
qtFax_placeholder: '00-0000-0000',
|
||||
},
|
||||
btn: {
|
||||
approval_request: 'ID 승인요청',
|
||||
},
|
||||
complete: {
|
||||
title: 'Q.CAST3 로그인ID 발행신청 완료',
|
||||
contents: '※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.',
|
||||
email_comment: '담당자 이메일 주소',
|
||||
email: 'test@naver.com',
|
||||
},
|
||||
},
|
||||
stuff: {
|
||||
gridHeader: {
|
||||
lastEditDatetime: '갱신일시',
|
||||
objectNo: '물건번호',
|
||||
planTotCnt: '플랜 수',
|
||||
objectName: '물건명',
|
||||
saleStoreId: '대리점ID',
|
||||
saleStoreName: '대리점명',
|
||||
address: '물건주소',
|
||||
dispCompanyName: '견적처',
|
||||
receiveUser: '담당자',
|
||||
specDate: '사양확인',
|
||||
createDatetime: '등록일',
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -247,6 +247,11 @@
|
||||
"modal.object.setting.direction.select": "方向の選択",
|
||||
"modal.placement.surface.setting.info": "ⓘ ①の長さ入力後に対角線の長さを入力すると、②の長さを自動計算します。",
|
||||
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
|
||||
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
||||
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
||||
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
||||
"plan.message.save": "저장되었습니다.",
|
||||
"plan.message.delete": "삭제되었습니다.",
|
||||
"setting": "設定",
|
||||
"common.message.no.data": "No data",
|
||||
"common.message.no.dataDown": "ダウンロードするデータがありません",
|
||||
@ -335,7 +340,7 @@
|
||||
"common.message.writeToConfirm": "作成解除を実行しますか?",
|
||||
"common.message.password.init.success": "パスワード [{0}] に初期化されました。",
|
||||
"common.message.no.edit.save": "この文書は変更できません。",
|
||||
"common.require": "필수",
|
||||
"common.require": "必須",
|
||||
"commons.west": "立つ",
|
||||
"commons.east": "ドン",
|
||||
"commons.south": "立つ",
|
||||
@ -380,6 +385,7 @@
|
||||
"myinfo.message.save": "パスワードが変更されました。",
|
||||
"myinfo.message.password.error": "パスワードが間違っています。",
|
||||
"login": "ログイン",
|
||||
"login.auto.page.text": "自動ログイン中です。",
|
||||
"login.id.save": "ID保存",
|
||||
"login.id.placeholder": "IDを入力してください。",
|
||||
"login.password.placeholder": "パスワードを入力してください。",
|
||||
@ -497,6 +503,7 @@
|
||||
"stuff.planReqPopup.search.period": "期間検索",
|
||||
"stuff.planReqPopup.search.schDateGbnS": "提出日",
|
||||
"stuff.planReqPopup.search.schDateGbnR": "受付日",
|
||||
"stuff.planReqPopup.error.message1": "設計依頼を選択してください。",
|
||||
"stuff.search.title": "物件状況",
|
||||
"stuff.search.btn1": "物件登録",
|
||||
"stuff.search.btn2": "照会",
|
||||
@ -511,6 +518,11 @@
|
||||
"stuff.search.period": "期間検索",
|
||||
"stuff.search.schDateTypeU": "更新日",
|
||||
"stuff.search.schDateTypeR": "登録日",
|
||||
"stuff.search.grid.title": "商品リスト",
|
||||
"stuff.search.grid.all": "全体",
|
||||
"stuff.search.grid.selected": "選択",
|
||||
"stuff.search.grid.schSortTypeR": "最近の登録日",
|
||||
"stuff.search.grid.schSortTypeU": "最近の更新日",
|
||||
"stuff.windSelectPopup.title": "風速選択",
|
||||
"stuff.windSelectPopup.table.selected": "選択",
|
||||
"stuff.windSelectPopup.table.windspeed": "風速",
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
console.log('Loaded KO')
|
||||
|
||||
export default {
|
||||
hello: '안녕',
|
||||
welcome: '안녕 {name}!',
|
||||
locale: '현재 로케일은 {locale}입니다.',
|
||||
common: {
|
||||
require: '필수',
|
||||
},
|
||||
site: {
|
||||
name: 'Q.CAST III',
|
||||
sub_name: '태양광 발전 시스템 도면관리 사이트',
|
||||
},
|
||||
login: {
|
||||
login: '로그인',
|
||||
init_password: {
|
||||
btn: '비밀번호 초기화',
|
||||
title: '비밀번호 초기화',
|
||||
sub_title: '비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.',
|
||||
complete_message: '비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.',
|
||||
},
|
||||
},
|
||||
join: {
|
||||
title: 'Q.CAST3 로그인ID 발행 신청',
|
||||
sub1: {
|
||||
title: '판매대리점 정보',
|
||||
comment: '※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점:××설비주식회사)」로 기입해 주세요.)',
|
||||
storeQcastNm: '판매대리점명',
|
||||
storeQcastNm_placeholder: '주식회사 에너지 기어 솔루션 앤 서비스 (2차점: 야마구치 주기 판매 유한회사)',
|
||||
storeQcastNmKana: '판매대리점명 후리가나',
|
||||
storeQcastNmKana_placeholder: '주식회사 에너지 기어 솔루션',
|
||||
postCd: '우편번호',
|
||||
postCd_placeholder: '숫자 7자리',
|
||||
addr: '주소',
|
||||
addr_placeholder: '전각50자이내',
|
||||
telNo: '전화번호',
|
||||
telNo_placeholder: '00-0000-0000',
|
||||
fax: 'FAX 번호',
|
||||
fax_placeholder: '00-0000-0000',
|
||||
},
|
||||
sub2: {
|
||||
title: '담당자 정보',
|
||||
userNm: '담당자명',
|
||||
userNmKana: '담당자명 후리가나',
|
||||
userId: '신청 ID',
|
||||
email: '이메일 주소',
|
||||
telNo: '전화번호',
|
||||
telNo_placeholder: '00-0000-0000',
|
||||
fax: 'FAX 번호',
|
||||
fax_placeholder: '00-0000-0000',
|
||||
category: '부서명',
|
||||
},
|
||||
sub3: {
|
||||
title: '견적서 제출용 회사정보',
|
||||
qtCompNm: '회사명',
|
||||
qtPostCd: '우편번호',
|
||||
qtPostCd_placeholder: '숫자 7자리',
|
||||
qtAddr: '주소',
|
||||
qtAddr_placeholder: '전각50자이내',
|
||||
qtEmail: '이메일 주소',
|
||||
qtTelNo: '전화번호',
|
||||
qtTelNo_placeholder: '00-0000-0000',
|
||||
qtFax: 'FAX 번호',
|
||||
qtFax_placeholder: '00-0000-0000',
|
||||
},
|
||||
btn: {
|
||||
approval_request: 'ID 승인요청',
|
||||
},
|
||||
complete: {
|
||||
title: 'Q.CAST3 로그인ID 발행신청 완료',
|
||||
contents: '※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.',
|
||||
email_comment: '담당자 이메일 주소',
|
||||
email: 'test@naver.com',
|
||||
},
|
||||
},
|
||||
stuff: {
|
||||
gridHeader: {
|
||||
lastEditDatetime: '갱신일시',
|
||||
objectNo: '물건번호',
|
||||
planTotCnt: '플랜 수',
|
||||
objectName: '물건명',
|
||||
saleStoreId: '대리점ID',
|
||||
saleStoreName: '대리점명',
|
||||
address: '물건주소',
|
||||
dispCompanyName: '견적처',
|
||||
receiveUser: '담당자',
|
||||
specDate: '사양확인',
|
||||
createDatetime: '등록일',
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -252,6 +252,11 @@
|
||||
"modal.object.setting.direction.select": "방향 선택",
|
||||
"modal.placement.surface.setting.info": "ⓘ ①의 길이 입력 후 대각선 길이를 입력하면 ②의 길이를 자동 계산합니다.",
|
||||
"modal.placement.surface.setting.diagonal.length": "대각선 길이",
|
||||
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
||||
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
||||
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
||||
"plan.message.save": "저장되었습니다.",
|
||||
"plan.message.delete": "삭제되었습니다.",
|
||||
"setting": "설정",
|
||||
"common.message.no.data": "No data",
|
||||
"common.message.no.dataDown": "No data to download",
|
||||
@ -385,6 +390,7 @@
|
||||
"myinfo.message.save": "비밀번호가 변경되었습니다.",
|
||||
"myinfo.message.password.error": "비밀번호가 틀렸습니다.",
|
||||
"login": "로그인",
|
||||
"login.auto.page.text": "자동로그인 중 입니다.",
|
||||
"login.id.save": "ID Save",
|
||||
"login.id.placeholder": "아이디를 입력해주세요.",
|
||||
"login.password.placeholder": "비밀번호를 입력해주세요.",
|
||||
@ -502,6 +508,7 @@
|
||||
"stuff.planReqPopup.search.period": "기간검색",
|
||||
"stuff.planReqPopup.search.schDateGbnS": "제출일",
|
||||
"stuff.planReqPopup.search.schDateGbnR": "접수일",
|
||||
"stuff.planReqPopup.error.message1": "설계의뢰를 선택해주세요.",
|
||||
"stuff.search.title": "물건현황",
|
||||
"stuff.search.btn1": "신규등록",
|
||||
"stuff.search.btn2": "조회",
|
||||
@ -516,6 +523,11 @@
|
||||
"stuff.search.period": "기간검색",
|
||||
"stuff.search.schDateTypeU": "갱신일",
|
||||
"stuff.search.schDateTypeR": "등록일",
|
||||
"stuff.search.grid.title": "물건목록",
|
||||
"stuff.search.grid.all": "전체",
|
||||
"stuff.search.grid.selected": "선택",
|
||||
"stuff.search.grid.schSortTypeR": "최근 등록일",
|
||||
"stuff.search.grid.schSortTypeU": "최근 갱신일",
|
||||
"stuff.windSelectPopup.title": "풍속선택",
|
||||
"stuff.windSelectPopup.table.selected": "선택",
|
||||
"stuff.windSelectPopup.table.windspeed": "풍속",
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
import { createI18nServer } from 'next-international/server'
|
||||
|
||||
export const { getI18n, getScopedI18n, getCurrentLocale, getStaticParams } = createI18nServer(
|
||||
{
|
||||
ko: () => import('./ko'),
|
||||
ja: () => import('./ja'),
|
||||
},
|
||||
{
|
||||
// Uncomment to use custom segment name
|
||||
// segmentName: 'locale',
|
||||
// Uncomment to set fallback locale
|
||||
// fallbackLocale: en,
|
||||
},
|
||||
)
|
||||
@ -289,3 +289,8 @@ export const canGridOptionSeletor = selector({
|
||||
return points.length === 0 || outerLineFix
|
||||
},
|
||||
})
|
||||
|
||||
export const globalPitchState = atom({
|
||||
key: 'globalPitch',
|
||||
default: 4,
|
||||
})
|
||||
|
||||
@ -16,7 +16,7 @@ export const planReqSearchState = atom({
|
||||
schStartDt: dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD'), //시작일
|
||||
schEndDt: dayjs(new Date()).format('YYYY-MM-DD'), //종료일
|
||||
startRow: 1,
|
||||
endRow: 100,
|
||||
endRow: 20,
|
||||
},
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
@ -15,12 +15,12 @@ export const settingModalFirstOptionsState = atom({
|
||||
{ id: 9, column: 'totalDisplay', name: 'modal.canvas.setting.first.option.total', selected: false },
|
||||
],
|
||||
dimensionDisplay: [
|
||||
{ id: 1, column: 'corridorDimension', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false },
|
||||
{ id: 1, column: 'corridorDimension', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: true },
|
||||
{ id: 2, column: 'realDimension', name: 'modal.canvas.setting.first.option.real.dimension', selected: false },
|
||||
{ id: 3, column: 'noneDimension', name: 'modal.canvas.setting.first.option.none.dimension', selected: false },
|
||||
],
|
||||
option2: [
|
||||
{ id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: false },
|
||||
{ id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: true },
|
||||
{ id: 2, column: 'lineHatch', name: 'modal.canvas.setting.first.option.line', selected: false },
|
||||
{ id: 3, column: 'allPainted', name: 'modal.canvas.setting.first.option.all', selected: false },
|
||||
],
|
||||
@ -57,3 +57,102 @@ export const settingModalGridOptionsState = atom({
|
||||
],
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 할당 표시
|
||||
export const allocDisplaySelector = selector({
|
||||
key: 'allocDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'allocDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 외벽선 표시
|
||||
export const outlineDisplaySelector = selector({
|
||||
key: 'outlineDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'outlineDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 그리드 표시
|
||||
export const gridDisplaySelector = selector({
|
||||
key: 'gridDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'gridDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 지붕선 표시
|
||||
export const roofLineDisplaySelector = selector({
|
||||
key: 'lineDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'lineDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 문자 표시
|
||||
export const wordDisplaySelector = selector({
|
||||
key: 'wordDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'wordDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 회로번호 표시
|
||||
export const circuitNumDisplaySelector = selector({
|
||||
key: 'circuitNumDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'circuitNumDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 흐름 방향 표시
|
||||
export const flowDisplaySelector = selector({
|
||||
key: 'flowDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'flowDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 가대 표시
|
||||
export const trestleDisplaySelector = selector({
|
||||
key: 'trestleDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'trestleDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 집계표 표시
|
||||
export const totalDisplaySelector = selector({
|
||||
key: 'totalDisplaySelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.option1.find((option) => option.column === 'totalDisplay').selected
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 치수 표시
|
||||
export const corridorDimensionSelector = selector({
|
||||
key: 'corridorDimensionSelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.dimensionDisplay.find((option) => option.selected)
|
||||
},
|
||||
})
|
||||
|
||||
// 디스플레이 설정 - 화면 표시
|
||||
export const realDimensionSelector = selector({
|
||||
key: 'realDimensionSelector',
|
||||
get: ({ get }) => {
|
||||
const settingModalFirstOptions = get(settingModalFirstOptionsState)
|
||||
return settingModalFirstOptions.dimensionDisplay.find((option) => option.selected)
|
||||
},
|
||||
})
|
||||
|
||||
@ -18,10 +18,6 @@ export const stuffSearchState = atom({
|
||||
startRow: 1,
|
||||
endRow: 100,
|
||||
schSortType: 'R', //정렬조건 (R:최근등록일 U:최근수정일)
|
||||
selObject: {
|
||||
value: '',
|
||||
label: '',
|
||||
},
|
||||
},
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +1,5 @@
|
||||
@import '_main.scss';
|
||||
|
||||
.locale-switch {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@ -8,8 +8,10 @@ export const handleFileDown = async (file) => {
|
||||
const params = new URLSearchParams({
|
||||
encodeFileNo: file.encodeFileNo,
|
||||
})
|
||||
const options = { responseType: 'blob' }
|
||||
const apiUrl = `${url}?${params.toString()}`
|
||||
await promiseGet({ url: apiUrl, responseType: 'blob' })
|
||||
|
||||
await promiseGet({ url: apiUrl, option: options })
|
||||
.then((resultData) => {
|
||||
if (resultData) {
|
||||
const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' })
|
||||
@ -25,7 +27,7 @@ export const handleFileDown = async (file) => {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
alert(error.response.data.message)
|
||||
alert('File does not exist.')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -744,67 +744,6 @@ export const polygonToTurfPolygon = (polygon) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const splitDormerTriangle = (triangle, direction) => {
|
||||
const halfWidth = triangle.width / 2
|
||||
|
||||
let leftPoints = []
|
||||
let rightPoints = []
|
||||
let leftPointOffset = []
|
||||
let rightPointOffset = []
|
||||
|
||||
if (direction === 'down') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - halfWidth, y: triangle.top + triangle.height },
|
||||
{ x: triangle.left, y: triangle.top + triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left, y: triangle.top + triangle.height },
|
||||
{ x: triangle.left + halfWidth, y: triangle.top + triangle.height },
|
||||
]
|
||||
} else if (direction === 'up') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - halfWidth, y: triangle.top - triangle.height },
|
||||
{ x: triangle.left, y: triangle.top - triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left, y: triangle.top - triangle.height },
|
||||
{ x: triangle.left + halfWidth, y: triangle.top - triangle.height },
|
||||
]
|
||||
} else if (direction === 'left') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top - halfWidth },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top },
|
||||
{ x: triangle.left - triangle.height, y: triangle.top + halfWidth },
|
||||
]
|
||||
} else if (direction === 'right') {
|
||||
leftPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top + triangle.height },
|
||||
]
|
||||
|
||||
rightPoints = [
|
||||
{ x: triangle.left, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top },
|
||||
{ x: triangle.left + triangle.height, y: triangle.top - triangle.height },
|
||||
]
|
||||
}
|
||||
|
||||
return [leftPoints, rightPoints]
|
||||
}
|
||||
|
||||
export const triangleToPolygon = (triangle) => {
|
||||
const points = []
|
||||
const halfWidth = triangle.width / 2
|
||||
@ -853,7 +792,7 @@ export function setSurfaceShapePattern(polygon) {
|
||||
patternSourceCanvas.width = polygon.width * ratio
|
||||
patternSourceCanvas.height = polygon.height * ratio
|
||||
const ctx = patternSourceCanvas.getContext('2d')
|
||||
const offset = roofStyle === 1 ? 0 : patternSize.width / 2
|
||||
let offset = roofStyle === 1 ? 0 : patternSize.width / 2
|
||||
|
||||
const rows = Math.floor(patternSourceCanvas.height / patternSize.height)
|
||||
const cols = Math.floor(patternSourceCanvas.width / patternSize.width)
|
||||
@ -861,23 +800,46 @@ export function setSurfaceShapePattern(polygon) {
|
||||
ctx.strokeStyle = 'green'
|
||||
ctx.lineWidth = 0.4
|
||||
|
||||
for (let row = 0; row <= rows; row++) {
|
||||
const y = row * patternSize.height
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, y) // 선 시작점
|
||||
ctx.lineTo(patternSourceCanvas.width, y) // 선 끝점
|
||||
ctx.stroke()
|
||||
|
||||
if (polygon.direction === 'east' || polygon.direction === 'west') {
|
||||
offset = roofStyle === 1 ? 0 : patternSize.height / 2
|
||||
for (let col = 0; col <= cols; col++) {
|
||||
const x = col * patternSize.width + (row % 2 === 0 ? 0 : offset)
|
||||
const yStart = row * patternSize.height
|
||||
const yEnd = yStart + patternSize.height
|
||||
|
||||
const x = col * patternSize.width
|
||||
const yStart = 0
|
||||
const yEnd = patternSourceCanvas.height
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x, yStart) // 선 시작점
|
||||
ctx.lineTo(x, yEnd) // 선 끝점
|
||||
ctx.stroke()
|
||||
|
||||
for (let row = 0; row <= rows; row++) {
|
||||
const y = row * patternSize.height + (col % 2 === 0 ? 0 : offset)
|
||||
const xStart = col * patternSize.width
|
||||
const xEnd = xStart + patternSize.width
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(xStart, y) // 선 시작점
|
||||
ctx.lineTo(xEnd, y) // 선 끝점
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let row = 0; row <= rows; row++) {
|
||||
const y = row * patternSize.height
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, y) // 선 시작점
|
||||
ctx.lineTo(patternSourceCanvas.width, y) // 선 끝점
|
||||
ctx.stroke()
|
||||
|
||||
for (let col = 0; col <= cols; col++) {
|
||||
const x = col * patternSize.width + (row % 2 === 0 ? 0 : offset)
|
||||
const yStart = row * patternSize.height
|
||||
const yEnd = yStart + patternSize.height
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x, yStart) // 선 시작점
|
||||
ctx.lineTo(x, yEnd) // 선 끝점
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
56
yarn.lock
56
yarn.lock
@ -273,7 +273,7 @@
|
||||
resolved "https://registry.npmjs.org/@bedrock-layout/use-stateful-ref/-/use-stateful-ref-1.4.1.tgz"
|
||||
integrity sha512-4eKO2KdQEXcR5LI4QcxqlJykJUDQJWDeWYAukIn6sRQYoabcfI5kDl61PUi6FR6o8VFgQ8IEP7HleKqWlSe8SQ==
|
||||
|
||||
"@emotion/babel-plugin@^11.11.0", "@emotion/babel-plugin@^11.12.0":
|
||||
"@emotion/babel-plugin@^11.12.0":
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz#7b43debb250c313101b3f885eba634f1d723fcc2"
|
||||
integrity sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==
|
||||
@ -290,7 +290,7 @@
|
||||
source-map "^0.5.7"
|
||||
stylis "4.2.0"
|
||||
|
||||
"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.0", "@emotion/cache@^11.4.0":
|
||||
"@emotion/cache@^11.13.0", "@emotion/cache@^11.4.0":
|
||||
version "11.13.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7"
|
||||
integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==
|
||||
@ -306,32 +306,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b"
|
||||
integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==
|
||||
|
||||
"@emotion/is-prop-valid@^1.2.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz#8d5cf1132f836d7adbe42cf0b49df7816fc88240"
|
||||
integrity sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==
|
||||
dependencies:
|
||||
"@emotion/memoize" "^0.9.0"
|
||||
|
||||
"@emotion/memoize@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102"
|
||||
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
|
||||
|
||||
"@emotion/react@11.11.0":
|
||||
version "11.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02"
|
||||
integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/babel-plugin" "^11.11.0"
|
||||
"@emotion/cache" "^11.11.0"
|
||||
"@emotion/serialize" "^1.1.2"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
"@emotion/weak-memoize" "^0.3.1"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
|
||||
"@emotion/react@^11.8.1":
|
||||
version "11.13.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.3.tgz#a69d0de2a23f5b48e0acf210416638010e4bd2e4"
|
||||
@ -346,7 +325,7 @@
|
||||
"@emotion/weak-memoize" "^0.4.0"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
|
||||
"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.2.0", "@emotion/serialize@^1.3.1":
|
||||
"@emotion/serialize@^1.2.0", "@emotion/serialize@^1.3.1":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.2.tgz#e1c1a2e90708d5d85d81ccaee2dfeb3cc0cccf7a"
|
||||
integrity sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==
|
||||
@ -362,38 +341,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c"
|
||||
integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==
|
||||
|
||||
"@emotion/styled@11.11.0":
|
||||
version "11.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346"
|
||||
integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/babel-plugin" "^11.11.0"
|
||||
"@emotion/is-prop-valid" "^1.2.1"
|
||||
"@emotion/serialize" "^1.1.2"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
|
||||
"@emotion/utils" "^1.2.1"
|
||||
|
||||
"@emotion/unitless@^0.10.0":
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745"
|
||||
integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==
|
||||
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.0.1", "@emotion/use-insertion-effect-with-fallbacks@^1.1.0":
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf"
|
||||
integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==
|
||||
|
||||
"@emotion/utils@^1.2.1", "@emotion/utils@^1.4.0", "@emotion/utils@^1.4.1":
|
||||
"@emotion/utils@^1.4.0", "@emotion/utils@^1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.1.tgz#b3adbb43de12ee2149541c4f1337d2eb7774f0ad"
|
||||
integrity sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==
|
||||
|
||||
"@emotion/weak-memoize@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
|
||||
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
|
||||
|
||||
"@emotion/weak-memoize@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6"
|
||||
@ -5955,14 +5917,6 @@ react-draggable@^4.4.6:
|
||||
clsx "^1.1.1"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
react-dropdown-select@^4.11.3:
|
||||
version "4.11.3"
|
||||
resolved "https://registry.yarnpkg.com/react-dropdown-select/-/react-dropdown-select-4.11.3.tgz#b23b8906f3bedc9d6a1a2125af936b34d4057158"
|
||||
integrity sha512-/mOGSqqhmKsxxrmotLM+qn1Ss3nxGN6QnYusyQ7f0wizsWrc7ZmbcZhGRtwkJwpL6JYDQVTn19EYxJU1XfXrDA==
|
||||
dependencies:
|
||||
"@emotion/react" "11.11.0"
|
||||
"@emotion/styled" "11.11.0"
|
||||
|
||||
react-hook-form@^7.53.0:
|
||||
version "7.53.0"
|
||||
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.53.0.tgz#3cf70951bf41fa95207b34486203ebefbd3a05ab"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user