Wahyu Ramadhan
2 years ago
6 changed files with 420 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,397 @@ |
|||||||
|
import React, { useState, useEffect, useMemo } from 'react'; |
||||||
|
import axios from "../../../../const/interceptorApi" |
||||||
|
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||||
|
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||||
|
import { Button, Table, Form, Upload, Tooltip, Alert, Spin } from 'antd'; |
||||||
|
import { InboxOutlined, UploadOutlined } from '@ant-design/icons'; |
||||||
|
import {OutTable, ExcelRenderer} from 'react-excel-renderer'; |
||||||
|
import './table.css'; |
||||||
|
import { BASE_OSPRO } from '../../../../const/ApiConst'; |
||||||
|
import { Prompt } from 'react-router-dom'; |
||||||
|
//
|
||||||
|
const config = { |
||||||
|
headers: |
||||||
|
{ |
||||||
|
Authorization: `Bearer ${token}`, |
||||||
|
"Content-type": `application/json` |
||||||
|
} |
||||||
|
}; |
||||||
|
//const token = window.localStorage.getItem('token');
|
||||||
|
const token = localStorage.getItem("token"); |
||||||
|
const HEADER = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
Authorization: `Bearer ${token}`, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
const normFile = (e) => { |
||||||
|
if (Array.isArray(e)) { |
||||||
|
return e; |
||||||
|
} |
||||||
|
|
||||||
|
return e?.fileList; |
||||||
|
}; |
||||||
|
|
||||||
|
const formItemLayout = { |
||||||
|
labelCol: { |
||||||
|
span: 6, |
||||||
|
}, |
||||||
|
wrapperCol: { |
||||||
|
span: 14, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
const errorHandler = { |
||||||
|
// error notif
|
||||||
|
// reload table
|
||||||
|
// reload upload
|
||||||
|
}; |
||||||
|
|
||||||
|
const columnToIndexs = { |
||||||
|
columnName: 'index', |
||||||
|
level: 0, |
||||||
|
predecessor: 1, |
||||||
|
no: 2, |
||||||
|
name: 3, |
||||||
|
weight: 4, |
||||||
|
start_date: 5, |
||||||
|
end_date: 6, |
||||||
|
picKit: 7, |
||||||
|
picOwner: 8, |
||||||
|
duration: 9 |
||||||
|
} |
||||||
|
|
||||||
|
const ExcelDateToJSDate = (date) => { |
||||||
|
let converted_date = new Date(Math.round((date - 25569) * 864e5)); |
||||||
|
converted_date = String(converted_date).slice(4, 15) |
||||||
|
date = converted_date.split(" ") |
||||||
|
let day = date[1]; |
||||||
|
let month = date[0]; |
||||||
|
month = "JanFebMarAprMayJunJulAugSepOctNovDec".indexOf(month) / 3 + 1 |
||||||
|
if (month.toString().length <= 1) |
||||||
|
month = '0' + month |
||||||
|
let year = date[2]; |
||||||
|
return String(day + '-' + month + '-' + year.slice(2, 4)) |
||||||
|
} |
||||||
|
|
||||||
|
const ImportActivity = ({ params }) => { |
||||||
|
const pageName = params.name; |
||||||
|
|
||||||
|
const [dataTable, setDatatable] = useState([]) |
||||||
|
//
|
||||||
|
const [isMovePage, setIsMovePage] = useState(false); |
||||||
|
const [isPreview, setIsPreview] = useState(false); |
||||||
|
|
||||||
|
const fileHandler = (file) => { |
||||||
|
setIsMovePage(true); |
||||||
|
if(file.name.slice(file.name.lastIndexOf('.')+1) === "xlsx"){ |
||||||
|
// NotificationManager.info('Loading...',' ');
|
||||||
|
setTimeout(() => {
|
||||||
|
previewHandler(file); |
||||||
|
setIsMovePage(false); |
||||||
|
}, 5000); |
||||||
|
} else { |
||||||
|
NotificationManager.error('file harus dalam format .xlsx', 'Failed'); |
||||||
|
} |
||||||
|
// else{
|
||||||
|
// errorHandler()
|
||||||
|
// }
|
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
const previewHandler = (fileObj) => { |
||||||
|
let dataMapped = [] |
||||||
|
|
||||||
|
ExcelRenderer(fileObj, (err, resp) => { |
||||||
|
if(err){ |
||||||
|
console.log(err) |
||||||
|
errorHandler() |
||||||
|
} else { |
||||||
|
// let columns = resp.cols
|
||||||
|
let rawRows = resp.rows |
||||||
|
|
||||||
|
let rows = rawRows.filter(function (el) { |
||||||
|
return el.length > 0; |
||||||
|
}); |
||||||
|
|
||||||
|
for(let i = 5; i < rows.length; i++){ |
||||||
|
let extractedRow = {} |
||||||
|
|
||||||
|
for (var prop in columnToIndexs) { |
||||||
|
if (columnToIndexs.hasOwnProperty.call(columnToIndexs, prop)) { |
||||||
|
let columnData = rows[i][columnToIndexs[prop]] |
||||||
|
|
||||||
|
// remove leading whitespace
|
||||||
|
if(typeof(columnData) == 'string') { |
||||||
|
columnData = columnData.trim().replace(/ /g, '').replace(/<[^\/>][^>]*><\/[^>]+>/g, "") |
||||||
|
} |
||||||
|
|
||||||
|
// convert excel's DATEVALUE
|
||||||
|
if(["start_date", "end_date"].includes(prop)){ |
||||||
|
columnData = ExcelDateToJSDate(columnData) |
||||||
|
} |
||||||
|
|
||||||
|
if(prop == 'weight'){ |
||||||
|
columnData = Math.round(columnData * 100) |
||||||
|
} |
||||||
|
|
||||||
|
extractedRow[prop] = columnData |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
dataMapped.push(extractedRow) |
||||||
|
} |
||||||
|
|
||||||
|
setDatatable(dataMapped) |
||||||
|
setIsPreview(true) |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
const saveHandler = async (e) => { |
||||||
|
setIsMovePage(true); |
||||||
|
|
||||||
|
let url = window.location.href; |
||||||
|
let urlSplitted = url.split('/') |
||||||
|
const ganttId = urlSplitted[5] |
||||||
|
|
||||||
|
const URL = `${BASE_OSPRO}/api/activity/import` |
||||||
|
|
||||||
|
let payload = { |
||||||
|
ganttId: ganttId, |
||||||
|
activities: dataTable |
||||||
|
} |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(URL, payload, HEADER) |
||||||
|
.then((res) => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
console.log(result) |
||||||
|
if (result.data.code == 200) { |
||||||
|
window.location = urlSplitted[0] + '//' + urlSplitted[2] + `/#/projects/` + ganttId + '/' + result.data.projectId + '/gantt' |
||||||
|
} |
||||||
|
|
||||||
|
setIsMovePage(true); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{ |
||||||
|
title: 'No', |
||||||
|
dataIndex: 'no', |
||||||
|
key: 'no', |
||||||
|
width: '5%', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Level', |
||||||
|
dataIndex: 'level', |
||||||
|
key: 'level', |
||||||
|
width: '10%', |
||||||
|
align: 'center', |
||||||
|
|
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Predecessor', |
||||||
|
dataIndex: 'predecessor', |
||||||
|
key: 'predecessor', |
||||||
|
align: 'center', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Name', |
||||||
|
dataIndex: 'name', |
||||||
|
key: 'name', |
||||||
|
render: (text, record) => { |
||||||
|
let prepend = "" |
||||||
|
for(let i = 1; i < record.level; i++) { |
||||||
|
prepend = prepend + "--" |
||||||
|
} |
||||||
|
|
||||||
|
return <Tooltip title={text}><span> {prepend} {text}</span></Tooltip> |
||||||
|
}, |
||||||
|
ellipsis: true, |
||||||
|
width: '25%', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Weight', |
||||||
|
dataIndex: 'weight', |
||||||
|
key: 'weight', |
||||||
|
render: (text, record) => { |
||||||
|
return <span>{text}%</span> |
||||||
|
}, |
||||||
|
width: '10%', |
||||||
|
align: 'center', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Start Date', |
||||||
|
dataIndex: 'start_date', |
||||||
|
key: 'start_date', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Finish Date', |
||||||
|
dataIndex: 'end_date', |
||||||
|
key: 'end_date', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'Duration', |
||||||
|
dataIndex: 'duration', |
||||||
|
key: 'duration', |
||||||
|
align: 'right', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'PIC KIT', |
||||||
|
dataIndex: 'picKit', |
||||||
|
key: 'picKit', |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: 'PIC Owner', |
||||||
|
dataIndex: 'picOwner', |
||||||
|
key: 'picOwner', |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
if (isMovePage) { |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<NotificationContainer /> |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col span={22}> |
||||||
|
<Form |
||||||
|
name="import_preview" |
||||||
|
{...formItemLayout} |
||||||
|
> |
||||||
|
<Form.Item |
||||||
|
name="upload" |
||||||
|
valuePropName="fileList" |
||||||
|
getValueFromEvent={normFile} |
||||||
|
extra="" |
||||||
|
> |
||||||
|
<Button |
||||||
|
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||||
|
href={"/template/template_activity.xlsx"} |
||||||
|
> |
||||||
|
<i className="fa fa-print" style={{ marginRight: "5px" }}></i> Download Template |
||||||
|
</Button> |
||||||
|
<Tooltip title="Format file .xlsx"> |
||||||
|
<Upload |
||||||
|
name="template" |
||||||
|
listType="text" |
||||||
|
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
||||||
|
maxCount={1} |
||||||
|
beforeUpload={(file)=> fileHandler(file)} |
||||||
|
showUploadList={false} |
||||||
|
> |
||||||
|
<Button icon={<UploadOutlined />}>Import Excel</Button> |
||||||
|
</Upload> |
||||||
|
</Tooltip> |
||||||
|
</Form.Item> |
||||||
|
</Form> |
||||||
|
</Col> |
||||||
|
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}> |
||||||
|
<Button |
||||||
|
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||||
|
disabled={dataTable.length > 0 ? false : true} |
||||||
|
onClick={(e)=> saveHandler(e)} |
||||||
|
> |
||||||
|
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</div> |
||||||
|
<Card> |
||||||
|
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||||
|
<h4 className="capitalize">Data Preview</h4> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<Spin tip="Loading..."> |
||||||
|
<Table |
||||||
|
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'} |
||||||
|
dataSource={dataTable} |
||||||
|
columns={columns} |
||||||
|
pagination={false} |
||||||
|
/> |
||||||
|
</Spin> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
<Prompt |
||||||
|
when={isPreview} |
||||||
|
message={() => 'Import Activity belum disave ingin meninggalkan halaman ini?'} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<NotificationContainer /> |
||||||
|
<div> |
||||||
|
<Row> |
||||||
|
<Col span={22}> |
||||||
|
<Form |
||||||
|
name="import_preview" |
||||||
|
{...formItemLayout} |
||||||
|
> |
||||||
|
<Form.Item |
||||||
|
name="upload" |
||||||
|
valuePropName="fileList" |
||||||
|
getValueFromEvent={normFile} |
||||||
|
extra="" |
||||||
|
> |
||||||
|
<Button |
||||||
|
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||||
|
href={"/template/template_activity.xlsx"} |
||||||
|
> |
||||||
|
<i className="fa fa-print" style={{ marginRight: "5px" }}></i> Download Template |
||||||
|
</Button> |
||||||
|
<Tooltip title="Format file .xlsx"> |
||||||
|
<Upload |
||||||
|
name="template" |
||||||
|
listType="text" |
||||||
|
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
||||||
|
maxCount={1} |
||||||
|
beforeUpload={(file)=> fileHandler(file)} |
||||||
|
showUploadList={false} |
||||||
|
> |
||||||
|
<Button icon={<UploadOutlined />}>Import Excel</Button> |
||||||
|
</Upload> |
||||||
|
</Tooltip> |
||||||
|
</Form.Item> |
||||||
|
</Form> |
||||||
|
</Col> |
||||||
|
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}> |
||||||
|
<Button |
||||||
|
style={{ marginLeft: "5px", marginRight: "10px" }} |
||||||
|
disabled={dataTable.length > 0 ? false : true} |
||||||
|
onClick={(e)=> saveHandler(e)} |
||||||
|
> |
||||||
|
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save |
||||||
|
</Button> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</div> |
||||||
|
<Card> |
||||||
|
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||||
|
<h4 className="capitalize">Data Preview</h4> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<Table |
||||||
|
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'} |
||||||
|
dataSource={dataTable} |
||||||
|
columns={columns} |
||||||
|
pagination={false} |
||||||
|
/> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
<Prompt |
||||||
|
when={isPreview} |
||||||
|
message={() => 'Import Activity belum disave ingin meninggalkan halaman ini?'} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default ImportActivity; |
Loading…
Reference in new issue