Merge branch 'dev' into dev-yj

This commit is contained in:
yjnoh 2024-10-21 14:32:26 +09:00
commit f50e1675d0
32 changed files with 2837 additions and 3069 deletions

View File

@ -1,27 +1,24 @@
'use client'
import { useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
import ServerError from './error'
import '@/styles/common.scss'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
// import KO from '@/locales/ko.json'
// import JA from '@/locales/ja.json'
export const QcastProvider = ({ children }) => {
const globalLocale = useRecoilValue(globalLocaleStore)
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
// const globalLocale = useRecoilValue(globalLocaleStore)
// const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
useEffect(() => {
if (globalLocale === 'ko') {
setAppMessageState(KO)
} else {
setAppMessageState(JA)
}
}, [globalLocale])
// useEffect(() => {
// if (globalLocale === 'ko') {
// setAppMessageState(KO)
// } else {
// setAppMessageState(JA)
// }
// }, [globalLocale])
return (
<>

View File

@ -16,6 +16,7 @@ import '../styles/style.scss'
import '../styles/contents.scss'
import Dimmed from '@/components/ui/Dimmed'
import SessionProvider from './SessionProvider'
import LocaleSwitch from '@/components/LocaleSwitch'
// const inter = Inter({ subsets: ['latin'] })
@ -76,8 +77,9 @@ export default async function RootLayout({ children }) {
</QcastProvider>
</div>
<footer>
<div className="footer-inner">
<div className="footer-inner flex justify-center">
<span>COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</span>
<LocaleSwitch />
</div>
</footer>
</div>

View File

@ -0,0 +1,23 @@
'use client'
import { globalLocaleStore } from '@/store/localeAtom'
import { useRecoilState } from 'recoil'
export default function LocaleSwitch() {
const [globalLocale, setGlobalLocale] = useRecoilState(globalLocaleStore)
return (
<span
className="locale-switch"
onClick={() => {
if (globalLocale === 'ko') {
setGlobalLocale('ja')
} else {
setGlobalLocale('ko')
}
}}
>
{globalLocale.toUpperCase()}
</span>
)
}

View File

@ -0,0 +1,21 @@
'use client'
import { useMessage } from '@/hooks/useMessage'
export default function AutoLoginPage() {
const { getMessage } = useMessage()
return (
<div className="login-input-frame">
<div className="login-frame-tit ">
<span>{getMessage('site.name')}</span>
{getMessage('site.sub_name')}
</div>
<div className="login-input-wrap">
<div className="login-area id" style={{ fontWeight: 'bolder' }}>
{getMessage('login.auto.page.text')}
</div>
</div>
</div>
)
}

View File

@ -15,6 +15,8 @@ import Cookies from 'js-cookie'
import { useSearchParams } from 'next/navigation'
import AutoLogin from './AutoLogin'
export default function Login() {
//
const initParams = useSearchParams()
@ -180,8 +182,7 @@ export default function Login() {
<Link href={'/login'} className="login-logo">
<Image src="/static/images/main/login-logo.svg" alt="react" width={236} height={43} styles={{ width: '236px', height: '43px' }} priority />
</Link>
{passwordReset === 1 && (
{!autoLoginParam && passwordReset === 1 && (
<>
<div className="login-input-frame">
<form onSubmit={loginProcess} className="space-y-6">
@ -266,7 +267,7 @@ export default function Login() {
</div>
</>
)}
{passwordReset === 2 && (
{!autoLoginParam && passwordReset === 2 && (
<>
<div className="login-input-frame">
<div className="login-frame-tit pw-reset">
@ -328,6 +329,7 @@ export default function Login() {
</div>
</>
)}
{autoLoginParam && <AutoLogin />}
</div>
<div className="login-copyright">COPYRIGHT©2024 Hanwha Japan All Rights Reserved.</div>
</div>

View File

@ -61,7 +61,7 @@ export default function Archive() {
<div className="sub-content">
<div className="sub-content-inner">
<div className="sub-table-box">
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={true} />
<Search title={boardType.boardTitle} subTitle={boardType.subTitle} isSelectUse={false} />
<ArchiveTable clsCode={boardType.clsCode} />
</div>
</div>

View File

@ -45,7 +45,7 @@ export default function ArchiveTable({ clsCode }) {
}
fetchData()
}, [search.searchValue])
}, [search.searchValue, search.searchFlag])
//
const handleDetailFileListDown = async (noticeNo) => {
@ -74,30 +74,34 @@ export default function ArchiveTable({ clsCode }) {
return (
<>
<div className="file-down-list">
{boardList?.map((board) => (
<div key={board.noticeNo} className="file-down-item">
<div className="file-item-info">
<div className="item-num">
{/* 번호 */}
{board.rowNumber}
{boardList.length > 0 ? (
<div className="file-down-list">
{boardList?.map((board) => (
<div key={board.noticeNo} className="file-down-item">
<div className="file-item-info">
<div className="item-num">
{/* 번호 */}
{board.rowNumber}
</div>
<div className="item-name">
{/* 제목 */}
{board.title}
</div>
<div className="item-date">
{/* 등록일 */}
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
</div>
</div>
<div className="item-name">
{/* 제목 */}
{board.title}
</div>
<div className="item-date">
{/* 등록일 */}
{getMessage('board.sub.updDt')} : {board.uptDt ? board.uptDt : board.regDt}
<div className="file-down-box">
{/* 첨부파일 */}
<button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button>
</div>
</div>
<div className="file-down-box">
{/* 첨부파일 */}
<button type="button" className="file-down-btn" onClick={() => handleDetailFileListDown(board.noticeNo)}></button>
</div>
</div>
))}
</div>
))}
</div>
) : (
<div className="file-down-nodata">{getMessage('common.message.no.data')}</div>
)}
</>
)
}

View File

@ -7,14 +7,11 @@ import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
import { usePlan } from '@/hooks/usePlan'
import { globalLocaleStore } from '@/store/localeAtom'
import { sessionStore } from '@/store/commonAtom'
import { SessionContext } from '@/app/SessionProvider'
export default function CanvasLayout() {
const { session } = useContext(SessionContext)
console.log('session >>> ', session)
const [objectNo, setObjectNo] = useState('test123240822001') //
const sessionState = useRecoilValue(sessionStore)
const globalLocaleState = useRecoilValue(globalLocaleStore)
const { getMessage } = useMessage()
@ -22,8 +19,7 @@ export default function CanvasLayout() {
const { plans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan()
useEffect(() => {
console.log('loadCanvasPlanData 실행, sessionState.userId >>> ', sessionState.userId)
loadCanvasPlanData(sessionState.userId, objectNo)
loadCanvasPlanData(session.userId, objectNo)
}, [])
return (
@ -34,7 +30,7 @@ export default function CanvasLayout() {
<button
key={`plan-${plan.id}`}
className={`canvas-page-box ${plan.isCurrent === true ? 'on' : ''}`}
onClick={() => handleCurrentPlan(sessionState.userId, plan.id)}
onClick={() => handleCurrentPlan(session.userId, plan.id)}
>
<span>{plan.name}</span>
<i
@ -53,7 +49,7 @@ export default function CanvasLayout() {
))}
</div>
{plans.length < 10 && (
<button className="plane-add" onClick={() => handleAddPlan(sessionState.userId, objectNo)}>
<button className="plane-add" onClick={() => handleAddPlan(session.userId, objectNo)}>
<span></span>
</button>
)}

View File

@ -7,7 +7,7 @@ import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState
import { onlyNumberInputChange } from '@/util/input-utils'
import { fabric } from 'fabric'
import { gridColorState } from '@/store/gridAtom'
import { settingModalGridOptionsState } from '@/store/settingAtom'
import { gridDisplaySelector, settingModalGridOptionsState } from '@/store/settingAtom'
import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
@ -24,6 +24,7 @@ export default function DotLineGrid(props) {
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
const gridColor = useRecoilValue(gridColorState)
const canvas = useRecoilValue(canvasState)
const isGridDisplay = useRecoilValue(gridDisplaySelector)
const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState)
const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState)
@ -179,6 +180,7 @@ export default function DotLineGrid(props) {
fill: pattern,
selectable: false,
name: 'dotGrid',
visible: isGridDisplay,
},
)
@ -209,6 +211,7 @@ export default function DotLineGrid(props) {
strokeDashArray: [5, 2],
opacity: 0.3,
direction: 'horizontal',
visible: isGridDisplay,
},
)
canvas.add(horizontalLine)
@ -235,6 +238,7 @@ export default function DotLineGrid(props) {
strokeDashArray: [5, 2],
opacity: 0.3,
direction: 'vertical',
visible: isGridDisplay,
},
)
canvas.add(verticalLine)

View File

@ -1,14 +1,14 @@
import { useRecoilState } from 'recoil'
import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
import { settingModalSecondOptionsState } from '@/store/settingAtom'
import { useMessage } from '@/hooks/useMessage'
import React, { useEffect, useState } from 'react'
import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
import { adsorptionPointAddModeState } from '@/store/canvasAtom'
import { useFirstOption } from '@/hooks/option/useFirstOption'
export default function FirstOption() {
const [objectNo, setObjectNo] = useState('test123240912001') //
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
const { settingModalFirstOptions, setSettingModalFirstOptions } = useFirstOption()
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
const { option3, option4 } = settingModalSecondOptions

View File

@ -34,7 +34,6 @@ export default function MainContents({ objectList, businessCharger, businessChar
startRow: 1,
endRow: 1,
}
// const noticeApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=NOTICE&schTitle=&startRow=1&endRow=1`
const noticeApiUrl = `api/board/list?${queryStringFormatter(param)}`
const res = await get({ url: noticeApiUrl })
//console.log('res::', res)
@ -57,7 +56,6 @@ export default function MainContents({ objectList, businessCharger, businessChar
startRow: 1,
endRow: 3,
}
// const faqApiUrl = `api/board/list?schNoticeTpCd=QC&schNoticeClsCd=FAQ&schTitle=&startRow=1&endRow=1`
const faqApiUrl = `api/board/list?${queryStringFormatter(param)}`
const res = await get({ url: faqApiUrl })
//console.log('FAQres::', res)

View File

@ -245,7 +245,6 @@ export default function Stuff() {
}
async function fetchData() {
// const apiUrl = `/api/object/list?saleStoreId=T01&${queryStringFormatter(params)}`
const apiUrl = `/api/object/list?saleStoreId=${sessionState?.storeId}&${queryStringFormatter(params)}`
await get({
url: apiUrl,
@ -294,7 +293,6 @@ export default function Stuff() {
useEffect(() => {
if (stuffSearchParams?.code === 'E') {
//console.log('::::::::', stuffSearchParams, sessionState)
stuffSearchParams.startRow = 1
stuffSearchParams.endRow = 1 * pageSize
stuffSearchParams.schSortType = defaultSortType

View File

@ -102,7 +102,6 @@ export default function StuffDetail() {
// API
get({ url: '/api/object/prefecture/list' }).then((res) => {
if (!isEmptyArray(res)) {
// console.log(' API :::', res)
setPrefCodeList(res)
}
})
@ -348,9 +347,8 @@ export default function StuffDetail() {
//
get({ url: `/api/object/prefecture/${prefValue}/list` }).then((res) => {
if (!isEmptyArray(res)) {
// console.log(' ::::::::', res)
form.setValue('areaId', res[0].areaId)
form.setValue('areaName', res[0].prefName)
// form.setValue('areaId', res[0].areaId)
// form.setValue('areaName', res[0].prefName)
setAreaIdList(res)
}
})
@ -359,7 +357,8 @@ export default function StuffDetail() {
//
const handleAreaIdOnChange = (e) => {
form.setValue('areaId', e.target.value)
form.setValue('areaId', e.areaId)
form.setValue('areaName', e.prefName)
}
//
@ -631,13 +630,28 @@ export default function StuffDetail() {
<div className="flx-box">
<div className="select-wrap" style={{ width: '200px' }}>
{prefCodeList?.length > 0 && (
<select className="select-light" name="prefName" {...register('prefId')} disabled>
{prefCodeList.map((row) => (
<option key={row.prefId} value={row.prefId}>
{row.prefName}
</option>
))}
</select>
// <select className="select-light" name="prefName" {...register('prefId')} disabled>
// {prefCodeList.map((row) => (
// <option key={row.prefId} value={row.prefId}>
// {row.prefName}
// </option>
// ))}
// </select>
<Select
id="long-value-select3"
instanceId="long-value-select3"
className="react-select-custom"
classNamePrefix="custom"
placeholder="Select"
options={prefCodeList}
getOptionLabel={(x) => x.prefName}
getOptionValue={(x) => x.prefId}
isSearchable={false}
value={prefCodeList.filter(function (option) {
return option.prefId === prefValue
})}
isDisabled={true}
/>
)}
</div>
<div className="input-wrap mr5" style={{ width: '580px' }}>
@ -652,7 +666,7 @@ export default function StuffDetail() {
</th>
<td>
<div className="select-wrap" style={{ width: '200px' }}>
<select
{/* <select
className="select-light"
name="areaId"
disabled={areaIdList?.length > 0 ? false : true}
@ -664,8 +678,25 @@ export default function StuffDetail() {
{row.prefName}
</option>
)
})}
</select>
*/}
<Select
id="long-value-select4"
instanceId="long-value-select4"
className="react-select-custom"
classNamePrefix="custom"
options={areaIdList}
placeholder="Select"
getOptionLabel={(x) => x.prefName}
getOptionValue={(x) => x.areaId}
isSearchable={false}
onChange={handleAreaIdOnChange}
value={areaIdList.filter(function (option) {
return option.areaId === form.watch('areaId')
})}
</select>
isDisabled={areaIdList.length > 0 ? false : true}
/>
</div>
</td>
</tr>
@ -794,9 +825,9 @@ export default function StuffDetail() {
</Button>
)}
<Link href="/management/stuff">
<Button type="button" className="btn-origin grey">
<button type="button" className="btn-origin grey">
NEW화면 물건목록이동
</Button>
</button>
</Link>
</div>
</div>
@ -911,9 +942,9 @@ export default function StuffDetail() {
{objectNo.substring(0, 1) === 'R' ? (
<>
<Link href="/management/stuff">
<Button type="button" className="btn-origin grey mr5">
<button type="button" className="btn-origin grey mr5">
R상세:물건목록
</Button>
</button>
</Link>
<Button type="submit" className="btn-origin navy mr5">
R상세:저장
@ -934,9 +965,9 @@ export default function StuffDetail() {
</Button>
)}
<Link href="/management/stuff">
<Button type="button" className="btn-origin grey">
<button type="button" className="btn-origin grey">
T상세:물건목록
</Button>
</button>
</Link>
</>
)}

View File

@ -24,6 +24,13 @@ export default function StuffSearchCondition() {
const ref = useRef()
const { get } = useAxios(globalLocaleState)
const objectNoRef = useRef(null)
const saleStoreNameRef = useRef(null)
const addressRef = useRef(null)
const objectNameRef = useRef(null)
const dispCompanyNameRef = useRef(null)
const receiveUserRef = useRef(null)
// props
const [startDate, setStartDate] = useState(dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD'))
const [endDate, setEndDate] = useState(dayjs(new Date()).format('YYYY-MM-DD'))
@ -42,13 +49,13 @@ export default function StuffSearchCondition() {
const resetStuffRecoil = useResetRecoilState(stuffSearchState)
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
const [objectNo, setObjectNo] = useState('') //
const [saleStoreName, setSaleStoreName] = useState('') //
const [address, setAddress] = useState('') //
const [objectName, setobjectName] = useState('') //
const [saleStoreName, setSaleStoreName] = useState('') //
const [receiveUser, setReceiveUser] = useState('') //
const [dispCompanyName, setDispCompanyName] = useState('') //
const [dateType, setDateType] = useState('U') //(U)/(R)
const [schSelSaleStoreId, setSchSelSaleStoreId] = useState('') //
const [receiveUser, setReceiveUser] = useState('') //
const [dateType, setDateType] = useState('U') //(U)/(R)
const [schSelSaleStoreList, setSchSelSaleStoreList] = useState([]) // SELECT
//
@ -58,26 +65,52 @@ export default function StuffSearchCondition() {
return alert(getMessage('stuff.message.periodError'))
}
setStuffSearch({
schObjectNo: stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo,
schAddress: stuffSearch?.schAddress ? stuffSearch.schAddress : address,
schObjectName: stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName,
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName,
schReceiveUser: stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser,
schDispCompanyName: stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName,
schDateType: stuffSearch?.schDateType ? stuffSearch.schDateType : dateType,
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
code: 'E',
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : schSelSaleStoreId,
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
})
if (stuffSearch.code === 'S') {
setStuffSearch({
schObjectNo: objectNo ? objectNo : stuffSearch?.schObjectNo,
schSaleStoreName: stuffSearch?.schSaleStoreName ? stuffSearch?.schSaleStoreName : saleStoreName,
schAddress: address ? address : stuffSearch?.schAddress,
schObjectName: objectName ? objectName : stuffSearch?.schObjectName,
schDispCompanyName: dispCompanyName ? dispCompanyName : stuffSearch?.schDispCompanyName,
schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : schSelSaleStoreId,
schReceiveUser: receiveUser ? receiveUser : stuffSearch?.schReceiveUser,
schDateType: stuffSearch?.schDateType ? stuffSearch.schDateType : dateType,
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
code: 'E',
startRow: stuffSearch?.startRow ? stuffSearch.startRow : 1,
endRow: stuffSearch?.endRow ? stuffSearch.endRow : 100,
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
})
} else {
setStuffSearch({
schObjectNo: objectNo ? objectNo : '',
schSaleStoreName: saleStoreName ? saleStoreName : '',
schAddress: address ? address : '',
schObjectName: objectName ? objectName : '',
schDispCompanyName: dispCompanyName ? dispCompanyName : '',
schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : '',
schReceiveUser: receiveUser ? receiveUser : '',
schDateType: dateType,
schFromDt: dayjs(startDate).format('YYYY-MM-DD'),
schToDt: dayjs(endDate).format('YYYY-MM-DD'),
code: 'E',
startRow: 1,
endRow: 100,
schSortType: stuffSearch?.schSortType ? stuffSearch.schSortType : 'R',
})
}
}
//
const resetRecoil = () => {
objectNoRef.current.value = ''
saleStoreNameRef.current.value = ''
addressRef.current.value = ''
objectNameRef.current.value = ''
dispCompanyNameRef.current.value = ''
receiveUserRef.current.value = ''
setObjectNo('')
setAddress('')
setobjectName('')
@ -143,6 +176,13 @@ export default function StuffSearchCondition() {
}
}, [globalLocaleState])
//
const handleByOnKeyUp = (e) => {
if (e.key === 'Enter') {
onSubmit()
}
}
return (
<>
{/* 퍼블적용시작 */}
@ -182,12 +222,13 @@ export default function StuffSearchCondition() {
<div className="input-wrap">
<input
type="text"
ref={objectNoRef}
className="input-light"
value={stuffSearch?.code === 'E' || stuffSearch?.code === 'M' ? stuffSearch.schObjectNo : objectNo}
defaultValue={stuffSearch.code === 'E' || stuffSearch.code === 'M' ? stuffSearch?.schObjectNo : objectNo}
onChange={(e) => {
setObjectNo(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schObjectNo: e.target.value })
setObjectNo(objectNoRef.current.value)
}}
onKeyUp={handleByOnKeyUp}
/>
</div>
</td>
@ -196,11 +237,11 @@ export default function StuffSearchCondition() {
<div className="input-wrap">
<input
type="text"
ref={saleStoreNameRef}
className="input-light"
value={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName}
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schSaleStoreName : saleStoreName}
onChange={(e) => {
setSaleStoreName(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schSaleStoreName: e.target.value })
setSaleStoreName(saleStoreNameRef.current.value)
}}
/>
</div>
@ -210,11 +251,11 @@ export default function StuffSearchCondition() {
<div className="input-wrap">
<input
type="text"
ref={addressRef}
className="input-light"
value={stuffSearch?.schAddress ? stuffSearch.schAddress : address}
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schAddress : address}
onChange={(e) => {
setAddress(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schAddress: e.target.value })
setAddress(addressRef.current.value)
}}
/>
</div>
@ -226,11 +267,11 @@ export default function StuffSearchCondition() {
<div className="input-wrap">
<input
type="text"
ref={objectNameRef}
className="input-light"
value={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName}
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schObjectName : objectName}
onChange={(e) => {
setobjectName(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schObjectName: e.target.value })
setobjectName(objectNameRef.current.value)
}}
/>
</div>
@ -240,11 +281,11 @@ export default function StuffSearchCondition() {
<div className="input-wrap">
<input
type="text"
ref={dispCompanyNameRef}
className="input-light"
value={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName}
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schDispCompanyName : dispCompanyName}
onChange={(e) => {
setDispCompanyName(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schDispCompanyName: e.target.value })
setDispCompanyName(dispCompanyNameRef.current.value)
}}
/>
</div>
@ -293,10 +334,10 @@ export default function StuffSearchCondition() {
<input
type="text"
className="input-light"
value={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser}
ref={receiveUserRef}
defaultValue={stuffSearch.code === 'E' ? stuffSearch?.schReceiveUser : receiveUser}
onChange={(e) => {
setReceiveUser(e.target.value)
setStuffSearch({ ...stuffSearch, code: 'S', schReceiveUser: e.target.value })
setReceiveUser(receiveUserRef.current.value)
}}
/>
</div>

View File

@ -0,0 +1,23 @@
import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom'
import { useEffect } from 'react'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
export function useFirstOption() {
const canvas = useRecoilValue(canvasState)
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
useEffect(() => {
const option1 = settingModalFirstOptions.option1
canvas
.getObjects()
.filter((obj) => obj.name === '')
.forEach((obj) => {
obj.set({ visible: !obj.visible })
})
}, [settingModalFirstOptions])
return { settingModalFirstOptions, setSettingModalFirstOptions }
}

View File

@ -30,6 +30,7 @@ import {
import { calculateAngle } from '@/util/qpolygon-utils'
import { fabric } from 'fabric'
import { QLine } from '@/components/fabric/QLine'
import { outlineDisplaySelector } from '@/store/settingAtom'
//외벽선 그리기
export function useOuterLineWall(setShowOutlineModal) {
@ -53,6 +54,8 @@ export function useOuterLineWall(setShowOutlineModal) {
const adsorptionRange = useRecoilValue(adsorptionRangeState)
const interval = useRecoilValue(dotLineIntervalSelector) // 가로 세로 간격
const isOutlineDisplay = useRecoilValue(outlineDisplaySelector)
const length1Ref = useRef(null)
const length2Ref = useRef(null)
const angle1Ref = useRef(null)
@ -253,6 +256,7 @@ export function useOuterLineWall(setShowOutlineModal) {
strokeWidth: 1,
selectable: false,
name: 'helpGuideLine',
visible: isOutlineDisplay,
})
} else {
const guideLine1 = addLine([lastPoint.x, lastPoint.y, lastPoint.x, firstPoint.y], {
@ -260,6 +264,7 @@ export function useOuterLineWall(setShowOutlineModal) {
strokeWidth: 1,
strokeDashArray: [1, 1, 1],
name: 'helpGuideLine',
visible: isOutlineDisplay,
})
const guideLine2 = addLine([guideLine1.x2, guideLine1.y2, firstPoint.x, firstPoint.y], {
@ -267,6 +272,7 @@ export function useOuterLineWall(setShowOutlineModal) {
strokeWidth: 1,
strokeDashArray: [1, 1, 1],
name: 'helpGuideLine',
visible: isOutlineDisplay,
})
}
}
@ -283,6 +289,7 @@ export function useOuterLineWall(setShowOutlineModal) {
y1: point1.y,
x2: point2.x,
y2: point2.y,
visible: isOutlineDisplay,
})
}

View File

@ -2,13 +2,14 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import { adsorptionPointAddModeState, adsorptionPointModeState, adsorptionRangeState, canvasState } from '@/store/canvasAtom'
import { fabric } from 'fabric'
import { useMouse } from '@/hooks/useMouse'
import { gridDisplaySelector } from '@/store/settingAtom'
export function useAdsorptionPoint() {
const canvas = useRecoilValue(canvasState)
const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState)
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState)
const isGridDisplay = useRecoilValue(gridDisplaySelector)
const { getIntersectMousePoint } = useMouse()
const getAdsorptionPoints = () => {
@ -28,6 +29,7 @@ export function useAdsorptionPoint() {
y: pointer.y,
selectable: true,
name: 'adsorptionPoint',
visible: isGridDisplay,
})
canvas.add(adsorptionPoint)

View File

@ -6,6 +6,7 @@ import { calculateDistance, calculateIntersection, distanceBetweenPoints, findCl
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
import { useDotLineGrid } from '@/hooks/useDotLineGrid'
import { useTempGrid } from '@/hooks/useTempGrid'
import { gridDisplaySelector } from '@/store/settingAtom'
export function useEvent() {
const canvas = useRecoilValue(canvasState)

View File

@ -1,14 +1,17 @@
import { useEffect } from 'react'
import { useRecoilValue } from 'recoil'
import { appMessageStore } from '@/store/localeAtom'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
// import KO from '@/locales/ko.json'
// import JA from '@/locales/ja.json'
import KO from '@/locales/ko.json'
import JA from '@/locales/ja.json'
const SESSION_STORAGE_MESSAGE_KEY = 'QCAST_MESSAGE_STORAGE'
export const useMessage = () => {
// const globalLocale = useRecoilValue(globalLocaleState)
const appMessageState = useRecoilValue(appMessageStore)
// const appMessageState = useRecoilValue(appMessageStore)
const globalLocale = useRecoilValue(globalLocaleStore)
const appMessageState = globalLocale === 'ko' ? KO : JA
const getMessage = (key, args = []) => {
// if (sessionStorage.getItem(SESSION_STORAGE_MESSAGE_KEY) === null) {

View File

@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { useRecoilState } from 'recoil'
import { v4 as uuidv4 } from 'uuid'
import { canvasState, currentCanvasPlanState, initCanvasPlansState, plansState } from '@/store/canvasAtom'
import { useAxios } from '@/hooks/useAxios'
import { useMessage } from '@/hooks/useMessage'
@ -269,15 +270,16 @@ export function usePlan() {
: addPlan(userId, objectNo)
}
const addPlan = (userId, objectNo, canvasStatus = '') => {
const id = uuidv4()
const newPlan = {
id: planNum,
id: id,
name: `Plan ${planNum + 1}`,
objectNo: objectNo,
userId: userId,
canvasStatus: canvasStatus,
}
setPlans([...plans, newPlan])
handleCurrentPlan(userId, planNum)
handleCurrentPlan(userId, id)
setPlanNum(planNum + 1)
}

View File

@ -1,11 +1,13 @@
import { canvasState, tempGridModeState } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue } from 'recoil'
import { gridColorState } from '@/store/gridAtom'
import { gridDisplaySelector } from '@/store/settingAtom'
export function useTempGrid() {
const canvas = useRecoilValue(canvasState)
const gridColor = useRecoilValue(gridColorState)
const [tempGridMode, setTempGridMode] = useRecoilState(tempGridModeState)
const isGridDisplay = useRecoilValue(gridDisplaySelector)
const tempGridModeStateLeftClickEvent = (e) => {
//임의 그리드 모드일 경우
let pointer = canvas.getPointer(e.e)
@ -22,6 +24,7 @@ export function useTempGrid() {
strokeDashArray: [5, 2],
opacity: 0.3,
direction: 'vertical',
visible: isGridDisplay,
name: 'tempGrid',
})
@ -48,6 +51,7 @@ export function useTempGrid() {
strokeDashArray: [5, 2],
opacity: 0.3,
name: 'tempGrid',
visible: isGridDisplay,
direction: 'horizontal',
})

View File

@ -1,18 +0,0 @@
'use client'
import { createI18nClient } from 'next-international/client'
export const { useI18n, useScopedI18n, I18nProviderClient, useChangeLocale, defineLocale, useCurrentLocale } = createI18nClient(
{
ko: () => import('./ko'),
ja: () => import('./ja'),
},
{
// Uncomment to set base path
// basePath: '/base',
// Uncomment to use custom segment name
// segmentName: 'locale',
// Uncomment to set fallback locale
// fallbackLocale: en,
},
)

View File

@ -1,90 +0,0 @@
console.log('Loaded JA')
export default {
hello: 'こんにちは',
welcome: 'こんにちは {name}!',
locale: '現在のロケールは {locale} です。',
common: {
require: '필수',
},
site: {
name: 'Q.CAST III',
sub_name: '태양광 발전 시스템 도면관리 사이트',
},
login: {
login: 'Login',
init_password: {
btn: '비밀번호 초기화',
title: '비밀번호 초기화',
sub_title: '비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.',
},
},
join: {
title: 'Q.CAST3 로그인ID 발행 신청',
sub1: {
title: '판매대리점 정보',
comment: '※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)',
storeQcastNm: '판매대리점명',
storeQcastNm_placeholder: '株式会社エネルギア・ソリューション・アンド・サービス2次店山口住機販売有限会社',
storeQcastNmKana: '판매대리점명 후리가나',
storeQcastNmKana_placeholder: 'カブシキガイシャエネルギア・ソリューション・アン',
postCd: '우편번호',
postCd_placeholder: '숫자 7자리',
addr: '주소',
addr_placeholder: '전각50자이내',
telNo: '전화번호',
telNo_placeholder: '00-0000-0000',
fax: 'FAX 번호',
fax_placeholder: '00-0000-0000',
},
sub2: {
title: '담당자 정보',
userNm: '담당자명',
userNmKana: '담당자명 후리가나',
userId: '신청 ID',
email: '이메일 주소',
telNo: '전화번호',
telNo_placeholder: '00-0000-0000',
fax: 'FAX 번호',
fax_placeholder: '00-0000-0000',
category: '부서명',
},
sub3: {
title: '견적서 제출용 회사정보',
qtCompNm: '회사명',
qtPostCd: '우편번호',
qtPostCd_placeholder: '숫자 7자리',
qtAddr: '주소',
qtAddr_placeholder: '전각50자이내',
qtEmail: '이메일 주소',
qtTelNo: '전화번호',
qtTelNo_placeholder: '00-0000-0000',
qtFax: 'FAX 번호',
qtFax_placeholder: '00-0000-0000',
},
btn: {
approval_request: 'ID 승인요청',
},
complete: {
title: 'Q.CAST3 로그인ID 발행신청 완료',
contents: '※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.',
email_comment: '담당자 이메일 주소',
email: 'test@naver.com',
},
},
stuff: {
gridHeader: {
lastEditDatetime: '갱신일시',
objectNo: '물건번호',
planTotCnt: '플랜 수',
objectName: '물건명',
saleStoreId: '대리점ID',
saleStoreName: '대리점명',
address: '물건주소',
dispCompanyName: '견적처',
receiveUser: '담당자',
specDate: '사양확인',
createDatetime: '등록일',
},
},
}

View File

@ -385,6 +385,7 @@
"myinfo.message.save": "パスワードが変更されました。",
"myinfo.message.password.error": "パスワードが間違っています。",
"login": "ログイン",
"login.auto.page.text": "自動ログイン中です。",
"login.id.save": "ID保存",
"login.id.placeholder": "IDを入力してください。",
"login.password.placeholder": "パスワードを入力してください。",

View File

@ -1,91 +0,0 @@
console.log('Loaded KO')
export default {
hello: '안녕',
welcome: '안녕 {name}!',
locale: '현재 로케일은 {locale}입니다.',
common: {
require: '필수',
},
site: {
name: 'Q.CAST III',
sub_name: '태양광 발전 시스템 도면관리 사이트',
},
login: {
login: '로그인',
init_password: {
btn: '비밀번호 초기화',
title: '비밀번호 초기화',
sub_title: '비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.',
complete_message: '비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.',
},
},
join: {
title: 'Q.CAST3 로그인ID 발행 신청',
sub1: {
title: '판매대리점 정보',
comment: '※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점××설비주식회사)」로 기입해 주세요.)',
storeQcastNm: '판매대리점명',
storeQcastNm_placeholder: '주식회사 에너지 기어 솔루션 앤 서비스 (2차점: 야마구치 주기 판매 유한회사)',
storeQcastNmKana: '판매대리점명 후리가나',
storeQcastNmKana_placeholder: '주식회사 에너지 기어 솔루션',
postCd: '우편번호',
postCd_placeholder: '숫자 7자리',
addr: '주소',
addr_placeholder: '전각50자이내',
telNo: '전화번호',
telNo_placeholder: '00-0000-0000',
fax: 'FAX 번호',
fax_placeholder: '00-0000-0000',
},
sub2: {
title: '담당자 정보',
userNm: '담당자명',
userNmKana: '담당자명 후리가나',
userId: '신청 ID',
email: '이메일 주소',
telNo: '전화번호',
telNo_placeholder: '00-0000-0000',
fax: 'FAX 번호',
fax_placeholder: '00-0000-0000',
category: '부서명',
},
sub3: {
title: '견적서 제출용 회사정보',
qtCompNm: '회사명',
qtPostCd: '우편번호',
qtPostCd_placeholder: '숫자 7자리',
qtAddr: '주소',
qtAddr_placeholder: '전각50자이내',
qtEmail: '이메일 주소',
qtTelNo: '전화번호',
qtTelNo_placeholder: '00-0000-0000',
qtFax: 'FAX 번호',
qtFax_placeholder: '00-0000-0000',
},
btn: {
approval_request: 'ID 승인요청',
},
complete: {
title: 'Q.CAST3 로그인ID 발행신청 완료',
contents: '※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.',
email_comment: '담당자 이메일 주소',
email: 'test@naver.com',
},
},
stuff: {
gridHeader: {
lastEditDatetime: '갱신일시',
objectNo: '물건번호',
planTotCnt: '플랜 수',
objectName: '물건명',
saleStoreId: '대리점ID',
saleStoreName: '대리점명',
address: '물건주소',
dispCompanyName: '견적처',
receiveUser: '담당자',
specDate: '사양확인',
createDatetime: '등록일',
},
},
}

View File

@ -390,6 +390,7 @@
"myinfo.message.save": "비밀번호가 변경되었습니다.",
"myinfo.message.password.error": "비밀번호가 틀렸습니다.",
"login": "로그인",
"login.auto.page.text": "자동로그인 중 입니다.",
"login.id.save": "ID Save",
"login.id.placeholder": "아이디를 입력해주세요.",
"login.password.placeholder": "비밀번호를 입력해주세요.",

View File

@ -1,14 +0,0 @@
import { createI18nServer } from 'next-international/server'
export const { getI18n, getScopedI18n, getCurrentLocale, getStaticParams } = createI18nServer(
{
ko: () => import('./ko'),
ja: () => import('./ja'),
},
{
// Uncomment to use custom segment name
// segmentName: 'locale',
// Uncomment to set fallback locale
// fallbackLocale: en,
},
)

View File

@ -15,12 +15,12 @@ export const settingModalFirstOptionsState = atom({
{ id: 9, column: 'totalDisplay', name: 'modal.canvas.setting.first.option.total', selected: false },
],
dimensionDisplay: [
{ id: 1, column: 'corridorDimension', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false },
{ id: 1, column: 'corridorDimension', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: true },
{ id: 2, column: 'realDimension', name: 'modal.canvas.setting.first.option.real.dimension', selected: false },
{ id: 3, column: 'noneDimension', name: 'modal.canvas.setting.first.option.none.dimension', selected: false },
],
option2: [
{ id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: false },
{ id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: true },
{ id: 2, column: 'lineHatch', name: 'modal.canvas.setting.first.option.line', selected: false },
{ id: 3, column: 'allPainted', name: 'modal.canvas.setting.first.option.all', selected: false },
],
@ -57,3 +57,102 @@ export const settingModalGridOptionsState = atom({
],
dangerouslyAllowMutability: true,
})
// 디스플레이 설정 - 할당 표시
export const allocDisplaySelector = selector({
key: 'allocDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'allocDisplay').selected
},
})
// 디스플레이 설정 - 외벽선 표시
export const outlineDisplaySelector = selector({
key: 'outlineDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'outlineDisplay').selected
},
})
// 디스플레이 설정 - 그리드 표시
export const gridDisplaySelector = selector({
key: 'gridDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'gridDisplay').selected
},
})
// 디스플레이 설정 - 지붕선 표시
export const roofLineDisplaySelector = selector({
key: 'lineDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'lineDisplay').selected
},
})
// 디스플레이 설정 - 문자 표시
export const wordDisplaySelector = selector({
key: 'wordDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'wordDisplay').selected
},
})
// 디스플레이 설정 - 회로번호 표시
export const circuitNumDisplaySelector = selector({
key: 'circuitNumDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'circuitNumDisplay').selected
},
})
// 디스플레이 설정 - 흐름 방향 표시
export const flowDisplaySelector = selector({
key: 'flowDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'flowDisplay').selected
},
})
// 디스플레이 설정 - 가대 표시
export const trestleDisplaySelector = selector({
key: 'trestleDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'trestleDisplay').selected
},
})
// 디스플레이 설정 - 집계표 표시
export const totalDisplaySelector = selector({
key: 'totalDisplaySelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.option1.find((option) => option.column === 'totalDisplay').selected
},
})
// 디스플레이 설정 - 치수 표시
export const corridorDimensionSelector = selector({
key: 'corridorDimensionSelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.dimensionDisplay.find((option) => option.selected)
},
})
// 디스플레이 설정 - 화면 표시
export const realDimensionSelector = selector({
key: 'realDimensionSelector',
get: ({ get }) => {
const settingModalFirstOptions = get(settingModalFirstOptionsState)
return settingModalFirstOptions.dimensionDisplay.find((option) => option.selected)
},
})

View File

@ -1,29 +1,32 @@
// CanvasPage
.canvas-wrap{
height: calc(100vh - 47px);
display: flex;
flex-direction: column;
.canvas-content{
flex: 1 1 auto;
.canvas-layout{
height: 100%;
}
}
&.sub-wrap{
overflow: hidden;
.canvas-content{
height: calc(100% - 47px);
}
}
}
// .canvas-wrap{
// height: calc(100vh - 47px);
// display: flex;
// flex-direction: column;
// .canvas-content{
// flex: 1 1 auto;
// .canvas-layout{
// height: 100%;
// }
// }
// &.sub-wrap{
// overflow: hidden;
// .canvas-content{
// height: calc(100% - 47px);
// }
// }
// }
// CanvasMenu
.canvas-menu-wrap{
position: relative;
position: fixed;
top: 46px;
left: 0;
display: block;
width: 100%;
padding-bottom: 0;
background-color: #383838;
transition: padding .17s ease-in-out;
z-index: 999;
.canvas-menu-inner{
position: relative;
display: flex;
@ -302,12 +305,34 @@
}
// canvas-layout
.canvas-content{
padding-top: 46.8px;
transition: all .17s ease-in-out;
.canvas-frame{
height: 86.3vh;
}
&.active{
padding-top: calc(46.8px + 50px);
.canvas-frame{
height: 81vh;
}
}
}
.canvas-layout{
padding-top: 37px;
.canvas-page-list{
position: fixed;
top: 92.8px;
left: 0;
display: flex;
background-color: #1C1C1C;
border-top: 1px solid #000;
width: 100%;
transition: all .17s ease-in-out;
z-index: 999;
&.active{
top: calc(92.8px + 50px);
}
.canvas-plane-wrap{
display: flex;
align-items: center;
@ -383,9 +408,24 @@
.canvas-frame{
position: relative;
height: calc(100% - 36.5px);
background-color: #fff;
// height: calc(100% - 36.5px);
background-color: #F4F4F7;
overflow: auto;
transition: all .17s ease-in-out;
// &::-webkit-scrollbar {
// width: 10px;
// height: 10px;
// background-color: #fff;
// }
// &::-webkit-scrollbar-thumb {
// background-color: #C1CCD7;
// border-radius: 30px;
// }
// &::-webkit-scrollbar-track {
// background-color: #fff;
// }
canvas{
background-color: #fff;
position: absolute;
top: 0;
left: 0;
@ -514,8 +554,6 @@
&.estimate{
display: flex;
flex-direction: column;
height: calc(100% - 36.5px);
overflow-y: auto;
padding-top: 0;
.sub-content-inner{
flex: 1;
@ -1200,4 +1238,18 @@
background-color: #F4F4F7;
}
}
}
.file-down-nodata{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 148px;
padding: 24px;
border-radius: 4px;
border: 1px solid #E5E5E5;
font-size: 16px;
font-weight: 500;
color: #344356;
}

View File

@ -112,8 +112,8 @@
border-radius: 6px;
background: #FFF;
box-shadow: 0px 3px 30px 0px rgba(0, 0, 0, 0.02);
&.item01{flex: 1; max-height: 400px;}
&.item02{flex: none; width: 451px; max-height: 400px;}
&.item01{flex: 1; height: 400px;}
&.item02{flex: none; width: 451px; height: 400px;}
&.item03{flex: 1;}
&.item04{flex: none; width: 351px;}
&.item05{flex: none; width: 451px;}
@ -566,17 +566,17 @@
transition: background .05s ease-in-out;
}
}
}
input[type=checkbox]:checked + label::before{
border-color: #A8B6C7;
background-color: #A8B6C7;
}
input[type=checkbox]:checked + label::after{
border-color: #fff;
width: 7px;
height: 11px;
top: -2px;
left: 1px;
input[type=checkbox]:checked + label::before{
border-color: #A8B6C7;
background-color: #A8B6C7;
}
input[type=checkbox]:checked + label::after{
border-color: #fff;
width: 7px;
height: 11px;
top: -2px;
left: 1px;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff