parent
3075d39606
commit
72e996193a
|
|
@ -1,9 +1,11 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import Button from '@mui/material/Button';
|
||||
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";
|
||||
import * as File from "utils/file";
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
label {
|
||||
|
|
@ -14,7 +16,7 @@ const StyledDiv = styled.div`
|
|||
border-radius: 6px;
|
||||
& > div {
|
||||
height: 100%;
|
||||
line-height: 37px;
|
||||
line-height: auto;
|
||||
padding: 20px;
|
||||
color: #999999;
|
||||
}
|
||||
|
|
@ -31,7 +33,6 @@ function AttachFile(props) {
|
|||
useEffect(function () {
|
||||
|
||||
const labelEle = document.querySelectorAll("label[for='preDataFile']")[0];
|
||||
console.log(labelEle); // NodeList(3) [li, li, li]
|
||||
// event
|
||||
const onClickLabel = (e) => {
|
||||
|
||||
|
|
@ -43,15 +44,16 @@ function AttachFile(props) {
|
|||
e.preventDefault();
|
||||
return false;
|
||||
} else {
|
||||
|
||||
if(
|
||||
oldTagName === 'path' ||
|
||||
oldTagName === 'svg' ||
|
||||
oldTagName === 'button'
|
||||
) {
|
||||
oldTagName = undefined;
|
||||
e.preventDefault();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -129,14 +131,12 @@ function AttachFile(props) {
|
|||
}
|
||||
|
||||
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);
|
||||
};
|
||||
|
|
@ -144,6 +144,7 @@ function AttachFile(props) {
|
|||
|
||||
const onClickDeleteItem = (e, targetEle) => {
|
||||
|
||||
|
||||
const dataIndex = Number(targetEle.getAttribute('data-index'));
|
||||
|
||||
let items = [];
|
||||
|
|
@ -157,7 +158,39 @@ function AttachFile(props) {
|
|||
|
||||
setFileItem(items);
|
||||
props.setFiles(items);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickFile = (e, item) => {
|
||||
e = e || window.event;
|
||||
const target = e.target || e.srcElement;
|
||||
const dataSeq = target.getAttribute('data-seq');
|
||||
if( dataSeq ) {
|
||||
// server로 부터 download 요청
|
||||
const fileSeq = Number(dataSeq);
|
||||
File.download(fileSeq);
|
||||
} else {
|
||||
//현재 첨부된 file 다운로드
|
||||
const file = item;
|
||||
let fr = new FileReader();
|
||||
fr.readAsDataURL(file);
|
||||
|
||||
var blob = new Blob([file], { type: "application/pdf" });
|
||||
|
||||
var objectURL = window.URL.createObjectURL(blob);
|
||||
|
||||
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
|
||||
window.navigator.msSaveOrOpenBlob(blob, item.name);
|
||||
} else {
|
||||
var link = document.createElement('a');
|
||||
link.href = objectURL;
|
||||
link.download = item.name;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledDiv>
|
||||
|
|
@ -179,11 +212,11 @@ function AttachFile(props) {
|
|||
fileItem.map((item) => (
|
||||
<span key={item.index} data-index={item.index}>
|
||||
<IconButton aria-label="delete" size="small"
|
||||
sx={{color: '#094c72', padding: '2px 4px'}}
|
||||
onClick={(e)=> {
|
||||
e = e || window.event;
|
||||
const target = e.target || e.srcElement;
|
||||
|
||||
console.log('%o', target);
|
||||
|
||||
const tagName = String(target.tagName).toLowerCase();
|
||||
|
||||
// target 보정
|
||||
|
|
@ -199,11 +232,20 @@ function AttachFile(props) {
|
|||
>
|
||||
<DeleteIcon fontSize="small" />
|
||||
</IconButton>
|
||||
{item.name}<br />
|
||||
<Button
|
||||
variant="text"
|
||||
sx={{textTransform: 'none', color: '#032b77', fontSize: '14px', padding: '2px 5px 4px 5px'}}
|
||||
onClick={(e)=> {
|
||||
onClickFile(e, item);
|
||||
}}
|
||||
key={item.index}
|
||||
data-seq={item.seq}
|
||||
>{item.name}</Button>
|
||||
<br />
|
||||
</span>
|
||||
))
|
||||
:
|
||||
<span><AttachFileIcon /> 파일을 마우스로 끌어놓으세요.</span>
|
||||
<span>여기를 누르시거나 파일을 마우스로 끌어놓으세요.</span>
|
||||
}
|
||||
</div>
|
||||
</FileDragDrop>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import React, { useState, useEffect, useCallback } from 'react';
|
|||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
import styled from "styled-components";
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
|
||||
import * as EgovNet from 'api/egovFetch';
|
||||
|
|
@ -62,7 +64,7 @@ function Schedules(props) {
|
|||
const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { schdulSe: '', year: TODAY.getFullYear(), month: TODAY.getMonth(), date: TODAY.getDate() });
|
||||
const [calendarTag, setCalendarTag] = useState([]);
|
||||
|
||||
const [scheduleList, setScheduleList] = useState([]);
|
||||
const [scheduleList, setScheduleList] = useState();
|
||||
|
||||
const innerConsole = (...args) => {
|
||||
console.log(...args);
|
||||
|
|
@ -189,7 +191,7 @@ function Schedules(props) {
|
|||
if (day !== 0) {//당월 일별 구현
|
||||
let sDate = day.toString().length === 1 ? "0" + day.toString() : day.toString();
|
||||
let iUseDate = Number(mutsUseYearMonth + sDate);
|
||||
if (scheduleList.length > 0) {//일정 있는 경우
|
||||
if (scheduleList && scheduleList.length > 0) {//일정 있는 경우
|
||||
return (
|
||||
<td key={keyIdx++}>
|
||||
<Link to={{pathname: URL.ADMIN__COMMITTEE__SCHEDULES__CREATE}} state={{ iUseDate: mutsUseYearMonth + sDate + "000000"}} className="day"
|
||||
|
|
@ -346,10 +348,24 @@ function Schedules(props) {
|
|||
<th>금</th>
|
||||
<th>토</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{true && calendarTag}
|
||||
</tbody>
|
||||
</thead>
|
||||
{
|
||||
typeof scheduleList === 'undefined'
|
||||
?
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="7">
|
||||
<Box sx={{ display: 'flex', width: '100%', padding: '250px 0px' }}>
|
||||
<CircularProgress sx={{ margin: '0px auto', }}/>
|
||||
</Box>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
:
|
||||
<tbody>
|
||||
{calendarTag}
|
||||
</tbody>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
</StyledDiv>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
|
||||
import * as EgovNet from 'api/egovFetch';
|
||||
import URL from 'constants/url';
|
||||
|
|
@ -54,7 +55,7 @@ function PopUp(props) {
|
|||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [listPopup, setListPopup] = useState([]);
|
||||
const [listPopup, setListPopup] = useState();
|
||||
const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });
|
||||
const [paginationInfo, setPaginationInfo] = useState({});
|
||||
|
||||
|
|
@ -152,10 +153,13 @@ function PopUp(props) {
|
|||
</div>
|
||||
<div className="result">
|
||||
{/* <!-- case : 데이터 없을때 --> */}
|
||||
{listPopup.length === 0 &&
|
||||
{typeof listPopup === 'undefined' &&
|
||||
<p className="no_data" key="0"><LinearProgress /></p>
|
||||
}
|
||||
{listPopup && listPopup.length === 0 &&
|
||||
<p className="no_data" key="0">검색된 결과가 없습니다.</p>
|
||||
}
|
||||
{listPopup.map((it)=>(
|
||||
{listPopup && listPopup.map((it)=>(
|
||||
<div className='list_item' key={it.seq}>
|
||||
<div>{it.number}</div>
|
||||
<div className="al"><Link to={URL.ADMIN__CONTENTS__POP_UP__MODIFY} state={{popupId: it.seq} } key={it.seq}>{it.popupTitle}</Link></div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import DatePicker from "react-datepicker";
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
import AttachFile from "../../../../components/file/AttachFile";
|
||||
import RichTextEditor from "../../../../components/editor/RichTextEditor";
|
||||
import AlertDialogSlide from "../../../../components/alert/AlertDialogSlide";
|
||||
|
|
@ -164,15 +165,17 @@ function PopupEditor(props) {
|
|||
formData.append("contents", text);
|
||||
|
||||
//첨부파일
|
||||
//formData.append("files", files);
|
||||
for(let i=0; i<files.length; i++) {
|
||||
// seq 항목을 가지고 있다면 그건 server에 이미 upload된 file이므로 continue
|
||||
if( files[i].seq ) {
|
||||
continue;
|
||||
}
|
||||
formData.append("files", files[i]);
|
||||
if( files ) {
|
||||
for(let i=0; i<files.length; i++) {
|
||||
if( files[i].seq ) {
|
||||
// 살아남은 file의 seq 목록 서버로 보내면 서버가 알아서 기존파일을 정리해준다.
|
||||
formData.append("survivingFiles", files[i].seq);
|
||||
continue;
|
||||
}
|
||||
formData.append("files", files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (formValidator(formData)) {
|
||||
const requestOptions = {
|
||||
method: modeInfo.method,
|
||||
|
|
@ -207,7 +210,7 @@ function PopupEditor(props) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const onClickDelete = (popupId) => {
|
||||
const deleteBoardURL = `/contents/api/popup-manage/${popupId}`;
|
||||
|
||||
|
|
@ -235,6 +238,27 @@ function PopupEditor(props) {
|
|||
setConfirm({...confirm, open: true, body: "삭제하시겠습니까?", yesCallback: requestTask});
|
||||
}
|
||||
|
||||
|
||||
// 첨부된 file을 삭제하는 요청
|
||||
const deleteFile = (fileSeq) => {
|
||||
const deleteFileURL = `/contents/api/popup-manage/file/${fileSeq}`;
|
||||
|
||||
const requestOptions = {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
}
|
||||
}
|
||||
|
||||
EgovNet.requestFetch(deleteFileURL,
|
||||
requestOptions,
|
||||
(resp) => {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const onClickList = (e) => {
|
||||
|
||||
const requestTask = () => {
|
||||
|
|
@ -315,6 +339,7 @@ function PopupEditor(props) {
|
|||
<dl>
|
||||
<dt><label htmlFor="title">제목</label><span className="req">필수</span></dt>
|
||||
<dd>
|
||||
{modeInfo.mode === CODE.MODE_MODIFY && typeof popupDetail.title === 'undefined' && <LinearProgress /> }
|
||||
<input className="f_input2 w_full" type="text" name="title" title="제목" id="title" placeholder="제목을 입력하세요."
|
||||
value={popupDetail.title}
|
||||
onChange={(e) => setPopupDetail({ ...popupDetail, title: e.target.value })}
|
||||
|
|
@ -364,7 +389,7 @@ function PopupEditor(props) {
|
|||
<dl className="file-attach-wrapper">
|
||||
<dt>첨부파일</dt>
|
||||
<dd>
|
||||
<AttachFile name="preDataFile" multiple={true} files={files} setFiles={setFiles} serverFiles={serverFiles} fileTypes={fileTypes} />
|
||||
<AttachFile name="preDataFile" multiple={true} files={files} setFiles={setFiles} serverFiles={serverFiles} fileTypes={fileTypes} deleteFile={deleteFile} />
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
|
@ -372,7 +397,13 @@ function PopupEditor(props) {
|
|||
{/* <!--// 상단 입력 form --> */}
|
||||
|
||||
{/* <!-- 게시판 --> */}
|
||||
<RichTextEditor item={text} setText={setText}/>
|
||||
{modeInfo.mode === CODE.MODE_MODIFY && typeof text === 'undefined'
|
||||
?
|
||||
<LinearProgress />
|
||||
:
|
||||
<RichTextEditor item={text} setText={setText}/>
|
||||
}
|
||||
|
||||
{/* <!--// 게시판 --> */}
|
||||
|
||||
{/* <!-- 버튼영역 --> */}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
|
||||
import * as EgovNet from 'api/egovFetch';
|
||||
import URL from 'constants/url';
|
||||
|
|
@ -67,7 +67,7 @@ function StandardResearch(props) {
|
|||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [list, setList] = useState([]);
|
||||
const [list, setList] = useState();
|
||||
const [searchCondition, setSearchCondition] = useState(location.state?.searchCondition || { pageIndex: 1, searchCnd: '0', searchWrd: '' });
|
||||
const [paginationInfo, setPaginationInfo] = useState({});
|
||||
|
||||
|
|
@ -167,10 +167,13 @@ function StandardResearch(props) {
|
|||
</div>
|
||||
<div className="result">
|
||||
{/* <!-- case : 데이터 없을때 --> */}
|
||||
{list.length === 0 &&
|
||||
{typeof list === 'undefined' &&
|
||||
<p className="no_data" key="0"><LinearProgress /></p>
|
||||
}
|
||||
{list && list.length === 0 &&
|
||||
<p className="no_data" key="0">검색된 결과가 없습니다.</p>
|
||||
}
|
||||
{list.map((it)=>(
|
||||
{list && list.map((it)=>(
|
||||
<div className='list_item' key={it.id}>
|
||||
<div>{it.number}</div>
|
||||
<div className="al"><Link to={URL.ADMIN__CONTENTS__STANDARDS_RESEARCH__MODIFY} state={{rsId: it.id} } key={it.id}>{it.title}</Link></div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import DatePicker from "react-datepicker";
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
|
||||
import EgovAttachFile from 'components/EgovAttachFile';
|
||||
import RichTextEditor from "../../../../components/editor/RichTextEditor";
|
||||
|
|
@ -45,12 +46,12 @@ function StandardResearchEditor(props) {
|
|||
const location = useLocation();
|
||||
|
||||
const [modeInfo, setModeInfo] = useState({ mode: props.mode });
|
||||
const [purpose, setPurpose] = useState("");
|
||||
const [purposeOriginal, setPurposeOriginal] = useState("");
|
||||
const [purpose, setPurpose] = useState();
|
||||
const [purposeOriginal, setPurposeOriginal] = useState();
|
||||
const [content, setContent] = useState("");
|
||||
const [contentOriginal, setContentOriginal] = useState("");
|
||||
const [contentOriginal, setContentOriginal] = useState();
|
||||
const [effectContent, setEffectContent] = useState("");
|
||||
const [effectContentOriginal, setEffectContentOriginal] = useState("");
|
||||
const [effectContentOriginal, setEffectContentOriginal] = useState();
|
||||
|
||||
|
||||
|
||||
|
|
@ -319,6 +320,7 @@ function StandardResearchEditor(props) {
|
|||
<dl>
|
||||
<dt><label htmlFor="title">연구명</label><span className="req">필수</span></dt>
|
||||
<dd>
|
||||
{modeInfo.mode === CODE.MODE_MODIFY && typeof standardResearchDetail.title === 'undefined' && <LinearProgress /> }
|
||||
<input className="f_input2 w_full" type="text" name="title" title="연구명" id="title" placeholder="연구명을 입력하세요."
|
||||
value={standardResearchDetail.title}
|
||||
onChange={(e) => setStandardResearchDetail({ ...standardResearchDetail, title: e.target.value })}
|
||||
|
|
@ -358,6 +360,7 @@ function StandardResearchEditor(props) {
|
|||
<dl>
|
||||
<dt><label htmlFor="director">연구 책임자</label><span className="req">필수</span></dt>
|
||||
<dd>
|
||||
{modeInfo.mode === CODE.MODE_MODIFY && typeof standardResearchDetail.director === 'undefined' && <LinearProgress /> }
|
||||
<input className="f_input2 w_full" type="text" name="director" title="연구 책임자" id="director" placeholder="연구 책임자를 입력하세요."
|
||||
value={standardResearchDetail.director}
|
||||
onChange={(e) => setStandardResearchDetail({ ...standardResearchDetail, director: e.target.value })}
|
||||
|
|
@ -369,13 +372,34 @@ function StandardResearchEditor(props) {
|
|||
|
||||
{/* <!-- 게시판 --> */}
|
||||
<label className="label-text-editor">연구 목적<span className="req">필수</span></label>
|
||||
<RichTextEditor item={purpose} setText={setPurpose}/>
|
||||
{
|
||||
modeInfo.mode === CODE.MODE_MODIFY && typeof purpose === 'undefined'
|
||||
?
|
||||
<LinearProgress />
|
||||
:
|
||||
<RichTextEditor item={purpose} setText={setPurpose}/>
|
||||
}
|
||||
|
||||
|
||||
<label className="label-text-editor">연구 내용<span className="req">필수</span></label>
|
||||
<RichTextEditor item={content} setText={setContent}/>
|
||||
{
|
||||
modeInfo.mode === CODE.MODE_MODIFY && typeof content === 'undefined'
|
||||
?
|
||||
<LinearProgress />
|
||||
:
|
||||
<RichTextEditor item={content} setText={setContent}/>
|
||||
}
|
||||
|
||||
|
||||
<label className="label-text-editor">기대 효과<span className="req">필수</span></label>
|
||||
<RichTextEditor item={effectContent} setText={setEffectContent}/>
|
||||
{
|
||||
modeInfo.mode === CODE.MODE_MODIFY && typeof effectContent === 'undefined'
|
||||
?
|
||||
<LinearProgress />
|
||||
:
|
||||
<RichTextEditor item={effectContent} setText={setEffectContent}/>
|
||||
}
|
||||
|
||||
{/* <!--// 게시판 --> */}
|
||||
|
||||
{/* <!-- 버튼영역 --> */}
|
||||
|
|
|
|||
Loading…
Reference in New Issue