farhantock
1 year ago
20 changed files with 498 additions and 105 deletions
@ -0,0 +1,293 @@ |
|||||||
|
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 axios from "../../../const/interceptorApi"; |
||||||
|
import { |
||||||
|
NotificationManager, |
||||||
|
} from "react-notifications"; |
||||||
|
import { BASE_SIMPRO_LUMEN } from "../../../const/ApiConst"; |
||||||
|
import 'antd/dist/antd.css'; |
||||||
|
import './style.css' |
||||||
|
import { Select, Table } from 'antd'; |
||||||
|
const { Option } = Select |
||||||
|
|
||||||
|
const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) => { |
||||||
|
const token = localStorage.getItem("token"); |
||||||
|
const [activeTab, setActiveTab] = useState('1'); |
||||||
|
const [search, setSearch] = useState(''); |
||||||
|
const [avgActivity, setAvgActivity] = useState(0); |
||||||
|
const [dataTable, setDatatable] = useState([]); |
||||||
|
const [dataTableActivityToHr, setDataTableActivityToHr] = useState([]); |
||||||
|
const [hrList, setHrList] = useState([]); |
||||||
|
const [selectedHr, setSelectedHr] = useState(null); |
||||||
|
|
||||||
|
const toggle = (tab) => { |
||||||
|
if (activeTab !== tab) { |
||||||
|
setActiveTab(tab); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const HEADER = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
Authorization: `Bearer ${token}`, |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
const columns = [ |
||||||
|
{title: "Activity", dataIndex: "name", key: "name"}, |
||||||
|
{title: "Gantt", dataIndex: "name_version", key: "name_version"}, |
||||||
|
{title: "Assign HR", dataIndex: "user_name", key: "user_name"}, |
||||||
|
{title: "Progress (%)", dataIndex: "persentase_progress", key: "persentase_progress"}, |
||||||
|
] |
||||||
|
|
||||||
|
const columnActivityToHr = [ |
||||||
|
{title: "Activity", dataIndex: "join_third_name", key: "join_third_name"}, |
||||||
|
{title: "Human Resource", dataIndex: "join_second_name", key: "join_second_name"}, |
||||||
|
{title: "Report Date", dataIndex: "report_date", key: "report_date"}, |
||||||
|
{title: "Volume Actual", dataIndex: "qty", key: "qty"}, |
||||||
|
{title: "Volume Planned", dataIndex: "join_first_qty_planning", key: "join_first_qty_planning"}, |
||||||
|
{title: "Description", dataIndex: "description", key: "description"} |
||||||
|
] |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (search) { |
||||||
|
getDataActivity() |
||||||
|
} |
||||||
|
}, [search]); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (selectedHr) { |
||||||
|
getDataActivityToHr() |
||||||
|
} |
||||||
|
}, [selectedHr]); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
getDataHr() |
||||||
|
}, []); |
||||||
|
|
||||||
|
const handleSearch = (e) => { |
||||||
|
const value = e.target.value; |
||||||
|
setSearch(value); |
||||||
|
}; |
||||||
|
|
||||||
|
const getDataHr = async () => { |
||||||
|
const result = await axios |
||||||
|
.get(`${BASE_SIMPRO_LUMEN}/human-resource/list`, HEADER) |
||||||
|
.then((res) => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let dataRes = result.data.data || []; |
||||||
|
setHrList(dataRes); |
||||||
|
} else { |
||||||
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||||
|
} |
||||||
|
} |
||||||
|
const getDataActivityToHr = async () => { |
||||||
|
setAvgActivity(0); |
||||||
|
let sum = 0; |
||||||
|
const payload = { |
||||||
|
columns: [ |
||||||
|
{ |
||||||
|
name: "user_id", |
||||||
|
logic_operator: "=", |
||||||
|
value: selectedHr, |
||||||
|
operator: "AND", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "proyek_id", |
||||||
|
logic_operator: "=", |
||||||
|
value: projectId, |
||||||
|
table_name: "m_activity", |
||||||
|
operator: "AND", |
||||||
|
} |
||||||
|
], |
||||||
|
joins: [ |
||||||
|
{ |
||||||
|
name: "assign_material_to_activity", |
||||||
|
column_join: "assign_material_id", |
||||||
|
column_results: ["qty_planning"] |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "m_users", |
||||||
|
column_join: "user_id", |
||||||
|
column_results: ["name"] |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "m_activity", |
||||||
|
column_join: "activity_id", |
||||||
|
column_results: ["name", "persentase_progress"] |
||||||
|
} |
||||||
|
], |
||||||
|
orders: { columns: ["id"], ascending: false }, |
||||||
|
paging: { start: 0, length: -1 }, |
||||||
|
}; |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(`${BASE_SIMPRO_LUMEN}/report-activity-material/search`, payload, HEADER) |
||||||
|
.then((res) => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let dataRes = result.data.data || []; |
||||||
|
dataRes.forEach(element => { |
||||||
|
element.join_third_persentase_progress ? sum += parseInt(element.join_third_persentase_progress) : sum += 0; |
||||||
|
}); |
||||||
|
setAvgActivity(sum / dataRes.length); |
||||||
|
setDataTableActivityToHr(dataRes); |
||||||
|
} else { |
||||||
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const getDataActivity = async () => { |
||||||
|
setAvgActivity(0); |
||||||
|
let sum = 0; |
||||||
|
const payload = { |
||||||
|
columns: [ |
||||||
|
{ |
||||||
|
name: "name", |
||||||
|
logic_operator: "ilike", |
||||||
|
value: search, |
||||||
|
operator: "AND", |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: "proyek_id", |
||||||
|
logic_operator: "=", |
||||||
|
value: projectId, |
||||||
|
operator: "AND", |
||||||
|
}, |
||||||
|
], |
||||||
|
orders: { columns: ["id"], ascending: false }, |
||||||
|
paging: { start: 0, length: -1 }, |
||||||
|
}; |
||||||
|
|
||||||
|
const result = await axios |
||||||
|
.post(`${BASE_SIMPRO_LUMEN}/activity/search-analysis`, payload, HEADER) |
||||||
|
.then((res) => res) |
||||||
|
.catch((error) => error.response); |
||||||
|
|
||||||
|
if (result && result.data && result.data.code == 200) { |
||||||
|
let dataRes = result.data.data || []; |
||||||
|
|
||||||
|
dataRes.forEach(element => { |
||||||
|
element.persentase_progress ? sum += parseInt(element.persentase_progress) : sum += 0; |
||||||
|
}); |
||||||
|
setAvgActivity(sum / dataRes.length); |
||||||
|
setDatatable(dataRes); |
||||||
|
} else { |
||||||
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
||||||
|
} |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
||||||
|
<ModalHeader className="capitalize" toggle={closeDialog}>Project</ModalHeader> |
||||||
|
<ModalBody> |
||||||
|
<div> |
||||||
|
<Nav tabs> |
||||||
|
<NavItem> |
||||||
|
<NavLink |
||||||
|
className={activeTab === '1' ? "active" : null} |
||||||
|
onClick={() => { |
||||||
|
toggle('1'); |
||||||
|
}} |
||||||
|
> |
||||||
|
Activity |
||||||
|
</NavLink> |
||||||
|
</NavItem> |
||||||
|
<NavItem> |
||||||
|
<NavLink |
||||||
|
className={activeTab === '2' ? "active" : null} |
||||||
|
onClick={() => { |
||||||
|
toggle('2'); |
||||||
|
}} |
||||||
|
> |
||||||
|
Human Resource |
||||||
|
</NavLink> |
||||||
|
</NavItem> |
||||||
|
</Nav> |
||||||
|
<TabContent activeTab={activeTab}> |
||||||
|
<TabPane tabId="1"> |
||||||
|
<Card> |
||||||
|
<CardHeader> |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<Input |
||||||
|
onChange={handleSearch} |
||||||
|
value={search} |
||||||
|
type="text" |
||||||
|
name="search" |
||||||
|
id="search" |
||||||
|
placeholder={`Search Activity Name`} |
||||||
|
style={{ width: 200 }} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<div style={{ textAlign: 'center' }}> |
||||||
|
<h1> |
||||||
|
{ |
||||||
|
search && avgActivity ? `Activity ${search} adalah ${avgActivity.toFixed(2)} %` : null |
||||||
|
} |
||||||
|
</h1> |
||||||
|
</div> |
||||||
|
<Table |
||||||
|
size="small" |
||||||
|
columns={columns} |
||||||
|
dataSource={dataTable} |
||||||
|
pagination={false} |
||||||
|
rowKey={"id"} |
||||||
|
/> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
</TabPane> |
||||||
|
<TabPane tabId="2"> |
||||||
|
<Card> |
||||||
|
<CardHeader> |
||||||
|
<Row> |
||||||
|
<Col> |
||||||
|
<Select showSearch value={selectedHr} onChange={(val) => setSelectedHr(val)} placeholder="Select Human Resource" filterOption={(input, option) => |
||||||
|
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
||||||
|
} style={{ width: '100%' }}> |
||||||
|
{hrList && hrList.map(res => ( |
||||||
|
<Option key={res.id} value={res.id}>{`${res.name}`}</Option> |
||||||
|
))} |
||||||
|
</Select> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</CardHeader> |
||||||
|
<CardBody> |
||||||
|
<div style={{ textAlign: 'center' }}> |
||||||
|
<h1> |
||||||
|
{ |
||||||
|
selectedHr && avgActivity ? `Activity user ini adalah ${avgActivity.toFixed(2)} %` : null |
||||||
|
} |
||||||
|
</h1> |
||||||
|
</div> |
||||||
|
<Table |
||||||
|
size="small" |
||||||
|
columns={columnActivityToHr} |
||||||
|
dataSource={dataTableActivityToHr} |
||||||
|
pagination={false} |
||||||
|
rowKey={"id"} |
||||||
|
/> |
||||||
|
</CardBody> |
||||||
|
</Card> |
||||||
|
</TabPane> |
||||||
|
</TabContent> |
||||||
|
</div> |
||||||
|
</ModalBody> |
||||||
|
<ModalFooter> |
||||||
|
<Button color="primary" onClick={closeDialog}>Close</Button> |
||||||
|
</ModalFooter> |
||||||
|
</Modal> |
||||||
|
</> |
||||||
|
) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
export default ReportAnalysis; |
Loading…
Reference in new issue