diff --git a/egovframe-template-simple-react-contribution/package.json b/egovframe-template-simple-react-contribution/package.json index bd8d7f2..40a1158 100644 --- a/egovframe-template-simple-react-contribution/package.json +++ b/egovframe-template-simple-react-contribution/package.json @@ -6,6 +6,7 @@ "@ant-design/colors": "^6.0.0", "@ant-design/icons": "^4.7.0", "@babel/runtime": "^7.23.9", + "@base2/pretty-print-object": "^1.0.2", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@material-ui/core": "^4.12.4", diff --git a/egovframe-template-simple-react-contribution/src/components/file/AttachFile.jsx b/egovframe-template-simple-react-contribution/src/components/file/AttachFile.jsx new file mode 100644 index 0000000..94e1e21 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/components/file/AttachFile.jsx @@ -0,0 +1,214 @@ +import React, { useState, useEffect } from 'react'; +import AttachFileIcon from '@mui/icons-material/AttachFile'; +import IconButton from '@mui/material/IconButton'; +import DeleteIcon from '@mui/icons-material/Delete'; +import styled from "styled-components"; +import FileDragDrop from "./FileDragDrop"; + +const StyledDiv = styled.div` + label { + //background: red; + width: 100%; + height: auto; + border: 2px dashed #888; + border-radius: 6px; + & > div { + height: 100%; + line-height: 37px; + padding: 20px; + color: #999999; + } + } +`; + + +function AttachFile(props) { + + const multiple = props.multiple ? props.multiple : false; + + // 삭제 버튼 눌렀을 때 파일선택 dialog가 뜨는 것을 방지 + let oldTagName; + useEffect(function () { + + const labelEle = document.querySelectorAll("label[for='preDataFile']")[0]; + console.log(labelEle); // NodeList(3) [li, li, li] + // event + const onClickLabel = (e) => { + + const tagName = String(e.target.tagName).toLowerCase(); + + if( tagName !== 'input' ) { + // eslint-disable-next-line react-hooks/exhaustive-deps + oldTagName = tagName; + e.preventDefault(); + return false; + } else { + if( + oldTagName === 'path' || + oldTagName === 'svg' || + oldTagName === 'button' + ) { + oldTagName = undefined; + e.preventDefault(); + return false; + } + } + + } + // remove Event + labelEle.removeEventListener("click", onClickLabel); + labelEle.addEventListener("click", onClickLabel); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + + //기존 server에 upload된 file인 props.serverFiles file들을 렌더링 초기에 넣어 놓기 + useEffect(function () { + + + if( !props.serverFiles ) { + return; + } + + let items = []; + let nNewIndex = 0; + for( let idx in props.serverFiles ) { + props.serverFiles[idx].index=nNewIndex++; + items.push( props.serverFiles[idx] ); + } + setFileItem(items); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.serverFiles]); + + + + + const [disabled, setDisabled] = useState( props.disabled ? props.disabled : false ); + useEffect(function () { + if( !props.disabled ) { + return; + } + setDisabled(props.disabled); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.disabled]); + + + const [maxSize, setMaxSize] = useState(props.maxSize ? props.maxSize : 100); + useEffect(function () { + if( !props.maxSize ) { + return; + } + setMaxSize(props.maxSize); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.maxSize]); + + + const [fileItem, setFileItem] = useState(); + + const onDrop = (e) => { + //alert('ddd'); + }; + + + const handleChange = (files) => { + + + if( !files ) { + return; + } + + let items = []; + let nNewIndex = 0; + + //파일이 이미 첨부되어 있는 상태에서 추가로 첨부한 경우 기존 것을 먼저 추가 후 새로운 항목을 추가한다. + for( let idx in fileItem ) { + fileItem[idx].index=nNewIndex++; + items.push( fileItem[idx] ); + } + + Object.keys(files).forEach(function(key, index) { + //console.log(key, props.files[key]); + if( typeof files[key].name === 'undefined' ) { + return; + } + files[key].index=nNewIndex++; + items.push( files[key] ); + }); + console.log('%o\n%o', files, items); + setFileItem(items); + props.setFiles(items); + }; + + + const onClickDeleteItem = (e, targetEle) => { + + const dataIndex = Number(targetEle.getAttribute('data-index')); + + let items = []; + let nNewIndex = 0; + Object.keys(fileItem).forEach(function(key, index) { + if( dataIndex !== index ) { + fileItem[key].index=nNewIndex++; + items.push( fileItem[key] ); + } + }); + + setFileItem(items); + props.setFiles(items); + } + + return ( + + +
+ + {fileItem && fileItem.length > 0 + ? + fileItem.map((item) => ( + + { + e = e || window.event; + const target = e.target || e.srcElement; + + console.log('%o', target); + const tagName = String(target.tagName).toLowerCase(); + + // target 보정 + let targetEle = target.parentNode.parentNode.parentNode; + if( tagName === 'svg' ) { + targetEle = target.parentNode.parentNode; + } else if( tagName === 'button' ) { + targetEle = target.parentNode; + } + + onClickDeleteItem(e, targetEle); + }} + > + + + {item.name}
+
+ )) + : + 파일을 마우스로 끌어놓으세요. + } +
+
+
+ ); + +} +export default AttachFile; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx b/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx index bd61604..8fc6842 100644 --- a/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx +++ b/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx @@ -7,17 +7,25 @@ import { FileUploader } from "react-drag-drop-files"; * @param {fileTypes} const fileTypes = ["JPG", "PNG", "GIF"]; * @returns */ -function FileDragDrop({fileTypes, children, multiple, label, onDrop, handleChange, file, setFile, dropMessageStyle, name}) { +function FileDragDrop({fileTypes, children, multiple, label, onDrop, handleChange, file, setFile, dropMessageStyle, name, maxSize, disabled}) { + + const temp = 0; return ( { + e = e || window.event; + }} > {children && children} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx index 8c966c0..0b2e2d4 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/committee/ProgressStatus/Edit.jsx @@ -1,21 +1,13 @@ import React, { useState, useEffect } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import DatePicker from "react-datepicker"; -import AttachFileIcon from '@mui/icons-material/AttachFile'; - - -import FileDragDrop from "components/file/FileDragDrop"; - - - +import AttachFile from "components/file/AttachFile"; import * as EgovNet from 'api/egovFetch'; import URL from 'constants/url'; import CODE from 'constants/code'; import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; -import 'react-datepicker/dist/react-datepicker.css'; - import styled from "styled-components"; import { makeStyles } from "@mui/styles"; @@ -35,15 +27,6 @@ const useStyles = makeStyles(() => ({ })); const StyledDiv = styled.div` - .org-under-id { - margin-left: 20px; - @media only screen and (max-width: 768px) { - display: block; - margin-left: 0px; - margin-top: 20px; - } - } - .f_select.w_250 { @media only screen and (max-width: 768px) { width: 100%; @@ -55,40 +38,17 @@ const StyledDiv = styled.div` width: 100%; } } + + .org-group-id-1 { + margin: 0px 29px; + @media only screen and (max-width: 768px) { + margin: 0px; + } + } `; -function AttachFile(props) { - - const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"]; - const onDrop = (e) => { - //alert('ddd'); - }; - - const handleChange = (file) => { - props.setFile(file); - }; - - return ( - -
- - {props.file ? props.file.name : props.fileName ? props.fileName : "파일을 마우스로 끌어놓으세요."} -
-
- ); - -} - -function SchedulesEdit(props) { +function ProgressStatusEdit(props) { console.group("EgovAdminScheduleEdit"); console.log("[Start] EgovAdminScheduleEdit ------------------------------"); console.log("EgovAdminScheduleEdit [props] : ", props); @@ -117,16 +77,16 @@ function SchedulesEdit(props) { const [requestItems, setRequestItems] = useState ( { + orgGroupId: 1, startDate: new Date(), eventId : 0, } ); - const [schdulBgndeHH, setSchdulBgndeHH] = useState(); - const [schdulBgndeMM, setSchdulBgndeMM] = useState(); + const [drftDatetimeHH, setDrftDatetimeHH] = useState(); + const [drftDatetimeMM, setDrftDatetimeMM] = useState(); const [scheduleInit, setScheduleInit] = useState({}); - const [scheduleApiOrgApiDepthList, setScheduleApiOrgApiDepthList] = useState({ }); const initMode = () => { @@ -152,7 +112,8 @@ function SchedulesEdit(props) { default: navigate({pathname: URL.ERROR}, {state: {msg : ""}}); } - retrieveDetail(); + + getList(orgSearchCondition); } const convertDate = (str) => { @@ -171,36 +132,107 @@ function SchedulesEdit(props) { } } - const retrieveDetail = () => { - EgovNet.requestFetch("/schedule/init", + const [orgSearchCondition, setOrgSearchCondition] = useState({ paramCodeGroup: null, paramCodeLevel: 'LV_01' }); + const [orgArray, setOrgArray] = useState([]); + const [orgSelectedIndex, setOrgSelectedIndex] = useState([]); + + + + + useEffect(function () { + getList(orgSearchCondition); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [orgSearchCondition]); + + + + + + useEffect(function () { + if ( typeof orgArray[0] === 'undefined' || typeof orgSelectedIndex[0] === 'undefined' ) { + return; + } + + if( orgSelectedIndex[0] === 0) { + orgArray[1] = undefined; + orgArray[2] = undefined; + let forChangeObject = [...orgArray]; + setOrgArray(forChangeObject); + setOrgSelectedIndex([orgSelectedIndex[0], undefined, undefined]); + return; + } + + if ( typeof orgArray[0][orgSelectedIndex[0]-1] === 'undefined' ) { + return; + } + + const paramCodeLevel = 'LV_02'; + const paramCodeGroup = orgArray[0][orgSelectedIndex[0]-1].orgId; + setOrgSearchCondition({ paramCodeGroup, paramCodeLevel }); + orgArray[1] = undefined; + orgArray[2] = undefined; + let forChangeObject = [...orgArray]; + setOrgArray(forChangeObject); + setOrgSelectedIndex([orgSelectedIndex[0], undefined, undefined]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [orgSelectedIndex[0]]); + + + + + useEffect(function () { + if ( typeof orgArray[1] === 'undefined' || typeof orgSelectedIndex[1] === 'undefined' ) { + return; + } + + if( orgSelectedIndex[1] === 0) { + orgArray[2] = undefined; + let forChangeObject = [...orgArray]; + setOrgArray(forChangeObject); + setOrgSelectedIndex([orgSelectedIndex[0], orgSelectedIndex[1], undefined]); + return; + } + + if ( typeof orgArray[0][orgSelectedIndex[1]-1] === 'undefined' ) { + return; + } + + const paramCodeLevel = 'LV_03'; + const paramCodeGroup = orgArray[1][orgSelectedIndex[1]-1].orgId; + setOrgSearchCondition({ paramCodeGroup, paramCodeLevel }); + + orgArray[2] = undefined; + let forChangeObject = [...orgArray]; + setOrgArray(forChangeObject); + setOrgSelectedIndex([orgSelectedIndex[0], orgSelectedIndex[1], undefined]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [orgSelectedIndex[1]]); + + + + + useEffect(function () { + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [orgSelectedIndex[2]]); + + + + + const getList = (orgSearchCondition) => { + + EgovNet.requestFetch(`/admin/config/committee-code-management?paramCodeGroup=${orgSearchCondition.paramCodeGroup}¶mCodeLevel=${orgSearchCondition.paramCodeLevel}`, requestOptions, function (resp) { - setScheduleInit( - resp - ); - - if (modeInfo.mode === CODE.MODE_CREATE) { - return; - } - - const retrieveDetailURL = `/schedule/${location.state?.schdulId}`; - const requestOptions = { - method: "GET", - headers: { - 'Content-type': 'application/json' - } - } - EgovNet.requestFetch(retrieveDetailURL, - requestOptions, - function (resp) { - } - ); + const myIndex = Number(String(orgSearchCondition.paramCodeLevel).replace('LV_','')) - 1; + const forCopy = [...orgArray]; + forCopy[myIndex] = resp.result.list; + setOrgArray(forCopy); } - ); - + ); } + const updateSchedule = () => { const formData = new FormData(); @@ -282,47 +314,8 @@ function SchedulesEdit(props) { console.log("------------------------------EgovAdminScheduleEdit [%o]", requestItems); // eslint-disable-next-line react-hooks/exhaustive-deps }, [requestItems]); - - useEffect(function () { - - EgovNet.requestFetch(`/schedule/api/org-api/depth/list?paramCodeGroup=${requestItems.upCommittee}`, - requestOptions, - function (resp) { - setScheduleApiOrgApiDepthList( - resp - ); - } - ); - console.log("------------------------------EgovAdminScheduleEdit [%o]", requestItems); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [requestItems && requestItems.upCommittee]); - - const onClickDeleteSchedule = (schdulId) => { - const deleteBoardURL = `/schedule/${schdulId}`; - - const requestOptions = { - method: "DELETE", - headers: { - 'Content-type': 'application/json', - } - } - - EgovNet.requestFetch(deleteBoardURL, - requestOptions, - (resp) => { - console.log("====>>> Schdule delete= ", resp); - if (Number(resp.resultCode) === Number(CODE.RCV_SUCCESS)) { - alert("게시글이 삭제되었습니다.") - navigate(URL.ADMIN__COMMITTEE__SCHEDULES ,{ replace: true }); - } else { - navigate({pathname: URL.ERROR}, {state: {msg : resp.resultMessage}}); - } - - } - ); - } - + const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"]; //사전검토자료 const [preDataFile, setPreDataFile] = useState(null); const [preDataFileName, setPreDataFileName] = useState(null); @@ -333,11 +326,11 @@ function SchedulesEdit(props) { const [partnerFile, setPartnerFile] = useState(null); const [partnerFileName, setPartnerFileName] = useState(null); //조치계획서 - //const [preDataFile, setPreDataFile] = useState(null); - //const [preDataFileName, setPreDataFileName] = useState(null); + const [actionPlanFile, setActionPlanFile] = useState(null); + const [actionPlanFileName, setActionPlanFileName] = useState(null); //조치결과서 - //const [preDataFile, setPreDataFile] = useState(null); - //const [preDataFileName, setPreDataFileName] = useState(null); + const [actionResultReportFile, setActionResultReportFile] = useState(null); + const [actionResultReportFileName, setActionResultReportFileName] = useState(null); @@ -372,30 +365,30 @@ function SchedulesEdit(props) { {/* */}
-
필수
+
필수
- setRequestItems({ ...requestItems, title: e.target.value })} />
-
필수
+
필수
- setRequestItems({ ...requestItems, title: e.target.value })} + setRequestItems({ ...requestItems, categoryId: e.target.value })} />
-
필수
+
필수
-
-
필수
+
필수
{ - console.log("setStartDate : ", date); - setRequestItems({ ...requestItems, schdulBgnde: getDateFourteenDigit(date), schdulBgndeYYYMMDD: getYYYYMMDD(date), schdulBgndeHH: date.getHours(), schdulBgndeMM: date.getMinutes(), startDate: date }); - setSchdulBgndeHH(date.getHours()); - setSchdulBgndeMM(date.getMinutes()); + setRequestItems({ ...requestItems, schdulBgnde: getDateFourteenDigit(date), drftDatetimeYYYMMDD: getYYYYMMDD(date), drftDatetime: date }); + setDrftDatetimeHH(date.getHours()); + setDrftDatetimeMM(date.getMinutes()); }} /> - - +
-
필수
+
필수
{/** top org */} @@ -468,81 +471,57 @@ function SchedulesEdit(props) {
필수
- -
+ +
필수
-
+
+
필수
-
+
+
필수
-
+
+
-
필수
+
필수
+
-
필수
+
필수
- setRequestItems({ ...requestItems, title: e.target.value })} + setRequestItems({ ...requestItems, drftConfeCharger: e.target.value })} />
-
필수
+
필수
- setRequestItems({ ...requestItems, title: e.target.value })} + setRequestItems({ ...requestItems, drftConfePw: e.target.value })} />
-
필수
+
필수
- setRequestItems({ ...requestItems, title: e.target.value })} - /> -
-
- - -
-
필수
-
- setRequestItems({ ...requestItems, title: e.target.value })} - /> -
-
-
-
필수
-
- setRequestItems({ ...requestItems, location: e.target.value })} /> -
-
-
-
필수
-
-
@@ -552,13 +531,7 @@ function SchedulesEdit(props) {
- {modeInfo.mode === CODE.MODE_MODIFY && - - } + > 저장
@@ -578,4 +551,4 @@ function SchedulesEdit(props) { ); } -export default SchedulesEdit; \ No newline at end of file +export default ProgressStatusEdit; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx index b75acda..efb1d77 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx @@ -1,10 +1,7 @@ import React, { useState, useEffect } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import DatePicker from "react-datepicker"; -import FileDragDrop from "../../../../components/file/FileDragDrop"; -import AttachFileIcon from '@mui/icons-material/AttachFile'; - -import EgovAttachFile from 'components/EgovAttachFile'; +import AttachFile from "../../../../components/file/AttachFile"; import RichTextEditor from "../../../../components/editor/RichTextEditor"; import AlertDialogSlide from "../../../../components/alert/AlertDialogSlide"; import CODE from 'constants/code'; @@ -59,7 +56,7 @@ function PopupEditor(props) { const [schdulBgndeMM, setSchdulBgndeMM] = useState(); const [schdulEnddeHH, setSchdulEnddeHH] = useState(); const [schdulEnddeMM, setSchdulEnddeMM] = useState(); - const [fileName, setFileName] = useState(); + const [confirm, setConfirm] = React.useState(); @@ -140,11 +137,11 @@ function PopupEditor(props) { setText(rawDetail.contents); setTextOriginal(rawDetail.contents); - if( rawDetail.fileName ) { - setFileName(rawDetail.fileName); + if( rawDetail.files ) { + setServerFiles(rawDetail.files); } } - ); + ); } @@ -167,7 +164,14 @@ function PopupEditor(props) { formData.append("contents", text); //첨부파일 - formData.append("file", file); + //formData.append("files", files); + for(let i=0; i { - //alert('ddd'); - }; - const [file, setFile] = useState(null); - const handleChange = (file) => { - setFile(file); + const [serverFiles, setServerFiles] = useState(); + const [files, setFiles] = useState(); + /* + let files = null; + const setFiles = (myFiles) => { + files = myFiles; }; - - - useEffect(function () { - if( file ) { - console.log('%o', file); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [file]); + */ const Location = React.memo(function Location() { @@ -367,21 +364,7 @@ function PopupEditor(props) {
첨부파일
- - -
- - {file ? file.name : fileName ? fileName : "파일을 마우스로 끌어놓으세요."} -
-
-
+
diff --git a/egovframe-template-simple-react-contribution/yarn.lock b/egovframe-template-simple-react-contribution/yarn.lock index b9950ec..6edd4bf 100644 --- a/egovframe-template-simple-react-contribution/yarn.lock +++ b/egovframe-template-simple-react-contribution/yarn.lock @@ -1135,6 +1135,11 @@ resolved "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz" integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== +"@base2/pretty-print-object@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.2.tgz#e30192222fd13e3c1e97040163d6628a95f70844" + integrity sha512-rBha0UDfV7EmBRjWrGG7Cpwxg8WomPlo0q+R2so47ZFf9wy4YKJzLuHcVa0UGFjdcLZj/4F/1FNC46GIQhe7sA== + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" @@ -8623,7 +8628,7 @@ react-drag-drop-files@^2.3.10: react-element-to-jsx-string@^15.0.0: version "15.0.0" - resolved "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz#1cafd5b6ad41946ffc8755e254da3fc752a01ac6" integrity sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ== dependencies: "@base2/pretty-print-object" "1.0.1"