|
|
|
@ -2,12 +2,20 @@ import '../../../node_modules/react-grid-layout/css/styles.css';
|
|
|
|
|
import '../../../node_modules/react-resizable/css/styles.css'; |
|
|
|
|
import './../DashboardPMO/Dashboard.css'; |
|
|
|
|
import { BASE_OSPRO } from '../../const/ApiConst'; |
|
|
|
|
import React, { useEffect, useState } from 'react'; |
|
|
|
|
import React, { useEffect, useState, useRef } from 'react'; |
|
|
|
|
import axios from 'axios' |
|
|
|
|
import { Table, Row, Col } from 'antd'; |
|
|
|
|
import { Table, Row, Col, Button, Input, Space } from 'antd'; |
|
|
|
|
import { formatRibuanDecimal } from '../../const/CustomFunc.js'; |
|
|
|
|
import { Badge } from 'reactstrap'; |
|
|
|
|
import { Link } from "react-router-dom"; |
|
|
|
|
import { SearchOutlined } from '@ant-design/icons'; |
|
|
|
|
import Highlighter from 'react-highlight-words'; |
|
|
|
|
import _ from "lodash"; |
|
|
|
|
|
|
|
|
|
const filterData = data => formatter => data.map(item => ({ |
|
|
|
|
text: formatter(item), |
|
|
|
|
value: formatter(item) |
|
|
|
|
})) |
|
|
|
|
|
|
|
|
|
const TableDashboardV1 = () => { |
|
|
|
|
const token = localStorage.getItem("token") |
|
|
|
@ -20,6 +28,104 @@ const TableDashboardV1 = () => {
|
|
|
|
|
|
|
|
|
|
const [MANPOWERS, SET_MANPOWERS] = useState(0) |
|
|
|
|
const [dataTable, setDataTable] = useState([]) |
|
|
|
|
const [searchText, setSearchText] = useState(''); |
|
|
|
|
const [searchedColumn, setSearchedColumn] = useState(''); |
|
|
|
|
const searchInput = useRef(null); |
|
|
|
|
|
|
|
|
|
const handleSearch = (selectedKeys, confirm, dataIndex) => { |
|
|
|
|
confirm(); |
|
|
|
|
setSearchText(selectedKeys[0]); |
|
|
|
|
setSearchedColumn(dataIndex); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handleReset = (clearFilters) => { |
|
|
|
|
clearFilters(); |
|
|
|
|
setSearchText(''); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getColumnSearchProps = (dataIndex) => ({ |
|
|
|
|
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => ( |
|
|
|
|
<div |
|
|
|
|
style={{ |
|
|
|
|
padding: 8, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
<Input |
|
|
|
|
ref={searchInput} |
|
|
|
|
placeholder={`Search ${dataIndex}`} |
|
|
|
|
value={selectedKeys[0]} |
|
|
|
|
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])} |
|
|
|
|
onPressEnter={() => handleSearch(selectedKeys, confirm, dataIndex)} |
|
|
|
|
style={{ |
|
|
|
|
marginBottom: 8, |
|
|
|
|
display: 'block', |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
<Space> |
|
|
|
|
<Button |
|
|
|
|
type="primary" |
|
|
|
|
onClick={() => handleSearch(selectedKeys, confirm, dataIndex)} |
|
|
|
|
icon={<SearchOutlined />} |
|
|
|
|
size="small" |
|
|
|
|
style={{ |
|
|
|
|
width: 90, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
Search |
|
|
|
|
</Button> |
|
|
|
|
<Button |
|
|
|
|
onClick={() => clearFilters && handleReset(clearFilters)} |
|
|
|
|
size="small" |
|
|
|
|
style={{ |
|
|
|
|
width: 90, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
Reset |
|
|
|
|
</Button> |
|
|
|
|
<Button |
|
|
|
|
type="link" |
|
|
|
|
size="small" |
|
|
|
|
onClick={() => { |
|
|
|
|
confirm({ |
|
|
|
|
closeDropdown: false, |
|
|
|
|
}); |
|
|
|
|
setSearchText(selectedKeys[0]); |
|
|
|
|
setSearchedColumn(dataIndex); |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
</Button> |
|
|
|
|
</Space> |
|
|
|
|
</div> |
|
|
|
|
), |
|
|
|
|
filterIcon: (filtered) => ( |
|
|
|
|
<SearchOutlined |
|
|
|
|
style={{ |
|
|
|
|
color: filtered ? '#1890ff' : undefined, |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
), |
|
|
|
|
onFilter: (value, record) => |
|
|
|
|
record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()), |
|
|
|
|
onFilterDropdownVisibleChange: (visible) => { |
|
|
|
|
if (visible) { |
|
|
|
|
setTimeout(() => searchInput.current?.select(), 100); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
render: (text) => |
|
|
|
|
searchedColumn === dataIndex ? ( |
|
|
|
|
<Highlighter |
|
|
|
|
highlightStyle={{ |
|
|
|
|
backgroundColor: '#ffc069', |
|
|
|
|
padding: 0, |
|
|
|
|
}} |
|
|
|
|
searchWords={[searchText]} |
|
|
|
|
autoEscape |
|
|
|
|
textToHighlight={text ? text.toString() : ''} |
|
|
|
|
/> |
|
|
|
|
) : ( |
|
|
|
|
text |
|
|
|
|
), |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const getProjects = async () => { |
|
|
|
|
const URL = `${BASE_OSPRO}/api/project/list` |
|
|
|
@ -40,11 +146,14 @@ const TableDashboardV1 = () => {
|
|
|
|
|
<Link to={`/dashboard-project/${record.id}/${record.lastGanttId}`}> |
|
|
|
|
{record.kode_sortname} <br /> {text} |
|
|
|
|
</Link>, |
|
|
|
|
...getColumnSearchProps('nama'), |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: 'Project Manager', |
|
|
|
|
dataIndex: 'projectManager', |
|
|
|
|
key: 'projectManager', |
|
|
|
|
filters: _.uniqWith(filterData(dataTable)(i => i.projectManager), _.isEqual), |
|
|
|
|
onFilter: (value, record) => record.projectManager.indexOf(value) === 0, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: 'Planned Interval', |
|
|
|
@ -88,7 +197,9 @@ const TableDashboardV1 = () => {
|
|
|
|
|
} else { |
|
|
|
|
return <Badge color="danger">Danger</Badge> |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
filters: _.uniqWith(filterData(dataTable)(i => i.costHealth), _.isEqual), |
|
|
|
|
onFilter: (value, record) => record.costHealth.indexOf(value) === 0, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
title: 'Progress', |
|
|
|
|