Merge branch 'dev' into feature/jaeyoung
This commit is contained in:
commit
81ea49ccdc
2
.gitignore
vendored
2
.gitignore
vendored
@ -41,3 +41,5 @@ next-env.d.ts
|
|||||||
#lock files
|
#lock files
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
pnpm-lock.yaml
|
||||||
|
certificates
|
||||||
1
MainLayout.codediagram
Normal file
1
MainLayout.codediagram
Normal file
File diff suppressed because one or more lines are too long
12
package.json
12
package.json
@ -6,13 +6,15 @@
|
|||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint",
|
||||||
|
"serve": "node server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nextui-org/react": "^2.4.2",
|
"@nextui-org/react": "^2.4.2",
|
||||||
"ag-grid-react": "^32.0.2",
|
"ag-grid-react": "^32.0.2",
|
||||||
"axios": "^1.7.8",
|
"axios": "^1.7.8",
|
||||||
"chart.js": "^4.4.6",
|
"chart.js": "^4.4.6",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"fabric": "^5.3.0",
|
"fabric": "^5.3.0",
|
||||||
"framer-motion": "^11.2.13",
|
"framer-motion": "^11.2.13",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
@ -20,7 +22,7 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"mathjs": "^13.0.2",
|
"mathjs": "^13.0.2",
|
||||||
"mssql": "^11.0.1",
|
"mssql": "^11.0.1",
|
||||||
"next": "14.2.14",
|
"next": "14.2.21",
|
||||||
"next-international": "^1.2.4",
|
"next-international": "^1.2.4",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-chartjs-2": "^5.2.0",
|
"react-chartjs-2": "^5.2.0",
|
||||||
@ -32,12 +34,12 @@
|
|||||||
"react-icons": "^5.3.0",
|
"react-icons": "^5.3.0",
|
||||||
"react-loading-skeleton": "^3.5.0",
|
"react-loading-skeleton": "^3.5.0",
|
||||||
"react-responsive-modal": "^6.4.2",
|
"react-responsive-modal": "^6.4.2",
|
||||||
|
"react-select": "^5.8.1",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"sweetalert2": "^11.14.1",
|
"sweetalert2": "^11.14.1",
|
||||||
"sweetalert2-react-content": "^5.0.7",
|
"sweetalert2-react-content": "^5.0.7",
|
||||||
"uuid": "^10.0.0",
|
"usehooks-ts": "^3.1.0",
|
||||||
"dayjs": "^1.11.13",
|
"uuid": "^10.0.0"
|
||||||
"react-select": "^5.8.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@turf/turf": "^7.0.0",
|
"@turf/turf": "^7.0.0",
|
||||||
|
|||||||
40
server.js
Normal file
40
server.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const http = require('http')
|
||||||
|
const { parse } = require('url')
|
||||||
|
const next = require('next')
|
||||||
|
|
||||||
|
const https = require('https')
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const dev = process.env.NODE_ENV !== 'production'
|
||||||
|
const app = next({ dev })
|
||||||
|
const handle = app.getRequestHandler()
|
||||||
|
|
||||||
|
const PORT = 3000
|
||||||
|
|
||||||
|
const httpsOptions = {
|
||||||
|
key: fs.readFileSync('./certificates/key.pem'),
|
||||||
|
cert: fs.readFileSync('./certificates/cert.pem'),
|
||||||
|
}
|
||||||
|
|
||||||
|
app.prepare().then(() => {
|
||||||
|
http
|
||||||
|
.createServer((req, res) => {
|
||||||
|
const parsedUrl = parse(req.url, true)
|
||||||
|
handle(req, res, parsedUrl)
|
||||||
|
})
|
||||||
|
.listen(PORT, (err) => {
|
||||||
|
if (err) throw err
|
||||||
|
console.log(`> Ready on http://localhost:${PORT}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
// https 서버 추가
|
||||||
|
https
|
||||||
|
.createServer(httpsOptions, (req, res) => {
|
||||||
|
const parsedUrl = parse(req.url, true)
|
||||||
|
handle(req, res, parsedUrl)
|
||||||
|
})
|
||||||
|
.listen(PORT + 1, (err) => {
|
||||||
|
if (err) throw err
|
||||||
|
console.log(`> HTTPS: Ready on https://localhost:${PORT + 1}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
24
src/app/GlobalDataProvider.js
Normal file
24
src/app/GlobalDataProvider.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { createContext, useEffect, useState } from 'react'
|
||||||
|
import { useLocalStorage } from 'usehooks-ts'
|
||||||
|
|
||||||
|
export const GlobalDataContext = createContext({
|
||||||
|
managementState: {},
|
||||||
|
setManagementState: () => {},
|
||||||
|
managementStateLoaded: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const GlobalDataProvider = ({ children }) => {
|
||||||
|
const [managementState, setManagementState] = useState({})
|
||||||
|
// TODO: 임시 조치이며 개발 완료시 삭제 예정 -> 잊지말기...
|
||||||
|
const [managementStateLoaded, setManagementStateLoaded] = useLocalStorage('managementStateLoaded', null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setManagementStateLoaded(managementState)
|
||||||
|
}, [managementState])
|
||||||
|
|
||||||
|
return <GlobalDataContext.Provider value={{ managementState, setManagementState, managementStateLoaded }}>{children}</GlobalDataContext.Provider>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GlobalDataProvider
|
||||||
@ -1,9 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { createContext, useEffect, useState } from 'react'
|
import { createContext, useState } from 'react'
|
||||||
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
||||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
|
||||||
import ServerError from './error'
|
import ServerError from './error'
|
||||||
|
|
||||||
import '@/styles/common.scss'
|
import '@/styles/common.scss'
|
||||||
@ -19,7 +18,6 @@ export const QcastContext = createContext({
|
|||||||
export const QcastProvider = ({ children }) => {
|
export const QcastProvider = ({ children }) => {
|
||||||
const [planSave, setPlanSave] = useState(false)
|
const [planSave, setPlanSave] = useState(false)
|
||||||
const [isGlobalLoading, setIsGlobalLoading] = useState(false)
|
const [isGlobalLoading, setIsGlobalLoading] = useState(false)
|
||||||
const { currentCanvasPlan, modifiedPlans, checkUnsavedCanvasPlan } = usePlan()
|
|
||||||
const { commonCode, findCommonCode } = useCommonCode()
|
const { commonCode, findCommonCode } = useCommonCode()
|
||||||
|
|
||||||
const [qcastState, setQcastState] = useState({
|
const [qcastState, setQcastState] = useState({
|
||||||
@ -30,16 +28,6 @@ export const QcastProvider = ({ children }) => {
|
|||||||
businessChargerMail: null,
|
businessChargerMail: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const targetElement = document.getElementById('canvas')
|
|
||||||
if (!targetElement && currentCanvasPlan?.id && planSave) {
|
|
||||||
setPlanSave((prev) => !prev)
|
|
||||||
checkUnsavedCanvasPlan()
|
|
||||||
} else if (targetElement && currentCanvasPlan?.id) {
|
|
||||||
setPlanSave(true)
|
|
||||||
}
|
|
||||||
}, [modifiedPlans])
|
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// console.log('commonCode', commonCode)
|
// console.log('commonCode', commonCode)
|
||||||
// console.log(findCommonCode(113600))
|
// console.log(findCommonCode(113600))
|
||||||
|
|||||||
@ -4,10 +4,11 @@ import { getSession } from '@/lib/authActions'
|
|||||||
import RecoilRootWrapper from './RecoilWrapper'
|
import RecoilRootWrapper from './RecoilWrapper'
|
||||||
|
|
||||||
import { QcastProvider } from './QcastProvider'
|
import { QcastProvider } from './QcastProvider'
|
||||||
|
import SessionProvider from './SessionProvider'
|
||||||
|
import GlobalDataProvider from './GlobalDataProvider'
|
||||||
import Header from '@/components/header/Header'
|
import Header from '@/components/header/Header'
|
||||||
import QModal from '@/components/common/modal/QModal'
|
import QModal from '@/components/common/modal/QModal'
|
||||||
import Dimmed from '@/components/ui/Dimmed'
|
import Dimmed from '@/components/ui/Dimmed'
|
||||||
import SessionProvider from './SessionProvider'
|
|
||||||
import PopupManager from '@/components/common/popupManager/PopupManager'
|
import PopupManager from '@/components/common/popupManager/PopupManager'
|
||||||
|
|
||||||
import './globals.css'
|
import './globals.css'
|
||||||
@ -50,7 +51,6 @@ export default async function RootLayout({ children }) {
|
|||||||
isLoggedIn: session.isLoggedIn,
|
isLoggedIn: session.isLoggedIn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!headerPathname.includes('/login') && !session.isLoggedIn) {
|
if (!headerPathname.includes('/login') && !session.isLoggedIn) {
|
||||||
redirect('/login')
|
redirect('/login')
|
||||||
}
|
}
|
||||||
@ -61,26 +61,28 @@ export default async function RootLayout({ children }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RecoilRootWrapper>
|
<RecoilRootWrapper>
|
||||||
<html lang="en">
|
<GlobalDataProvider>
|
||||||
<body>
|
<html lang="en">
|
||||||
{headerPathname === '/login' || headerPathname === '/join' ? (
|
<body>
|
||||||
<QcastProvider>{children}</QcastProvider>
|
{headerPathname === '/login' || headerPathname === '/join' ? (
|
||||||
) : (
|
<QcastProvider>{children}</QcastProvider>
|
||||||
<QcastProvider>
|
) : (
|
||||||
<div className="wrap">
|
<QcastProvider>
|
||||||
<Header userSession={sessionProps} />
|
<div className="wrap">
|
||||||
<div className="content">
|
<Header userSession={sessionProps} />
|
||||||
<Dimmed />
|
<div className="content">
|
||||||
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
<Dimmed />
|
||||||
|
<SessionProvider useSession={sessionProps}>{children}</SessionProvider>
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
</QcastProvider>
|
||||||
</div>
|
)}
|
||||||
</QcastProvider>
|
<QModal />
|
||||||
)}
|
<PopupManager />
|
||||||
<QModal />
|
</body>
|
||||||
<PopupManager />
|
</html>
|
||||||
</body>
|
</GlobalDataProvider>
|
||||||
</html>
|
|
||||||
</RecoilRootWrapper>
|
</RecoilRootWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,18 @@
|
|||||||
'ues client'
|
'ues client'
|
||||||
|
|
||||||
import { createContext, useEffect, useState } from 'react'
|
import { createContext } from 'react'
|
||||||
|
|
||||||
export const ManagementContext = createContext({
|
export const ManagementContext = createContext({})
|
||||||
managementState: {},
|
|
||||||
setManagementState: () => {},
|
|
||||||
})
|
|
||||||
|
|
||||||
const ManagementProvider = ({ children }) => {
|
const ManagementProvider = ({ children }) => {
|
||||||
const [managementState, setManagementState] = useState({})
|
// const [managementState, setManagementState] = useState({})
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
console.log('🚀 ~ managementState:', managementState)
|
// console.log('🚀 ~ managementState:', managementState)
|
||||||
}, [managementState])
|
// }, [managementState])
|
||||||
|
|
||||||
return <ManagementContext.Provider value={{ managementState, setManagementState }}>{children}</ManagementContext.Provider>
|
// return <ManagementContext.Provider value={{ managementState, setManagementState }}>{children}</ManagementContext.Provider>
|
||||||
|
return <ManagementContext.Provider>{children}</ManagementContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ManagementProvider
|
export default ManagementProvider
|
||||||
|
|||||||
@ -112,6 +112,7 @@ export const POLYGON_TYPE = {
|
|||||||
WALL: 'wall',
|
WALL: 'wall',
|
||||||
TRESTLE: 'trestle',
|
TRESTLE: 'trestle',
|
||||||
MODULE_SETUP_SURFACE: 'moduleSetupSurface',
|
MODULE_SETUP_SURFACE: 'moduleSetupSurface',
|
||||||
|
MODULE: 'module',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SAVE_KEY = [
|
export const SAVE_KEY = [
|
||||||
|
|||||||
@ -41,12 +41,12 @@ export default function MainPage(mainPageProps) {
|
|||||||
if (searchRadioType === 'object') {
|
if (searchRadioType === 'object') {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
...stuffSearch,
|
...stuffSearch,
|
||||||
schObjectNo: searchTxt,
|
schObjectNo: searchTxt.trim(),
|
||||||
code: 'M',
|
code: 'M',
|
||||||
})
|
})
|
||||||
router.push('/management/stuff', { scroll: false })
|
router.push('/management/stuff', { scroll: false })
|
||||||
} else {
|
} else {
|
||||||
setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' })
|
setSearchForm({ ...searchForm, searchValue: searchTxt.trim(), mainFlag: 'Y' })
|
||||||
router.push('/community/faq')
|
router.push('/community/faq')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useRef, useState, useEffect } from 'react'
|
import { useRef, useState, useEffect, useContext } from 'react'
|
||||||
|
import Image from 'next/image'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { FaAnglesUp } from 'react-icons/fa6'
|
import { FaAnglesUp } from 'react-icons/fa6'
|
||||||
import { FaAnglesDown } from 'react-icons/fa6'
|
import { FaAnglesDown } from 'react-icons/fa6'
|
||||||
|
import { Button } from '@nextui-org/react'
|
||||||
|
import ColorPicker from './common/color-picker/ColorPicker'
|
||||||
|
import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom'
|
||||||
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
import { convertDwgToPng } from '@/lib/cadAction'
|
|
||||||
import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom'
|
|
||||||
|
|
||||||
import { Button } from '@nextui-org/react'
|
|
||||||
import ColorPicker from './common/color-picker/ColorPicker'
|
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { convertDwgToPng } from '@/lib/cadAction'
|
||||||
import styles from './playground.module.css'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
import Image from 'next/image'
|
|
||||||
|
|
||||||
import QInput from './common/input/Qinput'
|
import QInput from './common/input/Qinput'
|
||||||
import QSelect from './common/select/QSelect'
|
import QSelect from './common/select/QSelect'
|
||||||
import QPagination from './common/pagination/QPagination'
|
import QPagination from './common/pagination/QPagination'
|
||||||
|
import QSelectBox from './common/select/QSelectBox'
|
||||||
|
import SampleReducer from './sample/SampleReducer'
|
||||||
|
|
||||||
|
import styles from './playground.module.css'
|
||||||
|
|
||||||
export default function Playground() {
|
export default function Playground() {
|
||||||
const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState)
|
const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState)
|
||||||
@ -36,7 +37,7 @@ export default function Playground() {
|
|||||||
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
|
const { getRoofMaterialList, getModuleTypeItemList, getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController()
|
||||||
|
|
||||||
const [color, setColor] = useState('#ff0000')
|
const [color, setColor] = useState('#ff0000')
|
||||||
|
|
||||||
@ -48,6 +49,8 @@ export default function Playground() {
|
|||||||
|
|
||||||
const [users, setUsers] = useState([])
|
const [users, setUsers] = useState([])
|
||||||
|
|
||||||
|
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('textInput:', textInput)
|
console.log('textInput:', textInput)
|
||||||
}, [textInput])
|
}, [textInput])
|
||||||
@ -154,6 +157,75 @@ export default function Playground() {
|
|||||||
console.log('users:', users)
|
console.log('users:', users)
|
||||||
}, [users])
|
}, [users])
|
||||||
|
|
||||||
|
const codes = [
|
||||||
|
{
|
||||||
|
clHeadCd: '203800',
|
||||||
|
clCode: 'HEI_455',
|
||||||
|
clCodeNm: '세로 455mm이하',
|
||||||
|
clPriority: 1,
|
||||||
|
name: '세로 455mm이하',
|
||||||
|
id: 'HEI_455',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clHeadCd: '203800',
|
||||||
|
clCode: 'HEI_500',
|
||||||
|
clCodeNm: '세로 500mm이하',
|
||||||
|
clPriority: 2,
|
||||||
|
name: '세로 500mm이하',
|
||||||
|
id: 'HEI_500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clHeadCd: '203800',
|
||||||
|
clCode: 'HEI_606',
|
||||||
|
clCodeNm: '세로 606mm이하',
|
||||||
|
clPriority: 3,
|
||||||
|
name: '세로 606mm이하',
|
||||||
|
id: 'HEI_606',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clHeadCd: '203800',
|
||||||
|
clCode: 'WID_606',
|
||||||
|
clCodeNm: '가로 606mm이하',
|
||||||
|
clPriority: 4,
|
||||||
|
name: '가로 606mm이하',
|
||||||
|
id: 'WID_606',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
clHeadCd: '203800',
|
||||||
|
clCode: 'ETC',
|
||||||
|
clCodeNm: '기타',
|
||||||
|
clPriority: 5,
|
||||||
|
name: '기타',
|
||||||
|
id: 'ETC',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const [myData, setMyData] = useState({
|
||||||
|
roofMatlCd: 'ROOF_ID_WA_53A',
|
||||||
|
roofMatlNm: '화와 A',
|
||||||
|
roofMatlNmJp: '和瓦A',
|
||||||
|
widAuth: 'R',
|
||||||
|
widBase: '265.000',
|
||||||
|
lenAuth: 'R',
|
||||||
|
lenBase: '235.000',
|
||||||
|
roofPchAuth: null,
|
||||||
|
roofPchBase: null,
|
||||||
|
raftAuth: 'C',
|
||||||
|
raftBaseCd: 'HEI_455',
|
||||||
|
id: 'ROOF_ID_WA_53A',
|
||||||
|
name: '화와 A',
|
||||||
|
selected: true,
|
||||||
|
nameJp: '和瓦A',
|
||||||
|
length: 235,
|
||||||
|
width: 265,
|
||||||
|
layout: 'P',
|
||||||
|
hajebichi: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChangeMyData = () => {
|
||||||
|
setMyData({ ...myData, raftBaseCd: 'HEI_500' })
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="container mx-auto p-4 m-4 border">
|
<div className="container mx-auto p-4 m-4 border">
|
||||||
@ -166,16 +238,70 @@ export default function Playground() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
지붕재 목록 조회 API 호출
|
지붕재 목록 조회 API 호출
|
||||||
</button>
|
</button>{' '}
|
||||||
<button
|
<button
|
||||||
className="btn-frame deepgray"
|
className="btn-frame deepgray"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
getModuleTypeItemList('ROOF_ID_HIRA_SEME')
|
getModuleTypeItemList(['ROOF_ID_HIRA_SEME', 'ROOF_ID_ROOGA'])
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
모듈 타입별 아이템 목록 조회 API 호출
|
모듈 타입별 아이템 목록 조회 API 호출
|
||||||
|
</button>{' '}
|
||||||
|
<button
|
||||||
|
className="btn-frame deepgray"
|
||||||
|
onClick={() => {
|
||||||
|
getTrestleList({ moduleTpCd: '', roofMatlCd: '', raftBaseCd: '', trestleMkrCd: '', constMthdCd: '', roofBaseCd: '' }) //임시 데이터
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
가대 목록 조회 API 호출
|
||||||
|
</button>{' '}
|
||||||
|
<button
|
||||||
|
className="btn-frame deepgray"
|
||||||
|
onClick={() => {
|
||||||
|
getConstructionList({
|
||||||
|
//임시 데이터
|
||||||
|
moduleTpCd: 'testData_1',
|
||||||
|
roofMatlCd: 'testData_2',
|
||||||
|
trestleMkrCd: 'testData_3',
|
||||||
|
constMthdCd: 'testData_4',
|
||||||
|
roofBaseCd: 'testData_5',
|
||||||
|
illuminationTp: 'testData_6',
|
||||||
|
instHt: 'testData_7',
|
||||||
|
stdWindSpeed: 'testData_8',
|
||||||
|
stdSnowLd: 'testData_9',
|
||||||
|
inclCd: 'testData_10',
|
||||||
|
raftBaseCd: '',
|
||||||
|
roofPitch: 30,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
시공법 목록 조회 API 호출
|
||||||
|
</button>{' '}
|
||||||
|
<button
|
||||||
|
className="btn-frame deepgray"
|
||||||
|
onClick={() => {
|
||||||
|
getTrestleDetailList({
|
||||||
|
//임시 데이터
|
||||||
|
moduleTpCd: 'testData_1',
|
||||||
|
roofMatlCd: 'testData_2',
|
||||||
|
trestleMkrCd: 'testData_3',
|
||||||
|
constMthdCd: 'testData_4',
|
||||||
|
roofBaseCd: 'testData_5',
|
||||||
|
illuminationTp: 'testData_6',
|
||||||
|
instHt: 'testData_7',
|
||||||
|
stdWindSpeed: 'testData_8',
|
||||||
|
stdSnowLd: 'testData_9',
|
||||||
|
inclCd: 'testData_10',
|
||||||
|
constTp: 'testData_11',
|
||||||
|
mixMatlNo: 30,
|
||||||
|
roofPitch: 0,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
가대 상세 조회 API 호출
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="m-2">
|
<div className="m-2">
|
||||||
<button
|
<button
|
||||||
className="btn-frame deepgray"
|
className="btn-frame deepgray"
|
||||||
@ -372,6 +498,29 @@ export default function Playground() {
|
|||||||
axios post test
|
axios post test
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<QSelectBox options={codes} value={myData} sourceKey="id" targetKey="raftBaseCd" showKey="clCodeNm" />
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<Button onClick={handleChangeMyData}>QSelectBox value change!!</Button>
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<SampleReducer />
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<Button onClick={() => setManagementState({ ...managementState, objectNo: '1234567890' })}>GlobalDataProvider 테스트</Button>
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<Button onClick={() => setManagementState({})}>GlobalDataProvider 초기화</Button>
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<p>{managementStateLoaded?.objectNo}</p>
|
||||||
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<Button onClick={() => swalFire({ text: 'alert 테스트입니다.', type: 'alert', confirmFn: () => console.log('Alert!!!') })}>
|
||||||
|
Sweetalert - alert
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Image from 'next/image'
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { setSession } from '@/lib/authActions'
|
import { setSession, login } from '@/lib/authActions'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { sessionStore } from '@/store/commonAtom'
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
@ -36,7 +36,7 @@ export default function Login() {
|
|||||||
const result = { ...response, storeLvl: response.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' }
|
const result = { ...response, storeLvl: response.groupId === '60000' ? '1' : '2', pwdInitYn: 'Y' }
|
||||||
setSession(result)
|
setSession(result)
|
||||||
setSessionState(result)
|
setSessionState(result)
|
||||||
router.push('/')
|
login()
|
||||||
} else {
|
} else {
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
}
|
}
|
||||||
@ -97,7 +97,8 @@ export default function Login() {
|
|||||||
} else {
|
} else {
|
||||||
Cookies.remove('chkLoginId')
|
Cookies.remove('chkLoginId')
|
||||||
}
|
}
|
||||||
router.push('/')
|
// router.push('/')
|
||||||
|
login()
|
||||||
} else {
|
} else {
|
||||||
alert(res.data.result.resultMsg)
|
alert(res.data.result.resultMsg)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ export default function ColorPickerModal(props) {
|
|||||||
|
|
||||||
//치수선색설정 아닐 때만 바로 저장 실행
|
//치수선색설정 아닐 때만 바로 저장 실행
|
||||||
if (name !== 'DimensionLineColor')
|
if (name !== 'DimensionLineColor')
|
||||||
setSettingsData({
|
setSettingsDataSave({
|
||||||
...settingsData,
|
...settingsData,
|
||||||
color: originColor,
|
color: originColor,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
import { Fragment } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { popupState } from '@/store/popupAtom'
|
import { popupState } from '@/store/popupAtom'
|
||||||
import { Fragment } from 'react'
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 관리자
|
||||||
|
*/
|
||||||
export default function PopupManager() {
|
export default function PopupManager() {
|
||||||
const popup = useRecoilValue(popupState)
|
const popup = useRecoilValue(popupState)
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,81 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
import { useOnClickOutside } from 'usehooks-ts'
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} title - 선택 제목 (선택이 없을때 보여질 값)
|
||||||
|
* @param {array} options - 선택 옵션 객체 {}
|
||||||
|
* @param {function} onChange - 선택 변경 함수
|
||||||
|
* @param {object} value - 선택 값 객체 {}
|
||||||
|
* @param {boolean} disabled - 선택 비활성화 여부
|
||||||
|
* @param {string} sourceKey - options에 있는 키
|
||||||
|
* @param {string} targetKey - value에 있는 키
|
||||||
|
* @param {string} showKey - options 있는 키중 보여줄 키
|
||||||
|
* @param {object} params - 추가 파라미터
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function QSelectBox({
|
||||||
|
title = '',
|
||||||
|
options,
|
||||||
|
onChange,
|
||||||
|
value,
|
||||||
|
disabled = false,
|
||||||
|
sourceKey = '',
|
||||||
|
targetKey = '',
|
||||||
|
showKey = '',
|
||||||
|
params = {},
|
||||||
|
}) {
|
||||||
|
/**
|
||||||
|
* 초기 상태 처리
|
||||||
|
* useState 초기 값으로 사용해야 해서 useState 보다 위에 작성
|
||||||
|
* @returns {string} 초기 상태
|
||||||
|
*/
|
||||||
|
const handleInitState = () => {
|
||||||
|
//title이 있으면 우선 보여준다(다른 키들 무시)
|
||||||
|
if (title !== '') {
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
|
//value가 없으면 showKey가 있으면 우선 보여준다
|
||||||
|
if (showKey !== '' && !value) {
|
||||||
|
return options[0][showKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
//value가 있으면 sourceKey와 targetKey를 비교하여 보여준다
|
||||||
|
if (showKey !== '' && value) {
|
||||||
|
const option = options.find((option) => option[sourceKey] === value[targetKey])
|
||||||
|
return option[showKey]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function QSelectBox({ title = '', options, onChange, value, disabled = false, params = {} }) {
|
|
||||||
const [openSelect, setOpenSelect] = useState(false)
|
const [openSelect, setOpenSelect] = useState(false)
|
||||||
const [selected, setSelected] = useState(title === '' ? options[0].name : title)
|
const [selected, setSelected] = useState(handleInitState())
|
||||||
|
const ref = useRef(null)
|
||||||
|
|
||||||
const handleClickSelectOption = (option) => {
|
const handleClickSelectOption = (option) => {
|
||||||
setSelected(option.name)
|
setSelected(showKey !== '' ? option[showKey] : option.name)
|
||||||
onChange?.(option, params)
|
onChange?.(option, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpenSelect(false)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
value && handleClickSelectOption(value)
|
// value && handleClickSelectOption(value)
|
||||||
}, [value])
|
setSelected(handleInitState())
|
||||||
|
}, [value, sourceKey, targetKey, showKey])
|
||||||
|
|
||||||
|
useOnClickOutside(ref, handleClose)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`sort-select ${openSelect ? 'active' : ''}`} onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)}>
|
<div className={`sort-select ${openSelect ? 'active' : ''}`} ref={ref} onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)}>
|
||||||
<p>{selected}</p>
|
<p>{selected}</p>
|
||||||
<ul className="select-item-wrap">
|
<ul className="select-item-wrap">
|
||||||
{options?.map((option, index) => (
|
{options?.map((option, index) => (
|
||||||
<li key={option.id || index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
<li key={option.id || index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
||||||
<button key={option.id + 'btn'}>{option.name}</button>
|
<button key={option.id + 'btn'}>{showKey !== '' ? option[showKey] : option.name}</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -35,10 +35,6 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
|
|
||||||
this.startPoint = { x: this.x1, y: this.y1 }
|
this.startPoint = { x: this.x1, y: this.y1 }
|
||||||
this.endPoint = { x: this.x2, y: this.y2 }
|
this.endPoint = { x: this.x2, y: this.y2 }
|
||||||
|
|
||||||
if (canvas) {
|
|
||||||
this.canvas = canvas
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
|
|||||||
@ -1,32 +1,28 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext, useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
|
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
|
|
||||||
|
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||||
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
|
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
||||||
import { useCanvas } from '@/hooks/useCanvas'
|
import { useCanvas } from '@/hooks/useCanvas'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
|
||||||
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
|
||||||
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
||||||
import { MENU } from '@/common/common'
|
import { currentMenuState } from '@/store/canvasAtom'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
import { MENU } from '@/common/common'
|
||||||
|
|
||||||
export default function CanvasFrame() {
|
export default function CanvasFrame() {
|
||||||
const canvasRef = useRef(null)
|
const canvasRef = useRef(null)
|
||||||
const { canvas, handleBackImageLoadToCanvas } = useCanvas('canvas')
|
const { canvas } = useCanvas('canvas')
|
||||||
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
|
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
|
||||||
const currentMenu = useRecoilValue(currentMenuState)
|
const currentMenu = useRecoilValue(currentMenuState)
|
||||||
const { contextMenu, handleClick } = useContextMenu()
|
const { contextMenu, handleClick } = useContextMenu()
|
||||||
const { selectedPlan, modifiedPlanFlag, checkCanvasObjectEvent, resetModifiedPlans, currentCanvasPlan } = usePlan()
|
const { selectedPlan } = usePlan()
|
||||||
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
||||||
// useEvent()
|
|
||||||
// const { initEvent } = useContext(EventContext)
|
|
||||||
// initEvent()
|
|
||||||
|
|
||||||
const loadCanvas = () => {
|
const loadCanvas = () => {
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
@ -41,21 +37,8 @@ export default function CanvasFrame() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (modifiedPlanFlag && selectedPlan?.id) {
|
|
||||||
checkCanvasObjectEvent(selectedPlan.id)
|
|
||||||
}
|
|
||||||
}, [modifiedPlanFlag])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
resetModifiedPlans()
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadCanvas()
|
loadCanvas()
|
||||||
resetModifiedPlans()
|
|
||||||
}, [selectedPlan, canvas])
|
}, [selectedPlan, canvas])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
import { useContext, useEffect } from 'react'
|
import { useContext, useEffect } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
export default function CanvasLayout({ children }) {
|
export default function CanvasLayout({ children }) {
|
||||||
// const { menuNumber } = props
|
// const { menuNumber } = props
|
||||||
@ -20,7 +20,7 @@ export default function CanvasLayout({ children }) {
|
|||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { plans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
|
const { plans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadCanvasPlanData(session.userId, objectNo, pid)
|
loadCanvasPlanData(session.userId, objectNo, pid)
|
||||||
@ -36,27 +36,31 @@ export default function CanvasLayout({ children }) {
|
|||||||
className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`}
|
className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`}
|
||||||
onClick={() => handleCurrentPlan(plan.id)}
|
onClick={() => handleCurrentPlan(plan.id)}
|
||||||
>
|
>
|
||||||
<span>
|
<span>{`Plan ${plan.ordering}`}</span>
|
||||||
{`Plan ${plan.ordering}`}
|
{plan.ordering !== 1 && (
|
||||||
{modifiedPlans.some((modifiedPlan) => modifiedPlan === plan.id) && ' [ M ]'}
|
<i
|
||||||
</span>
|
className="close"
|
||||||
<i
|
onClick={(e) =>
|
||||||
className="close"
|
swalFire({
|
||||||
onClick={(e) =>
|
text: `Plan ${plan.ordering} ` + getMessage('plan.message.confirm.delete'),
|
||||||
swalFire({
|
type: 'confirm',
|
||||||
text: `Plan ${plan.ordering} ` + getMessage('plan.message.confirm.delete'),
|
confirmFn: () => {
|
||||||
type: 'confirm',
|
handleDeletePlan(e, plan.id)
|
||||||
confirmFn: () => {
|
},
|
||||||
handleDeletePlan(e, plan.id)
|
})
|
||||||
},
|
}
|
||||||
})
|
></i>
|
||||||
}
|
)}
|
||||||
></i>
|
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
{plans.length < 10 && (
|
{plans.length < 10 && (
|
||||||
<button className="plane-add" onClick={() => handleAddPlan(session.userId, objectNo)}>
|
<button
|
||||||
|
className="plane-add"
|
||||||
|
onClick={async () => {
|
||||||
|
await handleAddPlan(session.userId, objectNo)
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span></span>
|
<span></span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -2,47 +2,47 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import { usePathname, useRouter } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
import { usePathname, useRouter } from 'next/navigation'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import MenuDepth01 from './MenuDepth01'
|
import MenuDepth01 from './MenuDepth01'
|
||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
||||||
|
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import EstimateCopyPop from '../estimate/popup/EstimateCopyPop'
|
||||||
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||||
|
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
||||||
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||||
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom'
|
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom'
|
||||||
import { sessionStore } from '@/store/commonAtom'
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
|
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||||
|
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||||
|
import { menusState, menuTypeState } from '@/store/menuAtom'
|
||||||
|
import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
|
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
||||||
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
|
|
||||||
import KO from '@/locales/ko.json'
|
import KO from '@/locales/ko.json'
|
||||||
import JA from '@/locales/ja.json'
|
import JA from '@/locales/ja.json'
|
||||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
|
||||||
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
|
||||||
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
|
||||||
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
|
||||||
|
|
||||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
|
||||||
import { menusState, menuTypeState } from '@/store/menuAtom'
|
|
||||||
import useMenu from '@/hooks/common/useMenu'
|
|
||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
|
|
||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
|
||||||
import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
|
||||||
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
|
||||||
import EstimateCopyPop from '../estimate/popup/EstimateCopyPop'
|
|
||||||
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
|
||||||
|
|
||||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const { menuNumber, setMenuNumber } = props
|
const { menuNumber, setMenuNumber } = props
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
@ -51,8 +51,8 @@ export default function CanvasMenu(props) {
|
|||||||
const canvasMenus = useRecoilValue(menusState)
|
const canvasMenus = useRecoilValue(menusState)
|
||||||
const [type, setType] = useRecoilState(menuTypeState)
|
const [type, setType] = useRecoilState(menuTypeState)
|
||||||
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
|
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
|
||||||
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
const setAppMessageState = useSetRecoilState(appMessageStore)
|
||||||
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
||||||
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
|
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
|
||||||
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
|
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
|
||||||
const canvasSetting = useRecoilValue(canvasSettingState)
|
const canvasSetting = useRecoilValue(canvasSettingState)
|
||||||
@ -75,10 +75,14 @@ export default function CanvasMenu(props) {
|
|||||||
// const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useContext(EventContext)
|
// const { initEvent, addCanvasMouseEventListener, addDocumentEventListener } = useContext(EventContext)
|
||||||
const commonUtils = useRecoilValue(commonUtilsState)
|
const commonUtils = useRecoilValue(commonUtilsState)
|
||||||
const { commonFunctions } = useCommonUtils()
|
const { commonFunctions } = useCommonUtils()
|
||||||
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
|
|
||||||
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||||
const { restoreModuleInstArea } = useModuleBasicSetting()
|
const { restoreModuleInstArea } = useModuleBasicSetting()
|
||||||
|
|
||||||
|
const [addedRoofs, setAddedRoofsState] = useRecoilState(addedRoofsState)
|
||||||
|
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
|
||||||
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
|
|
||||||
//견적서버튼 노출용
|
//견적서버튼 노출용
|
||||||
const [buttonStyle, setButtonStyle] = useState('')
|
const [buttonStyle, setButtonStyle] = useState('')
|
||||||
|
|
||||||
@ -112,6 +116,20 @@ export default function CanvasMenu(props) {
|
|||||||
if (pathname !== '/floor-plan') router.push('/floor-plan')
|
if (pathname !== '/floor-plan') router.push('/floor-plan')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeSelectedRoofMaterial = (e) => {
|
||||||
|
setBasicSetting({ ...basicSetting, selectedRoofMaterial: e })
|
||||||
|
|
||||||
|
const newAddedRoofs = addedRoofs.map((roof) => {
|
||||||
|
if (roof.index === e.index) {
|
||||||
|
return { ...roof, selected: true }
|
||||||
|
} else {
|
||||||
|
return { ...roof, selected: false }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setAddedRoofsState(newAddedRoofs)
|
||||||
|
}
|
||||||
|
|
||||||
const settingsModalOptions = useRecoilState(settingModalFirstOptionsState)
|
const settingsModalOptions = useRecoilState(settingModalFirstOptionsState)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -194,7 +212,7 @@ export default function CanvasMenu(props) {
|
|||||||
}, [canvasSetting])
|
}, [canvasSetting])
|
||||||
|
|
||||||
const checkMenuState = (menu) => {
|
const checkMenuState = (menu) => {
|
||||||
return ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2)
|
return (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) || (menuNumber === 4 && menu.index === 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 발전시물레이션 Excel/PDF 다운
|
// 발전시물레이션 Excel/PDF 다운
|
||||||
@ -265,7 +283,7 @@ export default function CanvasMenu(props) {
|
|||||||
key={`canvas-menu-${menu.index}`}
|
key={`canvas-menu-${menu.index}`}
|
||||||
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
className={`canvas-menu-item ${menuNumber === menu.index ? 'active' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if ([2, 3].some((num) => num === canvasSetting?.roofSizeSet) && menu.index === 2) return
|
if (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.index === 2) return
|
||||||
if (menuNumber === 4 && menu.index === 2) return
|
if (menuNumber === 4 && menu.index === 2) return
|
||||||
onClickNav(menu)
|
onClickNav(menu)
|
||||||
}}
|
}}
|
||||||
@ -292,9 +310,20 @@ export default function CanvasMenu(props) {
|
|||||||
<button className={`btn02 ${commonUtils.dimension ? 'active' : ''} `} onClick={() => commonFunctions('dimension')}></button>
|
<button className={`btn02 ${commonUtils.dimension ? 'active' : ''} `} onClick={() => commonFunctions('dimension')}></button>
|
||||||
<button className={`btn03 ${commonUtils.distance ? 'active' : ''} `} onClick={() => commonFunctions('distance')}></button>
|
<button className={`btn03 ${commonUtils.distance ? 'active' : ''} `} onClick={() => commonFunctions('distance')}></button>
|
||||||
</div>
|
</div>
|
||||||
<div className="select-box">
|
{isObjectNotEmpty(selectedRoofMaterial) && addedRoofs.length > 0 && (
|
||||||
<QSelectBox title={'瓦53A'} option={SelectOption} />
|
<div className="select-box">
|
||||||
</div>
|
{
|
||||||
|
<QSelectBox
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
options={addedRoofs}
|
||||||
|
value={selectedRoofMaterial}
|
||||||
|
onChange={changeSelectedRoofMaterial}
|
||||||
|
sourceKey={'index'}
|
||||||
|
targetKey={'index'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="btn-from">
|
<div className="btn-from">
|
||||||
<button
|
<button
|
||||||
className={`btn10 ${floorPlanState.refFileModalOpen && 'active'}`}
|
className={`btn10 ${floorPlanState.refFileModalOpen && 'active'}`}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext, useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
//import { useRecoilState } from 'recoil'
|
//import { useRecoilState } from 'recoil'
|
||||||
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { canvasState, currentMenuState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState } from '@/store/canvasAtom'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
||||||
import useMenu from '@/hooks/common/useMenu'
|
|
||||||
import { useEffect } from 'react'
|
|
||||||
|
|
||||||
export default function MenuDepth01() {
|
export default function MenuDepth01() {
|
||||||
const type = useRecoilValue(menuTypeState)
|
const type = useRecoilValue(menuTypeState)
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
import { useRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
|
||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
import { modalState } from '@/store/modalAtom'
|
|
||||||
import { ToggleonMouse } from '@/components/header/Header'
|
import { ToggleonMouse } from '@/components/header/Header'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { currentMenuState } from '@/store/canvasAtom'
|
||||||
|
import { modalState } from '@/store/modalAtom'
|
||||||
|
|
||||||
export default function RoofCoveringMenu() {
|
export default function RoofCoveringMenu() {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { forwardRef, useImperativeHandle, useState } from 'react'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useOrientation } from '@/hooks/module/useOrientation'
|
import { useOrientation } from '@/hooks/module/useOrientation'
|
||||||
import { getDegreeInOrientation } from '@/util/canvas-util'
|
import { getDegreeInOrientation } from '@/util/canvas-util'
|
||||||
|
import { numberCheck } from '@/util/common-utils'
|
||||||
|
|
||||||
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
export const Orientation = forwardRef(({ tabNum }, ref) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -18,6 +19,14 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
|
|||||||
nextStep()
|
nextStep()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkDegree = (e) => {
|
||||||
|
if (numberCheck(Number(e)) && Number(e) >= -180 && Number(e) <= 180) {
|
||||||
|
setCompasDeg(Number(e))
|
||||||
|
} else {
|
||||||
|
setCompasDeg(compasDeg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="properties-setting-wrap">
|
<div className="properties-setting-wrap">
|
||||||
@ -65,10 +74,15 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={compasDeg}
|
value={compasDeg}
|
||||||
readOnly={hasAnglePassivity}
|
readOnly={hasAnglePassivity}
|
||||||
onChange={(e) =>
|
placeholder={0}
|
||||||
setCompasDeg(
|
onChange={
|
||||||
e.target.value !== '' && parseInt(e.target.value) <= 360 && parseInt(e.target.value) >= 0 ? Number.parseInt(e.target.value) : 0,
|
(e) => checkDegree(e.target.value)
|
||||||
)
|
// setCompasDeg(
|
||||||
|
|
||||||
|
// e.target.value === '-' || (e.target.value !== '' && parseInt(e.target.value) <= 180 && parseInt(e.target.value) >= -180)
|
||||||
|
// ? e.target.value
|
||||||
|
// : 0,
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -57,8 +57,6 @@ const PitchPlacement = forwardRef((props, refs) => {
|
|||||||
} else {
|
} else {
|
||||||
const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
|
const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
|
||||||
moduleSetupSurfaces.forEach((surface, index) => {
|
moduleSetupSurfaces.forEach((surface, index) => {
|
||||||
console.log(`surface ${index} : `, surface)
|
|
||||||
|
|
||||||
const excretaLine = surface.lines
|
const excretaLine = surface.lines
|
||||||
|
|
||||||
excretaLine.forEach((line) => {
|
excretaLine.forEach((line) => {
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="number" className="input-origin block" defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8} ref={pitchRef} />
|
<input type="text" className="input-origin block" defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8} ref={pitchRef} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +29,7 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
|||||||
{getMessage('offset')}
|
{getMessage('offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="number" className="input-origin block" defaultValue={500} ref={offsetRef} />
|
<input type="text" className="input-origin block" defaultValue={500} ref={offsetRef} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,18 +3,71 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
import { polygonToTurfPolygon } from '@/util/canvas-util'
|
||||||
|
import { deepCopyArray } from '@/util/common-utils'
|
||||||
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import * as turf from '@turf/turf'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { useModal } from '@nextui-org/react'
|
||||||
|
import { useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
|
export const PANEL_EDIT_TYPE = {
|
||||||
|
MOVE: 'move',
|
||||||
|
MOVE_ALL: 'moveAll',
|
||||||
|
COPY: 'copy',
|
||||||
|
COPY_ALL: 'copyAll',
|
||||||
|
COLUMN_MOVE: 'columnMove',
|
||||||
|
COLUMN_COPY: 'columnCopy',
|
||||||
|
ROW_MOVE: 'rowMove',
|
||||||
|
ROW_COPY: 'rowCopy',
|
||||||
|
}
|
||||||
|
|
||||||
export default function PanelEdit(props) {
|
export default function PanelEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, type = 'move', apply } = props
|
const { id, pos = contextPopupPosition, type = PANEL_EDIT_TYPE.MOVE, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [length, setLength] = useState(0)
|
const [length, setLength] = useState(0)
|
||||||
const [direction, setDirection] = useState('')
|
const [direction, setDirection] = useState('up')
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { moduleMove, moduleCopy, moduleMultiMove, moduleMultiCopy, moduleMoveAll, moduleCopyAll } = useModule()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (canvas) {
|
||||||
|
const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module') // selectedObj에 없는 객체만 필터링
|
||||||
|
isSetupModules.forEach((obj) => obj.set({ lockMovementX: false, lockMovementY: false }))
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//모듈 이동 적용
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
apply()
|
switch (type) {
|
||||||
|
case PANEL_EDIT_TYPE.MOVE:
|
||||||
|
moduleMove(length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.MOVE_ALL:
|
||||||
|
moduleMoveAll(length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.COPY:
|
||||||
|
moduleCopy(length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.COPY_ALL:
|
||||||
|
moduleCopyAll(length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.COLUMN_MOVE:
|
||||||
|
moduleMultiMove('column', length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.COLUMN_COPY:
|
||||||
|
moduleMultiCopy('column', length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.ROW_MOVE:
|
||||||
|
moduleMultiMove('row', length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.ROW_COPY:
|
||||||
|
moduleMultiCopy('row', length, direction)
|
||||||
|
break
|
||||||
|
}
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,45 +75,49 @@ export default function PanelEdit(props) {
|
|||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap xm mount`}>
|
<div className={`modal-pop-wrap xm mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage(type === 'move' ? 'modal.move.setting' : 'modal.copy.setting')} </h1>
|
<h1 className="title">
|
||||||
|
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting' : 'modal.copy.setting')}{' '}
|
||||||
|
</h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
닫기
|
닫기
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<div className="grid-option-tit">{getMessage(type === 'move' ? 'modal.move.setting.info' : 'modal.copy.setting.info')}</div>
|
<div className="grid-option-tit">
|
||||||
|
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting.info' : 'modal.copy.setting.info')}
|
||||||
|
</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-wrap">
|
||||||
<div className="grid-option-box">
|
<div className="grid-option-box">
|
||||||
<div className="grid-input-form">
|
<div className="grid-input-form">
|
||||||
<span className="mr10">{getMessage('margin')}</span>
|
<span className="mr10">{getMessage('margin')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin" defaultValue={0} onClick={(e) => setLength(e.target.value)} />
|
<input type="text" className="input-origin" defaultValue={0} onKeyUp={(e) => setLength(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-direction">
|
<div className="grid-direction">
|
||||||
<button
|
<button
|
||||||
className={`direction up ${direction === '↑' ? 'act' : ''}`}
|
className={`direction up ${direction === 'up' ? 'act' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDirection('↑')
|
setDirection('up')
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction down ${direction === '↓' ? 'act' : ''}`}
|
className={`direction down ${direction === 'down' ? 'act' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDirection('↓')
|
setDirection('down')
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction left ${direction === '←' ? 'act' : ''}`}
|
className={`direction left ${direction === 'left' ? 'act' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDirection('←')
|
setDirection('left')
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
<button
|
<button
|
||||||
className={`direction right ${direction === '→' ? 'act' : ''}`}
|
className={`direction right ${direction === 'right' ? 'act' : ''}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDirection('→')
|
setDirection('right')
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,20 +5,22 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
import { MODULE_INSERT_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function ColumnInsert(props) {
|
export default function ColumnInsert(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_INSERT_TYPE.LEFT)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleColumnInsert } = useModule()
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
moduleColumnInsert(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const HandleRadioChange = (e) => {
|
const handleRadioChange = (e) => {
|
||||||
setSelectedType(Number(e.target.value))
|
setSelectedType(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -36,16 +38,30 @@ export default function ColumnInsert(props) {
|
|||||||
<div className="additional-wrap">
|
<div className="additional-wrap">
|
||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra01" onChange={HandleRadioChange} value={1} checked={selectedType === 1} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra01"
|
||||||
|
onChange={handleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.LEFT}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.LEFT}
|
||||||
|
/>
|
||||||
<label htmlFor="ra01">{getMessage('modal.panel.column.insert.type.left')}</label>
|
<label htmlFor="ra01">{getMessage('modal.panel.column.insert.type.left')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra02" onChange={HandleRadioChange} value={2} checked={selectedType === 2} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra02"
|
||||||
|
onChange={handleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.RIGHT}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.RIGHT}
|
||||||
|
/>
|
||||||
<label htmlFor="ra02">{getMessage('modal.panel.column.insert.type.right')}</label>
|
<label htmlFor="ra02">{getMessage('modal.panel.column.insert.type.right')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_INSERT_TYPE.LEFT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional-edit01.svg"
|
src="/static/images/canvas/additional-edit01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -54,7 +70,7 @@ export default function ColumnInsert(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_INSERT_TYPE.RIGHT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional-edit02.svg"
|
src="/static/images/canvas/additional-edit02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,21 +5,24 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
import { MODULE_REMOVE_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function ColumnRemove(props) {
|
export default function ColumnRemove(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_REMOVE_TYPE.LEFT)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleColumnRemove } = useModule()
|
||||||
const types = [
|
const types = [
|
||||||
{ name: getMessage('modal.panel.column.remove.type.left'), value: 1 },
|
{ name: getMessage('modal.panel.column.remove.type.left'), value: MODULE_REMOVE_TYPE.LEFT },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.right'), value: 2 },
|
{ name: getMessage('modal.panel.column.remove.type.right'), value: MODULE_REMOVE_TYPE.RIGHT },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.side'), value: 3 },
|
{ name: getMessage('modal.panel.column.remove.type.side'), value: MODULE_REMOVE_TYPE.HORIZONTAL_SIDE },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.none'), value: 4 },
|
{ name: getMessage('modal.panel.column.remove.type.none'), value: MODULE_REMOVE_TYPE.NONE },
|
||||||
]
|
]
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
// if (apply) apply()
|
||||||
|
moduleColumnRemove(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +42,12 @@ export default function ColumnRemove(props) {
|
|||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
{types.map((type, index) => {
|
{types.map((type, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop" key={index}>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="radio01"
|
name="radio01"
|
||||||
id={`ra0${index + 1}`}
|
id={`ra0${index + 1}`}
|
||||||
onClick={(e) => setSelectedType(Number(e.target.value))}
|
onClick={(e) => setSelectedType(e.target.value)}
|
||||||
value={type.value}
|
value={type.value}
|
||||||
checked={selectedType === type.value}
|
checked={selectedType === type.value}
|
||||||
/>
|
/>
|
||||||
@ -54,7 +57,7 @@ export default function ColumnRemove(props) {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_REMOVE_TYPE.LEFT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del01.svg"
|
src="/static/images/canvas/additional_del01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -63,7 +66,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_REMOVE_TYPE.RIGHT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del02.svg"
|
src="/static/images/canvas/additional_del02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -72,7 +75,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 3 && (
|
{selectedType === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del03.svg"
|
src="/static/images/canvas/additional_del03.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -81,7 +84,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 4 && (
|
{selectedType === MODULE_REMOVE_TYPE.NONE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del04.svg"
|
src="/static/images/canvas/additional_del04.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,20 +5,22 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { MODULE_INSERT_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function RowInsert(props) {
|
export default function RowInsert(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_INSERT_TYPE.TOP)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { muduleRowInsert } = useModule()
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
muduleRowInsert(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const HandleRadioChange = (e) => {
|
const HandleRadioChange = (e) => {
|
||||||
setSelectedType(Number(e.target.value))
|
setSelectedType(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -36,16 +38,30 @@ export default function RowInsert(props) {
|
|||||||
<div className="additional-wrap">
|
<div className="additional-wrap">
|
||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra01" onChange={HandleRadioChange} value={1} checked={selectedType === 1} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra01"
|
||||||
|
onChange={HandleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.TOP}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.TOP}
|
||||||
|
/>
|
||||||
<label htmlFor="ra01">{getMessage('modal.row.insert.type.up')}</label>
|
<label htmlFor="ra01">{getMessage('modal.row.insert.type.up')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra02" onChange={HandleRadioChange} value={2} checked={selectedType === 2} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra02"
|
||||||
|
onChange={HandleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.BOTTOM}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.BOTTOM}
|
||||||
|
/>
|
||||||
<label htmlFor="ra02">{getMessage('modal.row.insert.type.down')}</label>
|
<label htmlFor="ra02">{getMessage('modal.row.insert.type.down')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_INSERT_TYPE.TOP && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-edit01.svg"
|
src="/static/images/canvas/additional_bundle-edit01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -54,7 +70,7 @@ export default function RowInsert(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_INSERT_TYPE.BOTTOM && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-edit02.svg"
|
src="/static/images/canvas/additional_bundle-edit02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,21 +5,24 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { MODULE_REMOVE_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function RowRemove(props) {
|
export default function RowRemove(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_REMOVE_TYPE.TOP)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleRowRemove } = useModule()
|
||||||
const types = [
|
const types = [
|
||||||
{ name: getMessage('modal.row.remove.type.up'), value: 1 },
|
{ name: getMessage('modal.row.remove.type.up'), value: MODULE_REMOVE_TYPE.TOP },
|
||||||
{ name: getMessage('modal.row.remove.type.down'), value: 2 },
|
{ name: getMessage('modal.row.remove.type.down'), value: MODULE_REMOVE_TYPE.BOTTOM },
|
||||||
{ name: getMessage('modal.row.remove.type.side'), value: 3 },
|
{ name: getMessage('modal.row.remove.type.side'), value: MODULE_REMOVE_TYPE.VERTICAL_SIDE },
|
||||||
{ name: getMessage('modal.row.remove.type.none'), value: 4 },
|
{ name: getMessage('modal.row.remove.type.none'), value: MODULE_REMOVE_TYPE.NONE },
|
||||||
]
|
]
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
// if (apply) apply()
|
||||||
|
moduleRowRemove(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,22 +42,22 @@ export default function RowRemove(props) {
|
|||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
{types.map((type, index) => {
|
{types.map((type, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop" key={index}>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="radio01"
|
name="radio01"
|
||||||
id={`ra0${index + 1}`}
|
id={`ra0${index + 1}`}
|
||||||
onClick={() => setSelectedType(Number(e.target.value))}
|
onClick={(e) => setSelectedType(e.target.value)}
|
||||||
value={type.value}
|
value={type.value}
|
||||||
checked={selectedType === type.value}
|
checked={selectedType === type.value}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="ra01">{getMessage(type.name)}</label>
|
<label htmlFor={`ra0${index + 1}`}>{type.name}</label>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_REMOVE_TYPE.TOP && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del01.svg"
|
src="/static/images/canvas/additional_bundle-del01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -63,7 +66,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_REMOVE_TYPE.BOTTOM && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del02.svg"
|
src="/static/images/canvas/additional_bundle-del02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -72,7 +75,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 3 && (
|
{selectedType === MODULE_REMOVE_TYPE.VERTICAL_SIDE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del03.svg"
|
src="/static/images/canvas/additional_bundle-del03.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -81,7 +84,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 4 && (
|
{selectedType === MODULE_REMOVE_TYPE.NONE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del04.svg"
|
src="/static/images/canvas/additional_bundle-del04.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
@ -8,10 +8,18 @@ import MaterialGuide from '@/components/floor-plan/modal/placementShape/Material
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
|
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { roofMaterialsAtom } from '@/store/settingAtom'
|
import { roofMaterialsAtom } from '@/store/settingAtom'
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
|
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
|
export const ROOF_MATERIAL_LAYOUT = {
|
||||||
|
PARALLEL: 'P',
|
||||||
|
STAIRS: 'S',
|
||||||
|
}
|
||||||
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
||||||
const [showSizeGuideModal, setShowSizeGuidModal] = useState(false)
|
const [showSizeGuideModal, setShowSizeGuidModal] = useState(false)
|
||||||
const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false)
|
const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false)
|
||||||
@ -19,31 +27,113 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
|||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const roofMaterials = useRecoilValue(roofMaterialsAtom)
|
const roofMaterials = useRecoilValue(roofMaterialsAtom)
|
||||||
|
|
||||||
const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting()
|
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||||
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(
|
const { basicSetting, setBasicSettings, basicSettingSave, addedRoofs, setAddedRoofs } = useCanvasSetting()
|
||||||
isObjectNotEmpty(basicSetting.selectedRoofMaterial) ? basicSetting.selectedRoofMaterial : roofMaterials[0],
|
const { findCommonCode } = useCommonCode()
|
||||||
)
|
const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보
|
||||||
|
const [currentRoof, setCurrentRoof] = useState(addedRoofs[0]) // 현재 선택된 지붕재 정보
|
||||||
|
|
||||||
|
const roofRef = {
|
||||||
|
roofCd: useRef(null),
|
||||||
|
width: useRef(null),
|
||||||
|
length: useRef(null),
|
||||||
|
rafter: useRef(null),
|
||||||
|
hajebichi: useRef(null),
|
||||||
|
}
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchBasicSettings()
|
const raftCodeList = findCommonCode('203800')
|
||||||
|
setRaftCodes(raftCodeList)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(currentRoofMaterial)
|
setBasicSettings({
|
||||||
}, [roofMaterials])
|
...basicSetting,
|
||||||
|
roofsData: {
|
||||||
|
roofApply: true,
|
||||||
|
roofSeq: 0,
|
||||||
|
roofMatlCd: currentRoof.roofMatlCd,
|
||||||
|
roofWidth: currentRoof.width,
|
||||||
|
roofHeight: currentRoof.length,
|
||||||
|
roofHajebichi: currentRoof.hajebichi,
|
||||||
|
roofGap: currentRoof.raft,
|
||||||
|
roofLayout: currentRoof.layout,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [basicSetting.roofSizeSet, basicSetting.roofAngleSet, currentRoof])
|
||||||
|
|
||||||
// Function to update the roofType and corresponding values
|
// Function to update the roofType and corresponding values
|
||||||
const handleRoofTypeChange = (value) => {
|
const handleRoofTypeChange = (value) => {
|
||||||
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value)
|
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value)
|
||||||
setCurrentRoofMaterial(selectedRoofMaterial)
|
setCurrentRoof({...selectedRoofMaterial, index: 0})
|
||||||
/*const newBasicSetting = { ...basicSetting }
|
}
|
||||||
setBasicSettings({ ...newBasicSetting, selectedRoofMaterial: selectedRoofMaterial })*/
|
|
||||||
|
const changeInput = (value, e) => {
|
||||||
|
const { name } = e.target
|
||||||
|
setCurrentRoof({...currentRoof, [name]: Number(value)})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRafterChange = (value) => {
|
||||||
|
setCurrentRoof({...currentRoof, raft: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRoofLayoutChange = (value) => {
|
||||||
|
setCurrentRoof({...currentRoof, layout: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSaveBtn = () => {
|
||||||
|
const roofInfo = {
|
||||||
|
...currentRoof,
|
||||||
|
roofCd: roofRef.roofCd.current?.value,
|
||||||
|
width: roofRef.width.current?.value,
|
||||||
|
length: roofRef.length.current?.value,
|
||||||
|
hajebichi: roofRef.hajebichi.current?.value,
|
||||||
|
raft: roofRef.rafter.current?.value,
|
||||||
|
selected: true,
|
||||||
|
layout: currentRoof.layout,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
const newAddedRoofs = [...addedRoofs]
|
||||||
|
if (addedRoofs.length === 1) {
|
||||||
|
newAddedRoofs[0] = { ...roofInfo }
|
||||||
|
setAddedRoofs(newAddedRoofs)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('save Info', {
|
||||||
|
...basicSetting,
|
||||||
|
selectedRoofMaterial: {
|
||||||
|
// 선택된 지붕재 정보
|
||||||
|
roofInfo,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setBasicSettings({
|
||||||
|
...basicSetting,
|
||||||
|
selectedRoofMaterial: {
|
||||||
|
// 선택된 지붕재 정보
|
||||||
|
...roofInfo,
|
||||||
|
},
|
||||||
|
//roofs: addedRoofs,
|
||||||
|
roofsData: {
|
||||||
|
roofApply: true,
|
||||||
|
roofSeq: 0,
|
||||||
|
roofMatlCd: currentRoof.roofMatlCd,
|
||||||
|
roofWidth: currentRoof.width,
|
||||||
|
roofHeight: currentRoof.length,
|
||||||
|
roofHajebichi: currentRoof.hajebichi,
|
||||||
|
roofGap: currentRoof.raft,
|
||||||
|
roofLayout: currentRoof.layout,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
basicSettingSave()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap l mount`}>
|
<div className={`modal-pop-wrap ll mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage('plan.menu.placement.surface.initial.setting')}</h1>
|
<h1 className="title">{getMessage('plan.menu.placement.surface.initial.setting')}</h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
@ -145,12 +235,28 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
|||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<div className="placement-option">
|
<div className="placement-option">
|
||||||
<div className="select-wrap" style={{ width: '171px' }}>
|
<div className="grid-select no-flx" style={{ width: '171px' }}>
|
||||||
<select
|
<QSelectBox
|
||||||
|
title={basicSetting.roofSizeSet == 3 ? getMessage('modal.placement.initial.setting.size.none.pitch') : currentRoof.roofMatlNm}
|
||||||
|
ref={roofRef.roofCd}
|
||||||
|
options={roofMaterials.map((roof, index) => {
|
||||||
|
return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp }
|
||||||
|
})}
|
||||||
|
value={basicSetting.roofSizeSet == 3 ? null : currentRoof.roofMatlCd}
|
||||||
|
onChange={(e) => handleRoofTypeChange(e.roofMatlCd)}
|
||||||
|
sourceKey="id"
|
||||||
|
targetKey="id"
|
||||||
|
showKey="name"
|
||||||
|
disabled={basicSetting.roofSizeSet == 3}
|
||||||
|
/>
|
||||||
|
{/* <select
|
||||||
className="select-light dark"
|
className="select-light dark"
|
||||||
name="roofType"
|
name="roofMatlCd"
|
||||||
|
ref={roofRef.roofCd}
|
||||||
value={currentRoofMaterial.roofMatlCd}
|
value={currentRoofMaterial.roofMatlCd}
|
||||||
onChange={(e) => handleRoofTypeChange(e.target.value)}
|
onChange={(e) => {
|
||||||
|
handleRoofTypeChange(e.target.value)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{roofMaterials.map((roof, index) => {
|
{roofMaterials.map((roof, index) => {
|
||||||
return (
|
return (
|
||||||
@ -159,86 +265,131 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
|||||||
</option>
|
</option>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</select>
|
</select> */}
|
||||||
</div>
|
</div>
|
||||||
{['R', 'C'].includes(currentRoofMaterial.widAuth) && (
|
{basicSetting && ['R', 'C'].includes(currentRoof.widAuth) && (
|
||||||
<>
|
<div className="flex-ment">
|
||||||
<div className="flex-ment">
|
<span>W</span>
|
||||||
<span>W</span>
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
<input
|
||||||
<select
|
type="text"
|
||||||
className="select-light dark"
|
className="input-origin block"
|
||||||
name="roofWidth"
|
name={`width`}
|
||||||
onChange={(e) => {
|
ref={roofRef.width}
|
||||||
// 상태 업데이트 함수 호출
|
value={parseInt(currentRoof.width)}
|
||||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofWidth: e.target.value })
|
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||||
}}
|
readOnly={currentRoof.widAuth === 'R'}
|
||||||
>
|
disabled={basicSetting.roofSizeSet == 3}
|
||||||
<option value={parseInt(currentRoofMaterial.widBase)}>{parseInt(currentRoofMaterial.widBase)}</option>
|
/>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
{/* <div className="input-grid" style={{ width: '63px' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
ref={roofRef.width}
|
||||||
|
defaultValue={parseInt(currentRoofMaterial.width)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
{['R', 'C'].includes(currentRoofMaterial.lenAuth) && (
|
{basicSetting && ['R', 'C'].includes(currentRoof.lenAuth) && (
|
||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>L</span>
|
<span>L</span>
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
<select
|
<input
|
||||||
className="select-light dark"
|
type="text"
|
||||||
name="roofHeight"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
name={`length`}
|
||||||
// 상태 업데이트 함수 호출
|
ref={roofRef.length}
|
||||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofHeight: e.target.value })
|
value={parseInt(currentRoof.length)}
|
||||||
}}
|
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||||
>
|
readOnly={currentRoof.lenAuth === 'R'}
|
||||||
<option value={parseInt(currentRoofMaterial.lenBase)}>{parseInt(currentRoofMaterial.lenBase)}</option>
|
disabled={basicSetting.roofSizeSet == 3}
|
||||||
</select>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div className="input-grid" style={{ width: '63px' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
ref={roofRef.length}
|
||||||
|
defaultValue={parseInt(currentRoofMaterial.length)}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{['C', 'R'].includes(currentRoofMaterial.raftAuth) && (
|
{basicSetting && ['C', 'R'].includes(currentRoof.raftAuth) && (
|
||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
{raftCodes.length > 0 && (
|
||||||
<select
|
<div className="select-wrap" style={{ width: '160px' }}>
|
||||||
className="select-light dark"
|
<QSelectBox
|
||||||
name="roofGap"
|
options={raftCodes}
|
||||||
onChange={(e) => {
|
ref={roofRef.rafter}
|
||||||
// 상태 업데이트 함수 호출
|
title={raftCodes.find((r) => r.clCode === (currentRoof.raft === undefined ? currentRoof.raftBaseCd : currentRoof.raft)).clCodeNm}
|
||||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofGap: e.target.value })
|
value={currentRoof.raft === undefined ? currentRoof.raftBaseCd : currentRoof.raft}
|
||||||
}}
|
onChange={(e) => handleRafterChange(e.clCode)}
|
||||||
>
|
sourceKey="clCode"
|
||||||
<option>455</option>
|
targetKey={currentRoof.raft ? 'raft' : 'raftBaseCd'}
|
||||||
</select>
|
showKey="clCodeNm"
|
||||||
|
disabled={basicSetting.roofSizeSet == 3}
|
||||||
|
/>
|
||||||
|
{/* <select className="select-light dark" name="roofGap" ref={roofRef.rafter}>
|
||||||
|
{raftCodes.map((raft, index) => {
|
||||||
|
return (
|
||||||
|
<option key={index} value={raft.clCode} selected={currentRoofMaterial.raft === raft.clCode}>
|
||||||
|
{raft.clCodeNm}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</select> */}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{['C', 'R'].includes(currentRoofMaterial.roofPchAuth) && (
|
{basicSetting && ['C', 'R'].includes(currentRoof.roofPchAuth) && (
|
||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>{getMessage('hajebichi')}</span>
|
<span>{getMessage('hajebichi')}</span>
|
||||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
<select
|
<input
|
||||||
className="select-light dark"
|
type="text"
|
||||||
name="roofHajebichi"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
name={`hajebichi`}
|
||||||
// 상태 업데이트 함수 호출
|
ref={roofRef.hajebichi}
|
||||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofHajebichi: e.target.value })
|
value={parseInt(currentRoof.hajebichi)}
|
||||||
}}
|
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||||
>
|
readOnly={currentRoof.roofPchAuth === 'R'}
|
||||||
<option value={parseInt(currentRoofMaterial.roofPchBase)}>{parseInt(currentRoofMaterial.roofPchBase)}</option>
|
disabled={basicSetting.roofSizeSet == 3}
|
||||||
</select>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="placement-roof-btn-wrap">
|
||||||
|
<div className="icon-btn-wrap mt10">
|
||||||
|
<button
|
||||||
|
className={`${currentRoof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL && 'act'}`}
|
||||||
|
value={ROOF_MATERIAL_LAYOUT.PARALLEL}
|
||||||
|
onClick={() => handleRoofLayoutChange(ROOF_MATERIAL_LAYOUT.PARALLEL)}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.parallel')}
|
||||||
|
<i className="allocation01"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`${currentRoof.layout === ROOF_MATERIAL_LAYOUT.STAIRS && 'act'}`}
|
||||||
|
value={ROOF_MATERIAL_LAYOUT.STAIRS}
|
||||||
|
onClick={() => handleRoofLayoutChange(ROOF_MATERIAL_LAYOUT.STAIRS)}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal act" onClick={() => basicSettingSave()}>
|
<button className="btn-frame modal act" onClick={handleSaveBtn}>
|
||||||
{getMessage('modal.common.save')}
|
{getMessage('modal.common.save')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -0,0 +1,199 @@
|
|||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
|
import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting'
|
||||||
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { basicSettingState } from '@/store/settingAtom'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
|
|
||||||
|
export default function ContextRoofAllocationSetting(props) {
|
||||||
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
|
const { id, pos = contextPopupPosition } = props
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
const { closePopup } = usePopup()
|
||||||
|
const {
|
||||||
|
handleSave,
|
||||||
|
onAddRoofMaterial,
|
||||||
|
onDeleteRoofMaterial,
|
||||||
|
roofMaterials,
|
||||||
|
setCurrentRoofMaterial,
|
||||||
|
roofList,
|
||||||
|
handleDefaultRoofMaterial,
|
||||||
|
handleChangeRoofMaterial,
|
||||||
|
handleChangeRaft,
|
||||||
|
handleChangeLayout,
|
||||||
|
handleSaveContext,
|
||||||
|
currentRoofList,
|
||||||
|
} = useRoofAllocationSetting(id)
|
||||||
|
|
||||||
|
const { findCommonCode } = useCommonCode()
|
||||||
|
const [raftCodes, setRaftCodes] = useState([])
|
||||||
|
useEffect(() => {
|
||||||
|
const raftCodeList = findCommonCode('203800')
|
||||||
|
setRaftCodes(raftCodeList.map((raft) => ({ ...raft, value: raft.clCode, name: raft.clCodeNm })))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
|
<div className={`modal-pop-wrap lr mount`}>
|
||||||
|
<div className="modal-head">
|
||||||
|
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
||||||
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
|
닫기
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="modal-body">
|
||||||
|
<div className="properties-guide">{getMessage('modal.roof.alloc.info')}</div>
|
||||||
|
<div className="allocation-select-wrap">
|
||||||
|
<span>{getMessage('modal.roof.alloc.select.roof.material')}</span>
|
||||||
|
<div className="grid-select">
|
||||||
|
<QSelectBox
|
||||||
|
options={roofMaterials}
|
||||||
|
value={roofMaterials[0]}
|
||||||
|
onChange={(e) => {
|
||||||
|
// const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
|
||||||
|
setCurrentRoofMaterial(e)
|
||||||
|
}}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="allocation-edit"
|
||||||
|
onClick={() => {
|
||||||
|
onAddRoofMaterial()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="edit-ico"></i>
|
||||||
|
{getMessage('modal.common.add')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="grid-option-wrap">
|
||||||
|
{currentRoofList.map((roof, index) => {
|
||||||
|
return (
|
||||||
|
<div className="grid-option-box" key={index}>
|
||||||
|
<div className="d-check-radio pop no-text">
|
||||||
|
<input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} />
|
||||||
|
<label
|
||||||
|
htmlFor="ra01"
|
||||||
|
onClick={(e) => {
|
||||||
|
handleDefaultRoofMaterial(index)
|
||||||
|
}}
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
<div className="grid-option-block-form">
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<div className="grid-select" style={{ width: '248px' }}>
|
||||||
|
<QSelectBox
|
||||||
|
options={roofMaterials}
|
||||||
|
value={roof}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
|
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
|
||||||
|
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{(roof.widAuth || roof.lenAuth) && (
|
||||||
|
<div className="block-box">
|
||||||
|
{roof.widAuth && (
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>W</span>
|
||||||
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
|
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{roof.lenAuth && (
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>L</span>
|
||||||
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
|
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(roof.raftAuth || roof.roofPchAuth) && (
|
||||||
|
<div className="block-box">
|
||||||
|
{roof.raftAuth && (
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||||
|
{raftCodes.length > 0 && (
|
||||||
|
<div className="grid-select" style={{ width: '160px' }}>
|
||||||
|
<QSelectBox
|
||||||
|
options={raftCodes}
|
||||||
|
value={roof}
|
||||||
|
showKey={'clCodeNm'}
|
||||||
|
sourceKey={'clCode'}
|
||||||
|
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{roof.roofPchAuth && (
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>{getMessage('hajebichi')}</span>
|
||||||
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={parseInt(roof.hajebichi)}
|
||||||
|
readOnly={roof.roofPchAuth === 'R'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="icon-btn-wrap">
|
||||||
|
<button
|
||||||
|
className={roof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL ? 'act' : ''}
|
||||||
|
onClick={() => {
|
||||||
|
handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.parallel')}
|
||||||
|
<i className="allocation01"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={roof.layout === ROOF_MATERIAL_LAYOUT.STAIRS ? 'act' : ''}
|
||||||
|
onClick={() => {
|
||||||
|
handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="grid-btn-wrap">
|
||||||
|
<button className="btn-frame modal act" onClick={handleSaveContext}>
|
||||||
|
{getMessage('modal.roof.alloc.apply')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</WithDraggable>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -5,18 +5,41 @@ import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSet
|
|||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
export default function RoofAllocationSetting(props) {
|
export default function RoofAllocationSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition } = props
|
const { id, pos = contextPopupPosition } = props
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const { handleSave, onAddRoofMaterial, onDeleteRoofMaterial, values, roofMaterials, selectedRoofMaterial, setSelectedRoofMaterial } =
|
const {
|
||||||
useRoofAllocationSetting(id)
|
handleSave,
|
||||||
|
onAddRoofMaterial,
|
||||||
|
onDeleteRoofMaterial,
|
||||||
|
roofMaterials,
|
||||||
|
setCurrentRoofMaterial,
|
||||||
|
roofList,
|
||||||
|
handleDefaultRoofMaterial,
|
||||||
|
handleChangeRoofMaterial,
|
||||||
|
handleChangeRaft,
|
||||||
|
handleChangeLayout,
|
||||||
|
currentRoofList,
|
||||||
|
} = useRoofAllocationSetting(id)
|
||||||
|
const { findCommonCode } = useCommonCode()
|
||||||
|
const [raftCodes, setRaftCodes] = useState([])
|
||||||
|
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||||
|
useEffect(() => {
|
||||||
|
const raftCodeList = findCommonCode('203800')
|
||||||
|
setRaftCodes(raftCodeList.map((raft) => ({ ...raft, name: raft.clCodeNm })))
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap ml mount`}>
|
<div className={`modal-pop-wrap lr mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
@ -28,7 +51,17 @@ export default function RoofAllocationSetting(props) {
|
|||||||
<div className="allocation-select-wrap">
|
<div className="allocation-select-wrap">
|
||||||
<span>{getMessage('modal.roof.alloc.select.roof.material')}</span>
|
<span>{getMessage('modal.roof.alloc.select.roof.material')}</span>
|
||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox options={roofMaterials} value={selectedRoofMaterial} onChange={(e) => setSelectedRoofMaterial(e)} />
|
<QSelectBox
|
||||||
|
options={roofMaterials}
|
||||||
|
value={roofMaterials[0]}
|
||||||
|
onChange={(e) => {
|
||||||
|
// const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
|
||||||
|
setCurrentRoofMaterial(e)
|
||||||
|
}}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="allocation-edit"
|
className="allocation-edit"
|
||||||
@ -40,118 +73,121 @@ export default function RoofAllocationSetting(props) {
|
|||||||
{getMessage('modal.common.add')}
|
{getMessage('modal.common.add')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-overflow">
|
||||||
{values.map((value, index) => (
|
<div className="grid-option-wrap">
|
||||||
<div className="grid-option-box" key={index}>
|
{currentRoofList.map((roof, index) => {
|
||||||
<div className="d-check-radio pop no-text">
|
return (
|
||||||
<input type="radio" name="radio01" />
|
<div className="grid-option-box" key={index}>
|
||||||
<label htmlFor="ra01"></label>
|
<div className="d-check-radio pop no-text">
|
||||||
</div>
|
<input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} />
|
||||||
<div className="grid-option-block-form">
|
<label
|
||||||
<div className="block-box">
|
htmlFor="ra01"
|
||||||
<div className="flex-ment">
|
onClick={(e) => {
|
||||||
<div className="grid-select" style={{ width: '248px' }}>
|
handleDefaultRoofMaterial(index)
|
||||||
<QSelectBox options={roofMaterials} value={value} />
|
}}
|
||||||
|
></label>
|
||||||
|
</div>
|
||||||
|
<div className="grid-option-block-form">
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<div className="grid-select" style={{ width: '248px' }}>
|
||||||
|
<QSelectBox
|
||||||
|
options={roofMaterials}
|
||||||
|
value={roof}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
|
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
|
||||||
|
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{(roof.widAuth || roof.lenAuth) && (
|
||||||
|
<div className="block-box">
|
||||||
|
{roof.widAuth && (
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>W</span>
|
||||||
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
|
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{roof.lenAuth && (
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>L</span>
|
||||||
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
|
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(roof.raftAuth || roof.roofPchAuth) && (
|
||||||
|
<div className="block-box">
|
||||||
|
{roof.raftAuth && (
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||||
|
{raftCodes.length > 0 && (
|
||||||
|
<div className="grid-select" style={{ width: '160px' }}>
|
||||||
|
<QSelectBox
|
||||||
|
options={raftCodes}
|
||||||
|
value={roof}
|
||||||
|
showKey={'clCodeNm'}
|
||||||
|
sourceKey={'clCode'}
|
||||||
|
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||||
|
onChange={(e) => handleChangeRaft(e, index)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{roof.roofPchAuth && (
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="flex-ment">
|
||||||
|
<span>{getMessage('hajebichi')}</span>
|
||||||
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={parseInt(roof.hajebichi)}
|
||||||
|
readOnly={roof.roofPchAuth === 'R'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="block-box">
|
||||||
|
<div className="icon-btn-wrap">
|
||||||
|
<button
|
||||||
|
className={roof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL ? 'act' : ''}
|
||||||
|
onClick={() => {
|
||||||
|
handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.parallel')}
|
||||||
|
<i className="allocation01"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={roof.layout === ROOF_MATERIAL_LAYOUT.STAIRS ? 'act' : ''}
|
||||||
|
onClick={() => {
|
||||||
|
handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{index === 0 && <span className="dec">基本屋根材</span>}
|
|
||||||
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(value.id)}></button>}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="block-box">
|
)
|
||||||
{value.type === 'A' ? (
|
})}
|
||||||
<>
|
</div>
|
||||||
<div className="flex-ment">
|
|
||||||
<span>W</span>
|
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>L</span>
|
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>235</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
|
||||||
<div className="select-wrap" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>455</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : value.type === 'B' ? (
|
|
||||||
<>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>{getMessage('hajebichi')}</span>
|
|
||||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
|
||||||
<div className="grid-select no-flx right" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : value.type === 'C' ? (
|
|
||||||
<>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>{getMessage('hajebichi')}</span>
|
|
||||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : value.type === 'D' ? (
|
|
||||||
<>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>L</span>
|
|
||||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
|
||||||
<div className="grid-select no-flx right" style={{ width: '84px' }}>
|
|
||||||
<select className="select-light dark" name="" id="">
|
|
||||||
<option>265</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="block-box">
|
|
||||||
<div className="icon-btn-wrap">
|
|
||||||
<button className={value.alignType === 'parallel' ? 'act' : ''}>
|
|
||||||
{getMessage('modal.roof.alloc.select.parallel')}
|
|
||||||
<i className="allocation01"></i>
|
|
||||||
</button>
|
|
||||||
<button className={value.alignType === 'stairs' ? 'act' : ''}>
|
|
||||||
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal act" onClick={handleSave}>
|
<button className="btn-frame modal act" onClick={handleSave}>
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export default function FirstOption(props) {
|
export default function FirstOption(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,6 +10,7 @@ export default function FirstOption(props) {
|
|||||||
let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||||
const { initEvent } = useEvent()
|
const { initEvent } = useEvent()
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -60,24 +60,33 @@ export default function Header(props) {
|
|||||||
const qOrderUrl = process.env.NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL
|
const qOrderUrl = process.env.NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL
|
||||||
const qMusubiUrl = process.env.NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL
|
const qMusubiUrl = process.env.NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL
|
||||||
|
|
||||||
const [SelectOptions, setSelectOptions] = useState(
|
const [SelectOptions, setSelectOptions] = useState([])
|
||||||
userSession.groupId === '60000' ? [{ id: 0, name: 'Q.ORDER', link: `${qOrderUrl}` }] : [{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}` }],
|
|
||||||
)
|
|
||||||
|
|
||||||
const getAutoLoginParam = async () => {
|
const getAutoLoginParam = async () => {
|
||||||
await promisePost({ url: '/api/login/v1.0/user/login/autoLoginEncryptData', data: { loginId: userSession.userId } })
|
await promisePost({ url: '/api/login/v1.0/user/login/autoLoginEncryptData', data: { loginId: userSession.userId } })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
setSelectOptions(
|
setSelectOptions(
|
||||||
userSession.groupId === '60000'
|
userSession.storeId === 'T01'
|
||||||
? [{ id: 0, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }]
|
? [
|
||||||
: [{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }],
|
{ id: 0, name: getMessage('site.header.link1') },
|
||||||
)
|
{ id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` },
|
||||||
setSelected(
|
{ id: 2, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` },
|
||||||
userSession.groupId === '60000'
|
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
? { id: 0, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` }
|
]
|
||||||
: { id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` },
|
: userSession.groupId === '60000'
|
||||||
|
? [
|
||||||
|
{ id: 0, name: getMessage('site.header.link1') },
|
||||||
|
{ id: 1, name: 'Q.ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` },
|
||||||
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{ id: 0, name: getMessage('site.header.link1') },
|
||||||
|
{ id: 1, name: 'Q.Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}` },
|
||||||
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
onChangeSelect({ id: 0, name: getMessage('site.header.link1') })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -124,18 +133,31 @@ export default function Header(props) {
|
|||||||
const onChangeSelect = (option) => {
|
const onChangeSelect = (option) => {
|
||||||
setSelected(option)
|
setSelected(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
const navPage = () => {
|
const navPage = () => {
|
||||||
if (selected.link) {
|
if (selected.link) {
|
||||||
location.href = selected.link
|
if (selected.target === '_blank') {
|
||||||
|
window.open(selected.link)
|
||||||
|
} else {
|
||||||
|
location.href = selected.link
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Home 클릭시 물건 리코일 비우기
|
// 물건메뉴 이외 클릭시 물건 리코일 비우기
|
||||||
const moveHome = () => {
|
const removeStuffRecoil = (menu) => {
|
||||||
setStuffSearch({
|
//menu.id 0 HOME
|
||||||
...stuffSearch,
|
//menu.id 3 신규물건등록
|
||||||
code: 'DELETE',
|
//menu.id 4 물건리스트
|
||||||
})
|
//menu.id 5 공지사항
|
||||||
|
//menu.id 6 FAQ
|
||||||
|
//menu.id 7 자료실
|
||||||
|
if (menu.id === 0 || menu.id === 5 || menu.id === 6 || menu.id === 7) {
|
||||||
|
setStuffSearch({
|
||||||
|
...stuffSearch,
|
||||||
|
code: 'DELETE',
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getMenuTemplate = (menus) => {
|
const getMenuTemplate = (menus) => {
|
||||||
@ -152,7 +174,8 @@ export default function Header(props) {
|
|||||||
key={`${menu.id}`}
|
key={`${menu.id}`}
|
||||||
href={menu.url}
|
href={menu.url}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
moveHome()
|
// moveHome()
|
||||||
|
removeStuffRecoil(menu)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{getMessage(menu.name)}
|
{getMessage(menu.name)}
|
||||||
@ -169,7 +192,13 @@ export default function Header(props) {
|
|||||||
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
|
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')}
|
||||||
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
|
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
|
||||||
>
|
>
|
||||||
<Link scroll={false} href={m.url}>
|
<Link
|
||||||
|
scroll={false}
|
||||||
|
href={m.url}
|
||||||
|
onClick={() => {
|
||||||
|
removeStuffRecoil(m)
|
||||||
|
}}
|
||||||
|
>
|
||||||
{getMessage(m.name)}
|
{getMessage(m.name)}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
@ -190,7 +219,15 @@ export default function Header(props) {
|
|||||||
<div className="header-inner">
|
<div className="header-inner">
|
||||||
<div className="header-right">
|
<div className="header-right">
|
||||||
<h1 className="logo">
|
<h1 className="logo">
|
||||||
<Link href={'/'}></Link>
|
<Link
|
||||||
|
href={'/'}
|
||||||
|
onClick={() => {
|
||||||
|
setStuffSearch({
|
||||||
|
...stuffSearch,
|
||||||
|
code: 'DELETE',
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
></Link>
|
||||||
</h1>
|
</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ul className="nav-list ">{getMenuTemplate(menus)}</ul>
|
<ul className="nav-list ">{getMenuTemplate(menus)}</ul>
|
||||||
@ -223,7 +260,7 @@ export default function Header(props) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="select-box">
|
<div className="select-box">
|
||||||
<QSelectBox options={SelectOptions} onChange={onChangeSelect} />
|
<QSelectBox options={SelectOptions} onChange={onChangeSelect} title={getMessage('site.header.link1')} />
|
||||||
</div>
|
</div>
|
||||||
<div className="btn-wrap">
|
<div className="btn-wrap">
|
||||||
<button className="btn-frame small dark" onClick={() => navPage()}>
|
<button className="btn-frame small dark" onClick={() => navPage()}>
|
||||||
|
|||||||
@ -11,12 +11,13 @@ import { useRouter } from 'next/navigation'
|
|||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { queryStringFormatter } from '@/util/common-utils'
|
import { queryStringFormatter } from '@/util/common-utils'
|
||||||
import MainSkeleton from '../ui/MainSkeleton'
|
import MainSkeleton from '../ui/MainSkeleton'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
|
||||||
import { useMainContentsController } from '@/hooks/main/useMainContentsController'
|
import { useMainContentsController } from '@/hooks/main/useMainContentsController'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
|
||||||
export default function MainContents() {
|
export default function MainContents() {
|
||||||
const { session } = useContext(SessionContext)
|
const { swalFire } = useSwal()
|
||||||
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
@ -107,8 +108,8 @@ export default function MainContents() {
|
|||||||
>
|
>
|
||||||
<div className="item-inner">
|
<div className="item-inner">
|
||||||
<span className="time">{dayjs(row.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')}</span>
|
<span className="time">{dayjs(row.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||||
<span>{row.objectNo}</span>
|
<span>{row.tempFlg === '0' ? row.objectNo : getMessage('stuff.gridData.tempObjectNo')}</span>
|
||||||
<span>{row.objectName}</span>
|
<span>{row.objectName ? row.objectName : '-'}</span>
|
||||||
<span>{row.saleStoreName}</span>
|
<span>{row.saleStoreName}</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -116,51 +117,60 @@ export default function MainContents() {
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<MainSkeleton count={6} />
|
<div className="recently-no-data">
|
||||||
|
<h3>{getMessage('main.content.objectList.noData1')}</h3>
|
||||||
|
<p>{getMessage('main.content.objectList.noData2')}</p>
|
||||||
|
<button type="button" className="btn-origin navy" onClick={() => router.push('/management/stuff/tempReg')}>
|
||||||
|
+ {getMessage('stuff.search.btn.register')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</ProductItem>
|
</ProductItem>
|
||||||
<ProductItem num={2} name={getMessage('main.content.notice')}>
|
<ProductItem num={2} name={getMessage('main.content.notice')}>
|
||||||
<div className="notice-box">
|
{recentNoticeList.length > 0 ? (
|
||||||
{recentNoticeList.length > 0 ? (
|
<div className="notice-box">
|
||||||
<>
|
<div className="notice-day pre">{dayjs(recentNoticeList[0]?.regDt).format('YYYY.MM.DD')}</div>
|
||||||
<div className="notice-day pre">{dayjs(recentNoticeList[0]?.regDt).format('YYYY.MM.DD')}</div>
|
<div className="notice-title">{recentNoticeList[0]?.title}</div>
|
||||||
<div className="notice-title">{recentNoticeList[0]?.title}</div>
|
<div
|
||||||
<div className="notice-contents">{recentNoticeList[0]?.contents}</div>
|
className="notice-contents"
|
||||||
</>
|
dangerouslySetInnerHTML={{ __html: recentNoticeList[0]?.contents ? recentNoticeList[0].contents.replaceAll('\n', '<br/>') : '' }}
|
||||||
) : (
|
></div>
|
||||||
<MainSkeleton count={5} />
|
</div>
|
||||||
)}
|
) : (
|
||||||
</div>
|
<div className="recently-no-data">
|
||||||
|
<h3>{getMessage('main.content.noBusiness')}</h3>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</ProductItem>
|
</ProductItem>
|
||||||
</div>
|
</div>
|
||||||
<div className="main-product-list">
|
<div className="main-product-list">
|
||||||
<ProductItem num={3} name={getMessage('main.faq')}>
|
<ProductItem num={3} name={getMessage('main.faq')}>
|
||||||
<ul className="faq-list">
|
{recentFaqList.length > 0 ? (
|
||||||
{recentFaqList.length > 0 ? (
|
<ul className="faq-list">
|
||||||
<>
|
{recentFaqList.map((row) => {
|
||||||
{recentFaqList.map((row) => {
|
return (
|
||||||
return (
|
<li key={row.rowNumber} className="faq-item">
|
||||||
<li key={row.rowNumber} className="faq-item">
|
<div className="faq-item-inner">
|
||||||
<div className="faq-item-inner">
|
<div className="faq-num pre">FAQ {row.totCnt - row.rowNumber}</div>
|
||||||
<div className="faq-num pre">FAQ {row.noticeNo}</div>
|
<div className="faq-title pre">{row.title}</div>
|
||||||
<div className="faq-title pre">{row.title}</div>
|
<div className="faq-day pre">{dayjs(row.regDt).format('YYYY.MM.DD')}</div>
|
||||||
<div className="faq-day pre">{dayjs(row.regDt).format('YYYY.MM.DD')}</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
)
|
||||||
)
|
})}
|
||||||
})}
|
</ul>
|
||||||
</>
|
) : (
|
||||||
) : (
|
<div className="recently-no-data">
|
||||||
<MainSkeleton count={2} />
|
<h3>{getMessage('main.content.noBusiness')}</h3>
|
||||||
)}
|
</div>
|
||||||
</ul>
|
)}
|
||||||
</ProductItem>
|
</ProductItem>
|
||||||
<ProductItem num={4} name={'Data Download'}>
|
<ProductItem num={4} name={'Data Download'}>
|
||||||
<div className="data-download-wrap">
|
<div className="data-download-wrap">
|
||||||
<button className="data-down">
|
<button className="data-down" type="button" onClick={() => swalFire({ text: getMessage('main.content.alert.noFile'), type: 'alert' })}>
|
||||||
<span>{getMessage('main.content.download1')}</span>
|
<span>{getMessage('main.content.download1')}</span>
|
||||||
</button>
|
</button>
|
||||||
<button className="data-down">
|
<button className="data-down" type="button" onClick={() => swalFire({ text: getMessage('main.content.alert.noFile'), type: 'alert' })}>
|
||||||
<span>{getMessage('main.content.download2')}</span>
|
<span>{getMessage('main.content.download2')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -9,8 +9,10 @@ export default function ProductItem({ num, name, children }) {
|
|||||||
router.push('/management/stuff', { scroll: false })
|
router.push('/management/stuff', { scroll: false })
|
||||||
} else if (num === 2) {
|
} else if (num === 2) {
|
||||||
router.push('/community/notice')
|
router.push('/community/notice')
|
||||||
} else {
|
} else if (num === 3) {
|
||||||
router.push('/community/faq')
|
router.push('/community/faq')
|
||||||
|
} else {
|
||||||
|
router.push('/community/archive')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@ -20,7 +22,7 @@ export default function ProductItem({ num, name, children }) {
|
|||||||
<span className={`item-logo ico0${num}`}></span>
|
<span className={`item-logo ico0${num}`}></span>
|
||||||
{name}
|
{name}
|
||||||
</h2>
|
</h2>
|
||||||
{num !== 4 && num !== 5 && (
|
{num !== 5 && (
|
||||||
<button
|
<button
|
||||||
className="more-btn"
|
className="more-btn"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export default function Stuff() {
|
|||||||
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
||||||
const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수
|
const [pageSize, setPageSize] = useState(100) //페이지 당 게시물 수
|
||||||
const [totalCount, setTotalCount] = useState(0) //총 갯수
|
const [totalCount, setTotalCount] = useState(0) //총 갯수
|
||||||
const [defaultSortType, setDefaultSortType] = useState('R')
|
const [defaultSortType, setDefaultSortType] = useState('U')
|
||||||
|
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
const { get } = useAxios(globalLocaleState)
|
const { get } = useAxios(globalLocaleState)
|
||||||
@ -41,11 +41,42 @@ export default function Stuff() {
|
|||||||
|
|
||||||
//그리드 내부 복사버튼
|
//그리드 내부 복사버튼
|
||||||
const copyNo = async (value) => {
|
const copyNo = async (value) => {
|
||||||
try {
|
// try {
|
||||||
await navigator.clipboard.writeText(value)
|
// await navigator.clipboard.writeText(value)
|
||||||
alert(getMessage('stuff.detail.header.successCopy'))
|
// alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
alert(getMessage('stuff.detail.header.failCopy'))
|
// alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
// }
|
||||||
|
// Navigator clipboard api needs a secure context (https)
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
await navigator.clipboard
|
||||||
|
.writeText(value)
|
||||||
|
.then(() => {
|
||||||
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Use the 'out of viewport hidden text area' trick
|
||||||
|
const textArea = document.createElement('textArea')
|
||||||
|
textArea.value = value
|
||||||
|
|
||||||
|
// Move textarea out of the viewport so it's not visible
|
||||||
|
textArea.style.position = 'absolute'
|
||||||
|
textArea.style.left = '-999999px'
|
||||||
|
|
||||||
|
document.body.prepend(textArea)
|
||||||
|
textArea.select()
|
||||||
|
|
||||||
|
try {
|
||||||
|
document.execCommand('copy')
|
||||||
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
|
} catch (err) {
|
||||||
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
} finally {
|
||||||
|
textArea.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +254,7 @@ export default function Stuff() {
|
|||||||
startRow: (pageNo - 1) * pageSize + 1,
|
startRow: (pageNo - 1) * pageSize + 1,
|
||||||
endRow: pageNo * pageSize,
|
endRow: pageNo * pageSize,
|
||||||
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId,
|
||||||
schSortType: 'R',
|
schSortType: 'U',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
@ -297,7 +328,7 @@ export default function Stuff() {
|
|||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSelSaleStoreId: '',
|
schSelSaleStoreId: '',
|
||||||
schOtherSelSaleStoreId: '',
|
schOtherSelSaleStoreId: '',
|
||||||
schSortType: 'R',
|
schSortType: 'U',
|
||||||
code: 'S',
|
code: 'S',
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
@ -407,8 +438,8 @@ export default function Stuff() {
|
|||||||
<div className="left-unit-box">
|
<div className="left-unit-box">
|
||||||
<div className="select-box mr5" style={{ width: '110px' }}>
|
<div className="select-box mr5" style={{ width: '110px' }}>
|
||||||
<select className="select-light black" onChange={onChangeSortType} value={stuffSearch.schSortType}>
|
<select className="select-light black" onChange={onChangeSortType} value={stuffSearch.schSortType}>
|
||||||
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
|
|
||||||
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
|
<option value="U">{getMessage('stuff.search.grid.schSortTypeU')}</option>
|
||||||
|
<option value="R">{getMessage('stuff.search.grid.schSortTypeR')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="select-box" style={{ width: '80px' }}>
|
<div className="select-box" style={{ width: '80px' }}>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useContext } from 'react'
|
import { useState, useEffect, useRef, useContext } from 'react'
|
||||||
import { useRouter, useSearchParams, usePathname } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { Button } from '@nextui-org/react'
|
import { Button } from '@nextui-org/react'
|
||||||
import Select, { components } from 'react-select'
|
import Select, { components } from 'react-select'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
@ -18,7 +18,8 @@ import WindSelectPop from './popup/WindSelectPop'
|
|||||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
import StuffPlanQGrid from './StuffPlanQGrid'
|
import StuffPlanQGrid from './StuffPlanQGrid'
|
||||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
import { ManagementContext } from '@/app/management/ManagementProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
|
// import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||||
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
import { stuffSearchState } from '@/store/stuffAtom'
|
import { stuffSearchState } from '@/store/stuffAtom'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
@ -33,6 +34,8 @@ export default function StuffDetail() {
|
|||||||
|
|
||||||
const [popPlanNo, setPopPlanNo] = useState('1') //default 1
|
const [popPlanNo, setPopPlanNo] = useState('1') //default 1
|
||||||
|
|
||||||
|
const [showButton, setShowButton] = useState('') //임시저장, 저장, 삭제 버튼 컨트롤
|
||||||
|
|
||||||
//공통코드
|
//공통코드
|
||||||
const { commonCode, findCommonCode } = useCommonCode()
|
const { commonCode, findCommonCode } = useCommonCode()
|
||||||
const [selOptions, setSelOptions] = useState('') //선택한 1차점
|
const [selOptions, setSelOptions] = useState('') //선택한 1차점
|
||||||
@ -50,7 +53,7 @@ export default function StuffDetail() {
|
|||||||
const formInitValue = {
|
const formInitValue = {
|
||||||
// 물건번호 T...(임시) R...(진짜)
|
// 물건번호 T...(임시) R...(진짜)
|
||||||
planReqNo: '', //설계의뢰No
|
planReqNo: '', //설계의뢰No
|
||||||
receiveUser: '', //담당자
|
receiveUser: session?.userNm, //담당자 로그인사용자명 디폴트
|
||||||
objectStatusId: '0', //물건구분(신축:0 기축 : 1)
|
objectStatusId: '0', //물건구분(신축:0 기축 : 1)
|
||||||
objectName: '', //물건명
|
objectName: '', //물건명
|
||||||
objectNameOmit: '', //경칭선택
|
objectNameOmit: '', //경칭선택
|
||||||
@ -106,7 +109,7 @@ export default function StuffDetail() {
|
|||||||
const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set
|
const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set
|
||||||
|
|
||||||
const [editMode, setEditMode] = useState('NEW')
|
const [editMode, setEditMode] = useState('NEW')
|
||||||
const { managementState, setManagementState } = useContext(ManagementContext)
|
const { managementState, setManagementState } = useContext(GlobalDataContext)
|
||||||
const [planGridProps, setPlanGridProps] = useState({
|
const [planGridProps, setPlanGridProps] = useState({
|
||||||
planGridData: [],
|
planGridData: [],
|
||||||
isPageable: false,
|
isPageable: false,
|
||||||
@ -146,7 +149,8 @@ export default function StuffDetail() {
|
|||||||
let capacity
|
let capacity
|
||||||
if (origin) {
|
if (origin) {
|
||||||
capacity = origin / 1000
|
capacity = origin / 1000
|
||||||
return capacity.toFixed(3)
|
//#400 소수점 2자리까지만 변경
|
||||||
|
return capacity.toFixed(2) + 'kW'
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@ -264,7 +268,10 @@ export default function StuffDetail() {
|
|||||||
display: 'none',
|
display: 'none',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (managementState?.createUser === 'T01' && session?.userId !== 'T01') {
|
||||||
|
//createUser가 T01인데 로그인사용자가 T01이 아니면 버튼숨기기
|
||||||
|
buttonStyle = { display: 'none' }
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="grid-cell-btn">
|
<div className="grid-cell-btn">
|
||||||
@ -317,8 +324,21 @@ export default function StuffDetail() {
|
|||||||
}
|
}
|
||||||
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
|
// console.log(res.data.createUser)
|
||||||
|
// console.log(session)
|
||||||
|
if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
|
||||||
|
//createUser가 T01인데 로그인사용자가 T01이 아니면 버튼숨기기
|
||||||
|
setShowButton('none')
|
||||||
|
}
|
||||||
|
|
||||||
if (isObjectNotEmpty(res.data)) {
|
if (isObjectNotEmpty(res.data)) {
|
||||||
setManagementState(res.data)
|
let surfaceTypeValue
|
||||||
|
if (res.data.surfaceType === 'Ⅲ・Ⅳ') {
|
||||||
|
surfaceTypeValue = '3'
|
||||||
|
} else if (res.data.surfaceType === 'Ⅱ') {
|
||||||
|
surfaceTypeValue = '2'
|
||||||
|
}
|
||||||
|
setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
|
||||||
} else {
|
} else {
|
||||||
setManagementState({})
|
setManagementState({})
|
||||||
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
alert(getMessage('stuff.detail.header.notExistObjectNo'))
|
||||||
@ -1287,12 +1307,16 @@ export default function StuffDetail() {
|
|||||||
delete params_sort.workNo
|
delete params_sort.workNo
|
||||||
delete params_sort.workName
|
delete params_sort.workName
|
||||||
|
|
||||||
// console.log(JSON.stringify(detail_sort) === JSON.stringify(params_sort))
|
|
||||||
// console.log(Object.entries(detail_sort).toString() === Object.entries(params_sort).toString())
|
|
||||||
if (Object.entries(detail_sort).toString() === Object.entries(params_sort).toString()) {
|
if (Object.entries(detail_sort).toString() === Object.entries(params_sort).toString()) {
|
||||||
return alert(getMessage('stuff.detail.noChgData'))
|
return alert(getMessage('stuff.detail.noChgData'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params?.receiveUser !== '') {
|
||||||
|
if (params?.receiveUser.trim().length > 10) {
|
||||||
|
return alert(getMessage('stuff.detail.tempSave.message2'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (editMode === 'NEW') {
|
if (editMode === 'NEW') {
|
||||||
await promisePost({ url: apiUrl, data: params })
|
await promisePost({ url: apiUrl, data: params })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@ -1364,6 +1388,13 @@ export default function StuffDetail() {
|
|||||||
params.saleStoreLevel = session.storeLvl
|
params.saleStoreLevel = session.storeLvl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 담당자 자리수 체크
|
||||||
|
if (params?.receiveUser !== '') {
|
||||||
|
if (params?.receiveUser.trim().length > 10) {
|
||||||
|
return alert(getMessage('stuff.detail.tempSave.message2'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const apiUrl = '/api/object/save-object'
|
const apiUrl = '/api/object/save-object'
|
||||||
if (objectNo) {
|
if (objectNo) {
|
||||||
await promisePut({ url: apiUrl, data: params })
|
await promisePut({ url: apiUrl, data: params })
|
||||||
@ -1443,14 +1474,43 @@ export default function StuffDetail() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 그리드 더블 클릭
|
||||||
|
const getCellDoubleClicked = (params) => {
|
||||||
|
if (params?.column?.colId !== 'estimateDate') {
|
||||||
|
if (params?.data?.planNo && params?.data?.objectNo) {
|
||||||
|
let objectNo = params?.data?.objectNo
|
||||||
|
let planNo = params?.data?.planNo
|
||||||
|
router.push(`/floor-plan?pid=${planNo}&objectNo=${objectNo}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{(editMode === 'NEW' && (
|
{(editMode === 'NEW' && (
|
||||||
<form onSubmit={handleSubmit(onValid)}>
|
<form onSubmit={handleSubmit(onValid)}>
|
||||||
<div className="sub-table-box">
|
<div className="sub-table-box">
|
||||||
<div className="promise-gudie">
|
<div className="promise-title-wrap">
|
||||||
<span className="important">*</span>
|
<div className="promise-gudie">
|
||||||
{getMessage('stuff.detail.required')}
|
<span className="important">*</span>
|
||||||
|
{getMessage('stuff.detail.required')}
|
||||||
|
</div>
|
||||||
|
<div className="left-unit-box">
|
||||||
|
{!isFormValid ? (
|
||||||
|
<Button className="btn-origin grey mr5" onPress={onTempSave} style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.tempSave')}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.save')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Link href="/management/stuff" scroll={false}>
|
||||||
|
<button type="button" className="btn-origin grey">
|
||||||
|
{getMessage('stuff.detail.btn.moveList')}
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="infomation-table">
|
<div className="infomation-table">
|
||||||
<table>
|
<table>
|
||||||
@ -1476,7 +1536,7 @@ export default function StuffDetail() {
|
|||||||
)) ||
|
)) ||
|
||||||
null}
|
null}
|
||||||
</div>
|
</div>
|
||||||
<Button type="button" className="btn-origin grey" onPress={onSearchDesignRequestPopOpen}>
|
<Button type="button" className="btn-origin grey" onPress={onSearchDesignRequestPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.planReqPopup.title')}
|
{getMessage('stuff.planReqPopup.title')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -1685,7 +1745,7 @@ export default function StuffDetail() {
|
|||||||
onChange={onSelectionChange2}
|
onChange={onSelectionChange2}
|
||||||
getOptionLabel={(x) => x.saleStoreName}
|
getOptionLabel={(x) => x.saleStoreName}
|
||||||
getOptionValue={(x) => x.saleStoreId}
|
getOptionValue={(x) => x.saleStoreId}
|
||||||
isDisabled={otherSaleStoreList.length > 0 ? false : true}
|
isDisabled={otherSaleStoreList != null && otherSaleStoreList.length > 0 ? false : true}
|
||||||
isClearable={true}
|
isClearable={true}
|
||||||
value={otherSaleStoreList.filter(function (option) {
|
value={otherSaleStoreList.filter(function (option) {
|
||||||
return option.saleStoreId === otherSelOptions
|
return option.saleStoreId === otherSelOptions
|
||||||
@ -1713,7 +1773,7 @@ export default function StuffDetail() {
|
|||||||
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
||||||
<input type="text" className="input-light" disabled value={form.watch('zipNo') || ''} />
|
<input type="text" className="input-light" disabled value={form.watch('zipNo') || ''} />
|
||||||
</div>
|
</div>
|
||||||
<Button className="btn-origin grey" onPress={onSearchPostNumberPopOpen}>
|
<Button className="btn-origin grey" onPress={onSearchPostNumberPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.addressPop')}
|
{getMessage('stuff.detail.btn.addressPop')}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="guide">{getMessage('stuff.detail.btn.addressPop.guide')}</div>
|
<div className="guide">{getMessage('stuff.detail.btn.addressPop.guide')}</div>
|
||||||
@ -1803,7 +1863,7 @@ export default function StuffDetail() {
|
|||||||
></Select>
|
></Select>
|
||||||
</div>
|
</div>
|
||||||
<span className="mr10">{getMessage('stuff.detail.standardWindSpeedIdSpan')}</span>
|
<span className="mr10">{getMessage('stuff.detail.standardWindSpeedIdSpan')}</span>
|
||||||
<Button type="button" className="btn-origin grey" onPress={onSearchWindSpeedPopOpen}>
|
<Button type="button" className="btn-origin grey" onPress={onSearchWindSpeedPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.windSpeedPop')}
|
{getMessage('stuff.detail.btn.windSpeedPop')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -1925,11 +1985,11 @@ export default function StuffDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="sub-right-footer">
|
<div className="sub-right-footer">
|
||||||
{!isFormValid ? (
|
{!isFormValid ? (
|
||||||
<Button className="btn-origin grey mr5" onPress={onTempSave}>
|
<Button className="btn-origin grey mr5" onPress={onTempSave} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.tempSave')}
|
{getMessage('stuff.detail.btn.tempSave')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button type="submit" className="btn-origin navy mr5">
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.save')}
|
{getMessage('stuff.detail.btn.save')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@ -1945,8 +2005,46 @@ export default function StuffDetail() {
|
|||||||
<>
|
<>
|
||||||
<form onSubmit={handleSubmit(onValid)}>
|
<form onSubmit={handleSubmit(onValid)}>
|
||||||
<div className="sub-table-box">
|
<div className="sub-table-box">
|
||||||
<div className="promise-gudie">
|
<div className="promise-title-wrap">
|
||||||
<span className="important">*</span> {getMessage('stuff.detail.required')}
|
<div className="promise-gudie">
|
||||||
|
<span className="important">*</span> {getMessage('stuff.detail.required')}
|
||||||
|
</div>
|
||||||
|
{managementState?.tempFlg === '0' ? (
|
||||||
|
<>
|
||||||
|
<div className="left-unit-box">
|
||||||
|
<Link href="/management/stuff" scroll={false}>
|
||||||
|
<button type="button" className="btn-origin grey mr5">
|
||||||
|
{getMessage('stuff.detail.btn.moveList')}
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.save')}
|
||||||
|
</Button>
|
||||||
|
<Button type="button" className="btn-origin grey" onPress={onDelete} style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.delete')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="left-unit-box">
|
||||||
|
{!isFormValid ? (
|
||||||
|
<Button className="btn-origin grey mr5" onPress={onTempSave} style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.tempSave')}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
|
{getMessage('stuff.detail.btn.save')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Link href="/management/stuff" scroll={false}>
|
||||||
|
<button type="button" className="btn-origin grey">
|
||||||
|
{getMessage('stuff.detail.btn.moveList')}
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="infomation-wrap">
|
<div className="infomation-wrap">
|
||||||
<div className="infomation-table">
|
<div className="infomation-table">
|
||||||
@ -1969,12 +2067,13 @@ export default function StuffDetail() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
form.setValue('planReqNo', '')
|
form.setValue('planReqNo', '')
|
||||||
}}
|
}}
|
||||||
|
style={{ display: showButton }}
|
||||||
></button>
|
></button>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{managementState?.tempFlg === '1' ? (
|
{managementState?.tempFlg === '1' ? (
|
||||||
<>
|
<>
|
||||||
<Button className="btn-origin grey" onPress={onSearchDesignRequestPopOpen}>
|
<Button className="btn-origin grey" onPress={onSearchDesignRequestPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.planReqPopup.title')}
|
{getMessage('stuff.planReqPopup.title')}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
@ -2230,7 +2329,7 @@ export default function StuffDetail() {
|
|||||||
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
<div className="input-wrap mr5" style={{ width: '200px' }}>
|
||||||
<input type="text" className="input-light" disabled value={form.watch('zipNo') || ''} />
|
<input type="text" className="input-light" disabled value={form.watch('zipNo') || ''} />
|
||||||
</div>
|
</div>
|
||||||
<Button className="btn-origin grey" onPress={onSearchPostNumberPopOpen}>
|
<Button className="btn-origin grey" onPress={onSearchPostNumberPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.addressPop')}
|
{getMessage('stuff.detail.btn.addressPop')}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="guide">{getMessage('stuff.detail.btn.addressPop.guide')}</div>
|
<div className="guide">{getMessage('stuff.detail.btn.addressPop.guide')}</div>
|
||||||
@ -2325,7 +2424,7 @@ export default function StuffDetail() {
|
|||||||
></Select>
|
></Select>
|
||||||
</div>
|
</div>
|
||||||
<span className="mr10">{getMessage('stuff.detail.standardWindSpeedIdSpan')}</span>
|
<span className="mr10">{getMessage('stuff.detail.standardWindSpeedIdSpan')}</span>
|
||||||
<Button type="button" className="btn-origin grey" onPress={onSearchWindSpeedPopOpen}>
|
<Button type="button" className="btn-origin grey" onPress={onSearchWindSpeedPopOpen} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.windSpeedPop')}
|
{getMessage('stuff.detail.btn.windSpeedPop')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -2485,7 +2584,7 @@ export default function StuffDetail() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="information-grid">
|
<div className="information-grid">
|
||||||
<div className="q-grid no-cols">
|
<div className="q-grid no-cols">
|
||||||
<StuffPlanQGrid {...planGridProps} />
|
<StuffPlanQGrid {...planGridProps} getCellDoubleClicked={getCellDoubleClicked} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* 진짜R 플랜끝 */}
|
{/* 진짜R 플랜끝 */}
|
||||||
@ -2495,10 +2594,10 @@ export default function StuffDetail() {
|
|||||||
{getMessage('stuff.detail.btn.moveList')}
|
{getMessage('stuff.detail.btn.moveList')}
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<Button type="submit" className="btn-origin navy mr5">
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.save')}
|
{getMessage('stuff.detail.btn.save')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" className="btn-origin grey" onPress={onDelete}>
|
<Button type="button" className="btn-origin grey" onPress={onDelete} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.delete')}
|
{getMessage('stuff.detail.btn.delete')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -2507,11 +2606,11 @@ export default function StuffDetail() {
|
|||||||
<>
|
<>
|
||||||
<div className="sub-right-footer">
|
<div className="sub-right-footer">
|
||||||
{!isFormValid ? (
|
{!isFormValid ? (
|
||||||
<Button className="btn-origin grey mr5" onPress={onTempSave}>
|
<Button className="btn-origin grey mr5" onPress={onTempSave} style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.tempSave')}
|
{getMessage('stuff.detail.btn.tempSave')}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button type="submit" className="btn-origin navy mr5">
|
<Button type="submit" className="btn-origin navy mr5" style={{ display: showButton }}>
|
||||||
{getMessage('stuff.detail.btn.save')}
|
{getMessage('stuff.detail.btn.save')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -3,19 +3,53 @@
|
|||||||
import { useContext } from 'react'
|
import { useContext } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { ManagementContext } from '@/app/management/ManagementProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
|
// import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||||
export default function StuffHeader() {
|
export default function StuffHeader() {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
const { managementState } = useContext(ManagementContext)
|
const { managementState } = useContext(GlobalDataContext)
|
||||||
|
|
||||||
//물건번호 복사
|
//물건번호 복사
|
||||||
|
// const copyObjectNo = async (objectNo) => {
|
||||||
|
// await navigator.clipboard.writeText(objectNo)
|
||||||
|
// alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
|
// try {
|
||||||
|
// } catch (error) {
|
||||||
|
// alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
const copyObjectNo = async (objectNo) => {
|
const copyObjectNo = async (objectNo) => {
|
||||||
await navigator.clipboard.writeText(objectNo)
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
alert(getMessage('stuff.detail.header.successCopy'))
|
await navigator.clipboard
|
||||||
try {
|
.writeText(objectNo)
|
||||||
} catch (error) {
|
.then(() => {
|
||||||
alert(getMessage('stuff.detail.header.failCopy'))
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Use the 'out of viewport hidden text area' trick
|
||||||
|
const textArea = document.createElement('textArea')
|
||||||
|
textArea.value = objectNo
|
||||||
|
|
||||||
|
// Move textarea out of the viewport so it's not visible
|
||||||
|
textArea.style.position = 'absolute'
|
||||||
|
textArea.style.left = '-999999px'
|
||||||
|
|
||||||
|
document.body.prepend(textArea)
|
||||||
|
textArea.select()
|
||||||
|
|
||||||
|
try {
|
||||||
|
document.execCommand('copy')
|
||||||
|
alert(getMessage('stuff.detail.header.successCopy'))
|
||||||
|
} catch (err) {
|
||||||
|
alert(getMessage('stuff.detail.header.failCopy'))
|
||||||
|
} finally {
|
||||||
|
textArea.remove()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,13 +27,10 @@ export default function StuffPlanQGrid(props) {
|
|||||||
planGridData ? setRowData(planGridData) : ''
|
planGridData ? setRowData(planGridData) : ''
|
||||||
}, [planGridData])
|
}, [planGridData])
|
||||||
|
|
||||||
// const onGridReady = useCallback(
|
//그리드 더블클릭 추가
|
||||||
// (params) => {
|
const onCellDoubleClicked = useCallback((params) => {
|
||||||
// setGridApi(params.api)
|
props.getCellDoubleClicked(params)
|
||||||
// planGridData ? setRowData(planGridData) : ''
|
}, [])
|
||||||
// },
|
|
||||||
// [planGridData],
|
|
||||||
// )
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ag-theme-quartz" style={{ height: '100%' }}>
|
<div className="ag-theme-quartz" style={{ height: '100%' }}>
|
||||||
@ -47,6 +44,7 @@ export default function StuffPlanQGrid(props) {
|
|||||||
pagination={isPageable}
|
pagination={isPageable}
|
||||||
domLayout="autoHeight"
|
domLayout="autoHeight"
|
||||||
suppressCellFocus={true}
|
suppressCellFocus={true}
|
||||||
|
onCellDoubleClicked={onCellDoubleClicked}
|
||||||
overlayNoRowsTemplate={`<span className="ag-overlay-loading-center">${getMessage('stuff.grid.noData')}</span>`}
|
overlayNoRowsTemplate={`<span className="ag-overlay-loading-center">${getMessage('stuff.grid.noData')}</span>`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -86,165 +86,164 @@ export default function StuffSearchCondition() {
|
|||||||
if (stuffSearch.code === 'S') {
|
if (stuffSearch.code === 'S') {
|
||||||
if (stuffSearch.pageNo !== 1) {
|
if (stuffSearch.pageNo !== 1) {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
schObjectNo: objectNo ? objectNo.trim() : stuffSearch.schObjectNo.trim(),
|
||||||
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
|
||||||
schAddress: address ? address : '',
|
schAddress: address ? address.trim() : '',
|
||||||
schObjectName: objectName ? objectName : '',
|
schObjectName: objectName ? objectName.trim() : '',
|
||||||
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
schReceiveUser: receiveUser ? receiveUser : '',
|
schReceiveUser: receiveUser ? receiveUser.trim() : '',
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 1 * stuffSearch?.pageSize,
|
endRow: 1 * stuffSearch?.pageSize,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
schObjectNo: objectNo ? objectNo.trim() : stuffSearch.schObjectNo.trim(),
|
||||||
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
|
||||||
schAddress: address ? address : '',
|
schAddress: address ? address.trim() : '',
|
||||||
schObjectName: objectName ? objectName : '',
|
schObjectName: objectName ? objectName.trim() : '',
|
||||||
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
schReceiveUser: receiveUser ? receiveUser : '',
|
schReceiveUser: receiveUser ? receiveUser.trim() : '',
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: stuffSearch?.pageNo,
|
pageNo: stuffSearch?.pageNo,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (stuffSearch.code === 'FINISH') {
|
} else if (stuffSearch.code === 'FINISH') {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo,
|
schObjectNo: objectNo.trim(),
|
||||||
schSaleStoreName: saleStoreName,
|
schSaleStoreName: saleStoreName.trim(),
|
||||||
schAddress: address,
|
schAddress: address.trim(),
|
||||||
schObjectName: objectName,
|
schObjectName: objectName.trim(),
|
||||||
schDispCompanyName: dispCompanyName,
|
schDispCompanyName: dispCompanyName.trim(),
|
||||||
schSelSaleStoreId: schSelSaleStoreId,
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: receiveUser,
|
schReceiveUser: receiveUser.trim(),
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
})
|
})
|
||||||
} else if (stuffSearch.code === 'E') {
|
} else if (stuffSearch.code === 'E') {
|
||||||
if (session.storeId !== 'T01' && session.storeLvl === '1') {
|
if (session.storeId !== 'T01' && session.storeLvl === '1') {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
|
||||||
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
|
||||||
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
|
||||||
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
|
||||||
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
|
||||||
schSelSaleStoreId: otherSaleStoreId ? schSelSaleStoreId : '',
|
schSelSaleStoreId: otherSaleStoreId ? schSelSaleStoreId : '',
|
||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: stuffSearch?.pageNo,
|
pageNo: stuffSearch?.pageNo,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
} else if (session.storeId === 'T01') {
|
} else if (session.storeId === 'T01') {
|
||||||
if (stuffSearch.pageNo !== 1) {
|
if (stuffSearch.pageNo !== 1) {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo ? objectNo : stuffSearch.schObjectNo,
|
schObjectNo: objectNo ? objectNo.trim() : stuffSearch.schObjectNo.trim(),
|
||||||
schSaleStoreName: saleStoreName ? saleStoreName : '',
|
schSaleStoreName: saleStoreName ? saleStoreName.trim() : '',
|
||||||
schAddress: address ? address : '',
|
schAddress: address ? address.trim() : '',
|
||||||
schObjectName: objectName ? objectName : '',
|
schObjectName: objectName ? objectName.trim() : '',
|
||||||
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
|
schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '',
|
||||||
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '',
|
||||||
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
schOtherSelSaleStoreId: stuffSearch?.schOtherSelSaleStoreId ? stuffSearch.schOtherSelSaleStoreId : '',
|
||||||
schReceiveUser: receiveUser ? receiveUser : '',
|
schReceiveUser: receiveUser ? receiveUser.trim() : '',
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 1 * stuffSearch?.pageSize,
|
endRow: 1 * stuffSearch?.pageSize,
|
||||||
// schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: 'U',
|
||||||
schSortType: 'R',
|
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
|
||||||
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
|
||||||
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
|
||||||
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
|
||||||
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
|
||||||
schSelSaleStoreId: schSelSaleStoreId,
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: stuffSearch?.pageNo,
|
pageNo: stuffSearch?.pageNo,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
|
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo.trim() : objectNo.trim(),
|
||||||
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
|
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName.trim() : saleStoreName.trim(),
|
||||||
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
|
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress.trim() : address.trim(),
|
||||||
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
|
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName.trim() : objectName.trim(),
|
||||||
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
|
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName.trim() : dispCompanyName.trim(),
|
||||||
schSelSaleStoreId: schSelSaleStoreId,
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
|
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser.trim() : receiveUser.trim(),
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: stuffSearch?.pageNo,
|
pageNo: stuffSearch?.pageNo,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setStuffSearch({
|
setStuffSearch({
|
||||||
schObjectNo: objectNo,
|
schObjectNo: objectNo.trim(),
|
||||||
schSaleStoreName: saleStoreName,
|
schSaleStoreName: saleStoreName.trim(),
|
||||||
schAddress: address,
|
schAddress: address.trim(),
|
||||||
schObjectName: objectName,
|
schObjectName: objectName.trim(),
|
||||||
schDispCompanyName: dispCompanyName,
|
schDispCompanyName: dispCompanyName.trim(),
|
||||||
schSelSaleStoreId: schSelSaleStoreId,
|
schSelSaleStoreId: schSelSaleStoreId,
|
||||||
schOtherSelSaleStoreId: otherSaleStoreId,
|
schOtherSelSaleStoreId: otherSaleStoreId,
|
||||||
schReceiveUser: receiveUser,
|
schReceiveUser: receiveUser.trim(),
|
||||||
schDateType: dateType,
|
schDateType: dateType,
|
||||||
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
schFromDt: startDate ? dayjs(startDate).format('YYYY-MM-DD') : '',
|
||||||
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
schToDt: endDate ? dayjs(endDate).format('YYYY-MM-DD') : '',
|
||||||
code: 'E',
|
code: 'E',
|
||||||
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
|
||||||
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
|
||||||
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
|
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'U',
|
||||||
pageNo: stuffSearch?.pageNo,
|
pageNo: stuffSearch?.pageNo,
|
||||||
pageSize: stuffSearch?.pageSize,
|
pageSize: stuffSearch?.pageSize,
|
||||||
})
|
})
|
||||||
@ -288,10 +287,9 @@ export default function StuffSearchCondition() {
|
|||||||
schDateType: 'U',
|
schDateType: 'U',
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSortType: 'R',
|
schSortType: 'U',
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
// code: 'S',
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (otherSaleStoreList.length > 1) {
|
if (otherSaleStoreList.length > 1) {
|
||||||
@ -307,7 +305,7 @@ export default function StuffSearchCondition() {
|
|||||||
|
|
||||||
stuffSearch.startRow = 1
|
stuffSearch.startRow = 1
|
||||||
stuffSearch.endRow = 100
|
stuffSearch.endRow = 100
|
||||||
stuffSearch.schSortType = 'R'
|
stuffSearch.schSortType = 'U'
|
||||||
stuffSearch.pageNo = 1
|
stuffSearch.pageNo = 1
|
||||||
stuffSearch.pageSize = 100
|
stuffSearch.pageSize = 100
|
||||||
} else {
|
} else {
|
||||||
@ -321,7 +319,7 @@ export default function StuffSearchCondition() {
|
|||||||
|
|
||||||
stuffSearch.startRow = 1
|
stuffSearch.startRow = 1
|
||||||
stuffSearch.endRow = 100
|
stuffSearch.endRow = 100
|
||||||
stuffSearch.schSortType = 'R'
|
stuffSearch.schSortType = 'U'
|
||||||
stuffSearch.pageNo = 1
|
stuffSearch.pageNo = 1
|
||||||
stuffSearch.pageSize = 100
|
stuffSearch.pageSize = 100
|
||||||
}
|
}
|
||||||
@ -347,6 +345,8 @@ export default function StuffSearchCondition() {
|
|||||||
get({ url: url }).then((res) => {
|
get({ url: url }).then((res) => {
|
||||||
if (!isEmptyArray(res)) {
|
if (!isEmptyArray(res)) {
|
||||||
res.map((row) => {
|
res.map((row) => {
|
||||||
|
//#399
|
||||||
|
row.saleStoreName = row.saleStoreName + ' - ' + row.saleStoreId
|
||||||
row.value = row.saleStoreId
|
row.value = row.saleStoreId
|
||||||
row.label = row.saleStoreName
|
row.label = row.saleStoreName
|
||||||
})
|
})
|
||||||
@ -367,6 +367,8 @@ export default function StuffSearchCondition() {
|
|||||||
get({ url: url }).then((res) => {
|
get({ url: url }).then((res) => {
|
||||||
if (!isEmptyArray(res)) {
|
if (!isEmptyArray(res)) {
|
||||||
res.map((row) => {
|
res.map((row) => {
|
||||||
|
//#399
|
||||||
|
row.saleStoreName = row.saleStoreName + ' - ' + row.saleStoreId
|
||||||
row.value = row.saleStoreId
|
row.value = row.saleStoreId
|
||||||
row.label = row.saleStoreName
|
row.label = row.saleStoreName
|
||||||
})
|
})
|
||||||
@ -456,6 +458,8 @@ export default function StuffSearchCondition() {
|
|||||||
get({ url: url }).then((res) => {
|
get({ url: url }).then((res) => {
|
||||||
if (!isEmptyArray(res)) {
|
if (!isEmptyArray(res)) {
|
||||||
res.map((row) => {
|
res.map((row) => {
|
||||||
|
//#399
|
||||||
|
row.saleStoreName = row.saleStoreName + ' - ' + row.saleStoreId
|
||||||
row.value = row.saleStoreId
|
row.value = row.saleStoreId
|
||||||
row.label = row.saleStoreName
|
row.label = row.saleStoreName
|
||||||
})
|
})
|
||||||
@ -474,6 +478,10 @@ export default function StuffSearchCondition() {
|
|||||||
if (stuffSearch.code === 'S') {
|
if (stuffSearch.code === 'S') {
|
||||||
stuffSearch.schSelSaleStoreId = ''
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
stuffSearch.schOtherSelSaleStoreId = ''
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
|
} else if (stuffSearch.code === 'E') {
|
||||||
|
//#401
|
||||||
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
//2차점 판매점목록비우기
|
//2차점 판매점목록비우기
|
||||||
@ -540,7 +548,7 @@ export default function StuffSearchCondition() {
|
|||||||
stuffSearch.endRow = 100
|
stuffSearch.endRow = 100
|
||||||
stuffSearch.schSelSaleStoreId = ''
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
stuffSearch.schOtherSelSaleStoreId = ''
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
stuffSearch.schSortType = 'R'
|
stuffSearch.schSortType = 'U'
|
||||||
stuffSearch.pageNo = 1
|
stuffSearch.pageNo = 1
|
||||||
stuffSearch.pageSize = 100
|
stuffSearch.pageSize = 100
|
||||||
|
|
||||||
@ -572,7 +580,7 @@ export default function StuffSearchCondition() {
|
|||||||
stuffSearch.endRow = 100
|
stuffSearch.endRow = 100
|
||||||
stuffSearch.schSelSaleStoreId = ''
|
stuffSearch.schSelSaleStoreId = ''
|
||||||
stuffSearch.schOtherSelSaleStoreId = ''
|
stuffSearch.schOtherSelSaleStoreId = ''
|
||||||
stuffSearch.schSortType = 'R'
|
stuffSearch.schSortType = 'U'
|
||||||
stuffSearch.pageNo = 1
|
stuffSearch.pageNo = 1
|
||||||
stuffSearch.pageSize = 100
|
stuffSearch.pageSize = 100
|
||||||
setSchSelSaleStoreId('')
|
setSchSelSaleStoreId('')
|
||||||
|
|||||||
@ -13,7 +13,8 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
||||||
|
|
||||||
import { ManagementContext } from '@/app/management/ManagementProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
|
// import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
|
|
||||||
export default function StuffSubHeader({ type }) {
|
export default function StuffSubHeader({ type }) {
|
||||||
@ -25,7 +26,7 @@ export default function StuffSubHeader({ type }) {
|
|||||||
|
|
||||||
const { isGlobalLoading } = useContext(QcastContext)
|
const { isGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
const { managementState } = useContext(ManagementContext)
|
const { managementState } = useContext(GlobalDataContext)
|
||||||
|
|
||||||
const [buttonStyle, setButtonStyle] = useState('')
|
const [buttonStyle, setButtonStyle] = useState('')
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -87,7 +87,7 @@ export default function PlanRequestPop(props) {
|
|||||||
const onSubmit = (page, type) => {
|
const onSubmit = (page, type) => {
|
||||||
//2차점 테스트 201X112
|
//2차점 테스트 201X112
|
||||||
const params = {
|
const params = {
|
||||||
// saleStoreId: 'T100',
|
// saleStoreId: 'X112',
|
||||||
// saleStoreLevel: '1',
|
// saleStoreLevel: '1',
|
||||||
saleStoreId: props?.otherSaleStoreId ? props.otherSaleStoreId : props.saleStoreId,
|
saleStoreId: props?.otherSaleStoreId ? props.otherSaleStoreId : props.saleStoreId,
|
||||||
saleStoreLevel: props?.otherSaleStoreLevel ? props.otherSaleStoreLevel : props.saleStoreLevel,
|
saleStoreLevel: props?.otherSaleStoreLevel ? props.otherSaleStoreLevel : props.saleStoreLevel,
|
||||||
|
|||||||
115
src/components/sample/SampleReducer.jsx
Normal file
115
src/components/sample/SampleReducer.jsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { Card, CardBody, Input, Tab, Tabs } from '@nextui-org/react'
|
||||||
|
import { useEffect, useReducer } from 'react'
|
||||||
|
|
||||||
|
const reducer = (prevState, nextState) => {
|
||||||
|
return { ...prevState, ...nextState }
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultData = {
|
||||||
|
commonData: 'common',
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'tab1',
|
||||||
|
range: 10,
|
||||||
|
maker: 'maker1',
|
||||||
|
law: 'law1',
|
||||||
|
basis: 'basis1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'tab2',
|
||||||
|
range: 20,
|
||||||
|
maker: 'maker2',
|
||||||
|
law: 'law2',
|
||||||
|
basis: 'basis2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'tab3',
|
||||||
|
range: 30,
|
||||||
|
maker: 'maker3',
|
||||||
|
law: 'law3',
|
||||||
|
basis: 'basis3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: 'tab4',
|
||||||
|
range: 40,
|
||||||
|
maker: 'maker4',
|
||||||
|
law: 'law4',
|
||||||
|
basis: 'basis4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SampleReducer() {
|
||||||
|
const [sampleState, setSampleState] = useReducer(reducer, defaultData)
|
||||||
|
|
||||||
|
const handleChangeTabsData = (newTab) => {
|
||||||
|
const newTabs = sampleState.tabs.map((t) => {
|
||||||
|
if (t.id === newTab.id) {
|
||||||
|
return newTab
|
||||||
|
} else {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setSampleState({ tabs: newTabs })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ SampleReducer ~ sampleState:', sampleState)
|
||||||
|
}, [sampleState])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>공통: {sampleState.commonData}</div>
|
||||||
|
<div className="flex w-full flex-col">
|
||||||
|
<Tabs aria-label="Options">
|
||||||
|
{sampleState.tabs.map((s) => (
|
||||||
|
<Tab key={s.id} title={s.name}>
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||||
|
<Input
|
||||||
|
label="range"
|
||||||
|
type="text"
|
||||||
|
value={s.range}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, range: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="maker"
|
||||||
|
type="text"
|
||||||
|
value={s.maker}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, maker: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="law"
|
||||||
|
type="text"
|
||||||
|
value={s.law}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, law: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="basis"
|
||||||
|
type="text"
|
||||||
|
value={s.basis}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, basis: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -2,12 +2,13 @@ import { useEffect } from 'react'
|
|||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { basicSettingState, roofDisplaySelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
import { basicSettingState, roofDisplaySelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
import { canvasState, dotLineGridSettingState, pitchText, pitchTextSelector, showAngleUnitSelector } from '@/store/canvasAtom'
|
import { canvasState, dotLineGridSettingState, pitchText, pitchTextSelector, showAngleUnitSelector } from '@/store/canvasAtom'
|
||||||
import { getChonByDegree, getDegreeByChon, setSurfaceShapePattern } from '@/util/canvas-util'
|
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
||||||
import { useFont } from '@/hooks/common/useFont'
|
import { useFont } from '@/hooks/common/useFont'
|
||||||
import { useGrid } from '@/hooks/common/useGrid'
|
import { useGrid } from '@/hooks/common/useGrid'
|
||||||
import { globalFontAtom } from '@/store/fontAtom'
|
import { globalFontAtom } from '@/store/fontAtom'
|
||||||
import { useRoof } from '@/hooks/common/useRoof'
|
import { useRoof } from '@/hooks/common/useRoof'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useCanvasConfigInitialize() {
|
export function useCanvasConfigInitialize() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -18,6 +19,7 @@ export function useCanvasConfigInitialize() {
|
|||||||
const setDotLineGridSetting = useSetRecoilState(dotLineGridSettingState)
|
const setDotLineGridSetting = useSetRecoilState(dotLineGridSettingState)
|
||||||
const pitchText = useRecoilValue(pitchTextSelector)
|
const pitchText = useRecoilValue(pitchTextSelector)
|
||||||
const angleUnit = useRecoilValue(showAngleUnitSelector)
|
const angleUnit = useRecoilValue(showAngleUnitSelector)
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
const {} = useFont()
|
const {} = useFont()
|
||||||
const {} = useGrid()
|
const {} = useGrid()
|
||||||
const {} = useRoof()
|
const {} = useRoof()
|
||||||
@ -63,6 +65,7 @@ export function useCanvasConfigInitialize() {
|
|||||||
roofInit() //화면표시 초기화
|
roofInit() //화면표시 초기화
|
||||||
groupDimensionInit()
|
groupDimensionInit()
|
||||||
reGroupInit() //그룹 객체 재그룹
|
reGroupInit() //그룹 객체 재그룹
|
||||||
|
moduleInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
const gridInit = () => {
|
const gridInit = () => {
|
||||||
@ -194,5 +197,19 @@ export function useCanvasConfigInitialize() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moduleInit = () => {
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'module')
|
||||||
|
.forEach((obj) => {
|
||||||
|
obj.set({
|
||||||
|
selectable: true,
|
||||||
|
lockMovementX: false,
|
||||||
|
lockMovementY: false,
|
||||||
|
})
|
||||||
|
obj.setViewLengthText(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return { canvasLoadInit, gridInit }
|
return { canvasLoadInit, gridInit }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,10 +39,6 @@ export const useCommonCode = () => {
|
|||||||
return resultCodes
|
return resultCodes
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
findCommonCode()
|
|
||||||
}, [globalLocale])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getCommonCode = async () => {
|
const getCommonCode = async () => {
|
||||||
await promiseGet({ url: '/api/commcode/qc-comm-code' }).then((res) => {
|
await promiseGet({ url: '/api/commcode/qc-comm-code' }).then((res) => {
|
||||||
|
|||||||
@ -603,8 +603,12 @@ export function useCommonUtils() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deleteObject = () => {
|
const deleteObject = () => {
|
||||||
const obj = canvas?.getActiveObject()
|
const selectedObj = canvas?.getActiveObjects()
|
||||||
commonDeleteText(obj)
|
if (selectedObj) {
|
||||||
|
selectedObj.forEach((obj) => {
|
||||||
|
commonDeleteText(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const moveObject = () => {
|
const moveObject = () => {
|
||||||
|
|||||||
@ -28,11 +28,7 @@ export function useGrid() {
|
|||||||
// 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
|
// 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
|
||||||
canvas
|
canvas
|
||||||
?.getObjects()
|
?.getObjects()
|
||||||
.filter((obj) => obj.name === 'lineGrid')
|
.filter((obj) => ['lineGrid', 'dotGrid'].includes(obj.name))
|
||||||
.forEach((obj) => canvas?.remove(obj))
|
|
||||||
canvas
|
|
||||||
?.getObjects()
|
|
||||||
.filter((obj) => obj.name === 'dotGrid')
|
|
||||||
.forEach((obj) => canvas?.remove(obj))
|
.forEach((obj) => canvas?.remove(obj))
|
||||||
|
|
||||||
//const horizontalInterval = interval.horizontalInterval
|
//const horizontalInterval = interval.horizontalInterval
|
||||||
@ -181,8 +177,17 @@ export function useGrid() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeGrid = () => {
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => ['lineGrid', 'dotGrid', 'tempGrid'].includes(obj.name))
|
||||||
|
.forEach((obj) => canvas.remove(obj))
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
move,
|
move,
|
||||||
copy,
|
copy,
|
||||||
|
removeGrid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useAxios } from '@/hooks/useAxios'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { getQueryString } from '@/util/common-utils'
|
import { getQueryString } from '@/util/common-utils'
|
||||||
import axios from 'axios'
|
import { trestleRequest, constructionRequest, trestleDetailRequest } from '@/models/apiModels'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 마스터 컨트롤러 훅
|
* 마스터 컨트롤러 훅
|
||||||
@ -26,16 +26,15 @@ export function useMasterController() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 모듈 타입별 아이템 목록 조회
|
* 모듈 타입별 아이템 목록 조회
|
||||||
* @param {지붕재 코드} roofMatlCd
|
* @param {지붕재 코드 목록} arrRoofMatlCd
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getModuleTypeItemList = async (roofMatlCd) => {
|
const getModuleTypeItemList = async (paramArr) => {
|
||||||
if (!roofMatlCd || roofMatlCd.trim() === '') {
|
if (!Array.isArray(paramArr) || paramArr.length === 0 || paramArr.length > 4 || paramArr.some((item) => !item || item.trim() === '')) {
|
||||||
swalFire({ text: getMessage('master.moduletypeitem.message.error'), type: 'alert', icon: 'error' })
|
swalFire({ text: getMessage('master.moduletypeitem.message.error'), type: 'alert', icon: 'error' })
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const param = { roofMatlCd: roofMatlCd }
|
const paramString = `?${paramArr.map((item) => `arrRoofMatlCd=${item}`).join('&')}`
|
||||||
const paramString = getQueryString(param)
|
|
||||||
return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => {
|
return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => {
|
||||||
console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res)
|
console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res)
|
||||||
return res
|
return res
|
||||||
@ -44,11 +43,18 @@ export function useMasterController() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 가대 목록 조회
|
* 가대 목록 조회
|
||||||
* @param
|
* @param {모듈타입코드} moduleTpCd
|
||||||
|
* @param {지붕재코드} roofMatlCd
|
||||||
|
* @param {서까래기초코드} raftBaseCd
|
||||||
|
* @param {가대메이커코드} trestleMkrCd
|
||||||
|
* @param {공법코드} constMthdCd
|
||||||
|
* @param {지붕기초코드} roofBaseCd
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getTrestleList = async (params) => {
|
const getTrestleList = async (params) => {
|
||||||
return await get({ url: `/api/v1/master/getTrestleList/${params}` }).then((res) => {
|
const paramString = getQueryString(params)
|
||||||
|
console.log('🚀🚀 ~ getTrestleList ~ paramString:', paramString)
|
||||||
|
return await get({ url: '/api/v1/master/getTrestleList' + paramString }).then((res) => {
|
||||||
console.log('🚀🚀 ~ getTrestleList ~ res:', res)
|
console.log('🚀🚀 ~ getTrestleList ~ res:', res)
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
@ -56,11 +62,25 @@ export function useMasterController() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 모듈 시공법 목록 조회
|
* 모듈 시공법 목록 조회
|
||||||
* @param
|
* @param {모듈타입코드} moduleTpCd
|
||||||
|
* @param {지붕재코드} roofMatlCd
|
||||||
|
* @param {가대메이커코드} trestleMkrCd
|
||||||
|
* @param {공법코드} constMthdCd
|
||||||
|
* @param {지붕기초코드} roofBaseCd
|
||||||
|
* @param {면조도} illuminationTp
|
||||||
|
* @param {설치높이} instHt
|
||||||
|
* @param {풍속} stdWindSpeed
|
||||||
|
* @param {적설량} stdSnowLd
|
||||||
|
* @param {경사도코드} inclCd
|
||||||
|
* @param {서까래기초코드} raftBaseCd
|
||||||
|
* @param {하제(망둥어)피치} roofPitch
|
||||||
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getConstructionList = async (params) => {
|
const getConstructionList = async (params) => {
|
||||||
return await get({ url: `/api/v1/master/getConstructionList/${params}` }).then((res) => {
|
const paramString = getQueryString(params)
|
||||||
|
console.log('🚀🚀 ~ getConstructionList ~ paramString:', paramString)
|
||||||
|
return await get({ url: '/api/v1/master/getConstructionList' + paramString }).then((res) => {
|
||||||
console.log('🚀🚀 ~ getConstructionList ~ res:', res)
|
console.log('🚀🚀 ~ getConstructionList ~ res:', res)
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
@ -68,11 +88,25 @@ export function useMasterController() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 가대 상세 조회
|
* 가대 상세 조회
|
||||||
* @param
|
* @param {모듈타입코드} moduleTpCd
|
||||||
|
* @param {지붕재코드} roofMatlCd
|
||||||
|
* @param {가대메이커코드} trestleMkrCd
|
||||||
|
* @param {공법코드} constMthdCd
|
||||||
|
* @param {지붕기초코드} roofBaseCd
|
||||||
|
* @param {면조도} illuminationTp
|
||||||
|
* @param {설치높이} instHt
|
||||||
|
* @param {풍속} stdWindSpeed
|
||||||
|
* @param {적설량} stdSnowLd
|
||||||
|
* @param {경사도코드} inclCd
|
||||||
|
* @param {시공법} constTp
|
||||||
|
* @param {혼합모듈번호} mixMatlNo
|
||||||
|
* @param {하제(망둥어)피치}roofPitch
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const getTrestleDetailList = async (params) => {
|
const getTrestleDetailList = async (params) => {
|
||||||
return await get({ url: `/api/v1/master/getTrestleDetailList/${params}` }).then((res) => {
|
const paramString = getQueryString(params)
|
||||||
|
console.log('🚀🚀 ~ getTrestleDetailList ~ paramString:', paramString)
|
||||||
|
return await get({ url: '/api/v1/master/getTrestleDetailList' + paramString }).then((res) => {
|
||||||
console.log('🚀🚀 ~ getTrestleDetailList ~ res:', res)
|
console.log('🚀🚀 ~ getTrestleDetailList ~ res:', res)
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,12 +2,13 @@ import { canvasState } from '@/store/canvasAtom'
|
|||||||
import { allocDisplaySelector, roofDisplaySelector } from '@/store/settingAtom'
|
import { allocDisplaySelector, roofDisplaySelector } from '@/store/settingAtom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useRoof() {
|
export function useRoof() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
const allocDisplay = useRecoilValue(allocDisplaySelector)
|
const allocDisplay = useRecoilValue(allocDisplaySelector)
|
||||||
const roofDisplay = useRecoilValue(roofDisplaySelector)
|
const roofDisplay = useRecoilValue(roofDisplaySelector)
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!canvas) return
|
if (!canvas) return
|
||||||
canvas
|
canvas
|
||||||
@ -23,7 +24,7 @@ export function useRoof() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}, [allocDisplay])
|
}, [allocDisplay])
|
||||||
|
|
||||||
const setSurfaceShapePattern = (polygon, mode = 'onlyBorder') => {
|
/*const setSurfaceShapePattern = (polygon, mode = 'onlyBorder') => {
|
||||||
const ratio = window.devicePixelRatio || 1
|
const ratio = window.devicePixelRatio || 1
|
||||||
|
|
||||||
let width = 265 / 10
|
let width = 265 / 10
|
||||||
@ -145,7 +146,7 @@ export function useRoof() {
|
|||||||
polygon.set('fill', null)
|
polygon.set('fill', null)
|
||||||
polygon.set('fill', pattern)
|
polygon.set('fill', pattern)
|
||||||
polygon.canvas?.renderAll()
|
polygon.canvas?.renderAll()
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|||||||
170
src/hooks/common/useRoofFn.js
Normal file
170
src/hooks/common/useRoofFn.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
|
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
const ROOF_COLOR = {
|
||||||
|
0: 'rgb(199,240,213)',
|
||||||
|
1: 'rgb(178,238,255)',
|
||||||
|
2: 'rgb(187,204,255)',
|
||||||
|
3: 'rgb(228,202,255)',
|
||||||
|
}
|
||||||
|
export function useRoofFn() {
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
|
||||||
|
//면형상 선택 클릭시 지붕 패턴 입히기
|
||||||
|
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial) {
|
||||||
|
const ratio = window.devicePixelRatio || 1
|
||||||
|
const layout = roofMaterial.layout
|
||||||
|
|
||||||
|
let width = (roofMaterial.width ?? 226) / 10
|
||||||
|
let height = (roofMaterial.length ?? 158) / 10
|
||||||
|
const index = roofMaterial.index ?? 0
|
||||||
|
let roofStyle = 2
|
||||||
|
const inputPatternSize = { width: width, height: height } //임시 사이즈
|
||||||
|
const patternSize = { ...inputPatternSize } // 입력된 값을 뒤집기 위해
|
||||||
|
|
||||||
|
if (polygon.direction === 'east' || polygon.direction === 'west') {
|
||||||
|
//세로형이면 width height를 바꿈
|
||||||
|
;[patternSize.width, patternSize.height] = [inputPatternSize.height, patternSize.width]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 패턴 소스를 위한 임시 캔버스 생성
|
||||||
|
const patternSourceCanvas = document.createElement('canvas')
|
||||||
|
patternSourceCanvas.width = polygon.width * ratio
|
||||||
|
patternSourceCanvas.height = polygon.height * ratio
|
||||||
|
const ctx = patternSourceCanvas.getContext('2d')
|
||||||
|
let offset = roofStyle === 1 ? 0 : patternSize.width / 2
|
||||||
|
|
||||||
|
const rows = Math.floor(patternSourceCanvas.height / patternSize.height)
|
||||||
|
const cols = Math.floor(patternSourceCanvas.width / patternSize.width)
|
||||||
|
|
||||||
|
ctx.strokeStyle = mode === 'allPainted' ? 'black' : ROOF_COLOR[index]
|
||||||
|
ctx.lineWidth = 2
|
||||||
|
ctx.fillStyle = mode === 'allPainted' ? 'rgba(0, 159, 64, 0.7)' : 'white'
|
||||||
|
|
||||||
|
if (trestleMode) {
|
||||||
|
ctx.strokeStyle = 'black'
|
||||||
|
ctx.lineWidth = 0.2
|
||||||
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = 'rgba(255, 255, 255, 1)'
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
const yStart = 0
|
||||||
|
const yEnd = patternSourceCanvas.height
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(x, yStart) // 선 시작점
|
||||||
|
ctx.lineTo(x, yEnd) // 선 끝점
|
||||||
|
ctx.stroke()
|
||||||
|
if (mode === 'allPainted' || trestleMode) {
|
||||||
|
ctx.fillRect(x, yStart, patternSize.width, yEnd - yStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let row = 0; row <= rows; row++) {
|
||||||
|
const y = layout === ROOF_MATERIAL_LAYOUT.STAIRS ? row * patternSize.height + (col % 2 === 0 ? 0 : offset) : row * patternSize.height
|
||||||
|
const xStart = col * patternSize.width
|
||||||
|
const xEnd = xStart + patternSize.width
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(xStart, y) // 선 시작점
|
||||||
|
ctx.lineTo(xEnd, y) // 선 끝점
|
||||||
|
ctx.stroke()
|
||||||
|
if (mode === 'allPainted' || trestleMode) {
|
||||||
|
ctx.fillRect(xStart, y, xEnd - xStart, patternSize.height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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()
|
||||||
|
if (mode === 'allPainted' || trestleMode) {
|
||||||
|
ctx.fillRect(0, y, patternSourceCanvas.width, patternSize.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let col = 0; col <= cols; col++) {
|
||||||
|
const x = layout === ROOF_MATERIAL_LAYOUT.STAIRS ? col * patternSize.width + (row % 2 === 0 ? 0 : offset) : col * patternSize.width
|
||||||
|
const yStart = row * patternSize.height
|
||||||
|
const yEnd = yStart + patternSize.height
|
||||||
|
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(x, yStart) // 선 시작점
|
||||||
|
ctx.lineTo(x, yEnd) // 선 끝점
|
||||||
|
ctx.stroke()
|
||||||
|
if (mode === 'allPainted' || trestleMode) {
|
||||||
|
ctx.fillRect(x, yStart, patternSize.width, yEnd - yStart)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hachingPatternSourceCanvas = document.createElement('canvas')
|
||||||
|
|
||||||
|
if (mode === 'lineHatch') {
|
||||||
|
hachingPatternSourceCanvas.width = polygon.width * ratio
|
||||||
|
hachingPatternSourceCanvas.height = polygon.height * ratio
|
||||||
|
|
||||||
|
const ctx1 = hachingPatternSourceCanvas.getContext('2d')
|
||||||
|
|
||||||
|
const gap = 10
|
||||||
|
|
||||||
|
ctx1.strokeStyle = 'green' // 선 색상
|
||||||
|
ctx1.lineWidth = 0.3 // 선 두께
|
||||||
|
|
||||||
|
for (let x = 0; x < hachingPatternSourceCanvas.width + hachingPatternSourceCanvas.height; x += gap) {
|
||||||
|
ctx1.beginPath()
|
||||||
|
ctx1.moveTo(x, 0) // 선 시작점
|
||||||
|
ctx1.lineTo(0, x) // 선 끝점
|
||||||
|
ctx1.stroke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const combinedPatternCanvas = document.createElement('canvas')
|
||||||
|
combinedPatternCanvas.width = polygon.width * ratio
|
||||||
|
combinedPatternCanvas.height = polygon.height * ratio
|
||||||
|
const combinedCtx = combinedPatternCanvas.getContext('2d')
|
||||||
|
|
||||||
|
// 첫 번째 패턴을 그린 후 두 번째 패턴을 덧입힘
|
||||||
|
combinedCtx.drawImage(patternSourceCanvas, 0, 0)
|
||||||
|
combinedCtx.drawImage(hachingPatternSourceCanvas, 0, 0)
|
||||||
|
|
||||||
|
// 패턴 생성
|
||||||
|
const pattern = new fabric.Pattern({
|
||||||
|
source: combinedPatternCanvas,
|
||||||
|
repeat: 'repeat',
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.set('fill', null)
|
||||||
|
polygon.set('fill', pattern)
|
||||||
|
polygon.roofMaterial = roofMaterial
|
||||||
|
polygon.canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeRoofMaterial(roof = currentObject) {
|
||||||
|
if (roof === null || roof.name !== POLYGON_TYPE.ROOF) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
roof.set('fill', null)
|
||||||
|
roof.roofMaterial = null
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAllRoofMaterial() {
|
||||||
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
roofBases.forEach((roofBase) => {
|
||||||
|
removeRoofMaterial(roofBase)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial }
|
||||||
|
}
|
||||||
940
src/hooks/module/useModule.js
Normal file
940
src/hooks/module/useModule.js
Normal file
@ -0,0 +1,940 @@
|
|||||||
|
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
|
||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import * as turf from '@turf/turf'
|
||||||
|
import { useSwal } from '../useSwal'
|
||||||
|
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
||||||
|
import { useMessage } from '../useMessage'
|
||||||
|
|
||||||
|
export const MODULE_REMOVE_TYPE = {
|
||||||
|
LEFT: 'left',
|
||||||
|
RIGHT: 'right',
|
||||||
|
HORIZONTAL_SIDE: 'horizontalSide',
|
||||||
|
TOP: 'top',
|
||||||
|
BOTTOM: 'bottom',
|
||||||
|
VERTICAL_SIDE: 'verticalSide',
|
||||||
|
NONE: 'none',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MODULE_INSERT_TYPE = {
|
||||||
|
LEFT: 'left',
|
||||||
|
RIGHT: 'right',
|
||||||
|
TOP: 'up',
|
||||||
|
BOTTOM: 'down',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MODULE_ALIGN_TYPE = {
|
||||||
|
VERTICAL: 'vertical',
|
||||||
|
HORIZONTAL: 'horizontal',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useModule() {
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { swalFire } = useSwal()
|
||||||
|
const { getMessage } = useMessage()
|
||||||
|
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
||||||
|
|
||||||
|
const moduleMove = (length, direction) => {
|
||||||
|
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||||
|
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||||
|
|
||||||
|
canvas.discardActiveObject() //선택해제
|
||||||
|
|
||||||
|
const isSetupModules = getOtherModules(selectedObj)
|
||||||
|
const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
|
||||||
|
const setupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
const objects = getObjects()
|
||||||
|
|
||||||
|
if (selectedModules) {
|
||||||
|
selectedModules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, false)
|
||||||
|
module.originCoords = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
module.set({ top, left })
|
||||||
|
module.setCoords()
|
||||||
|
|
||||||
|
if (isOverlapOtherModules(module, isSetupModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, setupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.move.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
selectedModules.forEach((module) => {
|
||||||
|
module.set({ left: module.originCoords.left, top: module.originCoords.top, fill: module.originCoords.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const moduleMultiMove = (type, length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
if (canvas.getActiveObjects().length > 1) {
|
||||||
|
swalFire({
|
||||||
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(modules)
|
||||||
|
const objects = getObjects()
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, false)
|
||||||
|
module.originPos = {
|
||||||
|
top: module.top,
|
||||||
|
left: module.left,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.set({ top, left })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (otherModules.length > 0) {
|
||||||
|
if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.move.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
modules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleMoveAll = (length, direction) => {
|
||||||
|
const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const objects = getObjects()
|
||||||
|
|
||||||
|
let isWarning = false
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, false)
|
||||||
|
module.originPos = {
|
||||||
|
top: module.top,
|
||||||
|
left: module.left,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.set({ top, left })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.move.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
modules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleCopyAll = (length, direction) => {
|
||||||
|
const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
let copyModule = null
|
||||||
|
let isWarning = false
|
||||||
|
let moduleLength = 0
|
||||||
|
if (['up', 'down'].includes(direction)) {
|
||||||
|
modules.sort((a, b) => a.top - b.top)
|
||||||
|
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
||||||
|
} else if (['left', 'right'].includes(direction)) {
|
||||||
|
modules.sort((a, b) => a.left - b.left)
|
||||||
|
moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
|
||||||
|
}
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
||||||
|
module.clone((obj) => {
|
||||||
|
obj.set({
|
||||||
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
|
if (isOverlapObjects(copyModule, objects) || isOutsideSurface(copyModule, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
copyModule.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.copy.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleCopy = (length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
||||||
|
const modules = canvas.getObjects().filter((obj) => activeModuleIds.includes(obj.id))
|
||||||
|
const objects = getObjects()
|
||||||
|
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
let copyModules = []
|
||||||
|
let copyModule = null
|
||||||
|
canvas.discardActiveObject() //선택해제
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, true)
|
||||||
|
module.clone((obj) => {
|
||||||
|
obj.set({
|
||||||
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModules.push(obj)
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
copyModule.set({ fill: 'red' })
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.copy.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleMultiCopy = (type, length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
if (canvas.getActiveObjects().length > 1) {
|
||||||
|
swalFire({
|
||||||
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||||
|
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
let copyModule = null
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
let moduleLength = 0
|
||||||
|
if (['up', 'down'].includes(direction)) {
|
||||||
|
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
||||||
|
} else if (['left', 'right'].includes(direction)) {
|
||||||
|
moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
|
||||||
|
}
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
||||||
|
module.clone((obj) => {
|
||||||
|
obj.set({
|
||||||
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
copyModule.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.copy.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleColumnRemove = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const columnModules = getColumnModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(columnModules)
|
||||||
|
const objects = getObjects()
|
||||||
|
let targetModules = []
|
||||||
|
const rightModules = otherModules.filter((module) => activeModule.left < module.left).sort((a, b) => a.left - b.left)
|
||||||
|
const leftModules = otherModules.filter((module) => activeModule.left > module.left).sort((a, b) => b.left - a.left)
|
||||||
|
let width = -1
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
canvas.remove(...columnModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (type === MODULE_REMOVE_TYPE.LEFT) {
|
||||||
|
rightModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (width === -1) width = module.left - activeModule.left
|
||||||
|
module.set({ left: module.left - width })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isOverlapOtherModules(module, leftModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
isWarning = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
targetModules = rightModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
||||||
|
leftModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (width === -1) width = activeModule.left - module.left
|
||||||
|
module.set({ left: module.left + width })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isOverlapOtherModules(module, rightModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
isWarning = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
targetModules = leftModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
||||||
|
const sideModules = [...leftModules, ...rightModules]
|
||||||
|
leftModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (width === -1) width = activeModule.left - module.left
|
||||||
|
module.set({ left: module.left + width / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
rightModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (width === -1) width = module.left - activeModule.left
|
||||||
|
module.set({ left: module.left - width / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
sideModules.forEach((module) => {
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(
|
||||||
|
module,
|
||||||
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
|
) ||
|
||||||
|
isOverlapObjects(module, objects) ||
|
||||||
|
isOutsideSurface(module, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
targetModules = sideModules
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.remove.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.add(...columnModules)
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleRowRemove = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const rowModules = getRowModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(rowModules)
|
||||||
|
const objects = getObjects()
|
||||||
|
let targetModules = []
|
||||||
|
const topModules = otherModules.filter((module) => activeModule.top > module.top).sort((a, b) => b.top - a.top)
|
||||||
|
const bottomModules = otherModules.filter((module) => activeModule.top < module.top).sort((a, b) => a.top - b.top)
|
||||||
|
let height = -1
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let isWarning = false
|
||||||
|
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
canvas.remove(...rowModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (type === MODULE_REMOVE_TYPE.TOP) {
|
||||||
|
bottomModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (height === -1) height = module.top - activeModule.top
|
||||||
|
module.set({ top: module.top - height })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isOverlapOtherModules(module, topModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
targetModules = bottomModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
||||||
|
topModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (height === -1) height = activeModule.top - module.top
|
||||||
|
module.set({ top: module.top + activeModule.height })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isOverlapOtherModules(module, bottomModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
targetModules = topModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
||||||
|
topModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
// if (height === -1) height = activeModule.top - module.top
|
||||||
|
if (height === -1) height = activeModule.height
|
||||||
|
module.set({ top: module.top + height / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
|
||||||
|
bottomModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
// if (height === -1) height = module.top - activeModule.top
|
||||||
|
if (height === -1) height = activeModule.height
|
||||||
|
module.set({ top: module.top - height / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
|
const sideModules = [...topModules, ...bottomModules]
|
||||||
|
sideModules.forEach((module) => {
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(
|
||||||
|
module,
|
||||||
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
|
) ||
|
||||||
|
isOverlapObjects(module, objects) ||
|
||||||
|
isOutsideSurface(module, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
targetModules = sideModules
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
||||||
|
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.remove.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.add(...rowModules)
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleColumnInsert = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const columnModules = getColumnModules(activeModule)
|
||||||
|
let otherModules = getOtherModules(columnModules)
|
||||||
|
const targetModules =
|
||||||
|
type === MODULE_INSERT_TYPE.LEFT
|
||||||
|
? otherModules.filter((module) => module.left < activeModule.left).sort((a, b) => a.left - b.left)
|
||||||
|
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => a.left - b.left)
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let width = -1
|
||||||
|
let isWarning = false
|
||||||
|
if (targetModules.length === 0) {
|
||||||
|
swalFire({
|
||||||
|
title: '마지막 모듈입니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
if (width === -1)
|
||||||
|
width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left)
|
||||||
|
const { top, left } = getPosotion(module, type, module.width, false)
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
module.set({ left, top })
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
otherModules = getOtherModules(columnModules)
|
||||||
|
columnModules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, type, module.width, false)
|
||||||
|
let copyModule = null
|
||||||
|
module.clone((obj) => {
|
||||||
|
obj.set({
|
||||||
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
}
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.insert.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const muduleRowInsert = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const rowModules = getRowModules(activeModule)
|
||||||
|
let otherModules = getOtherModules(rowModules)
|
||||||
|
const targetModules =
|
||||||
|
type === MODULE_INSERT_TYPE.TOP
|
||||||
|
? otherModules.filter((module) => module.top < activeModule.top).sort((a, b) => a.top - b.top)
|
||||||
|
: otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
|
||||||
|
if (targetModules.length === 0) {
|
||||||
|
swalFire({
|
||||||
|
title: '마지막 모듈입니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let height = -1
|
||||||
|
let isWarning = false
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
if (height === -1)
|
||||||
|
height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top)
|
||||||
|
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
module.set({ left, top })
|
||||||
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
otherModules = getOtherModules(rowModules)
|
||||||
|
rowModules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||||
|
let copyModule = null
|
||||||
|
module.clone((obj) => {
|
||||||
|
obj.set({
|
||||||
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
fill: module.fill,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
copyModule.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.insert.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const alignModule = (type) => {
|
||||||
|
const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const objects = getObjects()
|
||||||
|
let [top, bottom, left, right] = [0, 0, 0, 0]
|
||||||
|
|
||||||
|
top = Math.min(...modules.map((module) => module.top))
|
||||||
|
bottom = Math.max(...modules.map((module) => module.top + module.height))
|
||||||
|
left = Math.min(...modules.map((module) => module.left))
|
||||||
|
right = Math.max(...modules.map((module) => module.left + module.width))
|
||||||
|
const moduleSurfacePos = {
|
||||||
|
top: Math.min(...moduleSetupSurface.points.map((point) => point.y)),
|
||||||
|
left: Math.min(...moduleSetupSurface.points.map((point) => point.x)),
|
||||||
|
}
|
||||||
|
const [height, width] = [bottom - top, right - left]
|
||||||
|
const verticalCenterLength = moduleSurfacePos.top + moduleSetupSurface.height / 2 - (top + height / 2)
|
||||||
|
const horizontalCenterLength = moduleSurfacePos.left + moduleSetupSurface.width / 2 - (left + width / 2)
|
||||||
|
let isWarning = false
|
||||||
|
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
modules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
|
}
|
||||||
|
if (type === MODULE_ALIGN_TYPE.VERTICAL) {
|
||||||
|
module.set({ top: module.top + verticalCenterLength })
|
||||||
|
} else if (type === MODULE_ALIGN_TYPE.HORIZONTAL) {
|
||||||
|
module.set({ left: module.left + horizontalCenterLength })
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
|
module.setCoords()
|
||||||
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.align.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
modules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const modulesRemove = () => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.surfaceId === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
canvas.remove(...modules)
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOverlapOtherModules = (module, otherModules) => {
|
||||||
|
return otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOverlapObjects = (module, objects) => {
|
||||||
|
return !checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOutsideSurface = (module, moduleSetupSurface) => {
|
||||||
|
return (
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRowModules = (target) => {
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.top === target.top)
|
||||||
|
.sort((a, b) => a.left - b.left)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColumnModules = (target) => {
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.left === target.left)
|
||||||
|
.sort((a, b) => a.top - b.top)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPosotion = (target, direction, length, hasMargin = false) => {
|
||||||
|
let top = target.top
|
||||||
|
let left = target.left
|
||||||
|
|
||||||
|
if (direction === 'up') {
|
||||||
|
top = Number(target.top) - Number(length)
|
||||||
|
top = hasMargin ? top - Number(target.height) : top
|
||||||
|
} else if (direction === 'down') {
|
||||||
|
top = Number(target.top) + Number(length)
|
||||||
|
top = hasMargin ? top + Number(target.height) : top
|
||||||
|
} else if (direction === 'left') {
|
||||||
|
left = Number(target.left) - Number(length)
|
||||||
|
left = hasMargin ? left - Number(target.width) : left
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
left = Number(target.left) + Number(length)
|
||||||
|
left = hasMargin ? left + Number(target.width) : left
|
||||||
|
}
|
||||||
|
return { top, left }
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOtherModules = (modules) => {
|
||||||
|
const moduleIds = modules.map((module) => module.id)
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE && !moduleIds.includes(obj.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
const getObjects = () => {
|
||||||
|
return canvas
|
||||||
|
?.getObjects()
|
||||||
|
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
moduleMove,
|
||||||
|
moduleMultiMove,
|
||||||
|
moduleMoveAll,
|
||||||
|
moduleCopy,
|
||||||
|
moduleMultiCopy,
|
||||||
|
moduleCopyAll,
|
||||||
|
moduleColumnRemove,
|
||||||
|
moduleRowRemove,
|
||||||
|
moduleColumnInsert,
|
||||||
|
muduleRowInsert,
|
||||||
|
modulesRemove,
|
||||||
|
alignModule,
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -5,13 +5,14 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { BATCH_TYPE, INPUT_TYPE } from '@/common/common'
|
import { BATCH_TYPE, INPUT_TYPE } from '@/common/common'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, setSurfaceShapePattern, triangleToPolygon } from '@/util/canvas-util'
|
import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon } from '@/util/canvas-util'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useObjectBatch({ isHidden, setIsHidden }) {
|
export function useObjectBatch({ isHidden, setIsHidden }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -20,6 +21,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
|
|||||||
// const { addCanvasMouseEventListener, initEvent, addDocumentEventListener } = useContext(EventContext)
|
// const { addCanvasMouseEventListener, initEvent, addDocumentEventListener } = useContext(EventContext)
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { drawDirectionArrow } = usePolygon()
|
const { drawDirectionArrow } = usePolygon()
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useEffect, useState, useRef } from 'react'
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import {
|
import {
|
||||||
adsorptionPointModeState,
|
adsorptionPointModeState,
|
||||||
@ -19,8 +19,9 @@ import {
|
|||||||
settingModalSecondOptionsState,
|
settingModalSecondOptionsState,
|
||||||
settingModalGridOptionsState,
|
settingModalGridOptionsState,
|
||||||
basicSettingState,
|
basicSettingState,
|
||||||
settingsState,
|
|
||||||
roofMaterialsAtom,
|
roofMaterialsAtom,
|
||||||
|
selectedRoofMaterialSelector,
|
||||||
|
addedRoofsState,
|
||||||
} from '@/store/settingAtom'
|
} from '@/store/settingAtom'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { globalFontAtom } from '@/store/fontAtom'
|
import { globalFontAtom } from '@/store/fontAtom'
|
||||||
@ -28,6 +29,7 @@ import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
|
|||||||
import { gridColorState } from '@/store/gridAtom'
|
import { gridColorState } from '@/store/gridAtom'
|
||||||
import { useColor } from 'react-color-palette'
|
import { useColor } from 'react-color-palette'
|
||||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
|
||||||
const defaultDotLineGridSetting = {
|
const defaultDotLineGridSetting = {
|
||||||
INTERVAL: {
|
INTERVAL: {
|
||||||
@ -41,6 +43,8 @@ const defaultDotLineGridSetting = {
|
|||||||
LINE: false,
|
LINE: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previousRoofMaterialsYn = 'N'; // 지붕재 select 정보 비교 후 변경된 것이 없으면 1회만 실행
|
||||||
|
|
||||||
export function useCanvasSetting() {
|
export function useCanvasSetting() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
// canvas가 null이 아닐 때에만 getObjects 호출
|
// canvas가 null이 아닐 때에만 getObjects 호출
|
||||||
@ -92,8 +96,9 @@ export function useCanvasSetting() {
|
|||||||
|
|
||||||
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
||||||
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
||||||
const { getRoofMaterialList } = useMasterController()
|
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
|
||||||
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
||||||
|
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
|
||||||
|
|
||||||
const SelectOptions = [
|
const SelectOptions = [
|
||||||
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
|
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
|
||||||
@ -102,15 +107,62 @@ export function useCanvasSetting() {
|
|||||||
{ id: 4, name: '1/10', value: 1 / 10 },
|
{ id: 4, name: '1/10', value: 1 / 10 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (roofMaterials.length !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
addRoofMaterials()
|
addRoofMaterials()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
//지붕재 초기세팅
|
||||||
const addRoofMaterials = async () => {
|
const addRoofMaterials = async () => {
|
||||||
|
if (roofMaterials.length !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const { data } = await getRoofMaterialList()
|
const { data } = await getRoofMaterialList()
|
||||||
setRoofMaterials(data)
|
|
||||||
|
const roofLists = data.map((item, idx) => ({
|
||||||
|
...item,
|
||||||
|
id: item.roofMatlCd,
|
||||||
|
name: item.roofMatlNm,
|
||||||
|
selected: idx === 0,
|
||||||
|
index: idx,
|
||||||
|
nameJp: item.roofMatlNmJp,
|
||||||
|
length: item.lenBase && parseInt(item.lenBase),
|
||||||
|
width: item.widBase && parseInt(item.widBase),
|
||||||
|
raft: item.raftBase && parseInt(item.raftBase),
|
||||||
|
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
|
||||||
|
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
|
||||||
|
}))
|
||||||
|
setRoofMaterials(roofLists)
|
||||||
|
const selectedRoofMaterial = roofLists[0]
|
||||||
|
|
||||||
|
if (addedRoofs.length === 0) {
|
||||||
|
const newAddedRoofs = []
|
||||||
|
newAddedRoofs.push({ ...selectedRoofMaterial, selected: true, index: 0 })
|
||||||
|
setAddedRoofs(newAddedRoofs)
|
||||||
|
}
|
||||||
|
setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const previousRoofMaterialsRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// 지붕재 select 정보가 존재해야 배치면초기설정 DB 정보 비교 후 지붕재 정보를 가져올 수 있음
|
||||||
|
if (roofMaterials.length !== 0 && JSON.stringify(previousRoofMaterialsRef.current) !== JSON.stringify(roofMaterials)) {
|
||||||
|
// 지붕재 select 정보 비교 후 변경된 것이 없으면 1회만 실행
|
||||||
|
if (roofMaterials && previousRoofMaterialsYn === 'N') {
|
||||||
|
fetchBasicSettings();
|
||||||
|
previousRoofMaterialsYn = 'Y';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 이전 값을 업데이트
|
||||||
|
previousRoofMaterialsRef.current = roofMaterials;
|
||||||
|
}
|
||||||
|
}, [roofMaterials]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
return
|
return
|
||||||
@ -141,14 +193,6 @@ export function useCanvasSetting() {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}, [corridorDimension])
|
}, [corridorDimension])
|
||||||
|
|
||||||
// 배치면 초기설정 변경 시
|
|
||||||
useEffect(() => {
|
|
||||||
//console.log('useCanvasSetting canvasSetting 실행', canvasSetting)
|
|
||||||
if (canvasSetting.flag) {
|
|
||||||
basicSettingSave()
|
|
||||||
}
|
|
||||||
}, [canvasSetting])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('🚀 ~ useEffect ~ settingsDataSave:', settingsDataSave)
|
console.log('🚀 ~ useEffect ~ settingsDataSave:', settingsDataSave)
|
||||||
if (settingsDataSave !== undefined) onClickOption2()
|
if (settingsDataSave !== undefined) onClickOption2()
|
||||||
@ -228,59 +272,82 @@ export function useCanvasSetting() {
|
|||||||
// 기본설정(PlacementShapeSetting) 조회 및 초기화
|
// 기본설정(PlacementShapeSetting) 조회 및 초기화
|
||||||
const fetchBasicSettings = async () => {
|
const fetchBasicSettings = async () => {
|
||||||
try {
|
try {
|
||||||
await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => {
|
await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/0/${correntObjectNo}` }).then((res) => {
|
||||||
console.log('fetchBasicSettings res ', res)
|
|
||||||
if (res.length == 0) return
|
|
||||||
|
|
||||||
// 'roofs' 배열을 생성하여 각 항목을 추가
|
let roofsRow = {}
|
||||||
const roofsRow = res.map((item) => {
|
let roofsArray = {}
|
||||||
return {
|
|
||||||
roofSizeSet: item.roofSizeSet,
|
|
||||||
roofAngleSet: item.roofAngleSet,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const roofsArray = res.some((item) => !item.roofSeq)
|
if (res.length > 0) {
|
||||||
? //최초 지붕재 추가 정보의 경우 roofsArray를 초기화 설정
|
roofsRow = res.map((item) => {
|
||||||
res.map(() => ({
|
return {
|
||||||
flag: false,
|
roofSizeSet: item.roofSizeSet,
|
||||||
|
roofAngleSet: item.roofAngleSet,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
roofsArray = res.map((item) => {
|
||||||
|
return {
|
||||||
roofApply: true,
|
roofApply: true,
|
||||||
roofSeq: 1,
|
roofSeq: 1,
|
||||||
roofType: 1,
|
roofMatlCd: item.roofMatlCd,
|
||||||
roofWidth: 265,
|
|
||||||
roofHeight: 235,
|
|
||||||
roofHajebichi: 0,
|
|
||||||
roofGap: 455,
|
|
||||||
// roofType: 1,
|
|
||||||
// roofWidth: 200,
|
|
||||||
// roofHeight: 200,
|
|
||||||
// roofHajebichi: 200,
|
|
||||||
// roofGap: 0,
|
|
||||||
roofLayout: 'parallel',
|
|
||||||
}))
|
|
||||||
: res.map((item) => ({
|
|
||||||
flag: false,
|
|
||||||
roofApply: item.roofApply === '' || item.roofApply === false ? false : true,
|
|
||||||
roofSeq: item.roofSeq,
|
|
||||||
roofType: item.roofType,
|
|
||||||
roofWidth: item.roofWidth,
|
roofWidth: item.roofWidth,
|
||||||
roofHeight: item.roofHeight,
|
roofHeight: item.roofHeight,
|
||||||
roofHajebichi: item.roofHajebichi,
|
roofHajebichi: item.roofHajebichi,
|
||||||
roofGap: item.roofGap,
|
roofGap: item.roofGap,
|
||||||
roofLayout: item.roofLayout,
|
roofLayout: item.roofLayout,
|
||||||
}))
|
}
|
||||||
console.log('roofsArray ', roofsArray)
|
})
|
||||||
|
} else {
|
||||||
|
roofsRow = [
|
||||||
|
{
|
||||||
|
roofSizeSet: 1,
|
||||||
|
roofAngleSet: 'slope',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
roofsArray = [
|
||||||
|
{
|
||||||
|
roofApply: true,
|
||||||
|
roofSeq: 1,
|
||||||
|
roofMatlCd: 'ROOF_ID_WA_53A',
|
||||||
|
roofWidth: 265,
|
||||||
|
roofHeight: 235,
|
||||||
|
roofHajebichi: 0,
|
||||||
|
roofGap: 'HEI_455',
|
||||||
|
roofLayout: 'P',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음
|
// 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음
|
||||||
const patternData = {
|
const patternData = {
|
||||||
roofSizeSet: roofsRow[0].roofSizeSet, // 첫 번째 항목의 값을 사용
|
roofSizeSet: roofsRow[0].roofSizeSet,
|
||||||
roofAngleSet: roofsRow[0].roofAngleSet, // 첫 번째 항목의 값을 사용
|
roofAngleSet: roofsRow[0].roofAngleSet,
|
||||||
roofs: roofsArray, // 만들어진 roofs 배열
|
roofs: roofsArray, // 만들어진 roofs 배열
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.error('patternData', patternData)
|
//console.log('fetchBasicSettings patternData', patternData)
|
||||||
|
|
||||||
// 데이터 설정
|
// 데이터 설정
|
||||||
setBasicSettings({ ...patternData })
|
const addRoofs = []
|
||||||
|
roofMaterials?.map((material) => {
|
||||||
|
if (material.roofMatlCd === roofsArray[0].roofMatlCd) {
|
||||||
|
addRoofs.push({ ...material, selected: true
|
||||||
|
, index: 0
|
||||||
|
, width: roofsArray[0].roofWidth
|
||||||
|
, length: roofsArray[0].roofHeight
|
||||||
|
, hajebichi: roofsArray[0].roofHajebichi
|
||||||
|
, raft: roofsArray[0].roofGap
|
||||||
|
, layout: roofsArray[0].roofLayout
|
||||||
|
})
|
||||||
|
|
||||||
|
setAddedRoofs(addRoofs)
|
||||||
|
setBasicSettings({ ...basicSetting, roofMaterials: addRoofs[0]
|
||||||
|
, roofSizeSet: roofsRow[0].roofSizeSet
|
||||||
|
, roofAngleSet: roofsRow[0].roofAngleSet
|
||||||
|
, roofsData: roofsArray
|
||||||
|
, selectedRoofMaterial: addRoofs[0] })
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Data fetching error:', error)
|
console.error('Data fetching error:', error)
|
||||||
@ -299,15 +366,29 @@ export function useCanvasSetting() {
|
|||||||
objectNo: correntObjectNo,
|
objectNo: correntObjectNo,
|
||||||
roofSizeSet: basicSetting.roofSizeSet,
|
roofSizeSet: basicSetting.roofSizeSet,
|
||||||
roofAngleSet: basicSetting.roofAngleSet,
|
roofAngleSet: basicSetting.roofAngleSet,
|
||||||
roofMaterialsAddList: basicSetting.roofs, // TODO : 선택된 roof로 변경해야함
|
roofMaterialsAddList: [
|
||||||
|
{
|
||||||
|
roofApply: true,
|
||||||
|
roofSeq: 0,
|
||||||
|
roofMatlCd: basicSetting.roofsData.roofMatlCd === null || basicSetting.roofsData.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : basicSetting.roofsData.roofMatlCd,
|
||||||
|
roofWidth: basicSetting.roofsData.roofWidth === null || basicSetting.roofsData.roofWidth === undefined ? 0 : basicSetting.roofsData.roofWidth,
|
||||||
|
roofHeight: basicSetting.roofsData.roofHeight === null || basicSetting.roofsData.roofHeight === undefined ? 0 : basicSetting.roofsData.roofHeight,
|
||||||
|
roofHajebichi: basicSetting.roofsData.roofHajebichi === null || basicSetting.roofsData.roofHajebichi === undefined ? 0 : basicSetting.roofsData.roofHajebichi,
|
||||||
|
roofGap: basicSetting.roofsData.roofGap === null || basicSetting.roofsData.roofGap === undefined ? 'HEI_455' : basicSetting.roofsData.roofGap,
|
||||||
|
roofLayout: basicSetting.roofsData.roofLayout === null || basicSetting.roofsData.roofLayout === undefined ? 'P' : basicSetting.roofsData.roofLayout,
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('basicSettingSave patternData ', patternData)
|
||||||
|
|
||||||
await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => {
|
await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => {
|
||||||
swalFire({ text: getMessage(res.returnMessage) })
|
swalFire({ text: getMessage(res.returnMessage) })
|
||||||
})
|
})
|
||||||
|
|
||||||
//Recoil 설정
|
//Recoil 설정
|
||||||
setCanvasSetting({ ...basicSetting, flag: false })
|
setCanvasSetting({ ...basicSetting })
|
||||||
|
fetchBasicSettings()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
|
swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
|
||||||
}
|
}
|
||||||
@ -681,11 +762,12 @@ export function useCanvasSetting() {
|
|||||||
setCanvasSetting,
|
setCanvasSetting,
|
||||||
basicSetting,
|
basicSetting,
|
||||||
setBasicSettings,
|
setBasicSettings,
|
||||||
fetchBasicSettings,
|
|
||||||
basicSettingSave,
|
basicSettingSave,
|
||||||
settingsData,
|
settingsData,
|
||||||
setSettingsData,
|
setSettingsData,
|
||||||
settingsDataSave,
|
settingsDataSave,
|
||||||
setSettingsDataSave,
|
setSettingsDataSave,
|
||||||
|
addedRoofs,
|
||||||
|
setAddedRoofs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
import { addedRoofsState, basicSettingState, roofDisplaySelector, roofMaterialsSelector, selectedRoofMaterialSelector } from '@/store/settingAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
@ -13,6 +12,8 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import useMenu from '@/hooks/common/useMenu'
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import { menuTypeState } from '@/store/menuAtom'
|
import { menuTypeState } from '@/store/menuAtom'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
|
||||||
// 지붕면 할당
|
// 지붕면 할당
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
@ -26,69 +27,15 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { setMenuNumber } = useCanvasMenu()
|
const { setMenuNumber } = useCanvasMenu()
|
||||||
const setMenuType = useSetRecoilState(menuTypeState)
|
const setMenuType = useSetRecoilState(menuTypeState)
|
||||||
const roofMaterials = [
|
const roofMaterials = useRecoilValue(roofMaterialsSelector)
|
||||||
{
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
id: 'A',
|
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
|
||||||
name: '기와1',
|
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재
|
||||||
type: 'A',
|
const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열
|
||||||
width: '200',
|
|
||||||
length: '200',
|
|
||||||
alignType: 'parallel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'B',
|
|
||||||
name: '기와2',
|
|
||||||
type: 'B',
|
|
||||||
rafter: '200',
|
|
||||||
alignType: 'parallel',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'C',
|
|
||||||
name: '기와3',
|
|
||||||
type: 'C',
|
|
||||||
hajebichi: '200',
|
|
||||||
alignType: 'stairs',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'D',
|
|
||||||
name: '기와4',
|
|
||||||
type: 'D',
|
|
||||||
length: '200',
|
|
||||||
alignType: 'stairs',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const widths = [
|
|
||||||
{ name: '200', id: 'q' },
|
|
||||||
{ name: '250', id: 'q1' },
|
|
||||||
{ name: '300', id: 'q2' },
|
|
||||||
]
|
|
||||||
const lengths = [
|
|
||||||
{ name: '200', id: 'w' },
|
|
||||||
{ name: '250', id: 'w1' },
|
|
||||||
{ name: '300', id: 'w2' },
|
|
||||||
]
|
|
||||||
const rafters = [
|
|
||||||
{ name: '200', id: 'e' },
|
|
||||||
{ name: '250', id: 'e1' },
|
|
||||||
{ name: '300', id: 'e2' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const [values, setValues] = useState([
|
|
||||||
{
|
|
||||||
id: 'A',
|
|
||||||
type: 'A',
|
|
||||||
roofMaterial: { name: '기와1' },
|
|
||||||
width: { name: '200' },
|
|
||||||
length: { name: '250' },
|
|
||||||
rafter: { name: '300' },
|
|
||||||
alignType: 'stairs',
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const [radioValue, setRadioValue] = useState('A')
|
|
||||||
const [editingLines, setEditingLines] = useState([])
|
const [editingLines, setEditingLines] = useState([])
|
||||||
|
const [currentRoofList, setCurrentRoofList] = useState(roofList)
|
||||||
|
|
||||||
const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(roofMaterials[0])
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines
|
||||||
@ -130,16 +77,31 @@ export function useRoofAllocationSetting(id) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onAddRoofMaterial = () => {
|
const onAddRoofMaterial = () => {
|
||||||
setValues([...values, selectedRoofMaterial])
|
if (currentRoofList.length >= 4) {
|
||||||
|
swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setCurrentRoofList([
|
||||||
|
...currentRoofList,
|
||||||
|
{
|
||||||
|
...currentRoofMaterial,
|
||||||
|
selected: false,
|
||||||
|
id: currentRoofMaterial.roofMatlCd,
|
||||||
|
name: currentRoofMaterial.roofMatlNm,
|
||||||
|
index: currentRoofList.length,
|
||||||
|
},
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDeleteRoofMaterial = (id) => {
|
const onDeleteRoofMaterial = (idx) => {
|
||||||
setValues(values.filter((value) => value.id !== id))
|
const isSelected = currentRoofList[idx].selected
|
||||||
|
const newRoofList = [...currentRoofList].filter((_, index) => index !== idx)
|
||||||
|
if (isSelected) {
|
||||||
|
newRoofList[0].selected = true
|
||||||
|
}
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { handleMenu } = useMenu()
|
|
||||||
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
|
||||||
|
|
||||||
// 선택한 지붕재로 할당
|
// 선택한 지붕재로 할당
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
||||||
@ -150,6 +112,24 @@ export function useRoofAllocationSetting(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
||||||
|
const handleSaveContext = () => {
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
return { ...roof, index: idx }
|
||||||
|
})
|
||||||
|
setBasicSetting((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
selectedRoofMaterial: newRoofList.find((roof) => roof.selected),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setRoofList(newRoofList)
|
||||||
|
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
|
||||||
|
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
|
||||||
|
closeAll()
|
||||||
|
}
|
||||||
|
|
||||||
const handleAlloc = () => {
|
const handleAlloc = () => {
|
||||||
if (!checkInnerLines()) {
|
if (!checkInnerLines()) {
|
||||||
apply()
|
apply()
|
||||||
@ -167,16 +147,18 @@ export function useRoofAllocationSetting(id) {
|
|||||||
let result = false
|
let result = false
|
||||||
|
|
||||||
roofBases.forEach((roof) => {
|
roofBases.forEach((roof) => {
|
||||||
roof.innerLines.forEach((line) => {
|
if (roof.separatePolygon.length === 0) {
|
||||||
if (!line.attributes.actualSize || line.attributes?.actualSize === 0) {
|
roof.innerLines.forEach((line) => {
|
||||||
line.set({
|
if (!line.attributes.actualSize || line.attributes?.actualSize === 0) {
|
||||||
strokeWidth: 4,
|
line.set({
|
||||||
stroke: 'black',
|
strokeWidth: 4,
|
||||||
selectable: true,
|
stroke: 'black',
|
||||||
})
|
selectable: true,
|
||||||
result = true
|
})
|
||||||
}
|
result = true
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
if (result) canvas?.renderAll()
|
if (result) canvas?.renderAll()
|
||||||
|
|
||||||
@ -184,7 +166,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const apply = () => {
|
const apply = () => {
|
||||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
try {
|
try {
|
||||||
@ -207,6 +189,19 @@ export function useRoofAllocationSetting(id) {
|
|||||||
canvas.remove(wallLine)
|
canvas.remove(wallLine)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
return { ...roof, index: idx }
|
||||||
|
})
|
||||||
|
|
||||||
|
setBasicSetting((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
selectedRoofMaterial: newRoofList.find((roof) => roof.selected),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setRoofList(newRoofList)
|
||||||
|
|
||||||
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
|
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
|
||||||
|
|
||||||
roofs.forEach((roof) => {
|
roofs.forEach((roof) => {
|
||||||
@ -214,7 +209,12 @@ export function useRoofAllocationSetting(id) {
|
|||||||
roof.set({
|
roof.set({
|
||||||
isFixed: true,
|
isFixed: true,
|
||||||
})
|
})
|
||||||
setSurfaceShapePattern(roof, roofDisplay.column)
|
setSurfaceShapePattern(
|
||||||
|
roof,
|
||||||
|
roofDisplay.column,
|
||||||
|
false,
|
||||||
|
currentRoofList.find((roof) => roof.selected),
|
||||||
|
)
|
||||||
drawDirectionArrow(roof)
|
drawDirectionArrow(roof)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -246,25 +246,72 @@ export function useRoofAllocationSetting(id) {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRadioOnChange = (e) => {
|
// 지붕재 변경
|
||||||
setRadioValue(e.target)
|
const handleChangeRoofMaterial = (value, index) => {
|
||||||
|
const selectedIndex = roofMaterials.findIndex((roof) => roof.selected)
|
||||||
|
|
||||||
|
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
if (idx === index) {
|
||||||
|
return { ...selectedRoofMaterial }
|
||||||
|
}
|
||||||
|
return roof
|
||||||
|
})
|
||||||
|
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기본 지붕재 radio값 변경
|
||||||
|
const handleDefaultRoofMaterial = (index) => {
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
return { ...roof, selected: idx === index }
|
||||||
|
})
|
||||||
|
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 서까래 변경
|
||||||
|
const handleChangeRaft = (e, index) => {
|
||||||
|
const raftValue = e.clCode
|
||||||
|
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
if (idx === index) {
|
||||||
|
return { ...roof, raft: raftValue }
|
||||||
|
}
|
||||||
|
return roof
|
||||||
|
})
|
||||||
|
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChangeLayout = (layoutValue, index) => {
|
||||||
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
|
if (idx === index) {
|
||||||
|
return { ...roof, layout: layoutValue }
|
||||||
|
}
|
||||||
|
return roof
|
||||||
|
})
|
||||||
|
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleSave,
|
handleSave,
|
||||||
onAddRoofMaterial,
|
onAddRoofMaterial,
|
||||||
onDeleteRoofMaterial,
|
onDeleteRoofMaterial,
|
||||||
handleRadioOnChange,
|
|
||||||
handleAlloc,
|
handleAlloc,
|
||||||
setLineSize,
|
setLineSize,
|
||||||
widths,
|
|
||||||
lengths,
|
|
||||||
rafters,
|
|
||||||
values,
|
|
||||||
roofMaterials,
|
roofMaterials,
|
||||||
selectedRoofMaterial,
|
selectedRoofMaterial,
|
||||||
setSelectedRoofMaterial,
|
basicSetting,
|
||||||
radioValue,
|
setBasicSetting,
|
||||||
setRadioValue,
|
currentRoofMaterial,
|
||||||
|
setCurrentRoofMaterial,
|
||||||
|
handleDefaultRoofMaterial,
|
||||||
|
handleChangeRoofMaterial,
|
||||||
|
handleChangeRaft,
|
||||||
|
handleChangeLayout,
|
||||||
|
handleSaveContext,
|
||||||
|
currentRoofList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,12 +86,24 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
let stroke, strokeWidth
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
|
if (line.attributes?.type === LINE_TYPE.WALLLINE.EAVES || line.attributes?.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
||||||
|
stroke = '#45CD7D'
|
||||||
|
strokeWidth = 4
|
||||||
|
} else if (line.attributes?.type === LINE_TYPE.WALLLINE.GABLE || line.attributes?.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||||
|
stroke = '#3FBAE6'
|
||||||
|
strokeWidth = 4
|
||||||
|
} else {
|
||||||
|
stroke = '#000000'
|
||||||
|
strokeWidth = 4
|
||||||
|
}
|
||||||
line.set({
|
line.set({
|
||||||
stroke: '#000000',
|
stroke,
|
||||||
strokeWidth: 4,
|
strokeWidth,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
if (!currentObject) {
|
if (!currentObject) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -105,7 +117,6 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
currentLineRef.current = currentObject
|
currentLineRef.current = currentObject
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}, [currentObject])
|
}, [currentObject])
|
||||||
|
|
||||||
@ -125,6 +136,10 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
const index = lines.findIndex((line) => line === selectedLine)
|
const index = lines.findIndex((line) => line === selectedLine)
|
||||||
|
|
||||||
const nextLine = lines[index + 1] || lines[0]
|
const nextLine = lines[index + 1] || lines[0]
|
||||||
|
if (nextLine.attributes?.isFixed) {
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
canvas.setActiveObject(nextLine)
|
canvas.setActiveObject(nextLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +170,7 @@ export function useRoofShapePassivitySetting(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentLineRef.current.set({
|
currentLineRef.current.set({
|
||||||
attributes,
|
attributes: { ...attributes, isFixed: true },
|
||||||
})
|
})
|
||||||
|
|
||||||
history.current.push(currentLineRef.current)
|
history.current.push(currentLineRef.current)
|
||||||
|
|||||||
@ -185,9 +185,20 @@ export function useRoofShapeSetting(id) {
|
|||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
outerLines.forEach((line) => {
|
const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch
|
||||||
// hideLine(line)
|
// 변별로 설정중 한쪽흐름일 경우 한쪽흐름의 pitch로 설정
|
||||||
})
|
if (pitch) {
|
||||||
|
outerLines.forEach((line) => {
|
||||||
|
if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
|
||||||
|
line.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
pitch: pitch,
|
||||||
|
onlyOffset: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +216,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +233,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +264,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,6 +281,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +311,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +328,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,6 +359,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,6 +376,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
offset: eavesOffset / 10,
|
offset: eavesOffset / 10,
|
||||||
pitch: pitchRef.current,
|
pitch: pitchRef.current,
|
||||||
type: LINE_TYPE.WALLLINE.EAVES,
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
onlyOffset: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,17 +614,23 @@ export function useRoofShapeSetting(id) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectedLine.attributes = attributes
|
selectedLine.attributes = { ...attributes, isFixed: true }
|
||||||
history.current.push(selectedLine)
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
nextLineFocus(selectedLine)
|
nextLineFocus(selectedLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextLineFocus = (selectedLine) => {
|
const nextLineFocus = (selectedLine) => {
|
||||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
const index = lines.findIndex((line) => line.idx === selectedLine.idx)
|
const index = lines.findIndex((line) => line.idx === selectedLine.idx)
|
||||||
|
|
||||||
const nextLine = lines[index + 1] || lines[0]
|
const nextLine = lines[index + 1] || lines[0]
|
||||||
|
if (nextLine.attributes.isFixed) {
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
history.current.push(selectedLine)
|
||||||
canvas.setActiveObject(nextLine)
|
canvas.setActiveObject(nextLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { useMouse } from '@/hooks/useMouse'
|
|||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useTempGrid } from '@/hooks/useTempGrid'
|
import { useTempGrid } from '@/hooks/useTempGrid'
|
||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import { distanceBetweenPoints, setSurfaceShapePattern } from '@/util/canvas-util'
|
import { distanceBetweenPoints } from '@/util/canvas-util'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||||
import {
|
import {
|
||||||
@ -33,6 +33,7 @@ import { POLYGON_TYPE } from '@/common/common'
|
|||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
|
||||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
// 면형상 배치
|
// 면형상 배치
|
||||||
export function usePlacementShapeDrawing(id) {
|
export function usePlacementShapeDrawing(id) {
|
||||||
@ -46,6 +47,7 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
const { addPolygonByLines, drawDirectionArrow } = usePolygon()
|
const { addPolygonByLines, drawDirectionArrow } = usePolygon()
|
||||||
const { tempGridMode } = useTempGrid()
|
const { tempGridMode } = useTempGrid()
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
|
||||||
const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState)
|
const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState)
|
||||||
const adsorptionPointAddMode = useRecoilValue(adsorptionPointAddModeState)
|
const adsorptionPointAddMode = useRecoilValue(adsorptionPointAddModeState)
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { canvasState, globalPitchState } from '@/store/canvasAtom'
|
import { canvasState, globalPitchState } from '@/store/canvasAtom'
|
||||||
import { MENU, POLYGON_TYPE } from '@/common/common'
|
import { MENU, POLYGON_TYPE } from '@/common/common'
|
||||||
import { getIntersectionPoint, setSurfaceShapePattern } from '@/util/canvas-util'
|
import { getIntersectionPoint } from '@/util/canvas-util'
|
||||||
import { degreesToRadians } from '@turf/turf'
|
import { degreesToRadians } from '@turf/turf'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
@ -15,6 +15,7 @@ import { usePolygon } from '@/hooks/usePolygon'
|
|||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { slopeSelector } from '@/store/commonAtom'
|
import { slopeSelector } from '@/store/commonAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useSurfaceShapeBatch() {
|
export function useSurfaceShapeBatch() {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -29,6 +30,7 @@ export function useSurfaceShapeBatch() {
|
|||||||
const { addCanvasMouseEventListener, initEvent } = useEvent()
|
const { addCanvasMouseEventListener, initEvent } = useEvent()
|
||||||
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
|
||||||
const applySurfaceShape = (surfaceRefs, selectedType, id) => {
|
const applySurfaceShape = (surfaceRefs, selectedType, id) => {
|
||||||
let length1, length2, length3, length4, length5
|
let length1, length2, length3, length4, length5
|
||||||
|
|||||||
@ -36,11 +36,20 @@ export function useAdsorptionPoint() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeAdsorptionPoint = () => {
|
||||||
|
const adsorptionPoints = getAdsorptionPoints()
|
||||||
|
adsorptionPoints.forEach((adsorptionPoint) => {
|
||||||
|
canvas.remove(adsorptionPoint)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
adsorptionPointAddMode,
|
adsorptionPointAddMode,
|
||||||
adsorptionPointMode,
|
adsorptionPointMode,
|
||||||
adsorptionRange,
|
adsorptionRange,
|
||||||
getAdsorptionPoints,
|
getAdsorptionPoints,
|
||||||
adsorptionPointAddModeStateEvent,
|
adsorptionPointAddModeStateEvent,
|
||||||
|
removeAdsorptionPoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useRecoilState, useRecoilValue } from 'recoil'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { canvasSizeState, canvasState, canvasZoomState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasSizeState, canvasState, canvasZoomState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
|
|
||||||
// 캔버스에 필요한 이벤트
|
// 캔버스에 필요한 이벤트
|
||||||
@ -14,7 +13,6 @@ export function useCanvasEvent() {
|
|||||||
const canvasSize = useRecoilValue(canvasSizeState)
|
const canvasSize = useRecoilValue(canvasSizeState)
|
||||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||||
const lengthTextOption = useRecoilValue(fontSelector('lengthText'))
|
const lengthTextOption = useRecoilValue(fontSelector('lengthText'))
|
||||||
const { modifiedPlanFlag, setModifiedPlanFlag } = usePlan()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
canvas?.setZoom(canvasZoom / 100)
|
canvas?.setZoom(canvasZoom / 100)
|
||||||
@ -40,10 +38,6 @@ export function useCanvasEvent() {
|
|||||||
onChange: (e) => {
|
onChange: (e) => {
|
||||||
const target = e.target
|
const target = e.target
|
||||||
|
|
||||||
if (target.name !== 'mouseLine' && !modifiedPlanFlag) {
|
|
||||||
setModifiedPlanFlag((prev) => !prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
// settleDown(target)
|
// settleDown(target)
|
||||||
}
|
}
|
||||||
@ -58,10 +52,6 @@ export function useCanvasEvent() {
|
|||||||
target.uuid = uuidv4()
|
target.uuid = uuidv4()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.name !== 'mouseLine' && !modifiedPlanFlag) {
|
|
||||||
setModifiedPlanFlag((prev) => !prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.type === 'QPolygon' || target.type === 'QLine') {
|
if (target.type === 'QPolygon' || target.type === 'QLine') {
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'lengthText')
|
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'lengthText')
|
||||||
textObjs.forEach((obj) => {
|
textObjs.forEach((obj) => {
|
||||||
@ -164,9 +154,6 @@ export function useCanvasEvent() {
|
|||||||
|
|
||||||
target.on('moving', (e) => {
|
target.on('moving', (e) => {
|
||||||
target.uuid = uuidv4()
|
target.uuid = uuidv4()
|
||||||
if (!modifiedPlanFlag) {
|
|
||||||
setModifiedPlanFlag((prev) => !prev)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.parentDirection === 'left' || target.parentDirection === 'right') {
|
if (target.parentDirection === 'left' || target.parentDirection === 'right') {
|
||||||
const minX = target.minX
|
const minX = target.minX
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { MENU } from '@/common/common'
|
import { MENU, POLYGON_TYPE } from '@/common/common'
|
||||||
import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize'
|
import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
@ -23,7 +23,7 @@ import { useCommonUtils } from './common/useCommonUtils'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||||
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
|
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
|
||||||
import PanelEdit from '@/components/floor-plan/modal/module/PanelEdit'
|
import PanelEdit, { PANEL_EDIT_TYPE } from '@/components/floor-plan/modal/module/PanelEdit'
|
||||||
import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/DimensionLineSetting'
|
import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/DimensionLineSetting'
|
||||||
import ColumnRemove from '@/components/floor-plan/modal/module/column/ColumnRemove'
|
import ColumnRemove from '@/components/floor-plan/modal/module/column/ColumnRemove'
|
||||||
import ColumnInsert from '@/components/floor-plan/modal/module/column/ColumnInsert'
|
import ColumnInsert from '@/components/floor-plan/modal/module/column/ColumnInsert'
|
||||||
@ -35,6 +35,12 @@ import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
|||||||
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import ContextRoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting'
|
||||||
|
import { useCanvasSetting } from './option/useCanvasSetting'
|
||||||
|
import { useGrid } from './common/useGrid'
|
||||||
|
import { useAdsorptionPoint } from './useAdsorptionPoint'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
import { MODULE_ALIGN_TYPE, useModule } from './module/useModule'
|
||||||
|
|
||||||
export function useContextMenu() {
|
export function useContextMenu() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -56,8 +62,13 @@ export function useContextMenu() {
|
|||||||
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
|
const { removeGrid } = useGrid()
|
||||||
|
const { removeAdsorptionPoint } = useAdsorptionPoint()
|
||||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||||
|
const { settingsData, setSettingsDataSave } = useCanvasSetting()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
|
const { alignModule } = useModule()
|
||||||
|
const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
|
||||||
|
|
||||||
const currentMenuSetting = () => {
|
const currentMenuSetting = () => {
|
||||||
switch (currentMenu) {
|
switch (currentMenu) {
|
||||||
@ -77,7 +88,15 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('modal.grid.color.edit'),
|
name: getMessage('modal.grid.color.edit'),
|
||||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
component: (
|
||||||
|
<ColorPickerModal
|
||||||
|
id={popupId}
|
||||||
|
color={gridColor}
|
||||||
|
setColor={setGridColor}
|
||||||
|
settingsData={settingsData}
|
||||||
|
setSettingsDataSave={setSettingsDataSave}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
@ -86,6 +105,10 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'removeAll',
|
id: 'removeAll',
|
||||||
name: getMessage('delete.all'),
|
name: getMessage('delete.all'),
|
||||||
|
fn: () => {
|
||||||
|
removeGrid()
|
||||||
|
removeAdsorptionPoint()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
@ -105,14 +128,17 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'roofMaterialPlacement',
|
id: 'roofMaterialPlacement',
|
||||||
name: getMessage('contextmenu.roof.material.placement'),
|
name: getMessage('contextmenu.roof.material.placement'),
|
||||||
|
component: <RoofAllocationSetting id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'roofMaterialRemove',
|
id: 'roofMaterialRemove',
|
||||||
name: getMessage('contextmenu.roof.material.remove'),
|
name: getMessage('contextmenu.roof.material.remove'),
|
||||||
|
fn: () => removeRoofMaterial(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'roofMaterialRemoveAll',
|
id: 'roofMaterialRemoveAll',
|
||||||
name: getMessage('contextmenu.roof.material.remove.all'),
|
name: getMessage('contextmenu.roof.material.remove.all'),
|
||||||
|
fn: () => removeAllRoofMaterial(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'selectMove',
|
id: 'selectMove',
|
||||||
@ -377,7 +403,7 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'roofMaterialEdit',
|
id: 'roofMaterialEdit',
|
||||||
name: getMessage('contextmenu.roof.material.edit'),
|
name: getMessage('contextmenu.roof.material.edit'),
|
||||||
component: <RoofAllocationSetting id={popupId} />,
|
component: <ContextRoofAllocationSetting id={popupId} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'linePropertyEdit',
|
id: 'linePropertyEdit',
|
||||||
@ -516,7 +542,15 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('contextmenu.grid.color.edit'),
|
name: getMessage('contextmenu.grid.color.edit'),
|
||||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
component: (
|
||||||
|
<ColorPickerModal
|
||||||
|
id={popupId}
|
||||||
|
color={gridColor}
|
||||||
|
setColor={setGridColor}
|
||||||
|
settingsData={settingsData}
|
||||||
|
setSettingsDataSave={setSettingsDataSave}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
@ -530,12 +564,8 @@ export function useContextMenu() {
|
|||||||
id: 'removeAll',
|
id: 'removeAll',
|
||||||
name: getMessage('contextmenu.remove.all'),
|
name: getMessage('contextmenu.remove.all'),
|
||||||
fn: () => {
|
fn: () => {
|
||||||
canvas
|
removeGrid()
|
||||||
.getObjects()
|
removeAdsorptionPoint()
|
||||||
.filter((obj) => ['tempGrid', 'lineGrid', 'dotGrid'].includes(obj.name))
|
|
||||||
.forEach((grid) => {
|
|
||||||
canvas.remove(grid)
|
|
||||||
})
|
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -597,34 +627,35 @@ export function useContextMenu() {
|
|||||||
],
|
],
|
||||||
])
|
])
|
||||||
break
|
break
|
||||||
case 'panel':
|
case 'module':
|
||||||
setContextMenu([
|
setContextMenu([
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
name: getMessage('contextmenu.remove'),
|
name: getMessage('contextmenu.remove'),
|
||||||
|
fn: () => deleteObject(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'move',
|
id: 'move',
|
||||||
name: getMessage('contextmenu.move'),
|
name: getMessage('contextmenu.move'),
|
||||||
component: <PanelEdit id={popupId} type={'move'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'copy',
|
id: 'copy',
|
||||||
name: getMessage('contextmenu.copy'),
|
name: getMessage('contextmenu.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'copy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COPY} />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'columnMove',
|
id: 'columnMove',
|
||||||
name: getMessage('contextmenu.column.move'),
|
name: getMessage('contextmenu.column.move'),
|
||||||
component: <PanelEdit id={popupId} type={'move'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COLUMN_MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'columnCopy',
|
id: 'columnCopy',
|
||||||
name: getMessage('contextmenu.column.copy'),
|
name: getMessage('contextmenu.column.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'copy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COLUMN_COPY} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'columnRemove',
|
id: 'columnRemove',
|
||||||
@ -641,12 +672,12 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'rowMove',
|
id: 'rowMove',
|
||||||
name: getMessage('contextmenu.row.move'),
|
name: getMessage('contextmenu.row.move'),
|
||||||
component: <PanelEdit id={popupId} type={'move'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.ROW_MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rowCopy',
|
id: 'rowCopy',
|
||||||
name: getMessage('contextmenu.row.copy'),
|
name: getMessage('contextmenu.row.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'copy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.ROW_COPY} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rowRemove',
|
id: 'rowRemove',
|
||||||
@ -661,37 +692,39 @@ export function useContextMenu() {
|
|||||||
],
|
],
|
||||||
])
|
])
|
||||||
break
|
break
|
||||||
case 'module':
|
case 'moduleSetupSurface':
|
||||||
case 'dimensionLineText':
|
case 'roof':
|
||||||
setContextMenu([
|
setContextMenu([
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'moduleVerticalCenterAlign',
|
id: 'moduleVerticalCenterAlign',
|
||||||
name: getMessage('contextmenu.module.vertical.align'),
|
name: getMessage('contextmenu.module.vertical.align'),
|
||||||
|
fn: () => alignModule(MODULE_ALIGN_TYPE.VERTICAL),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'moduleHorizonCenterAlign',
|
id: 'moduleHorizonCenterAlign',
|
||||||
name: getMessage('contextmenu.module.horizon.align'),
|
name: getMessage('contextmenu.module.horizon.align'),
|
||||||
},
|
fn: () => alignModule(MODULE_ALIGN_TYPE.HORIZONTAL),
|
||||||
{
|
|
||||||
id: 'moduleLeftAlign',
|
|
||||||
name: getMessage('contextmenu.module.left.align'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'moduleRightAlign',
|
|
||||||
name: getMessage('contextmenu.module.right.align'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'moduleUpAlign',
|
|
||||||
name: getMessage('contextmenu.module.up.align'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'moduleDownAlign',
|
|
||||||
name: getMessage('contextmenu.module.down.align'),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'moduleRemove',
|
id: 'moduleRemove',
|
||||||
name: getMessage('contextmenu.module.remove'),
|
name: getMessage('contextmenu.module.remove'),
|
||||||
|
fn: () => {
|
||||||
|
const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
canvas.remove(...modules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'moduleMove',
|
||||||
|
name: getMessage('contextmenu.module.move'),
|
||||||
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.MOVE_ALL} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'moduleCopy',
|
||||||
|
name: getMessage('contextmenu.module.copy'),
|
||||||
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COPY_ALL} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'moduleCircuitNumberEdit',
|
id: 'moduleCircuitNumberEdit',
|
||||||
|
|||||||
@ -86,13 +86,14 @@ export const useLine = () => {
|
|||||||
const addPitchText = (line) => {
|
const addPitchText = (line) => {
|
||||||
removePitchText(line)
|
removePitchText(line)
|
||||||
const { startPoint, endPoint, direction, attributes } = line
|
const { startPoint, endPoint, direction, attributes } = line
|
||||||
|
const { offset, onlyOffset = false } = attributes
|
||||||
|
|
||||||
let left, top
|
let left, top
|
||||||
|
|
||||||
const textStr =
|
const textStr =
|
||||||
currentAngleType === ANGLE_TYPE.SLOPE
|
currentAngleType === ANGLE_TYPE.SLOPE
|
||||||
? `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${attributes.pitch ? '-∠' + attributes.pitch + angleUnit : ''}`
|
? `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${onlyOffset && attributes.pitch ? '-∠' + attributes.pitch + angleUnit : ''}`
|
||||||
: `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${attributes.pitch ? '-∠' + getDegreeByChon(attributes.pitch) + angleUnit : ''}`
|
: `${attributes.offset ? attributes.offset * 10 : attributes.width * 10}${onlyOffset && attributes.pitch ? '-∠' + getDegreeByChon(attributes.pitch) + angleUnit : ''}`
|
||||||
|
|
||||||
if (direction === 'top') {
|
if (direction === 'top') {
|
||||||
left = (startPoint.x + endPoint.x) / 2
|
left = (startPoint.x + endPoint.x) / 2
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { canvasState, currentCanvasPlanState, plansState, modifiedPlansState, modifiedPlanFlagState } from '@/store/canvasAtom'
|
import { canvasState, currentCanvasPlanState, plansState } from '@/store/canvasAtom'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
@ -12,14 +12,11 @@ import { useCanvas } from '@/hooks/useCanvas'
|
|||||||
export function usePlan() {
|
export function usePlan() {
|
||||||
const [planNum, setPlanNum] = useState(0)
|
const [planNum, setPlanNum] = useState(0)
|
||||||
const [selectedPlan, setSelectedPlan] = useState(null)
|
const [selectedPlan, setSelectedPlan] = useState(null)
|
||||||
const [currentCanvasStatus, setCurrentCanvasStatus] = useState(null)
|
|
||||||
|
|
||||||
const [canvas, setCanvas] = useRecoilState(canvasState)
|
const [canvas, setCanvas] = useRecoilState(canvasState)
|
||||||
|
|
||||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||||
const [plans, setPlans] = useRecoilState(plansState) // 전체 plan
|
const [plans, setPlans] = useRecoilState(plansState) // 전체 plan
|
||||||
const [modifiedPlans, setModifiedPlans] = useRecoilState(modifiedPlansState) // 변경된 canvas plan
|
|
||||||
const [modifiedPlanFlag, setModifiedPlanFlag] = useRecoilState(modifiedPlanFlagState) // 캔버스 실시간 오브젝트 이벤트 감지 flag
|
|
||||||
|
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -95,64 +92,6 @@ export function usePlan() {
|
|||||||
return addCanvas()
|
return addCanvas()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 캔버스에서 발생하는 실시간 오브젝트 이벤트를 감지하여 수정 여부를 확인 후 관리
|
|
||||||
*/
|
|
||||||
const checkCanvasObjectEvent = (planId) => {
|
|
||||||
setCurrentCanvasStatus(currentCanvasData())
|
|
||||||
if (!modifiedPlans.some((modifiedPlan) => modifiedPlan === planId) && checkModifiedCanvasPlan(planId)) {
|
|
||||||
setModifiedPlans((prev) => [...prev, planId])
|
|
||||||
setModifiedPlanFlag(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
useEffect(() => {
|
|
||||||
if (currentCanvasStatus) {
|
|
||||||
setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: currentCanvasStatus }))
|
|
||||||
}
|
|
||||||
}, [currentCanvasStatus])
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 현재 캔버스 상태와 DB에 저장된 캔버스 상태를 비교하여 수정 여부를 판단
|
|
||||||
*/
|
|
||||||
const checkModifiedCanvasPlan = (planId) => {
|
|
||||||
const planData = plans.find((plan) => plan.id === planId)
|
|
||||||
if (planData.canvasStatus === '') {
|
|
||||||
// 빈 상태로 저장된 캔버스
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 각각 object들의 uuid 목록을 추출하여 비교
|
|
||||||
const canvasStatus = currentCanvasData()
|
|
||||||
const canvasObjsUuids = getObjectUuids(JSON.parse(canvasStatus).objects)
|
|
||||||
const dbObjsUuids = getObjectUuids(JSON.parse(planData.canvasStatus).objects)
|
|
||||||
return canvasObjsUuids.length !== dbObjsUuids.length || !canvasObjsUuids.every((uuid, index) => uuid === dbObjsUuids[index])
|
|
||||||
}
|
|
||||||
const getObjectUuids = (objects) => {
|
|
||||||
return objects
|
|
||||||
.filter((obj) => obj.hasOwnProperty('uuid'))
|
|
||||||
.map((obj) => obj.uuid)
|
|
||||||
.sort()
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetModifiedPlans = () => {
|
|
||||||
setModifiedPlans([])
|
|
||||||
setModifiedPlanFlag(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 캔버스에 저장되지 않은 변경사항이 있을때 저장 여부를 확인 후 저장
|
|
||||||
*/
|
|
||||||
const checkUnsavedCanvasPlan = async () => {
|
|
||||||
swalFire({
|
|
||||||
text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.save.modified'),
|
|
||||||
type: 'confirm',
|
|
||||||
confirmFn: async () => {
|
|
||||||
await putCanvasStatus(currentCanvasPlan.canvasStatus)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
resetModifiedPlans()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DB에 저장된 데이터를 canvas에서 사용할 수 있도록 포맷화
|
* DB에 저장된 데이터를 canvas에서 사용할 수 있도록 포맷화
|
||||||
*/
|
*/
|
||||||
@ -206,8 +145,8 @@ export function usePlan() {
|
|||||||
}
|
}
|
||||||
await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setPlans([...plans, { id: res.data, objectNo: objectNo, userId: userId, canvasStatus: canvasStatus, ordering: planNum + 1 }])
|
setPlans((plans) => [...plans, { id: res.data, objectNo: objectNo, userId: userId, canvasStatus: canvasStatus, ordering: planNum + 1 }])
|
||||||
handleCurrentPlan(res.data)
|
updateCurrentPlan(res.data)
|
||||||
setPlanNum(planNum + 1)
|
setPlanNum(planNum + 1)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -228,7 +167,6 @@ export function usePlan() {
|
|||||||
await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
|
setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)))
|
||||||
setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id))
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
swalFire({ text: error.message, icon: 'error' })
|
swalFire({ text: error.message, icon: 'error' })
|
||||||
@ -251,13 +189,11 @@ export function usePlan() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* plan 이동
|
* plan 이동
|
||||||
* 현재 plan의 작업상태를 확인, 저장 후 이동
|
* 현재 plan의 작업상태를 저장 후 이동
|
||||||
*/
|
*/
|
||||||
const handleCurrentPlan = async (newCurrentId) => {
|
const handleCurrentPlan = async (newCurrentId) => {
|
||||||
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
|
if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) {
|
||||||
if (currentCanvasPlan?.id && modifiedPlans.some((modifiedPlan) => modifiedPlan === currentCanvasPlan.id)) {
|
await saveCanvas()
|
||||||
await saveCanvas()
|
|
||||||
}
|
|
||||||
updateCurrentPlan(newCurrentId)
|
updateCurrentPlan(newCurrentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,9 +217,12 @@ export function usePlan() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 새로운 plan 생성
|
* 새로운 plan 생성
|
||||||
* 현재 plan의 데이터가 있을 경우 복제 여부를 확인
|
* 현재 plan의 데이터가 있을 경우 현재 plan 저장 및 복제 여부를 확인
|
||||||
*/
|
*/
|
||||||
const handleAddPlan = async (userId, objectNo) => {
|
const handleAddPlan = async (userId, objectNo) => {
|
||||||
|
if (currentCanvasPlan?.id) {
|
||||||
|
await saveCanvas()
|
||||||
|
}
|
||||||
JSON.parse(currentCanvasData()).objects.length > 0
|
JSON.parse(currentCanvasData()).objects.length > 0
|
||||||
? swalFire({
|
? swalFire({
|
||||||
text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.copy'),
|
text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.copy'),
|
||||||
@ -324,7 +263,6 @@ export function usePlan() {
|
|||||||
await delCanvasById(id)
|
await delCanvasById(id)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
setPlans((plans) => plans.filter((plan) => plan.id !== id))
|
||||||
setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id))
|
|
||||||
removeImage(currentCanvasPlan.id)
|
removeImage(currentCanvasPlan.id)
|
||||||
swalFire({ text: getMessage('plan.message.delete') })
|
swalFire({ text: getMessage('plan.message.delete') })
|
||||||
})
|
})
|
||||||
@ -362,14 +300,6 @@ export function usePlan() {
|
|||||||
canvas,
|
canvas,
|
||||||
plans,
|
plans,
|
||||||
selectedPlan,
|
selectedPlan,
|
||||||
currentCanvasPlan,
|
|
||||||
setCurrentCanvasPlan,
|
|
||||||
modifiedPlans,
|
|
||||||
modifiedPlanFlag,
|
|
||||||
setModifiedPlanFlag,
|
|
||||||
checkCanvasObjectEvent,
|
|
||||||
checkUnsavedCanvasPlan,
|
|
||||||
resetModifiedPlans,
|
|
||||||
saveCanvas,
|
saveCanvas,
|
||||||
handleCurrentPlan,
|
handleCurrentPlan,
|
||||||
handleAddPlan,
|
handleAddPlan,
|
||||||
|
|||||||
@ -1,10 +1,21 @@
|
|||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { contextPopupState, popupState } from '@/store/popupAtom'
|
import { contextPopupState, popupState } from '@/store/popupAtom'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 관리 훅
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function usePopup() {
|
export function usePopup() {
|
||||||
const [popup, setPopup] = useRecoilState(popupState)
|
const [popup, setPopup] = useRecoilState(popupState)
|
||||||
const [contextMenuPopup, setContextMenuPopup] = useRecoilState(contextPopupState)
|
const [contextMenuPopup, setContextMenuPopup] = useRecoilState(contextPopupState)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 추가
|
||||||
|
* @param {*} id 팝업 아이디
|
||||||
|
* @param {*} depth 팝업 깊이
|
||||||
|
* @param {*} component 팝업 컴포넌트
|
||||||
|
* @param {*} isConfig 팝업 타입
|
||||||
|
*/
|
||||||
const addPopup = (id, depth, component, isConfig = false) => {
|
const addPopup = (id, depth, component, isConfig = false) => {
|
||||||
setPopup({
|
setPopup({
|
||||||
config: isConfig ? [...filterDepth(depth, isConfig), { id, depth, component, isConfig }] : [...popup.config],
|
config: isConfig ? [...filterDepth(depth, isConfig), { id, depth, component, isConfig }] : [...popup.config],
|
||||||
@ -12,6 +23,11 @@ export function usePopup() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 닫기
|
||||||
|
* @param {*} id 팝업 아이디
|
||||||
|
* @param {*} isConfig 팝업 타입
|
||||||
|
*/
|
||||||
const closePopup = (id, isConfig = false) => {
|
const closePopup = (id, isConfig = false) => {
|
||||||
if (contextMenuPopup) setContextMenuPopup(null)
|
if (contextMenuPopup) setContextMenuPopup(null)
|
||||||
if (isConfig) {
|
if (isConfig) {
|
||||||
@ -27,6 +43,10 @@ export function usePopup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 필터
|
||||||
|
* @param {*} depth 팝업 깊이
|
||||||
|
*/
|
||||||
const filterPopup = (depth) => {
|
const filterPopup = (depth) => {
|
||||||
setPopup({
|
setPopup({
|
||||||
config: [...filterDepth(depth)],
|
config: [...filterDepth(depth)],
|
||||||
@ -34,6 +54,12 @@ export function usePopup() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 자식 필터
|
||||||
|
* @param {*} id 팝업 아이디
|
||||||
|
* @param {*} isConfig 팝업 타입
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const filterChildrenPopup = (id, isConfig) => {
|
const filterChildrenPopup = (id, isConfig) => {
|
||||||
let target = []
|
let target = []
|
||||||
if (isConfig) {
|
if (isConfig) {
|
||||||
@ -57,6 +83,10 @@ export function usePopup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 여러개 닫기
|
||||||
|
* @param {*} ids 팝업 아이디 배열
|
||||||
|
*/
|
||||||
const closePopups = (ids) => {
|
const closePopups = (ids) => {
|
||||||
setPopup({
|
setPopup({
|
||||||
config: [...popup?.config.filter((child) => !ids.includes(child.id))],
|
config: [...popup?.config.filter((child) => !ids.includes(child.id))],
|
||||||
@ -64,6 +94,9 @@ export function usePopup() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 전체 닫기
|
||||||
|
*/
|
||||||
const closeAll = () => {
|
const closeAll = () => {
|
||||||
setPopup({
|
setPopup({
|
||||||
other: [],
|
other: [],
|
||||||
@ -71,6 +104,9 @@ export function usePopup() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 이전 팝업 닫기
|
||||||
|
*/
|
||||||
const closePrevPopup = () => {
|
const closePrevPopup = () => {
|
||||||
setPopup({
|
setPopup({
|
||||||
config: [...popup?.slice(popup?.length - 1)],
|
config: [...popup?.slice(popup?.length - 1)],
|
||||||
@ -78,6 +114,12 @@ export function usePopup() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 깊이 필터
|
||||||
|
* @param {*} depth 팝업 깊이
|
||||||
|
* @param {*} isConfig 팝업 타입
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const filterDepth = (depth, isConfig) => {
|
const filterDepth = (depth, isConfig) => {
|
||||||
if (isConfig) {
|
if (isConfig) {
|
||||||
return [...popup?.config.filter((child) => child.depth < depth)]
|
return [...popup?.config.filter((child) => child.depth < depth)]
|
||||||
|
|||||||
@ -21,6 +21,8 @@ export const useSwal = () => {
|
|||||||
text,
|
text,
|
||||||
icon: icon === '' ? 'success' : icon,
|
icon: icon === '' ? 'success' : icon,
|
||||||
confirmButtonText: '확인',
|
confirmButtonText: '확인',
|
||||||
|
}).then(() => {
|
||||||
|
confirmFn()
|
||||||
})
|
})
|
||||||
} else if (type === 'confirm') {
|
} else if (type === 'confirm') {
|
||||||
MySwal.fire({
|
MySwal.fire({
|
||||||
|
|||||||
@ -59,33 +59,36 @@ export async function setSession(data) {
|
|||||||
await session.save()
|
await session.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(formData) {
|
export async function login() {
|
||||||
const session = await getSession()
|
const session = await getSession()
|
||||||
|
if (session) {
|
||||||
const userId = formData.get('id')
|
redirect('/')
|
||||||
const password = formData.get('password')
|
|
||||||
|
|
||||||
console.log('id:', userId)
|
|
||||||
console.log('password:', password)
|
|
||||||
|
|
||||||
// const loginUser = await getUserByIdAndPassword({ userId, password })
|
|
||||||
const loginUser = {
|
|
||||||
id: 1,
|
|
||||||
userId: 'test123',
|
|
||||||
name: 'jinsoo Kim',
|
|
||||||
email: 'jinsoo.kim@example.com',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loginUser) {
|
// const userId = formData.get('id')
|
||||||
throw Error('Wrong Credentials!')
|
// const password = formData.get('password')
|
||||||
}
|
|
||||||
|
|
||||||
session.name = loginUser.name
|
// console.log('id:', userId)
|
||||||
session.userId = loginUser.userId
|
// console.log('password:', password)
|
||||||
session.email = loginUser.email
|
|
||||||
session.isLoggedIn = true
|
|
||||||
console.log('session:', session)
|
|
||||||
|
|
||||||
await session.save()
|
// // const loginUser = await getUserByIdAndPassword({ userId, password })
|
||||||
redirect('/')
|
// const loginUser = {
|
||||||
|
// id: 1,
|
||||||
|
// userId: 'test123',
|
||||||
|
// name: 'jinsoo Kim',
|
||||||
|
// email: 'jinsoo.kim@example.com',
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!loginUser) {
|
||||||
|
// throw Error('Wrong Credentials!')
|
||||||
|
// }
|
||||||
|
|
||||||
|
// session.name = loginUser.name
|
||||||
|
// session.userId = loginUser.userId
|
||||||
|
// session.email = loginUser.email
|
||||||
|
// session.isLoggedIn = true
|
||||||
|
// console.log('session:', session)
|
||||||
|
|
||||||
|
// await session.save()
|
||||||
|
// redirect('/')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,8 @@ export const defaultSession = {}
|
|||||||
export const sessionOptions = {
|
export const sessionOptions = {
|
||||||
password: process.env.SESSION_SECRET,
|
password: process.env.SESSION_SECRET,
|
||||||
cookieName: 'lama-session',
|
cookieName: 'lama-session',
|
||||||
// cookieOptions: {
|
cookieOptions: {
|
||||||
// httpOnly: true,
|
httpOnly: true,
|
||||||
// secure: process.env.NODE_ENV === 'production',
|
secure: process.env.NODE_ENV === 'production',
|
||||||
// },
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,6 +157,7 @@
|
|||||||
"plan.menu.estimate": "見積",
|
"plan.menu.estimate": "見積",
|
||||||
"plan.menu.estimate.roof.alloc": "屋根面の割り当て",
|
"plan.menu.estimate.roof.alloc": "屋根面の割り当て",
|
||||||
"modal.roof.alloc.info": "※配置面初期設定で保存した[基本屋根材]を変更したり、屋根材を追加して割り当てることができます。",
|
"modal.roof.alloc.info": "※配置面初期設定で保存した[基本屋根材]を変更したり、屋根材を追加して割り当てることができます。",
|
||||||
|
"modal.roof.alloc.default.roof.material": "基本屋根材",
|
||||||
"modal.roof.alloc.select.roof.material": "屋根材の選択",
|
"modal.roof.alloc.select.roof.material": "屋根材の選択",
|
||||||
"modal.roof.alloc.select.parallel": "並列式",
|
"modal.roof.alloc.select.parallel": "並列式",
|
||||||
"modal.roof.alloc.select.stairs": "カスケード",
|
"modal.roof.alloc.select.stairs": "カスケード",
|
||||||
@ -296,7 +297,6 @@
|
|||||||
"modal.actual.size.setting.plane.size.length": "廊下の寸法の長さ",
|
"modal.actual.size.setting.plane.size.length": "廊下の寸法の長さ",
|
||||||
"modal.actual.size.setting.actual.size.length": "実寸長",
|
"modal.actual.size.setting.actual.size.length": "実寸長",
|
||||||
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
||||||
"plan.message.confirm.save.modified": "PLAN의 변경사항을 저장하시겠습니까?",
|
|
||||||
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
||||||
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
||||||
"plan.message.save": "저장되었습니다.",
|
"plan.message.save": "저장되었습니다.",
|
||||||
@ -514,6 +514,8 @@
|
|||||||
"color.darkblue": "남색(JA)",
|
"color.darkblue": "남색(JA)",
|
||||||
"site.name": "Q.CAST III",
|
"site.name": "Q.CAST III",
|
||||||
"site.sub_name": "太陽光発電システム図面管理サイト",
|
"site.sub_name": "太陽光発電システム図面管理サイト",
|
||||||
|
"site.header.link1": "選択してください。",
|
||||||
|
"site.header.link2": "オンライン保証システム",
|
||||||
"board.notice.title": "お知らせ",
|
"board.notice.title": "お知らせ",
|
||||||
"board.notice.sub.title": "お知らせ一覧",
|
"board.notice.sub.title": "お知らせ一覧",
|
||||||
"board.faq.title": "FAQ",
|
"board.faq.title": "FAQ",
|
||||||
@ -630,7 +632,7 @@
|
|||||||
"stuff.detail.header.successCopy": "商品番号がコピーされました。",
|
"stuff.detail.header.successCopy": "商品番号がコピーされました。",
|
||||||
"stuff.detail.header.failCopy": "存在しないものです。",
|
"stuff.detail.header.failCopy": "存在しないものです。",
|
||||||
"stuff.detail.header.objectNo": "商品番号のコピーに失敗しました。",
|
"stuff.detail.header.objectNo": "商品番号のコピーに失敗しました。",
|
||||||
"stuff.detail.header.specificationConfirmDate": "仕様拡張日",
|
"stuff.detail.header.specificationConfirmDate": "仕様確認日",
|
||||||
"stuff.detail.header.lastEditDatetime": "更新日時",
|
"stuff.detail.header.lastEditDatetime": "更新日時",
|
||||||
"stuff.detail.header.createDatetime": "登録日",
|
"stuff.detail.header.createDatetime": "登録日",
|
||||||
"stuff.detail.required": "必須入力項目",
|
"stuff.detail.required": "必須入力項目",
|
||||||
@ -664,6 +666,7 @@
|
|||||||
"stuff.detail.tooltip.saleStoreId": "販売代理店または販売代理店IDを1文字以上入力してください",
|
"stuff.detail.tooltip.saleStoreId": "販売代理店または販売代理店IDを1文字以上入力してください",
|
||||||
"stuff.detail.tooltip.surfaceType": "塩害地域の定義は各メーカーの設置マニュアルをご確認ください",
|
"stuff.detail.tooltip.surfaceType": "塩害地域の定義は各メーカーの設置マニュアルをご確認ください",
|
||||||
"stuff.detail.tempSave.message1": "一時保存されました。商品番号を取得するには、必須項目をすべて入力してください。",
|
"stuff.detail.tempSave.message1": "一時保存されました。商品番号を取得するには、必須項目をすべて入力してください。",
|
||||||
|
"stuff.detail.tempSave.message2": "担当者は10桁以下で入力してください.",
|
||||||
"stuff.detail.confirm.message1": "販売店情報を変更すると、設計依頼文書番号が削除されます。変更しますか?",
|
"stuff.detail.confirm.message1": "販売店情報を変更すると、設計依頼文書番号が削除されます。変更しますか?",
|
||||||
"stuff.detail.delete.message1": "仕様が確定したものは削除できません。",
|
"stuff.detail.delete.message1": "仕様が確定したものは削除できません。",
|
||||||
"stuff.detail.planList.title": "プランリスト",
|
"stuff.detail.planList.title": "プランリスト",
|
||||||
@ -725,7 +728,7 @@
|
|||||||
"stuff.search.grid.all": "全体",
|
"stuff.search.grid.all": "全体",
|
||||||
"stuff.search.grid.selected": "選択",
|
"stuff.search.grid.selected": "選択",
|
||||||
"stuff.search.grid.schSortTypeR": "最近の登録日",
|
"stuff.search.grid.schSortTypeR": "最近の登録日",
|
||||||
"stuff.search.grid.schSortTypeU": "最近の更新日",
|
"stuff.search.grid.schSortTypeU": "最近修正日",
|
||||||
"stuff.windSelectPopup.title": "風速選択",
|
"stuff.windSelectPopup.title": "風速選択",
|
||||||
"stuff.windSelectPopup.table.selected": "選択",
|
"stuff.windSelectPopup.table.selected": "選択",
|
||||||
"stuff.windSelectPopup.table.windspeed": "風速",
|
"stuff.windSelectPopup.table.windspeed": "風速",
|
||||||
@ -799,11 +802,14 @@
|
|||||||
"main.storeName": "販売店名",
|
"main.storeName": "販売店名",
|
||||||
"main.objectNo": "物件番号",
|
"main.objectNo": "物件番号",
|
||||||
"main.faq": "FAQ",
|
"main.faq": "FAQ",
|
||||||
|
"main.content.objectList.noData1": "登録された商品情報はありません.",
|
||||||
|
"main.content.objectList.noData2": "下のボタンをクリックして商品情報を登録してください.",
|
||||||
"main.content.objectList": "最近の更新物件一覧",
|
"main.content.objectList": "最近の更新物件一覧",
|
||||||
"main.content.notice": "お知らせ",
|
"main.content.notice": "お知らせ",
|
||||||
"main.content.download1": "操作マニュアル",
|
"main.content.download1": "操作マニュアル",
|
||||||
"main.content.download2": "屋根の説明書",
|
"main.content.download2": "屋根の説明書",
|
||||||
"main.content.noBusiness": "Hanwha Japanにお問い合わせください",
|
"main.content.noBusiness": "Hanwha Japanにお問い合わせください",
|
||||||
|
"main.content.alert.noFile": "資料が準備中です",
|
||||||
"main.popup.login.popupTitle": "パスワード変更",
|
"main.popup.login.popupTitle": "パスワード変更",
|
||||||
"main.popup.login.newPassword1": "新しいパスワードを入力",
|
"main.popup.login.newPassword1": "新しいパスワードを入力",
|
||||||
"main.popup.login.newPassword2": "新規パスワード再入力",
|
"main.popup.login.newPassword2": "新規パスワード再入力",
|
||||||
@ -934,5 +940,10 @@
|
|||||||
"simulator.table.sub9": "予測発電量 (kWh)",
|
"simulator.table.sub9": "予測発電量 (kWh)",
|
||||||
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
||||||
"simulator.notice.sub2": "シミュレーション案内事項",
|
"simulator.notice.sub2": "シミュレーション案内事項",
|
||||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||||
|
"can.not.move.module": "모듈을 이동할 수 없습니다.(JA)",
|
||||||
|
"can.not.copy.module": "모듈을 복사할 수 없습니다.(JA)",
|
||||||
|
"can.not.remove.module": "모듈을 삭제할 수 없습니다.(JA)",
|
||||||
|
"can.not.insert.module": "모듈을 삽입할 수 없습니다.(JA)",
|
||||||
|
"can.not.align.module": "모듈을 정렬할 수 없습니다.(JA)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -161,6 +161,7 @@
|
|||||||
"plan.menu.estimate": "견적서",
|
"plan.menu.estimate": "견적서",
|
||||||
"plan.menu.estimate.roof.alloc": "지붕면 할당",
|
"plan.menu.estimate.roof.alloc": "지붕면 할당",
|
||||||
"modal.roof.alloc.info": "※ 배치면 초기설정에서 저장한 [기본 지붕재]를 변경하거나, 지붕재를 추가하여 할당할 수 있습니다.",
|
"modal.roof.alloc.info": "※ 배치면 초기설정에서 저장한 [기본 지붕재]를 변경하거나, 지붕재를 추가하여 할당할 수 있습니다.",
|
||||||
|
"modal.roof.alloc.default.roof.material": "기본지붕재",
|
||||||
"modal.roof.alloc.select.roof.material": "지붕재 선택",
|
"modal.roof.alloc.select.roof.material": "지붕재 선택",
|
||||||
"modal.roof.alloc.select.parallel": "병렬식",
|
"modal.roof.alloc.select.parallel": "병렬식",
|
||||||
"modal.roof.alloc.select.stairs": "계단식",
|
"modal.roof.alloc.select.stairs": "계단식",
|
||||||
@ -301,7 +302,6 @@
|
|||||||
"modal.actual.size.setting.plane.size.length": "복도치수 길이",
|
"modal.actual.size.setting.plane.size.length": "복도치수 길이",
|
||||||
"modal.actual.size.setting.actual.size.length": "실제치수 길이",
|
"modal.actual.size.setting.actual.size.length": "실제치수 길이",
|
||||||
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
|
||||||
"plan.message.confirm.save.modified": "PLAN의 변경사항을 저장하시겠습니까?",
|
|
||||||
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
|
||||||
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
|
||||||
"plan.message.save": "저장되었습니다.",
|
"plan.message.save": "저장되었습니다.",
|
||||||
@ -524,6 +524,8 @@
|
|||||||
"color.darkblue": "남색",
|
"color.darkblue": "남색",
|
||||||
"site.name": "Q.CAST III",
|
"site.name": "Q.CAST III",
|
||||||
"site.sub_name": "태양광 발전 시스템 도면관리 사이트",
|
"site.sub_name": "태양광 발전 시스템 도면관리 사이트",
|
||||||
|
"site.header.link1": "선택하세요.",
|
||||||
|
"site.header.link2": "온라인보증시스템",
|
||||||
"board.notice.title": "공지사항",
|
"board.notice.title": "공지사항",
|
||||||
"board.notice.sub.title": "공지사항 목록",
|
"board.notice.sub.title": "공지사항 목록",
|
||||||
"board.faq.title": "FAQ",
|
"board.faq.title": "FAQ",
|
||||||
@ -640,7 +642,7 @@
|
|||||||
"stuff.detail.header.successCopy": "물건번호가 복사되었습니다.",
|
"stuff.detail.header.successCopy": "물건번호가 복사되었습니다.",
|
||||||
"stuff.detail.header.failCopy": "물건번호 복사에 실패했습니다.",
|
"stuff.detail.header.failCopy": "물건번호 복사에 실패했습니다.",
|
||||||
"stuff.detail.header.objectNo": "물건번호",
|
"stuff.detail.header.objectNo": "물건번호",
|
||||||
"stuff.detail.header.specificationConfirmDate": "사양확장일",
|
"stuff.detail.header.specificationConfirmDate": "사양확정일",
|
||||||
"stuff.detail.header.lastEditDatetime": "갱신일시",
|
"stuff.detail.header.lastEditDatetime": "갱신일시",
|
||||||
"stuff.detail.header.createDatetime": "등록일",
|
"stuff.detail.header.createDatetime": "등록일",
|
||||||
"stuff.detail.required": "필수 입력항목",
|
"stuff.detail.required": "필수 입력항목",
|
||||||
@ -674,6 +676,7 @@
|
|||||||
"stuff.detail.tooltip.saleStoreId": "판매대리점 또는 판매대리점ID를 1자 이상 입력하세요",
|
"stuff.detail.tooltip.saleStoreId": "판매대리점 또는 판매대리점ID를 1자 이상 입력하세요",
|
||||||
"stuff.detail.tooltip.surfaceType": "염해지역 정의는 각 메이커의 설치 메뉴얼을 확인해주십시오",
|
"stuff.detail.tooltip.surfaceType": "염해지역 정의는 각 메이커의 설치 메뉴얼을 확인해주십시오",
|
||||||
"stuff.detail.tempSave.message1": "임시저장 되었습니다. 물건번호를 획득하려면 필수 항목을 모두 입력해 주십시오.",
|
"stuff.detail.tempSave.message1": "임시저장 되었습니다. 물건번호를 획득하려면 필수 항목을 모두 입력해 주십시오.",
|
||||||
|
"stuff.detail.tempSave.message2": "담당자는 10자리 이하로 입력해 주십시오.",
|
||||||
"stuff.detail.confirm.message1": "판매점 정보를 변경하면, 설계의뢰 문서번호가 삭제됩니다. 변경하시겠습니까?",
|
"stuff.detail.confirm.message1": "판매점 정보를 변경하면, 설계의뢰 문서번호가 삭제됩니다. 변경하시겠습니까?",
|
||||||
"stuff.detail.delete.message1": "사양이 확정된 물건은 삭제할 수 없습니다.",
|
"stuff.detail.delete.message1": "사양이 확정된 물건은 삭제할 수 없습니다.",
|
||||||
"stuff.detail.planList.title": "플랜리스트",
|
"stuff.detail.planList.title": "플랜리스트",
|
||||||
@ -735,7 +738,7 @@
|
|||||||
"stuff.search.grid.all": "전체",
|
"stuff.search.grid.all": "전체",
|
||||||
"stuff.search.grid.selected": "선택",
|
"stuff.search.grid.selected": "선택",
|
||||||
"stuff.search.grid.schSortTypeR": "최근 등록일",
|
"stuff.search.grid.schSortTypeR": "최근 등록일",
|
||||||
"stuff.search.grid.schSortTypeU": "최근 갱신일",
|
"stuff.search.grid.schSortTypeU": "최근 수정일",
|
||||||
"stuff.windSelectPopup.title": "풍속선택",
|
"stuff.windSelectPopup.title": "풍속선택",
|
||||||
"stuff.windSelectPopup.table.selected": "선택",
|
"stuff.windSelectPopup.table.selected": "선택",
|
||||||
"stuff.windSelectPopup.table.windspeed": "풍속",
|
"stuff.windSelectPopup.table.windspeed": "풍속",
|
||||||
@ -809,11 +812,14 @@
|
|||||||
"main.storeName": "판매점명",
|
"main.storeName": "판매점명",
|
||||||
"main.objectNo": "물건번호",
|
"main.objectNo": "물건번호",
|
||||||
"main.faq": "FAQ",
|
"main.faq": "FAQ",
|
||||||
|
"main.content.objectList.noData1": "등록된 물건정보가 없습니다.",
|
||||||
|
"main.content.objectList.noData2": "아래 버튼을 클릭하여 물건정보를 등록하십시오.",
|
||||||
"main.content.objectList": "최근 갱신 물건목록",
|
"main.content.objectList": "최근 갱신 물건목록",
|
||||||
"main.content.notice": "공지사항",
|
"main.content.notice": "공지사항",
|
||||||
"main.content.download1": "조작메뉴얼",
|
"main.content.download1": "조작메뉴얼",
|
||||||
"main.content.download2": "지붕설명서",
|
"main.content.download2": "지붕설명서",
|
||||||
"main.content.noBusiness": "Hanwha Japan에 문의하세요",
|
"main.content.noBusiness": "Hanwha Japan에 문의하세요",
|
||||||
|
"main.content.alert.noFile": "자료가 준비중입니다",
|
||||||
"main.popup.login.popupTitle": "비밀번호변경",
|
"main.popup.login.popupTitle": "비밀번호변경",
|
||||||
"main.popup.login.newPassword1": "새 비밀번호 입력",
|
"main.popup.login.newPassword1": "새 비밀번호 입력",
|
||||||
"main.popup.login.newPassword2": "새 비밀번호 재입력",
|
"main.popup.login.newPassword2": "새 비밀번호 재입력",
|
||||||
@ -944,5 +950,10 @@
|
|||||||
"simulator.table.sub9": "예측발전량 (kWh)",
|
"simulator.table.sub9": "예측발전량 (kWh)",
|
||||||
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
||||||
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
||||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||||
|
"can.not.move.module": "모듈을 이동할 수 없습니다.",
|
||||||
|
"can.not.copy.module": "모듈을 복사할 수 없습니다.",
|
||||||
|
"can.not.remove.module": "모듈을 삭제할 수 없습니다.",
|
||||||
|
"can.not.insert.module": "모듈을 삽입할 수 없습니다.",
|
||||||
|
"can.not.align.module": "모듈을 정렬할 수 없습니다."
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/models/apiModels.js
Normal file
42
src/models/apiModels.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// 가대 목록 Request Models
|
||||||
|
export const trestleRequestModels = {
|
||||||
|
moduleTpCd: '',
|
||||||
|
roofMatlCd: '',
|
||||||
|
raftBaseCd: '',
|
||||||
|
trestleMkrCd: '',
|
||||||
|
constMthdCd: '',
|
||||||
|
roofBaseCd: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시공법 목록 Request Models
|
||||||
|
export const constructionRequestModels = {
|
||||||
|
moduleTpCd: '',
|
||||||
|
roofMatlCd: '',
|
||||||
|
trestleMkrCd: '',
|
||||||
|
constMthdCd: '',
|
||||||
|
roofBaseCd: '',
|
||||||
|
illuminationTp: '',
|
||||||
|
instHt: '',
|
||||||
|
stdWindSpeed: '',
|
||||||
|
stdSnowLd: '',
|
||||||
|
inclCd: '',
|
||||||
|
raftBaseCd: '',
|
||||||
|
roofPitch: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가대 상세 Request Models
|
||||||
|
export const trestleDetailRequestModels = {
|
||||||
|
moduleTpCd: '',
|
||||||
|
roofMatlCd: '',
|
||||||
|
trestleMkrCd: '',
|
||||||
|
constMthdCd: '',
|
||||||
|
roofBaseCd: '',
|
||||||
|
illuminationTp: '',
|
||||||
|
instHt: '',
|
||||||
|
stdWindSpeed: '',
|
||||||
|
stdSnowLd: '',
|
||||||
|
inclCd: '',
|
||||||
|
constTp: '',
|
||||||
|
mixMatlNo: 0,
|
||||||
|
roofPitch: 0,
|
||||||
|
}
|
||||||
@ -272,17 +272,6 @@ export const plansState = atom({
|
|||||||
default: [],
|
default: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
// 변경된 canvas plan 목록
|
|
||||||
export const modifiedPlansState = atom({
|
|
||||||
key: 'modifiedPlansState',
|
|
||||||
default: [],
|
|
||||||
})
|
|
||||||
// 변경감지 flag
|
|
||||||
export const modifiedPlanFlagState = atom({
|
|
||||||
key: 'modifiedPlanFlagState',
|
|
||||||
default: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const tempGridModeState = atom({
|
export const tempGridModeState = atom({
|
||||||
key: 'tempGridModeState',
|
key: 'tempGridModeState',
|
||||||
default: false,
|
default: false,
|
||||||
|
|||||||
@ -203,8 +203,15 @@ export const basicSettingState = atom({
|
|||||||
default: {
|
default: {
|
||||||
roofSizeSet: 1,
|
roofSizeSet: 1,
|
||||||
roofAngleSet: 'slope',
|
roofAngleSet: 'slope',
|
||||||
selectedRoofMaterial: {},
|
selectedRoofMaterial: {}, // 선택된 지붕재
|
||||||
|
roofs: [], // 지붕면 할당에서 추가된 지붕재 목록
|
||||||
},
|
},
|
||||||
|
dangerouslyAllowMutability: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const addedRoofsState = atom({
|
||||||
|
key: 'addedRoofsState',
|
||||||
|
default: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
// db에 등록된 지붕재 목록
|
// db에 등록된 지붕재 목록
|
||||||
@ -213,6 +220,23 @@ export const roofMaterialsAtom = atom({
|
|||||||
default: [],
|
default: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//현재 선택된 지붕재
|
||||||
|
export const selectedRoofMaterialSelector = selector({
|
||||||
|
key: 'selectedRoofMaterialSelector',
|
||||||
|
get: ({ get }) => {
|
||||||
|
return get(basicSettingState).selectedRoofMaterial
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// QSelectBox에서 사용할 지붕재 목록
|
||||||
|
export const roofMaterialsSelector = selector({
|
||||||
|
key: 'roofMaterialsSelector',
|
||||||
|
get: ({ get }) => {
|
||||||
|
const roofMaterials = get(roofMaterialsAtom)
|
||||||
|
return roofMaterials.map((material) => ({ ...material, id: material.roofMatlCd, name: material.roofMatlNm }))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 현재 선택된 물건 번호
|
* 현재 선택된 물건 번호
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export const stuffSearchState = atom({
|
|||||||
schOtherSelSaleStoreId: '', //1차 이외 판매대리점 선택
|
schOtherSelSaleStoreId: '', //1차 이외 판매대리점 선택
|
||||||
startRow: 1,
|
startRow: 1,
|
||||||
endRow: 100,
|
endRow: 100,
|
||||||
schSortType: 'R', //정렬조건 (R:최근등록일 U:최근수정일)
|
schSortType: 'U', //정렬조건 (R:최근등록일 U:최근수정일)
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -207,6 +207,7 @@ header{
|
|||||||
.select-box{
|
.select-box{
|
||||||
min-width: 165px;
|
min-width: 165px;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
|
height: 30px;
|
||||||
>div{
|
>div{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,6 +155,7 @@
|
|||||||
.product-item-content{
|
.product-item-content{
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
.recently-list{
|
.recently-list{
|
||||||
.recently-item{
|
.recently-item{
|
||||||
border: 1px solid #F2F2F2;
|
border: 1px solid #F2F2F2;
|
||||||
@ -208,6 +209,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.recently-no-data{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
h3{
|
||||||
|
font-size: 16px;
|
||||||
|
color: #101010;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.notice-box{
|
.notice-box{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -751,16 +751,8 @@ export const pointsToTurfPolygon = (points) => {
|
|||||||
return turf.polygon([coordinates])
|
return turf.polygon([coordinates])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const polygonToTurfPolygon = (polygon) => {
|
export function isOverlap(polygon1, polygon2) {
|
||||||
const coordinates = polygon.points.map((point) => [point.x, point.y])
|
return turf.booleanOverlap(polygon1, polygon2)
|
||||||
coordinates.push(coordinates[0])
|
|
||||||
return turf.polygon(
|
|
||||||
[coordinates],
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
parentId: polygon.parentId,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const triangleToPolygon = (triangle) => {
|
export const triangleToPolygon = (triangle) => {
|
||||||
@ -792,7 +784,7 @@ export const rectToPolygon = (rect) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//면형상 선택 클릭시 지붕 패턴 입히기
|
//면형상 선택 클릭시 지붕 패턴 입히기
|
||||||
export function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false) {
|
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false) {
|
||||||
const ratio = window.devicePixelRatio || 1
|
const ratio = window.devicePixelRatio || 1
|
||||||
|
|
||||||
let width = 265 / 10
|
let width = 265 / 10
|
||||||
@ -1003,3 +995,17 @@ export function findAndRemoveClosestPoint(targetPoint, points) {
|
|||||||
|
|
||||||
return closestPoint
|
return closestPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function polygonToTurfPolygon(object, current = false) {
|
||||||
|
let coordinates
|
||||||
|
coordinates = object.points.map((point) => [point.x, point.y])
|
||||||
|
if (current) coordinates = object.getCurrentPoints().map((point) => [point.x, point.y])
|
||||||
|
coordinates.push(coordinates[0])
|
||||||
|
return turf.polygon(
|
||||||
|
[coordinates],
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
parentId: object.parentId,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -94,6 +94,11 @@ export const inputNumberCheck = (e) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 값이 숫자인지 확인
|
||||||
|
export const numberCheck = (value) => {
|
||||||
|
return !isNaN(value)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 파이프함수 정의
|
* 파이프함수 정의
|
||||||
* @param {...any} fns 순수함수들
|
* @param {...any} fns 순수함수들
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user