Backend for Custom Frontend OSPRO Surveyor Indonesia
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

391 lines
12 KiB

3 years ago
import React, { Component } from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import ToolkitProvider, { Search, CSVExport } from 'react-bootstrap-table2-toolkit';
import paginationFactory from 'react-bootstrap-table2-paginator';
import cellEditFactory from 'react-bootstrap-table2-editor';
import { Badge, Card, CardBody, CardHeader, Col, Row, Table, Button,
Modal, ModalHeader, ModalBody, ModalFooter,
Form, FormGroup, Label, Input, FormText
} from 'reactstrap';
import { Icon, InlineIcon } from '@iconify/react';
import createOutline from '@iconify/icons-ion/create-outline';
import archiveOutline from '@iconify/icons-ion/archive-outline';
import addCircleOutline from '@iconify/icons-ion/add-circle-outline';
import { AppSwitch } from '@coreui/react';
import { UncontrolledTooltip } from 'reactstrap';
import './DataTable.css';
import SweetAlert from 'react-bootstrap-sweetalert';
import moment from "moment"
import { resetWarningCache } from 'prop-types';
const dataColumns = [{
dataField: 'id',
text: 'Id'
}];
const { SearchBar } = Search;
const { ExportCSVButton } = CSVExport;
class DataTable extends Component {
constructor(props) {
const {columns} = props
const val = columns.reduce((obj, item) => (obj[item.dataField] = item.state, obj) ,{});
super(props)
this.state = {
columns: [],
data: [],
selectRow: {
mode: 'checkbox',
clickToSelect: true,
clickToEdit: false,
bgColor: '#e4e5e6',
onSelect: (row, isSelect, rowIndex, e) => this.onSelectRowTable({row, isSelect, e, rowIndex}),
onSelectAll: (isSelect, rows, e) => this.onSelectRowTable({row: rows, isSelect, e}),
},
editCellMode: false,
onSelectAllMode: false,
selectedRows: [],
alert: false,
alertWarning: false,
successAlert: false,
dangerAlert: false,
messageAlert: "",
openDialog : false,
editData : false,
... val
}
this.mapTableInit = this.mapTableInit.bind(this);
}
getDataTable = () => {
fetch(this.props.urlParamGet, {
method: 'POST',
header: JSON.stringify({
'Content-Type': 'application/json'
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson.code_message === "Success"){
let dataArray = []
for(let i = 0; i < responseJson.data.length; i++){
dataArray.push(responseJson.data[i]);
}
this.mapTableInit(dataArray)
}else{
console.log("gagal login");
}
}).catch((error) => {
});
}
componentDidMount() {
this.getDataTable();
}
mapTableInit(data) {
let columns = [];
if (data.length > 0) {
for (let key in data[0]) {
columns.push({
dataField: key,
text: key,
sort: true
})
}
}
this.setState({
columns: data.length !== 0 ? columns:dataColumns,
data: data
})
}
onSelectRowTable = ({row, isSelect, e}) => {
const {selectedRows} = this.state
if(typeof row === "object"){
if(isSelect){
this.setState({selectedRows: [...selectedRows, row]})
} else {
const idx = selectedRows.indexOf(row)
selectedRows.splice(idx, 1)
this.setState({selectedRows})
}
} else {
console.log("type array")
this.setState({selectedRows: row})
}
}
openDialog = () => this.setState({openDialog: true})
closeDialog = () => this.setState({openDialog: false})
saveDialog = async () => {
const {editData} = this.state
const {columns, urlParamInsert, urlParamUpdate} = this.props
const urlParam = editData ? urlParamUpdate:urlParamInsert
const val = columns.reduce((obj, item) => (obj[item.dataField] = item.state, obj) ,{});
const obj = columns.reduce((obj, item) => Object.assign(obj, {
[item.dataField]: item.dataField === "last_updated" || item.dataField === "created_time" || item.dataField === "modified_time"
? moment().format("YYYY-MM-DD HH:mm:ssZ"): this.state[item.dataField]
}), {});
const param = {
method: 'POST',
header: JSON.stringify({'Content-Type': 'application/json'}),
body: JSON.stringify(obj)
}
this.setState({selectedRows: []})
try {
const result = await fetch(urlParam, param).then(response => response.json()).then(res => res)
if(result.data){
this.getDataTable();
this.setState({openDialog: false, alert: true, messageAlert: result.code_message, successAlert: true, dangerAlert: false, ...val})
} else {
this.setState({openDialog: false, alert: true, messageAlert: result.code_message, successAlert: false, dangerAlert: true, ...val})
}
} catch {
this.setState({openDialog: false, alert: true, messageAlert: "Opss! looks like something wrong", successAlert: false, dangerAlert: true, ...val})
}
}
dialogContent = () => {
const {editData, openDialog} = this.state
const {columns} = this.props
return (
<div>
<Modal isOpen={openDialog} toggle={this.closeDialog} >
<ModalHeader toggle={this.closeDialog}>{editData ? "Update data":"Add new"} {this.props.title}</ModalHeader>
<ModalBody>
{columns.map((res, idx) => {
if(res.showInput){
return (
<FormGroup key={idx}>
<Label for="exampleEmail">{res.alias}</Label>
<Input value={this.state[res.dataField]} onChange={(e) => this.setState({[res.dataField]: e.target.value})} type={res.type} />
</FormGroup>
)
}
})}
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.closeDialog}>Cancel</Button>
<Button color="primary" onClick={this.saveDialog}>Save</Button>{' '}
</ModalFooter>
</Modal>
</div>
)
}
getDataUpdate = () => {
const {selectedRows} = this.state
this.setState({
...selectedRows[0],
openDialog: true,
editData: true
})
}
updateFunction = async (oldValue, newValue, row, column) => {
let {editCellMode} = this.state
console.log('editCellMode', editCellMode);
console.log(row)
const param = {
method: 'POST',
header: JSON.stringify({'Content-Type': 'application/json'}),
body: JSON.stringify(row)
}
const result = await fetch(this.props.urlParamUpdate, param).then(response => response.json()).then(res => res)
if(result.data){
this.getDataTable()
this.setState({alert: true, successAlert: true, dangerAlert: false, messageAlert: result.code_message, editCellMode: false})
} else {
this.setState({alert: true, successAlert: false, dangerAlert: true, messageAlert: result.code_message })
}
}
handleDelete = data => {
}
deleteFunction = async param => {
const {selectedRows} = this.state
console.log("row selected",selectedRows)
if(param === "delete") {
const {columns} = this.props
const val = columns.reduce((obj, item) => (obj[item.dataField] = item.state, obj) ,{});
const param = {
method: 'POST',
header: JSON.stringify({'Content-Type': 'application/json'}),
body: JSON.stringify(selectedRows)
}
try {
const result = await fetch(this.props.urlParamDelete, param).then(response => response.json()).then(res => res)
if(result.data){
this.getDataTable();
this.setState({alert: true, alertWarning: false, messageAlert: result.code_message, successAlert: true, dangerAlert: false, ...val})
} else {
this.setState({alert: true, alertWarning: false, messageAlert: result.code_message, successAlert: false, dangerAlert: true, ...val})
}
} catch {
this.setState({alert: true, messageAlert: "Opss! looks like something wrong", successAlert: false, dangerAlert: true})
}
} else {
this.setState({alertWarning: false})
}
}
allDeleteFunction = () => {
console.log()
}
render() {
const { columns, data, selectedRows, selectRow, editCellMode, alert, messageAlert,
alertWarning, deleteData, successAlert, dangerAlert } = this.state;
return (
<div className="animated fadeIn">
<SweetAlert show={alert} success={successAlert} danger={dangerAlert} title={messageAlert} onConfirm={() => this.setState({alert: false, successAlert: false, dangerAlert: false})}>
{messageAlert}
</SweetAlert>
<SweetAlert
show={alertWarning}
warning
showCancel
confirmBtnText="Yes, delete it!"
confirmBtnBsStyle="danger"
title="Are you sure?"
onConfirm={() => this.deleteFunction("delete")}
onCancel={() => this.deleteFunction("cancel")}
focusCancelBtn
>
This {this.props.title} will be deleted
</SweetAlert>
<Row>
<Col xl={12}>
<Card>
<CardHeader>
<Row>
<Col xl={6} xs={6}>
<i className="fa fa-align-justify"></i>Master { this.props.title !== undefined ? this.props.title : 'DataTable' }
</Col>
<Col xl={6} xs={6}>
<div className="add-button-container">
<Button color="primary" size="sm" outline onClick={this.openDialog}>
<Icon icon={addCircleOutline} width={15} height={15} /> Add New Data
</Button>
{this.dialogContent()}
</div>
</Col>
</Row>
</CardHeader>
<CardBody>
{data.length === 0 ? (
<div>No result found</div>
):(
<div>
<ToolkitProvider
keyField={"id"}
data={ data }
columns={ columns }
search
exportCSV
>
{
props => (
<div>
<Row>
<Col xl={6} xs={6}>
<div className="search-bar-wrapper">
<SearchBar { ...props.searchProps } />
</div>
</Col>
<Col xl={6} xs={6}>
<div className="table-option-button-group pull-right">
<Row>
{/* <div style={{paddingRight: 5}} className="switch-button-upper clearfix">
<small><b>Edit</b></small><br />
<AppSwitch className={'float-right'} variant={'pill'} label color={'success'} size={'sm'} onChange={() => this.toggleEditCell()} defaultChecked={editCellMode} />
</div> */}
<div className="clearfix">
{selectedRows.length === 1 && <Button style={{marginRight: 5}} onClick={this.getDataUpdate} size="sm" outline color="success"><i className="cil-pencil"></i></Button>}
{selectedRows.length > 0 && <Button onClick={() => this.setState({alertWarning: true})} size="sm" outline color="danger"><i className="cil-trash"></i></Button>}
<ExportCSVButton { ...props.csvProps }>
<Button color="success" size="sm" outline id="exportCSVTooltip">
<Icon icon={archiveOutline} width={20} height={20} />
</Button>
</ExportCSVButton>
<UncontrolledTooltip placement="top" target="exportCSVTooltip">
Export CSV
</UncontrolledTooltip>
</div>
</Row>
</div>
</Col>
</Row>
{/*<hr />*/}
<div className="table-wrapper">
<BootstrapTable
{ ...props.baseProps }
bootstrap4
keyField={"id"}
hover
pagination={ paginationFactory() }
noDataIndication={ 'No results found' }
selectRow={ selectRow }
cellEdit={ editCellMode ? cellEditFactory({
mode: 'click',
blurToSave: true,
timeToCloseMessage: 2500,
errorMessage: '',
afterSaveCell: (oldValue, newValue, row, column) => this.updateFunction(oldValue, newValue, row, column),
}) : false }
/>
</div>
</div>
)
}
</ToolkitProvider>
</div>
)}
</CardBody>
</Card>
</Col>
</Row>
</div>
)
}
}
export default DataTable;