diff --git a/prisma/schema.prisma b/prisma/schema.prisma deleted file mode 100644 index 027c8859..00000000 --- a/prisma/schema.prisma +++ /dev/null @@ -1,28 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "sqlserver" - url = env("DATABASE_URL") -} - -model M_USER { - USER_ID String @id(map: "M_USER_pk") @db.VarChar(50) - SALE_STORE_ID String @db.VarChar(10) - PASSWORD String @db.VarChar(10) - CATEGORY String? @db.NVarChar(20) - NAME String @db.NVarChar(20) - NAME_KANA String @db.NVarChar(20) - TEL String? @db.VarChar(15) - FAX String? @db.VarChar(15) - MAIL String? @db.NVarChar(100) - GROUP_ID String @db.VarChar(5) - MODULE_SELECT_GROUP_ID String? @db.VarChar(5) - VERSION_MANAGEMENT_ID String? @db.VarChar(20) - DISP_COST_PRICE Boolean? - DISP_SELLING_PRICE Boolean? - REGIST_DATETIME DateTime? @db.DateTime - LAST_EDIT_DATETIME DateTime? @db.DateTime - LAST_EDIT_USER String? @db.VarChar(50) -} \ No newline at end of file diff --git a/public/static/images/canvas/ico-flx05.svg b/public/static/images/canvas/ico-flx05.svg new file mode 100644 index 00000000..350aee07 --- /dev/null +++ b/public/static/images/canvas/ico-flx05.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/static/images/canvas/return-btn.svg b/public/static/images/canvas/return-btn.svg new file mode 100644 index 00000000..f33f417b --- /dev/null +++ b/public/static/images/canvas/return-btn.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/app/QcastProvider.js b/src/app/QcastProvider.js index 23ad5a75..16a62d63 100644 --- a/src/app/QcastProvider.js +++ b/src/app/QcastProvider.js @@ -34,7 +34,7 @@ export const QcastProvider = ({ children }) => { const targetElement = document.getElementById('canvas') if (!targetElement && currentCanvasPlan?.id && planSave) { setPlanSave((prev) => !prev) - checkUnsavedCanvasPlan(currentCanvasPlan.userId) + checkUnsavedCanvasPlan() } else if (targetElement && currentCanvasPlan?.id) { setPlanSave(true) } diff --git a/src/app/api/html2canvas/route.js b/src/app/api/html2canvas/route.js index ada6c54a..21f93c82 100644 --- a/src/app/api/html2canvas/route.js +++ b/src/app/api/html2canvas/route.js @@ -3,6 +3,7 @@ import fs from 'fs/promises' import { NextResponse } from 'next/server' +import { writeImage, writeImageBuffer } from '@/lib/fileAction' export async function GET(req) { const path = 'public/plan-map-images' @@ -15,14 +16,7 @@ export async function GET(req) { const response = await fetch(decodeUrl) const data = await response.arrayBuffer() const buffer = Buffer.from(data) - - try { - await fs.readdir(path) - } catch { - await fs.mkdir(path) - } finally { - await fs.writeFile(`${path}/${fileNm}.png`, buffer) - } + await writeImage(fileNm, buffer) return NextResponse.json({ fileNm: `${fileNm}.png` }) } diff --git a/src/app/api/image-upload/route.js b/src/app/api/image-upload/route.js index e817bd3b..219544fe 100644 --- a/src/app/api/image-upload/route.js +++ b/src/app/api/image-upload/route.js @@ -1,25 +1,15 @@ 'use server' -import fs from 'fs/promises' - import { NextResponse } from 'next/server' +import { writeImage } from '@/lib/fileAction' export async function POST(req) { - const path = 'public/plan-bg-images' - const formData = await req.formData() const file = formData.get('file') + const fileName = formData.get('fileName') const arrayBuffer = await file.arrayBuffer() const buffer = Buffer.from(arrayBuffer) - // const buffer = new Uint8Array(arrayBuffer) + await writeImage(fileName, buffer) - try { - await fs.readdir(path) - } catch { - await fs.mkdir(path) - } finally { - await fs.writeFile(`${path}/${file.name}`, buffer) - } - - return NextResponse.json({ fileNm: `${file.name}` }) + return NextResponse.json({ fileNm: `${fileName}.png` }) } diff --git a/src/app/floor-plan/EventProvider.js b/src/app/floor-plan/EventProvider.js deleted file mode 100644 index 991b19bb..00000000 --- a/src/app/floor-plan/EventProvider.js +++ /dev/null @@ -1,34 +0,0 @@ -import { useEvent } from '@/hooks/useEvent' -import { createContext, useState } from 'react' - -export const EventContext = createContext({}) - -const EventProvider = ({ children }) => { - const { - addDocumentEventListener, - addCanvasMouseEventListener, - addTargetMouseEventListener, - removeAllMouseEventListeners, - removeAllDocumentEventListeners, - removeDocumentEvent, - removeMouseEvent, - removeMouseLine, - initEvent, - } = useEvent() - - const [value, setValue] = useState({ - addDocumentEventListener, - addCanvasMouseEventListener, - addTargetMouseEventListener, - removeAllMouseEventListeners, - removeAllDocumentEventListeners, - removeDocumentEvent, - removeMouseEvent, - removeMouseLine, - initEvent, - }) - - return {children} -} - -export default EventProvider diff --git a/src/app/floor-plan/FloorPlanProvider.js b/src/app/floor-plan/FloorPlanProvider.js index ba2a8226..37399ddd 100644 --- a/src/app/floor-plan/FloorPlanProvider.js +++ b/src/app/floor-plan/FloorPlanProvider.js @@ -2,8 +2,6 @@ import { correntObjectNoState } from '@/store/settingAtom' import { notFound, usePathname, useSearchParams } from 'next/navigation' -// import { ErrorBoundary } from 'next/dist/client/components/error-boundary' -// import ServerError from '../error' import { createContext, useReducer, useState } from 'react' import { useSetRecoilState } from 'recoil' diff --git a/src/app/floor-plan/layout.js b/src/app/floor-plan/layout.js index 532a83d6..19c730cf 100644 --- a/src/app/floor-plan/layout.js +++ b/src/app/floor-plan/layout.js @@ -3,20 +3,25 @@ import FloorPlanProvider from './FloorPlanProvider' import FloorPlan from '@/components/floor-plan/FloorPlan' import CanvasLayout from '@/components/floor-plan/CanvasLayout' -import EventProvider from './EventProvider' +import { usePathname } from 'next/navigation' export default function FloorPlanLayout({ children }) { console.log('๐Ÿš€ ~ FloorPlanLayout ~ FloorPlanLayout:') + const pathname = usePathname() + console.log('๐Ÿš€ ~ FloorPlanLayout ~ pathname:', pathname) return ( <> - - - + + + {pathname.includes('estimate') || pathname.includes('simulator') ? ( +
{children}
+ ) : ( {children} -
-
-
+ )} + {/* {children} */} + + ) } diff --git a/src/app/management/stuff/page.jsx b/src/app/management/stuff/page.jsx index 414f377b..c1a3729c 100644 --- a/src/app/management/stuff/page.jsx +++ b/src/app/management/stuff/page.jsx @@ -1,7 +1,9 @@ -import StuffSearchCondition from '@/components/management/StuffSearchCondition' import Stuff from '@/components/management/Stuff' +import StuffSearchCondition from '@/components/management/StuffSearchCondition' import StuffSubHeader from '@/components/management/StuffSubHeader' + import '@/styles/grid.scss' + export default async function ManagementStuffPage() { return ( <> diff --git a/src/app/management/stuff/tempReg/page.jsx b/src/app/management/stuff/tempReg/page.jsx new file mode 100644 index 00000000..ce7e684a --- /dev/null +++ b/src/app/management/stuff/tempReg/page.jsx @@ -0,0 +1,18 @@ +import React from 'react' +import StuffSubHeader from '@/components/management/StuffSubHeader' +import '@/styles/contents.scss' +import StuffDetail from '@/components/management/StuffDetail' +export default function ManagementStuffRegPage() { + return ( + <> + +
+
+
+ +
+
+
+ + ) +} diff --git a/src/common/common.js b/src/common/common.js index 02a953fe..9bf6d367 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -161,6 +161,7 @@ export const SAVE_KEY = [ 'surfaceCompass', 'moduleCompass', 'isFixed', + 'modules', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/components/Main.jsx b/src/components/Main.jsx index e3c491e3..29d1305a 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -15,6 +15,7 @@ import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' export default function MainPage() { + const [chagePasswordPopOpen, setChagePasswordPopOpen] = useState(false) const { session } = useContext(SessionContext) const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -27,37 +28,12 @@ export default function MainPage() { const [searchRadioType, setSearchRadioType] = useState('object') - // const [saleStoreId, setSaleStoreId] = useState('') - // const [saleStoreName, setSaleStoreName] = useState('') - const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const [searchForm, setSearchForm] = useRecoilState(searchState) const { qcastState } = useContext(QcastContext) - // useEffect(() => { - // if (session.pwdInitYn === 'Y') { - // fetchObjectList() - // } - // }, [session]) - - const fetchObjectList = async () => { - try { - const apiUrl = `/api/main-page/object/${session?.storeId}/list` - await promiseGet({ - url: apiUrl, - }).then((res) => { - if (res.status === 200) { - setSaleStoreId(res.data.saleStoreId) - setSaleStoreName(res.data.saleStoreName) - } - }) - } catch (error) { - console.error('MAIN API fetching error:', error) - } - } - // ์—”ํ„ฐ ์ด๋ฒคํŠธ const handleByOnKeyUp = (e) => { if (e.key === 'Enter') { @@ -68,7 +44,7 @@ export default function MainPage() { schObjectNo: searchTxt, code: 'M', }) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else { setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) router.push('/community/faq') @@ -90,16 +66,22 @@ export default function MainPage() { code: 'M', }) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else { setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) router.push('/community/faq') } } + useEffect(() => { + if (session?.pwdInitYn !== 'Y') { + setChagePasswordPopOpen(true) + } + }, [session]) + return ( <> - {(session?.pwdInitYn !== 'N' && ( + {(!chagePasswordPopOpen && ( <>
@@ -143,7 +125,7 @@ export default function MainPage() { )) || ( <> - + )} diff --git a/src/components/common/color-picker/ColorPickerModal.jsx b/src/components/common/color-picker/ColorPickerModal.jsx index 03d9899f..37a5343c 100644 --- a/src/components/common/color-picker/ColorPickerModal.jsx +++ b/src/components/common/color-picker/ColorPickerModal.jsx @@ -8,13 +8,13 @@ import { contextPopupPositionState } from '@/store/popupAtom' export default function ColorPickerModal(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) // ํ˜„์žฌ ๋ฉ”๋‰ด - const { isShow, setIsShow, pos = contextPopupPosition, color = '#ff0000', setColor, id, isConfig = false } = props - const { getMessage } = useMessage() + const { isShow, setIsShow, pos = contextPopupPosition, color, setColor, id, isConfig = false } = props //color = '#ff0000' const [originColor, setOriginColor] = useState(color) + const { getMessage } = useMessage() const { closePopup } = usePopup() useEffect(() => { - setOriginColor(color) + setOriginColor(originColor) }, [isShow]) return ( diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index a52f8423..1d3b18ae 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1,7 +1,7 @@ 'use client' import { useEffect, useState, useContext } from 'react' -import { useRecoilValue } from 'recoil' +import { useRecoilValue, useSetRecoilState } from 'recoil' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { useMessage } from '@/hooks/useMessage' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' @@ -9,7 +9,7 @@ import SingleDatePicker from '../common/datepicker/SingleDatePicker' import EstimateFileUploader from './EstimateFileUploader' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' -import { isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' +import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import dayjs from 'dayjs' import { useCommonCode } from '@/hooks/common/useCommonCode' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' @@ -18,8 +18,11 @@ import Select, { components } from 'react-select' import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils' import ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' +import { correntObjectNoState } from '@/store/settingAtom' +import { useSearchParams } from 'next/navigation' export default function Estimate({ params }) { + const [uniqueData, setUniqueData] = useState([]) const [handlePricingFlag, setHandlePricingFlag] = useState(false) const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false) const fixedKey = 'itemKey' @@ -73,6 +76,15 @@ export default function Estimate({ params }) { const { setMenuNumber } = useCanvasMenu() + /** + * objectNo ์…‹ํŒ… + * url๋กœ ๋„˜์–ด์˜จ objectNo์„ ๋ฆฌ์ฝ”์ผ์— ์„ธํŒ… + */ + const setCurrentObjectNo = useSetRecoilState(correntObjectNoState) + const searchParams = useSearchParams() + const currentObjectNo = searchParams.get('objectNo') + setCurrentObjectNo(currentObjectNo) + //์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ์ฒจ๋ถ€ํŒŒ์ผ props const fileUploadProps = { uploadFiles: files, @@ -119,11 +131,9 @@ export default function Estimate({ params }) { let url = `/api/estimate/special-note-title-list` get({ url: url }).then((res) => { if (isNotEmptyArray(res)) { - //๋””ํ…Œ์ผ ATTR001ใ€ATTR002ใ€ATTR003ใ€ATTR007ใ€ATTR009ใ€ATTR010ใ€ATTR015ใ€ATTR019 if (estimateContextState?.estimateOption) { res.map((row) => { let estimateOption = estimateContextState?.estimateOption?.split('ใ€') - // console.log('์ตœ์ดˆ:::', estimateOption) row.check = false estimateOption.map((row2) => { if (row.pkgYn === '0') { @@ -140,10 +150,10 @@ export default function Estimate({ params }) { //detail๊ณผ ์ƒ๊ด€์—†์ด ๋””ํดํŠธ ์ฒดํฌ๋ชฉ๋ก //ATTR003,ATTR007 if (row.code === 'ATTR003') { - row.check = true + //row.check = true } if (row.code === 'ATTR007') { - row.check = true + //row.check = true } }) @@ -167,14 +177,20 @@ export default function Estimate({ params }) { //๊ฒฌ์ ์ผ set useEffect(() => { - let estimateDate = dayjs(startDate).format('YYYY-MM-DD') - if (begin === 1) { - setEstimateContextState({ estimateDate: estimateDate }) + let estimateDate + if (startDate) { + estimateDate = dayjs(startDate).format('YYYY-MM-DD') + if (begin === 1) { + setEstimateContextState({ estimateDate: estimateDate }) + } + } else { + setEstimateContextState({ estimateDate: '' }) } }, [startDate]) useEffect(() => { //์„ ํƒ๋œ ๊ฒฌ์ ํŠน์ด์‚ฌํ•ญ setEstimateContextState + if (isNotEmptyArray(specialNoteList)) { const liveCheckedData = specialNoteList.filter((row) => row.check === true) @@ -184,14 +200,14 @@ export default function Estimate({ params }) { } const newData = data.join('ใ€') - setEstimateContextState({ estimateOption: newData }) + //์ €์žฅ์šฉ ๋ณด๋‚ด๊ธฐ + setEstimateContextState({ estimateOption: newData, specialNoteList: specialNoteList, uniqueData: uniqueData }) } }, [specialNoteList]) // ๊ฒฌ์ ํŠน์ด์‚ฌํ•ญ remark ๋ณด์—ฌ์ฃผ๊ธฐ - const settingShowContent = (code, event) => { + const settingShowContent = (code) => { setShowContentCode(code) - event.stopPropagation() } // ์ถ”๊ฐ€ํ•œ ์ฒจ๋ถ€ํŒŒ์ผ estimateContextState์— ๋„ฃ๊ธฐ @@ -200,10 +216,11 @@ export default function Estimate({ params }) { let fileList = [] files.map((row) => { fileList.push(row.data) - setEstimateContextState({ fileList: row.data, tempFileList: fileList }) + setEstimateContextState({ fileList: row.data, newFileList: fileList }) + // setEstimateContextState({ fileList: row.data }) }) } else { - setEstimateContextState({ fileList: [] }) + setEstimateContextState({ fileList: [], newFileList: [] }) } }, [files]) @@ -213,26 +230,49 @@ export default function Estimate({ params }) { //๋“œ๋ž˜๊ทธ์˜์—ญ ๋น„์›Œ์ฃผ๊ธฐ setFiles([]) setOriginFiles(estimateContextState.fileList) + } else { + if (originFiles.length > 0) { + if (isEmptyArray(files)) { + let file + file = originFiles.filter((item) => item.delFlg === '0') + setEstimateContextState({ + originFiles: file, + }) + setOriginFiles(file) + } + } } }, [estimateContextState?.fileList]) - // ๊ธฐ์กด์ฒจ๋ถ€ํŒŒ์ผ ์‚ญ์ œ - const deleteOriginFile = async (objectNo, no) => { - const delParams = { - userId: session.userId, - objectNo: objectNo, - no: no, - } - await promisePost({ url: 'api/file/fileDelete', data: delParams }).then((res) => { - if (res.status === 204) { - setOriginFiles(originFiles.filter((file) => file.objectNo === objectNo && file.no !== no)) - setEstimateContextState({ - fileList: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no), - }) - - alert(getMessage('plan.message.delete')) + // ์‚ญ์ œ๋ˆ„๋ฅธ ์ฒจ๋ถ€ํŒŒ์ผ ๋ณต์› + const returnOriginFile = (no) => { + originFiles.map((file) => { + if (file.no === no) { + file.delFlg = '0' } }) + setOriginFiles((prev) => { + return [...prev] + }) + setEstimateContextState({ + originFiles: originFiles, + }) + } + // ๊ธฐ์กด์ฒจ๋ถ€ํŒŒ์ผ ์‚ญ์ œ (ํ”Œ๋ž˜๊ทธ๊ฐ’ ์ถ”๊ฐ€?) ์ €์žฅํ• ๋•Œ ํ”Œ๋ž˜๊ทธ๊ฐ’์— ๋”ฐ๋ผ ์ง„์งœ ์‚ญ์ œ + const deleteOriginFile = (no) => { + originFiles.map((file) => { + if (file.no === no) { + file.delFlg = '1' + } + }) + + setOriginFiles((prev) => { + return [...prev] + }) + setEstimateContextState({ + originFiles: originFiles, + }) + alert(getMessage('estimate.detail.alert.delFile')) } //๊ฐ€๊ฒฉํ‘œ์‹œ option ๋ชฉ๋ก ์ตœ์ดˆ์„ธํŒ… && ์ฃผ๋ฌธ๋ถ„๋ฅ˜ ๋ณ€๊ฒฝ์‹œ @@ -291,22 +331,66 @@ export default function Estimate({ params }) { //๊ฐ€๊ฒฉ ํ‘œ์‹œ option ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ const onChangeStorePriceList = (priceCd) => { - const param = { - saleStoreId: session.storeId, - sapSalesStoreCd: session.custCd, - docTpCd: priceCd, - } - //ํ”„๋ผ์ด์‹ฑ ํ–ˆ์„๋•Œ priceCd setEstimateContextState //ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ๊ฐ’์€ showPriceCd๋กœ ๊ด€๋ฆฌ setShowPriceCd(priceCd) + // return + // const param = { + // saleStoreId: session.storeId, + // sapSalesStoreCd: session.custCd, + // docTpCd: priceCd, + // } - const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}` - get({ url: apiUrl }).then((res) => { - if (isNotEmptyArray(res?.data)) { - setStorePriceList(res.data) + // const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}` + // get({ url: apiUrl }).then((res) => { + // if (isNotEmptyArray(res?.data)) { + // setStorePriceList(res.data) + // } + // }) + } + + const makeUniqueSpecialNoteCd = (itemList) => { + let pushData = [] + let uniquSet = new Set() + + itemList.forEach((item) => { + if (item.delFlg === '0') { + if (item.specialNoteCd) { + let splitData = item.specialNoteCd.split('ใ€') + splitData.forEach((note) => { + if (!uniquSet.has(note)) { + uniquSet.add(note) + pushData.push(note) + } + }) + + setSpecialNoteFirstFlg(false) + } } }) + + setUniqueData(pushData) + specialNoteList.map((item) => { + if (item.pkgYn === '1') { + let flg = '0' + let codes = item.code + for (let i = 0; i < pushData.length; i++) { + if (codes.indexOf(pushData[i]) > -1) { + flg = '1' + } + } + + if (flg === '1') { + item.check = true + } else { + item.check = false + } + } + }) + setEstimateContextState({ + specialNoteList: specialNoteList, + uniqueData: uniqueData, + }) } //Pricing ๋ฒ„ํŠผ @@ -351,23 +435,26 @@ export default function Estimate({ params }) { if (isNotEmptyArray(data.data2)) { estimateContextState.itemList.map((item) => { let checkYn = false - data.data2.map((item2) => { - if (item2) { - if (item2.itemId === item.itemId) { + for (let i = 0; i < data.data2.length; i++) { + if (data.data2[i]) { + if (data.data2[i].itemId === item.itemId) { updateList.push({ ...item, - salePrice: item2.unitPrice === null ? '0' : item2.unitPrice, - saleTotPrice: (item.amount * item2.unitPrice).toString(), + openFlg: data.data2[i].unitPrice === '0.0' ? '1' : '0', + salePrice: data.data2[i].unitPrice === null ? '0' : data.data2[i].unitPrice, + saleTotPrice: (item.amount * data.data2[i].unitPrice).toString(), }) checkYn = true + break } } - }) + } if (!checkYn) { updateList.push({ ...item, salePrice: '0', saleTotPrice: '0' }) } }) + setEstimateContextState({ priceCd: showPriceCd, itemList: updateList, @@ -411,23 +498,41 @@ export default function Estimate({ params }) { setSelection(newSelection) } + function formatNumberWithComma(number) { + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + } + //์ฃผํƒPKG input ๋ณ€๊ฒฝ const onChangePkgAsp = (value) => { if (estimateContextState.estimateType === 'YJSS') { - let pkgAsp = Number(value.replaceAll(',', '')) - if (isNaN(pkgAsp)) { - pkgAsp = 0 - } else { - pkgAsp = pkgAsp.toLocaleString() + let newValue = value.replace(/[^0-9.]/g, '') + if (newValue.length > 1) { + newValue = newValue.replace(/(^0+)/, '') + if (newValue.length === 0) { + newValue = '0' + } } - //ํ˜„์žฌ PKG์šฉ๋Ÿ‰๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ + const parts = newValue.split('.') + if (parts.length > 2) { + newValue = parts[0] + '.' + parts.slice(1).join('') + } + + if (parts[1] && parts[1].length > 2) { + newValue = parts[0] + '.' + parts[1].substring(0, 2) + } + + let pkgAsp = newValue || '0' + + //ํ˜„์žฌ PKG์šฉ๋Ÿ‰๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ let totVolKw = estimateContextState.totVolKw * 1000 - let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw * 1000 + let pkgTotPrice = parseFloat(pkgAsp?.replaceAll(',', '')) * totVolKw * 1000 + + // pkgAsp = formatNumberWithComma(parseFloat(pkgAsp).toFixed(2)) setEstimateContextState({ pkgAsp: pkgAsp, - pkgTotPrice: pkgTotPrice.toFixed(3), + pkgTotPrice: pkgTotPrice.toFixed(2), }) //์•„์ดํ…œ๋“ค ์ค‘ ์กฐ๊ฑด์— ๋งž๋Š”์• ๋“ค ๋ฝ‘์•„์„œ ์ƒ๋‹จ ๊ณต๊ธ‰๊ฐ€์•ก ๋ถ€๊ฐ€์„ธ ์ด์•ก ์ˆ˜์ • setItemChangeYn(true) @@ -438,6 +543,7 @@ export default function Estimate({ params }) { const onChangeAmount = (value, dispOrder, index) => { //itemChangeFlg = 1, partAdd = 0 ์…‹ํŒ… let amount = Number(value.replace(/[^0-9]/g, '').replaceAll(',', '')) + if (isNaN(amount)) { amount = '0' } else { @@ -511,7 +617,7 @@ export default function Estimate({ params }) { let updateList = [] let updates = {} get({ url: apiUrl }).then((res) => { - console.log('์•„์ดํ…œ๋””ํ…Œ์ผ::::::::', res) + // console.log('์•„์ดํ…œ๋””ํ…Œ์ผ::::::::', res) updates.objectNo = objectNo updates.planNo = planNo updates.itemId = res.itemId @@ -526,22 +632,27 @@ export default function Estimate({ params }) { updates.pkgMaterialFlg = res.pkgMaterialFlg updates.pnowW = res.pnowW updates.salePrice = res.salePrice - // updates.salePrice = '' updates.specification = res.specification updates.unit = res.unit updates.specialNoteCd = res.spnAttrCds updates.itemGroup = res.itemGroup updates.delFlg = '0' // ์‚ญ์ œํ”Œ๋ž˜๊ทธ 0 updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() - // updates.saleTotPrice = '' updates.amount = '' + updates.openFlg = res.openFlg if (estimateContextState.estimateType === 'YJSS') { if (res.pkgMaterialFlg === '0') { updates.showSalePrice = '0' updates.showSaleTotPrice = '0' } + } else { + if (res.openFlg === '1') { + updates.showSalePrice = '0' + updates.showSaleTotPrice = '0' + } } + //104671 let bomList = res.itemBomList @@ -557,7 +668,6 @@ export default function Estimate({ params }) { } } } else if (item.paDispOrder === dispOrder) { - //๋ด„์ œํ’ˆ์„ ๋ฐ”๊ฟจ์„๋–„ return { ...item, delFlg: '1' } } else { return item @@ -574,19 +684,23 @@ export default function Estimate({ params }) { bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' + bomItem.showSalePrice = '0' } else { bomItem.dispOrder = (index + 1 + Number(dispOrder)).toString() bomItem.paDispOrder = dispOrder bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' + bomItem.showSalePrice = '0' } bomItem.delFlg = '0' bomItem.objectNo = objectNo bomItem.planNo = planNo + bomItem.addFlg = true //๋ด„ ์ถ”๊ฐ€์‹œ๋„ addFlg }) + updateList = updateList.filter((item) => item.delFlg === '0') setEstimateContextState({ itemList: [...updateList, ...bomList], }) @@ -603,6 +717,9 @@ export default function Estimate({ params }) { //์ œํ’ˆ ์‚ญ์ œ const removeItem = () => { const array = [...selection] + if (isEmptyArray(array)) { + return alert(getMessage('estimate.detail.alert.selectDelItem')) + } let delList = [] estimateContextState.itemList.filter((row) => { array.map((row2) => { @@ -644,135 +761,147 @@ export default function Estimate({ params }) { useEffect(() => { if (itemChangeYn) { - let totAmount = 0 - let totVolKw = 0 - let supplyPrice = 0 - let vatPrice = 0 - let totPrice = 0 - let addSupplyPrice = 0 - if (estimateContextState.estimateType === 'YJOD') { - estimateContextState.itemList.sort((a, b) => { - return a.dispOrder - b.dispOrder - }) - console.log('YJOD ํ† ํƒˆ๋งŒ๋“ค์–ด์ฃผ๊ธฐ::::::::::', estimateContextState.itemList) + let totals = { + totAmount: 0, + totVolKw: 0, + supplyPrice: 0, + vatPrice: 0, + totPrice: 0, + addSupplyPrice: 0, + pkgTotPrice: 0, + } - let pushData = [] - let uniquSet = new Set() + const calculateYJODTotals = (itemList) => { + itemList.sort((a, b) => a.dispOrder - b.dispOrder) + makeUniqueSpecialNoteCd(itemList) - estimateContextState.itemList.forEach((item) => { - if (item.delFlg === '1') { - if (item.specialNoteCd) { - let splitData = item.specialNoteCd.split('ใ€') - splitData.forEach((note) => { - if (!uniquSet.has(note)) { - uniquSet.add(note) - pushData.push(note) - } - }) - - setSpecialNoteFirstFlg(false) - } - } - }) - - estimateContextState.itemList.map((item) => { + itemList.forEach((item) => { delete item.showSalePrice delete item.showSaleTotPrice if (item.delFlg === '0') { - let amount = Number(item?.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) - if (isNaN(amount)) { - amount = '0' - } - let price = Number(item?.saleTotPrice?.replaceAll(',', '')) - if (isNaN(price)) { + let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 + let price + if (amount === 0) { price = 0 + } else { + price = Number(item.saleTotPrice?.replaceAll(',', '')) || 0 } + if (item.moduleFlg === '1') { - //์šฉ๋Ÿ‰(Kw)์€ ๋ชจ๋“ˆํ”Œ๋ž˜๊ทธ 1๋งŒ ํ•ฉ์‚ฐ const volKw = (item.pnowW * amount) / 1000 - // const volKw = item.pnowW * amount - totVolKw += volKw + totals.totVolKw += volKw + } + totals.supplyPrice += price + totals.totAmount += amount + + if (item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + if (item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' } - // const price - totAmount += amount - supplyPrice += price } }) - vatPrice = supplyPrice * 0.1 - totPrice = supplyPrice + vatPrice + totals.vatPrice = totals.supplyPrice * 0.1 + totals.totPrice = totals.supplyPrice + totals.vatPrice + } - setEstimateContextState({ - totAmount: totAmount, - totVolKw: totVolKw.toFixed(3), - supplyPrice: supplyPrice.toFixed(3), - vatPrice: vatPrice.toFixed(3), - totPrice: totPrice.toFixed(3), - }) - } else { - //YJSS - console.log('YJSS ํ† ํƒˆ๋งŒ๋“ค์–ด์ฃผ๊ธฐ::::::::::', estimateContextState.itemList) - estimateContextState.itemList.sort((a, b) => { - return a.dispOrder - b.dispOrder - }) - estimateContextState.itemList.map((item) => { + const calculateYJSSTotals = (itemList) => { + itemList.sort((a, b) => a.dispOrder - b.dispOrder) + makeUniqueSpecialNoteCd(itemList) + itemList.forEach((item) => { if (item.delFlg === '0') { - let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) - let salePrice = Number(item.salePrice?.replaceAll(',', '')) - let saleTotPrice = Number(item.saleTotPrice?.replaceAll(',', '')) - - if (isNaN(amount)) { - amount = '0' - } - - if (isNaN(saleTotPrice)) { - saleTotPrice = 0 - } - - if (isNaN(salePrice)) { - salePrice = 0 - } + let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 + let salePrice if (item.moduleFlg === '1') { - //์šฉ๋Ÿ‰(Kw)์€ ๋ชจ๋“ˆํ”Œ๋ž˜๊ทธ 1๋งŒ ํ•ฉ์‚ฐ const volKw = (item.pnowW * amount) / 1000 - // const volKw = item.pnowW * amount - totVolKw += volKw + totals.totVolKw += volKw } - setEstimateContextState({ - pkgTotPrice: estimateContextState.pkgAsp.replaceAll(',', '') * totVolKw * 1000, - }) - //pkgTotPrice - // const saleTotPrice - totAmount += amount + if (amount === 0) { + salePrice = 0 + } else { + salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 + } + + totals.totAmount += amount if (item.pkgMaterialFlg === '1') { - const pkgPrice = amount * salePrice - //๋‹ค์‹œ๊ณ„์‚ฐํ•˜๊ธฐ - //YJSS๋Š” PKG์ œ์™ธ์ƒํ’ˆ๋“ค๋งŒ(1) ๋ชจ์•„์„œ ์ˆ˜๋Ÿ‰ * ๋‹จ๊ฐ€๋ฅผ ๊ณต๊ธ‰๊ฐ€์•ก(supplyPrice)์— ์ถ”๊ฐ€๋กœ ๋”ํ•ด์คŒ - addSupplyPrice += pkgPrice + const saleTotPrice = amount * salePrice + totals.addSupplyPrice += saleTotPrice } if (!item.paDispOrder) { - //paDispOrder if (item.pkgMaterialFlg === '0') { item.showSalePrice = '0' item.showSaleTotPrice = '0' } + } else { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + + if (item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' } } }) - supplyPrice = addSupplyPrice + Number(estimateContextState.pkgTotPrice / 1000) - vatPrice = supplyPrice * 0.1 - totPrice = supplyPrice + vatPrice + let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0 + + totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000 + totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice + totals.vatPrice = totals.supplyPrice * 0.1 + totals.totPrice = totals.supplyPrice + totals.vatPrice + } + if (estimateContextState.estimateType === 'YJOD') { + calculateYJODTotals(estimateContextState.itemList) setEstimateContextState({ - totAmount: totAmount, - totVolKw: totVolKw.toFixed(3), - supplyPrice: supplyPrice.toFixed(3), - vatPrice: vatPrice.toFixed(3), - totPrice: totPrice.toFixed(3), + totAmount: totals.totAmount, + totVolKw: totals.totVolKw.toFixed(2), + supplyPrice: totals.supplyPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + vatPrice: totals.vatPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + totPrice: totals.totPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + }) + } else if (estimateContextState.estimateType === 'YJSS') { + calculateYJSSTotals(estimateContextState.itemList) + setEstimateContextState({ + pkgTotPrice: totals.pkgTotPrice, + totAmount: totals.totAmount, + totVolKw: totals.totVolKw.toFixed(2), + supplyPrice: totals.supplyPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + vatPrice: totals.vatPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + totPrice: totals.totPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ }) } setItemChangeYn(false) + } else { + estimateContextState.itemList.forEach((item) => { + if (estimateContextState.estimateType === 'YJSS' && !item.paDispOrder && item.pkgMaterialFlg === '0') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + if (estimateContextState.estimateType === 'YJSS' && item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + if (estimateContextState.estimateType === 'YJSS' && item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + }) + estimateContextState.itemList.forEach((item) => { + if (estimateContextState.estimateType === 'YJOD' && item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + if (estimateContextState.estimateType === 'YJOD' && item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + }) } }, [itemChangeYn, estimateContextState.itemList]) @@ -966,18 +1095,15 @@ export default function Estimate({ params }) { } //์‚ฌ์–‘์‹œ๊ณต let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('ใ€') - return ( - <> -
-
- -
-
- -
+
+
+
- +
+ +
+
) })} @@ -987,7 +1113,7 @@ export default function Estimate({ params }) { {getMessage('estimate.detail.remarks')}
- +
@@ -1064,18 +1190,38 @@ export default function Estimate({ params }) {
    {originFiles.map((originFile) => { return ( -
  • - handleEstimateFileDownload(originFile)}> - {originFile.faileName} - - +
  • + {/*
  • */} +
    + handleEstimateFileDownload(originFile)} + > + {originFile.faileName} + + +
    + {originFile.faileName} + +
    +
  • ) })} @@ -1108,29 +1254,31 @@ export default function Estimate({ params }) { {specialNoteList.length > 0 && specialNoteList.map((row) => { return ( -
    { - // settingShowContent(row.code, event) - }} - > -
    - { - setSpecialNoteList((specialNote) => - specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), - ) - settingShowContent(row.code, event) + //
    +
    +
    +
    + { + setSpecialNoteList((specialNote) => + specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), + ) + }} + /> + +
    + { + settingShowContent(row.code) }} - /> - + > + {row.codeNm} +
    ) @@ -1146,7 +1294,7 @@ export default function Estimate({ params }) { if (isObjectNotEmpty(showcontent)) { return ( -
    +
    {showcontent.codeNm}
    @@ -1161,12 +1309,23 @@ export default function Estimate({ params }) { } }) }) - return pushData.map((item) => ( -
    -
    {item.codeNm}
    -
    -
    - )) + //์ œํ’ˆ์— ์žˆ๋Š” ํŠน์ด์‚ฌํ•ญ๋งŒ ๋ณด์—ฌ์ฃผ๊ธฐ ์ œํ’ˆ์— ํŠน์ด์‚ฌํ•ญ์ด ์—†์œผ๋ฉด ์ „๋ถ€ + let filterData = pushData.filter((item) => uniqueData.includes(item.code)) + if (filterData.length > 0) { + return filterData.map((item) => ( +
    +
    {item.codeNm}
    +
    +
    + )) + } else { + return pushData.map((item) => ( +
    +
    {item.codeNm}
    +
    +
    + )) + } } } })} @@ -1192,19 +1351,19 @@ export default function Estimate({ params }) {
    {getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}
    -
    {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.supplyPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.supplyPrice, 0)}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.vatPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.vatPrice, 0)}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.totPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.totPrice, 0)}
    @@ -1238,7 +1397,7 @@ export default function Estimate({ params }) {
{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')} - {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)} + {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)} {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')} {convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)} @@ -1253,14 +1412,18 @@ export default function Estimate({ params }) {
{session?.storeLvl === '1' ? ( ) : ( @@ -1371,7 +1533,7 @@ export default function Estimate({ params }) {
handleRefFileMethod(e)} checked={refFileMethod === '1'} /> - +
- {/* - */} - {currentCanvasPlan?.bgImageName === null ? ( - - ) : ( - - )} - {(refImage || currentCanvasPlan?.bgImageName) && } + + {refImage && }
handleRefFileMethod(e)} checked={refFileMethod === '2'} /> - +
setMapPositionAddress(e.target.value)} />
-
- {mapPositionAddress && } + {mapPositionAddress && } {/* */}
diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index af5d9037..ea46bd3b 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -20,7 +20,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const orientationRef = useRef(null) const { initEvent } = useEvent() // const { initEvent } = useContext(EventContext) - const { makeModuleInstArea, manualModuleSetup, autoModuleSetup } = useModuleBasicSetting() + const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup } = useModuleBasicSetting() const handleBtnNextStep = () => { if (tabNum === 1) { orientationRef.current.handleNextStep() @@ -28,20 +28,16 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { setTabNum(tabNum + 1) } - useEffect(() => { - makeModuleInstArea() //๊ธฐ๋ถ• ๋ชจ๋“ˆ์„ค์น˜๋ฉด ์ƒ์„ฑ - - return () => { - initEvent() //๋ชจ๋“ˆ์„ค์น˜๋ฉด ์„ ํƒ ์ด๋ฒคํŠธ ์‚ญ์ œ - } - }, []) - const placementRef = { isChidori: useRef('false'), setupLocation: useRef('center'), isMaxSetup: useRef('false'), } + const placementFlatRef = { + setupLocation: useRef('south'), + } + return (
@@ -66,7 +62,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {/*๋ฐฐ์น˜๋ฉด ์ดˆ๊ธฐ์„ค์ • - ์ž…๋ ฅ๋ฐฉ๋ฒ•: ์œก์ง€๋ถ•*/} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && } - {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && } + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && ( + + )}
{tabNum !== 1 && ( @@ -80,14 +78,29 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { Next )} + {tabNum === 3 && ( <> - - + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && ( + <> + + + + )} + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet === 3 && ( + <> + + + + )} )}
diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index b080b1b1..296cce4a 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -34,7 +34,7 @@ export const Orientation = forwardRef(({ tabNum }, ref) => { onClick={() => setCompasDeg(15 * (12 + index))} > {index === 0 && 180ยฐ} - {index === 6 && 270ยฐ} + {index === 6 && -90ยฐ}
))} {Array.from({ length: 180 / 15 }).map((dot, index) => ( @@ -56,7 +56,7 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
setHasAnglePassivity(!hasAnglePassivity)} /> - +
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 13c48a08..a087f3dc 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -1,5 +1,6 @@ +import { forwardRef, useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' -import { forwardRef, useState } from 'react' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() @@ -7,6 +8,12 @@ const Placement = forwardRef((props, refs) => { const [setupLocation, setSetupLocation] = useState('center') const [isMaxSetup, setIsMaxSetup] = useState('false') + const { makeModuleInstArea } = useModuleBasicSetting() + + useEffect(() => { + makeModuleInstArea() + }, []) + const moduleData = { header: [ { type: 'check', name: '', prop: 'check', width: 70 }, diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx index a2dcd556..7b00478e 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -1,7 +1,26 @@ +import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' +import { compasDegAtom } from '@/store/orientationAtom' +import { canvasState } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' +import { POLYGON_TYPE } from '@/common/common' -export default function PitchPlacement() { +const PitchPlacement = forwardRef((props, refs) => { const { getMessage } = useMessage() + const [setupLocation, setSetupLocation] = useState('south') + const { makeModuleInstArea } = useModuleBasicSetting() + const compasDeg = useRecoilValue(compasDegAtom) + const canvas = useRecoilValue(canvasState) + + useEffect(() => { + makeModuleInstArea() + }, []) + + useEffect(() => { + handleChangeSetupLocation() + }, [setupLocation]) + const moduleData = { header: [ { type: 'check', name: '', prop: 'check', width: 70 }, @@ -24,6 +43,45 @@ export default function PitchPlacement() { }, ], } + + const handleSetupLocation = (e) => { + refs.setupLocation.current = e.target + setSetupLocation(e.target.value) + } + + const handleChangeSetupLocation = () => { + if (setupLocation === 'south') { + canvas.getObjects().forEach((obj) => obj.name === 'flatExcretaLine' && canvas.remove(obj)) + return null + } else { + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //๋ชจ๋“ˆ์„ค์น˜๋ฉด๋ฅผ ๊ฐ€์ ธ์˜ด + moduleSetupSurfaces.forEach((surface, index) => { + console.log(`surface ${index} : `, surface) + + const excretaLine = surface.lines + + excretaLine.forEach((line) => { + line.set({ + stroke: '#642EFB', + strokeWidth: 5, + surfaceId: surface.surfaceId, + name: 'flatExcretaLine', + }) + canvas.add(line) + + line.on('selected', () => { + excretaLine.forEach((obj) => obj.set({ stroke: '#642EFB', isSelected: false })) + if (!line.isSelected) { + line.set({ stroke: 'red', isSelected: true }) + } else { + line.set({ stroke: '#642EFB', isSelected: false }) + } + }) + }) + }) + } + } + return ( <>
@@ -88,11 +146,26 @@ export default function PitchPlacement() {
- +
- +
@@ -102,4 +175,6 @@ export default function PitchPlacement() {
) -} +}) + +export default PitchPlacement diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index f4caa40b..3928353c 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -1,54 +1,44 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import QSelectBox from '@/components/common/select/QSelectBox' -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' -import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom' -import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' import { onlyNumberInputChange } from '@/util/input-utils' -import { settingModalGridOptionsState } from '@/store/settingAtom' -import { useAxios } from '@/hooks/useAxios' -import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useSwal } from '@/hooks/useSwal' const TYPE = { DOT: 'DOT', LINE: 'LINE', } -const defaultDotLineGridSetting = { - INTERVAL: { - type: 2, // 1: ๊ฐ€๋กœ,์„ธ๋กœ ๊ฐ„๊ฒฉ ์ˆ˜๋™, 2: ๋น„์œจ ๊ฐ„๊ฒฉ - ratioInterval: 910, - verticalInterval: 910, - horizontalInterval: 910, - dimension: 1, // ์น˜์ˆ˜ - }, - DOT: false, - LINE: false, -} - export default function DotLineGrid(props) { // const [modalOption, setModalOption] = useRecoilState(modalState); //modal ์—ด๋ฆผ๋‹ซํž˜ state - const [objectNo, setObjectNo] = useState('test123240912001') // ์ดํ›„ ์‚ญ์ œ ํ•„์š” - const [close, setClose] = useState(false) + //const interval = useRecoilValue(dotLineIntervalSelector) const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false } = props - const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) - const canvas = useRecoilValue(canvasState) - const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) - const [currentSetting, setCurrentSetting] = useState( - JSON.stringify(dotLineGridSetting) === JSON.stringify(defaultDotLineGridSetting) ? { ...defaultDotLineGridSetting } : { ...dotLineGridSetting }, - ) - const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) - const interval = useRecoilValue(dotLineIntervalSelector) - const { getMessage } = useMessage() - const { get, post } = useAxios() - const { swalFire } = useSwal() const { closePopup } = usePopup() + const { swalFire } = useSwal() + const { + selectOption, + setSelectOption, + SelectOptions, + currentSetting, + setCurrentSetting, + dotLineGridSettingState, + setSettingModalGridOptions, + setDotLineGridSettingState, + } = useCanvasSetting() + + // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ useEffect(() => { + console.log('DotLineGrid useEffect ์‹คํ–‰') + return () => { setSettingModalGridOptions((prev) => { const newSettingOptions = [...prev] @@ -58,20 +48,6 @@ export default function DotLineGrid(props) { } }, []) - const SelectOption = [ - { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, - { id: 2, name: '1/2', value: 1 / 2 }, - { id: 3, name: '1/4', value: 1 / 4 }, - { id: 4, name: '1/10', value: 1 / 10 }, - ] - const [selectOption, setSelectOption] = useState(SelectOption[0]) - - // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ - useEffect(() => { - console.log('DotLineGrid useEffect ์‹คํ–‰') - fetchGridSettings() - }, [objectNo]) - const HandleClickClose = () => { // setClose(true) // setTimeout(() => { @@ -90,61 +66,31 @@ export default function DotLineGrid(props) { }) } - // Canvas Grid Setting ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” - const fetchGridSettings = async () => { - try { - const res = await get({ url: `/api/canvas-management/canvas-grid-settings/by-object/${objectNo}` }) - - const patternData = { - INTERVAL: { - type: res.gridType, - horizontalInterval: res.gridHorizon * 10, - verticalInterval: res.gridVertical * 10, - ratioInterval: res.gridRatio * 10, - }, - dimension: res.gridDimen, - DOT: res.dotGridDisplay, - LINE: res.lineGridDisplay, - } - - const matchedOption = SelectOption.find((option) => option.value == res.gridDimen) - - // dimension ๊ฐ’์— ๋งž๋Š” ์˜ต์…˜์„ ์„ ํƒ - setSelectOption(matchedOption) - - // ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ ์ƒํƒœ ์—…๋ฐ์ดํŠธ - setCurrentSetting(patternData) - } catch (error) { - console.error('Data fetching error:', error) - } - } - const handleSave = async () => { if (!currentSetting.DOT && !currentSetting.LINE) { swalFire({ text: '๋ฐฐ์น˜ํ•  ๊ทธ๋ฆฌ๋“œ๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.' }) return } - try { - const patternData = { - objectNo, - dotGridDisplay: currentSetting.DOT, - lineGridDisplay: currentSetting.LINE, - gridType: currentSetting.INTERVAL.type, - gridHorizon: currentSetting.INTERVAL.horizontalInterval / 10, - gridVertical: currentSetting.INTERVAL.verticalInterval / 10, - gridRatio: currentSetting.INTERVAL.ratioInterval / 10, - gridDimen: currentSetting.INTERVAL.dimension, - } - // HTTP POST ์š”์ฒญ ๋ณด๋‚ด๊ธฐ - await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - setDotLineGridSettingState({ ...currentSetting }) - closePopup(id, isConfig) - }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } + setDotLineGridSettingState((prev) => { + return { + ...prev, + INTERVAL: { + type: currentSetting.INTERVAL.type, + horizontalInterval: currentSetting.INTERVAL.horizontalInterval, + verticalInterval: currentSetting.INTERVAL.verticalInterval, + ratioInterval: currentSetting.INTERVAL.ratioInterval, + dimension: currentSetting.INTERVAL.dimension, + }, + DOT: currentSetting.DOT, + LINE: currentSetting.LINE, + flag: true, + } + //setDotLineGridSettingState({ ...currentSetting }) + }) + + setIsShow(false) + closePopup(id, isConfig) } const handleRadioChange = (e) => { @@ -198,8 +144,19 @@ export default function DotLineGrid(props) { .filter((obj) => obj.name === 'dotGrid') .forEach((obj) => canvas?.remove(obj)) - resetDotLineGridSetting() - setSelectOption(SelectOption[0]) + // resetDotLineGridSetting() + setCurrentSetting({ + INTERVAL: { + type: 2, // 1: ๊ฐ€๋กœ,์„ธ๋กœ ๊ฐ„๊ฒฉ ์ˆ˜๋™, 2: ๋น„์œจ ๊ฐ„๊ฒฉ + ratioInterval: 910, + verticalInterval: 910, + horizontalInterval: 910, + dimension: 1, // ์น˜์ˆ˜ + }, + DOT: false, + LINE: false, + }) + setSelectOption(SelectOptions[0]) } return ( @@ -296,7 +253,7 @@ export default function DotLineGrid(props) { mm
- +
diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index 86f79df7..2f768406 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -17,8 +17,7 @@ export default function GridCopy(props) { const currentObject = useRecoilValue(currentObjectState) const { copy } = useGrid() const handleApply = () => { - // copy(currentObject, ) - copy(currentObject, ['โ†‘', 'โ†'].includes(arrow) ? Number(length) * -1 : Number(length)) + copy(currentObject, ['โ†‘', 'โ†'].includes(arrow) ? +length * -1 : +length) } return ( diff --git a/src/components/floor-plan/modal/object/SizeSetting.jsx b/src/components/floor-plan/modal/object/SizeSetting.jsx index bddc9f07..3466e2ed 100644 --- a/src/components/floor-plan/modal/object/SizeSetting.jsx +++ b/src/components/floor-plan/modal/object/SizeSetting.jsx @@ -5,12 +5,10 @@ import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import { usePopup } from '@/hooks/usePopup' import { contextPopupPositionState } from '@/store/popupAtom' -import { useRef, useState, useEffect, useContext } from 'react' +import { useRef, useState } from 'react' import { useObjectBatch } from '@/hooks/object/useObjectBatch' -import { useEvent } from '@/hooks/useEvent' import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' -import { EventContext } from '@/app/floor-plan/EventProvider' export default function SizeSetting(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 26d6f1b9..1ce18a85 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -1,113 +1,26 @@ import { useEffect, useState } from 'react' -import { useRecoilState } from 'recoil' - -import { canvasSettingState } from '@/store/canvasAtom' -import { basicSettingState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' -import { useAxios } from '@/hooks/useAxios' -import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide' import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide' import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' + export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) { - const [objectNo, setObjectNo] = useState('test123241008001') // ํ›„์— ์‚ญ์ œ ํ•„์š” const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) - const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(1) - const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const { closePopup } = usePopup() - const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) - const { getMessage } = useMessage() - const { get, post } = useAxios() - const { swalFire } = useSwal() + + const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ useEffect(() => { - console.log('PlacementShapeSetting useEffect ์‹คํ–‰') - - fetchSettings() - }, [objectNo]) - - // PlacementShapeSetting ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” - const fetchSettings = async () => { - try { - await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => { - if (res.length == 0) return - - // 'roofs' ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ - const roofsRow = res.map((item) => { - return { - roofSizeSet: item.roofSizeSet, - roofAngleSet: item.roofAngleSet, - } - }) - - const roofsArray = res.some((item) => !item.roofSeq) - ? //์ตœ์ดˆ ์ง€๋ถ•์žฌ ์ถ”๊ฐ€ ์ •๋ณด์˜ ๊ฒฝ์šฐ roofsArray๋ฅผ ์ดˆ๊ธฐํ™” ์„ค์ • - res.map(() => ({ - roofApply: true, - roofSeq: 1, - roofType: 1, - roofWidth: 200, - roofHeight: 200, - roofHajebichi: 200, - roofGap: 0, - roofLayout: 'parallel', - })) - : res.map((item) => ({ - roofApply: item.roofApply === '' || item.roofApply === false ? false : true, - roofSeq: item.roofSeq, - roofType: item.roofType, - roofWidth: item.roofWidth, - roofHeight: item.roofHeight, - roofHajebichi: item.roofHajebichi, - roofGap: item.roofGap, - roofLayout: item.roofLayout, - })) - console.log('roofsArray ', roofsArray) - // ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ 'roofs' ๋ฐฐ์—ด์„ patternData์— ๋„ฃ์Œ - const patternData = { - roofSizeSet: roofsRow[0].roofSizeSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ - roofAngleSet: roofsRow[0].roofAngleSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ - roofs: roofsArray, // ๋งŒ๋“ค์–ด์ง„ roofs ๋ฐฐ์—ด - } - - // ๋ฐ์ดํ„ฐ ์„ค์ • - setBasicSettings({ ...patternData }) - }) - } catch (error) { - console.error('Data fetching error:', error) - } - - if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { - setBasicSettings({ ...canvasSetting }) - } - } - - const submitCanvasConfig = async () => { - try { - const patternData = { - objectNo, - roofSizeSet: basicSetting.roofSizeSet, - roofAngleSet: basicSetting.roofAngleSet, - roofMaterialsAddList: basicSetting.roofs, - } - - await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - }) - - //Recoil ์„ค์ • - setCanvasSetting({ ...basicSetting }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } - } + fetchBasicSettings() + }, []) // Function to update the roofType and corresponding values const handleRoofTypeChange = (index, value) => { @@ -122,7 +35,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set roofWidth: 265, roofHeight: 235, roofGap: 455, - hajebichi: 0, + roofHajebichi: 0, } } else if (roofType === 2) { updatedRoofs[index] = { @@ -490,7 +403,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
-
diff --git a/src/components/floor-plan/modal/placementShape/SizeGuide.jsx b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx index 1f9d2770..fff7dbe8 100644 --- a/src/components/floor-plan/modal/placementShape/SizeGuide.jsx +++ b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx @@ -14,7 +14,7 @@ export default function SizeGuide({ setShowSizeGuidModal }) {
- + diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index 1f70f21f..f3ef9b8b 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -3,11 +3,14 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useMessage } from '@/hooks/useMessage' import { POLYGON_TYPE } from '@/common/common' import { setSurfaceShapePattern } from '@/util/canvas-util' +import { useEvent } from '@/hooks/useEvent' -export default function FirstOption() { +export default function FirstOption(props) { const { getMessage } = useMessage() - const { canvas, settingModalFirstOptions, setSettingModalFirstOptions } = useCanvasSetting() + // const { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = useCanvasSetting() + let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = props const { option1, option2, dimensionDisplay } = settingModalFirstOptions + const { initEvent } = useEvent() // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ useEffect(() => { @@ -16,19 +19,27 @@ export default function FirstOption() { const onClickOption = async (item) => { //์น˜์ˆ˜ ํ‘œ์‹œ(๋‹จ ๊ฑด ์„ ํƒ) + let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay + let option1 = settingModalFirstOptions?.option1 + let option2 = settingModalFirstOptions?.option2 + if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') { - const options = settingModalFirstOptions?.dimensionDisplay.map((option) => { + dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.map((option) => { option.selected = option.id === item.id return option }) + // setSettingModalFirstOptions({ ...settingModalFirstOptions, dimensionDisplay: [...options] }) + //ํ™”๋ฉด ํ‘œ์‹œ(๋‹จ ๊ฑด ์„ ํƒ) } else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') { - const options2 = settingModalFirstOptions?.option2.map((option2) => { + option2 = settingModalFirstOptions?.option2.map((option2) => { option2.selected = option2.id === item.id return option2 }) + // setSettingModalFirstOptions({ ...settingModalFirstOptions, option2: [...options] }) + const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) polygons.forEach((polygon) => { @@ -36,12 +47,24 @@ export default function FirstOption() { }) //๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ • ํ‘œ์‹œ(๋‹จ ๊ฑด ์„ ํƒ) } else { - item.selected = !item.selected + option1 = settingModalFirstOptions?.option1.map((opt) => { + if (opt.id === item.id) { + opt.selected = !opt.selected + } + return opt + }) + + // setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] }) } - setSettingModalFirstOptions({ ...settingModalFirstOptions, option1, option2, dimensionDisplay, fontFlag: true }) + setSettingsData({ ...settingsData, option1: [...option1], option2: [...option2], dimensionDisplay: [...dimensionDisplay] }) } + // useEffect(() => { + // console.log('๐Ÿš€ ~ useEffect ~ initEvent:') + // initEvent() + // }, [onClickOption]) + return ( <>
diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index f3465365..1d40ddbc 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -4,28 +4,32 @@ import { settingModalGridOptionsState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' import { adsorptionPointAddModeState } from '@/store/canvasAtom' import { useTempGrid } from '@/hooks/useTempGrid' -import { gridColorState } from '@/store/gridAtom' -import { useColor } from 'react-color-palette' import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal' import { usePopup } from '@/hooks/usePopup' import { v4 as uuidv4 } from 'uuid' import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useEvent } from '@/hooks/useEvent' -export default function GridOption() { +export default function GridOption(props) { const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState) const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState) const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) const { getMessage } = useMessage() const { tempGridMode, setTempGridMode } = useTempGrid() - const [gridColor, setGridColor] = useRecoilState(gridColorState) - const [color, setColor] = useColor(gridColor) const [showColorPickerModal, setShowColorPickerModal] = useState(false) const [showDotLineGridModal, setShowDotLineGridModal] = useState(false) const { addPopup, closePopup, closePopups } = usePopup() const [colorId, setColorId] = useState(uuidv4()) const [dotLineId, setDotLineId] = useState(uuidv4()) + // const { gridColor, setGridColor, color } = useCanvasSetting() + const { gridColor, setGridColor, color } = props + + const { initEvent } = useEvent() + useEffect(() => { + console.log('GridOption useEffect ์‹คํ–‰') setGridColor(color.hex) }, [color]) @@ -91,6 +95,11 @@ export default function GridOption() { setGridOptions(newGridOptions) } + useEffect(() => { + console.log('๐Ÿš€ ~ useEffect ~ initEvent:') + initEvent() + }, [gridOptions]) + const dotLineGridProps = { id: dotLineId, setIsShow: setShowDotLineGridModal, diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index b5e9d98d..df60763d 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -8,8 +8,9 @@ import PlanSizeSetting from '@/components/floor-plan/modal/setting01/planSize/Pl import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useRecoilState, useRecoilValue } from 'recoil' import { fontSelector, globalFontAtom } from '@/store/fontAtom' +import { useEvent } from '@/hooks/useEvent' -export default function SecondOption() { +export default function SecondOption(props) { const { getMessage } = useMessage() const { addPopup, closePopup } = usePopup() const [showFontSettingModal, setShowFontSettingModal] = useState(false) @@ -24,6 +25,18 @@ export default function SecondOption() { const [fontId, setFontId] = useState(uuidv4()) const [planSizeId, setPlanSizeId] = useState(uuidv4()) + const { initEvent } = useEvent() + + // const { + // fetchSettings, + // planSizeSettingMode, + // setPlanSizeSettingMode, + // settingModalSecondOptions, + // setSettingModalSecondOptions, + // adsorptionPointMode, + // setAdsorptionPointMode, + // setAdsorptionRange, + // } = useCanvasSetting() const { fetchSettings, planSizeSettingMode, @@ -33,7 +46,7 @@ export default function SecondOption() { adsorptionPointMode, setAdsorptionPointMode, setAdsorptionRange, - } = useCanvasSetting() + } = props const { option3, option4 } = settingModalSecondOptions // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ @@ -189,6 +202,11 @@ export default function SecondOption() { setAdsorptionRange(50) } + useEffect(() => { + console.log('๐Ÿš€ ~ useEffect ~ initEvent:') + initEvent() + }, [adsorptionPointMode]) + return ( <>
diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 222226c1..73ce8fa2 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -9,6 +9,7 @@ import GridOption from '@/components/floor-plan/modal/setting01/GridOption' import { canGridOptionSeletor } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { usePopup } from '@/hooks/usePopup' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export default function SettingModal01(props) { const { id } = props @@ -17,6 +18,37 @@ export default function SettingModal01(props) { const canGridOptionSeletorValue = useRecoilValue(canGridOptionSeletor) const { closePopup } = usePopup() + const { + canvas, + settingModalFirstOptions, + setSettingModalFirstOptions, + settingsData, + setSettingsData, + fetchSettings, + planSizeSettingMode, + setPlanSizeSettingMode, + settingModalSecondOptions, + setSettingModalSecondOptions, + adsorptionPointMode, + setAdsorptionPointMode, + setAdsorptionRange, + gridColor, + setGridColor, + color, + } = useCanvasSetting() + const firstProps = { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } + const secondProps = { + fetchSettings, + planSizeSettingMode, + setPlanSizeSettingMode, + settingModalSecondOptions, + setSettingModalSecondOptions, + adsorptionPointMode, + setAdsorptionPointMode, + setAdsorptionRange, + } + const gridProps = { gridColor, setGridColor, color } + const handleBtnClick = (num) => { setButtonAct(num) } @@ -46,9 +78,9 @@ export default function SettingModal01(props) { )}
- {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && }
diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index a841efd5..e65d28ca 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -75,8 +75,6 @@ export default function PlanSizeSetting(props) { className="input-origin block" name={`originHorizon`} value={planSizeSettingMode.originHorizon} - //onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: Number(e.target.value), flag: false })} - //onFocus={(e) => (originHorizon.current.value = '')} onChange={(e) => onlyNumberInputChange(e, changeInput)} /> @@ -90,8 +88,6 @@ export default function PlanSizeSetting(props) { className="input-origin block" name={`originVertical`} value={planSizeSettingMode.originVertical} - //onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originVertical: Number(e.target.value), flag: false })} - //onFocus={(e) => (originVertical.current.value = '')} onChange={(e) => onlyNumberInputChange(e, changeInput)} /> diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 2674936c..b8cfafd2 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -96,7 +96,8 @@ export default function Header(props) { name: 'header.menus.management', url: '', children: [ - { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempdetail', children: [] }, + // { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempdetail', children: [] }, + { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempReg', children: [] }, { id: 4, name: 'header.menus.management.stuffList', url: '/management/stuff', children: [] }, ], }, @@ -129,6 +130,14 @@ export default function Header(props) { } } + // Home ํด๋ฆญ์‹œ ๋ฌผ๊ฑด ๋ฆฌ์ฝ”์ผ ๋น„์šฐ๊ธฐ + const moveHome = () => { + setStuffSearch({ + ...stuffSearch, + code: 'DELETE', + }) + } + const getMenuTemplate = (menus) => { return menus.map((menu) => { return ( @@ -139,7 +148,13 @@ export default function Header(props) { onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')} > {menu.children.length === 0 ? ( - + { + moveHome() + }} + > {getMessage(menu.name)} ) : ( @@ -154,7 +169,9 @@ export default function Header(props) { onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage(m.name)} + + {getMessage(m.name)} + ) })} diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx index 42ab6ef6..188a3fe7 100644 --- a/src/components/main/ChangePasswordPop.jsx +++ b/src/components/main/ChangePasswordPop.jsx @@ -6,8 +6,9 @@ import { useRecoilValue, useRecoilState } from 'recoil' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { useRouter } from 'next/navigation' +import { setSession } from '@/lib/authActions' -export default function ChangePasswordPop() { +export default function ChangePasswordPop(props) { const globalLocaleState = useRecoilValue(globalLocaleStore) const { patch } = useAxios(globalLocaleState) @@ -77,6 +78,7 @@ export default function ChangePasswordPop() { alert(getMessage('main.popup.login.success')) setSessionState({ ...sessionState, pwdInitYn: 'Y' }) //๋ฉ”์ธ์œผ๋กœ ์ด๋™ + props.setChagePasswordPopOpen(false) router.push('/') } else { alert(res.result.resultMsg) diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx index e45cfd33..ccae193a 100644 --- a/src/components/main/MainContents.jsx +++ b/src/components/main/MainContents.jsx @@ -22,19 +22,12 @@ export default function MainContents() { const globalLocaleState = useRecoilValue(globalLocaleStore) const { promiseGet } = useAxios(globalLocaleState) - //์ตœ๊ทผ ๋ฌผ๊ฑด - // const [objectList, setObjectList] = useState([]) - //๊ณต์ง€์‚ฌํ•ญ const [recentNoticeList, setRecentNoticeList] = useState([]) //FAQ const [recentFaqList, setRecentFaqList] = useState([]) - //Sales Contact info - // const [businessCharger, setBusinessCharger] = useState(null) - // const [businessChargerMail, setBusinessChargerMail] = useState(null) - const { qcastState } = useContext(QcastContext) const { fetchObjectList, initObjectList } = useMainContentsController() @@ -47,28 +40,6 @@ export default function MainContents() { } }, []) - //์ตœ๊ทผ ๊ฐฑ์‹  ๋ฌผ๊ฑด๋ชฉ๋ก / Sales Contact info ์ •๋ณด - // const fetchObjectList = async () => { - // try { - // const apiUrl = `/api/main-page/object/${session?.storeId}/list` - // await promiseGet({ - // url: apiUrl, - // }).then((res) => { - // if (res.status === 200) { - // setObjectList(res.data.objectList) - // setBusinessCharger(res.data.businessCharger) - // setBusinessChargerMail(res.data.businessChargerMail) - // } else { - // setObjectList([]) - // setBusinessCharger(null) - // setBusinessChargerMail(null) - // } - // }) - // } catch (error) { - // console.error('MAIN API fetching error:', error) - // } - // } - //๊ณต์ง€์‚ฌํ•ญ ํ˜ธ์ถœ const fetchNoticeList = async () => { try { @@ -128,9 +99,9 @@ export default function MainContents() { className="recently-item" onClick={() => { if (row.tempFlg === '0') { - router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`) + router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`, { scroll: false }) } else { - router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`) + router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`, { scroll: false }) } }} > diff --git a/src/components/main/ProductItem.jsx b/src/components/main/ProductItem.jsx index 928bc269..707e35c7 100644 --- a/src/components/main/ProductItem.jsx +++ b/src/components/main/ProductItem.jsx @@ -6,7 +6,7 @@ export default function ProductItem({ num, name, children }) { // ๋”๋ณด๊ธฐ ํŽ˜์ด์ง€ ์ด๋™ const pageMove = (num) => { if (num === 1) { - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else if (num === 2) { router.push('/community/notice') } else { diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 9eb50dca..0ae7299b 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -211,7 +211,6 @@ export default function Stuff() { fetchData() } else if (stuffSearchParams?.code === 'M') { const params = { - saleStoreId: session?.storeId, schObjectNo: stuffSearchParams.schObjectNo, schAddress: '', schObjectName: '', @@ -225,7 +224,7 @@ export default function Stuff() { endRow: pageNo * pageSize, schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId, schSortType: 'R', - code: 'S', + code: 'E', pageNo: 1, pageSize: 100, } @@ -261,6 +260,7 @@ export default function Stuff() { fetchData() } else if (stuffSearchParams?.code === 'C') { resetStuffRecoil() + setIsGlobalLoading(false) } else if (stuffSearchParams?.code === 'FINISH') { stuffSearchParams.startRow = 1 stuffSearchParams.endRow = 1 * pageSize @@ -278,6 +278,7 @@ export default function Stuff() { setTotalCount(0) } }) + setIsGlobalLoading(false) } fetchData() } else if (stuffSearchParams?.code === 'DELETE') { @@ -305,6 +306,11 @@ export default function Stuff() { setStuffSearch({ ...newParams, }) + + setIsGlobalLoading(false) + } else { + stuffSearchParams.code = 'DELETE' + setIsGlobalLoading(false) } }, [stuffSearchParams]) @@ -320,7 +326,7 @@ export default function Stuff() { setPageSize(e.target.value) setStuffSearch({ ...stuffSearch, - code: 'S', + code: 'E', startRow: startRow, endRow: 1 * e.target.value, pageSize: e.target.value, @@ -331,7 +337,6 @@ export default function Stuff() { //์ตœ๊ทผ ๋“ฑ๋ก์ผ ์ˆ˜์ •์ผ ์ •๋ ฌ ์ด๋ฒคํŠธ const onChangeSortType = (e) => { - // let startRow = (stuffSearchParams.pageNo - 1) * pageSize + 1 let startRow = (1 - 1) * stuffSearchParams.pageSize + 1 stuffSearchParams.startRow = startRow stuffSearchParams.endRow = startRow * stuffSearchParams.pageSize @@ -345,7 +350,7 @@ export default function Stuff() { setStuffSearch({ ...stuffSearch, - code: 'S', + code: 'E', startRow: startRow, endRow: startRow * stuffSearchParams.pageSize, pageSize: stuffSearchParams.pageSize, @@ -371,7 +376,7 @@ export default function Stuff() { setStuffSearch({ ...stuffSearch, - code: 'S', + code: 'E', startRow: (page - 1) * pageSize + 1, endRow: page * stuffSearchParams?.pageSize, pageNo: page, diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 231ce94c..bba99266 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -7,7 +7,7 @@ import Select, { components } from 'react-select' import Link from 'next/link' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' -import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty } from '@/util/common-utils' +import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' import { useRecoilValue, useSetRecoilState, useResetRecoilState, useRecoilState } from 'recoil' @@ -75,7 +75,7 @@ export default function StuffDetail() { installHeight: '', //์„ค์น˜๋†’์ด conType: '0', //๊ณ„์•ฝ์กฐ๊ฑด(์ž‰์—ฌ / ์ „๋Ÿ‰) remarks: '', //๋ฉ”๋ชจ - tempFlag: 'T', //์ž„์‹œ์ €์žฅ(1) ์ €์žฅ(0) + tempFlg: 'T', //์ž„์‹œ์ €์žฅ(1) ์ €์žฅ(0) } const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({ defaultValues: formInitValue, @@ -108,7 +108,6 @@ export default function StuffDetail() { const [editMode, setEditMode] = useState('NEW') const { managementState, setManagementState } = useContext(ManagementContext) - const [planGridProps, setPlanGridProps] = useState({ planGridData: [], isPageable: false, @@ -135,6 +134,7 @@ export default function StuffDetail() { field: 'moduleModel', headerName: getMessage('stuff.detail.planGridHeader.moduleModel'), flex: 1, + wrapText: true, cellStyle: { justifyContent: 'flex-start' /* ์ขŒ์ธก์ •๋ ฌ*/ }, }, { @@ -283,6 +283,7 @@ export default function StuffDetail() { {getMessage('stuff.detail.planGrid.btn1')} diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 1ea2a699..ab838335 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -1,19 +1,26 @@ 'use client' -import { useEffect } from 'react' +import { useContext, useEffect } from 'react' + import Link from 'next/link' import Image from 'next/image' -import { useMessage } from '@/hooks/useMessage' import { useRouter, useSearchParams } from 'next/navigation' -import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' + import { useSetRecoilState } from 'recoil' + +import { QcastContext } from '@/app/QcastProvider' +import { useMessage } from '@/hooks/useMessage' +import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { queryStringFormatter } from '@/util/common-utils' + export default function StuffSubHeader({ type }) { const { getMessage } = useMessage() const router = useRouter() const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) + const { isGlobalLoading } = useContext(QcastContext) + useEffect(() => { window.scrollTo(0, 0) }, []) @@ -35,85 +42,87 @@ export default function StuffSubHeader({ type }) { } return ( - <> -
-
- {type === 'list' && ( - <> - -

{getMessage('header.menus.management')}

- -
    -
  • - - - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.stuffList')} -
  • -
- - )} - {type === 'temp' && ( - <> -
    -
  • - - {getMessage('stuff.temp.subTitle')} - -
  • -
-
    -
  • - - - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.newStuff')} -
  • -
- - )} - {type === 'detail' && ( - <> - -
    -
  • - - - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.detail')} -
  • -
- - )} + !isGlobalLoading && ( + <> +
+
+ {type === 'list' && ( + <> + +

{getMessage('header.menus.management')}

+ +
    +
  • + + + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.stuffList')} +
  • +
+ + )} + {type === 'temp' && ( + <> +
    +
  • + + {getMessage('stuff.temp.subTitle')} + +
  • +
+
    +
  • + + + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.newStuff')} +
  • +
+ + )} + {type === 'detail' && ( + <> + +
    +
  • + + + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.detail')} +
  • +
+ + )} +
-
- + + ) ) } diff --git a/src/hooks/common/useCommonCode.js b/src/hooks/common/useCommonCode.js index f912beb9..bab32007 100644 --- a/src/hooks/common/useCommonCode.js +++ b/src/hooks/common/useCommonCode.js @@ -5,14 +5,28 @@ import { globalLocaleStore } from '@/store/localeAtom' import { isObjectNotEmpty } from '@/util/common-utils' import { useAxios } from '../useAxios' +/** + * ๊ณตํ†ต์ฝ”๋“œ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ปค์Šคํ…€ ํ›… + * + * @description + * - ๊ณตํ†ต์ฝ”๋“œ๋ฅผ ์ „์—ญ ์ƒํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ํ•„์š”ํ•œ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ + * - ์ตœ์ดˆ 1ํšŒ๋งŒ API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ณตํ†ต์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ด + * - ์–ธ์–ด ์„ค์ •์— ๋”ฐ๋ผ ํ•œ๊ตญ์–ด/์ผ๋ณธ์–ด ์ฝ”๋“œ๋ช…์„ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ + * + * @returns {Object} + * - commonCode: ์ „์ฒด ๊ณตํ†ต์ฝ”๋“œ ๊ฐ์ฒด(recoil state) + * - findCommonCode: ํŠน์ • ๊ณตํ†ต์ฝ”๋“œ ๊ทธ๋ฃน์„ ์กฐํšŒํ•˜๋Š” ํ•จ์ˆ˜ + * + * @example + * const { commonCode, findCommonCode } = useCommonCode(); + * const honorificCodes = findCommonCode(200800); + */ export const useCommonCode = () => { const [commonCode, setCommonCode] = useRecoilState(commonCodeState) const globalLocale = useRecoilValue(globalLocaleStore) const { promiseGet } = useAxios() const findCommonCode = (key) => { - // const arr = commonCode[key] - // return arr.sort((a, b) => a.clPriority - b.clPriority) const resultCodes = commonCode[key]?.map((code) => { const result = { clHeadCd: code.clHeadCd, diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 05f60afe..df0b5634 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -1,83 +1,161 @@ import { useEffect, useRef, useState } from 'react' -import { useRecoilState } from 'recoil' -import { v4 as uuidv4 } from 'uuid' +import { useRecoilState, useRecoilValue } from 'recoil' import { useSwal } from '@/hooks/useSwal' import { useAxios } from '../useAxios' -import { currentCanvasPlanState } from '@/store/canvasAtom' -import { convertDwgToPng, writeImageBuffer } from '@/lib/fileAction' +import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' +import { convertDwgToPng, removeImage, writeImageBuffer, readImage } from '@/lib/fileAction' +import { useCanvas } from '@/hooks/useCanvas' export function useRefFiles() { const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL const [refImage, setRefImage] = useState(null) const [refFileMethod, setRefFileMethod] = useState('1') const [mapPositionAddress, setMapPositionAddress] = useState('') - const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) + const [currentBgImage, setCurrentBgImage] = useState(null) const queryRef = useRef(null) - + const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) + const canvas = useRecoilValue(canvasState) + const { handleBackImageLoadToCanvas } = useCanvas() const { swalFire } = useSwal() - const { get, promisePut, promisePost } = useAxios() - // const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan() + const { get, post, promisePost } = useAxios() + + useEffect(() => { + if (refFileMethod === '1') { + // ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ + setMapPositionAddress('') + } else { + setRefImage(null) + } + }, [refFileMethod]) + + /** + * ํ˜„์žฌ ํ”Œ๋žœ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ”Œ๋žœ ์ƒํƒœ ์ €์žฅ + */ + useEffect(() => { + // console.log('๐Ÿš€ ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) + // const handleCurrentPlan = async () => { + // await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => { + // console.log('๐Ÿš€ ~ awaitpromisePut ~ res:', res) + // }) + // } + // handleCurrentPlan() + }, [currentCanvasPlan]) /** * ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฒ„ํŠผ ์ปจํŠธ๋กค * @param {*} file */ const handleRefFile = (file) => { - setRefImage(file) - /** - * ํŒŒ์ผ ํ™•์žฅ์ž๊ฐ€ dwg์ผ ๊ฒฝ์šฐ ๋ณ€ํ™˜ํ•˜์—ฌ ์ด๋ฏธ์ง€๋กœ ์ €์žฅ - * ํŒŒ์ผ ํ™•์žฅ์ž๊ฐ€ ์ด๋ฏธ์ง€์ผ ๊ฒฝ์šฐ ์ด๋ฏธ์ง€ ์ €์žฅ - */ - file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) - // handleUploadRefFile(file) + console.log('handleRefFile', file) + console.log('refImage', refImage) + + if (refImage) { + swalFire({ + text: 'ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?', + type: 'confirm', + confirmFn: () => { + refFileSetting(file) + // setRefImage(file) + // file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + }, + }) + } else { + refFileSetting(file) + } } + const refFileSetting = (file) => { + if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) { + // setRefImage(file) + file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + } else { + swalFire({ + text: '์ด๋ฏธ์ง€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.', + type: 'alert', + icon: 'error', + }) + } + } /** * ํŒŒ์ผ ์‚ญ์ œ */ const handleFileDelete = () => { - setRefImage(null) - setCurrentCanvasPlan((prev) => ({ ...prev, bgFileName: null })) + swalFire({ + text: '์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?', + type: 'confirm', + confirmFn: () => { + setRefImage(null) + setCurrentCanvasPlan((prev) => ({ ...prev, bgFileName: null })) + removeImage(currentCanvasPlan.id).then((res) => { + console.log(res) + }) + }, + }) } /** * ์ฃผ์†Œ ์‚ญ์ œ */ const handleAddressDelete = () => { - setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null })) + swalFire({ + text: '์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?', + type: 'confirm', + confirmFn: () => { + setMapPositionAddress('') + setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null })) + removeImage(currentCanvasPlan.id).then((res) => { + console.log(res) + }) + }, + }) } /** * ์ฃผ์†Œ๋กœ ๊ตฌ๊ธ€ ๋งต ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ */ const handleMapImageDown = async () => { + console.log('๐Ÿš€ ~ handleMapImageDown ~ handleMapImageDown:') if (queryRef.current.value === '' || queryRef.current.value === null) { return } - const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${uuidv4()}&zoom=20` }) + const res = await get({ + url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`, + }) console.log('๐Ÿš€ ~ handleMapImageDown ~ res:', res) - setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: res.fileNm, mapPositionAddress: queryRef.current.value })) + const file = await readImage(res.fileNm) + console.log('๐Ÿš€ ~ handleMapImageDown ~ file:', file) + setCurrentBgImage(file) + // handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + // setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) } + useEffect(() => { + if (!currentBgImage) { + return + } + console.log('๐Ÿš€ ~ useEffect ~ currentBgImage:', currentBgImage) + handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: refImage?.name ?? null, mapPositionAddress: queryRef.current.value })) + }, [currentBgImage]) + /** * ์ด๋ฏธ์ง€ ํŒŒ์ผ ์—…๋กœ๋“œ * @param {*} file */ const handleUploadImageRefFile = async (file) => { - console.log('๐Ÿš€ ~ handleUploadImageRefFile ~ file:', file) const formData = new FormData() formData.append('file', file) + formData.append('fileName', currentCanvasPlan.id) - const response = await fetch('http://localhost:3000/api/image-upload', { - method: 'POST', - body: formData, - }) + const res = await post({ url: 'http://localhost:3000/api/image-upload', data: formData }) + console.log('๐Ÿš€ ~ handleUploadImageRefFile ~ res:', res) + const image = await readImage(res.fileNm) + console.log('๐Ÿš€ ~ handleUploadImageRefFile ~ file:', image) - const result = await response.json() - console.log('๐Ÿš€ ~ handleUploadImageRefFile ~ res:', result) - // writeImageBuffer(file) + setCurrentBgImage(image) + setRefImage(file) } /** @@ -92,6 +170,7 @@ export function useRefFiles() { .then((res) => { convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData) swalFire({ text: 'ํŒŒ์ผ ๋ณ€ํ™˜ ์„ฑ๊ณต' }) + setRefImage(res.data.Files[0].FileData) }) .catch((err) => { swalFire({ text: 'ํŒŒ์ผ ๋ณ€ํ™˜ ์‹คํŒจ', icon: 'error' }) @@ -106,19 +185,6 @@ export function useRefFiles() { setRefFileMethod(e.target.value) } - /** - * ํ˜„์žฌ ํ”Œ๋žœ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ”Œ๋žœ ์ƒํƒœ ์ €์žฅ - */ - useEffect(() => { - console.log('๐Ÿš€ ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) - // const handleCurrentPlan = async () => { - // await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => { - // console.log('๐Ÿš€ ~ awaitpromisePut ~ res:', res) - // }) - // } - // handleCurrentPlan() - }, [currentCanvasPlan]) - return { refImage, queryRef, diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index e48d6b76..6c9f221b 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -3,7 +3,7 @@ import { useContext, useEffect, useReducer, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { globalLocaleStore } from '@/store/localeAtom' import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom' -import { isObjectNotEmpty, isNotEmptyArray } from '@/util/common-utils' +import { isObjectNotEmpty, isEmptyArray, isNotEmptyArray } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { useMessage } from '@/hooks/useMessage' import { useRouter } from 'next/navigation' @@ -18,6 +18,9 @@ const updateItemInList = (itemList, dispOrder, updates) => { } export const useEstimateController = (planNo) => { + const [fileList, setFileList] = useState([]) + const [deleteFileList, setDeleteFileList] = useState([]) + const router = useRouter() const { session } = useContext(SessionContext) const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -39,6 +42,12 @@ export const useEstimateController = (planNo) => { } }, []) + useEffect(() => { + if (fileList.length > 0) { + realSave(fileList) + } + }, [fileList]) + // ์ƒ์„ธ ์กฐํšŒ const fetchSetting = async (objectNo, planNo) => { try { @@ -50,6 +59,14 @@ export const useEstimateController = (planNo) => { item.delFlg = '0' }) } + if (res.data.pkgAsp === null || res.data.pkgAsp == undefined) { + res.data.pkgAsp = '0.00' + } else { + const number = parseFloat(res.data.pkgAsp) + const roundedNumber = isNaN(number) ? '0.00' : number.toFixed(2) + + res.data.pkgAsp = roundedNumber.toString() + } setEstimateContextState(res.data) } } @@ -68,7 +85,7 @@ export const useEstimateController = (planNo) => { } const addItem = () => { - let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder)) + let newItemDispOrder = estimateContextState.itemList.length === 0 ? 0 : Math.max(...estimateContextState.itemList.map((item) => item.dispOrder)) newItemDispOrder = (Math.floor(newItemDispOrder / 100) + 1) * 100 setEstimateContextState({ itemList: [ @@ -89,6 +106,7 @@ export const useEstimateController = (planNo) => { partAdd: '1', //NEW ์ฒด์ธ์ง€ ํ”Œ๋ž˜๊ทธ delFlg: '0', //์‚ญ์ œ ํ”Œ๋ž˜๊ทธ 0 ์‚ญ์ œํ•˜๋ฉด 1 addFlg: true, + paDispOrder: null, }, ], }) @@ -127,6 +145,7 @@ export const useEstimateController = (planNo) => { const handleEstimateSubmit = async () => { //0. ํ•„์ˆ˜์ฒดํฌ let flag = true + let originFileFlg = false let fileFlg = true let itemFlg = true if (estimateData.charger.trim().length === 0) { @@ -144,23 +163,44 @@ export const useEstimateController = (planNo) => { return alert(getMessage('estimate.detail.save.requiredEstimateDate')) } - //์ฒจ๋ถ€ํŒŒ์ผ์„ ์ฒจ๋ถ€์•ˆํ–ˆ๋Š”๋ฐ - //์•„์ดํ…œ fileUploadFlg๊ฐ€1(์ฒจ๋ถ€ํŒŒ์ผ ํ•„์ˆ˜)์ด 1๊ฐœ๋ผ๋„ ์žˆ๋Š”๋ฐ ํ›„์ผ ์ž๋ฃŒ ์ œ์ถœ(fileFlg) ์ฒดํฌ์•ˆํ–ˆ์œผ๋ฉด(0) alert ์ €์žฅ์•ˆ๋ผ + if (estimateData.estimateType === 'YJSS') { + let pkgAsp = estimateData.pkgAsp + if (pkgAsp === '0') { + flag = false + return alert(getMessage('estimate.detail.save.requiredPkgAsp')) + } + } + + //๊ธฐ์กด์— ์ฒจ๋ถ€๋œ ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ํŒŒ์ผ์ฒจ๋ถ€๊ด€๋ จ ํ†ต๊ณผ + if (estimateData?.originFiles?.length > 0) { + let cnt = estimateData.originFiles.filter((file) => file.delFlg === '0').length + + if (cnt == 0) { + originFileFlg = false + } else { + originFileFlg = true + } + } + if (flag) { - if (estimateData.fileList.length < 1) { - if (estimateData.itemList.length > 1) { - estimateData.itemList.map((row) => { - if (row.delFlg === '0') { - if (row.fileUploadFlg === '1') { - if (fileFlg) { - if (estimateData.fileFlg === '0') { - fileFlg = false - return alert(getMessage('estimate.detail.save.requiredFileUpload')) + if (!originFileFlg) { + //๊ธฐ์กด์— ์ฒจ๋ถ€๋œ ํŒŒ์ผ์ด ์—†์œผ๋ฉด + if (isEmptyArray(estimateData.newFileList)) { + //์ƒˆ๋กœ ์ฒจ๋ถ€ํ•œ ํŒŒ์ผ์ด ์—†์œผ๋ฉด + if (estimateData.itemList.length > 1) { + estimateData.itemList.map((row) => { + if (row.delFlg === '0') { + if (row.fileUploadFlg === '1') { + if (fileFlg) { + if (estimateData.fileFlg === '0') { + fileFlg = false + return alert(getMessage('estimate.detail.save.requiredFileUpload')) + } } } } - } - }) + }) + } } } } @@ -168,10 +208,16 @@ export const useEstimateController = (planNo) => { if (fileFlg) { estimateData.itemList.map((item) => { if (item.delFlg === '0') { - item.amount = item.amount?.replaceAll(',', '') - item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2) - item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) + if (item.addFlg) { + if (item.itemId === '') { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredItemId')) + } + } + item.amount = item.amount?.replaceAll(',', '') + item.salePrice = Number(item.salePrice?.replaceAll(',', '')).toFixed(2) + item.saleTotPrice = Number(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) if (!item.paDispOrder) { if (itemFlg) { if (isNaN(item.amount)) { @@ -188,39 +234,27 @@ export const useEstimateController = (planNo) => { item.salePrice = '0' } - if (item.salePrice < 1) { - itemFlg = false - return alert(getMessage('estimate.detail.save.requiredSalePrice')) + if (item.openFlg !== '1') { + if (item.salePrice < 1) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } } estimateData.pkgAsp = '0' estimateData.pkgTotPrice = '0' + } else { + if (item.pkgMaterialFlg === '1') { + if (isNaN(item.salePrice)) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } + } } } } } }) - } - - if (flag && fileFlg && itemFlg) { - //1. ์ฒจ๋ถ€ํŒŒ์ผ ์ €์žฅ์‹œ์ž‘ - const formData = new FormData() - if (isNotEmptyArray(estimateData.tempFileList) > 1) { - estimateData.tempFileList.forEach((file) => { - formData.append('files', file) - }) - formData.append('objectNo', estimateData.objectNo) - formData.append('planNo', estimateData.planNo) - formData.append('category', '10') - formData.append('userId', estimateData.userId) - - await post({ url: '/api/file/fileUpload', data: formData }) - } - - //์ฒจ๋ถ€ํŒŒ์ผ์ €์žฅ๋ - - //์ œํ’ˆ๋ผ์ธ ์ถ”๊ฐ€ํ–ˆ๋Š”๋ฐ ์•„์ดํ…œ ์•ˆ๊ณ ๋ฅด๊ณ  ์ €์žฅํ•˜๋ฉดitemId=''์€ ๋‚ ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ์ €์žฅํ•˜๊ธฐ - // estimateData.itemList = estimateData.itemList.filter((item) => item.itemId !== '') estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) let delCnt = 0 @@ -232,30 +266,104 @@ export const useEstimateController = (planNo) => { if (delCnt === estimateData.itemList.length) { return alert(getMessage('estimate.detail.save.requiredItem')) } + } - let option = [] - estimateData.itemList.forEach((item) => { - if (item.specialNoteCd) { - let split2 = item.specialNoteCd.split('ใ€') - option = option.concat(split2) + if (flag && fileFlg && itemFlg) { + //1. ์ฒจ๋ถ€ํŒŒ์ผ ์ €์žฅ์‹œ์ž‘ + const formData = new FormData() + if (estimateData?.newFileList?.length > 0) { + estimateData.newFileList.forEach((file) => { + formData.append('files', file) + }) + formData.append('objectNo', estimateData.objectNo) + formData.append('planNo', estimateData.planNo) + formData.append('category', '10') + formData.append('userId', estimateData.userId) + + await post({ url: '/api/file/fileUpload', data: formData }).then((res) => { + setFileList(res) + }) + } else { + setFileList([]) + realSave() + } + } + } + + const realSave = async (fileList) => { + //์ฒจ๋ถ€ํŒŒ์ผ์ €์žฅ๋ + + let option = [] + estimateData.itemList.forEach((item) => { + if (item.specialNoteCd) { + let split2 = item.specialNoteCd.split('ใ€') + option = option.concat(split2) + } + }) + + let estimateOptions = '' + let estimateOptionsArray + estimateData.specialNoteList.map((item) => { + if (item.pkgYn === '0') { + if (item.check) { + if (estimateOptions === '') { + estimateOptions = item.code + } else { + estimateOptions += 'ใ€' + item.code + } + } + } else { + if (item.check) { + let flg = '0' + for (let i = 0; i < estimateData.uniqueData.length; i++) { + if (item.code.indexOf(estimateData.uniqueData[i]) > -1) { + flg = '1' + } + if (flg === '1') { + estimateOptions += 'ใ€' + estimateData.uniqueData[i] + } + } + } + } + }) + + estimateOptionsArray = estimateOptions.split('ใ€').sort() + estimateOptionsArray = Array.from(new Set(estimateOptionsArray)) + + estimateOptions = estimateOptionsArray.join('ใ€') + + estimateData.estimateOption = estimateOptions + // console.log('์ตœ์ข…์•„์ดํ…œ:::', estimateData.itemList) + if (fileList?.length > 0) { + estimateData.fileList = fileList + } else { + estimateData.fileList = [] + } + if (estimateData.originFiles?.length > 0) { + estimateData.deleteFileList = estimateData.originFiles?.filter((item) => item.delFlg === '1') + } else { + estimateData.deleteFileList = [] + } + + if (estimateData.estimateType === 'YJSS') { + estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') + } + + console.log('์ตœ์ข…์ €์žฅ::', estimateData) + //2. ์ƒ์„ธ๋ฐ์ดํ„ฐ ์ €์žฅ + // return + try { + await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { + if (res.status === 201) { + estimateData.newFileList = [] + // estimateData.originFiles = [] + alert(getMessage('estimate.detail.save.alertMsg')) + //์–ด๋””๋กœ ๋ณด๋‚ผ์ง€ + fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) } }) - - console.log('์•„์ดํ…œ๋ฆฌ์ŠคํŠธ::', estimateData.itemList) - console.log('์ตœ์ข… ์ •๋ณด::;', estimateData) - //2. ์ƒ์„ธ๋ฐ์ดํ„ฐ ์ €์žฅ - // return - try { - await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { - if (res.status === 201) { - alert(getMessage('estimate.detail.save.alertMsg')) - //์–ด๋””๋กœ ๋ณด๋‚ผ์ง€ - fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) - } - }) - } catch (e) { - console.log('error::::::::::::', e.response.data.message) - } + } catch (e) { + console.log('error::::::::::::', e.response.data.message) } } diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 067d9f8a..f51cf00f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1,17 +1,17 @@ -import { useContext, useEffect, useState } from 'react' -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util' import { roofDisplaySelector } from '@/store/settingAtom' -import offsetPolygon from '@/util/qpolygon-utils' +import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' -import { QLine } from '@/components/fabric/QLine' import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom' import { useEvent } from '@/hooks/useEvent' import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common' - import * as turf from '@turf/turf' -import { EventContext } from '@/app/floor-plan/EventProvider' +import { v4 as uuidv4 } from 'uuid' +import { useSwal } from '@/hooks/useSwal' +import { canvasSettingState } from '@/store/canvasAtom' +import { compasDegAtom } from '@/store/orientationAtom' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) @@ -19,10 +19,35 @@ export function useModuleBasicSetting() { const [moduleSetupSurface, setModuleSetupSurface] = useRecoilState(moduleSetupSurfaceState) const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent() + const { swalFire } = useSwal() + const canvasSetting = useRecoilValue(canvasSettingState) + const compasDeg = useRecoilValue(compasDegAtom) + // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) - const [flowModuleLine, setFlowModuleLine] = useState({}) let selectedModuleInstSurfaceArray = [] + //๋ชจ๋“ˆ,ํšŒ๋กœ์—์„œ ๋‹ค๋ฅธ๋ฉ”๋‰ด -> ๋ฐฐ์น˜๋ฉด์œผ๋กœ ๊ฐˆ ๊ฒฝ์ˆ˜ ์ดˆ๊ธฐํ™” + const restoreModuleInstArea = () => { + //์„ค์น˜๋ฉด ์‚ญ์ œ + const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + + //๋ชจ๋“ˆ ์‚ญ์ œ ๋ฐ ์ดˆ๊ธฐํ™” + setupArea.forEach((obj) => { + if (obj.modules.length > 0) { + obj.modules.forEach((module) => { + canvas.remove(module) + }) + } + canvas.remove(obj) + obj.modules = [] + }) + + //์ง€๋ถ•ํŒจํ„ด ๋ณ€๊ฒฝ + const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') + roofs.forEach((roof) => { + setSurfaceShapePattern(roof, roofDisplay.column, false) //ํŒจํ„ด ๋ณ€๊ฒฝ + }) + } const makeModuleInstArea = () => { //์ง€๋ถ• ๊ฐ์ฒด ๋ฐ˜ํ™˜ const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') @@ -32,9 +57,19 @@ export function useModuleBasicSetting() { } roofs.forEach((roof) => { + const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id) + if (isExistSurface) { + return + } + setSurfaceShapePattern(roof, roofDisplay.column, true) //ํŒจํ„ด ๋ณ€๊ฒฝ const offsetPoints = offsetPolygon(roof.points, -20) //์•ˆ์ชฝ offset //๋ชจ๋“ˆ์„ค์น˜์˜์—ญ?? ์ƒ์„ฑ + + const surfaceId = uuidv4() + + console.log('roof.moduleCompass', roof.moduleCompass) + let setupSurface = new QPolygon(offsetPoints, { stroke: 'red', fill: 'transparent', @@ -49,20 +84,25 @@ export function useModuleBasicSetting() { parentId: roof.id, //๊ฐ€๋Œ€ ํด๋ฆฌ๊ณค์˜ ์ž„์‹œ ์ธ๋ฑ์Šค๋ฅผ ๋„ฃ์–ด์คŒ name: POLYGON_TYPE.MODULE_SETUP_SURFACE, flowDirection: roof.direction, + direction: roof.direction, flipX: roof.flipX, flipY: roof.flipY, + surfaceId: surfaceId, + modules: [], }) setupSurface.setViewLengthText(false) + canvas.add(setupSurface) //๋ชจ๋“ˆ์„ค์น˜๋ฉด ๋งŒ๋“ค๊ธฐ - canvas.add(setupSurface) - - if (setupSurface.flowDirection === 'south' || setupSurface.flowDirection === 'north') { - setFlowModuleLine(bottomTopFlowLine(setupSurface)) - } else { - setFlowModuleLine(leftRightFlowLine(setupSurface)) + const flowLines = { + bottom: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'bottom'), + top: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'top'), + left: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'left'), + right: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'right'), } + setupSurface.set({ flowLines: flowLines }) + //์ง€๋ถ•๋ฉด ์„ ํƒ ๊ธˆ์ง€ roof.set({ selectable: false, @@ -128,13 +168,29 @@ export function useModuleBasicSetting() { obj.name === BATCH_TYPE.SHADOW, ) //๋„๋จธs ๊ฐ์ฒด + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: false, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • + lockMovementX: true, // X ์ถ• ์ด๋™ ์ž ๊ธˆ + lockMovementY: true, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ + lockRotation: true, // ํšŒ์ „ ์ž ๊ธˆ + lockScalingX: true, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + lockScalingY: true, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } + if (moduleSetupSurfaces.length !== 0) { let tempModule - let manualDrawModules = moduleIsSetup // ์•ž์—์„œ ์ž๋™์œผ๋กœ ํ–ˆ์„๋•Œ ์ถ”๊ฐ€๋จ + let manualDrawModules = [] let inside = false let turfPolygon let flowDirection let trestlePolygon + addCanvasMouseEventListener('mouse:move', (e) => { //๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์‚ญ์ œ ํ›„ ์žฌ์ถ”๊ฐ€ const mousePoint = canvas.getPointer(e.e) @@ -142,6 +198,7 @@ export function useModuleBasicSetting() { for (let i = 0; i < moduleSetupSurfaces.length; i++) { turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) trestlePolygon = moduleSetupSurfaces[i] + manualDrawModules = moduleSetupSurfaces[i].modules // ์•ž์—์„œ ์ž๋™์œผ๋กœ ํ–ˆ์„๋•Œ ์ถ”๊ฐ€๋จ flowDirection = moduleSetupSurfaces[i].flowDirection //๋„ํ˜•์˜ ๋ฐฉํ–ฅ let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113 let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172 @@ -319,6 +376,7 @@ export function useModuleBasicSetting() { } if (!inside) { + // tempModule.set({ fill: 'red' }) canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) canvas?.renderAll() } @@ -371,14 +429,12 @@ export function useModuleBasicSetting() { //๋งˆ์šฐ์Šค ํด๋ฆญ์‹œ set์œผ๋กœ ํ•ด๋‹น ์œ„์น˜์— ์…€์„ ๋„ฃ์Œ const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ if (!isOverlap) { + canvas?.remove(tempModule) //์•ˆ๊ฒน์น˜๋ฉด ๋„ฃ๋Š”๋‹ค - tempModule.setCoords() - tempModule.set({ name: 'module', fill: '#BFFD9F' }) - manualDrawModules.push(tempModule) //๋ชจ๋“ˆ๋ฐฐ์—ด์— ์ถ”๊ฐ€ - //ํ•ด๋‹น ๋ชจ๋“ˆ์— ํ”„๋กœํผํ‹ฐ๋กœ ๋„ฃ๋Š”๋‹ค - trestlePolygon.set({ - modules: manualDrawModules, - }) + // tempModule.setCoords() + let manualModule = new QPolygon(tempModule.points, { ...moduleOptions }) + canvas?.add(manualModule) + manualDrawModules.push(manualModule) } else { alert('์…€๋ผ๋ฆฌ ๊ฒน์น˜๋ฉด ์•ˆ๋˜์ฃ ?') } @@ -392,11 +448,11 @@ export function useModuleBasicSetting() { //์ž๋™ ๋ชจ๋“ˆ ์„ค์น˜(๊ทธ๋ฆฌ๋“œ ๋ฐฉ์‹) const autoModuleSetup = (placementRef) => { - const isChidori = placementRef.isChidori.current + initEvent() //๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์ดˆ๊ธฐํ™” + const isChidori = placementRef.isChidori.current === 'true' ? true : false const setupLocation = placementRef.setupLocation.current - const isMaxSetup = placementRef.isMaxSetup.current + const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false - initEvent() const moduleSetupSurfaces = moduleSetupSurface //์„ ํƒ ์„ค์น˜๋ฉด const notSelectedTrestlePolygons = canvas @@ -418,12 +474,27 @@ export function useModuleBasicSetting() { return } - if (moduleIsSetup.length > 0) { - alert('๊ธฐ์กด ๋ชจ๋“ˆ์€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.') - moduleIsSetup.forEach((module) => { - canvas?.remove(module) - }) - } + //์–ด์งœํ”ผ ์ž๋™์œผ๋กœ ๋ˆ„๋ฅด๋ฉด ์„ ํƒ์•ˆ๋œ๋ฐ๋„ ๋‹ค ๋‚ ์•„๊ฐ„๋‹ค + canvas.getObjects().forEach((obj) => { + if (obj.name === 'module') { + canvas.remove(obj) + } + }) + + // console.log('moduleIsSetup', moduleIsSetup) + + // if (moduleIsSetup.length > 0) { + // swalFire({ text: 'alert ์•„์ด์ฝ˜ ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.', icon: 'error' }) + // } + + // moduleSetupSurfaces.forEach((obj) => { + // if (obj.modules) { + // obj.modules.forEach((module) => { + // canvas?.remove(module) + // }) + // obj.modules = [] + // } + // }) notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { @@ -434,19 +505,27 @@ export function useModuleBasicSetting() { } }) - const moduleSetupArray = [] - moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { - moduleSetupSurface.fire('mousedown') + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: false, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • + lockMovementX: true, // X ์ถ• ์ด๋™ ์ž ๊ธˆ + lockMovementY: true, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ + lockRotation: true, // ํšŒ์ „ ์ž ๊ธˆ + lockScalingX: true, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + lockScalingY: true, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } - const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) + let leftMargin, bottomMargin, square, chidoriLength - let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { - return acc.length > cur.length ? acc : cur - }) - - const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //ํด๋ฆฌ๊ณค์„ turf ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ - - const containsBatchObjects = batchObjects.filter((batchObject) => { + //์„ ํƒ๋œ ์ง€๋ถ•์•ˆ์— ์˜ค๋ธŒ์ ํŠธ(๋„๋จธ, ๊ฐœ๊ตฌ๋“ฑ)์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง ํฌํ•จ๋˜๋ฉด ๋ฐฐ์—ด ๋ฐ˜ํ™˜ + const objectsIncludeSurface = (turfModuleSetupSurface) => { + let containsBatchObjects = [] + containsBatchObjects = batchObjects.filter((batchObject) => { let convertBatchObject if (batchObject.type === 'group') { @@ -454,9 +533,7 @@ export function useModuleBasicSetting() { convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) } else { //๊ฐœ๊ตฌ, ๊ทธ๋ฆผ์ž - batchObject.set({ - points: rectToPolygon(batchObject), - }) + batchObject.set({ points: rectToPolygon(batchObject) }) canvas?.renderAll() // set๋œ๊ฑธ ๋ฐ”๋กœ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด convertBatchObject = polygonToTurfPolygon(batchObject) //rect๋ฅผ ํด๋ฆฌ๊ณค์œผ๋กœ ๋ณ€ํ™˜ -> turf ํด๋ฆฌ๊ณค์œผ๋กœ ๋ณ€ํ™˜ } @@ -465,19 +542,323 @@ export function useModuleBasicSetting() { return turf.booleanContains(turfModuleSetupSurface, convertBatchObject) || turf.booleanWithin(convertBatchObject, turfModuleSetupSurface) }) - let difference = turfModuleSetupSurface //๊ธฐ๋ณธ ๊ฐ์ฒด(๋ฉดํ˜•์ƒ) + return containsBatchObjects + } + + /** + * ๋„๋จธ๋‚˜ ๊ฐœ๊ตฌ๊ฐ€ ๋ชจ๋“ˆ์— ๊ฑธ์น˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง + * @param {*} squarePolygon + * @param {*} containsBatchObjects + * @returns + */ + const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => { + let isDisjoint = false if (containsBatchObjects.length > 0) { - //turf๋กœ ๋„๋จธ๋ฅผ ์ œ์™ธ์‹œํ‚ค๋Š” ๋กœ์ง - for (let i = 0; i < containsBatchObjects.length; i++) { - let convertBatchObject - if (containsBatchObjects[i].type === 'group') { - convertBatchObject = batchObjectGroupToTurfPolygon(containsBatchObjects[i]) + let convertBatchObject + //๋„๋จธ๊ฐ€ ์žˆ์œผ๋ฉด ์ ์šฉ๋˜๋Š” ๋กœ์ง + isDisjoint = containsBatchObjects.every((batchObject) => { + if (batchObject.type === 'group') { + convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) } else { - convertBatchObject = polygonToTurfPolygon(containsBatchObjects[i]) + convertBatchObject = polygonToTurfPolygon(batchObject) + } + /** + * ๋„๋จธ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ์ˆ˜์žˆ์œผ๋ฏ€๋กœ ๊ฒน์น˜๋Š”๊ฒŒ ์žˆ๋‹ค๋ฉด... + * ์•ˆ๊ฒน์น˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง์ด๋ผ ์•ˆ๊ฒน์น˜๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ + */ + return turf.booleanDisjoint(squarePolygon, convertBatchObject) + }) + } else { + isDisjoint = true + } + return isDisjoint + } + + /** + * ๋ฐฐ์น˜๋ฉด ์•ˆ์— ์žˆ๋Š”์ง€ ํ™•์ธ + * @param {*} squarePolygon + * @param {*} turfModuleSetupSurface + * @returns + */ + const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => { + return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) + } + + const downFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.bottom + + if (isCenter) { + //์ค‘์•™๋ฐฐ์น˜์ผ ๊ฒฝ์šฐ์—๋Š” ๊ณ„์‚ฐํ•œ๋‹ค + + if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + //ํ•˜๋‹จ ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const halfModuleWidthLength = width / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + + if (flowModuleLine.top.type === 'flat') { + //์ƒ๋‹จ๊นŒ์ง€ ํ‰๋ฉด์ด๋ฉด ์ง์‚ฌ๊ฐ,์ •์‚ฌ๊ฐ์ด๋ผ ๊ฐ€์ •ํ•˜๊ณ  ์ƒ์ž์˜ ์ค‘์‹ฌ์œผ๋กœ ๊ณ„์‚ฐ + const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //์˜†์—์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2 + startPoint = { ...startPoint, y1: startPoint.y1 - heightMargin } } } } + // else { + // //์ค‘์•™๋ฐฐ์น˜๊ฐ€ ์•„๋‹๋•Œ๋„ ํ๋ฆ„ ๋ฐฉํ–ฅ ๊ธฐ์ค€๋ฉด์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ๊ฐ€์šด๋ฐ ๋ฐฐ์น˜ + // if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + // //ํ•˜๋‹จ ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + // const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + // const halfModuleWidthLength = width / 2 + // startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + // } + // } + + const maxLeftEndPoint = surfaceMaxLines.left.x1 //์ตœ ์ขŒ์ธก + const maxRightEndPoint = surfaceMaxLines.right.x1 //์ตœ ์šฐ์ธก + const maxTopEndPoint = surfaceMaxLines.top.y1 //์ตœ ์ƒ๋‹จ + + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalTopEndPoint = maxTopEndPoint - startPoint.y1 + let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + let tempMaxWidth = isMaxSetup ? width / 2 : width //์ตœ๋Œ€๋ฐฐ์น˜์ธ์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ๋„ฃ์Œ + if (isMaxSetup) totalWidth = totalWidth * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌํ•˜๊ธฐ์œ„ํ•จ + + for (let j = 0; j < diffTopEndPoint; j++) { + bottomMargin = j === 0 ? 1 : 2 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = i === 0 ? 1 : 2 + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + + square = [ + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.left + + //์ค‘์•™๋ฐฐ์น˜์ผ ๊ฒฝ์šฐ์—๋Š” ๊ณ„์‚ฐํ•œ๋‹ค + if (isCenter) { + if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') { + //์ขŒ์ธก ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const halfModuleWidthLength = height / 2 + startPoint = { ...startPoint, y1: halfWidthLength - halfModuleWidthLength } + if (flowModuleLine.right.type === 'flat') { + //์šฐ์ธก๊นŒ์ง€ ํ‰๋ฉด์ด๋ฉด ์ง์‚ฌ๊ฐ,์ •์‚ฌ๊ฐ์ด๋ผ ๊ฐ€์ •ํ•˜๊ณ  ์ƒ์ž์˜ ์ค‘์‹ฌ์œผ๋กœ ๊ณ„์‚ฐ + const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //์˜†์—์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2 + startPoint = { ...startPoint, x1: startPoint.x1 + widthMargin } + } + } + } + + const maxRightEndPoint = surfaceMaxLines.right.x1 //์ตœ ์šฐ์ธก + const maxTopEndPoint = surfaceMaxLines.top.y1 //์ตœ ์ƒ๋‹จ + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //์ตœํ•˜๋‹จ + + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //์ „์ฒด ๋†’์ด์—์„œ ํ˜„์žฌ ๋†’์ด๋ฅผ ๋บŒ + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + + let tempMaxHeight = isMaxSetup ? height / 2 : height //์ตœ๋Œ€๋ฐฐ์น˜์ธ์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ๋„ฃ์Œ + if (isMaxSetup) totalHeight = totalHeight * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌ + + for (let i = 0; i <= totalWidth; i++) { + bottomMargin = i === 0 ? 1 : 2 + for (let j = 0; j < totalHeight; j++) { + leftMargin = i === 0 ? 1 : 2 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } + + square = [ + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const topFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.top + + if (isCenter) { + //์ค‘์•™๋ฐฐ์น˜์ผ ๊ฒฝ์šฐ์—๋Š” ๊ณ„์‚ฐํ•œ๋‹ค + if (flowModuleLine.top.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + //ํ•˜๋‹จ ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const halfModuleWidthLength = width / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + + if (flowModuleLine.bottom.type === 'flat') { + //์ƒ๋‹จ๊นŒ์ง€ ํ‰๋ฉด์ด๋ฉด ์ง์‚ฌ๊ฐ,์ •์‚ฌ๊ฐ์ด๋ผ ๊ฐ€์ •ํ•˜๊ณ  ์ƒ์ž์˜ ์ค‘์‹ฌ์œผ๋กœ ๊ณ„์‚ฐ + const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //์˜†์—์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength, y1: startPoint.y1 - heightMargin } + } + } + } + // else { + // //์ค‘์•™๋ฐฐ์น˜๊ฐ€ ์•„๋‹๋•Œ๋„ ํ๋ฆ„ ๋ฐฉํ–ฅ ๊ธฐ์ค€๋ฉด์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ๊ฐ€์šด๋ฐ ๋ฐฐ์น˜ + // if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + // //ํ•˜๋‹จ ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + // const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + // const halfModuleWidthLength = width / 2 + // startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + // } + // } + + const maxLeftEndPoint = surfaceMaxLines.left.x1 //์ตœ ์ขŒ์ธก + const maxRightEndPoint = surfaceMaxLines.right.x1 //์ตœ ์šฐ์ธก + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //์ตœํ•˜๋‹จ + + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint + let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width)) + let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height)) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + let tempMaxWidth = isMaxSetup ? width / 2 : width //์ตœ๋Œ€๋ฐฐ์น˜์ธ์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ๋„ฃ์Œ + if (isMaxSetup) diffRightEndPoint = diffRightEndPoint * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌํ•˜๊ธฐ์œ„ํ•จ + + for (let j = 0; j < diffBottomEndPoint; j++) { + bottomMargin = j === 0 ? 1 : 2 + for (let i = 0; i < diffRightEndPoint; i++) { + leftMargin = i === 0 ? 1 : 2 + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + square = [ + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const rightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.right + + if (isCenter) { + if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') { + //์ขŒ์ธก ๊ธฐ์ค€์œผ๋กœ ์–‘๋ฉด์ด ์ง์„ ์ด๋ฉด ํ•˜๋‹จ ๋ฐฉ๋ฉด์œผ๋กœ ๊ฐ€์šด๋ฐ๋กœ ๋ฐฐ์น˜ + const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //๋ฐ‘์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const halfModuleWidthLength = height / 2 + startPoint = { ...startPoint, y1: halfWidthLength + halfModuleWidthLength } + + if (flowModuleLine.right.type === 'flat') { + //์šฐ์ธก๊นŒ์ง€ ํ‰๋ฉด์ด๋ฉด ์ง์‚ฌ๊ฐ,์ •์‚ฌ๊ฐ์ด๋ผ ๊ฐ€์ •ํ•˜๊ณ  ์ƒ์ž์˜ ์ค‘์‹ฌ์œผ๋กœ ๊ณ„์‚ฐ + const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //์˜†์—์— ๊ธธ์ด์—์„œ ๋ฐ˜์„ ๊ฐ€๋ฅธ๋‹ค + const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2 + startPoint = { ...startPoint, x1: startPoint.x1 - widthMargin } + } + } + } + + const maxLeftEndPoint = surfaceMaxLines.left.x1 //์ตœ ์ขŒ์ธก + const maxTopEndPoint = surfaceMaxLines.top.y1 //์ตœ ์ƒ๋‹จ + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //์ตœํ•˜๋‹จ + + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //์ „์ฒด ๋†’์ด์—์„œ ํ˜„์žฌ ๋†’์ด๋ฅผ ๋บŒ + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3์œผ๋กœ ์œ„์น˜์‚ด์ง ๋ณด์ • + + let tempMaxHeight = isMaxSetup ? height / 2 : height //์ตœ๋Œ€๋ฐฐ์น˜์ธ์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ๋„ฃ์Œ + if (isMaxSetup) totalHeight = totalHeight * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌ + + for (let i = 0; i <= totalWidth; i++) { + bottomMargin = i === 0 ? 1 : 2 + for (let j = 0; j < totalHeight; j++) { + leftMargin = j === 0 ? 1 : 2 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } + + square = [ + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { + moduleSetupSurface.fire('mousedown') + const moduleSetupArray = [] + + let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { + return acc.length > cur.length ? acc : cur + }) + + const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //ํด๋ฆฌ๊ณค์„ turf ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ + const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //๋ฐฐ์น˜๋ฉด์— ์˜ค๋ธŒ์ ํŠธ(๋„๋จธ, ๊ฐœ๊ตฌ๋“ฑ)์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4 let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2 @@ -488,205 +869,335 @@ export function useModuleBasicSetting() { height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2 } - let square - let startPoint, endPoint + const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) + //์ฒ˜๋งˆ๋ฉด ๋ฐฐ์น˜ if (setupLocation === 'eaves') { + // ํ๋ฆ„๋ฐฉํ–ฅ์ด ๋‚จ์ชฝ์ผ๋•Œ if (moduleSetupSurface.flowDirection === 'south') { - startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') - endPoint = flowModuleLine.find((obj) => obj.target === 'top') - const totalHeight = endPoint.y1 - startPoint.y1 - const diffHeight = Math.abs(totalHeight / height) - let leftMargin = 0 - let bottomMargin = 0 - - for (let i = 0; i < diffHeight; i++) { - leftMargin = i === 0 ? 1 : 0 - bottomMargin = i === 0 ? 0 : 1 - - square = [ - [startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin], - [startPoint.x1 + leftMargin, startPoint.y1 - bottomMargin], - [startPoint.x1 + leftMargin + width, startPoint.y1 - bottomMargin], - [startPoint.x1 + leftMargin + width, startPoint.y1 - height - bottomMargin], - [startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin], - ] - - const squarePolygon = turf.polygon([square]) - - //์„ค์น˜๋ฉด ์•ˆ์— ์žˆ๋Š”์ง€ ํ™•์ธ - const disjointFromTrestle = - turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) - - if (disjointFromTrestle) { - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - - if (containsBatchObjects.length > 0) { - let convertBatchObject - //๋„๋จธ๊ฐ€ ์žˆ์œผ๋ฉด ์ ์šฉ๋˜๋Š” ๋กœ์ง - const isDisjoint = containsBatchObjects.every((batchObject) => { - if (batchObject.type === 'group') { - convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) - } else { - convertBatchObject = polygonToTurfPolygon(batchObject) - } - return turf.booleanDisjoint(squarePolygon, convertBatchObject) //๋„๋จธ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ์ˆ˜์žˆ์œผ๋ฏ€๋กœ ๊ฒน์น˜๋Š”๊ฒŒ ์žˆ๋‹ค๋ฉด... - }) - if (isDisjoint) { - const tempModule = new QPolygon(points, { - fill: '#BFFD9F', - stroke: 'black', - strokeWidth: 0.1, - selectable: true, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • - lockMovementX: false, // X ์ถ• ์ด๋™ ์ž ๊ธˆ - lockMovementY: false, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ - lockRotation: false, // ํšŒ์ „ ์ž ๊ธˆ - lockScalingX: false, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ - lockScalingY: false, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ - opacity: 0.8, - parentId: moduleSetupSurface.parentId, - name: 'module', - }) - tempModule.setViewLengthText(false) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } else { - //๋„๋จธ๊ฐ€ ์—†์„๋• ๊ทธ๋ƒฅ ๊ทธ๋ฆผ - const tempModule = new QPolygon(points, { - fill: '#BFFD9F', - stroke: 'black', - selectable: true, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • - lockMovementX: true, // X ์ถ• ์ด๋™ ์ž ๊ธˆ - lockMovementY: true, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ - lockRotation: true, // ํšŒ์ „ ์ž ๊ธˆ - lockScalingX: true, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ - lockScalingY: true, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ - opacity: 0.8, - parentId: moduleSetupSurface.parentId, - name: 'module', - }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - startPoint = { x1: points[0].x, y1: points[0].y, x2: points[3].x, y2: points[3].y } - } - } + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'west') { + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'east') { + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'north') { + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } } else if (setupLocation === 'ridge') { - } else { + //์šฉ๋งˆ๋ฃจ + if (moduleSetupSurface.flowDirection === 'south') { + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'west') { + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'east') { + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'north') { + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + } else if (setupLocation === 'center') { + //์ค‘๊ฐ€๋ฉด + if (moduleSetupSurface.flowDirection === 'south') { + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'west') { + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'east') { + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'north') { + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } } - moduleSetupSurface.set({ modules: moduleSetupArray }) + const setupedModules = moduleSetupArray.filter((module, index) => { + let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) + let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) + + if (!(disjointFromTrestle && isDisjoint)) { + canvas?.remove(module) + // module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + return false + } else { + return module + } + }) + + canvas?.renderAll() + + //๋‚˜๊ฐ„์• ๋“ค ์ œ์™ธํ•˜๊ณ  ์„ค์น˜๋œ ์• ๋“ค๋กœ ๊ฒน์นœ์• ๋“ค ์‚ญ์ œ ํ•˜๊ธฐ + setupedModules.forEach((module, index) => { + if (isMaxSetup && index > 0) { + const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module)) + //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ + if (isOverlap) { + //๊ฒน์ณ์žˆ์œผ๋ฉด ์‚ญ์ œ + canvas?.remove(module) + // module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 }) + canvas.renderAll() + setupedModules.splice(index, 1) + return false + } + } + }) + + moduleSetupSurface.set({ modules: setupedModules }) + + // const moduleArray = [...moduleIsSetup] + // moduleArray.push({ + // surfaceId: moduleSetupSurface.surfaceId, + // moduleSetupArray: setupedModules, + // }) + // setModuleIsSetup(moduleArray) }) - - setModuleIsSetup(moduleSetupArray) - - console.log(calculateForApi(moduleSetupArray)) + calculateForApi() } - const calculateForApi = (moduleSetupArray) => { - const centerPoints = [] - moduleSetupArray.forEach((module, index) => { - module.tempIndex = index - const { x, y } = module.getCenterPoint() - const { width, height } = module - centerPoints.push({ x, y, width, height, index }) - const circle = new fabric.Circle({ - radius: 5, - fill: 'red', - name: 'redCircle', - left: x - 5, - top: y - 5, - index: index, - selectable: false, + const calculateForApi = () => { + const moduleSufaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + + const results = [] + + moduleSufaces.forEach((moduleSurface) => { + const centerPoints = [] + const direction = moduleSurface.direction + const modules = moduleSurface.modules + + modules.forEach((module, index) => { + module.tempIndex = index + const { x, y } = module.getCenterPoint() + const { width, height } = module + centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index }) + }) + + if (centerPoints.length === 0) return + + //์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด + let exposedBottom = 0 + // ๋ฐ˜ ๋…ธ์ถœ ํ•˜๋ฉด + let exposedHalfBottom = 0 + // ์™„์ „ ๋…ธ์ถœ ์ƒ๋ฉด + let exposedTop = 0 + //๋ฐ˜ ๋…ธ์ถœ ์ƒ๋ฉด + let exposedHalfTop = 0 + // ์™„์ „ ์ ‘๋ฉด + let touchDimension = 0 + //๋ฐ˜์ ‘๋ฉด + let halfTouchDimension = 0 + // ๋…ธ์ถœํ•˜๋ฉด ์ฒดํฌ + centerPoints.forEach((centerPoint, index) => { + const { x, y, width, height } = centerPoint + // centerPoints์ค‘์— ํ˜„์žฌ centerPoint์™€ x๊ฐ’์ด ๊ฐ™๊ณ , y๊ฐ’์ด y-height๊ฐ’๊ณผ ๊ฐ™์€ centerPoint๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ + let bottomCell + let bottomLeftPoint + let bottomRightPoint + let leftBottomCnt + let rightBottomCnt + + switch (direction) { + case 'south': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + bottomLeftPoint = { x: x - width / 2, y: y + height } + bottomRightPoint = { x: x + width / 2, y: y + height } + break + case 'north': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + bottomLeftPoint = { x: x + width / 2, y: y - height } + bottomRightPoint = { x: x - width / 2, y: y - height } + break + case 'east': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomLeftPoint = { x: x + width, y: y + height / 2 } + bottomRightPoint = { x: x + width, y: y - height / 2 } + break + case 'west': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomLeftPoint = { x: x - width, y: y - height / 2 } + bottomRightPoint = { x: x - width, y: y + height / 2 } + break + } + + if (bottomCell.length === 1) { + return + } + + // ๋ฐ”๋กœ ์•„๋ž˜์— ์…€์ด ์—†๋Š” ๊ฒฝ์šฐ ๋ฌผ๋–ผ์„ธ ๋ฐฐ์น˜๊ฐ€ ์™ผ์ชฝ ๋˜์–ด์žˆ๋Š” ์…€์„ ์ฐพ๋Š”๋‹ค. + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2, + ).length + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2, + ).length + + if (leftBottomCnt + rightBottomCnt === 1) { + exposedHalfBottom++ + return + } + }) + // ๋…ธ์ถœ์ƒ๋ฉด ์ฒดํฌ + + centerPoints.forEach((centerPoint, index) => { + const { x, y, width, height } = centerPoint + + let topCell + let topLeftPoint + let topRightPoint + let leftTopCnt + let rightTopCnt + + switch (direction) { + case 'south': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + topLeftPoint = { x: x - width / 2, y: y - height } + topRightPoint = { x: x + width / 2, y: y - height } + break + case 'north': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + topLeftPoint = { x: x + width / 2, y: y + height } + topRightPoint = { x: x - width / 2, y: y + height } + break + case 'east': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + topLeftPoint = { x: x - width, y: y + height / 2 } + topRightPoint = { x: x - width, y: y - height / 2 } + break + case 'west': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + topLeftPoint = { x: x + width, y: y - height / 2 } + topRightPoint = { x: x + width, y: y + height / 2 } + break + } + + if (topCell.length === 1) { + touchDimension++ + return + } + + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2, + ).length + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, + ).length + + if (leftTopCnt + rightTopCnt === 2) { + touchDimension++ + return + } + + if (leftTopCnt + rightTopCnt === 1) { + exposedHalfTop++ + halfTouchDimension++ + return + } + if (leftTopCnt + rightTopCnt === 0) { + exposedTop++ + } + }) + // ์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด ๊ณ„์‚ฐ + + /*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId) + const points = cells.map((cell) => { + return cell.getCenterPoint() + })*/ + const groupPoints = groupCoordinates(centerPoints, modules[0], direction) + + groupPoints.forEach((group) => { + let maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y + let minY = group.reduce((acc, cur) => (acc.y < cur.y ? acc : cur)).y + let maxX = group.reduce((acc, cur) => (acc.x > cur.x ? acc : cur)).x + let minX = group.reduce((acc, cur) => (acc.x < cur.x ? acc : cur)).x + + let maxYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - maxY) < 2) + let minYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - minY) < 2) + let maxXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - maxX) < 2) + let minXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - minX) < 2) + + switch (direction) { + case 'south': + exposedBottom += maxYCenterPoint.length + break + case 'north': + exposedBottom += minYCenterPoint.length + break + case 'east': + exposedBottom += maxXCenterPoint.length + break + case 'west': + exposedBottom += minXCenterPoint.length + break + } + }) + + results.push({ + exposedBottom, + exposedHalfBottom, + exposedTop, + exposedHalfTop, + touchDimension, + halfTouchDimension, + }) + console.log({ + direction, + exposedBottom, + exposedHalfBottom, + exposedTop, + exposedHalfTop, + touchDimension, + halfTouchDimension, }) - canvas.add(circle) }) - //์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด - let exposedBottom = 0 - // ๋ฐ˜ ๋…ธ์ถœ ํ•˜๋ฉด - let exposedHalfBottom = 0 - // ์™„์ „ ๋…ธ์ถœ ์ƒ๋ฉด - let exposedTop = 0 - //๋ฐ˜ ๋…ธ์ถœ ์ƒ๋ฉด - let exposedHalfTop = 0 - // ์™„์ „ ์ ‘๋ฉด - let touchDimension = 0 - //๋ฐ˜์ ‘๋ฉด - let halfTouchDimension = 0 - // ๋…ธ์ถœํ•˜๋ฉด ์ฒดํฌ - centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint - // centerPoints์ค‘์— ํ˜„์žฌ centerPoint์™€ x๊ฐ’์ด ๊ฐ™๊ณ , y๊ฐ’์ด y-height๊ฐ’๊ณผ ๊ฐ™์€ centerPoint๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ - const bottomCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y + height)) < 2) - if (bottomCell.length === 1) { - touchDimension++ - return - } + return results + } - const bottomLeftPoint = { x: x - width / 2, y: y + height } - const bottomRightPoint = { x: x + width / 2, y: y + height } + // polygon ๋‚ด๋ถ€ cell๋“ค์˜ centerPoint ๋ฐฐ์—ด์„ ๊ทธ๋ฃนํ™” ํ•ด์„œ ๋ฐ˜ํ™˜ + const groupCoordinates = (points, moduleExample, direction) => { + const groups = [] + const visited = new Set() + const width = Math.floor(moduleExample.width) + const height = Math.floor(moduleExample.height) + const horizonPadding = 0 // ๊ฐ€๋กœ ํŒจ๋”ฉ + const verticalPadding = 0 // ์„ธ๋กœ ํŒจ๋”ฉ - // ๋ฐ”๋กœ ์•„๋ž˜์— ์…€์ด ์—†๋Š” ๊ฒฝ์šฐ ๋ฌผ๋–ผ์„ธ ๋ฐฐ์น˜๊ฐ€ ์™ผ์ชฝ ๋˜์–ด์žˆ๋Š” ์…€์„ ์ฐพ๋Š”๋‹ค. - const leftBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2, - ).length - const rightBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2, - ).length - if (leftBottomCnt + rightBottomCnt === 2) { - touchDimension++ - return - } - if (leftBottomCnt + rightBottomCnt === 1) { - halfTouchDimension++ - exposedHalfBottom++ - return - } - if (leftBottomCnt + rightBottomCnt === 0) { - exposedBottom++ - return - } - }) - // ๋…ธ์ถœ์ƒ๋ฉด ์ฒดํฌ - - centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint - const topCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y - height)) < 2) - if (topCell.length === 1) { - return - } - - const topLeftPoint = { x: x - width / 2, y: y - height } - const topRightPoint = { x: x + width / 2, y: y - height } - - const leftTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, - ).length - const rightTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, - ).length - - if (leftTopCnt + rightTopCnt === 1) { - exposedHalfTop++ - return - } - if (leftTopCnt + rightTopCnt === 0) { - exposedTop++ - return - } - }) - return { - exposedBottom, - exposedHalfBottom, - exposedTop, - exposedHalfTop, - touchDimension, - halfTouchDimension, + function isAdjacent(p1, p2) { + const dx = Math.abs(p1.x - p2.x) + const dy = Math.abs(p1.y - p2.y) + return ( + (Math.abs(width + horizonPadding - dx) < 2 && dy < 2) || + (dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 || + (Math.abs(dx - width / 2 + horizonPadding / 2) < 2 && Math.abs(dy - height + verticalPadding) < 2) + ) } + + function dfs(point, group) { + visited.add(`${point.x},${point.y}`) + group.push(point) + + for (const nextPoint of points) { + const key = `${nextPoint.x},${nextPoint.y}` + if (!visited.has(key) && isAdjacent(point, nextPoint)) { + dfs(nextPoint, group) + } + } + } + + for (const point of points) { + const key = `${point.x},${point.y}` + if (!visited.has(key)) { + const group = [] + dfs(point, group) + groups.push(group) + } + } + + return groups } const coordToTurfPolygon = (points) => { @@ -744,9 +1255,8 @@ export function useModuleBasicSetting() { ) flowArray.push(topFlow) - let idx = 0 let rtnObjArray = [] - flowArray.forEach((center) => { + flowArray.forEach((center, index) => { const linesArray = new Array() surface.lines.filter((line) => { @@ -779,35 +1289,60 @@ export function useModuleBasicSetting() { const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000) const angle3 = 180 - (angle1 + angle2) - const charlie = 173.3 + 3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ ์คŒ + const charlie = 173.3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ ์คŒ const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180) const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180)) const h = beta * Math.sin((angle1 * Math.PI) / 180) // ๋†’์ด const sign = Math.sign(coords[0].y - coords[1].y) // ์ง„ํ–‰๋ฐฉํ–ฅ const top = coords[1].y + sign * h // ๋ณ€๊ฒฝ๋˜๋Š” ๋†’์ด ์ขŒํ‘œ ๊ฐ’ - // const line3 = new QLine([coords[1].x, coords[1].y, coords[1].x, top], { - // stroke: 'blue', - // strokeWidth: 1, - // selectable: true, - // }) - // // canvas?.add(line3) const pointX1 = coords[0].x + ((coords[0].y - top) / (coords[0].y - coords[1].y)) * (coords[1].x - coords[0].x) const pointY1 = top const pointX2 = coords[2].x + ((coords[2].y - top) / (coords[2].y - coords[1].y)) * (coords[1].x - coords[2].x) const pointY2 = top - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) - canvas?.add(finalLine) - canvas?.renderAll() + // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { + // stroke: 'red', + // strokeWidth: 1, + // selectable: true, + // }) + // canvas?.add(finalLine) + // canvas?.renderAll() + + let rtnObj + //ํ‰ํ‰ํ•˜๋ฉด + if (alpha === 0 || beta === 0 || h === 0 || sign === 0) { + //๊ผญ์ง€์ ์ด ์—†๊ณ  ํ‰ํ‰ํ• ๋•Œ ex) ๋„ค๋ชจ + let standardLine + if (index === 0) { + //bottom + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.y2 > acc.y2)) { + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } + } + return acc + }) + } else { + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.y2 < acc.y2)) { + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } + } + return acc + }) + } + rtnObj = { + target: index === 0 ? 'bottom' : 'top', + x1: standardLine.x1, + y1: standardLine.y1, + x2: standardLine.x2, + y2: standardLine.y2, + type: 'flat', + } + } else { + rtnObj = { target: index === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2, type: 'curve' } + } - const rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } rtnObjArray.push(rtnObj) - ++idx }) return rtnObjArray @@ -837,9 +1372,8 @@ export function useModuleBasicSetting() { ) flowArray.push(rightFlow) - let idx = 0 let rtnObjArray = [] - flowArray.forEach((center) => { + flowArray.forEach((center, index) => { const linesArray = surface.lines.filter((line) => { if ((center.x1 === line.x1 && center.y1 === line.y1) || (center.x1 === line.x2 && center.y1 === line.y2)) { return line @@ -870,7 +1404,7 @@ export function useModuleBasicSetting() { const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000) const angle3 = 180 - (angle1 + angle2) - const charlie = 173.3 + 3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ์คŒ + const charlie = 173.3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ์คŒ const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180) const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180)) @@ -890,18 +1424,49 @@ export function useModuleBasicSetting() { const pointX2 = top const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y) - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) - canvas?.add(finalLine) - canvas?.renderAll() + // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { + // stroke: 'red', + // strokeWidth: 1, + // selectable: true, + // }) + // canvas?.add(finalLine) + // canvas?.renderAll() - const rtnObj = { target: idx === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + let rtnObj + //ํ‰ํ‰ํ•˜๋ฉด + if (alpha === 0 || beta === 0 || h === 0 || sign === 0) { + //๊ผญ์ง€์ ์ด ์—†๊ณ  ํ‰ํ‰ํ• ๋•Œ ex) ๋„ค๋ชจ + let standardLine + if (index === 0) { + //bottom + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) { + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } + } + return acc + }) + } else { + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) { + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } + } + return acc + }) + } + rtnObj = { + target: index === 0 ? 'left' : 'right', + x1: standardLine.x1, + y1: standardLine.y1, + x2: standardLine.x2, + y2: standardLine.y2, + type: 'flat', + } + } else { + rtnObj = { target: index === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2, type: 'curve' } + } rtnObjArray.push(rtnObj) - ++idx }) + return rtnObjArray } const findSetupSurfaceMaxLines = (surface) => { @@ -955,9 +1520,343 @@ export function useModuleBasicSetting() { return obj } + const manualFlatroofModuleSetup = (placementFlatRef) => { + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //๋ชจ๋“ˆ์„ค์น˜๋ฉด๋ฅผ ๊ฐ€์ ธ์˜ด + let applyAngle + let flatBatchType = placementFlatRef.setupLocation.current.value + let excretaLinesAngle = [] + + if (flatBatchType === 'south') { + applyAngle = compasDeg + } else { + const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine' && obj.isSelected === true) + excretaLines.forEach((obj) => { + const points1 = { x: obj.x1, y: obj.y1 } + const points2 = { x: obj.x2, y: obj.y2 } + excretaLinesAngle.push({ + surfaceId: obj.surfaceId, + angle: calculateAngle(points1, points2), + }) + }) + } + + //calculateAngle + + const batchObjects = canvas + ?.getObjects() + .filter( + (obj) => + obj.name === BATCH_TYPE.OPENING || + obj.name === BATCH_TYPE.TRIANGLE_DORMER || + obj.name === BATCH_TYPE.PENTAGON_DORMER || + obj.name === BATCH_TYPE.SHADOW, + ) //๋„๋จธs ๊ฐ์ฒด + + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: false, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • + lockMovementX: true, // X ์ถ• ์ด๋™ ์ž ๊ธˆ + lockMovementY: true, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ + lockRotation: true, // ํšŒ์ „ ์ž ๊ธˆ + lockScalingX: true, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + lockScalingY: true, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } + + function getRotatedCorners(rect) { + // ์‚ฌ๊ฐํ˜•์˜ ์ค‘์‹ฌ์  + const center = rect.getCenterPoint() + + // ์‚ฌ๊ฐํ˜•์˜ ์›๋ž˜ ๊ผญ์ง“์  ์ขŒํ‘œ (๋กœ์ปฌ ์ขŒํ‘œ ๊ธฐ์ค€) + const halfWidth = (rect.width / 2) * rect.scaleX + const halfHeight = (rect.height / 2) * rect.scaleY + + const corners = [ + { x: -halfWidth, y: -halfHeight }, // ์ขŒ์ƒ๋‹จ + { x: halfWidth, y: -halfHeight }, // ์šฐ์ƒ๋‹จ + { x: halfWidth, y: halfHeight }, // ์šฐํ•˜๋‹จ + { x: -halfWidth, y: halfHeight }, // ์ขŒํ•˜๋‹จ + ] + + // ๊ฐ ๊ผญ์ง“์  ์ขŒํ‘œ๋ฅผ ์บ”๋ฒ„์Šค ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ + const transformedCorners = corners.map((corner) => { + const point = new fabric.Point(corner.x, corner.y) + return fabric.util.transformPoint(point, rect.calcTransformMatrix()) + }) + + return transformedCorners + } + + function getSelectedExcretaLine() {} + + if (moduleSetupSurfaces.length !== 0) { + let tempModule + let manualDrawModules = [] + let inside = false + let turfPolygon + let flowDirection + let trestlePolygon + + addCanvasMouseEventListener('mouse:move', (e) => { + //๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์‚ญ์ œ ํ›„ ์žฌ์ถ”๊ฐ€ + const mousePoint = canvas.getPointer(e.e) + + for (let i = 0; i < moduleSetupSurfaces.length; i++) { + turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) + trestlePolygon = moduleSetupSurfaces[i] + manualDrawModules = moduleSetupSurfaces[i].modules // ์•ž์—์„œ ์ž๋™์œผ๋กœ ํ–ˆ์„๋•Œ ์ถ”๊ฐ€๋จ + flowDirection = moduleSetupSurfaces[i].flowDirection //๋„ํ˜•์˜ ๋ฐฉํ–ฅ + + if (flatBatchType === 'excreta') { + const tempLine = excretaLinesAngle.find((obj) => obj.surfaceId === trestlePolygon.surfaceId) + if (tempLine) { + applyAngle = tempLine.angle + } else { + applyAngle = compasDeg + } + } + + // const excretaLine = excretaLines.find((obj) => obj.isSelected === true && obj.surfaceId === trestlePolygon.surfaceId) + + // console.log('excretaLine', excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) + + // applyAngle = calculateAngle(excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) + + // console.log('applyAngle', applyAngle) + + let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113 + let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172 + + const angledModule = new fabric.Rect({ + width: width, + height: height, + left: mousePoint.x - width / 2, + top: mousePoint.y - height / 2, + }) + + const center = angledModule.getCenterPoint() + angledModule.set('angle', applyAngle) + angledModule.setPositionByOrigin(center, 'center', 'center') + + const points = getRotatedCorners(angledModule) // + const turfPoints = coordToTurfPolygon(points) + + if (turf.booleanWithin(turfPoints, turfPolygon)) { + let isDrawing = false + + if (isDrawing) return + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //์›€์ง์ผ๋•Œ ์ผ๋‹จ ์ง€์›Œ๊ฐ€๋ฉด์„œ ์›€์ง์ž„ + + tempModule = new QPolygon(points, { + fill: 'white', + stroke: 'black', + strokeWidth: 0.3, + name: 'tempModule', + }) + + canvas?.add(tempModule) //์›€์ง์—ฌ๊ฐ€๋ฉด์„œ ์ถ”๊ฐ€๋จ + canvas?.renderAll() + + /** + * ์Šค๋ƒ…๊ธฐ๋Šฅ + */ + let snapDistance = 10 + let cellSnapDistance = 20 + + const trestleLeft = moduleSetupSurfaces[i].left + const trestleTop = moduleSetupSurfaces[i].top + const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX + const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY + const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 + + // ์ž‘์€ ํด๋ฆฌ๊ณค์˜ ๊ฒฝ๊ณ„ ์ขŒํ‘œ ๊ณ„์‚ฐ + const smallLeft = tempModule.left + const smallTop = tempModule.top + const smallRight = smallLeft + tempModule.width * tempModule.scaleX + const smallBottom = smallTop + tempModule.height * tempModule.scaleY + const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2 + const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2 + + if (manualDrawModules) { + manualDrawModules.forEach((cell) => { + const holdCellLeft = cell.left + const holdCellTop = cell.top + const holdCellRight = holdCellLeft + cell.width * cell.scaleX + const holdCellBottom = holdCellTop + cell.height * cell.scaleY + const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2 + const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2 + + //์„ค์น˜๋œ ์…€์— ์ขŒ์ธก์— ์Šค๋ƒ… + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft - width - 0.5 + } + + //์„ค์น˜๋œ ์…€์— ์šฐ์ธก์— ์Šค๋ƒ… + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + tempModule.left = holdCellRight + 0.5 + } + + //์„ค์น˜๋œ ์…€์— ์œ„์ชฝ์— ์Šค๋ƒ… + if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + tempModule.top = holdCellTop - height - 0.5 + } + + //์„ค์น˜๋œ ์…€์— ๋ฐ‘์ชฝ์— ์Šค๋ƒ… + if (Math.abs(smallTop - holdCellBottom) < snapDistance) { + tempModule.top = holdCellBottom + 0.5 + } + //๊ฐ€์šด๋ฐ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX - width / 2 + } + //์™ผ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX + } + // ์˜ค๋ฅธ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX - width + } + //์„ธ๋กœ ๊ฐ€์šด๋ฐ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY - height / 2 + } + //์œ„์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY + } + //์•„๋žซ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY - height + } + }) + } + + // ์œ„์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallTop - trestleTop) < snapDistance) { + tempModule.top = trestleTop + } + + // ์•„๋ž˜์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY + } + + // ์™ผ์ชฝ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallLeft - trestleLeft) < snapDistance) { + tempModule.left = trestleLeft + } + //์˜ค๋ฅธ์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallRight - trestleRight) < snapDistance) { + tempModule.left = trestleRight - tempModule.width * tempModule.scaleX + } + + if (flowDirection === 'south' || flowDirection === 'north') { + // ๋ชจ๋“ˆ์™ผ์ชฝ์ด ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 + } + + // ๋ชจ๋“ˆ์ด ๊ฐ€์šด๋ฐ๊ฐ€ ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2 + } + + // ๋ชจ๋“ˆ์˜ค๋ฅธ์ชฝ์ด ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX + } + } else { + // ๋ชจ๋“ˆ์ด ๊ฐ€๋กœ์ค‘์•™์„ ์— ์Šค๋ƒ… + if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) { + tempModule.top = bigCenterY - tempModule.height / 2 + } + + if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 + } + // ๋ชจ๋“ˆ ๋ฐ‘๋ฉด์ด ๊ฐ€๋กœ์ค‘์•™์„ ์— ์Šค๋ƒ… + if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY + } + } + + inside = true + break + } else { + inside = false + } + } + + if (!inside) { + // tempModule.set({ fill: 'red' }) + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) + canvas?.renderAll() + } + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + let isIntersection = true + if (!inside) return + if (tempModule) { + const tempTurfModule = polygonToTurfPolygon(tempModule) + + //๋„๋จธ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ด + if (batchObjects) { + batchObjects.forEach((object) => { + let dormerTurfPolygon + + if (object.type === 'group') { + //๋„๋จธ๋Š” ๊ทธ๋ฃนํ˜•ํƒœ์ž„ + dormerTurfPolygon = batchObjectGroupToTurfPolygon(object) + } else { + //๊ฐœ๊ตฌ, ๊ทธ๋ฆผ์ž + dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object)) + } + + const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ + //๊ฒน์น˜๋ฉด ์•ˆ๋จ + if (intersection) { + alert('๋„๋จธ์œ„์— ๋ชจ๋“ˆ์„ ์˜ฌ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.') + isIntersection = false + } + }) + } + + if (!isIntersection) return + + if (turf.booleanWithin(tempTurfModule, turfPolygon)) { + //๋งˆ์šฐ์Šค ํด๋ฆญ์‹œ set์œผ๋กœ ํ•ด๋‹น ์œ„์น˜์— ์…€์„ ๋„ฃ์Œ + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ + if (!isOverlap) { + console.log('tempModule.points', tempModule.points) + + let manualModule = new QPolygon(tempModule.points, { ...moduleOptions }) + canvas?.add(manualModule) + manualDrawModules.push(tempModule) + } else { + alert('์…€๋ผ๋ฆฌ ๊ฒน์น˜๋ฉด ์•ˆ๋˜์ฃ ?') + } + } else { + alert('๋‚˜๊ฐ”์ฃ ?!!') + } + } + }) + } + } + + const autoFlatroofModuleSetup = (placementFlatRef) => {} + return { makeModuleInstArea, manualModuleSetup, autoModuleSetup, + restoreModuleInstArea, + manualFlatroofModuleSetup, + autoFlatroofModuleSetup, } } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index c3155512..77ff8bc3 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -1,16 +1,43 @@ import { useCallback, useEffect, useState } from 'react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { adsorptionPointModeState, adsorptionRangeState, canvasState, planSizeSettingState } from '@/store/canvasAtom' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' +import { + adsorptionPointModeState, + adsorptionRangeState, + canvasState, + planSizeSettingState, + dotLineGridSettingState, + canvasSettingState, +} from '@/store/canvasAtom' import { globalLocaleStore } from '@/store/localeAtom' import { useMessage } from '@/hooks/useMessage' import { useAxios } from '@/hooks/useAxios' import { useSwal } from '@/hooks/useSwal' -import { correntObjectNoState, corridorDimensionSelector, settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' +import { + correntObjectNoState, + corridorDimensionSelector, + settingModalFirstOptionsState, + settingModalSecondOptionsState, + settingModalGridOptionsState, + basicSettingState, + settingsState, +} from '@/store/settingAtom' import { POLYGON_TYPE } from '@/common/common' import { globalFontAtom } from '@/store/fontAtom' import { dimensionLineSettingsState } from '@/store/commonUtilsAtom' +import { gridColorState } from '@/store/gridAtom' +import { useColor } from 'react-color-palette' -let objectNo +const defaultDotLineGridSetting = { + INTERVAL: { + type: 2, // 1: ๊ฐ€๋กœ,์„ธ๋กœ ๊ฐ„๊ฒฉ ์ˆ˜๋™, 2: ๋น„์œจ ๊ฐ„๊ฒฉ + ratioInterval: 910, + verticalInterval: 910, + horizontalInterval: 910, + dimension: 1, // ์น˜์ˆ˜ + }, + DOT: false, + LINE: false, +} export function useCanvasSetting() { const canvas = useRecoilValue(canvasState) @@ -20,8 +47,11 @@ export function useCanvasSetting() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) + + // const [settingsData, setSettingsData] = useRecoilState(settingsState) + const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions }) const { option1, option2, dimensionDisplay } = settingModalFirstOptions - const { option3, option4 } = settingModalSecondOptions + const { option4 } = settingModalSecondOptions const corridorDimension = useRecoilValue(corridorDimensionSelector) @@ -42,6 +72,27 @@ export function useCanvasSetting() { const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState) + const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) + const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) + const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) + const [currentSetting, setCurrentSetting] = useState( + JSON.stringify(dotLineGridSetting) === JSON.stringify(defaultDotLineGridSetting) ? { ...defaultDotLineGridSetting } : { ...dotLineGridSetting }, + ) + const [gridColor, setGridColor] = useRecoilState(gridColorState) + const [color, setColor] = useColor(gridColor ?? '#FF0000') + const [colorTemp, setColorTemp] = useState() + + const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) + + const SelectOptions = [ + { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, + { id: 2, name: '1/2', value: 1 / 2 }, + { id: 3, name: '1/4', value: 1 / 4 }, + { id: 4, name: '1/10', value: 1 / 10 }, + ] + const [selectOption, setSelectOption] = useState(SelectOptions[0]) + useEffect(() => { if (!canvas) { return @@ -72,51 +123,66 @@ export function useCanvasSetting() { canvas?.renderAll() }, [corridorDimension]) + // ๋ฐฐ์น˜๋ฉด ์ดˆ๊ธฐ์„ค์ • ๋ณ€๊ฒฝ ์‹œ useEffect(() => { - console.log('useCanvasSetting useEffect ์‹คํ–‰1', correntObjectNo) - }, []) + //console.log('useCanvasSetting canvasSetting ์‹คํ–‰', canvasSetting) + if (canvasSetting.flag) { + basicSettingSave() + } + }, [canvasSetting]) + + useEffect(() => { + console.log('๐Ÿš€ ~ useEffect ~ settingsData:', settingsData) + }, [settingsData]) //ํก์ฐฉ์  ON/OFF ๋ณ€๊ฒฝ ์‹œ - useEffect(() => { - console.log('useCanvasSetting useEffect ์‹คํ–‰2', adsorptionPointMode.fontFlag, correntObjectNo) - - if (adsorptionPointMode.fontFlag) { - onClickOption2() - frontSettings() - fetchSettings() - } - }, [adsorptionPointMode]) + // useEffect(() => { + // //console.log('useCanvasSetting ์‹คํ–‰2', adsorptionPointMode.fontFlag, correntObjectNo) + // if (adsorptionPointMode.fontFlag) { + // onClickOption2() + // } + // }, [adsorptionPointMode]) // 1 ๊ณผ 2 ๋ณ€๊ฒฝ ์‹œ - useEffect(() => { - console.log('useCanvasSetting useEffect ์‹คํ–‰3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo) - if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) { - onClickOption2() - frontSettings() - fetchSettings() - } - }, [settingModalFirstOptions, settingModalSecondOptions]) + // useEffect(() => { + // //console.log('useCanvasSetting ์‹คํ–‰3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo) + // if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) { + // onClickOption2() + // } + // }, [settingModalFirstOptions, settingModalSecondOptions]) // ๊ธ€๊ผด ๋ณ€๊ฒฝ ์‹œ - useEffect(() => { - console.log('useCanvasSetting useEffect ์‹คํ–‰4', globalFont.fontFlag, correntObjectNo) - if (globalFont.fontFlag) { - onClickOption2() - frontSettings() - fetchSettings() - } - }, [globalFont]) + // useEffect(() => { + // //console.log('useCanvasSetting ์‹คํ–‰4', globalFont.fontFlag, correntObjectNo) + // if (globalFont.fontFlag) { + // onClickOption2() + // } + // }, [globalFont]) // ๋„๋ช…ํฌ๊ธฐ ๋ณ€๊ฒฝ ์‹œ - useEffect(() => { - console.log('useCanvasSetting useEffect ์‹คํ–‰5', planSizeSettingMode.flag, correntObjectNo) + // useEffect(() => { + // //console.log('useCanvasSetting ์‹คํ–‰5', planSizeSettingMode.flag, correntObjectNo) + // if (planSizeSettingMode.flag) { + // onClickOption2() + // } + // }, [planSizeSettingMode]) - if (planSizeSettingMode.flag) { - onClickOption2() - frontSettings() - fetchSettings() - } - }, [planSizeSettingMode]) + // ์ /์„  ๊ทธ๋ฆฌ๋“œ ๋ณ€๊ฒฝ ์‹œ + // useEffect(() => { + // //console.log('useCanvasSetting ์‹คํ–‰6', dotLineGridSetting.flag) + // if (dotLineGridSetting.flag) { + // onClickOption2() + // } + // }, [dotLineGridSetting]) + + // ๊ทธ๋ฆฌ๋“œ ์ƒ‰ ์„ค์ • ๋ณ€๊ฒฝ ์‹œ + // useEffect(() => { + // console.log('useCanvasSetting ์‹คํ–‰7', colorTemp, gridColor) + // //colorTemp๋Š” ๋ณ€๊ฒฝ ์ „.. ๊ฐ’์ด ์žˆ๊ณ  ๋ณ€๊ฒฝ๋œ ์ปฌ๋Ÿฌ์™€ ๋‹ค๋ฅผ ๋•Œ ์‹คํ–‰ + // if (colorTemp !== undefined && colorTemp !== gridColor) { + // onClickOption2() + // } + // }, [color]) const getFonts = (itemValue) => { if (!itemValue) return { id: 1, name: 'MS PGothic', value: 'MS PGothic' } @@ -189,6 +255,95 @@ export function useCanvasSetting() { } } + // ๊ธฐ๋ณธ์„ค์ •(PlacementShapeSetting) ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” + const fetchBasicSettings = async () => { + try { + await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => { + console.log('fetchBasicSettings res ', res) + if (res.length == 0) return + + // 'roofs' ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ + const roofsRow = res.map((item) => { + return { + roofSizeSet: item.roofSizeSet, + roofAngleSet: item.roofAngleSet, + } + }) + + const roofsArray = res.some((item) => !item.roofSeq) + ? //์ตœ์ดˆ ์ง€๋ถ•์žฌ ์ถ”๊ฐ€ ์ •๋ณด์˜ ๊ฒฝ์šฐ roofsArray๋ฅผ ์ดˆ๊ธฐํ™” ์„ค์ • + res.map(() => ({ + flag: false, + roofApply: true, + roofSeq: 1, + roofType: 1, + 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, + roofHeight: item.roofHeight, + roofHajebichi: item.roofHajebichi, + roofGap: item.roofGap, + roofLayout: item.roofLayout, + })) + console.log('roofsArray ', roofsArray) + // ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ 'roofs' ๋ฐฐ์—ด์„ patternData์— ๋„ฃ์Œ + const patternData = { + roofSizeSet: roofsRow[0].roofSizeSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ + roofAngleSet: roofsRow[0].roofAngleSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ + roofs: roofsArray, // ๋งŒ๋“ค์–ด์ง„ roofs ๋ฐฐ์—ด + } + + //console.error('patternData', patternData) + + // ๋ฐ์ดํ„ฐ ์„ค์ • + setBasicSettings({ ...patternData }) + }) + } catch (error) { + console.error('Data fetching error:', error) + } + + if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { + setBasicSettings({ ...canvasSetting }) + } + //setCanvasSetting({ ...basicSetting }) + } + + // ๊ธฐ๋ณธ์„ค์ •(PlacementShapeSetting) ์ €์žฅ + const basicSettingSave = async () => { + try { + const patternData = { + objectNo: correntObjectNo, + roofSizeSet: basicSetting.roofSizeSet, + roofAngleSet: basicSetting.roofAngleSet, + roofMaterialsAddList: basicSetting.roofs, + } + + await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + swalFire({ text: getMessage(res.returnMessage) }) + }) + + //Recoil ์„ค์ • + setCanvasSetting({ ...basicSetting, flag: false }) + } catch (error) { + swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) + } + } + + // CanvasSetting ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” const fetchSettings = async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` }) @@ -269,10 +424,35 @@ export function useCanvasSetting() { //๊ธ€๊ผด ์„ค์ • Flag fontFlag: false, } - console.log('fontPatternData', fontPatternData) //์กฐํšŒ๋œ ๊ธ€๊ผด ๋ฐ์ดํ„ฐ set setGlobalFont(fontPatternData) + + //์ /์„  ๊ทธ๋ฆฌ๋“œ + const patternData = { + INTERVAL: { + type: res.gridType, + horizontalInterval: res.gridHorizon * 10, + verticalInterval: res.gridVertical * 10, + ratioInterval: res.gridRatio * 10, + dimension: res.gridDimen, + }, + DOT: res.dotGridDisplay, + LINE: res.lineGridDisplay, + flag: false, + } + + const matchedOption = SelectOptions.find((option) => option.value == res.gridDimen) + + // dimension ๊ฐ’์— ๋งž๋Š” ์˜ต์…˜์„ ์„ ํƒ + setSelectOption(matchedOption) + + setDotLineGridSettingState(patternData) + //setCurrentSetting(patternData) + + //๊ทธ๋ฆฌ๋“œ ์ƒ‰ ์„ค์ • + setGridColor(res.gridColor) + setColorTemp(res.gridColor) } else { //์กฐํšŒ๋œ ๊ธ€๊ผด ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ @@ -299,6 +479,14 @@ export function useCanvasSetting() { }) setGlobalFont({ ...globalFont, fontFlag: false }) + + //์ /์„  ๊ทธ๋ฆฌ๋“œ + setDotLineGridSettingState({ ...defaultDotLineGridSetting, flag: false }) + //setCurrentSetting({ ...defaultDotLineGridSetting }) + + //๊ทธ๋ฆฌ๋“œ ์ƒ‰ ์„ค์ • + setGridColor('#FF0000') + setColorTemp('#FF0000') } frontSettings() } catch (error) { @@ -306,8 +494,8 @@ export function useCanvasSetting() { } } - // ์˜ต์…˜ ํด๋ฆญ ํ›„ ์ €์žฅ - const onClickOption2 = useCallback(async () => { + // CanvasSetting ์˜ต์…˜ ํด๋ฆญ ํ›„ ์ €์žฅ + const onClickOption2 = async () => { // ์„œ๋ฒ„์— ์ „์†กํ•  ๋ฐ์ดํ„ฐ const dataToSend = { firstOption1: option1.map((item) => ({ @@ -394,13 +582,26 @@ export function useCanvasSetting() { originPixel: dimensionLineSettings.pixel, originColor: dimensionLineSettings.color, - //์น˜์ˆ˜์„  ์„ค์ • + //๋„๋ฉดํฌ๊ธฐ ์„ค์ • originHorizon: planSizeSettingMode.originHorizon, originVertical: planSizeSettingMode.originVertical, + + dotGridDisplay: dotLineGridSetting.DOT, + lineGridDisplay: dotLineGridSetting.LINE, + gridType: dotLineGridSetting.INTERVAL.type, + gridHorizon: dotLineGridSetting.INTERVAL.horizontalInterval / 10, + gridVertical: dotLineGridSetting.INTERVAL.verticalInterval / 10, + gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, + gridDimen: dotLineGridSetting.INTERVAL.dimension, + + //gridColor: gridColor.gridColor, + gridColor: gridColor, } console.log('patternData ', patternData) + setColorTemp(gridColor) + // HTTP POST ์š”์ฒญ ๋ณด๋‚ด๊ธฐ await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) .then((res) => { @@ -408,13 +609,15 @@ export function useCanvasSetting() { // Canvas ๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ • ์‹œ ํ•ด๋‹น ์˜ต์…˜ ์ ์šฉ frontSettings() + // ์ €์žฅ ํ›„ ์žฌ์กฐํšŒ + fetchSettings() }) .catch((error) => { swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) }) //setAdsorptionRange(item.range) - }, [settingModalFirstOptions, settingModalSecondOptions, adsorptionPointMode, globalFont, planSizeSettingMode]) + } // Canvas ๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ • ์‹œ ํ•ด๋‹น ์˜ต์…˜ ์ ์šฉ const frontSettings = async () => { @@ -491,6 +694,7 @@ export function useCanvasSetting() { return { canvas, + correntObjectNo, settingModalFirstOptions, setSettingModalFirstOptions, settingModalSecondOptions, @@ -500,7 +704,6 @@ export function useCanvasSetting() { adsorptionRange, setAdsorptionRange, fetchSettings, - //onClickOption, frontSettings, globalFont, setGlobalFont, @@ -516,5 +719,26 @@ export function useCanvasSetting() { setDimensionLineSettings, planSizeSettingMode, setPlanSizeSettingMode, + selectOption, + setSelectOption, + SelectOptions, + currentSetting, + setCurrentSetting, + dotLineGridSettingState, + setSettingModalGridOptions, + setDotLineGridSettingState, + resetDotLineGridSetting, + gridColor, + setGridColor, + color, + setColor, + canvasSetting, + setCanvasSetting, + basicSetting, + setBasicSettings, + fetchBasicSettings, + basicSettingSave, + settingsData, + setSettingsData, } } diff --git a/src/hooks/option/useCanvasSettingController.js b/src/hooks/option/useCanvasSettingController.js deleted file mode 100644 index 48db6c08..00000000 --- a/src/hooks/option/useCanvasSettingController.js +++ /dev/null @@ -1,127 +0,0 @@ -import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' -import { useEffect, useState } from 'react' -import { useRecoilState } from 'recoil' - -export const useCanvasSettingController = () => { - const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) - const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) - const [objectNo, setObjectNo] = useState('test123240912001') // ์ดํ›„ ์‚ญ์ œ ํ•„์š” - const { get } = useAxios() - - useEffect(() => { - fetchSettings() - }, [objectNo]) - - useEffect(() => { - fetchSettings() - }, []) - - useEffect(() => { - onClickOnlyOne() - fetchSettings() - }, [settingModalFirstOptions, settingModalSecondOptions]) - - const fetchSettings = async () => { - try { - const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) - const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] })) - const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] })) - const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item })) - const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] })) - const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ - ...item, - })) - // ๋ฐ์ดํ„ฐ ์„ค์ • - setSettingModalFirstOptions({ - option1: optionData1, - option2: optionData2, - dimensionDisplay: optionData5, - }) - setSettingModalSecondOptions({ - option3: optionData3, - option4: optionData4, - }) - } catch (error) { - console.error('Data fetching error:', error) - } - } - - // - const onClickOption = async (option) => { - option.selected = !option.selected - - setSettingModalFirstOptions({ option1, option2, dimensionDisplay }) - setSettingModalSecondOptions({ option3, option4 }) - - try { - // ์„œ๋ฒ„์— ์ „์†กํ•  ๋ฐ์ดํ„ฐ - const dataToSend = { - firstOption1: option1.map((item) => ({ - column: item.column, - selected: item.selected, - })), - firstOption2: option2.map((item) => ({ - column: item.column, - selected: item.selected, - })), - firstOption3: dimensionDisplay.map((item) => ({ - column: item.column, - selected: item.selected, - })), - // secondOption1: secondOptions[0].option1.map((item) => ({ - // name: item.id, - // name: item.name, - // // ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ ์ถ”๊ฐ€ - // })), - secondOption2: option4.map((item) => ({ - column: item.column, - selected: item.selected, - })), - } - - const patternData = { - objectNo, - //๋””์Šคํ”Œ๋ ˆ์ด ์„ค์ •(๋‹ค์ค‘) - allocDisplay: dataToSend.firstOption1[0].selected, - outlineDisplay: dataToSend.firstOption1[1].selected, - gridDisplay: dataToSend.firstOption1[2].selected, - lineDisplay: dataToSend.firstOption1[3].selected, - wordDisplay: dataToSend.firstOption1[4].selected, - circuitNumDisplay: dataToSend.firstOption1[5].selected, - flowDisplay: dataToSend.firstOption1[6].selected, - trestleDisplay: dataToSend.firstOption1[7].selected, - totalDisplay: dataToSend.firstOption1[8].selected, - //์ฐจ์ˆ˜ ํ‘œ์‹œ(๋‹ค๊ฑด) - corridorDimension: dataToSend.firstOption3[0].selected, - realDimension: dataToSend.firstOption3[1].selected, - noneDimension: dataToSend.firstOption3[2].selected, - //ํ™”๋ฉด ํ‘œ์‹œ(๋‹ค์ค‘) - onlyBorder: dataToSend.firstOption2[0].selected, - lineHatch: dataToSend.firstOption2[1].selected, - allPainted: dataToSend.firstOption2[2].selected, - //ํก์ฐฉ๋ฒ”์œ„ ์„ค์ •(๋‹จ๊ฑด) - adsorpRangeSmall: dataToSend.secondOption2[0].selected, - adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, - adsorpRangeMedium: dataToSend.secondOption2[2].selected, - adsorpRangeLarge: dataToSend.secondOption2[3].selected, - } - - // HTTP POST ์š”์ฒญ ๋ณด๋‚ด๊ธฐ - await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } - } - - return { - fetchSettings, - settingModalFirstOptions, - setSettingModalFirstOptions, - settingModalSecondOptions, - setSettingModalSecondOptions, - onClickOption, - รŸ, - } -} diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js index c668dd60..74bfcbcc 100644 --- a/src/hooks/roofcover/useOuterLineWall.js +++ b/src/hooks/roofcover/useOuterLineWall.js @@ -1,4 +1,4 @@ -import { useContext, useEffect, useRef } from 'react' +import { useEffect, useRef } from 'react' import { distanceBetweenPoints } from '@/util/canvas-util' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { @@ -31,7 +31,6 @@ import { fabric } from 'fabric' import { outlineDisplaySelector } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting' -import { EventContext } from '@/app/floor-plan/EventProvider' //์™ธ๋ฒฝ์„  ๊ทธ๋ฆฌ๊ธฐ export function useOuterLineWall(id, propertiesId) { diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 46dbbb35..d6443c2a 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -507,18 +507,33 @@ export function useCanvas(id) { * cad ํŒŒ์ผ ์‚ฌ์šฉ์‹œ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ํ•จ์ˆ˜ */ const handleBackImageLoadToCanvas = (url) => { - console.log('image load url: ', url) - - fabric.Image.fromURL(url, function (img) { + canvas + .getObjects() + .filter((obj) => obj.name === 'backGroundImage') + .forEach((img) => { + canvas.remove(img) + canvas?.renderAll() + }) + fabric.Image.fromURL(`${url}?${new Date().getTime()}`, function (img) { + console.log(img) img.set({ left: 0, top: 0, - width: 1500, - height: 1500, - selectable: true, + width: img.width, + height: img.height, + name: 'backGroundImage', + selectable: false, + hasRotatingPoint: false, // ํšŒ์ „ ํ•ธ๋“ค ํ™œ์„ฑํ™” + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, }) - canvas.add(img) - canvas.renderAll() + // image = img + canvas?.add(img) + canvas?.sendToBack(img) + canvas?.renderAll() setBackImg(img) }) } diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 16d0896d..55058cf4 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef } from 'react' +import { useRef } from 'react' import { useRecoilValue, useSetRecoilState } from 'recoil' import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom' import { fabric } from 'fabric' @@ -20,9 +20,15 @@ export function useEvent() { const textMode = useRecoilValue(textModeState) - useEffect(() => { - initEvent() - }, [currentMenu, canvas, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, dotLineGridSetting, tempGridMode]) + // ์ด๋ฒคํŠธ ์ดˆ๊ธฐํ™” ์œ„์น˜ ์ˆ˜์ • -> useCanvasSetting์—์„œ ์„ธํŒ…๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋‚˜์„œ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜ ํ˜ธ์ถœ + // useEffect(() => { + // initEvent() + // }, [currentMenu, canvas, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, dotLineGridSetting]) + + // ์ž„์‹œ ๊ทธ๋ฆฌ๋“œ ๋ชจ๋“œ ๋ณ€๊ฒฝ ์‹œ ์ด๋ฒคํŠธ ์ดˆ๊ธฐํ™” ํ˜ธ์ถœ ์œ„์น˜ ์ˆ˜์ • -> GridOption ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž„์‹œ ๊ทธ๋ฆฌ๋“œ ๋ชจ๋“œ ๋ณ€๊ฒฝ ์‹œ ์ด๋ฒคํŠธ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜ ํ˜ธ์ถœ + // useEffect(() => { + // initEvent() + // }, [tempGridMode]) const initEvent = () => { if (!canvas) { diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 6b1336a5..532759a4 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -1,11 +1,13 @@ import { useEffect, useState } from 'react' import { useRecoilState } from 'recoil' -import { v4 as uuidv4, validate as isValidUUID } from 'uuid' -import { canvasState, currentCanvasPlanState, initCanvasPlansState, plansState, modifiedPlansState, modifiedPlanFlagState } from '@/store/canvasAtom' +import { v4 as uuidv4 } from 'uuid' +import { canvasState, currentCanvasPlanState, plansState, modifiedPlansState, modifiedPlanFlagState } from '@/store/canvasAtom' import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' import { SAVE_KEY } from '@/common/common' +import { readImage, removeImage } from '@/lib/fileAction' +import { useCanvas } from '@/hooks/useCanvas' export function usePlan() { const [planNum, setPlanNum] = useState(0) @@ -13,9 +15,9 @@ export function usePlan() { const [currentCanvasStatus, setCurrentCanvasStatus] = useState(null) const [canvas, setCanvas] = useRecoilState(canvasState) + const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) - const [initCanvasPlans, setInitCanvasPlans] = useRecoilState(initCanvasPlansState) // DB์— ์ €์žฅ๋œ plan - const [plans, setPlans] = useRecoilState(plansState) // ์ „์ฒด plan (DB์— ์ €์žฅ๋œ plan + ์ €์žฅ ์•ˆ๋œ ์ƒˆ๋กœ์šด plan) + const [plans, setPlans] = useRecoilState(plansState) // ์ „์ฒด plan const [modifiedPlans, setModifiedPlans] = useRecoilState(modifiedPlansState) // ๋ณ€๊ฒฝ๋œ canvas plan const [modifiedPlanFlag, setModifiedPlanFlag] = useRecoilState(modifiedPlanFlagState) // ์บ”๋ฒ„์Šค ์‹ค์‹œ๊ฐ„ ์˜ค๋ธŒ์ ํŠธ ์ด๋ฒคํŠธ ๊ฐ์ง€ flag @@ -108,22 +110,22 @@ export function usePlan() { setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: currentCanvasStatus })) } }, [currentCanvasStatus]) + /** * ํ˜„์žฌ ์บ”๋ฒ„์Šค ์ƒํƒœ์™€ DB์— ์ €์žฅ๋œ ์บ”๋ฒ„์Šค ์ƒํƒœ๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ˆ˜์ • ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จ */ const checkModifiedCanvasPlan = (planId) => { - const canvasStatus = currentCanvasData() - if (isValidUUID(planId)) { - // ์ƒˆ๋กœ์šด ์บ”๋ฒ„์Šค - return JSON.parse(canvasStatus).objects.length > 0 - } else { - // ์ €์žฅ๋œ ์บ”๋ฒ„์Šค - // ๊ฐ๊ฐ object๋“ค์˜ uuid ๋ชฉ๋ก์„ ์ถ”์ถœํ•˜์—ฌ ๋น„๊ต - const canvasObjsUuids = getObjectUuids(JSON.parse(canvasStatus).objects) - const initPlanData = initCanvasPlans.find((plan) => plan.id === planId) - const dbObjsUuids = getObjectUuids(JSON.parse(initPlanData.canvasStatus).objects) - return canvasObjsUuids.length !== dbObjsUuids.length || !canvasObjsUuids.every((uuid, index) => uuid === dbObjsUuids[index]) + 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 @@ -140,16 +142,12 @@ export function usePlan() { /** * ์บ”๋ฒ„์Šค์— ์ €์žฅ๋˜์ง€ ์•Š์€ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์„๋•Œ ์ €์žฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ ํ›„ ์ €์žฅ */ - const checkUnsavedCanvasPlan = async (userId) => { + const checkUnsavedCanvasPlan = async () => { swalFire({ - text: - (!initCanvasPlans.some((initCanvasPlans) => initCanvasPlans.id === currentCanvasPlan.id) ? 'New ' : '') + - `Plan ${currentCanvasPlan.ordering}์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ €์žฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?`, + text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.save.modified'), type: 'confirm', confirmFn: async () => { - initCanvasPlans.some((plan) => plan.id === currentCanvasPlan.id) - ? await putCanvasStatus(currentCanvasPlan.canvasStatus) - : await postCanvasStatus(userId, currentCanvasPlan.canvasStatus) + await putCanvasStatus(currentCanvasPlan.canvasStatus) }, }) resetModifiedPlans() @@ -172,18 +170,16 @@ export function usePlan() { /** * ํŽ˜์ด์ง€ ๋‚ด ์บ”๋ฒ„์Šค๋ฅผ ์ €์žฅ */ - const saveCanvas = async (userId) => { + const saveCanvas = async () => { const canvasStatus = currentCanvasData('save') - initCanvasPlans.some((plan) => plan.id === currentCanvasPlan.id) - ? await putCanvasStatus(canvasStatus) - : await postCanvasStatus(userId, canvasStatus) + await putCanvasStatus(canvasStatus) } /** * objectNo์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ชฉ๋ก์„ ์กฐํšŒ */ const getCanvasByObjectNo = async (userId, objectNo) => { - return get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) => + return await get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) => res.map((item, index) => ({ id: item.id, userId: item.userId, @@ -199,28 +195,20 @@ export function usePlan() { /** * ์‹ ๊ทœ canvas ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ */ - const postCanvasStatus = async (userId, canvasStatus) => { + const postCanvasStatus = async (userId, objectNo, canvasStatus) => { const planData = { userId: userId, imageName: 'image_name', // api ํ•„์ˆ˜ํ•ญ๋ชฉ์ด์—ฌ์„œ ์ž„์‹œ๋กœ ๋„ฃ์Œ, ์ดํ›„ ์‚ญ์ œ ํ•„์š” - objectNo: currentCanvasPlan.objectNo, + objectNo: objectNo, + bgImageName: currentCanvasPlan?.bgImageName ?? null, + mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData }) .then((res) => { - setInitCanvasPlans((initCanvasPlans) => [...initCanvasPlans, { id: res.data, canvasStatus: canvasStatus }]) - setPlans((plans) => - plans.map((plan) => - plan.id === currentCanvasPlan.id - ? { - ...plan, - id: res.data, - canvasStatus: canvasStatus, - } - : plan, - ), - ) - setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) + setPlans([...plans, { id: res.data, objectNo: objectNo, userId: userId, canvasStatus: canvasStatus, ordering: planNum + 1 }]) + handleCurrentPlan(res.data) + setPlanNum(planNum + 1) }) .catch((error) => { swalFire({ text: error.message, icon: 'error' }) @@ -233,13 +221,12 @@ export function usePlan() { const putCanvasStatus = async (canvasStatus) => { const planData = { id: currentCanvasPlan.id, + bgImageName: currentCanvasPlan?.bgImageName ?? null, + mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData }) .then((res) => { - setInitCanvasPlans((initCanvasPlans) => - initCanvasPlans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan)), - ) setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan))) setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) }) @@ -251,40 +238,30 @@ export function usePlan() { /** * id์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œ */ - const delCanvasById = (id) => { - return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-id/${id}` }) + const delCanvasById = async (id) => { + return await promiseDel({ url: `/api/canvas-management/canvas-statuses/by-id/${id}` }) } /** * objectNo์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ฐ์ดํ„ฐ๋“ค์„ ์‚ญ์ œ */ - const delCanvasByObjectNo = (objectNo) => { - return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` }) + const delCanvasByObjectNo = async (objectNo) => { + return await promiseDel({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` }) } /** * plan ์ด๋™ * ํ˜„์žฌ plan์˜ ์ž‘์—…์ƒํƒœ๋ฅผ ํ™•์ธ, ์ €์žฅ ํ›„ ์ด๋™ */ - const handleCurrentPlan = async (userId, newCurrentId) => { + const handleCurrentPlan = async (newCurrentId) => { if (!currentCanvasPlan || currentCanvasPlan.id !== newCurrentId) { if (currentCanvasPlan?.id && modifiedPlans.some((modifiedPlan) => modifiedPlan === currentCanvasPlan.id)) { - // swalFire({ - // text: `${currentCanvasPlan.name} ` + getMessage('plan.message.confirm.save'), - // type: 'confirm', - // confirmFn: async () => { - // await saveCanvas(userId) - // updateCurrentPlan(newCurrentId) - // }, - // denyFn: () => { - // updateCurrentPlan(newCurrentId) - // }, - // }) - await saveCanvas(userId) + await saveCanvas() } updateCurrentPlan(newCurrentId) } } + const updateCurrentPlan = (newCurrentId) => { setPlans((plans) => plans.map((plan) => { @@ -295,29 +272,35 @@ export function usePlan() { useEffect(() => { setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null) setSelectedPlan(plans.find((plan) => plan.isCurrent)) + // setBgImage() }, [plans]) + const setBgImage = () => { + // readImage(selectedPlan?.id) + } + /** * ์ƒˆ๋กœ์šด plan ์ƒ์„ฑ * ํ˜„์žฌ plan์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๋ณต์ œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ */ - const handleAddPlan = (userId, objectNo) => { + const handleAddPlan = async (userId, objectNo) => { JSON.parse(currentCanvasData()).objects.length > 0 ? swalFire({ - text: - (!initCanvasPlans.some((initCanvasPlans) => initCanvasPlans.id === currentCanvasPlan.id) ? 'New ' : '') + - `Plan ${currentCanvasPlan.ordering} ` + - getMessage('plan.message.confirm.copy'), + text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.copy'), type: 'confirm', - confirmFn: () => { - addPlan(userId, objectNo, currentCanvasData()) + confirmFn: async () => { + await postCanvasStatus(userId, objectNo, currentCanvasData()) }, - denyFn: () => { - addPlan(userId, objectNo, '') + denyFn: async () => { + await postCanvasStatus(userId, objectNo, '') }, }) - : addPlan(userId, objectNo, '') + : await postCanvasStatus(userId, objectNo, '') } + + /** + * DB์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ํ™”๋ฉด ์ƒ์—์„œ plan์„ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜ + */ const addPlan = (userId, objectNo, canvasStatus) => { const id = uuidv4() const newPlan = { @@ -328,32 +311,26 @@ export function usePlan() { ordering: planNum + 1, } setPlans([...plans, newPlan]) - handleCurrentPlan(userId, id) + handleCurrentPlan(id) setPlanNum(planNum + 1) } /** * plan ์‚ญ์ œ */ - const handleDeletePlan = (e, id) => { + const handleDeletePlan = async (e, id) => { e.stopPropagation() // ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ๋ฐฉ์ง€ - if (initCanvasPlans.some((plan) => plan.id === id)) { - delCanvasById(id) - .then((res) => { - setInitCanvasPlans((initCanvasPlans) => initCanvasPlans.filter((plan) => plan.id !== id)) - setPlans((plans) => plans.filter((plan) => plan.id !== id)) - setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) - swalFire({ text: getMessage('plan.message.delete') }) - }) - .catch((error) => { - swalFire({ text: error.message, icon: 'error' }) - }) - } else { - setPlans((plans) => plans.filter((plan) => plan.id !== id)) - setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) - swalFire({ text: getMessage('plan.message.delete') }) - } + await delCanvasById(id) + .then((res) => { + setPlans((plans) => plans.filter((plan) => plan.id !== id)) + setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) + removeImage(currentCanvasPlan.id) + swalFire({ text: getMessage('plan.message.delete') }) + }) + .catch((error) => { + swalFire({ text: error.message, icon: 'error' }) + }) // ์‚ญ์ œ ํ›„ last ๋ฐ์ดํ„ฐ์— ํฌ์ปค์‹ฑ const lastPlan = plans.filter((plan) => plan.id !== id).at(-1) @@ -368,16 +345,15 @@ export function usePlan() { /** * plan ์กฐํšŒ */ - const loadCanvasPlanData = (userId, objectNo, pid) => { - getCanvasByObjectNo(userId, objectNo).then((res) => { + const loadCanvasPlanData = async (userId, objectNo, pid) => { + await getCanvasByObjectNo(userId, objectNo).then((res) => { // console.log('canvas ๋ชฉ๋ก ', res) if (res.length > 0) { - setInitCanvasPlans(res) setPlans(res) updateCurrentPlan(res[pid - 1].id) setPlanNum(res.length) } else { - addPlan(userId, objectNo, '') + postCanvasStatus(userId, objectNo, '') } }) } @@ -385,9 +361,9 @@ export function usePlan() { return { canvas, plans, - initCanvasPlans, selectedPlan, currentCanvasPlan, + setCurrentCanvasPlan, modifiedPlans, modifiedPlanFlag, setModifiedPlanFlag, diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index d09473a8..d2c4cff9 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -4,6 +4,7 @@ import fs from 'fs/promises' const CAD_FILE_PATH = 'public/cad-images' const IMAGE_FILE_PATH = 'public/plan-bg-images' +const FILE_PATH = 'public/plan-images' /** * ํŒŒ์ผ ๋ณ€ํ™˜ & ์ €์žฅ @@ -39,25 +40,56 @@ const writeImageBase64 = async (title, data) => { return fs.writeFile(`${IMAGE_FILE_PATH}/${title}.png`, data, 'base64') } -/** - * ์ด๋ฏธ์ง€ ์ €์žฅ - * Buffer ํ˜•์‹์œผ๋กœ ์ €์žฅ - * @param {*} title - * @param {*} data - * @returns - */ -const writeImageBuffer = async (file) => { - // ํ•ด๋‹น ๊ฒฝ๋กœ์— Directory ๊ฐ€ ์—†๋‹ค๋ฉด ์ƒ์„ฑ +// /** +// * ์ด๋ฏธ์ง€ ์ €์žฅ +// * Buffer ํ˜•์‹์œผ๋กœ ์ €์žฅ +// * @param {*} title +// * @param {*} data +// * @returns +// */ +// const writeImageBuffer = async (file) => { +// // ํ•ด๋‹น ๊ฒฝ๋กœ์— Directory ๊ฐ€ ์—†๋‹ค๋ฉด ์ƒ์„ฑ +// try { +// await fs.readdir(IMAGE_FILE_PATH) +// } catch { +// await fs.mkdir(IMAGE_FILE_PATH) +// } +// +// const arrayBuffer = await fileURLToPath.arrayBuffer() +// const buffer = new Uint8Array(arrayBuffer) +// +// return fs.writeFile(`${IMAGE_FILE_PATH}/${file.fileName}`, buffer) +// } + +const writeImage = async (fileName, file) => { try { - await fs.readdir(IMAGE_FILE_PATH) + await fs.readdir(FILE_PATH) } catch { - await fs.mkdir(IMAGE_FILE_PATH) + await fs.mkdir(FILE_PATH) } - const arrayBuffer = await fileURLToPath.arrayBuffer() - const buffer = new Uint8Array(arrayBuffer) - - return fs.writeFile(`${IMAGE_FILE_PATH}/${file.fileName}`, buffer) + return fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) } -export { convertDwgToPng, writeImageBase64, writeImageBuffer } +const readImage = async (fileName) => { + const file = await fs.readFile(`${FILE_PATH}/${fileName}`) + // .then((res) => { + // console.log('readImage-then', res) + // }) + // .catch((e) => { + // console.log('readImage-catch', e) + // }) + console.log('๐Ÿš€ ~ readImage ~ file:', file) + + return file +} + +const removeImage = async (fileName) => { + try { + await fs.rm(`${FILE_PATH}/${fileName}.png`) + } catch (e) { + console.log(e) + } +} + +export { convertDwgToPng, writeImageBase64, writeImage, readImage, removeImage } diff --git a/src/lib/session.js b/src/lib/session.js index ff5a2078..bcedecf4 100644 --- a/src/lib/session.js +++ b/src/lib/session.js @@ -3,8 +3,8 @@ export const defaultSession = {} export const sessionOptions = { password: process.env.SESSION_SECRET, cookieName: 'lama-session', - cookieOptions: { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - }, + // cookieOptions: { + // httpOnly: true, + // secure: process.env.NODE_ENV === 'production', + // }, } diff --git a/src/locales/ja.json b/src/locales/ja.json index 23903120..8521c658 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -164,6 +164,7 @@ "plan.menu.estimate.save": "ไฟๅญ˜", "plan.menu.estimate.reset": "ๅˆๆœŸๅŒ–", "plan.menu.estimate.copy": "่ฆ‹็ฉๆ›ธใฎใ‚ณใƒ”ใƒผ", + "plan.menu.estimate.unLock": "ใƒญใƒƒใ‚ฏ่งฃ้™ค", "plan.menu.simulation": "็™บๅฑ•ใ‚ทใƒŸใƒฅใƒฌใƒผใ‚ทใƒงใƒณ", "plan.menu.simulation.excel": "Excel", "plan.menu.simulation.pdf": "PDF", @@ -294,6 +295,7 @@ "modal.actual.size.setting.plane.size.length": "ๅปŠไธ‹ใฎๅฏธๆณ•ใฎ้•ทใ•", "modal.actual.size.setting.actual.size.length": "ๅฎŸๅฏธ้•ท", "plan.message.confirm.save": "PLAN์„ ์ €์žฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", + "plan.message.confirm.save.modified": "PLAN์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ €์žฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.confirm.copy": "PLAN์„ ๋ณต์‚ฌํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.confirm.delete": "PLAN์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.save": "์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", @@ -341,6 +343,7 @@ "modal.panel.column.insert.info": "ๆŒฟๅ…ฅใ™ใ‚‹ๆ–นๅ‘ใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚", "modal.panel.column.insert.type.left": "ๅทฆๆŒฟๅ…ฅ", "modal.panel.column.insert.type.right": "ๅณๆŒฟๅ…ฅ", + "modal.image.load.size.rotate": "ใ‚ตใ‚คใ‚บ่ชฟๆ•ดใจๅ›ž่ปข", "contextmenu.column.insert": "ๅˆ—ใฎๆŒฟๅ…ฅ", "contextmenu.row.move": "๋‹จ ์ด๋™(JA)", "contextmenu.row.copy": "๋‹จ ๋ณต์‚ฌ(JA)", @@ -483,9 +486,13 @@ "common.message.writeToConfirm": "ไฝœๆˆ่งฃ้™คใ‚’ๅฎŸ่กŒใ—ใพใ™ใ‹๏ผŸ", "common.message.password.init.success": "ใƒ‘ใ‚นใƒฏใƒผใƒ‰ [{0}] ใซๅˆๆœŸๅŒ–ใ•ใ‚Œใพใ—ใŸใ€‚", "common.message.no.edit.save": "ใ“ใฎๆ–‡ๆ›ธใฏๅค‰ๆ›ดใงใใพใ›ใ‚“ใ€‚", + "common.load": "ใƒ•ใ‚กใ‚คใƒซใฎ่ฟฝๅŠ ", "common.input.file": "ใƒ•ใ‚กใ‚คใƒซใ‚’่ชญใฟ่พผใ‚€", "common.input.file.load": "ใƒ•ใ‚กใ‚คใƒซใฎ่ฟฝๅŠ ", + "common.input.image.load": "์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ", + "common.input.address.load": "ใ‚ขใƒ‰ใƒฌใ‚นใ‚’่ชญใฟ่พผใ‚€", "common.require": "ๅฟ…้ ˆ", + "common.finish": "ๅฎŒไบ†", "common.ok": "็ขบ่ช", "commons.west": "็ซ‹ใค", "commons.east": "ใƒ‰ใƒณ", @@ -835,6 +842,7 @@ "estimate.detail.fileList.btn": "ใƒ•ใ‚กใ‚คใƒซ้ธๆŠž", "estimate.detail.fileList.extCheck": "ใใฎใƒ•ใ‚กใ‚คใƒซใฏใ‚คใƒกใƒผใ‚ธใƒ•ใ‚กใ‚คใƒซใงใฏใ‚ใ‚Šใพใ›ใ‚“", "estimate.detail.header.fileList2": "ๆทปไป˜ใƒ•ใ‚กใ‚คใƒซไธ€่ฆง", + "estimate.detail.fileList2.btn.return": "ๅพฉๅ…ƒ", "estimate.detail.header.specialEstimate": "่ฆ‹็ฉใ‚‚ใ‚Šใฎๅ…ทไฝ“็š„ใช", "estimate.detail.header.specialEstimateProductInfo": "่ฃฝๅ“ๆƒ…ๅ ฑ", "estimate.detail.sepcialEstimateProductInfo.totAmount": "ๆ•ฐ้‡ (PCS)", @@ -897,10 +905,14 @@ "estimate.detail.save.requiredItem": "่ฃฝๅ“ใฏ1ใคไปฅไธŠ็™ป้Œฒใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™.", "estimate.detail.save.requiredCharger": "ๆ‹…ๅฝ“่€…ใฏๅฟ…้ ˆใงใ™.", "estimate.detail.save.requiredObjectName": "ๆกˆไปถๅใฏๅฟ…้ ˆใงใ™.", + "estimate.detail.save.requiredPkgAsp": "ไฝๅฎ…pkgๅ˜ไพกใฏ0ใ‚ˆใ‚Šๅคงใใ„ๅ€คใ‚’ๅ…ฅๅŠ›ใ—ใฆใใ ใ•ใ„.", "estimate.detail.save.requiredEstimateDate": "่ฆ‹็ฉๆ—ฅใฏๅฟ…้ ˆใงใ™.", + "estimate.detail.save.requiredItemId": "่ฃฝๅ“ใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„.", "estimate.detail.save.requiredAmount": "ๆ•ฐ้‡ใฏ0ใ‚ˆใ‚Šๅคงใใ„ๅ€คใ‚’ๅ…ฅๅŠ›ใ—ใฆใใ ใ•ใ„.", "estimate.detail.save.requiredSalePrice": "ๅ˜ไพกใฏ0ใ‚ˆใ‚Šๅคงใใ„ๅ€คใ‚’ๅ…ฅๅŠ›ใ—ใฆใใ ใ•ใ„.", "estimate.detail.reset.confirmMsg": "ไฟๅญ˜ใ—ใŸ่ฆ‹็ฉๆ›ธๆƒ…ๅ ฑใŒๅˆๆœŸๅŒ–ใ•ใ‚Œใ€ๅ›ณ้ขๆƒ…ๅ ฑใŒๅๆ˜ ใ•ใ‚Œใพใ™ใ€‚ๆœฌๅฝ“ใซๅˆๆœŸๅŒ–ใ—ใพใ™ใ‹?", + "estimate.detail.alert.delFile": "ๆทปไป˜ใƒ•ใ‚กใ‚คใƒซใ‚’ๅฎŒๅ…จใซๅ‰Š้™คใ™ใ‚‹ใซใฏ[ไฟๅญ˜]ใƒœใ‚ฟใƒณใ‚’ใ‚ฏใƒชใƒƒใ‚ฏใ—ใฆใใ ใ•ใ„", + "estimate.detail.alert.selectDelItem": "ๅ‰Š้™คใ™ใ‚‹ๅ•†ๅ“ใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„.", "simulator.title.sub1": "็‰ฉไปถ็•ชๅท", "simulator.title.sub2": "ไฝœๆˆๆ—ฅ", "simulator.title.sub3": "ใ‚ทใ‚นใƒ†ใƒ ๅฎน้‡", diff --git a/src/locales/ko.json b/src/locales/ko.json index 0cf7217b..cc65bb7d 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -168,6 +168,7 @@ "plan.menu.estimate.save": "์ €์žฅ", "plan.menu.estimate.reset": "์ดˆ๊ธฐํ™”", "plan.menu.estimate.copy": "๊ฒฌ์ ์„œ ๋ณต์‚ฌ", + "plan.menu.estimate.unLock": "์ž ๊ธˆ ํ•ด์ œ", "plan.menu.simulation": "๋ฐœ์ „ ์‹œ๋ฎฌ๋ ˆ์ด์…˜", "plan.menu.simulation.excel": "Excel", "plan.menu.simulation.pdf": "PDF", @@ -299,6 +300,7 @@ "modal.actual.size.setting.plane.size.length": "๋ณต๋„์น˜์ˆ˜ ๊ธธ์ด", "modal.actual.size.setting.actual.size.length": "์‹ค์ œ์น˜์ˆ˜ ๊ธธ์ด", "plan.message.confirm.save": "PLAN์„ ์ €์žฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", + "plan.message.confirm.save.modified": "PLAN์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ €์žฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.confirm.copy": "PLAN์„ ๋ณต์‚ฌํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.confirm.delete": "PLAN์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "plan.message.save": "์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", @@ -348,6 +350,7 @@ "modal.panel.column.insert.info": "์‚ฝ์ž…ํ•  ๋ฐฉํ–ฅ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”.", "modal.panel.column.insert.type.left": "์™ผ์ชฝ ์‚ฝ์ž…", "modal.panel.column.insert.type.right": "์˜ค๋ฅธ์ชฝ ์‚ฝ์ž…", + "modal.image.load.size.rotate": "ํฌ๊ธฐ ์กฐ์ ˆ ๋ฐ ํšŒ์ „", "contextmenu.row.move": "๋‹จ ์ด๋™", "contextmenu.row.copy": "๋‹จ ๋ณต์‚ฌ", "contextmenu.row.remove": "๋‹จ ์‚ญ์ œ", @@ -492,9 +495,13 @@ "common.message.writeToConfirm": "์ž‘์„ฑ ํ•ด์ œ๋ฅผ ์‹คํ–‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "common.message.password.init.success": "๋น„๋ฐ€๋ฒˆํ˜ธ [{0}]๋กœ ์ดˆ๊ธฐํ™” ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", "common.message.no.edit.save": "This document cannot be changed.", + "common.load": "๋ถˆ๋Ÿฌ์˜ค๊ธฐ", "common.input.file": "ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ", "common.input.file.load": "๋ถˆ๋Ÿฌ์˜ค๊ธฐ", + "common.input.image.load": "์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ", + "common.input.address.load": "์ฃผ์†Œ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ", "common.require": "ํ•„์ˆ˜", + "common.finish": "์™„๋ฃŒ", "common.ok": "ํ™•์ธ", "commons.west": "์„œ", "commons.east": "๋™", @@ -845,6 +852,7 @@ "estimate.detail.fileList.btn": "ํŒŒ์ผ์„ ํƒ", "estimate.detail.fileList.extCheck": "ํ•ด๋‹น ํŒŒ์ผ์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค", "estimate.detail.header.fileList2": "์ฒจ๋ถ€ํŒŒ์ผ ๋ชฉ๋ก", + "estimate.detail.fileList2.btn.return": "๋ณต์›", "estimate.detail.header.specialEstimate": "๊ฒฌ์ ํŠน์ด์‚ฌํ•ญ", "estimate.detail.header.specialEstimateProductInfo": "์ œํ’ˆ์ •๋ณด", "estimate.detail.sepcialEstimateProductInfo.totAmount": "์ˆ˜๋Ÿ‰ (PCS)", @@ -907,10 +915,14 @@ "estimate.detail.save.requiredItem": "์ œํ’ˆ์€ 1๊ฐœ์ด์ƒ ๋“ฑ๋กํ•ด์•ผ ๋ฉ๋‹ˆ๋‹ค.", "estimate.detail.save.requiredCharger": "๋‹ด๋‹น์ž๋Š” ํ•„์ˆ˜๊ฐ’ ์ž…๋‹ˆ๋‹ค.", "estimate.detail.save.requiredObjectName": "์•ˆ๊ฑด๋ช…์€ ํ•„์ˆ˜๊ฐ’ ์ž…๋‹ˆ๋‹ค.", + "estimate.detail.save.requiredPkgAsp": "์ฃผํƒpkg ๋‹จ๊ฐ€๋Š” 0๋ณด๋‹ค ํฐ ๊ฐ’์„ ์ž…๋ ฅํ•˜์„ธ์š”.", "estimate.detail.save.requiredEstimateDate": "๊ฒฌ์ ์ผ์€ ํ•„์ˆ˜๊ฐ’ ์ž…๋‹ˆ๋‹ค.", + "estimate.detail.save.requiredItemId": "์ œํ’ˆ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”.", "estimate.detail.save.requiredAmount": "์ˆ˜๋Ÿ‰์€ 0๋ณด๋‹ค ํฐ๊ฐ’์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", "estimate.detail.save.requiredSalePrice": "๋‹จ๊ฐ€๋Š” 0๋ณด๋‹ค ํฐ๊ฐ’์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.", "estimate.detail.reset.confirmMsg": "์ €์žฅ๋œ ๊ฒฌ์ ์„œ ์ •๋ณด๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๊ณ , ๋„๋ฉด์ •๋ณด๊ฐ€ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ์ •๋ง๋กœ ์ดˆ๊ธฐํ™” ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", + "estimate.detail.alert.delFile": "์ฒจ๋ถ€ํŒŒ์ผ์„ ์™„์ „ํžˆ ์‚ญ์ œํ•˜๋ ค๋ฉด [์ €์žฅ]๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์‹ญ์‹œ์˜ค.", + "estimate.detail.alert.selectDelItem": "์‚ญ์ œํ•  ์ œํ’ˆ์„ ์„ ํƒํ•˜์„ธ์š”.", "simulator.title.sub1": "๋ฌผ๊ฑด๋ฒˆํ˜ธ", "simulator.title.sub2": "์ž‘์„ฑ์ผ", "simulator.title.sub3": "์‹œ์Šคํ…œ ์šฉ๋Ÿ‰", diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index 9be9f402..b0e21d41 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -260,12 +260,6 @@ export const dotLineIntervalSelector = selector({ }, }) -// canvas plan ์ดˆ๊ธฐ ๋ชฉ๋ก -export const initCanvasPlansState = atom({ - key: 'initCanvasPlans', - default: [], -}) - // ํ˜„์žฌ canvas plan export const currentCanvasPlanState = atom({ key: 'currentCanvasPlan', diff --git a/src/store/stuffAtom.js b/src/store/stuffAtom.js index 1608beac..06593e2b 100644 --- a/src/store/stuffAtom.js +++ b/src/store/stuffAtom.js @@ -1,8 +1,7 @@ import { atom } from 'recoil' import dayjs from 'dayjs' -import { v1 } from 'uuid' export const stuffSearchState = atom({ - key: `stuffSearchState/${v1()}`, + key: `stuffSearchState`, default: { schObjectNo: '', //๋ฌผ๊ฑด๋ฒˆํ˜ธ schAddress: '', //๋ฌผ๊ฑด์ฃผ์†Œ diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index 08b40e93..e2ab95b7 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -139,6 +139,7 @@ &.ico02{background-image: url(../../public/static/images/canvas/ico-flx02.svg);} &.ico03{background-image: url(../../public/static/images/canvas/ico-flx03.svg);} &.ico04{background-image: url(../../public/static/images/canvas/ico-flx04.svg);} + &.ico05{background-image: url(../../public/static/images/canvas/ico-flx05.svg);} } .name{ font-size: 12px; @@ -720,6 +721,7 @@ &.one{ .estimate-box{ &:last-child{ + flex: 1; min-width: unset; } } @@ -803,6 +805,7 @@ } } .file-list{ + min-height: 52px; .file-item{ margin-bottom: 15px; span{ @@ -827,6 +830,47 @@ &:last-child{ margin-bottom: 0; } + .file-item-wrap{ + display: flex; + align-items: center; + gap: 30px; + .return-wrap{ + display: flex; + align-items: center; + } + .return{ + padding: 0; + font-size: 13px; + color: #B0BCCD; + text-decoration: line-through; + } + .return-btn{ + flex: none; + position: relative; + top: 0; + left: 0; + transform: none; + display: flex; + align-items: center; + height: 24px; + padding: 0 9px; + margin-left: 10px; + background: none; + border: 1px solid #B0BCCD; + border-radius: 2px; + font-size: 12px; + color: #B0BCCD; + font-weight: 500; + .return-ico{ + display: block; + width: 14px; + height: 14px; + background: url(../../public/static/images/canvas/return-btn.svg)no-repeat center; + background-size: contain; + margin-right: 5px; + } + } + } } } } @@ -877,6 +921,16 @@ &.act{ background-color: #F7F9FA; } + .special-note-check-box{ + display: flex; + align-items: center; + .check-name{ + font-size: 13px; + color: #45576F; + cursor: pointer; + line-height: 1.3; + } + } } } @@ -884,7 +938,7 @@ border: 1px solid #ECF0F4; border-radius: 3px; padding: 24px; - max-height: 350px; + height: 350px; overflow-y: auto; margin-bottom: 30px; dl{ diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index b4987651..50e2a4eb 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -1308,23 +1308,23 @@ $alert-color: #101010; height: 253px; .circle{ top: 86%; - &:nth-child(1), - &:nth-child(7), - &:nth-child(13), - &:nth-child(19){ - &::before{ - content: ''; - position: absolute; - top: 20px; - left: 50%; - transform: translateX(-50%); - width: 1px; - height: 6px; - background-color: #8B8B8B; - } - } + // &:nth-child(1), + // &:nth-child(7), + // &:nth-child(13), + // &:nth-child(19){ + // &::before{ + // content: ''; + // position: absolute; + // top: 20px; + // left: 50%; + // transform: translateX(-50%); + // width: 1px; + // height: 6px; + // background-color: #8B8B8B; + // } + // } i{ - top: 32px; + top: 22px; } &.act{ i{color: #8B8B8B;} diff --git a/src/styles/spinner.scss b/src/styles/spinner.scss index 18993c78..b6398e94 100644 --- a/src/styles/spinner.scss +++ b/src/styles/spinner.scss @@ -1,109 +1,45 @@ -.spinner-wrap { - width: 100%; - height: 100vh; - display: flex; - align-items: center; - justify-content: center; - background-color: #fff; - .loader { - font-size: 10px; - width: 1.2em; - height: 1.2em; - border-radius: 50%; - position: relative; - text-indent: -9999em; - animation: mulShdSpin 1.1s infinite ease; - transform: translateZ(0); - } - @keyframes mulShdSpin { - 0%, - 100% { - box-shadow: - 0em -2.6em 0em 0em #101010, - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.5), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7); +.spinner-wrap{ + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background-color: #fff; + .loader { + font-size: 10px; + width: 1.2em; + height: 1.2em; + border-radius: 50%; + position: relative; + text-indent: -9999em; + animation: mulShdSpin 1.1s infinite ease; + transform: translateZ(0); } - 12.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.7), - 1.8em -1.8em 0 0em #101010, - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5); - } - 25% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.5), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7), - 2.5em 0em 0 0em #101010, - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 37.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.7), - 1.75em 1.75em 0 0em #101010, - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 50% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.5), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.7), - 0em 2.5em 0 0em #101010, - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 62.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.5), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.7), - -1.8em 1.8em 0 0em #101010, - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 75% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.5), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.7), - -2.6em 0em 0 0em #101010, - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 87.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.5), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.7), - -1.8em -1.8em 0 0em #101010; - } - } -} + @keyframes mulShdSpin { + 0%, + 100% { + box-shadow: 0em -2.6em 0em 0em #101010, 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.5), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7); + } + 12.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.7), 1.8em -1.8em 0 0em #101010, 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5); + } + 25% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.5), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7), 2.5em 0em 0 0em #101010, 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 37.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5), 2.5em 0em 0 0em rgba(16, 16, 16, 0.7), 1.75em 1.75em 0 0em #101010, 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 50% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.5), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.7), 0em 2.5em 0 0em #101010, -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 62.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.5), 0em 2.5em 0 0em rgba(16, 16, 16, 0.7), -1.8em 1.8em 0 0em #101010, -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 75% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.5), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.7), -2.6em 0em 0 0em #101010, -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 87.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.5), -2.6em 0em 0 0em rgba(16, 16, 16, 0.7), -1.8em -1.8em 0 0em #101010; + } + } +} \ No newline at end of file diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 65c46b74..b27f91db 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -824,6 +824,8 @@ export function setSurfaceShapePattern(polygon, mode = 'onlyBorder', 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') { diff --git a/src/util/common-utils.js b/src/util/common-utils.js index 5a7ebde4..06b96b60 100644 --- a/src/util/common-utils.js +++ b/src/util/common-utils.js @@ -93,3 +93,27 @@ export const inputNumberCheck = (e) => { input.value = input.value.replace(/[^\d]/g, '') } } + +/** + * ํŒŒ์ดํ”„ํ•จ์ˆ˜ ์ •์˜ + * @param {...any} fns ์ˆœ์ˆ˜ํ•จ์ˆ˜๋“ค + * @returns + */ +export const pipe = + (...fns) => + (x) => + fns.reduce((v, f) => f(v), x) + +/** + * ์บ”๋ฒ„์Šค ๊ฐ๋„์— ๋”ฐ๋ฅธ ํ๋ฆ„ ๋ฐฉํ–ฅ ๊ณ„์‚ฐ + * @param {number} canvasAngle + * @returns {object} ํ๋ฆ„ ๋ฐฉํ–ฅ ๊ฐ์ฒด + */ +export const calculateFlowDirection = (canvasAngle) => { + return { + down: -canvasAngle, + up: 180 - canvasAngle, + left: 90 - canvasAngle < 180 ? 90 - canvasAngle : 90 - canvasAngle - 360, + right: -90 - canvasAngle < -180 ? -90 - canvasAngle + 360 : -90 - canvasAngle, + } +} diff --git a/yarn.lock b/yarn.lock index 1a4d340d..6dd98dd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -223,7 +223,14 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.20.13", "@babel/runtime@^7.24.8": +"@babel/runtime@^7.20.13": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.24.8": version "7.25.0" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== @@ -532,21 +539,6 @@ resolved "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz" integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw== -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@next/env@14.2.14": version "14.2.14" resolved "https://registry.npmjs.org/@next/env/-/env-14.2.14.tgz" @@ -1251,7 +1243,7 @@ "@react-types/shared" "3.23.1" clsx "^1.2.1" -"@nextui-org/system@2.2.5": +"@nextui-org/system@>=2.0.0", "@nextui-org/system@>=2.1.0", "@nextui-org/system@2.2.5": version "2.2.5" resolved "https://registry.npmjs.org/@nextui-org/system/-/system-2.2.5.tgz" integrity sha512-nrX6768aiyWtpxX3OTFBIVWR+v9nlMsC3KaBinNfek97sNm7gAfTHi7q5kylE3L5yIMpNG+DclAKpuxgDQEmvw== @@ -1304,7 +1296,7 @@ "@react-types/tabs" "3.3.7" scroll-into-view-if-needed "3.0.10" -"@nextui-org/theme@2.2.9": +"@nextui-org/theme@>=2.1.0", "@nextui-org/theme@>=2.2.0", "@nextui-org/theme@2.2.9": version "2.2.9" resolved "https://registry.npmjs.org/@nextui-org/theme/-/theme-2.2.9.tgz" integrity sha512-TN2I9sMriLaj00pXsIMlg19+UHeOdjzS2JV0u4gjL14mSbQl5BYNxgbvU3gbMqkZZQ6OpwT4RnT8RS+ks6TXCw== @@ -1525,7 +1517,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1658,7 +1650,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/focus@3.17.1", "@react-aria/focus@^3.17.1": +"@react-aria/focus@^3.17.1", "@react-aria/focus@3.17.1": version "3.17.1" resolved "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz" integrity sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ== @@ -1680,7 +1672,7 @@ "@swc/helpers" "^0.5.0" clsx "^2.0.0" -"@react-aria/form@3.0.5", "@react-aria/form@^3.0.5": +"@react-aria/form@^3.0.5", "@react-aria/form@3.0.5": version "3.0.5" resolved "https://registry.npmjs.org/@react-aria/form/-/form-3.0.5.tgz" integrity sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ== @@ -1710,7 +1702,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/i18n@3.11.1", "@react-aria/i18n@^3.11.1": +"@react-aria/i18n@^3.11.1", "@react-aria/i18n@3.11.1": version "3.11.1" resolved "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.11.1.tgz" integrity sha512-vuiBHw1kZruNMYeKkTGGnmPyMnM5T+gT8bz97H1FqIq1hQ6OPzmtBZ6W6l6OIMjeHI5oJo4utTwfZl495GALFQ== @@ -1738,7 +1730,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/interactions@3.21.3", "@react-aria/interactions@^3.21.3": +"@react-aria/interactions@^3.21.3", "@react-aria/interactions@3.21.3": version "3.21.3" resolved "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz" integrity sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA== @@ -1758,7 +1750,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/label@3.7.8", "@react-aria/label@^3.7.8": +"@react-aria/label@^3.7.8", "@react-aria/label@3.7.8": version "3.7.8" resolved "https://registry.npmjs.org/@react-aria/label/-/label-3.7.8.tgz" integrity sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg== @@ -1767,7 +1759,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/link@3.7.1", "@react-aria/link@^3.7.1": +"@react-aria/link@^3.7.1", "@react-aria/link@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-aria/link/-/link-3.7.1.tgz" integrity sha512-a4IaV50P3fXc7DQvEIPYkJJv26JknFbRzFT5MJOMgtzuhyJoQdILEUK6XHYjcSSNCA7uLgzpojArVk5Hz3lCpw== @@ -1779,7 +1771,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/listbox@3.12.1", "@react-aria/listbox@^3.12.1": +"@react-aria/listbox@^3.12.1", "@react-aria/listbox@3.12.1": version "3.12.1" resolved "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.12.1.tgz" integrity sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA== @@ -1801,7 +1793,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-aria/menu@3.14.1", "@react-aria/menu@^3.14.1": +"@react-aria/menu@^3.14.1", "@react-aria/menu@3.14.1": version "3.14.1" resolved "https://registry.npmjs.org/@react-aria/menu/-/menu-3.14.1.tgz" integrity sha512-BYliRb38uAzq05UOFcD5XkjA5foQoXRbcH3ZufBsc4kvh79BcP1PMW6KsXKGJ7dC/PJWUwCui6QL1kUg8PqMHA== @@ -1820,7 +1812,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/overlays@3.22.1", "@react-aria/overlays@^3.22.1": +"@react-aria/overlays@^3.22.1", "@react-aria/overlays@3.22.1": version "3.22.1" resolved "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.22.1.tgz" integrity sha512-GHiFMWO4EQ6+j6b5QCnNoOYiyx1Gk8ZiwLzzglCI4q1NY5AG2EAmfU4Z1+Gtrf2S5Y0zHbumC7rs9GnPoGLUYg== @@ -1865,7 +1857,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/selection@3.18.1", "@react-aria/selection@^3.18.1": +"@react-aria/selection@^3.18.1", "@react-aria/selection@3.18.1": version "3.18.1" resolved "https://registry.npmjs.org/@react-aria/selection/-/selection-3.18.1.tgz" integrity sha512-GSqN2jX6lh7v+ldqhVjAXDcrWS3N4IsKXxO6L6Ygsye86Q9q9Mq9twWDWWu5IjHD6LoVZLUBCMO+ENGbOkyqeQ== @@ -1918,7 +1910,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/ssr@3.9.4", "@react-aria/ssr@^3.9.4": +"@react-aria/ssr@^3.9.4", "@react-aria/ssr@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz" integrity sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ== @@ -1978,7 +1970,7 @@ "@react-types/tabs" "^3.3.7" "@swc/helpers" "^0.5.0" -"@react-aria/textfield@3.14.5", "@react-aria/textfield@^3.14.5": +"@react-aria/textfield@^3.14.5", "@react-aria/textfield@3.14.5": version "3.14.5" resolved "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.5.tgz" integrity sha512-hj7H+66BjB1iTKKaFXwSZBZg88YT+wZboEXZ0DNdQB2ytzoz/g045wBItUuNi4ZjXI3P+0AOZznVMYadWBAmiA== @@ -2019,7 +2011,7 @@ "@react-types/tooltip" "^3.4.9" "@swc/helpers" "^0.5.0" -"@react-aria/utils@3.24.1", "@react-aria/utils@^3.24.1": +"@react-aria/utils@^3.24.1", "@react-aria/utils@3.24.1": version "3.24.1" resolved "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz" integrity sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q== @@ -2041,7 +2033,7 @@ "@swc/helpers" "^0.5.0" clsx "^2.0.0" -"@react-aria/visually-hidden@3.8.12", "@react-aria/visually-hidden@^3.8.12": +"@react-aria/visually-hidden@^3.8.12", "@react-aria/visually-hidden@3.8.12": version "3.8.12" resolved "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.12.tgz" integrity sha512-Bawm+2Cmw3Xrlr7ARzl2RLtKh0lNUdJ0eNqzWcyx4c0VHUAWtThmH5l+HRqFUGzzutFZVo89SAy40BAbd0gjVw== @@ -2051,7 +2043,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/calendar@3.5.1", "@react-stately/calendar@^3.5.1": +"@react-stately/calendar@^3.5.1", "@react-stately/calendar@3.5.1": version "3.5.1" resolved "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.1.tgz" integrity sha512-7l7QhqGUJ5AzWHfvZzbTe3J4t72Ht5BmhW4hlVI7flQXtfrmYkVtl3ZdytEZkkHmWGYZRW9b4IQTQGZxhtlElA== @@ -2062,7 +2054,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/checkbox@3.6.5", "@react-stately/checkbox@^3.6.5": +"@react-stately/checkbox@^3.6.5", "@react-stately/checkbox@3.6.5": version "3.6.5" resolved "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.5.tgz" integrity sha512-IXV3f9k+LtmfQLE+DKIN41Q5QB/YBLDCB1YVx5PEdRp52S9+EACD5683rjVm8NVRDwjMi2SP6RnFRk7fVb5Azg== @@ -2073,7 +2065,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/collections@3.10.7", "@react-stately/collections@^3.10.7": +"@react-stately/collections@^3.10.7", "@react-stately/collections@3.10.7": version "3.10.7" resolved "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.7.tgz" integrity sha512-KRo5O2MWVL8n3aiqb+XR3vP6akmHLhLWYZEmPKjIv0ghQaEebBTrN3wiEjtd6dzllv0QqcWvDLM1LntNfJ2TsA== @@ -2089,7 +2081,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/combobox@3.8.4", "@react-stately/combobox@^3.8.4": +"@react-stately/combobox@^3.8.4", "@react-stately/combobox@3.8.4": version "3.8.4" resolved "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.4.tgz" integrity sha512-iLVGvKRRz0TeJXZhZyK783hveHpYA6xovOSdzSD+WGYpiPXo1QrcrNoH3AE0Z2sHtorU+8nc0j58vh5PB+m2AA== @@ -2104,7 +2096,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/datepicker@3.9.4", "@react-stately/datepicker@^3.9.4": +"@react-stately/datepicker@^3.9.4", "@react-stately/datepicker@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.4.tgz" integrity sha512-yBdX01jn6gq4NIVvHIqdjBUPo+WN8Bujc4OnPw+ZnfA4jI0eIgq04pfZ84cp1LVXW0IB0VaCu1AlQ/kvtZjfGA== @@ -2125,7 +2117,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-stately/form@3.0.3", "@react-stately/form@^3.0.3": +"@react-stately/form@^3.0.3", "@react-stately/form@3.0.3": version "3.0.3" resolved "https://registry.npmjs.org/@react-stately/form/-/form-3.0.3.tgz" integrity sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg== @@ -2152,7 +2144,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/list@3.10.5", "@react-stately/list@^3.10.5": +"@react-stately/list@^3.10.5", "@react-stately/list@3.10.5": version "3.10.5" resolved "https://registry.npmjs.org/@react-stately/list/-/list-3.10.5.tgz" integrity sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA== @@ -2174,7 +2166,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/menu@3.7.1", "@react-stately/menu@^3.7.1": +"@react-stately/menu@^3.7.1", "@react-stately/menu@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-stately/menu/-/menu-3.7.1.tgz" integrity sha512-mX1w9HHzt+xal1WIT2xGrTQsoLvDwuB2R1Er1MBABs//MsJzccycatcgV/J/28m6tO5M9iuFQQvLV+i1dCtodg== @@ -2184,7 +2176,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/overlays@3.6.7", "@react-stately/overlays@^3.6.7": +"@react-stately/overlays@^3.6.7", "@react-stately/overlays@3.6.7": version "3.6.7" resolved "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.7.tgz" integrity sha512-6zp8v/iNUm6YQap0loaFx6PlvN8C0DgWHNlrlzMtMmNuvjhjR0wYXVaTfNoUZBWj25tlDM81ukXOjpRXg9rLrw== @@ -2202,7 +2194,7 @@ "@react-types/overlays" "^3.8.9" "@swc/helpers" "^0.5.0" -"@react-stately/radio@3.10.4", "@react-stately/radio@^3.10.4": +"@react-stately/radio@^3.10.4", "@react-stately/radio@3.10.4": version "3.10.4" resolved "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.4.tgz" integrity sha512-kCIc7tAl4L7Hu4Wt9l2jaa+MzYmAJm0qmC8G8yPMbExpWbLRu6J8Un80GZu+JxvzgDlqDyrVvyv9zFifwH/NkQ== @@ -2235,7 +2227,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/slider@3.5.4", "@react-stately/slider@^3.5.4": +"@react-stately/slider@^3.5.4", "@react-stately/slider@3.5.4": version "3.5.4" resolved "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.4.tgz" integrity sha512-Jsf7K17dr93lkNKL9ij8HUcoM1sPbq8TvmibD6DhrK9If2lje+OOL8y4n4qreUnfMT56HCAeS9wCO3fg3eMyrw== @@ -2245,7 +2237,7 @@ "@react-types/slider" "^3.7.3" "@swc/helpers" "^0.5.0" -"@react-stately/table@3.11.8", "@react-stately/table@^3.11.8": +"@react-stately/table@^3.11.8", "@react-stately/table@3.11.8": version "3.11.8" resolved "https://registry.npmjs.org/@react-stately/table/-/table-3.11.8.tgz" integrity sha512-EdyRW3lT1/kAVDp5FkEIi1BQ7tvmD2YgniGdLuW/l9LADo0T+oxZqruv60qpUS6sQap+59Riaxl91ClDxrJnpg== @@ -2260,7 +2252,7 @@ "@react-types/table" "^3.9.5" "@swc/helpers" "^0.5.0" -"@react-stately/tabs@3.6.6", "@react-stately/tabs@^3.6.6": +"@react-stately/tabs@^3.6.6", "@react-stately/tabs@3.6.6": version "3.6.6" resolved "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.6.tgz" integrity sha512-sOLxorH2uqjAA+v1ppkMCc2YyjgqvSGeBDgtR/lyPSDd4CVMoTExszROX2dqG0c8il9RQvzFuufUtQWMY6PgSA== @@ -2270,7 +2262,7 @@ "@react-types/tabs" "^3.3.7" "@swc/helpers" "^0.5.0" -"@react-stately/toggle@3.7.4", "@react-stately/toggle@^3.7.4": +"@react-stately/toggle@^3.7.4", "@react-stately/toggle@3.7.4": version "3.7.4" resolved "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.4.tgz" integrity sha512-CoYFe9WrhLkDP4HGDpJYQKwfiYCRBAeoBQHv+JWl5eyK61S8xSwoHsveYuEZ3bowx71zyCnNAqWRrmNOxJ4CKA== @@ -2288,7 +2280,7 @@ "@react-types/checkbox" "^3.8.3" "@swc/helpers" "^0.5.0" -"@react-stately/tooltip@3.4.9", "@react-stately/tooltip@^3.4.9": +"@react-stately/tooltip@^3.4.9", "@react-stately/tooltip@3.4.9": version "3.4.9" resolved "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.9.tgz" integrity sha512-P7CDJsdoKarz32qFwf3VNS01lyC+63gXpDZG31pUu+EO5BeQd4WKN/AH1Beuswpr4GWzxzFc1aXQgERFGVzraA== @@ -2297,7 +2289,7 @@ "@react-types/tooltip" "^3.4.9" "@swc/helpers" "^0.5.0" -"@react-stately/tree@3.8.1", "@react-stately/tree@^3.8.1": +"@react-stately/tree@^3.8.1", "@react-stately/tree@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.1.tgz" integrity sha512-LOdkkruJWch3W89h4B/bXhfr0t0t1aRfEp+IMrrwdRAl23NaPqwl5ILHs4Xu5XDHqqhg8co73pHrJwUyiTWEjw== @@ -2308,7 +2300,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/utils@3.10.1", "@react-stately/utils@^3.10.1": +"@react-stately/utils@^3.10.1", "@react-stately/utils@3.10.1": version "3.10.1" resolved "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz" integrity sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg== @@ -2322,7 +2314,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-stately/virtualizer@3.7.1", "@react-stately/virtualizer@^3.7.1": +"@react-stately/virtualizer@^3.7.1", "@react-stately/virtualizer@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.7.1.tgz" integrity sha512-voHgE6EQ+oZaLv6u2umKxakvIKNkCQuUihqKACTjdslp7SJh4Mvs3oLBI0hf0JOh+rCcFIKDvQtFwy1fXFRYBA== @@ -2338,7 +2330,7 @@ dependencies: "@react-types/shared" "^3.23.1" -"@react-types/breadcrumbs@3.7.5", "@react-types/breadcrumbs@^3.7.5": +"@react-types/breadcrumbs@^3.7.5", "@react-types/breadcrumbs@3.7.5": version "3.7.5" resolved "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.5.tgz" integrity sha512-lV9IDYsMiu2TgdMIjEmsOE0YWwjb3jhUNK1DCZZfq6uWuiHLgyx2EncazJBUWSjHJ4ta32j7xTuXch+8Ai6u/A== @@ -2346,7 +2338,7 @@ "@react-types/link" "^3.5.5" "@react-types/shared" "^3.23.1" -"@react-types/button@3.9.4", "@react-types/button@^3.9.4": +"@react-types/button@^3.9.4", "@react-types/button@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-types/button/-/button-3.9.4.tgz" integrity sha512-raeQBJUxBp0axNF74TXB8/H50GY8Q3eV6cEKMbZFP1+Dzr09Ngv0tJBeW0ewAxAguNH5DRoMUAUGIXtSXskVdA== @@ -2360,7 +2352,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/calendar@3.4.6", "@react-types/calendar@^3.4.6": +"@react-types/calendar@^3.4.6", "@react-types/calendar@3.4.6": version "3.4.6" resolved "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.6.tgz" integrity sha512-WSntZPwtvsIYWvBQRAPvuCn55UTJBZroTvX0vQvWykJRQnPAI20G1hMQ3dNsnAL+gLZUYxBXn66vphmjUuSYew== @@ -2368,7 +2360,7 @@ "@internationalized/date" "^3.5.4" "@react-types/shared" "^3.23.1" -"@react-types/checkbox@3.8.1", "@react-types/checkbox@^3.8.1": +"@react-types/checkbox@^3.8.1", "@react-types/checkbox@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz" integrity sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ== @@ -2382,14 +2374,14 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/combobox@3.11.1", "@react-types/combobox@^3.11.1": +"@react-types/combobox@^3.11.1", "@react-types/combobox@3.11.1": version "3.11.1" resolved "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.11.1.tgz" integrity sha512-UNc3OHt5cUt5gCTHqhQIqhaWwKCpaNciD8R7eQazmHiA9fq8ROlV+7l3gdNgdhJbTf5Bu/V5ISnN7Y1xwL3zqQ== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/datepicker@3.7.4", "@react-types/datepicker@^3.7.4": +"@react-types/datepicker@^3.7.4", "@react-types/datepicker@3.7.4": version "3.7.4" resolved "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.4.tgz" integrity sha512-ZfvgscvNzBJpYyVWg3nstJtA/VlWLwErwSkd1ivZYam859N30w8yH+4qoYLa6FzWLCFlrsRHyvtxlEM7lUAt5A== @@ -2407,7 +2399,7 @@ "@react-types/overlays" "^3.8.9" "@react-types/shared" "^3.24.1" -"@react-types/grid@3.2.6", "@react-types/grid@^3.2.6": +"@react-types/grid@^3.2.6", "@react-types/grid@3.2.6": version "3.2.6" resolved "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.6.tgz" integrity sha512-XfHenL2jEBUYrhKiPdeM24mbLRXUn79wVzzMhrNYh24nBwhsPPpxF+gjFddT3Cy8dt6tRInfT6pMEu9nsXwaHw== @@ -2421,7 +2413,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/link@3.5.5", "@react-types/link@^3.5.5": +"@react-types/link@^3.5.5", "@react-types/link@3.5.5": version "3.5.5" resolved "https://registry.npmjs.org/@react-types/link/-/link-3.5.5.tgz" integrity sha512-G6P5WagHDR87npN7sEuC5IIgL1GsoY4WFWKO4734i2CXRYx24G9P0Su3AX4GA3qpspz8sK1AWkaCzBMmvnunfw== @@ -2435,7 +2427,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/menu@3.9.9", "@react-types/menu@^3.9.9": +"@react-types/menu@^3.9.9", "@react-types/menu@3.9.9": version "3.9.9" resolved "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.9.tgz" integrity sha512-FamUaPVs1Fxr4KOMI0YcR2rYZHoN7ypGtgiEiJ11v/tEPjPPGgeKDxii0McCrdOkjheatLN1yd2jmMwYj6hTDg== @@ -2443,7 +2435,7 @@ "@react-types/overlays" "^3.8.7" "@react-types/shared" "^3.23.1" -"@react-types/overlays@3.8.7", "@react-types/overlays@^3.8.7": +"@react-types/overlays@^3.8.7", "@react-types/overlays@3.8.7": version "3.8.7" resolved "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.7.tgz" integrity sha512-zCOYvI4at2DkhVpviIClJ7bRrLXYhSg3Z3v9xymuPH3mkiuuP/dm8mUCtkyY4UhVeUTHmrQh1bzaOP00A+SSQA== @@ -2457,27 +2449,20 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/progress@3.5.4", "@react-types/progress@^3.5.4": +"@react-types/progress@^3.5.4", "@react-types/progress@3.5.4": version "3.5.4" resolved "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.4.tgz" integrity sha512-JNc246sTjasPyx5Dp7/s0rp3Bz4qlu4LrZTulZlxWyb53WgBNL7axc26CCi+I20rWL9+c7JjhrRxnLl/1cLN5g== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/radio@3.8.1", "@react-types/radio@^3.8.1": +"@react-types/radio@^3.8.1", "@react-types/radio@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.1.tgz" integrity sha512-bK0gio/qj1+0Ldu/3k/s9BaOZvnnRgvFtL3u5ky479+aLG5qf1CmYed3SKz8ErZ70JkpuCSrSwSCFf0t1IHovw== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/select@3.9.4": - version "3.9.4" - resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz" - integrity sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg== - dependencies: - "@react-types/shared" "^3.23.1" - "@react-types/select@^3.9.6": version "3.9.6" resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.6.tgz" @@ -2485,7 +2470,14 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/shared@3.23.1", "@react-types/shared@^3.23.1": +"@react-types/select@3.9.4": + version "3.9.4" + resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz" + integrity sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg== + dependencies: + "@react-types/shared" "^3.23.1" + +"@react-types/shared@^3.23.1", "@react-types/shared@3.23.1": version "3.23.1" resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz" integrity sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw== @@ -2509,7 +2501,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/table@3.9.5", "@react-types/table@^3.9.5": +"@react-types/table@^3.9.5", "@react-types/table@3.9.5": version "3.9.5" resolved "https://registry.npmjs.org/@react-types/table/-/table-3.9.5.tgz" integrity sha512-fgM2j9F/UR4Anmd28CueghCgBwOZoCVyN8fjaIFPd2MN4gCwUUfANwxLav65gZk4BpwUXGoQdsW+X50L3555mg== @@ -2517,21 +2509,21 @@ "@react-types/grid" "^3.2.6" "@react-types/shared" "^3.23.1" -"@react-types/tabs@3.3.7", "@react-types/tabs@^3.3.7": +"@react-types/tabs@^3.3.7", "@react-types/tabs@3.3.7": version "3.3.7" resolved "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.7.tgz" integrity sha512-ZdLe5xOcFX6+/ni45Dl2jO0jFATpTnoSqj6kLIS/BYv8oh0n817OjJkLf+DS3CLfNjApJWrHqAk34xNh6nRnEg== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/textfield@3.9.3", "@react-types/textfield@^3.9.3": +"@react-types/textfield@^3.9.3", "@react-types/textfield@3.9.3": version "3.9.3" resolved "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.3.tgz" integrity sha512-DoAY6cYOL0pJhgNGI1Rosni7g72GAt4OVr2ltEx2S9ARmFZ0DBvdhA9lL2nywcnKMf27PEJcKMXzXc10qaHsJw== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/tooltip@3.4.9", "@react-types/tooltip@^3.4.9": +"@react-types/tooltip@^3.4.9", "@react-types/tooltip@3.4.9": version "3.4.9" resolved "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.9.tgz" integrity sha512-wZ+uF1+Zc43qG+cOJzioBmLUNjRa7ApdcT0LI1VvaYvH5GdfjzUJOorLX9V/vAci0XMJ50UZ+qsh79aUlw2yqg== @@ -2544,6 +2536,13 @@ resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz" integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== +"@swc/helpers@^0.5.0": + version "0.5.13" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz" + integrity sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w== + dependencies: + tslib "^2.4.0" + "@swc/helpers@0.5.5": version "0.5.5" resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz" @@ -2552,13 +2551,6 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" -"@swc/helpers@^0.5.0": - version "0.5.13" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz" - integrity sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w== - dependencies: - tslib "^2.4.0" - "@tediousjs/connection-string@^0.5.0": version "0.5.0" resolved "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-0.5.0.tgz" @@ -4057,7 +4049,7 @@ dependencies: "@types/react" "*" -"@types/react@*": +"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0": version "18.3.11" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz" integrity sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ== @@ -4078,11 +4070,6 @@ abab@^2.0.5, abab@^2.0.6: resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -4133,13 +4120,6 @@ ag-grid-react@^32.0.2: ag-grid-community "32.1.0" prop-types "^15.8.1" -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" @@ -4147,6 +4127,13 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -4189,19 +4176,6 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - arg@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" @@ -4260,14 +4234,6 @@ body-scroll-lock@^3.1.5: resolved "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz" integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" @@ -4322,15 +4288,6 @@ caniuse-lite@^1.0.30001579: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz" integrity sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA== -canvas@^2.8.0: - version "2.11.2" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860" - integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.17.0" - simple-get "^3.0.3" - chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -4340,14 +4297,14 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chart.js@^4.4.6: +chart.js@^4.1.1, chart.js@^4.4.6: version "4.4.6" resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.4.6.tgz" integrity sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA== dependencies: "@kurkle/color" "^0.3.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: +chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0": version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -4362,22 +4319,22 @@ chart.js@^4.4.6: optionalDependencies: fsevents "~2.3.2" -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - classnames@^2.3.1: version "2.5.1" resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== -client-only@0.0.1, client-only@^0.0.1: +client-only@^0.0.1, client-only@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== -clsx@^1.1.1, clsx@^1.2.1: +clsx@^1.1.1: + version "1.2.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +clsx@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -4401,16 +4358,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -4419,16 +4376,6 @@ color-string@^1.9.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -color2k@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz" - integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== - color@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz" @@ -4437,6 +4384,11 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" +color2k@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz" + integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -4444,11 +4396,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@2: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^11.0.0: version "11.1.0" resolved "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz" @@ -4459,6 +4406,11 @@ commander@^4.0.0: resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@2: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + complex.js@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz" @@ -4469,11 +4421,6 @@ compute-scroll-into-view@^3.0.2: resolved "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz" integrity sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg== -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - concaveman@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz" @@ -4484,11 +4431,6 @@ concaveman@^1.2.1: robust-predicates "^2.0.4" tinyqueue "^2.0.3" -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - convert-source-map@^1.5.0: version "1.9.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" @@ -4589,13 +4531,6 @@ dayjs@^1.11.13: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== -debug@4, debug@^4.3.3, debug@^4.3.4: - version "4.3.5" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" - integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== - dependencies: - ms "2.1.2" - debug@^4.3.1: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" @@ -4603,18 +4538,18 @@ debug@^4.3.1: dependencies: ms "^2.1.3" +debug@^4.3.3, debug@^4.3.4, debug@4: + version "4.3.5" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decimal.js@^10.3.1, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - deepmerge@4.3.1: version "4.3.1" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" @@ -4630,16 +4565,6 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -detect-libc@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - detect-node-es@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" @@ -4830,25 +4755,13 @@ fraction.js@^4.3.7: resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== -framer-motion@^11.2.13: +framer-motion@^11.2.13, framer-motion@>=10.17.0: version "11.3.21" resolved "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.21.tgz" integrity sha512-D+hfIsvzV8eL/iycld4K+tKlg2Q2LdwnrcBEohtGw3cG1AIuNYATbT5RUqIM1ndsAk+EfGhoSGf0UaiFodc5Tw== dependencies: tslib "^2.4.0" -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - fs@^0.0.1-security: version "0.0.1-security" resolved "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz" @@ -4864,21 +4777,6 @@ function-bind@^1.1.2: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - geojson-equality-ts@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/geojson-equality-ts/-/geojson-equality-ts-1.0.2.tgz" @@ -4923,18 +4821,6 @@ glob@^10.3.10: minipass "^7.1.2" path-scurry "^1.11.1" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -4955,11 +4841,6 @@ has-flag@^3.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - hasown@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -5014,7 +4895,7 @@ https-proxy-agent@^7.0.0: agent-base "^7.0.2" debug "4" -iconv-lite@0.6.3, iconv-lite@^0.6.3: +iconv-lite@^0.6.3, iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -5039,17 +4920,9 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4: +inherits@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== international-types@^0.8.1: @@ -5380,13 +5253,6 @@ lru-cache@^10.2.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz" integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - marchingsquares@^1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/marchingsquares/-/marchingsquares-1.3.3.tgz" @@ -5437,18 +5303,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@^9.0.4: version "9.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz" @@ -5456,37 +5310,17 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "7.1.2" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.1.2, ms@^2.1.1: +ms@^2.1.1, ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -5517,11 +5351,6 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.17.0: - version "2.22.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.0.tgz#31bc433fc33213c97bad36404bb68063de604de3" - integrity sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw== - nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" @@ -5564,35 +5393,11 @@ next@14.2.14: "@next/swc-win32-ia32-msvc" "14.2.14" "@next/swc-win32-x64-msvc" "14.2.14" -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - nwsapi@^2.2.0: version "2.2.10" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz" @@ -5608,13 +5413,6 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -once@^1.3.0, once@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - open@^8.0.0: version "8.4.2" resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" @@ -5646,11 +5444,6 @@ parse5@6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" @@ -5756,6 +5549,15 @@ postcss-value-parser@^4.0.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== +postcss@^8, postcss@^8.0.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@>=8.0.9: + version "8.4.38" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + postcss@8.4.31: version "8.4.31" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" @@ -5765,15 +5567,6 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8, postcss@^8.4.23: - version "8.4.38" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.2.0" - prettier@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz" @@ -5868,7 +5661,7 @@ react-datepicker@^7.3.0: prop-types "^15.7.2" react-onclickoutside "^6.13.0" -react-dom@^18: +"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.3.0", react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -5980,7 +5773,7 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^18: +react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17 || ^18", react@^18, react@^18.0.0, react@^18.2.0, react@^18.3.1, "react@>= 16.3.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.13.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -5994,15 +5787,6 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@^4.2.0: version "4.5.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz" @@ -6062,13 +5846,6 @@ rfdc@^1.3.0: resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - robust-predicates@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz" @@ -6101,7 +5878,7 @@ safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@^1.77.8: +sass@^1.3.0, sass@^1.77.8: version "1.77.8" resolved "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz" integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ== @@ -6136,14 +5913,9 @@ seedrandom@^3.0.5: resolved "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz" integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.5, semver@^7.5.4: +semver@^7.5.4: version "7.6.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== server-only@^0.0.1: @@ -6151,11 +5923,6 @@ server-only@^0.0.1: resolved "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz" integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA== -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -6168,30 +5935,11 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" @@ -6204,7 +5952,7 @@ skmeans@0.9.7: resolved "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz" integrity sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0: +source-map-js@^1.0.2, source-map-js@^1.2.0, "source-map-js@>=0.6.2 <2.0.0": version "1.2.0" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== @@ -6239,6 +5987,13 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -6248,16 +6003,16 @@ streamsearch@^1.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: +string-width@^4.1.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: +string-width@^5.0.1: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -6266,14 +6021,23 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1, string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== +string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - safe-buffer "~5.2.0" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -6336,7 +6100,7 @@ sweetalert2-react-content@^5.0.7: resolved "https://registry.npmjs.org/sweetalert2-react-content/-/sweetalert2-react-content-5.0.7.tgz" integrity sha512-8Fk82Mpk45lFXpJWKIFF/lq8k/dJKDDQGFcuqVosaL/qRdViyAs5+u37LoTGfnOIvf+rfQB3PAXcp1XLLn+0ew== -sweetalert2@^11.14.1: +sweetalert2@^11.0.0, sweetalert2@^11.14.1: version "11.14.1" resolved "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.14.1.tgz" integrity sha512-xadhfcA4STGMh8nC5zHFFWURhRpWc4zyI3GdMDFH/m3hGWZeQQNWhX9xcG4lI9gZYsi/IlazKbwvvje3juL3Xg== @@ -6363,7 +6127,7 @@ tailwind-variants@^0.1.20: dependencies: tailwind-merge "^1.14.0" -tailwindcss@^3.4.1: +tailwindcss@*, tailwindcss@^3.4.1, tailwindcss@>=3.4.0: version "3.4.4" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz" integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== @@ -6391,18 +6155,6 @@ tailwindcss@^3.4.1: resolve "^1.22.2" sucrase "^3.32.0" -tar@^6.1.11: - version "6.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - tarn@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz" @@ -6491,11 +6243,6 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" @@ -6566,9 +6313,9 @@ use-sidecar@^1.1.2: detect-node-es "^1.1.0" tslib "^2.0.0" -util-deprecate@^1.0.1, util-deprecate@^1.0.2: +util-deprecate@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== uuid@^10.0.0: @@ -6595,11 +6342,6 @@ w3c-xmlserializer@^3.0.0: dependencies: xml-name-validator "^4.0.0" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" @@ -6633,14 +6375,6 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -6648,13 +6382,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -6673,11 +6400,6 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - ws@^8.2.3: version "8.17.1" resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz" @@ -6693,11 +6415,6 @@ xmlchars@^2.2.0: resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^1.10.0: version "1.10.2" resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"