ibnu
1 year ago
25 changed files with 7271 additions and 5753 deletions
@ -1,140 +1,142 @@
|
||||
{ |
||||
"name": "simpro-web", |
||||
"version": "0.0.1", |
||||
"description": "Sistem Informasi Manajemen Proyek", |
||||
"author": "Ardhi", |
||||
"homepage": ".", |
||||
"copyright": "Copyright Integrasia Utama", |
||||
"license": "MIT", |
||||
"private": true, |
||||
"repository": { |
||||
"type": "http", |
||||
"url": "https://git.oslog.id/iu/simpro-website.git" |
||||
}, |
||||
"dependencies": { |
||||
"@ant-design/plots": "^1.1.1", |
||||
"@coreui/coreui": "^2.1.12", |
||||
"@coreui/icons": "0.3.0", |
||||
"@coreui/react": "^2.5.1", |
||||
"@dabeng/react-orgchart": "^1.0.0", |
||||
"@develoka/angka-rupiah-js": "^1.0.3", |
||||
"@faker-js/faker": "^7.3.0", |
||||
"@iconify/icons-ant-design": "^1.0.6", |
||||
"@iconify/icons-fa-solid": "^1.0.6", |
||||
"@iconify/icons-fe": "^1.0.3", |
||||
"@iconify/icons-geo": "^1.0.3", |
||||
"@iconify/icons-ion": "^1.0.7", |
||||
"@iconify/icons-mdi": "^1.0.57", |
||||
"@iconify/icons-uil": "^1.0.6", |
||||
"@iconify/react": "^1.1.1", |
||||
"@nicholasadamou/react-iframe": "^1.0.3", |
||||
"@reduxjs/toolkit": "^1.9.2", |
||||
"@terrestris/ol-util": "^7.2.0", |
||||
"@terrestris/react-geo": "^12.0.0", |
||||
"alasql": "^1.7.3", |
||||
"antd": "^4.16.13", |
||||
"axios": "^0.21.1", |
||||
"bootstrap": "^4.3.1", |
||||
"chart.js": "^3.9.1", |
||||
"chartjs-plugin-datalabels": "^2.1.0", |
||||
"chartjs-plugin-zoom": "^0.7.7", |
||||
"classnames": "^2.2.6", |
||||
"core-js": "^3.1.4", |
||||
"dhtmlx-gantt": "^7.1.7", |
||||
"dom-to-image": "^2.6.0", |
||||
"enzyme": "^3.10.0", |
||||
"enzyme-adapter-react-16": "^1.14.0", |
||||
"flag-icon-css": "^3.3.0", |
||||
"font-awesome": "^4.7.0", |
||||
"i18next": "^22.4.9", |
||||
"interactjs": "^1.10.11", |
||||
"jspdf": "^2.5.1", |
||||
"jspdf-autotable": "^3.5.25", |
||||
"leaflet": "^1.8.0", |
||||
"leaflet-control-geocoder": "^2.4.0", |
||||
"leaflet-draw": "^1.0.4", |
||||
"leaflet.markercluster": "^1.5.3", |
||||
"moment": "^2.24.0", |
||||
"node-sass": "^4.12.0", |
||||
"numeral": "^2.0.6", |
||||
"ol": "^5.3.3", |
||||
"prop-types": "^15.7.2", |
||||
"rc-color-picker": "^1.2.6", |
||||
"re-resizable": "^6.9.9", |
||||
"react": "^16.14.0", |
||||
"react-app-polyfill": "^1.0.1", |
||||
"react-awesome-query-builder": "^4.3.0", |
||||
"react-bootstrap-sweetalert": "^5.1.9", |
||||
"react-bootstrap-table-next": "^3.3.3", |
||||
"react-bootstrap-table2-editor": "^1.4.0", |
||||
"react-bootstrap-table2-paginator": "^2.1.0", |
||||
"react-bootstrap-table2-toolkit": "^2.1.1", |
||||
"react-calendar-timeline": "^0.27.0", |
||||
"react-chartjs-2": "^4.3.1", |
||||
"react-color": "^2.17.3", |
||||
"react-content-loader": "^6.0.3", |
||||
"react-dom": "^16.14.0", |
||||
"react-excel-renderer": "^1.1.0", |
||||
"react-grid-layout": "^1.2.5", |
||||
"react-highlight-words": "^0.18.0", |
||||
"react-i18next": "^12.1.5", |
||||
"react-leaflet": "^3.2.0", |
||||
"react-leaflet-draw": "^0.19.8", |
||||
"react-loader-spinner": "^3.1.5", |
||||
"react-notifications": "^1.7.2", |
||||
"react-redux": "^8.0.5", |
||||
"react-router-dom": "^5.0.1", |
||||
"react-select": "^4.3.1", |
||||
"react-slick": "^0.28.1", |
||||
"react-tiny-fab": "^4.0.4", |
||||
"react-toastify": "^5.5.0", |
||||
"reactstrap": "^8.0.0", |
||||
"redux": "^4.2.1", |
||||
"redux-persist": "^6.0.0", |
||||
"redux-thunk": "^2.4.2", |
||||
"simple-line-icons": "^2.4.1", |
||||
"slick-carousel": "^1.8.1", |
||||
"underscore": "^1.13.1", |
||||
"xlsx": "^0.17.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.14.5", |
||||
"babel-plugin-module-resolver": "^4.1.0", |
||||
"clean-webpack-plugin": "^3.0.0", |
||||
"cypress": "^12.17.2", |
||||
"react-scripts": "^3.0.1", |
||||
"webpack-sources": "1.0.1" |
||||
}, |
||||
"scripts": { |
||||
"start": "react-scripts start", |
||||
"build": "react-scripts --max_old_space_size=8096 build", |
||||
"test": "react-scripts test", |
||||
"test:cov": "npm test -- --coverage --watchAll=false", |
||||
"test:debug": "react-scripts --inspect-brk test --runInBand", |
||||
"eject": "react-scripts eject" |
||||
}, |
||||
"bugs": { |
||||
"url": "https://git.oslog.id/iu/simpro-website/issues" |
||||
}, |
||||
"eslintConfig": { |
||||
"extends": "react-app" |
||||
}, |
||||
"browserslist": [ |
||||
">0.2%", |
||||
"not dead", |
||||
"not ie <= 9", |
||||
"not op_mini all" |
||||
], |
||||
"jest": { |
||||
"collectCoverageFrom": [ |
||||
"src/**/*.{js,jsx}", |
||||
"!**/*index.js", |
||||
"!src/serviceWorker.js", |
||||
"!src/polyfill.js" |
||||
] |
||||
}, |
||||
"engines": { |
||||
"node": ">=8.10", |
||||
"npm": ">=6" |
||||
} |
||||
} |
||||
{ |
||||
"name": "simpro-web", |
||||
"version": "0.0.1", |
||||
"description": "Sistem Informasi Manajemen Proyek", |
||||
"author": "Ardhi", |
||||
"homepage": ".", |
||||
"copyright": "Copyright Integrasia Utama", |
||||
"license": "MIT", |
||||
"private": true, |
||||
"repository": { |
||||
"type": "http", |
||||
"url": "https://git.oslog.id/iu/simpro-website.git" |
||||
}, |
||||
"dependencies": { |
||||
"@ant-design/plots": "^1.1.1", |
||||
"@ckeditor/ckeditor5-build-classic": "^39.0.2", |
||||
"@ckeditor/ckeditor5-react": "^6.1.0", |
||||
"@coreui/coreui": "^2.1.12", |
||||
"@coreui/icons": "0.3.0", |
||||
"@coreui/react": "^2.5.1", |
||||
"@dabeng/react-orgchart": "^1.0.0", |
||||
"@develoka/angka-rupiah-js": "^1.0.3", |
||||
"@faker-js/faker": "^7.3.0", |
||||
"@iconify/icons-ant-design": "^1.0.6", |
||||
"@iconify/icons-fa-solid": "^1.0.6", |
||||
"@iconify/icons-fe": "^1.0.3", |
||||
"@iconify/icons-geo": "^1.0.3", |
||||
"@iconify/icons-ion": "^1.0.7", |
||||
"@iconify/icons-mdi": "^1.0.57", |
||||
"@iconify/icons-uil": "^1.0.6", |
||||
"@iconify/react": "^1.1.1", |
||||
"@nicholasadamou/react-iframe": "^1.0.3", |
||||
"@reduxjs/toolkit": "^1.9.2", |
||||
"@terrestris/ol-util": "^7.2.0", |
||||
"@terrestris/react-geo": "^12.0.0", |
||||
"alasql": "^1.7.3", |
||||
"antd": "^4.16.13", |
||||
"axios": "^0.21.1", |
||||
"bootstrap": "^4.3.1", |
||||
"chart.js": "^3.9.1", |
||||
"chartjs-plugin-datalabels": "^2.1.0", |
||||
"chartjs-plugin-zoom": "^0.7.7", |
||||
"classnames": "^2.2.6", |
||||
"core-js": "^3.1.4", |
||||
"dhtmlx-gantt": "^7.1.7", |
||||
"dom-to-image": "^2.6.0", |
||||
"enzyme": "^3.10.0", |
||||
"enzyme-adapter-react-16": "^1.14.0", |
||||
"flag-icon-css": "^3.3.0", |
||||
"font-awesome": "^4.7.0", |
||||
"i18next": "^22.4.9", |
||||
"interactjs": "^1.10.11", |
||||
"jspdf": "^2.5.1", |
||||
"jspdf-autotable": "^3.5.25", |
||||
"leaflet": "^1.8.0", |
||||
"leaflet-control-geocoder": "^2.4.0", |
||||
"leaflet-draw": "^1.0.4", |
||||
"leaflet.markercluster": "^1.5.3", |
||||
"moment": "^2.24.0", |
||||
"node-sass": "^4.12.0", |
||||
"numeral": "^2.0.6", |
||||
"ol": "^5.3.3", |
||||
"prop-types": "^15.7.2", |
||||
"rc-color-picker": "^1.2.6", |
||||
"re-resizable": "^6.9.9", |
||||
"react": "^16.14.0", |
||||
"react-app-polyfill": "^1.0.1", |
||||
"react-awesome-query-builder": "^4.3.0", |
||||
"react-bootstrap-sweetalert": "^5.1.9", |
||||
"react-bootstrap-table-next": "^3.3.3", |
||||
"react-bootstrap-table2-editor": "^1.4.0", |
||||
"react-bootstrap-table2-paginator": "^2.1.0", |
||||
"react-bootstrap-table2-toolkit": "^2.1.1", |
||||
"react-calendar-timeline": "^0.27.0", |
||||
"react-chartjs-2": "^4.3.1", |
||||
"react-color": "^2.17.3", |
||||
"react-content-loader": "^6.0.3", |
||||
"react-dom": "^16.14.0", |
||||
"react-excel-renderer": "^1.1.0", |
||||
"react-grid-layout": "^1.2.5", |
||||
"react-highlight-words": "^0.18.0", |
||||
"react-i18next": "^12.1.5", |
||||
"react-leaflet": "^3.2.0", |
||||
"react-leaflet-draw": "^0.19.8", |
||||
"react-loader-spinner": "^3.1.5", |
||||
"react-notifications": "^1.7.2", |
||||
"react-redux": "^8.0.5", |
||||
"react-router-dom": "^5.0.1", |
||||
"react-select": "^4.3.1", |
||||
"react-slick": "^0.28.1", |
||||
"react-tiny-fab": "^4.0.4", |
||||
"react-toastify": "^5.5.0", |
||||
"reactstrap": "^8.0.0", |
||||
"redux": "^4.2.1", |
||||
"redux-persist": "^6.0.0", |
||||
"redux-thunk": "^2.4.2", |
||||
"simple-line-icons": "^2.4.1", |
||||
"slick-carousel": "^1.8.1", |
||||
"underscore": "^1.13.1", |
||||
"xlsx": "^0.17.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.14.5", |
||||
"babel-plugin-module-resolver": "^4.1.0", |
||||
"clean-webpack-plugin": "^3.0.0", |
||||
"cypress": "^12.17.2", |
||||
"react-scripts": "^3.0.1", |
||||
"webpack-sources": "1.0.1" |
||||
}, |
||||
"scripts": { |
||||
"start": "react-scripts start", |
||||
"build": "react-scripts --max_old_space_size=8096 build", |
||||
"test": "react-scripts test", |
||||
"test:cov": "npm test -- --coverage --watchAll=false", |
||||
"test:debug": "react-scripts --inspect-brk test --runInBand", |
||||
"eject": "react-scripts eject" |
||||
}, |
||||
"bugs": { |
||||
"url": "https://git.oslog.id/iu/simpro-website/issues" |
||||
}, |
||||
"eslintConfig": { |
||||
"extends": "react-app" |
||||
}, |
||||
"browserslist": [ |
||||
">0.2%", |
||||
"not dead", |
||||
"not ie <= 9", |
||||
"not op_mini all" |
||||
], |
||||
"jest": { |
||||
"collectCoverageFrom": [ |
||||
"src/**/*.{js,jsx}", |
||||
"!**/*index.js", |
||||
"!src/serviceWorker.js", |
||||
"!src/polyfill.js" |
||||
] |
||||
}, |
||||
"engines": { |
||||
"node": ">=8.10", |
||||
"npm": ">=6" |
||||
} |
||||
} |
||||
|
@ -1,99 +1,99 @@
|
||||
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'; |
||||
|
||||
const { Option } = Select |
||||
|
||||
const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu}) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [descripton, setDescription] = useState('') |
||||
const [status, setStatus] = useState('') |
||||
|
||||
|
||||
useEffect(()=> { |
||||
if(typeDialog==="Edit"){ |
||||
console.log("data edit", dataEdit) |
||||
setId(dataEdit.id) |
||||
setName(dataEdit.nama) |
||||
setDescription(dataEdit.keterangan) |
||||
setStatus(dataEdit.status) |
||||
}else{ |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
setStatus('') |
||||
} |
||||
},[dataEdit,openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if(typeDialog==="Save"){ |
||||
data = { |
||||
nama:name, |
||||
keterangan:descripton, |
||||
status |
||||
} |
||||
|
||||
closeDialog('save', data); |
||||
}else{ |
||||
data = { |
||||
id, |
||||
nama:name, |
||||
keterangan:descripton, |
||||
status |
||||
} |
||||
|
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
setStatus('') |
||||
} |
||||
|
||||
|
||||
const renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label className="capitalize">Nama Alert</Label> |
||||
<Input type="text" value={name} onChange={(e)=> setName(e.target.value)} placeholder={`Waspang tidak sesuai target..`}/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Keterangan</Label> |
||||
<Input type="text" value={descripton} onChange={(e)=> setDescription(e.target.value)} placeholder={`Rencana vs actual tidak sesuai..`} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Status</Label> |
||||
<Input type="text" value={status} onChange={(e)=> setStatus(e.target.value)} placeholder={`Warning..`} /> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog=="Save" ? `Tambah` : "Edit"} Config Alert</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</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'; |
||||
|
||||
const { Option } = Select |
||||
|
||||
const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataMenu}) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [descripton, setDescription] = useState('') |
||||
const [status, setStatus] = useState('') |
||||
|
||||
|
||||
useEffect(()=> { |
||||
if(typeDialog==="Edit"){ |
||||
console.log("data edit", dataEdit) |
||||
setId(dataEdit.id) |
||||
setName(dataEdit.nama) |
||||
setDescription(dataEdit.keterangan) |
||||
setStatus(dataEdit.status) |
||||
}else{ |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
setStatus('') |
||||
} |
||||
},[dataEdit,openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if(typeDialog==="Save"){ |
||||
data = { |
||||
nama:name, |
||||
keterangan:descripton, |
||||
status |
||||
} |
||||
|
||||
closeDialog('save', data); |
||||
}else{ |
||||
data = { |
||||
id, |
||||
nama:name, |
||||
keterangan:descripton, |
||||
status |
||||
} |
||||
|
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
setStatus('') |
||||
} |
||||
|
||||
|
||||
const renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label className="capitalize">Nama Alert</Label> |
||||
<Input type="text" value={name} onChange={(e)=> setName(e.target.value)} placeholder={`Waspang tidak sesuai target..`}/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Keterangan</Label> |
||||
<Input type="text" value={descripton} onChange={(e)=> setDescription(e.target.value)} placeholder={`Rencana vs actual tidak sesuai..`} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Status</Label> |
||||
<Input type="text" value={status} onChange={(e)=> setStatus(e.target.value)} placeholder={`Warning..`} /> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog=="Save" ? `Tambah` : "Edit"} Config Alert</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
|
@ -1,172 +1,172 @@
|
||||
import Bell from '@iconify/icons-ion/notifications-outline'; |
||||
import BellOff from '@iconify/icons-ion/notifications-off-outline'; |
||||
import React, { useState, useEffect } from 'react'; |
||||
import axios from 'axios'; |
||||
import { CALERTUSER_SEARCH,CONFIGALERT_SEARCH,CALERTUSER_DELETE, CALERTUSER_ADD } from '../../../const/ApiConst.js'; |
||||
import { Card as ACard,Row, Col, Switch } from 'antd'; |
||||
import { Card, CardBody, CardHeader, Input } from 'reactstrap'; |
||||
import { Icon } from '@iconify/react'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const userID = window.localStorage.getItem('user_id'); |
||||
|
||||
const Index = ({params}) => { |
||||
|
||||
const [alertUser, setAlertUser] = useState([]) |
||||
const [checked, setChecked] = useState({}) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [onSetSwitch, setOnSetSwitch] = useState(false) |
||||
const pageName = params.name; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization : `Bearer ${token}`, |
||||
"Content-type" : `application/json` |
||||
} |
||||
}; |
||||
|
||||
useEffect(()=> { |
||||
getDataConfigAlert(); |
||||
},[]) |
||||
|
||||
useEffect(() => { |
||||
getDataConfigAlertUser(); |
||||
},[dataTable]) |
||||
|
||||
const getDataConfigAlert = async () => { |
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "nama", "logic_operator": "ilike", "value": "", "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CONFIGALERT_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data |
||||
let checkedAlert = {} |
||||
resData.map((val, index) => { |
||||
checkedAlert[val.id] = false |
||||
}); |
||||
setChecked(checkedAlert); |
||||
setDatatable(resData); |
||||
}else{ |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataConfigAlertUser = async () => { |
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "user_id", "logic_operator": "=", "value": localStorage.getItem('user_id'), "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CALERTUSER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data |
||||
let configAlert = []; |
||||
resData.map((val, index) => { |
||||
configAlert.push(val.config_alert_id); |
||||
let indexRes = dataTable.findIndex(x => x.id === val.config_alert_id); |
||||
if(indexRes >= 0){ |
||||
let id = dataTable[indexRes].id; |
||||
let tempChecked = checked; |
||||
tempChecked[id] = true; |
||||
setChecked(tempChecked); |
||||
} |
||||
}); |
||||
window.localStorage.setItem('userConfigAlert', configAlert.join()); |
||||
setOnSetSwitch(false) |
||||
setAlertUser(result.data.data); |
||||
}else{ |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const onChange = (checked, id) => { |
||||
setOnSetSwitch(true) |
||||
if(checked){ |
||||
addConfigAlertUser(id); |
||||
}else{ |
||||
setDeleteConfigAlertUser(id) |
||||
} |
||||
} |
||||
|
||||
const addConfigAlertUser = async (id) => { |
||||
const formData = { |
||||
"user_id":parseInt(localStorage.getItem('user_id')), |
||||
"config_alert_id":id |
||||
} |
||||
|
||||
const result = await axios.post(CALERTUSER_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
getDataConfigAlertUser(); |
||||
} |
||||
} |
||||
|
||||
const setDeleteConfigAlertUser = async (id) => { |
||||
let indexCek = alertUser.findIndex(x => x.user_id === parseInt(localStorage.getItem('user_id')) && x.config_alert_id === id); |
||||
if(indexCek >= 0){ |
||||
let idAlert = alertUser[indexCek].id |
||||
deleteConfigAlertUser(idAlert) |
||||
} |
||||
} |
||||
|
||||
const deleteConfigAlertUser = async (id) => { |
||||
const url = CALERTUSER_DELETE(id) |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataConfigAlert(); |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Row gutter={16}> |
||||
{dataTable.map((val, index) => ( |
||||
<Col key={index} md={{span:5,offset:1}} xs={{span:11,offset:1}}> |
||||
<ACard style={{height:"100%"}} actions={[ |
||||
<Switch checked={checked[val.id] ? true : false} onChange={(checked) => onChange(checked, val.id)} disabled={onSetSwitch} />, |
||||
]}> |
||||
<div style={{height:'100%',width:'100%',display:'flex',justifyContent:'center', alignItems:'center', textAlign:'center', flexDirection:'column'}}> |
||||
<i style={{marginBottom:"25px"}}><Icon icon={checked[val.id] ? Bell : BellOff} color="black" width="100" height="100" /></i> |
||||
<p style={{marginBottom:"0"}}>{val.nama}</p> |
||||
</div> |
||||
</ACard> |
||||
</Col> |
||||
))} |
||||
</Row> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Index; |
||||
import Bell from '@iconify/icons-ion/notifications-outline'; |
||||
import BellOff from '@iconify/icons-ion/notifications-off-outline'; |
||||
import React, { useState, useEffect } from 'react'; |
||||
import axios from 'axios'; |
||||
import { CALERTUSER_SEARCH,CONFIGALERT_SEARCH,CALERTUSER_DELETE, CALERTUSER_ADD } from '../../../const/ApiConst.js'; |
||||
import { Card as ACard,Row, Col, Switch } from 'antd'; |
||||
import { Card, CardBody, CardHeader, Input } from 'reactstrap'; |
||||
import { Icon } from '@iconify/react'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const userID = window.localStorage.getItem('user_id'); |
||||
|
||||
const Index = ({params}) => { |
||||
|
||||
const [alertUser, setAlertUser] = useState([]) |
||||
const [checked, setChecked] = useState({}) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [onSetSwitch, setOnSetSwitch] = useState(false) |
||||
const pageName = params.name; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization : `Bearer ${token}`, |
||||
"Content-type" : `application/json` |
||||
} |
||||
}; |
||||
|
||||
useEffect(()=> { |
||||
getDataConfigAlert(); |
||||
},[]) |
||||
|
||||
useEffect(() => { |
||||
getDataConfigAlertUser(); |
||||
},[dataTable]) |
||||
|
||||
const getDataConfigAlert = async () => { |
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "nama", "logic_operator": "ilike", "value": "", "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CONFIGALERT_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data |
||||
let checkedAlert = {} |
||||
resData.map((val, index) => { |
||||
checkedAlert[val.id] = false |
||||
}); |
||||
setChecked(checkedAlert); |
||||
setDatatable(resData); |
||||
}else{ |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataConfigAlertUser = async () => { |
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "user_id", "logic_operator": "=", "value": localStorage.getItem('user_id'), "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(CALERTUSER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data |
||||
let configAlert = []; |
||||
resData.map((val, index) => { |
||||
configAlert.push(val.config_alert_id); |
||||
let indexRes = dataTable.findIndex(x => x.id === val.config_alert_id); |
||||
if(indexRes >= 0){ |
||||
let id = dataTable[indexRes].id; |
||||
let tempChecked = checked; |
||||
tempChecked[id] = true; |
||||
setChecked(tempChecked); |
||||
} |
||||
}); |
||||
window.localStorage.setItem('userConfigAlert', configAlert.join()); |
||||
setOnSetSwitch(false) |
||||
setAlertUser(result.data.data); |
||||
}else{ |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const onChange = (checked, id) => { |
||||
setOnSetSwitch(true) |
||||
if(checked){ |
||||
addConfigAlertUser(id); |
||||
}else{ |
||||
setDeleteConfigAlertUser(id) |
||||
} |
||||
} |
||||
|
||||
const addConfigAlertUser = async (id) => { |
||||
const formData = { |
||||
"user_id":parseInt(localStorage.getItem('user_id')), |
||||
"config_alert_id":id |
||||
} |
||||
|
||||
const result = await axios.post(CALERTUSER_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
getDataConfigAlertUser(); |
||||
} |
||||
} |
||||
|
||||
const setDeleteConfigAlertUser = async (id) => { |
||||
let indexCek = alertUser.findIndex(x => x.user_id === parseInt(localStorage.getItem('user_id')) && x.config_alert_id === id); |
||||
if(indexCek >= 0){ |
||||
let idAlert = alertUser[indexCek].id |
||||
deleteConfigAlertUser(idAlert) |
||||
} |
||||
} |
||||
|
||||
const deleteConfigAlertUser = async (id) => { |
||||
const url = CALERTUSER_DELETE(id) |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataConfigAlert(); |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Row gutter={16}> |
||||
{dataTable.map((val, index) => ( |
||||
<Col key={index} md={{span:5,offset:1}} xs={{span:11,offset:1}}> |
||||
<ACard style={{height:"100%"}} actions={[ |
||||
<Switch checked={checked[val.id] ? true : false} onChange={(checked) => onChange(checked, val.id)} disabled={onSetSwitch} />, |
||||
]}> |
||||
<div style={{height:'100%',width:'100%',display:'flex',justifyContent:'center', alignItems:'center', textAlign:'center', flexDirection:'column'}}> |
||||
<i style={{marginBottom:"25px"}}><Icon icon={checked[val.id] ? Bell : BellOff} color="black" width="100" height="100" /></i> |
||||
<p style={{marginBottom:"0"}}>{val.nama}</p> |
||||
</div> |
||||
</ACard> |
||||
</Col> |
||||
))} |
||||
</Row> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default Index; |
||||
|
@ -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,459 +1,459 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import DialogMenuRoles from './DialogMenuRoles'; |
||||
import React, { Component, 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 { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip, Table } from 'antd'; |
||||
import { ROLE_ADD, ROLE_SEARCH, ROLE_EDIT, ROLE_DELETE, ROLEMENU_ADD, ROLEMENU_SEARCH, ROLEMENU_DELETE_ROLE } from '../../../const/ApiConst.js'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/"; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const momentFormat = 'HH:mm'; |
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
alertDelete: false, |
||||
alertNotDelete: false, |
||||
currentPage: 1, |
||||
dataEdit: null, |
||||
dataExport: [], |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
dataTable: [], |
||||
dialogMenuForm: false, |
||||
idDelete: 0, |
||||
idRoles: 0, |
||||
menuRoles: [], |
||||
openDialog: false, |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
search: "", |
||||
tooltipDelete: false, |
||||
tooltipEdit: false, |
||||
tooltipExport: false, |
||||
tooltipImport: false, |
||||
tooltipMenu: false, |
||||
tooltipTambah: false, |
||||
totalPage: 0, |
||||
typeDialog: 'Save', |
||||
} |
||||
|
||||
this.columns = [ |
||||
{ |
||||
title: this.props.t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
className: 'nowrap', |
||||
render: (text, record) => <> |
||||
<Tooltip title={this.props.t('menuRoles')}> |
||||
<i className="cil-menu" style={{ color: 'green', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleMenuRoles(text.id)}></i> |
||||
</Tooltip> |
||||
|
||||
<Tooltip title={this.props.t('delete')}> |
||||
<i className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleDelete(text.id)}></i> |
||||
</Tooltip> |
||||
|
||||
<Tooltip title={this.props.t('edit')}> |
||||
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(text)}></i> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
{ title: this.props.t('nameRole'), dataIndex: 'name', key: 'name', className: "nowrap" }, |
||||
{ title: this.props.t('description'), dataIndex: 'description', key: 'description' }, |
||||
] |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataRoles(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search } = this.state |
||||
if (search !== prevState.search) this.getDataRoles() |
||||
if (prevProps.dataExport !== this.props.dataExport && this.props.dataExport.length > 0) { |
||||
this.handleExportExcel(); |
||||
} |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataRoles = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1 && this.state.currentPage > 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
|
||||
const formData = { |
||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
this.setState({ openDialog: true, typeDialog: type }) |
||||
this.showChildDialog(); |
||||
} |
||||
|
||||
handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
this.saveRole(data); |
||||
} else if (type === "edit") { |
||||
this.editRole(data); |
||||
} |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
handleOpenDialogMr = () => { |
||||
this.setState({ dialogMenuForm: true }) |
||||
this.showMenuRolesDialog(); |
||||
} |
||||
|
||||
handleCloseDialogMr = (type, data) => { |
||||
if (type === "save") { |
||||
this.saveMenuRoles(data) |
||||
} |
||||
this.setState({ dialogMenuForm: false }) |
||||
} |
||||
|
||||
toggleAddDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
onConfirmDelete = async () => { |
||||
const { idDelete } = this.state |
||||
const url = ROLE_DELETE(idDelete) |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
this.deleteCurrentRoleMenu(idDelete) |
||||
this.getDataRoles() |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.success(`Data role berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.error(`Data role gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
saveRole = async (data) => { |
||||
|
||||
const formData = { |
||||
name: data.name, |
||||
description: data.description |
||||
} |
||||
|
||||
const result = await axios.post(ROLE_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success(`Data role berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
editRole = async (data) => { |
||||
const formData = { |
||||
name: data.name, |
||||
description: data.description |
||||
} |
||||
const url = ROLE_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) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success(`Data role berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data role gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
handleEdit = (data) => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
id == '1' ? this.setState({ alertNotDelete: true }) : |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataRoles(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataRoles(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "menu") { |
||||
this.setState(prevState => ({ tooltipMenu: !prevState.tooltipMenu })) |
||||
} else if (param === "tambah") { |
||||
this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
} |
||||
|
||||
dataNotAvailable = () => { |
||||
if (this.state.dataTable.length === 0) { |
||||
return ( |
||||
<tr> |
||||
<td align="center" colSpan="3">{this.props.t('noData')}</td> |
||||
</tr> |
||||
) |
||||
} |
||||
} |
||||
|
||||
handleMenuRoles = async (id) => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "role_id", "logic_operator": "=", "value": `${id}`, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLEMENU_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ menuRoles: result.data.data, idRoles: id }, () => { |
||||
this.handleOpenDialogMr(); |
||||
}); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
saveMenuRoles = async (dataArray) => { |
||||
let payloadArray = dataArray || [] |
||||
if (payloadArray.length > 0) { |
||||
await this.deleteCurrentRoleMenu(payloadArray[0].roles_id) |
||||
} |
||||
let promises = [] |
||||
let result = [] |
||||
dataArray.map((val, index) => { |
||||
if (val.checked === true) { |
||||
const formData = { |
||||
menu_id: val.menu_id, |
||||
role_id: val.roles_id |
||||
} |
||||
promises.push(axios.post(ROLEMENU_ADD, formData, config) |
||||
.then(res => result.push(res))) |
||||
} |
||||
}) |
||||
|
||||
await Promise.all(promises); |
||||
if (result) { |
||||
if (result.length > 0) { |
||||
if (result[0].data.code === 200) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success('Data roles berhasil ditambahkan!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result[0].data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
deleteCurrentRoleMenu = async (id) => { |
||||
let urlDel = ROLEMENU_DELETE_ROLE(id) |
||||
const result = await axios.delete(urlDel, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
return true |
||||
} else { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
handleExportExcel = async () => { |
||||
let start = 0; |
||||
let end = "ALL"; |
||||
const formData = { |
||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.statusText == "OK") { |
||||
const dataRes = result.data.data || []; |
||||
const dataExport = []; |
||||
dataRes.map((val, index) => { |
||||
let row = { |
||||
Nama: val.name, |
||||
Deskripsi: val.description |
||||
} |
||||
dataExport.push(row); |
||||
}) |
||||
this.setState({ dataExport: dataExport }, () => { |
||||
this.exportExcel(); |
||||
}); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
exportExcel = () => { |
||||
const dataExcel = this.state.dataExport || []; |
||||
const fileName = "Data Roles.xlsx"; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Data Roles'); |
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
render() { |
||||
const { t } = this.props; |
||||
const { tooltipTambah, tooltipExport, dialogMenuForm, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, tooltipMenu } = this.state |
||||
let noSeq = 0; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={this.props.t('deleteConfirm')} |
||||
onConfirm={this.onConfirmDelete} |
||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
||||
focusCancelBtn |
||||
> |
||||
{this.props.t('deleteMsg')} |
||||
</SweetAlert> |
||||
<SweetAlert |
||||
show={this.state.alertNotDelete} |
||||
warning |
||||
confirmBtnText="Can't Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Data can't be delete!" |
||||
onConfirm={() => this.setState({ alertNotDelete: false })} |
||||
> |
||||
Data tipe roles tidak dapat di hapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleAddDialog} |
||||
typeDialog={this.state.typeDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
dataHs={this.state.dataIdHo} |
||||
/> |
||||
<DialogMenuRoles |
||||
openDialog={dialogMenuForm} |
||||
closeDialog={this.handleCloseDialogMr} |
||||
idRoles={this.state.idRoles} |
||||
showDialog={showDialog => this.showMenuRolesDialog = showDialog} |
||||
menuRoles={this.state.menuRoles} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>{this.props.params.name}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchRoles')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={this.props.t('rolesAdd')}> |
||||
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={this.props.t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={this.columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
bordered={false} |
||||
/> |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(index); |
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import DialogMenuRoles from './DialogMenuRoles'; |
||||
import React, { Component, 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 { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip, Table } from 'antd'; |
||||
import { ROLE_ADD, ROLE_SEARCH, ROLE_EDIT, ROLE_DELETE, ROLEMENU_ADD, ROLEMENU_SEARCH, ROLEMENU_DELETE_ROLE } from '../../../const/ApiConst.js'; |
||||
import { withTranslation } from 'react-i18next'; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
|
||||
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/"; |
||||
|
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const momentFormat = 'HH:mm'; |
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
alertDelete: false, |
||||
alertNotDelete: false, |
||||
currentPage: 1, |
||||
dataEdit: null, |
||||
dataExport: [], |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
dataTable: [], |
||||
dialogMenuForm: false, |
||||
idDelete: 0, |
||||
idRoles: 0, |
||||
menuRoles: [], |
||||
openDialog: false, |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
search: "", |
||||
tooltipDelete: false, |
||||
tooltipEdit: false, |
||||
tooltipExport: false, |
||||
tooltipImport: false, |
||||
tooltipMenu: false, |
||||
tooltipTambah: false, |
||||
totalPage: 0, |
||||
typeDialog: 'Save', |
||||
} |
||||
|
||||
this.columns = [ |
||||
{ |
||||
title: this.props.t('action'), |
||||
dataIndex: '', |
||||
key: 'x', |
||||
className: 'nowrap', |
||||
render: (text, record) => <> |
||||
<Tooltip title={this.props.t('menuRoles')}> |
||||
<i className="cil-menu" style={{ color: 'green', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleMenuRoles(text.id)}></i> |
||||
</Tooltip> |
||||
|
||||
<Tooltip title={this.props.t('delete')}> |
||||
<i className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleDelete(text.id)}></i> |
||||
</Tooltip> |
||||
|
||||
<Tooltip title={this.props.t('edit')}> |
||||
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(text)}></i> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
{ title: this.props.t('nameRole'), dataIndex: 'name', key: 'name', className: "nowrap" }, |
||||
{ title: this.props.t('description'), dataIndex: 'description', key: 'description' }, |
||||
] |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataRoles(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search } = this.state |
||||
if (search !== prevState.search) this.getDataRoles() |
||||
if (prevProps.dataExport !== this.props.dataExport && this.props.dataExport.length > 0) { |
||||
this.handleExportExcel(); |
||||
} |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataRoles = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1 && this.state.currentPage > 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
|
||||
const formData = { |
||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
this.setState({ openDialog: true, typeDialog: type }) |
||||
this.showChildDialog(); |
||||
} |
||||
|
||||
handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
this.saveRole(data); |
||||
} else if (type === "edit") { |
||||
this.editRole(data); |
||||
} |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
handleOpenDialogMr = () => { |
||||
this.setState({ dialogMenuForm: true }) |
||||
this.showMenuRolesDialog(); |
||||
} |
||||
|
||||
handleCloseDialogMr = (type, data) => { |
||||
if (type === "save") { |
||||
this.saveMenuRoles(data) |
||||
} |
||||
this.setState({ dialogMenuForm: false }) |
||||
} |
||||
|
||||
toggleAddDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
onConfirmDelete = async () => { |
||||
const { idDelete } = this.state |
||||
const url = ROLE_DELETE(idDelete) |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
await this.deleteCurrentRoleMenu(idDelete); |
||||
this.getDataRoles(); |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.success(`Data role berhasil dihapus`, 'Success!!'); |
||||
} else { |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.error(`Data role gagal dihapus`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
saveRole = async (data) => { |
||||
|
||||
const formData = { |
||||
name: data.name, |
||||
description: data.description |
||||
} |
||||
|
||||
const result = await axios.post(ROLE_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success(`Data role berhasil ditambahkan`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data role gagal ditambahkan`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
editRole = async (data) => { |
||||
const formData = { |
||||
name: data.name, |
||||
description: data.description |
||||
} |
||||
const url = ROLE_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) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success(`Data role berhasil diubah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data role gagal diubah`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
handleEdit = (data) => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
id == '1' ? this.setState({ alertNotDelete: true }) : |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataRoles(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataRoles(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "menu") { |
||||
this.setState(prevState => ({ tooltipMenu: !prevState.tooltipMenu })) |
||||
} else if (param === "tambah") { |
||||
this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
} |
||||
|
||||
dataNotAvailable = () => { |
||||
if (this.state.dataTable.length === 0) { |
||||
return ( |
||||
<tr> |
||||
<td align="center" colSpan="3">{this.props.t('noData')}</td> |
||||
</tr> |
||||
) |
||||
} |
||||
} |
||||
|
||||
handleMenuRoles = async (id) => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "role_id", "logic_operator": "=", "value": `${id}`, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLEMENU_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code == 200) { |
||||
this.setState({ menuRoles: result.data.data, idRoles: id }, () => { |
||||
this.handleOpenDialogMr(); |
||||
}); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
saveMenuRoles = async (dataArray) => { |
||||
let payloadArray = dataArray || [] |
||||
if (payloadArray.length > 0) { |
||||
await this.deleteCurrentRoleMenu(payloadArray[0].roles_id) |
||||
} |
||||
let promises = [] |
||||
let result = [] |
||||
dataArray.map((val, index) => { |
||||
if (val.checked === true) { |
||||
const formData = { |
||||
menu_id: val.menu_id, |
||||
role_id: val.roles_id |
||||
} |
||||
promises.push(axios.post(ROLEMENU_ADD, formData, config) |
||||
.then(res => result.push(res))) |
||||
} |
||||
}) |
||||
|
||||
await Promise.all(promises); |
||||
if (result) { |
||||
if (result.length > 0) { |
||||
if (result[0].data.code === 200) { |
||||
this.getDataRoles(); |
||||
NotificationManager.success('Data roles berhasil ditambahkan!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result[0].data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
deleteCurrentRoleMenu = async (id) => { |
||||
let urlDel = ROLEMENU_DELETE_ROLE(id) |
||||
const result = await axios.delete(urlDel, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
return true |
||||
} else { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
handleExportExcel = async () => { |
||||
let start = 0; |
||||
let end = "ALL"; |
||||
const formData = { |
||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
||||
"columns": [ |
||||
{ "name": "name", "logic_operator": "ilike", "value": this.state.search, "operator": "AND" } |
||||
], |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.statusText == "OK") { |
||||
const dataRes = result.data.data || []; |
||||
const dataExport = []; |
||||
dataRes.map((val, index) => { |
||||
let row = { |
||||
Nama: val.name, |
||||
Deskripsi: val.description |
||||
} |
||||
dataExport.push(row); |
||||
}) |
||||
this.setState({ dataExport: dataExport }, () => { |
||||
this.exportExcel(); |
||||
}); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
exportExcel = () => { |
||||
const dataExcel = this.state.dataExport || []; |
||||
const fileName = "Data Roles.xlsx"; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Data Roles'); |
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
render() { |
||||
const { t } = this.props; |
||||
const { tooltipTambah, tooltipExport, dialogMenuForm, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, tooltipMenu } = this.state |
||||
let noSeq = 0; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={this.props.t('deleteConfirm')} |
||||
onConfirm={this.onConfirmDelete} |
||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
||||
focusCancelBtn |
||||
> |
||||
{this.props.t('deleteMsg')} |
||||
</SweetAlert> |
||||
<SweetAlert |
||||
show={this.state.alertNotDelete} |
||||
warning |
||||
confirmBtnText="Can't Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Data can't be delete!" |
||||
onConfirm={() => this.setState({ alertNotDelete: false })} |
||||
> |
||||
Data tipe roles tidak dapat di hapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleAddDialog} |
||||
typeDialog={this.state.typeDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
dataHs={this.state.dataIdHo} |
||||
/> |
||||
<DialogMenuRoles |
||||
openDialog={dialogMenuForm} |
||||
closeDialog={this.handleCloseDialogMr} |
||||
idRoles={this.state.idRoles} |
||||
showDialog={showDialog => this.showMenuRolesDialog = showDialog} |
||||
menuRoles={this.state.menuRoles} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>{this.props.params.name}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchRoles')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={this.props.t('rolesAdd')}> |
||||
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title={this.props.t('exportExcel')}> |
||||
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table |
||||
rowKey="id" |
||||
size="small" |
||||
columns={this.columns} |
||||
dataSource={dataTable} |
||||
pagination={false} |
||||
bordered={false} |
||||
/> |
||||
<Pagination |
||||
style={{ marginTop: "25px" }} |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(index); |
||||
|
@ -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('Parent Division')}</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,369 +1,363 @@
|
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||
import { DIVISI_LIST, DIVISI_ADD, DIVISI_EDIT, DIVISI_DELETE, DIVISI_SEARCH } from '../../../const/ApiConst'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Button, Tooltip } from 'antd'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const url = ""; |
||||
const proyek_id = localStorage.getItem('proyek_id'); |
||||
const role_id = localStorage.getItem('role_id'); |
||||
const format = "DD-MM-YYYY"; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const column = [ |
||||
{ name: "Nama" }, |
||||
{ name: "Deskripsi" }, |
||||
] |
||||
|
||||
const ProjectType = ({ 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 [dataDivisions, setDataDivisions] = useState([]) |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
getListDivision() |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
getDataProjectType() |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const getListDivision = async () => { |
||||
const listDivions = await axios |
||||
.get(DIVISI_LIST, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (listDivions && listDivions.data && listDivions.data.code == 200) { |
||||
let arr = [] |
||||
for (const v in listDivions.data.data) { |
||||
arr.push(listDivions.data.data[v]) |
||||
} |
||||
setDataDivisions(arr); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
const getDataProjectType = 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(DIVISI_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
result.data.data.map((res) => { |
||||
res.key = res.id.toString() |
||||
}); |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
const handleExportExcel = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "like", |
||||
"value": search, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"ascending": true, |
||||
"columns": [ |
||||
'id' |
||||
] |
||||
}, |
||||
"paging": { |
||||
"length": rowsPerPage, |
||||
"start": start |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(DIVISI_SEARCH, payload, HEADER) |
||||
.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 Divisi": 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 handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveProjectType(data); |
||||
} else if (type === "edit") { |
||||
editMaterialR(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveProjectType = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(DIVISI_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataProjectType() |
||||
NotificationManager.success(`Data berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editMaterialR = async (data) => { |
||||
let urlEdit = DIVISI_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) { |
||||
getDataProjectType(); |
||||
NotificationManager.success(`Data berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = DIVISI_DELETE(idDelete); |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataProjectType() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data 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} |
||||
dataDivisions={dataDivisions} |
||||
/> |
||||
<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('searchDivision')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('divisionAdd')}> |
||||
<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" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>Aksi</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> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ProjectType; |
||||
import * as XLSX from 'xlsx'; |
||||
import DialogForm from './DialogForm'; |
||||
import React, { useState, useEffect } from 'react'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap'; |
||||
import { DIVISI_LIST, DIVISI_ADD, DIVISI_EDIT, DIVISI_DELETE, DIVISI_SEARCH } from '../../../const/ApiConst'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Button, Tooltip } from 'antd'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
|
||||
const url = ""; |
||||
const proyek_id = localStorage.getItem('proyek_id'); |
||||
const role_id = localStorage.getItem('role_id'); |
||||
const format = "DD-MM-YYYY"; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const column = [ |
||||
{ name: "Nama" }, |
||||
{ name: "Deskripsi" }, |
||||
] |
||||
|
||||
const ProjectType = ({ 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 [dataDivisions, setDataDivisions] = useState([]) |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
getDataProjectType(); |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const getListDivision = async () => { |
||||
const listDivions = await axios |
||||
.get(DIVISI_LIST, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (listDivions && listDivions.data && listDivions.data.code == 200) { |
||||
let arr = [] |
||||
for (const v in listDivions.data.data) { |
||||
arr.push(listDivions.data.data[v]) |
||||
} |
||||
setDataDivisions(arr); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
const getDataProjectType = 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(DIVISI_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let dataRes = result.data.data || []; |
||||
setDatatable(dataRes); |
||||
setTotalPage(result.data.totalRecord); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
const handleExportExcel = async () => { |
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "like", |
||||
"value": search, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"ascending": true, |
||||
"columns": [ |
||||
'id' |
||||
] |
||||
}, |
||||
"paging": { |
||||
"length": rowsPerPage, |
||||
"start": start |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(DIVISI_SEARCH, payload, HEADER) |
||||
.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 Divisi": 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 handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveProjectType(data); |
||||
} else if (type === "edit") { |
||||
editMaterialR(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveProjectType = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(DIVISI_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataProjectType() |
||||
NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editMaterialR = async (data) => { |
||||
let urlEdit = DIVISI_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) { |
||||
getDataProjectType(); |
||||
NotificationManager.success(`Data berhasil diubah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data gagal diubah`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = DIVISI_DELETE(idDelete); |
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataProjectType() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data 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} |
||||
dataDivisions={dataDivisions} |
||||
/> |
||||
<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('searchDivision')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('divisionAdd')}> |
||||
<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" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>Aksi</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> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default ProjectType; |
||||
|
@ -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); |
||||
|
@ -1,343 +1,337 @@
|
||||
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 { SATUAN_ADD, SATUAN_EDIT, SATUAN_DELETE, SATUAN_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 Satuan = ({ 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() |
||||
useEffect(() => { |
||||
getDataSatuan() |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const column = [ |
||||
{ name: t('name') }, |
||||
{ name: t('description') }, |
||||
] |
||||
const getDataSatuan = 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" |
||||
}, |
||||
{ |
||||
"name": "description", |
||||
"logic_operator": "ilike", |
||||
"value": search, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"ascending": true, |
||||
"columns": [ |
||||
'id' |
||||
] |
||||
}, |
||||
"paging": { |
||||
"length": rowsPerPage, |
||||
"start": start |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(SATUAN_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" } |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
const result = await axios |
||||
.post(SATUAN_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") { |
||||
saveSatuan(data); |
||||
} else if (type === "edit") { |
||||
editMaterialR(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveSatuan = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(SATUAN_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataSatuan() |
||||
NotificationManager.success(`Data project type berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editMaterialR = async (data) => { |
||||
let urlEdit = SATUAN_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) { |
||||
getDataSatuan(); |
||||
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 = SATUAN_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataSatuan() |
||||
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('searchUom')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('uomAdd')}> |
||||
<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('ubah')}> |
||||
<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 Satuan; |
||||
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 { SATUAN_ADD, SATUAN_EDIT, SATUAN_DELETE, SATUAN_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 Satuan = ({ 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() |
||||
useEffect(() => { |
||||
getDataSatuan() |
||||
}, [currentPage, rowsPerPage, search]) |
||||
|
||||
useEffect(() => { |
||||
const cekData = dataExport || [] |
||||
if (cekData.length > 0) { |
||||
exportExcel() |
||||
} |
||||
}, [dataExport]) |
||||
|
||||
const column = [ |
||||
{ name: t('name') }, |
||||
{ name: t('description') }, |
||||
] |
||||
const getDataSatuan = 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(SATUAN_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" } |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
const result = await axios |
||||
.post(SATUAN_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") { |
||||
saveSatuan(data); |
||||
} else if (type === "edit") { |
||||
editMaterialR(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveSatuan = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(SATUAN_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataSatuan() |
||||
NotificationManager.success(`Satuan berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editMaterialR = async (data) => { |
||||
let urlEdit = SATUAN_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) { |
||||
getDataSatuan(); |
||||
NotificationManager.success(`Satuan berhasil diubah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Satuan gagal diubah`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = SATUAN_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataSatuan() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Satuan berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Satuan 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('searchUom')} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title={t('uomAdd')}> |
||||
<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('ubah')}> |
||||
<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 Satuan; |
||||
|
Loading…
Reference in new issue