2024-03-18 01:41:54 +00:00
|
|
|
import React, { useState, useEffect } from 'react';
|
2024-03-18 08:42:25 +00:00
|
|
|
import Button from '@mui/material/Button';
|
2024-03-18 01:41:54 +00:00
|
|
|
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";
|
2024-03-18 08:42:25 +00:00
|
|
|
import * as File from "utils/file";
|
2024-03-18 01:41:54 +00:00
|
|
|
|
|
|
|
|
const StyledDiv = styled.div`
|
|
|
|
|
label {
|
|
|
|
|
//background: red;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: auto;
|
|
|
|
|
border: 2px dashed #888;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
& > div {
|
|
|
|
|
height: 100%;
|
2024-03-18 08:42:25 +00:00
|
|
|
line-height: auto;
|
2024-03-18 01:41:54 +00:00
|
|
|
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];
|
|
|
|
|
// 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 {
|
2024-03-18 08:42:25 +00:00
|
|
|
|
2024-03-18 01:41:54 +00:00
|
|
|
if(
|
|
|
|
|
oldTagName === 'path' ||
|
|
|
|
|
oldTagName === 'svg' ||
|
|
|
|
|
oldTagName === 'button'
|
|
|
|
|
) {
|
|
|
|
|
oldTagName = undefined;
|
2024-03-18 08:42:25 +00:00
|
|
|
e.preventDefault();
|
2024-03-18 01:41:54 +00:00
|
|
|
return false;
|
2024-03-18 08:42:25 +00:00
|
|
|
}
|
2024-03-18 01:41:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// 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) {
|
|
|
|
|
if( typeof files[key].name === 'undefined' ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
files[key].index=nNewIndex++;
|
|
|
|
|
items.push( files[key] );
|
|
|
|
|
});
|
|
|
|
|
setFileItem(items);
|
|
|
|
|
props.setFiles(items);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onClickDeleteItem = (e, targetEle) => {
|
|
|
|
|
|
2024-03-18 08:42:25 +00:00
|
|
|
|
2024-03-18 01:41:54 +00:00
|
|
|
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);
|
2024-03-18 08:42:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
2024-03-18 01:41:54 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<StyledDiv>
|
|
|
|
|
<FileDragDrop
|
|
|
|
|
className="file-drag-drop"
|
|
|
|
|
multiple={multiple}
|
|
|
|
|
name={props.name}
|
|
|
|
|
fileTypes={props.fileTypes}
|
|
|
|
|
onDrop={onDrop}
|
|
|
|
|
handleChange={handleChange}
|
|
|
|
|
dropMessageStyle={{backgroundColor: '#cfe2ff'}}
|
|
|
|
|
maxSize={maxSize}
|
|
|
|
|
disabled={disabled}
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
|
|
{fileItem && fileItem.length > 0
|
|
|
|
|
?
|
|
|
|
|
fileItem.map((item) => (
|
|
|
|
|
<span key={item.index} data-index={item.index}>
|
|
|
|
|
<IconButton aria-label="delete" size="small"
|
2024-03-18 08:42:25 +00:00
|
|
|
sx={{color: '#094c72', padding: '2px 4px'}}
|
2024-03-18 01:41:54 +00:00
|
|
|
onClick={(e)=> {
|
|
|
|
|
e = e || window.event;
|
|
|
|
|
const target = e.target || e.srcElement;
|
2024-03-18 08:42:25 +00:00
|
|
|
|
2024-03-18 01:41:54 +00:00
|
|
|
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);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<DeleteIcon fontSize="small" />
|
|
|
|
|
</IconButton>
|
2024-03-18 08:42:25 +00:00
|
|
|
<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 />
|
2024-03-18 01:41:54 +00:00
|
|
|
</span>
|
|
|
|
|
))
|
|
|
|
|
:
|
2024-03-18 08:42:25 +00:00
|
|
|
<span>여기를 누르시거나 파일을 마우스로 끌어놓으세요.</span>
|
2024-03-18 01:41:54 +00:00
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</FileDragDrop>
|
|
|
|
|
</StyledDiv>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
export default AttachFile;
|