|
|
|
@ -1,7 +1,21 @@
|
|
|
|
|
import React, {useState, useEffect} from 'react' |
|
|
|
|
import { Modal, ModalHeader, ModalBody, ModalFooter, Card, CardHeader, CardBody } from 'reactstrap'; |
|
|
|
|
import { TabContent, TabPane, Nav, NavItem, NavLink, Row, Col, Input } from 'reactstrap'; |
|
|
|
|
import { Button } from 'reactstrap'; |
|
|
|
|
import { |
|
|
|
|
Modal, |
|
|
|
|
ModalHeader, |
|
|
|
|
ModalBody, |
|
|
|
|
ModalFooter, |
|
|
|
|
Card, |
|
|
|
|
CardHeader, |
|
|
|
|
CardBody, |
|
|
|
|
TabContent, |
|
|
|
|
TabPane, |
|
|
|
|
Nav, |
|
|
|
|
NavItem, |
|
|
|
|
NavLink, |
|
|
|
|
Row, |
|
|
|
|
Col, |
|
|
|
|
Button |
|
|
|
|
} from 'reactstrap'; |
|
|
|
|
import axios from "../../../const/interceptorApi"; |
|
|
|
|
import { |
|
|
|
|
NotificationManager, |
|
|
|
@ -9,7 +23,7 @@ import {
|
|
|
|
|
import { BASE_SIMPRO_LUMEN } from "../../../const/ApiConst"; |
|
|
|
|
import 'antd/dist/antd.css'; |
|
|
|
|
import './style.css' |
|
|
|
|
import { Select, Table, Tooltip } from 'antd'; |
|
|
|
|
import { Select, Table, Tooltip, Spin } from 'antd'; |
|
|
|
|
import DialogFormAnalysis from './DialogFormAnalysis'; |
|
|
|
|
import moment from "moment"; |
|
|
|
|
const { Option } = Select |
|
|
|
@ -21,12 +35,15 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
const [openDialogFormAnalysis, setOpenDialogFormAnalysis] = useState(false); |
|
|
|
|
const [dataDetail, setDataDetail] = useState(null); |
|
|
|
|
const [avgActivityHr, setAvgActivityHr] = useState(0); |
|
|
|
|
const [sumVolPlan, setSumVolPlan] = useState(0); |
|
|
|
|
const [sumVolAct, setSumVolAct] = useState(0); |
|
|
|
|
const [avgActivity, setAvgActivity] = useState(0); |
|
|
|
|
const [dataTable, setDatatable] = useState([]); |
|
|
|
|
const [dataTableActivityToHr, setDataTableActivityToHr] = useState([]); |
|
|
|
|
const [hrList, setHrList] = useState([]); |
|
|
|
|
const [groupedActivity, setGroupedActivity] = useState([]); |
|
|
|
|
const [selectedHr, setSelectedHr] = useState(null); |
|
|
|
|
const [loading, setLoading] = useState(false); |
|
|
|
|
|
|
|
|
|
const toggle = (tab) => { |
|
|
|
|
if (activeTab !== tab) { |
|
|
|
@ -57,7 +74,57 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
|
|
|
|
|
const columns = [ |
|
|
|
|
{title: "Gantt", dataIndex: "name_version", key: "name_version"}, |
|
|
|
|
{title: "Assign HR", dataIndex: "user_name", key: "user_name"}, |
|
|
|
|
{title: "Baseline Start", dataIndex: "planned_start", key: "planned_start", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.planned_start ? moment(record.planned_start).format("DD-MM-YY") : ''} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Baseline Finish", dataIndex: "planned_end", key: "planned_end", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.planned_end ? moment(record.planned_end).format("DD-MM-YY") : ''} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Early Start", dataIndex: "start_date", key: "start_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.start_date).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Early Finish", dataIndex: "end_date", key: "end_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.end_date).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Actual Start", dataIndex: "actual_start", key: "actual_start", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.actual_start ? moment(record.actual_start).format("DD-MM-YY") : ""} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Actual Finish", dataIndex: "actual_end", key: "actual_end", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.actual_end ? moment(record.actual_end).format("DD-MM-YY") : ""} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Assign HR", dataIndex: "user_name", key: "user_name", width: "8%", |
|
|
|
|
ellipsis:{ |
|
|
|
|
showTitle: true |
|
|
|
|
}, |
|
|
|
|
render: (text) => |
|
|
|
|
<Tooltip placement="topLeft" title={text}> |
|
|
|
|
{text} |
|
|
|
|
</Tooltip> |
|
|
|
|
}, |
|
|
|
|
{title: "Volume Plan", dataIndex: "qty_planning", key: "qty_planning", |
|
|
|
|
render: (text, record) => |
|
|
|
|
<> |
|
|
|
@ -81,7 +148,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
); |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{title: "Progress Actual (%)", dataIndex: "persentase_progress", key: "persentase_progress"}, |
|
|
|
|
{title: "Progress Actual (%)", dataIndex: "persentase_progress", key: "persentase_progress", width: "8%"}, |
|
|
|
|
{ |
|
|
|
|
title: 'Action', |
|
|
|
|
dataIndex: '', |
|
|
|
@ -100,17 +167,45 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
const columnActivityToHr = [ |
|
|
|
|
{title: "Activity", dataIndex: "join_second_name", key: "join_second_name"}, |
|
|
|
|
{title: "Gantt", dataIndex: "join_fourth_name_version", key: "join_fourth_name_version"}, |
|
|
|
|
{title: "Start Date", dataIndex: "start_date", key: "start_date", |
|
|
|
|
{title: "Baseline Start", dataIndex: "join_second_planned_start", key: "join_second_planned_start", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.join_second_planned_start).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Baseline Finish", dataIndex: "join_second_planned_end", key: "join_second_planned_end", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.start_date).format("DD-MM-YYYY")} |
|
|
|
|
{moment(record.join_second_planned_end).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "End Date", dataIndex: "end_date", key: "end_date", |
|
|
|
|
{title: "Early Start", dataIndex: "join_second_start_date", key: "join_second_start_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.end_date).format("DD-MM-YYYY")} |
|
|
|
|
{moment(record.join_second_start_date).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Early Finish", dataIndex: "join_second_end_date", key: "join_second_end_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.join_second_end_date).format("DD-MM-YY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Actual Start", dataIndex: "join_second_actual_start", key: "join_second_actual_start", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.join_second_actual_start ? moment(record.join_second_actual_start).format("DD-MM-YY") : ""} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Actual Finish", dataIndex: "join_second_actual_end", key: "join_second_actual_end", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{record.join_second_actual_end ? moment(record.join_second_actual_end).format("DD-MM-YY") : ""} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
@ -155,12 +250,14 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (search) { |
|
|
|
|
setLoading(true); |
|
|
|
|
getDataActivity() |
|
|
|
|
} |
|
|
|
|
}, [search]); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (selectedHr) { |
|
|
|
|
setLoading(true); |
|
|
|
|
getDataActivityToHr() |
|
|
|
|
} |
|
|
|
|
}, [selectedHr]); |
|
|
|
@ -279,7 +376,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
{ |
|
|
|
|
name: "m_activity", |
|
|
|
|
column_join: "activity_id", |
|
|
|
|
column_results: ["name", "persentase_progress", "start_date", "end_date", "duration"] |
|
|
|
|
column_results: ["name", "persentase_progress", "actual_start", "actual_end", "planned_start", "planned_end", "start_date", "end_date", "duration"] |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name1: "m_activity", |
|
|
|
@ -318,7 +415,9 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
}); |
|
|
|
|
setAvgActivityHr(sum / dataRes.length); |
|
|
|
|
setDataTableActivityToHr(dataRes); |
|
|
|
|
setLoading(false); |
|
|
|
|
} else { |
|
|
|
|
setLoading(false); |
|
|
|
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -352,8 +451,12 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
|
|
|
|
|
const getDataActivity = async () => { |
|
|
|
|
setAvgActivity(0); |
|
|
|
|
setSumVolPlan(0); |
|
|
|
|
setSumVolAct(0); |
|
|
|
|
setDatatable([]); |
|
|
|
|
let sum = 0; |
|
|
|
|
let sumPlan = 0; |
|
|
|
|
let sumAct = 0; |
|
|
|
|
const payload = { |
|
|
|
|
columns: [ |
|
|
|
|
{ |
|
|
|
@ -383,10 +486,16 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
|
|
|
|
|
dataRes.forEach(element => { |
|
|
|
|
element.persentase_progress ? sum += parseInt(element.persentase_progress) : sum += 0; |
|
|
|
|
element.qty_planning ? sumPlan += parseInt(element.qty_planning) : sumPlan += 0; |
|
|
|
|
element.qty ? sumAct += parseInt(element.qty) : sumAct += 0; |
|
|
|
|
}); |
|
|
|
|
setAvgActivity(sum / dataRes.length); |
|
|
|
|
setSumVolPlan(sumPlan); |
|
|
|
|
setSumVolAct(sumAct); |
|
|
|
|
setDatatable(dataRes); |
|
|
|
|
setLoading(false); |
|
|
|
|
} else { |
|
|
|
|
setLoading(false); |
|
|
|
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -434,21 +543,25 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
</Col> |
|
|
|
|
</Row> |
|
|
|
|
</CardHeader> |
|
|
|
|
<CardBody> |
|
|
|
|
<CardBody style={{ width: '100%' }}> |
|
|
|
|
<div style={{ textAlign: 'center' }}> |
|
|
|
|
<h1> |
|
|
|
|
{ |
|
|
|
|
search && avgActivity ? `Activity ${search} adalah ${avgActivity.toFixed(2)} %` : null |
|
|
|
|
search ? `Activity ${search}, Total Plan = ${sumVolPlan ? sumVolPlan.toFixed(0) : 0} dan Total Actual = ${sumVolAct ? sumVolAct.toFixed(0) : 0}` : null |
|
|
|
|
} |
|
|
|
|
</h1> |
|
|
|
|
</div> |
|
|
|
|
<Table |
|
|
|
|
size="small" |
|
|
|
|
columns={columns} |
|
|
|
|
dataSource={dataTable} |
|
|
|
|
pagination={false} |
|
|
|
|
rowKey={"id"} |
|
|
|
|
/> |
|
|
|
|
<div style={{ width: '100%', overflowX: 'auto' }}> |
|
|
|
|
<Spin tip="Loading..." spinning={loading}> |
|
|
|
|
<Table |
|
|
|
|
size="small" |
|
|
|
|
columns={columns} |
|
|
|
|
dataSource={dataTable} |
|
|
|
|
pagination={false} |
|
|
|
|
rowKey="id" |
|
|
|
|
/> |
|
|
|
|
</Spin> |
|
|
|
|
</div> |
|
|
|
|
</CardBody> |
|
|
|
|
</Card> |
|
|
|
|
</TabPane> |
|
|
|
@ -467,14 +580,18 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
</Col> |
|
|
|
|
</Row> |
|
|
|
|
</CardHeader> |
|
|
|
|
<CardBody> |
|
|
|
|
<Table |
|
|
|
|
size="small" |
|
|
|
|
columns={columnActivityToHr} |
|
|
|
|
dataSource={dataTableActivityToHr} |
|
|
|
|
pagination={false} |
|
|
|
|
rowKey={"id"} |
|
|
|
|
/> |
|
|
|
|
<CardBody style={{ width: '100%' }}> |
|
|
|
|
<div style={{ width: '100%', overflowX: 'auto' }}> |
|
|
|
|
<Spin tip="Loading..." spinning={loading}> |
|
|
|
|
<Table |
|
|
|
|
size="small" |
|
|
|
|
columns={columnActivityToHr} |
|
|
|
|
dataSource={dataTableActivityToHr} |
|
|
|
|
pagination={false} |
|
|
|
|
rowKey={"id"} |
|
|
|
|
/> |
|
|
|
|
</Spin> |
|
|
|
|
</div> |
|
|
|
|
</CardBody> |
|
|
|
|
</Card> |
|
|
|
|
</TabPane> |
|
|
|
|