|
|
@ -4,13 +4,15 @@ import './../DashboardPMO/Dashboard.css'; |
|
|
|
import { BASE_OSPRO } from '../../const/ApiConst'; |
|
|
|
import { BASE_OSPRO } from '../../const/ApiConst'; |
|
|
|
import React, { useEffect, useState, useRef } from 'react'; |
|
|
|
import React, { useEffect, useState, useRef } from 'react'; |
|
|
|
import axios from 'axios' |
|
|
|
import axios from 'axios' |
|
|
|
import { Table, Row, Col, Button, Input, Space } from 'antd'; |
|
|
|
import { Table, Row, Col, Button, Input, InputNumber, Space } from 'antd'; |
|
|
|
import { formatRibuanDecimal } from '../../const/CustomFunc.js'; |
|
|
|
import { formatRibuanDecimal } from '../../const/CustomFunc.js'; |
|
|
|
import { Badge } from 'reactstrap'; |
|
|
|
import { Badge } from 'reactstrap'; |
|
|
|
import { Link } from "react-router-dom"; |
|
|
|
import { Link } from "react-router-dom"; |
|
|
|
import { SearchOutlined } from '@ant-design/icons'; |
|
|
|
import { SearchOutlined } from '@ant-design/icons'; |
|
|
|
import Highlighter from 'react-highlight-words'; |
|
|
|
import Highlighter from 'react-highlight-words'; |
|
|
|
import _ from "lodash"; |
|
|
|
import _ from "lodash"; |
|
|
|
|
|
|
|
import Slider from "antd/lib/slider"; |
|
|
|
|
|
|
|
import numeral from "numeral"; |
|
|
|
|
|
|
|
|
|
|
|
const filterData = data => formatter => data.map(item => ({ |
|
|
|
const filterData = data => formatter => data.map(item => ({ |
|
|
|
text: formatter(item), |
|
|
|
text: formatter(item), |
|
|
@ -28,23 +30,112 @@ const TableDashboardV1 = () => { |
|
|
|
|
|
|
|
|
|
|
|
const [MANPOWERS, SET_MANPOWERS] = useState(0) |
|
|
|
const [MANPOWERS, SET_MANPOWERS] = useState(0) |
|
|
|
const [dataTable, setDataTable] = useState([]) |
|
|
|
const [dataTable, setDataTable] = useState([]) |
|
|
|
const [searchText, setSearchText] = useState(''); |
|
|
|
const [searchText, setSearchText] = useState('') |
|
|
|
const [searchedColumn, setSearchedColumn] = useState(''); |
|
|
|
const [searchedColumn, setSearchedColumn] = useState('') |
|
|
|
const searchInput = useRef(null); |
|
|
|
const searchInput = useRef(null) |
|
|
|
|
|
|
|
const [maxSlider, setMaxSlider] = useState(MANPOWERS) |
|
|
|
|
|
|
|
//const [sliderValue, setSliderValue] = useState([]);
|
|
|
|
|
|
|
|
|
|
|
|
const handleSearch = (selectedKeys, confirm, dataIndex) => { |
|
|
|
const handleSearch = (selectedKeys, confirm, dataIndex) => { |
|
|
|
confirm(); |
|
|
|
confirm() |
|
|
|
setSearchText(selectedKeys[0]); |
|
|
|
setSearchText(selectedKeys[0]) |
|
|
|
setSearchedColumn(dataIndex); |
|
|
|
setSearchedColumn(dataIndex) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleSlide = (dataIndex, value, confirm) => { |
|
|
|
|
|
|
|
confirm({ closeDropdown: false }); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const slider = (dataIndex) => ({ |
|
|
|
|
|
|
|
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => { |
|
|
|
|
|
|
|
if(dataIndex == 'manpower'){ |
|
|
|
|
|
|
|
setMaxSlider(MANPOWERS) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
className="custom-filter-dropdown ant-table-filter-dropdown" |
|
|
|
|
|
|
|
style={{ minWidth: "20rem", padding: "0.5rem 1rem" }} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Row> |
|
|
|
|
|
|
|
<Col span={4}> |
|
|
|
|
|
|
|
<div style={{ display: "flex", flexDirection: "column" }}> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<strong>Min: </strong> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div>0</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</Col> |
|
|
|
|
|
|
|
<Col span={16}> |
|
|
|
|
|
|
|
<Slider |
|
|
|
|
|
|
|
range={true} |
|
|
|
|
|
|
|
min={0} |
|
|
|
|
|
|
|
max={maxSlider} |
|
|
|
|
|
|
|
onAfterChange={(value) => { |
|
|
|
|
|
|
|
setSelectedKeys([value]) |
|
|
|
|
|
|
|
handleSlide(dataIndex, value, confirm)} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</Col> |
|
|
|
|
|
|
|
<Col span={4}> |
|
|
|
|
|
|
|
<div style={{ display: "flex", flexDirection: "column" }}> |
|
|
|
|
|
|
|
<div> |
|
|
|
|
|
|
|
<strong>Max:</strong> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<div>{maxSlider}</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</Col> |
|
|
|
|
|
|
|
</Row> |
|
|
|
|
|
|
|
{/* <Row style={{ marginBottom: "10px" }}> |
|
|
|
|
|
|
|
<Col span={24}> |
|
|
|
|
|
|
|
<InputNumber |
|
|
|
|
|
|
|
min={0} |
|
|
|
|
|
|
|
max={maxSlider} |
|
|
|
|
|
|
|
value={sliderValue[0]} |
|
|
|
|
|
|
|
style={{ width: '100%' }} |
|
|
|
|
|
|
|
placeholder={"Min"} |
|
|
|
|
|
|
|
onChange={(value) => { |
|
|
|
|
|
|
|
setSelectedKeys([value]) |
|
|
|
|
|
|
|
handleSlide(dataIndex, value, confirm)} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</Col> |
|
|
|
|
|
|
|
</Row> */} |
|
|
|
|
|
|
|
{/* <Row> |
|
|
|
|
|
|
|
<Col span={24}> |
|
|
|
|
|
|
|
<InputNumber |
|
|
|
|
|
|
|
min={0} |
|
|
|
|
|
|
|
max={maxSlider} |
|
|
|
|
|
|
|
style={{ width: '100%' }} |
|
|
|
|
|
|
|
placeholder={"Max"} |
|
|
|
|
|
|
|
onChange={(value) => { |
|
|
|
|
|
|
|
console.log(value) |
|
|
|
|
|
|
|
setSelectedKeys([value]) |
|
|
|
|
|
|
|
handleSlide(dataIndex, value, confirm)} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</Col> |
|
|
|
|
|
|
|
</Row> */} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
)}, |
|
|
|
|
|
|
|
onFilter: (value, record) => { |
|
|
|
|
|
|
|
return (record[dataIndex] >= value[0] && record[dataIndex] <= value[1]) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onFilterDropdownVisibleChange: (visible) => { |
|
|
|
|
|
|
|
if (visible) { |
|
|
|
|
|
|
|
setTimeout(() => searchInput.current?.select(), 100); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const handleReset = (clearFilters) => { |
|
|
|
const handleReset = (clearFilters) => { |
|
|
|
clearFilters(); |
|
|
|
clearFilters(); |
|
|
|
setSearchText(''); |
|
|
|
setSearchText(''); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const getColumnSearchProps = (dataIndex) => ({ |
|
|
|
const getColumnSearchProps = (dataIndex) => ({ |
|
|
|
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => ( |
|
|
|
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => { |
|
|
|
|
|
|
|
return ( |
|
|
|
<div |
|
|
|
<div |
|
|
|
style={{ |
|
|
|
style={{ |
|
|
|
padding: 8, |
|
|
|
padding: 8, |
|
|
@ -96,7 +187,7 @@ const TableDashboardV1 = () => { |
|
|
|
</Button> |
|
|
|
</Button> |
|
|
|
</Space> |
|
|
|
</Space> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
), |
|
|
|
)}, |
|
|
|
filterIcon: (filtered) => ( |
|
|
|
filterIcon: (filtered) => ( |
|
|
|
<SearchOutlined |
|
|
|
<SearchOutlined |
|
|
|
style={{ |
|
|
|
style={{ |
|
|
@ -104,8 +195,9 @@ const TableDashboardV1 = () => { |
|
|
|
}} |
|
|
|
}} |
|
|
|
/> |
|
|
|
/> |
|
|
|
), |
|
|
|
), |
|
|
|
onFilter: (value, record) => |
|
|
|
onFilter: (value, record) => { |
|
|
|
record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()), |
|
|
|
return record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()) |
|
|
|
|
|
|
|
}, |
|
|
|
onFilterDropdownVisibleChange: (visible) => { |
|
|
|
onFilterDropdownVisibleChange: (visible) => { |
|
|
|
if (visible) { |
|
|
|
if (visible) { |
|
|
|
setTimeout(() => searchInput.current?.select(), 100); |
|
|
|
setTimeout(() => searchInput.current?.select(), 100); |
|
|
@ -163,15 +255,18 @@ const TableDashboardV1 = () => { |
|
|
|
{ |
|
|
|
{ |
|
|
|
title: 'Manpower', |
|
|
|
title: 'Manpower', |
|
|
|
dataIndex: 'manpower', |
|
|
|
dataIndex: 'manpower', |
|
|
|
|
|
|
|
key: 'manpower', |
|
|
|
render: (text) => { |
|
|
|
render: (text) => { |
|
|
|
return `${text}/${MANPOWERS}` |
|
|
|
return `${text}/${MANPOWERS}` |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
...slider('manpower') |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
title: 'Budget Project', |
|
|
|
title: 'Budget Project', |
|
|
|
dataIndex: 'plannedCost', |
|
|
|
dataIndex: 'plannedCost', |
|
|
|
key: 'plannedCost', |
|
|
|
key: 'plannedCost', |
|
|
|
render: (text) => <a>{formatRibuanDecimal(text)}</a>, |
|
|
|
render: (text) => <a>{formatRibuanDecimal(text)}</a>, |
|
|
|
|
|
|
|
filterDropdown: slider |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
title: 'Actual Cost', |
|
|
|
title: 'Actual Cost', |
|
|
@ -220,7 +315,10 @@ const TableDashboardV1 = () => { |
|
|
|
<> |
|
|
|
<> |
|
|
|
<Row gutter={[16, 16]}> |
|
|
|
<Row gutter={[16, 16]}> |
|
|
|
<Col span={24}> |
|
|
|
<Col span={24}> |
|
|
|
<Table columns={columns} dataSource={dataTable} /> |
|
|
|
<Table |
|
|
|
|
|
|
|
columns={columns} |
|
|
|
|
|
|
|
dataSource={dataTable} |
|
|
|
|
|
|
|
/> |
|
|
|
</Col> |
|
|
|
</Col> |
|
|
|
</Row> |
|
|
|
</Row> |
|
|
|
</> |
|
|
|
</> |
|
|
|