wahyu
1 year ago
21 changed files with 5651 additions and 4196 deletions
@ -1,123 +1,141 @@
|
||||
import 'antd/dist/antd.css'; |
||||
import React, { Component } from 'react'; |
||||
import moment from 'moment'; |
||||
import { Button, Table, FormFeedback, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; |
||||
import Select from 'react-select'; |
||||
import axios from 'axios'; |
||||
import { BASE_SIMPRO_LUMEN, BASE_URL_GEOHR_API } from '../../../const/ApiConst'; |
||||
import { Transfer } from 'antd'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
const ERROR_TITLE = "judul is required!" |
||||
const ERROR_MESSAGE = "message is required!" |
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
let countError = 0; |
||||
class DialogDetail extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
dataListDetail: [], |
||||
id: 0, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
const { dataDetail } = this.props |
||||
console.log("cek data detail", dataDetail) |
||||
this.setState({ |
||||
id: dataDetail.id |
||||
}, () => { |
||||
this.getDataDetail(); |
||||
this.setState({ isParentClick: false }); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
getDataDetail = async () => { |
||||
countError++; |
||||
let url = BASE_SIMPRO_LUMEN + `/broadcast/search`; |
||||
const payload = { |
||||
"paging": { "start": 0, "length": 25 }, |
||||
"orders": { "columns": ["id"], "ascending": true }, |
||||
"columns": [ |
||||
{ "name": "id", "logic_operator": "=", "value": this.state.id, "operator": "AND" } |
||||
] |
||||
} |
||||
const result = await axios |
||||
.post(url, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
console.log('cek data detail', result.data) |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
if (result.data.data && result.data.data) { |
||||
this.setState({ dataListDetail: result.data.data }) |
||||
} |
||||
} else { |
||||
if (countError < 6) { |
||||
this.getDataDetail(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.props.closeDialog() |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal size="xl" isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.handleCloseDialog}>{this.props.t('broadcastDetail')}</ModalHeader> |
||||
<ModalBody> |
||||
<Table> |
||||
<thead> |
||||
<tr> |
||||
<th>{this.props.t('statusSend')}</th> |
||||
<th>{this.props.t('dateSend')}</th> |
||||
<th>{this.props.t('description')}</th> |
||||
<th>{this.props.t('titleNotification')}</th> |
||||
<th>{this.props.t('messageNotification')}</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{this.state.dataListDetail.map((val, index) => { |
||||
return ( |
||||
<tr key={index}> |
||||
<td>{val.status_send === "" ? "-" : val.status_send}</td> |
||||
<td>{val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")}</td> |
||||
<td>{val.description === "" ? "-" : val.description}</td> |
||||
<td>{val.title_notif === "" ? "-" : val.title_notif}</td> |
||||
<td>{val.message_notif === "" ? "-" : val.message_notif}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
|
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="secondary" onClick={this.handleCloseDialog}>{this.props.t('close')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogDetail); |
||||
import 'antd/dist/antd.css'; |
||||
import React, { Component } from 'react'; |
||||
import moment from 'moment'; |
||||
import { Button, Table, FormFeedback, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; |
||||
import Select from 'react-select'; |
||||
import axios from 'axios'; |
||||
import { BASE_SIMPRO_LUMEN, USER_LIST } from '../../../const/ApiConst'; |
||||
import { Transfer } from 'antd'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
const ERROR_TITLE = "judul is required!" |
||||
const ERROR_MESSAGE = "message is required!" |
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
let countError = 0; |
||||
class DialogDetail extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
dataListDetail: [], |
||||
id: 0, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
const { dataDetail } = this.props |
||||
console.log("cek data detail", dataDetail) |
||||
this.setState({ |
||||
id: dataDetail.id |
||||
}, () => { |
||||
this.getDataDetail(); |
||||
this.getDataUsers(); |
||||
this.setState({ isParentClick: false }); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
getDataUsers = async () => { |
||||
const result = await axios |
||||
.get(USER_LIST, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
console.log('Get Data User', result) |
||||
|
||||
if (result && result.data && result.status == 200) { |
||||
this.setState({ dataUser: result.data.data }, () => { |
||||
}); |
||||
} |
||||
} |
||||
|
||||
getDataDetail = async () => { |
||||
countError++; |
||||
let url = BASE_SIMPRO_LUMEN + `/broadcast/search`; |
||||
const payload = { |
||||
"paging": { "start": 0, "length": 25 }, |
||||
"orders": { "columns": ["id"], "ascending": true }, |
||||
"columns": [ |
||||
{ "name": "id", "logic_operator": "=", "value": this.state.id, "operator": "AND" } |
||||
] |
||||
} |
||||
const result = await axios |
||||
.post(url, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
console.log('cek data detail', result.data) |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
if (result.data.data && result.data.data) { |
||||
this.setState({ dataListDetail: result.data.data }) |
||||
} |
||||
} else { |
||||
if (countError < 6) { |
||||
this.getDataDetail(); |
||||
this.getDataUsers(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.props.closeDialog() |
||||
} |
||||
render() { |
||||
const dataUser = this.state.dataUser || []; |
||||
return ( |
||||
<Modal size="xl" isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.handleCloseDialog}>{this.props.t('broadcastDetail')}</ModalHeader> |
||||
<ModalBody> |
||||
<Table> |
||||
<thead> |
||||
<tr> |
||||
<th>{this.props.t('statusSend')}</th> |
||||
<th>{this.props.t('dateSend')}</th> |
||||
<th>{this.props.t('description')}</th> |
||||
<th>{this.props.t('receiver')}</th> |
||||
<th>{this.props.t('titleNotification')}</th> |
||||
<th>{this.props.t('messageNotification')}</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{this.state.dataListDetail.map((val, index) => { |
||||
const matchedUser = dataUser.find(item => item.id == val.send_to_id); |
||||
return ( |
||||
<tr key={index}> |
||||
<td>{val.status_send === "" ? "-" : val.status_send}</td> |
||||
<td>{val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")}</td> |
||||
<td>{val.description === "" ? "-" : val.description}</td> |
||||
<td>{ matchedUser ? matchedUser.name : "-" }</td> |
||||
<td>{val.title_notif === "" ? "-" : val.title_notif}</td> |
||||
<td>{val.message_notif === "" ? "-" : val.message_notif}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
|
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="secondary" onClick={this.handleCloseDialog}>{this.props.t('close')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogDetail); |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,166 +1,193 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
||||
import { Select } from 'antd'; |
||||
import moment from 'moment'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const { Option } = Select |
||||
|
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [url, setUrl] = useState('') |
||||
const [aliasName, setAliasName] = useState('') |
||||
const [icon, setIcon] = useState('') |
||||
const [sequence, setSequence] = useState(0) |
||||
const [parentId, setParentId] = useState(null) |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
console.log("data edit", dataEdit) |
||||
setId(dataEdit.id) |
||||
setName(dataEdit.name) |
||||
setUrl(dataEdit.url) |
||||
setIcon(dataEdit.icon) |
||||
setParentId(dataEdit.parent_id) |
||||
setSequence(dataEdit.sequence) |
||||
setAliasName(dataEdit.alias_name) |
||||
} else { |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name, |
||||
url, |
||||
sequence: parseInt(sequence), |
||||
icon, |
||||
alias_name: aliasName |
||||
} |
||||
|
||||
if (parentId && parentId > 0) { |
||||
data['parent_id'] = parentId |
||||
} |
||||
|
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name, |
||||
url, |
||||
sequence: parseInt(sequence), |
||||
icon, |
||||
alias_name: aliasName |
||||
} |
||||
|
||||
if (parentId && parentId > 0) { |
||||
data['parent_id'] = parentId |
||||
} |
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
|
||||
const onChangeParent = (val) => { |
||||
setParentId(val) |
||||
} |
||||
|
||||
const setupSelectParent = () => { |
||||
return ( |
||||
<> |
||||
{dataMenu.map((val, index) => { |
||||
return ( |
||||
<Option key={index} value={val.id}>{val.name}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')} Menu</Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">URL</Label> |
||||
<Input type="text" value={url} onChange={(e) => setUrl(e.target.value)} placeholder={t('inputUrl')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('icon')} </Label> |
||||
<Input type="text" value={icon} onChange={(e) => setIcon(e.target.value)} placeholder={t('inputIcon')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('order')}</Label> |
||||
<Input type="number" value={sequence} onChange={(e) => setSequence(e.target.value)} placeholder={t('inputOrder')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('parentMenu')}</Label> |
||||
<Select showSearch defaultValue={parentId} onChange={onChangeParent} placeholder={t('inputParentMenu')} style={{ width: '100%' }}> |
||||
{setupSelectParent()} |
||||
</Select> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Alias Menu</Label> |
||||
<Input type="text" value={aliasName} onChange={(e) => setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
|
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Tambah` : "Edit"} Menu</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
||||
import { Select } from 'antd'; |
||||
import moment from 'moment'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const { Option } = Select |
||||
|
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [url, setUrl] = useState('') |
||||
const [aliasName, setAliasName] = useState('') |
||||
const [icon, setIcon] = useState('') |
||||
const [sequence, setSequence] = useState(0) |
||||
const [parentId, setParentId] = useState(null) |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
console.log("data edit", dataEdit) |
||||
setId(dataEdit.id) |
||||
setName(dataEdit.name) |
||||
setUrl(dataEdit.url) |
||||
setIcon(dataEdit.icon) |
||||
setParentId(dataEdit.parent_id) |
||||
setSequence(dataEdit.sequence) |
||||
setAliasName(dataEdit.alias_name) |
||||
} else { |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const validation = () => { |
||||
if (!name || name === "") { |
||||
alert("Menu Name cannot be empty!"); |
||||
return true; |
||||
} |
||||
if (!url || url === "") { |
||||
alert("URL cannot be empty!"); |
||||
return true; |
||||
} |
||||
if (!icon || icon === "") { |
||||
alert("Icon cannot be empty!"); |
||||
return true; |
||||
} |
||||
if (sequence < 0) { |
||||
alert("Order cannot be empty!"); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
const err = validation(); |
||||
if (!err) { |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name, |
||||
url, |
||||
sequence: parseInt(sequence), |
||||
icon, |
||||
alias_name: aliasName |
||||
} |
||||
|
||||
if (parentId && parentId > 0) { |
||||
data['parent_id'] = parentId |
||||
} |
||||
|
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name, |
||||
url, |
||||
sequence: parseInt(sequence), |
||||
icon, |
||||
alias_name: aliasName |
||||
} |
||||
|
||||
if (parentId && parentId > 0) { |
||||
data['parent_id'] = parentId |
||||
} |
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setUrl('') |
||||
setIcon('') |
||||
setParentId(null) |
||||
setSequence(0) |
||||
setAliasName('') |
||||
} |
||||
|
||||
const onChangeParent = (val) => { |
||||
setParentId(val) |
||||
} |
||||
|
||||
const setupSelectParent = () => { |
||||
return ( |
||||
<> |
||||
{dataMenu.map((val, index) => { |
||||
return ( |
||||
<Option key={index} value={val.id}>{val.name}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')} Menu<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">URL<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={url} onChange={(e) => setUrl(e.target.value)} placeholder={t('inputUrl')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('icon')}<span style={{ color: "red" }}>*</span> </Label> |
||||
<Input type="text" value={icon} onChange={(e) => setIcon(e.target.value)} placeholder={t('inputIcon')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('order')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" min="0" value={sequence} onChange={(e) => setSequence(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputOrder')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('parentMenu')}</Label> |
||||
<Select showSearch defaultValue={parentId} onChange={onChangeParent} placeholder={t('inputParentMenu')} style={{ width: '100%' }}> |
||||
{setupSelectParent()} |
||||
</Select> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Alias Menu</Label> |
||||
<Input type="text" value={aliasName} onChange={(e) => setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
|
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Tambah` : "Edit"} Menu</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
|
@ -1,377 +1,371 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from 'axios'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE } from '../../../const/ApiConst.js'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip, Table } from 'antd'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
const column = [ |
||||
{ name: "Nama" }, |
||||
{ name: "Url" }, |
||||
{ name: "Ikon" }, |
||||
{ name: "Alias" }, |
||||
{ name: "Urutan" }, |
||||
{ name: "Parent" }, |
||||
] |
||||
|
||||
const Index = ({ params }) => { |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [search, setSearch] = useState('') |
||||
const [tooltipDelete, setTooltipDelete] = useState(false) |
||||
const [tooltipEdit, setTooltipEdit] = useState(false) |
||||
const [tooltipExport, setTooltipExport] = useState(false) |
||||
const [tooltipTambah, setTooltipTambah] = useState(false) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const { t } = useTranslation() |
||||
const pageName = params.name; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
|
||||
useEffect(() => { |
||||
getDataMenu(); |
||||
getDataAllMenu(); |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
getDataMenu(); |
||||
}, [search, currentPage, rowsPerPage]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const getDataAllMenu = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setAllDataMenu(result.data.data); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
const getDataMenu = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging": { "start": start, "length": rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [{ |
||||
"name": "m_menu", |
||||
"column_join": "parent_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
}], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleOpenDialog = async (type) => { |
||||
await setTypeDialog(type) |
||||
setOpenDialog(true) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveMenu(data); |
||||
} else if (type === "edit") { |
||||
editMenu(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
const url = MENU_DELETE(idDelete) |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data menu berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data menu gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const saveMenu = async (data) => { |
||||
const formData = data |
||||
|
||||
const result = await axios.post(MENU_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu(); |
||||
getDataAllMenu(); |
||||
NotificationManager.success(`Data menu berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
const editMenu = async (data) => { |
||||
const formData = data |
||||
const url = MENU_EDIT(data.id) |
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu(); |
||||
NotificationManager.success(`Data menu berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data menu gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const toggle = (param) => { |
||||
if (param === "edit") { |
||||
setTooltipEdit(!tooltipEdit) |
||||
} else if (param === "delete") { |
||||
setTooltipDelete(!tooltipDelete) |
||||
} else if (param === "tambah") { |
||||
setTooltipTambah(!tooltipTambah) |
||||
} else if (param === "export") { |
||||
setTooltipExport(!tooltipExport) |
||||
} |
||||
} |
||||
|
||||
const handleExportExcel = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [{ |
||||
"name": "m_menu", |
||||
"column_join": "parent_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
}], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((val, index) => { |
||||
let dataRow = { |
||||
"Nama": val.name, |
||||
"Url": val.url, |
||||
"Icon": val.icon, |
||||
"Alias Name": val.alias_name, |
||||
"Urutan": val.sequence, |
||||
"Parent Name": val.join_first_name ? val.join_first_name : "-" |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const exportExcel = () => { |
||||
const dataExcel = dataExport || []; |
||||
const fileName = `Data ${pageName}.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||
XLSX.writeFile(wb, fileName); |
||||
setDataExport([]) |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const renderTable = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
<Tooltip title={t('delete')}> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
{ title: t('name'), dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Url', dataIndex: 'url', key: 'url' }, |
||||
{ title: t('icon'), dataIndex: 'icon', key: 'icon' }, |
||||
{ title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' }, |
||||
{ title: t('order'), dataIndex: 'sequence', key: 'sequence' }, |
||||
{ title: t('parentMenu'), dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") } |
||||
]; |
||||
return ( |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={t('deleteConfirm')} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
{t('deleteMsg')} |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataMenu={allDataMenu} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchMenu')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('menuAdd')}> |
||||
<Button id="TooltipTambah" color="success" onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
{renderTable} |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
current={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Index; |
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from 'axios'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE } from '../../../const/ApiConst.js'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip, Table } from 'antd'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
const column = [ |
||||
{ name: "Nama" }, |
||||
{ name: "Url" }, |
||||
{ name: "Ikon" }, |
||||
{ name: "Alias" }, |
||||
{ name: "Urutan" }, |
||||
{ name: "Parent" }, |
||||
] |
||||
|
||||
const Index = ({ params }) => { |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [search, setSearch] = useState('') |
||||
const [tooltipDelete, setTooltipDelete] = useState(false) |
||||
const [tooltipEdit, setTooltipEdit] = useState(false) |
||||
const [tooltipExport, setTooltipExport] = useState(false) |
||||
const [tooltipTambah, setTooltipTambah] = useState(false) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const { t } = useTranslation() |
||||
const pageName = params.name; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
useEffect(() => { |
||||
getDataMenu(); |
||||
}, [search, currentPage, rowsPerPage]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const getDataAllMenu = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": "", "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setAllDataMenu(result.data.data); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
const getDataMenu = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging": { "start": start, "length": rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [{ |
||||
"name": "m_menu", |
||||
"column_join": "parent_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
}], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleOpenDialog = async (type) => { |
||||
await setTypeDialog(type) |
||||
setOpenDialog(true) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveMenu(data); |
||||
} else if (type === "edit") { |
||||
editMenu(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
const url = MENU_DELETE(idDelete) |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data menu berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data menu gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const saveMenu = async (data) => { |
||||
const formData = data |
||||
|
||||
const result = await axios.post(MENU_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu(); |
||||
getDataAllMenu(); |
||||
NotificationManager.success(`Data menu berhasil ditambahkan`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data menu gagal ditambahkan`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
const editMenu = async (data) => { |
||||
const formData = data |
||||
const url = MENU_EDIT(data.id) |
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataMenu(); |
||||
NotificationManager.success(`Data menu berhasil diubah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data menu gagal diubah`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const toggle = (param) => { |
||||
if (param === "edit") { |
||||
setTooltipEdit(!tooltipEdit) |
||||
} else if (param === "delete") { |
||||
setTooltipDelete(!tooltipDelete) |
||||
} else if (param === "tambah") { |
||||
setTooltipTambah(!tooltipTambah) |
||||
} else if (param === "export") { |
||||
setTooltipExport(!tooltipExport) |
||||
} |
||||
} |
||||
|
||||
const handleExportExcel = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [{ |
||||
"name": "m_menu", |
||||
"column_join": "parent_id", |
||||
"column_results": [ |
||||
"name" |
||||
] |
||||
}], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(MENU_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((val, index) => { |
||||
let dataRow = { |
||||
"Nama": val.name, |
||||
"Url": val.url, |
||||
"Icon": val.icon, |
||||
"Alias Name": val.alias_name, |
||||
"Urutan": val.sequence, |
||||
"Parent Name": val.join_first_name ? val.join_first_name : "-" |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const exportExcel = () => { |
||||
const dataExcel = dataExport || []; |
||||
const fileName = `Data ${pageName}.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||
XLSX.writeFile(wb, fileName); |
||||
setDataExport([]) |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const renderTable = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
<Tooltip title={t('delete')}> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
{ title: t('name'), dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Url', dataIndex: 'url', key: 'url' }, |
||||
{ title: t('icon'), dataIndex: 'icon', key: 'icon' }, |
||||
{ title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' }, |
||||
{ title: t('order'), dataIndex: 'sequence', key: 'sequence' }, |
||||
{ title: t('parentMenu'), dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") } |
||||
]; |
||||
return ( |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={t('deleteConfirm')} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
{t('deleteMsg')} |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataMenu={allDataMenu} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchMenu')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('menuAdd')}> |
||||
<Button id="TooltipTambah" color="success" onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
{renderTable} |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
current={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Index; |
||||
|
@ -1,112 +1,136 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
name: "", |
||||
description: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
if (this.props.typeDialog === "Edit") { |
||||
const { dataEdit } = this.props |
||||
this.setState({ |
||||
id: dataEdit.id, |
||||
name: dataEdit.name, |
||||
description: dataEdit.description |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
id: 0, |
||||
name: "", |
||||
description: "" |
||||
}) |
||||
} |
||||
this.setState({ isParentClick: false }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
|
||||
handleSave = () => { |
||||
const { |
||||
id, |
||||
name, |
||||
description |
||||
} = this.state |
||||
|
||||
let data = ''; |
||||
if (this.props.typeDialog === "Save") { |
||||
data = { |
||||
id, |
||||
name, |
||||
description |
||||
} |
||||
this.props.closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name, |
||||
description |
||||
} |
||||
this.props.closeDialog('edit', data); |
||||
} |
||||
|
||||
this.setState({ id: 0 }); |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const { t } = this.props; |
||||
return ( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label>{this.props.t('nameRole')}</Label> |
||||
<Input type="text" value={this.state.name} onChange={(e) => this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('description')}</Label> |
||||
<Input type="text" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('roles')}</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogForm); |
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
name: "", |
||||
description: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate() { |
||||
if (this.state.isParentClick === true) { |
||||
if (this.props.typeDialog === "Edit") { |
||||
const { dataEdit } = this.props |
||||
this.setState({ |
||||
id: dataEdit.id, |
||||
name: dataEdit.name, |
||||
description: dataEdit.description |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
id: 0, |
||||
name: "", |
||||
description: "" |
||||
}) |
||||
} |
||||
this.setState({ isParentClick: false }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
validation = () => { |
||||
if (!this.state.name || this.state.name === "") { |
||||
alert("Role Name cannot be empty!"); |
||||
return true; |
||||
} |
||||
if (!this.state.description || this.state.description === "") { |
||||
alert("Description cannot be empty!"); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
handleSave = () => { |
||||
const { |
||||
id, |
||||
name, |
||||
description |
||||
} = this.state |
||||
|
||||
let data = ''; |
||||
const err = this.validation(); |
||||
if(!err) { |
||||
if (this.props.typeDialog === "Save") { |
||||
data = { |
||||
id, |
||||
name, |
||||
description |
||||
} |
||||
this.props.closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name, |
||||
description |
||||
} |
||||
this.props.closeDialog('edit', data); |
||||
} |
||||
this.setState({ id: 0 }); |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const { t } = this.props; |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={12}> |
||||
<FormGroup> |
||||
<Label>{this.props.t('nameRole')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={this.state.name} onChange={(e) => this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={12}> |
||||
<FormGroup> |
||||
<Label>{this.props.t('description')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input type="text" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('roles')}</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogForm); |
||||
|
@ -1,340 +1,340 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Button, Tooltip } from 'antd'; |
||||
import { |
||||
CHECKLIST_K3_ADD, CHECKLIST_K3_EDIT, CHECKLIST_K3_DELETE, CHECKLIST_K3_SEARCH |
||||
} from '../../../const/ApiConst'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const ChecklistK3 = ({ params }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const pageName = params.name; |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [search, setSearch] = useState('') |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const { t } = useTranslation() |
||||
const column = [ |
||||
{ name: t('name') }, |
||||
{ name: t('description') }, |
||||
] |
||||
useEffect(() => { |
||||
getDataChecklistK3() |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const getDataChecklistK3 = async () => { |
||||
|
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "ilike", |
||||
"value": search, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"ascending": true, |
||||
"columns": [ |
||||
'id' |
||||
] |
||||
}, |
||||
"paging": { |
||||
"length": rowsPerPage, |
||||
"start": start |
||||
} |
||||
} |
||||
const result = await axios |
||||
.post(CHECKLIST_K3_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleExportExcel = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CHECKLIST_K3_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((val, index) => { |
||||
let dataRow = { |
||||
"Nama": val.name, |
||||
"Deskripsi": val.description, |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const exportExcel = () => { |
||||
const dataExcel = dataExport || []; |
||||
const fileName = `Data ${pageName}.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||
XLSX.writeFile(wb, fileName); |
||||
setDataExport([]) |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveChecklistK3(data); |
||||
} else if (type === "edit") { |
||||
editChecklistK3(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveChecklistK3 = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(CHECKLIST_K3_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3() |
||||
NotificationManager.success(`Data project type berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editChecklistK3 = async (data) => { |
||||
|
||||
let urlEdit = CHECKLIST_K3_EDIT(data.id) |
||||
const formData = data |
||||
const result = await axios.put(urlEdit, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3(); |
||||
NotificationManager.success(`Data project type berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data project type gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = CHECKLIST_K3_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data project type berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data project type gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const dataNotAvailable = () => { |
||||
if (dataTable.length === 0) { |
||||
return ( |
||||
<tr> |
||||
<td align="center" colSpan="3">{t('noData')}</td> |
||||
</tr> |
||||
) |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={t('deleteConfirm')} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
{t('deleteMsg')} |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataParent={allDataMenu} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchChecklistK3')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('ChecklistK3Add')}> |
||||
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>{t('action')}</th> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{dataNotAvailable()} |
||||
{dataTable.map((n, index) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td className='nowrap'> |
||||
<Tooltip title={t('delete')}> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i> |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.name}</td> |
||||
<td>{n.description}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ChecklistK3; |
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Button, Tooltip } from 'antd'; |
||||
import { |
||||
CHECKLIST_K3_ADD, CHECKLIST_K3_EDIT, CHECKLIST_K3_DELETE, CHECKLIST_K3_SEARCH |
||||
} from '../../../const/ApiConst'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const ChecklistK3 = ({ params }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const pageName = params.name; |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [search, setSearch] = useState('') |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const { t } = useTranslation() |
||||
const column = [ |
||||
{ name: t('name') }, |
||||
{ name: t('description') }, |
||||
] |
||||
useEffect(() => { |
||||
getDataChecklistK3() |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const getDataChecklistK3 = async () => { |
||||
|
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "ilike", |
||||
"value": search, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"ascending": true, |
||||
"columns": [ |
||||
'id' |
||||
] |
||||
}, |
||||
"paging": { |
||||
"length": rowsPerPage, |
||||
"start": start |
||||
} |
||||
} |
||||
const result = await axios |
||||
.post(CHECKLIST_K3_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleExportExcel = async () => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CHECKLIST_K3_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((val, index) => { |
||||
let dataRow = { |
||||
"Nama": val.name, |
||||
"Deskripsi": val.description, |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const exportExcel = () => { |
||||
const dataExcel = dataExport || []; |
||||
const fileName = `Data ${pageName}.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||
XLSX.writeFile(wb, fileName); |
||||
setDataExport([]) |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveChecklistK3(data); |
||||
} else if (type === "edit") { |
||||
editChecklistK3(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveChecklistK3 = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(CHECKLIST_K3_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3() |
||||
NotificationManager.success(`Checklist K3 berhasil disimpan!`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editChecklistK3 = async (data) => { |
||||
|
||||
let urlEdit = CHECKLIST_K3_EDIT(data.id) |
||||
const formData = data |
||||
const result = await axios.put(urlEdit, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3(); |
||||
NotificationManager.success(`Checklist K3 berhasil diubah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Checklist K3 gagal diubah`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = CHECKLIST_K3_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataChecklistK3() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Checklist K3 berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Checklist K3 gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const dataNotAvailable = () => { |
||||
if (dataTable.length === 0) { |
||||
return ( |
||||
<tr> |
||||
<td align="center" colSpan="3">{t('noData')}</td> |
||||
</tr> |
||||
) |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={t('deleteConfirm')} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
{t('deleteMsg')} |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataParent={allDataMenu} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchChecklistK3')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('ChecklistK3Add')}> |
||||
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>{t('action')}</th> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{dataNotAvailable()} |
||||
{dataTable.map((n, index) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td className='nowrap'> |
||||
<Tooltip title={t('delete')}> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i> |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.name}</td> |
||||
<td>{n.description}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ChecklistK3; |
||||
|
@ -1,123 +1,174 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
||||
import axios from "../../../const/interceptorApi"; |
||||
import { VERSION_GANTT_ADD } from '../../../const/ApiConst'; |
||||
import { Select } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parentId }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState("") |
||||
const [description, setDesctription] = useState("") |
||||
const [calculationType, setCalculationType] = useState("detail") |
||||
const handleCLearData = () => { |
||||
setId(0) |
||||
setName("") |
||||
setDesctription("") |
||||
} |
||||
|
||||
useEffect(() => { |
||||
handleCLearData() |
||||
}, [openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
saveVersionGantt() |
||||
handleCLearData() |
||||
} |
||||
|
||||
const saveVersionGantt = async () => { |
||||
|
||||
const formData = { |
||||
name_version: name, |
||||
description, |
||||
calculation_type: calculationType, |
||||
proyek_id: idTask, |
||||
hierarchy_ftth_id: parentId |
||||
|
||||
} |
||||
const result = await axios |
||||
.post(VERSION_GANTT_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
closeDialog('success') |
||||
} else { |
||||
closeDialog('failed') |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel') |
||||
handleCLearData() |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label className="capitalize">Nama <span style={{ color: "red" }}>*</span> </Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder='' /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Deskripsi </Label> |
||||
<Input type="textarea" value={description} onChange={(e) => setDesctription(e.target.value)} placeholder='' /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Tipe Kalkulasi </Label> |
||||
<div> |
||||
<Select |
||||
defaultValue="detail" |
||||
style={{ |
||||
width: 120, |
||||
}} |
||||
onChange={(v) => setCalculationType(v)} |
||||
options={[ |
||||
{ |
||||
value: 'detail', |
||||
label: 'Detail', |
||||
}, |
||||
{ |
||||
value: 'simple', |
||||
label: 'Simple', |
||||
}, |
||||
]} |
||||
/> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div> |
||||
Notes: |
||||
</div> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>Add Gantt Project</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>Save</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogFormGantt; |
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
||||
import axios from "../../../const/interceptorApi"; |
||||
import { VERSION_GANTT_ADD, VERSION_GANTT_EDIT } from '../../../const/ApiConst'; |
||||
import { Select } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
const DialogFormGantt = ({ openDialog, closeDialog, toggleDialog, idTask, parentId, dataEdit, typeDialog}) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState("") |
||||
const [description, setDesctription] = useState("") |
||||
const [calculationType, setCalculationType] = useState("detail") |
||||
const handleCLearData = () => { |
||||
setId(0) |
||||
setName("") |
||||
setDesctription("") |
||||
} |
||||
const validation = () => { |
||||
if (!name || name === "") { |
||||
alert("Gantt Name cannot be empty!"); |
||||
return true; |
||||
} |
||||
} |
||||
useEffect(() => { |
||||
if(typeDialog === "Edit") |
||||
{ |
||||
setId(dataEdit.id); |
||||
setName(dataEdit.name_version); |
||||
setDesctription(dataEdit.description); |
||||
setCalculationType(dataEdit.calculation_type); |
||||
} else { |
||||
handleCLearData() |
||||
} |
||||
|
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
const err = validation(); |
||||
if (!err) { |
||||
if (typeDialog === "Edit") { |
||||
data = { |
||||
id, |
||||
name, |
||||
description, |
||||
calculationType |
||||
}; |
||||
editVersionGantt(data) |
||||
} else { |
||||
saveVersionGantt() |
||||
} |
||||
handleCLearData() |
||||
} |
||||
} |
||||
|
||||
const saveVersionGantt = async () => { |
||||
|
||||
const formData = { |
||||
name_version: name, |
||||
description, |
||||
calculation_type: calculationType, |
||||
proyek_id: idTask, |
||||
hierarchy_ftth_id: parentId |
||||
|
||||
} |
||||
const result = await axios |
||||
.post(VERSION_GANTT_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
closeDialog('Save') |
||||
} else { |
||||
closeDialog('failed') |
||||
} |
||||
} |
||||
|
||||
const editVersionGantt = async (data) => { |
||||
|
||||
const formData = { |
||||
name_version: data.name, |
||||
description:data.description, |
||||
calculation_type: data.calculationType, |
||||
proyek_id: idTask, |
||||
hierarchy_ftth_id: parentId |
||||
|
||||
} |
||||
const url = VERSION_GANTT_EDIT(data.id); |
||||
const result = await axios.put(url, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
closeDialog('Edit') |
||||
} else { |
||||
closeDialog('failed') |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel') |
||||
handleCLearData() |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label className="capitalize">Nama <span style={{ color: "red" }}>*</span> </Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)}/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Deskripsi </Label> |
||||
<Input type="textarea" value={description} onChange={(e) => setDesctription(e.target.value)}/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Tipe Kalkulasi </Label> |
||||
<div> |
||||
<Select |
||||
value={calculationType} |
||||
defaultValue={calculationType} |
||||
style={{ |
||||
width: 120, |
||||
}} |
||||
onChange={(v) => setCalculationType(v)} |
||||
options={[ |
||||
{ |
||||
value: 'detail', |
||||
label: 'Detail', |
||||
}, |
||||
{ |
||||
value: 'simple', |
||||
label: 'Simple', |
||||
}, |
||||
]} |
||||
/> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div> |
||||
Notes: |
||||
</div> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Edit" ? "Edit" :"Tambah"} Gantt Project</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog == "Edit" ? "Update" :"Save"}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogFormGantt; |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,276 +1,293 @@
|
||||
import React, { useEffect, useState, useMemo } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Breadcrumb, BreadcrumbItem} from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Table, Tooltip } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import moment from 'moment'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import { VERSION_GANTT_DELETE, VERSION_GANTT_SEARCH, USER_LIST } from '../../../const/ApiConst'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import DialogForm from './DialogFormGantt'; |
||||
import DialogUserGantt from './DialogUserGantt'; |
||||
|
||||
import { Link } from 'react-router-dom'; |
||||
|
||||
const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName, hierarchyId, hierarchyName, openDialogHierarchy }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const [openDialogForm, setOpenDialogForm] = useState(false) |
||||
const [openDialogUserGantt, setOpenDialogUserGantt] = useState(false) |
||||
const [dataGantt, setDataGantt] = useState([]) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [idGantt, setIdGantt] = useState(0) |
||||
const [humanResource, setHumanResource] = useState([]) |
||||
|
||||
useEffect(() => { |
||||
if (openDialog && hierarchyId > 0 || idTask > 0 && !openDialogHierarchy) { |
||||
getdataGantt(); |
||||
} |
||||
if (!openDialog) { |
||||
setDataGantt([]); |
||||
} |
||||
}, [hierarchyId, idTask, openDialog]) |
||||
|
||||
const getDataHumanResource = async () => { |
||||
const result = await axios |
||||
.get(USER_LIST, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
setTransferUser(result.data.data); |
||||
} else { |
||||
|
||||
} |
||||
} |
||||
|
||||
const setTransferUser = (data) => { |
||||
const finalData = [] |
||||
data.map((val, index) => { |
||||
let data = { |
||||
key: val.id, |
||||
title: val.name |
||||
} |
||||
finalData.push(data) |
||||
}); |
||||
setHumanResource(finalData) |
||||
} |
||||
|
||||
|
||||
const getdataGantt = async () => { |
||||
let payload; |
||||
if (hierarchyId) { |
||||
payload = { |
||||
"select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], |
||||
"columns": [ |
||||
{ "name": "hierarchy_ftth_id", "logic_operator": "=", "value": hierarchyId, "operator": "AND" } |
||||
] |
||||
} |
||||
} else { |
||||
payload = { |
||||
"select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], |
||||
"columns": [ |
||||
{ "name": "proyek_id", "logic_operator": "=", "value": idTask, "operator": "AND" } |
||||
] |
||||
} |
||||
} |
||||
const result = await axios |
||||
.post(VERSION_GANTT_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
setDataGantt(result.data.data); |
||||
} else { |
||||
NotificationManager.error(`Data gantt project gagal terload silahkan coba lagi!`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
setDataGantt([]); |
||||
closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
const handleDelete = (id) => { |
||||
setIdDelete(id) |
||||
setAlertDelete(true) |
||||
} |
||||
|
||||
const handleUserGant = (id) => { |
||||
setIdGantt(id) |
||||
setOpenDialogUserGantt(true) |
||||
} |
||||
|
||||
const RenderTable = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: 'Action', |
||||
dataIndex: '', |
||||
key: 'id', |
||||
className: "nowrap", |
||||
render: (text, record) => |
||||
<> |
||||
<Tooltip title="Delete Gantt"> |
||||
<Button size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Tooltip title="Gantt Permission"> |
||||
<Button size={"sm"} color='success' onClick={() => handleUserGant(text.id)}><i className="fa fa-users"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Link to={`/projects/${text.id}/${idTask}/import/activity`}> |
||||
{" "}<Tooltip title="Import Activity"> |
||||
<Button size={"sm"} color='success'> |
||||
<i className="fa fa-file-excel-o"></i> |
||||
</Button> |
||||
</Tooltip>{" "} |
||||
</Link> |
||||
|
||||
<Link to={`/projects/${text.id}/${idTask}/gantt`}> |
||||
<Tooltip title="Gantt"> |
||||
<Button size={"sm"} color='primary'><i className="fa fa-gears"></i></Button> |
||||
</Tooltip></Link>{" "} |
||||
</> |
||||
, |
||||
}, |
||||
{ title: 'Nama', dataIndex: 'name_version', key: 'name_version' }, |
||||
{ title: 'Tipe kalkulasi', dataIndex: 'calculation_type', key: 'calculation_type' }, |
||||
{ title: 'Deskripsi', dataIndex: 'description', key: 'description' }, |
||||
{ title: 'Tanggal dibuat', dataIndex: 'created_at', key: 'created_at', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY") : "-"}</div>) }, |
||||
{ title: 'Progress', dataIndex: 'progress', key: 'progress' } |
||||
|
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
rowKey={"id"} |
||||
dataSource={dataGantt} |
||||
pagination={{ position: ["bottomLeft"] }} |
||||
/> |
||||
) |
||||
}, [dataGantt]) |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let urlDel = VERSION_GANTT_DELETE(idDelete) |
||||
const result = await axios.delete(urlDel, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getdataGantt() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Dokumen project berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Dokumen project gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const handleOpenDialogForm = () => { |
||||
setOpenDialogForm(true) |
||||
} |
||||
|
||||
const toggleDialogForm = () => { |
||||
setOpenDialogForm(!openDialogForm) |
||||
} |
||||
|
||||
const closeDialogForm = (status) => { |
||||
if (status == "success") { |
||||
getdataGantt() |
||||
NotificationManager.success(`Gantt berhasil dibuat!`, 'Success!!'); |
||||
} else if (status == "failed") { |
||||
NotificationManager.error(`Gantt gagal dibuat!`, 'Failed!!'); |
||||
} |
||||
setOpenDialogForm(false) |
||||
} |
||||
|
||||
const toggleDialogUser = () => { |
||||
if (openDialogUserGantt) { |
||||
setIdGantt(0) |
||||
} |
||||
setOpenDialogUserGantt(!openDialogUserGantt) |
||||
} |
||||
|
||||
const closeDialogUser = (status) => { |
||||
if (status == "success") { |
||||
NotificationManager.success(`Gantt Permission berhasil disimpan!`, 'Success!!'); |
||||
} else if (status == "failed") { |
||||
NotificationManager.error(`Gantt Permission gagal disimpan!`, 'Failed!!'); |
||||
} |
||||
setOpenDialogUserGantt(false) |
||||
setIdGantt(0) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}> |
||||
{hierarchyName ? |
||||
<Breadcrumb> |
||||
<BreadcrumbItem><a href="/projects">Project</a></BreadcrumbItem> |
||||
<BreadcrumbItem active>{hierarchyName}</BreadcrumbItem> |
||||
</Breadcrumb> |
||||
:
|
||||
<div>Gantt Project {proyekName} </div> |
||||
} |
||||
{!hierarchyId && (<> <Button onClick={handleOpenDialogForm} size='sm' color="primary"><i className='fa fa-plus'></i></Button> |
||||
</> |
||||
)} |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
<div style={{ width: '100%', overflow: "auto" }}> |
||||
{RenderTable} |
||||
</div> |
||||
</ModalBody> |
||||
{/* <ModalFooter> |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
||||
</ModalFooter> */} |
||||
</Modal> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={`Are you sure?`} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
Delete this data |
||||
</SweetAlert> |
||||
<DialogForm |
||||
idTask={idTask} |
||||
openDialog={openDialogForm} |
||||
toggleDialog={toggleDialogForm} |
||||
closeDialog={closeDialogForm} |
||||
/> |
||||
|
||||
<DialogUserGantt |
||||
idGantt={idGantt} |
||||
openDialog={openDialogUserGantt} |
||||
toggleDialog={toggleDialogUser} |
||||
closeDialog={closeDialogUser} |
||||
/> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogGantt; |
||||
import React, { useEffect, useState, useMemo } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Breadcrumb, BreadcrumbItem} from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Table, Tooltip } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import moment from 'moment'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import { VERSION_GANTT_DELETE, VERSION_GANTT_SEARCH, USER_LIST } from '../../../const/ApiConst'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import DialogForm from './DialogFormGantt'; |
||||
import DialogUserGantt from './DialogUserGantt'; |
||||
|
||||
import { Link } from 'react-router-dom'; |
||||
|
||||
const DialogGantt = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName, hierarchyId, hierarchyName, openDialogHierarchy }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const [openDialogForm, setOpenDialogForm] = useState(false) |
||||
const [openDialogUserGantt, setOpenDialogUserGantt] = useState(false) |
||||
const [dataGantt, setDataGantt] = useState([]) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [idGantt, setIdGantt] = useState(0) |
||||
const [humanResource, setHumanResource] = useState([]) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [typeDialog, setTypeDialog] = useState('') |
||||
|
||||
useEffect(() => { |
||||
if (openDialog && hierarchyId > 0 || idTask > 0 && !openDialogHierarchy) { |
||||
getdataGantt(); |
||||
} |
||||
if (!openDialog) { |
||||
setDataGantt([]); |
||||
} |
||||
}, [hierarchyId, idTask, openDialog]) |
||||
|
||||
const getDataHumanResource = async () => { |
||||
const result = await axios |
||||
.get(USER_LIST, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
setTransferUser(result.data.data); |
||||
} else { |
||||
|
||||
} |
||||
} |
||||
|
||||
const setTransferUser = (data) => { |
||||
const finalData = [] |
||||
data.map((val, index) => { |
||||
let data = { |
||||
key: val.id, |
||||
title: val.name |
||||
} |
||||
finalData.push(data) |
||||
}); |
||||
setHumanResource(finalData) |
||||
} |
||||
|
||||
|
||||
const getdataGantt = async () => { |
||||
let payload; |
||||
if (hierarchyId) { |
||||
payload = { |
||||
"select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], |
||||
"columns": [ |
||||
{ "name": "hierarchy_ftth_id", "logic_operator": "=", "value": hierarchyId, "operator": "AND" } |
||||
] |
||||
} |
||||
} else { |
||||
payload = { |
||||
"select": ["id", "name_version", "calculation_type", "description", "created_at", "progress"], |
||||
"columns": [ |
||||
{ "name": "proyek_id", "logic_operator": "=", "value": idTask, "operator": "AND" } |
||||
] |
||||
} |
||||
} |
||||
const result = await axios |
||||
.post(VERSION_GANTT_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.status == 200) { |
||||
setDataGantt(result.data.data); |
||||
} else { |
||||
NotificationManager.error(`Data gantt project gagal terload silahkan coba lagi!`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
setDataGantt([]); |
||||
closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
const handleDelete = (id) => { |
||||
setIdDelete(id) |
||||
setAlertDelete(true) |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialogForm('Edit'); |
||||
} |
||||
|
||||
const handleUserGant = (id) => { |
||||
setIdGantt(id) |
||||
setOpenDialogUserGantt(true) |
||||
} |
||||
|
||||
const RenderTable = useMemo(() => { |
||||
const columns = [ |
||||
{ |
||||
title: 'Action', |
||||
dataIndex: '', |
||||
key: 'id', |
||||
className: "nowrap", |
||||
render: (text, record) => |
||||
<> |
||||
<Tooltip title="Delete Gantt"> |
||||
<Button size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Tooltip title="Edit Gantt"> |
||||
<Button size={"sm"} color='success' onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Tooltip title="Gantt Permission"> |
||||
<Button size={"sm"} color='success' onClick={() => handleUserGant(text.id)}><i className="fa fa-users"></i></Button> |
||||
</Tooltip>{" "} |
||||
<Link to={`/projects/${text.id}/${idTask}/import/activity`}> |
||||
{" "}<Tooltip title="Import Activity"> |
||||
<Button size={"sm"} color='success'> |
||||
<i className="fa fa-file-excel-o"></i> |
||||
</Button> |
||||
</Tooltip>{" "} |
||||
</Link> |
||||
|
||||
<Link to={`/projects/${text.id}/${idTask}/gantt`}> |
||||
<Tooltip title="Gantt"> |
||||
<Button size={"sm"} color='primary'><i className="fa fa-gears"></i></Button> |
||||
</Tooltip></Link>{" "} |
||||
</> |
||||
, |
||||
}, |
||||
{ title: 'Nama', dataIndex: 'name_version', key: 'name_version' }, |
||||
{ title: 'Tipe kalkulasi', dataIndex: 'calculation_type', key: 'calculation_type' }, |
||||
{ title: 'Deskripsi', dataIndex: 'description', key: 'description' }, |
||||
{ title: 'Tanggal dibuat', dataIndex: 'created_at', key: 'created_at', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY") : "-"}</div>) }, |
||||
{ title: 'Progress', dataIndex: 'progress', key: 'progress' } |
||||
|
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
rowKey={"id"} |
||||
dataSource={dataGantt} |
||||
pagination={{ position: ["bottomLeft"] }} |
||||
/> |
||||
) |
||||
}, [dataGantt]) |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let urlDel = VERSION_GANTT_DELETE(idDelete) |
||||
const result = await axios.delete(urlDel, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getdataGantt() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Dokumen project berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Dokumen project gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const handleOpenDialogForm = async (type) => { |
||||
await setTypeDialog(type); |
||||
setOpenDialogForm(true); |
||||
} |
||||
|
||||
const toggleDialogForm = () => { |
||||
setOpenDialogForm(!openDialogForm) |
||||
} |
||||
|
||||
const closeDialogForm = (status) => { |
||||
if (status == "Save") { |
||||
getdataGantt() |
||||
NotificationManager.success(`Gantt berhasil dibuat!`, 'Success!!'); |
||||
}else if (status == "Edit") { |
||||
getdataGantt() |
||||
NotificationManager.success(`Gantt berhasil dibubah!`, 'Failed!!'); |
||||
}else if (status == "failed") { |
||||
NotificationManager.error(`Gantt gagal dibuat!`, 'Failed!!'); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialogForm(false) |
||||
} |
||||
|
||||
const toggleDialogUser = () => { |
||||
if (openDialogUserGantt) { |
||||
setIdGantt(0) |
||||
} |
||||
setOpenDialogUserGantt(!openDialogUserGantt) |
||||
} |
||||
|
||||
const closeDialogUser = (status) => { |
||||
if (status == "success") { |
||||
NotificationManager.success(`Gantt Permission berhasil disimpan!`, 'Success!!'); |
||||
} else if (status == "failed") { |
||||
NotificationManager.error(`Gantt Permission gagal disimpan!`, 'Failed!!'); |
||||
} |
||||
setOpenDialogUserGantt(false) |
||||
setIdGantt(0) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}> |
||||
{hierarchyName ? |
||||
<Breadcrumb> |
||||
<BreadcrumbItem><a href="/projects">Project</a></BreadcrumbItem> |
||||
<BreadcrumbItem active>{hierarchyName}</BreadcrumbItem> |
||||
</Breadcrumb> |
||||
: |
||||
<div>Gantt Project {proyekName} </div> |
||||
} |
||||
{!hierarchyId && (<> <Button onClick={handleOpenDialogForm} size='sm' color="primary"><i className='fa fa-plus'></i></Button> |
||||
</> |
||||
)} |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
<div style={{ width: '100%', overflow: "auto" }}> |
||||
{RenderTable} |
||||
</div> |
||||
</ModalBody> |
||||
{/* <ModalFooter> |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
||||
</ModalFooter> */} |
||||
</Modal> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={`Are you sure?`} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
Delete this data |
||||
</SweetAlert> |
||||
<DialogForm |
||||
idTask={idTask} |
||||
openDialog={openDialogForm} |
||||
toggleDialog={toggleDialogForm} |
||||
closeDialog={closeDialogForm} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
/> |
||||
|
||||
<DialogUserGantt |
||||
idGantt={idGantt} |
||||
openDialog={openDialogUserGantt} |
||||
toggleDialog={toggleDialogUser} |
||||
closeDialog={closeDialogUser} |
||||
/> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogGantt; |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,117 +1,137 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import { Select } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
const { Option } = Select |
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataDivisions }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [parent, setParent] = useState(null) |
||||
const [description, setDescription] = useState('') |
||||
const { t } = useTranslation() |
||||
|
||||
const onChangeParent = (val) => { |
||||
setParent(val) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setDescription(dataEdit.description) |
||||
setName(dataEdit.name) |
||||
setParent(dataEdit.parent) |
||||
} else { |
||||
setId(0) |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: name, |
||||
description, |
||||
parent |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name: name, |
||||
description, |
||||
parent |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
setDescription('') |
||||
} |
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setDescription('') |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')}</Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('nameDivision')}</Label> |
||||
<Select showSearch |
||||
value={parent} |
||||
onChange={onChangeParent} |
||||
style={{ width: '100%' }} |
||||
filterOption={(input, option) => option.children.toLowerCase().includes(input.toLowerCase())} |
||||
> |
||||
{dataDivisions.map((res, idx) => ( |
||||
<Option key={res['id']} value={res['id']}>{res['displayName']}</Option> |
||||
))} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('description')}</Label> |
||||
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('division')}</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import { Select } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
const { Option } = Select |
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataDivisions }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [parent, setParent] = useState(null) |
||||
const [description, setDescription] = useState('') |
||||
const { t } = useTranslation() |
||||
|
||||
const onChangeParent = (val) => { |
||||
setParent(val) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setDescription(dataEdit.description) |
||||
setName(dataEdit.name) |
||||
setParent(dataEdit.parent) |
||||
} else { |
||||
setId(0) |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const validation = () => { |
||||
if (!name || name === "") { |
||||
alert("Division Name cannot be empty!"); |
||||
return true; |
||||
} |
||||
} |
||||
const handleSave = () => { |
||||
let data = ''; |
||||
const err = validation(); |
||||
|
||||
if (!err) { |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: name, |
||||
description, |
||||
parent |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name: name, |
||||
description, |
||||
parent |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
setDescription('') |
||||
setName('') |
||||
} |
||||
} |
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setDescription('') |
||||
setName('') |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={12}> |
||||
<span style={{ color: "red" }}>*</span> Wajib diisi. |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')}<span style={{ color: "red" }}>*</span></Label> |
||||
<Input |
||||
type="text" |
||||
value={name} |
||||
onChange={(e) => setName(e.target.value)} |
||||
placeholder={t('inputName')} |
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('nameDivision')}</Label> |
||||
<Select showSearch |
||||
value={parent} |
||||
onChange={onChangeParent} |
||||
style={{ width: '100%' }} |
||||
filterOption={(input, option) => option.children.toLowerCase().includes(input.toLowerCase())} |
||||
> |
||||
{dataDivisions.map((res, idx) => ( |
||||
<Option key={res['id']} value={res['id']}>{res['displayName']}</Option> |
||||
))} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row> |
||||
<Col md={12}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('description')}</Label> |
||||
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('division')}</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
|
@ -1,399 +1,399 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import DialogEdit from './DialogEdit'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { Component } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup } from 'reactstrap'; |
||||
import { DatePicker } from 'antd'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { PANIC_BUTTON_UPDATE, PANIC_BUTTON_SEARCH } from '../../../const/ApiConst'; |
||||
import { Pagination, Tooltip } from 'antd'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
const id_org = window.localStorage.getItem('id_org'); |
||||
const roleName = window.localStorage.getItem('role_name'); |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const { RangePicker } = DatePicker; |
||||
|
||||
const momentFormat = 'HH:mm'; |
||||
|
||||
|
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
alertDelete: false, |
||||
currentDay: 'today', |
||||
currentPage: 1, |
||||
dataEdit: null, |
||||
dataExport: [], |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
dataMap: "", |
||||
dataTable: [], |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
idDelete: 0, |
||||
openDialog: false, |
||||
openDialogEdit: false, |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
search: "", |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
tooltipDelete: false, |
||||
tooltipExport: false, |
||||
tooltipMap: false, |
||||
totalPage: 0, |
||||
typeClock: "All", |
||||
typeDialog: 'Save', |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataPanicButton(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search, startDate } = this.state |
||||
if (search !== prevState.search) this.getDataPanicButton() |
||||
if (startDate !== prevState.startDate) this.getDataPanicButton() |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataPanicButton = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
|
||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
||||
|
||||
const payload = { |
||||
"paging": { |
||||
"start": start, |
||||
"length": this.state.rowsPerPage |
||||
}, |
||||
"filter_columns": [ |
||||
{ |
||||
"name": "name", |
||||
"value": "", |
||||
"table_name": "m_users" |
||||
} |
||||
], |
||||
"columns": [ |
||||
{ "name": "created_at", "logic_operator": "range", "value": dateStart, "value1": dateEnd, "operator": "AND" }, |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND", "table_name": "m_users" } |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name": "m_users", |
||||
"column_join": "user_id", |
||||
"column_results": [ |
||||
"name", |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PANIC_BUTTON_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data) { |
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord, dataExport: result.data.data_export }); |
||||
} else { |
||||
NotificationManager.error('Gagal Menerima Data!!', 'Failed'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
if (type === "Map") { |
||||
this.setState({ openDialog: true }) |
||||
this.showChildDialog(); |
||||
} else { |
||||
this.setState({ openDialogEdit: true }) |
||||
this.showDialogEdit(); |
||||
} |
||||
|
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
handleCloseDialogEdit = (type, data) => { |
||||
if (type === "save") { |
||||
this.updateStatusResponse(data); |
||||
} |
||||
this.setState({ openDialogEdit: false }) |
||||
} |
||||
|
||||
toggleMapDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
toggleEditDialog = () => { |
||||
this.setState({ openDialogEdit: !this.state.openDialogEdit }); |
||||
} |
||||
|
||||
handleMap = data => { |
||||
this.setState({ dataMap: data }); |
||||
this.handleOpenDialog('Map'); |
||||
} |
||||
|
||||
handleEdit = data => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "map") { |
||||
this.setState(prevState => ({ tooltipMap: !prevState.tooltipMap })) |
||||
} else if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
} |
||||
|
||||
handleDatePicker = (date, dateString) => { |
||||
this.setState({ startDate: date[0], endDate: date[1] }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
handleTipe = (e) => { |
||||
this.setState({ typeClock: e.target.value }, () => { |
||||
this.getDataPanicButton(); |
||||
}); |
||||
} |
||||
|
||||
handleExportExcel = () => { |
||||
const dataExcel = this.state.dataTable || []; |
||||
const fileName = "Panic Button.xlsx"; |
||||
let dataExport = []; |
||||
dataExcel.map((val) => { |
||||
let row = { |
||||
"Tanggal": moment(val.created_date).format("DD-MM-YYYY HH:MM:SS"), |
||||
"Nama Karyawan": val.join_first_name, |
||||
"Latitude": val.lat, |
||||
"Longitude": val.lon, |
||||
"Status": val.status_response |
||||
} |
||||
dataExport.push(row); |
||||
}) |
||||
const ws = XLSX.utils.json_to_sheet(dataExport); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Panic Button'); |
||||
|
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
updateStatusResponse = async (data) => { |
||||
let url = PANIC_BUTTON_UPDATE(data.id); |
||||
let payload = { |
||||
"user_id": data.user_id, |
||||
"lat": data.lat, |
||||
"lon": data.lon, |
||||
"status_response": data.status_response, |
||||
"description": "update data panic" |
||||
|
||||
} |
||||
|
||||
const result = await axios |
||||
.put(url, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data) { |
||||
if (result.data.code == 200) { |
||||
this.getDataPanicButton() |
||||
NotificationManager.success('Berhasil update status response!!', 'Success!'); |
||||
} else { |
||||
NotificationManager.error('Gagal update status response!!', 'Failed'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
renderTable = () => { |
||||
const t = this.props; |
||||
const dataTable2 = this.state.dataTable || []; |
||||
return ( |
||||
<tbody> |
||||
{dataTable2.length !== 0 ? dataTable2.map((n) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td> |
||||
<Tooltip title={this.props.t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer", marginRight: 15 }} onClick={() => this.handleEdit(n)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={this.props.t('map')}> |
||||
<i id="tooltipMap" className="fa fa-map" style={{ color: 'black', cursor: "pointer" }} onClick={() => this.handleMap(n)}></i> |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.created_date !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"}</td> |
||||
<td>{n.join_first_name !== null ? n.join_first_name : "-"}</td> |
||||
<td>{n.status_response !== null ? n.status_response : "-"}</td> |
||||
</tr> |
||||
) |
||||
}) : <tr> |
||||
<td colSpan="4" align="center">No Data Available</td> |
||||
</tr> |
||||
} |
||||
</tbody> |
||||
) |
||||
} |
||||
|
||||
handleChangeDay = (e) => { |
||||
const val = e.target.value; |
||||
this.setState({ currentDay: val }); |
||||
if (val === "today") { |
||||
this.setState({ |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else if (val === "3 day") { |
||||
this.setState({ |
||||
startDate: moment(moment().subtract(3, "days").format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else if (val === "7 day") { |
||||
this.setState({ |
||||
startDate: moment(moment().subtract(7, "days").format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
const column = [ |
||||
{ name: this.props.t('action') }, |
||||
{ name: this.props.t('date') }, |
||||
{ name: this.props.t('nameHR') }, |
||||
{ name: this.props.t('statusResponse') }, |
||||
] |
||||
const t = this.props; |
||||
const { tooltipExport, dataTable, openDialogEdit, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipMap, tooltipDelete } = this.state |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleMapDialog} |
||||
dataMap={this.state.dataMap} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
/> |
||||
<DialogEdit |
||||
openDialog={openDialogEdit} |
||||
closeDialog={this.handleCloseDialogEdit} |
||||
toggleDialog={() => this.toggleEditDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showDialogEdit = showDialog} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>{this.props.t('panicButton')}</h4> |
||||
<div> |
||||
<Tooltip title={this.props.t('exportExcel')}> |
||||
<Button id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</div> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: "25px" }}> |
||||
<div style={{ width: "100%", display: "inline-flex", alignItems: "center" }}> |
||||
<div style={{ width: "50%", marginRight: "10px", maxWidth: "200px" }}> |
||||
<Input type="select" onChange={(e) => this.handleChangeDay(e)} defaultValue={this.state.currentDay}> |
||||
<option value="today">{this.props.t('today')}</option> |
||||
<option value="3 day">{this.props.t('3days')}</option> |
||||
<option value="7 day">{this.props.t('7days')}</option> |
||||
</Input> |
||||
</div> |
||||
<div style={{ width: "50%" }}> |
||||
<RangePicker format={"DD-MM-YYYY"} size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker} />{' '} |
||||
<Button color="primary" onClick={() => this.getDataPanicButton()}>{this.props.t('search')}</Button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
{this.renderTable()} |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={parseInt(totalPage)} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(index); |
||||
import * as XLSX from 'xlsx'; |
||||
import DialogEdit from './DialogEdit'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { Component } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import { Button } from 'reactstrap'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup } from 'reactstrap'; |
||||
import { DatePicker } from 'antd'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { PANIC_BUTTON_UPDATE, PANIC_BUTTON_SEARCH } from '../../../const/ApiConst'; |
||||
import { Pagination, Tooltip } from 'antd'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
const id_org = window.localStorage.getItem('id_org'); |
||||
const roleName = window.localStorage.getItem('role_name'); |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const { RangePicker } = DatePicker; |
||||
|
||||
const momentFormat = 'HH:mm'; |
||||
|
||||
|
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
alertDelete: false, |
||||
currentDay: 'today', |
||||
currentPage: 1, |
||||
dataEdit: null, |
||||
dataExport: [], |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
dataMap: "", |
||||
dataTable: [], |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
idDelete: 0, |
||||
openDialog: false, |
||||
openDialogEdit: false, |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
search: "", |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
tooltipDelete: false, |
||||
tooltipExport: false, |
||||
tooltipMap: false, |
||||
totalPage: 0, |
||||
typeClock: "All", |
||||
typeDialog: 'Save', |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataPanicButton(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search, startDate } = this.state |
||||
if (search !== prevState.search) this.getDataPanicButton() |
||||
if (startDate !== prevState.startDate) this.getDataPanicButton() |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataPanicButton = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
|
||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
||||
|
||||
const payload = { |
||||
"paging": { |
||||
"start": start, |
||||
"length": this.state.rowsPerPage |
||||
}, |
||||
"filter_columns": [ |
||||
{ |
||||
"name": "name", |
||||
"value": "", |
||||
"table_name": "m_users" |
||||
} |
||||
], |
||||
"columns": [ |
||||
{ "name": "created_at", "logic_operator": "range", "value": dateStart, "value1": dateEnd, "operator": "AND" }, |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND", "table_name": "m_users" } |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name": "m_users", |
||||
"column_join": "user_id", |
||||
"column_results": [ |
||||
"name", |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PANIC_BUTTON_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data) { |
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord, dataExport: result.data.data_export }); |
||||
} else { |
||||
NotificationManager.error('Gagal Menerima Data!!', 'Failed'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
if (type === "Map") { |
||||
this.setState({ openDialog: true }) |
||||
this.showChildDialog(); |
||||
} else { |
||||
this.setState({ openDialogEdit: true }) |
||||
this.showDialogEdit(); |
||||
} |
||||
|
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
handleCloseDialogEdit = (type, data) => { |
||||
if (type === "save") { |
||||
this.updateStatusResponse(data); |
||||
} |
||||
this.setState({ openDialogEdit: false }) |
||||
} |
||||
|
||||
toggleMapDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
toggleEditDialog = () => { |
||||
this.setState({ openDialogEdit: !this.state.openDialogEdit }); |
||||
} |
||||
|
||||
handleMap = data => { |
||||
this.setState({ dataMap: data }); |
||||
this.handleOpenDialog('Map'); |
||||
} |
||||
|
||||
handleEdit = data => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "map") { |
||||
this.setState(prevState => ({ tooltipMap: !prevState.tooltipMap })) |
||||
} else if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
} |
||||
|
||||
handleDatePicker = (date, dateString) => { |
||||
this.setState({ startDate: date[0], endDate: date[1] }, () => { |
||||
this.getDataPanicButton(); |
||||
}) |
||||
} |
||||
|
||||
handleTipe = (e) => { |
||||
this.setState({ typeClock: e.target.value }, () => { |
||||
this.getDataPanicButton(); |
||||
}); |
||||
} |
||||
|
||||
handleExportExcel = () => { |
||||
const dataExcel = this.state.dataTable || []; |
||||
const fileName = "Panic Button.xlsx"; |
||||
let dataExport = []; |
||||
dataExcel.map((val) => { |
||||
let row = { |
||||
"Tanggal": moment(val.created_at).format("DD-MM-YYYY HH:MM:SS"), |
||||
"Nama Karyawan": val.join_first_name, |
||||
"Latitude": val.lat, |
||||
"Longitude": val.lon, |
||||
"Status": val.status_response |
||||
} |
||||
dataExport.push(row); |
||||
}) |
||||
const ws = XLSX.utils.json_to_sheet(dataExport); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Panic Button'); |
||||
|
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
updateStatusResponse = async (data) => { |
||||
let url = PANIC_BUTTON_UPDATE(data.id); |
||||
let payload = { |
||||
"user_id": data.user_id, |
||||
"lat": data.lat, |
||||
"lon": data.lon, |
||||
"status_response": data.status_response, |
||||
"description": "update data panic" |
||||
|
||||
} |
||||
|
||||
const result = await axios |
||||
.put(url, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data) { |
||||
if (result.data.code == 200) { |
||||
this.getDataPanicButton() |
||||
NotificationManager.success('Berhasil update status response!!', 'Success!'); |
||||
} else { |
||||
NotificationManager.error('Gagal update status response!!', 'Failed'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
renderTable = () => { |
||||
const t = this.props; |
||||
const dataTable2 = this.state.dataTable || []; |
||||
return ( |
||||
<tbody> |
||||
{dataTable2.length !== 0 ? dataTable2.map((n) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td> |
||||
<Tooltip title={this.props.t('edit')}> |
||||
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer", marginRight: 15 }} onClick={() => this.handleEdit(n)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={this.props.t('map')}> |
||||
<i id="tooltipMap" className="fa fa-map" style={{ color: 'black', cursor: "pointer" }} onClick={() => this.handleMap(n)}></i> |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.created_at !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"}</td> |
||||
<td>{n.join_first_name !== null ? n.join_first_name : "-"}</td> |
||||
<td>{n.status_response !== null ? n.status_response : "-"}</td> |
||||
</tr> |
||||
) |
||||
}) : <tr> |
||||
<td colSpan="4" align="center">No Data Available</td> |
||||
</tr> |
||||
} |
||||
</tbody> |
||||
) |
||||
} |
||||
|
||||
handleChangeDay = (e) => { |
||||
const val = e.target.value; |
||||
this.setState({ currentDay: val }); |
||||
if (val === "today") { |
||||
this.setState({ |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else if (val === "3 day") { |
||||
this.setState({ |
||||
startDate: moment(moment().subtract(3, "days").format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else if (val === "7 day") { |
||||
this.setState({ |
||||
startDate: moment(moment().subtract(7, "days").format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
startDate: moment(moment().format("YYYY-M-D")), |
||||
endDate: moment(moment().format("YYYY-M-D")), |
||||
currentPage: 1 |
||||
}) |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
const column = [ |
||||
{ name: this.props.t('action') }, |
||||
{ name: this.props.t('date') }, |
||||
{ name: this.props.t('nameHR') }, |
||||
{ name: this.props.t('statusResponse') }, |
||||
] |
||||
const t = this.props; |
||||
const { tooltipExport, dataTable, openDialogEdit, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipMap, tooltipDelete } = this.state |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleMapDialog} |
||||
dataMap={this.state.dataMap} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
/> |
||||
<DialogEdit |
||||
openDialog={openDialogEdit} |
||||
closeDialog={this.handleCloseDialogEdit} |
||||
toggleDialog={() => this.toggleEditDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showDialogEdit = showDialog} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>{this.props.t('panicButton')}</h4> |
||||
<div> |
||||
<Tooltip title={this.props.t('exportExcel')}> |
||||
<Button id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</div> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom: "25px" }}> |
||||
<div style={{ width: "100%", display: "inline-flex", alignItems: "center" }}> |
||||
<div style={{ width: "50%", marginRight: "10px", maxWidth: "200px" }}> |
||||
<Input type="select" onChange={(e) => this.handleChangeDay(e)} defaultValue={this.state.currentDay}> |
||||
<option value="today">{this.props.t('today')}</option> |
||||
<option value="3 day">{this.props.t('3days')}</option> |
||||
<option value="7 day">{this.props.t('7days')}</option> |
||||
</Input> |
||||
</div> |
||||
<div style={{ width: "50%" }}> |
||||
<RangePicker format={"DD-MM-YYYY"} size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker} />{' '} |
||||
<Button color="primary" onClick={() => this.getDataPanicButton()}>{this.props.t('search')}</Button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
{this.renderTable()} |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={parseInt(totalPage)} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(index); |
||||
|
Loading…
Reference in new issue