Browse Source

Merge pull request 'staging' (#117) from staging into master

Reviewed-on: ordo/adw-frontend#117
pull/2/head
ibnu 1 year ago
parent
commit
3fda8d42dc
  1. 282
      package.json
  2. 58
      src/const/ApiConst.js
  3. 8
      src/views/Dashboard/DashboardBOD.js
  4. 24
      src/views/Dashboard/DashboardProject.js
  5. 198
      src/views/Master/ConfigAlert/DialogForm.js
  6. 344
      src/views/Master/ConfigAlert/index.js
  7. 264
      src/views/Master/MasterBroadcast/DialogDetail.js
  8. 1251
      src/views/Master/MasterBroadcast/index.js
  9. 359
      src/views/Master/MasterMenu/DialogForm.js
  10. 748
      src/views/Master/MasterMenu/index.js
  11. 248
      src/views/Master/MasterRoles/DialogForm.js
  12. 918
      src/views/Master/MasterRoles/index.js
  13. 680
      src/views/SimproV2/ChecklistK3/index.js
  14. 135
      src/views/SimproV2/CreatedProyek/AsignCustProject.js
  15. 92
      src/views/SimproV2/CreatedProyek/DialogAssignCust.js
  16. 297
      src/views/SimproV2/CreatedProyek/DialogFormGantt.js
  17. 2557
      src/views/SimproV2/CreatedProyek/DialogFormProyek.js
  18. 569
      src/views/SimproV2/CreatedProyek/DialogGantt.js
  19. 1040
      src/views/SimproV2/CreatedProyek/ViewProject.js
  20. 461
      src/views/SimproV2/CreatedProyek/index.js
  21. 254
      src/views/SimproV2/Divisi/DialogForm.js
  22. 732
      src/views/SimproV2/Divisi/index.js
  23. 798
      src/views/SimproV2/PanicButton/index.js
  24. 27
      src/views/SimproV2/ResourceWorker/DialogForm.js
  25. 680
      src/views/SimproV2/Satuan/index.js

282
package.json

@ -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"
}
}

58
src/const/ApiConst.js

@ -117,7 +117,7 @@ export const TOKEN_ADW =
// export let BASE_OSPRO = "https://ospro-api.ospro.id";
export let BASE_OSPRO = "https://adw-api.ospro.id";
// export let BASE_OSPRO = "http://localhost:8444";
// export let BASE_OSPRO = "http://localhost:8444/adw-backend";
// export let BASE_OSPRO = "http://103.73.125.81:8444"; // ip public adw
export let BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;
export let BASE_SIMPRO_LUMEN_IMAGE = `${BASE_OSPRO}/assets/image`;
@ -363,6 +363,55 @@ export const PROYEK_ADD = `${BASE_SIMPRO_LUMEN}/project/add`;
export const PROYEK_LIST = `${BASE_SIMPRO_LUMEN}/project/list`;
export const PROYEK_SEARCH = `${BASE_SIMPRO_LUMEN}/project/search`;
export const PROYEK_SEARCH_DETAIL = `${BASE_SIMPRO_LUMEN}/project/search`;
// Checklist
export const PROJECT_CHECKLIST_ADD = `${BASE_SIMPRO_LUMEN}/project-checklists/add`;
export const PROJECT_CHECKLIST_SEARCH = `${BASE_SIMPRO_LUMEN}/project-checklists/search`;
export const PROJECT_CHECKLIST_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/update/${id}`;
};
export const PROJECT_CHECKLIST_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/delete/${id}`;
};
export const PROJECT_CHECKLIST_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/delete-by-proyek/${id}`;
};
export const PROJECT_CHECKLIST_LIST = `${BASE_SIMPRO_LUMEN}/project-checklists/list`;
export const PROJECT_CHECKLIST_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-checklists/${where}/${id}`;
};
// Issue
export const PROJECT_ISSUE_ADD = `${BASE_SIMPRO_LUMEN}/project-issues/add`;
export const PROJECT_ISSUE_SEARCH = `${BASE_SIMPRO_LUMEN}/project-issues/search`;
export const PROJECT_ISSUE_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/update/${id}`;
};
export const PROJECT_ISSUE_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/delete/${id}`;
};
export const PROJECT_ISSUE_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/delete-by-proyek/${id}`;
};
export const PROJECT_ISSUE_LIST = `${BASE_SIMPRO_LUMEN}/project-issues/list`;
export const PROJECT_ISSUE_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-issues/${where}/${id}`;
};
// Potential Risk
export const PROJECT_RISK_ADD = `${BASE_SIMPRO_LUMEN}/project-risks/add`;
export const PROJECT_RISK_SEARCH = `${BASE_SIMPRO_LUMEN}/project-risks/search`;
export const PROJECT_RISK_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/update/${id}`;
};
export const PROJECT_RISK_DELETE = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/delete/${id}`;
};
export const PROJECT_RISK_DELETE_BY_PROYEK = (id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/delete-by-proyek/${id}`;
};
export const PROJECT_RISK_LIST = `${BASE_SIMPRO_LUMEN}/project-risks/list`;
export const PROJECT_RISK_WHERE_CUSTOM = (where, id) => {
return `${BASE_SIMPRO_LUMEN}/project-risks/${where}/${id}`;
};
// export const PROYEK_SEARCH_BY_USER = (id) => {
// return `${BASE_SIMPRO_LUMEN}/project-by-customer/${id}`;
// };
@ -608,6 +657,7 @@ export const CHECKLIST_K3_DELETE = (id) => {
export const CHECKLIST_K3_LIST = `${BASE_SIMPRO_LUMEN}/checklist-k3/list`;
export const ASSIGN_HR_PROJECT_ADD = `${BASE_SIMPRO_LUMEN}/user-to-proyek/add`;
export const ASSIGN_HR_PROJECT_ADD_MULTIPLE = `${BASE_SIMPRO_LUMEN}/user-to-proyek/add-multiple`;
export const ASSIGN_HR_PROJECT_SEARCH = `${BASE_SIMPRO_LUMEN}/user-to-proyek/search`;
export const ASSIGN_HR_PROJECT_EDIT = (id) => {
return `${BASE_SIMPRO_LUMEN}/user-to-proyek/update/${id}`;
@ -676,3 +726,9 @@ export const HIERARCHY_FTTH_TREE = (id) => {
return `${BASE_SIMPRO_LUMEN}/hierarchy-ftths/tree/${id}`;
};
export const WAYPOINT_SEARCH = `${BASE_SIMPRO_LUMEN}/waypoint/search`;
export const IMAGE_UPLOAD = `${BASE_SIMPRO_LUMEN}/image/upload`;
export const IMAGE_DELETE = (id, category) => {
return `${BASE_SIMPRO_LUMEN}/image/delete/${id}/${category}`;
}

8
src/views/Dashboard/DashboardBOD.js

@ -244,8 +244,10 @@ const DashboardBOD = () => {
return;
}
if (result.status == 200 && result.data.data) {
SET_PROJECT_PER_DIVISION(result.data.data);
if (result.status == 200 && result.data.data) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.parent === null);
SET_PROJECT_PER_DIVISION(filteredData);
}
SET_READY_PROJECT_PER_DIVISION(true);
}
@ -311,7 +313,7 @@ const DashboardBOD = () => {
planningProgress = item.scurve[0].data.percentagePlan[item.scurve[0].data.percentagePlan.length - 1]
actualProgress = item.scurve[0].data.percentageReal[item.scurve[0].data.percentageReal.length - 1]
}
selisihProgress = planningProgress - actualProgress
if (selisihProgress > 0 && selisihProgress <= 5) {

24
src/views/Dashboard/DashboardProject.js

@ -268,7 +268,13 @@ const DashboardProject = () => {
const getProjectDetail = async () => {
setIsReadyProjectDetail(false);
const URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`;
let URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}`;
if (GANTT_ID) {
URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}/${GANTT_ID}`;
}
if (SCURVE) {
URL = `${BASE_OSPRO}/api/project/detail/${PROJECT_ID}/${GANTT_ID}/${SCURVE}`;
}
const result = await axios
.get(URL, HEADER)
.then((res) => res)
@ -298,10 +304,22 @@ const DashboardProject = () => {
result.data.data.company ? result.data.data.company : "-"
);
setPlannedStart(
result.data.data?.mulai_proyek ? result.data.data.mulai_proyek : null
SCURVE
? result.data.data.mulai_proyek
? result.data.data.mulai_proyek
: null
: result.data.data.header?.planned_start
? result.data.data.header?.planned_start
: null
);
setPlannedFinish(
result.data.data?.akhir_proyek ? result.data.data.akhir_proyek : null
SCURVE
? result.data.data.akhir_proyek
? result.data.data.akhir_proyek
: null
: result.data.data.header?.planned_end
? result.data.data.header?.planned_end
: null
);
setActualStart(
result.data.data.header?.start_date

198
src/views/Master/ConfigAlert/DialogForm.js

@ -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;

344
src/views/Master/ConfigAlert/index.js

@ -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;

264
src/views/Master/MasterBroadcast/DialogDetail.js

@ -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);

1251
src/views/Master/MasterBroadcast/index.js

File diff suppressed because it is too large Load Diff

359
src/views/Master/MasterMenu/DialogForm.js

@ -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;

748
src/views/Master/MasterMenu/index.js

@ -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;

248
src/views/Master/MasterRoles/DialogForm.js

@ -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);

918
src/views/Master/MasterRoles/index.js

@ -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);

680
src/views/SimproV2/ChecklistK3/index.js

@ -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;

135
src/views/SimproV2/CreatedProyek/AsignCustProject.js

@ -4,14 +4,16 @@ import { Button, Form } from 'reactstrap';
import { Table, Tooltip } from 'antd';
import 'antd/dist/antd.css';
import moment from 'moment';
import { API_ADW, TOKEN_ADW, ASSIGN_HR_PROJECT_SEARCH, ASSIGN_HR_PROJECT_DELETE, USER_LIST, PROJECT_ROLE_SEARCH, ASSIGN_HR_PROJECT_ADD, ASSIGN_HR_PROJECT_EDIT } from '../../../const/ApiConst';
import {
ASSIGN_HR_PROJECT_SEARCH,
ASSIGN_HR_PROJECT_DELETE
} from '../../../const/ApiConst';
import axios from "../../../const/interceptorApi"
import { NotificationContainer, NotificationManager } from 'react-notifications';
import SweetAlert from 'react-bootstrap-sweetalert';
import FormAsignCust from './DialogAssignCust';
import { formatThousand } from '../../../const/CustomFunc';
const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsResource, proyekName }) => {
const AssignCustProject = ({ openDialog, closeDialog, toggleDialog, idTask, proyekName }) => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
@ -23,9 +25,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
const [alertDelete, setAlertDelete] = useState(false)
const [idDelete, setIdDelete] = useState(0)
const [openDialogFormTools, setOpenDialogFormTools] = useState(false)
const [dataEdit, setDataEdit] = useState(null)
const [listUser, setListUser] = useState([])
const [listRole, setListRole] = useState([])
useEffect(() => {
if (idTask > 0) {
@ -35,8 +34,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
useEffect(() => {
if (openDialog) {
getDataProjectRole();
getDataUser();
}
}, [dataUserToProject])
@ -76,52 +73,6 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
}
}
const getDataUser = async () => {
const HEADER_ADW = {
headers: {
"Authorization": `${TOKEN_ADW}`
}
}
const result = await axios
.get(USER_LIST, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.data.length != 0) {
let dataRes = result.data.data
setListUser(dataRes)
}
}
const getDataProjectRole = async () => {
const payload = {
"paging": {
"start": 0,
"length": -1
},
"columns": [
{ "name": "created_by", "logic_operator": "ilike", "value": "" },
],
"joins": [],
"orders": {
"columns": [
"id"
],
"ascending": false
}
}
const result = await axios
.post(PROJECT_ROLE_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data || []
setListRole(dataRes);
} else {
}
}
const handleDelete = (id) => {
setIdDelete(id)
setAlertDelete(true)
@ -142,11 +93,11 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
getDataAssignHr()
setIdDelete(0)
setAlertDelete(false)
NotificationManager.success(`Data assign human resource berhasil dihapus`, 'Success!!');
NotificationManager.success(`Data assign customer berhasil dihapus`, 'Success!!');
} else {
setIdDelete(0)
setAlertDelete(false)
NotificationManager.error(`Data assign human resource gagal dihapus`, 'Failed!!');
NotificationManager.error(`Data assign customer gagal dihapus`, 'Failed!!');
}
}
@ -167,18 +118,11 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
dataIndex: '',
key: 'x',
className: "nowrap",
render: (text, record) => <><Tooltip title="Delete Request Resource">
render: (text, record) => <><Tooltip title={`Delete Request Resource ${text.id}`}>
<Button size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button>
</Tooltip>{" "}</>,
},
{ title: 'Name Human Resource', dataIndex: 'join_first_name', key: 'join_first_name', className: "nowrap" },
{ title: 'Role Human Resource', dataIndex: 'join_second_name', key: 'join_second_name', className: "nowrap" },
{ title: 'Percentage Available User', dataIndex: 'max_used', key: 'max_used', className: "nowrap", render: (text, record) => record.max_used ? formatThousand(record.max_used) : '-' },
{ title: 'Standard Rate', dataIndex: 'standart_rate', key: 'standart_rate', className: "nowrap", render: (text, record) => record.standart_rate ? formatThousand(record.standart_rate) : '-' },
{ title: 'UOM Standard Rate', dataIndex: 'uom_standart_rate', key: 'uom_standart_rate', className: "nowrap" },
{ title: 'Overtime Rate', dataIndex: 'overtime_rate', key: 'overtime_rate', className: "nowrap", render: (text, record) => record.overtime_rate ? formatThousand(record.overtime_rate) : '-' },
{ title: 'UOM Overtime Rate', dataIndex: 'uom_overtime_rate', key: 'uom_overtime_rate', className: "nowrap" },
{ title: 'Name Human Resource', dataIndex: 'join_first_name', key: 'join_first_name', className: "nowrap" }
];
return (
@ -199,53 +143,24 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
)
}
const handleCloseDialogFormTools = (type, data) => {
if(type=="add"){
addDataAssignHr(data);
}else if(type=="edit"){
editDataAssignHr(data);
}else{
setDataEdit(null)
setOpenDialogFormTools(false)
}
}
const addDataAssignHr = async (payload) => {
const result = await axios
.post(ASSIGN_HR_PROJECT_ADD, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
getDataAssignHr();
NotificationManager.success('assign human resource berhasil!!', 'Success');
setDataEdit(null)
setOpenDialogFormTools(false)
} else {
NotificationManager.error('assign human resource gagal!!', 'Failed');
}
}
const editDataAssignHr = async (payload) => {
let url = ASSIGN_HR_PROJECT_EDIT(payload.id)
const result = await axios
.put(url, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
getDataAssignHr();
NotificationManager.success('assign human resource berhasil diedit!!', 'Success');
setDataEdit(null)
const handleCloseDialogFormTools = (type, data) => {
if (type === "add") getDataAssignHr();
if (type === "success") {
NotificationManager.success(
`Assign Customer Project berhasil disimpan!`,
"Success!!"
);
} else if (type === "failed") {
NotificationManager.error(
`Assign Customer Project gagal disimpan!`,
"Failed!!"
);
}
setOpenDialogFormTools(false)
} else {
NotificationManager.error('assign human resource gagal diedit!!', 'Failed');
}
}
const toogleDialogFormTools = () => {
if (openDialogFormTools) {
setDataEdit(null)
}
setOpenDialogFormTools(!openDialogFormTools)
}
@ -281,14 +196,10 @@ const AssignHrProject = ({ openDialog, closeDialog, toggleDialog, idTask, toolsR
closeDialog={handleCloseDialogFormTools}
toggleDialog={toogleDialogFormTools}
idTask={idTask}
dataEdit={dataEdit}
dataHr={listUser}
dataRole={listRole}
dataCurrentHr={dataUserToProject}
/>
</>
)
}
export default AssignHrProject;
export default AssignCustProject;

92
src/views/SimproV2/CreatedProyek/DialogAssignCust.js

@ -2,12 +2,17 @@ import React, { useEffect, useState } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button, Form } from 'reactstrap';
import axios from "../../../const/interceptorApi";
import { USER_VERSION_GANTT_ADDS, USER_VERSION_GANTT_SEARCH, USER_LIST} from '../../../const/ApiConst';
import {
USER_LIST,
ASSIGN_HR_PROJECT_SEARCH,
ASSIGN_HR_PROJECT_ADD_MULTIPLE
} from '../../../const/ApiConst';
import { Transfer } from 'antd';
import 'antd/dist/antd.css';
import { NotificationManager } from 'react-notifications';
const role_id = localStorage.getItem('role_id');
const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) => {
const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idTask }) => {
const token = localStorage.getItem("token")
const HEADER = {
headers: {
@ -15,29 +20,24 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
"Authorization": `Bearer ${token}`
}
}
const [id, setId] = useState(0)
const [targetKeys, setTargetKeys] = useState([])
const [assignCustomer, setAssignCustomer] = useState([])
const handleCLearData = () => {
setId(0)
setTargetKeys([])
}
useEffect(() => {
if(!openDialog){
handleCLearData()
if (!openDialog) {
handleCLearData();
closeDialog('add');
} else {
getDataAssignCustomer();
getDataAssignCustomer();
getCustProject();
}
}, [openDialog])
}, [openDialog]);
useEffect(() => {
if(idGantt && idGantt > 0){
getUserGantt()
}
}, [idGantt])
const getDataAssignCustomer = async () => {
const result = await axios
@ -49,8 +49,6 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.role_id === 44);
setTransferUser(filteredData);
} else {
}
}
@ -66,51 +64,23 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
setAssignCustomer(finalData)
}
const getUserGantt = async () => {
const payload = {
"columns": [
{ "name": "version_gantt_id", "logic_operator": "=", "value": idGantt, "operator": "AND" }
]
}
const result = await axios
.post(USER_VERSION_GANTT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek resource get user gantt",result.data.data)
setUserGantt(result.data.data);
}else{
}
}
const setUserGantt = (data) => {
let newTargetKeys = []
data.map((val,index)=> {
newTargetKeys.push(val.user_id)
});
setTargetKeys(newTargetKeys)
}
const handleSave = async () => {
await saveVersionGantt()
await saveCustProject()
handleCLearData()
}
const saveVersionGantt= async () => {
const saveCustProject= async () => {
const formData = {
user_id:targetKeys,
version_gantt_id:idGantt
user_id: targetKeys,
proyek_id: idTask
}
const result = await axios
.post(USER_VERSION_GANTT_ADDS, formData, HEADER)
.post(ASSIGN_HR_PROJECT_ADD_MULTIPLE, formData, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
closeDialog('success')
}else{
@ -120,13 +90,37 @@ const DialogAssignCust = ({ openDialog, closeDialog, toggleDialog, idGantt}) =>
const handleCancel = () => {
closeDialog('cancel')
handleCLearData()
handleCLearData();
}
const handleChange = targetKeys => {
setTargetKeys(targetKeys)
};
const getCustProject = async () => {
const payload = {
"columns": [
{ "name": "proyek_id", "logic_operator": "=", "value": idTask },
{"name": "is_customer", "logic_operator": "=", "value": "true"}
]
}
const result = await axios
.post(ASSIGN_HR_PROJECT_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek get assign HR is custumer",result.data.data)
let data = result.data.data || []
let newTargetKeys = []
if (data.length > 0) {
data.map((val,index)=> {
newTargetKeys.push(val.user_id)
});
}
setTargetKeys(newTargetKeys)
}
}
const renderForm = () => {
return (
<div style={{

297
src/views/SimproV2/CreatedProyek/DialogFormGantt.js

@ -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;

2557
src/views/SimproV2/CreatedProyek/DialogFormProyek.js

File diff suppressed because it is too large Load Diff

569
src/views/SimproV2/CreatedProyek/DialogGantt.js

@ -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;

1040
src/views/SimproV2/CreatedProyek/ViewProject.js

File diff suppressed because it is too large Load Diff

461
src/views/SimproV2/CreatedProyek/index.js

@ -25,6 +25,9 @@ import {
PROJECT_APPROVAL_ADD,
PROJECT_APPROVAL_EDIT,
PROJECT_PARTICIPANT_ADD,
PROJECT_CHECKLIST_ADD,
PROJECT_ISSUE_ADD,
PROJECT_RISK_ADD,
PROJECT_PARTICIPANT_EDIT,
PROJECT_MILESTONE_ADD,
PROJECT_MILESTONE_EDIT,
@ -37,12 +40,19 @@ import {
PROYEK_SEARCH,
PROYEK_SEARCH_BY_USER,
PROYEK_EDIT,
ASSIGN_HR_PROJECT_SEARCH,
PROJECT_CHECKLIST_SEARCH,
PROYEK_DELETE,
TOOLS_RESOURCE_SEARCH,
MATERIAL_RESOURCE_SEARCH,
USER_SEARCH,
PROJECT_CHARTER_SEARCH,
HIERARCHY_FTTH_SEARCH,
PROJECT_ISSUE_SEARCH,
PROJECT_RISK_SEARCH,
PROJECT_CHECKLIST_DELETE_BY_PROYEK,
PROJECT_ISSUE_DELETE_BY_PROYEK,
PROJECT_RISK_DELETE_BY_PROYEK,
TOOLS_RESOURCE_LIST,
MATERIAL_RESOURCE_LIST,
PROYEK_GET_ID,
@ -54,6 +64,9 @@ import {
PHASE_PROYEK,
DIVISI_LIST,
BASE_OSPRO,
IMAGE_UPLOAD,
IMAGE_GET_BY_ID,
IMAGE_DELETE,
} from "../../../const/ApiConst";
import {
formatNumber,
@ -95,6 +108,13 @@ const CreatedProyek = ({ params, ...props }) => {
},
};
const HEADER_MULTIPART = {
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${token}`,
},
};
const [idTask, setidTask] = useState(0);
const [dataTable, setDatatable] = useState([]);
const [search, setSearch] = useState("");
@ -130,8 +150,15 @@ const CreatedProyek = ({ params, ...props }) => {
// project charter
const [projectCharter, setProjectCharter] = useState(null);
const [projectParticipant, setProjectParticipant] = useState(null);
const [projectChecklist, setProjectChecklist] = useState(null);
const [projectIssue, setProjectIssue] = useState(null);
const [projectRisk, setProjectRisk] = useState(null);
const [projectMilestone, setProjectMilestone] = useState(null);
const [projectApproval, setProjectApproval] = useState(null);
const [projectPM, setPM] = useState(null);
const [projectK3Search, setK3Search] = useState(null);
const [projectAssignHR, setProjectAssignHR] = useState(null);
const [image, setProjectImage] = useState(null);
const [loadVersionGantt, setLoadVersionGantt] = useState(false);
const [loadHierarchy, setLoadHierarchy] = useState(false);
@ -218,17 +245,20 @@ const CreatedProyek = ({ params, ...props }) => {
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setDataDivisions(result.data.data);
const dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.parent === null);
setDataDivisions(filteredData);
}
};
const handleGetDataPm = async () => {
const handleGetDataPm = async (text) => {
const result = await axios
.get(USER_LIST, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setDataPM(result.data.data);
const dataRes = result.data.data;
setDataPM(dataRes);
} else {
}
};
@ -252,7 +282,7 @@ const CreatedProyek = ({ params, ...props }) => {
return;
} else if (result.status == 200 && result.data.data) {
history.push(
`dashboard-customer/${text.id}/${result.data.gantt.last_gantt_id}/1`
`dashboard-customer/${text.id}/${result.data.gantt}/1`
);
}
};
@ -426,9 +456,10 @@ const CreatedProyek = ({ params, ...props }) => {
setidTask(id);
};
const handleOpenDialogProyek = (id) => {
const handleOpenDialogProyek = async (id) => {
setOpenDialogProyek(true);
setidTask(id);
await getProjectImage(id);
};
const handleOpenDialogGantt = (data) => {
@ -496,8 +527,15 @@ const CreatedProyek = ({ params, ...props }) => {
await getDataProject(data.id);
await getProjectMilestone(data.id);
await getProjectParticipant(data.id);
await getProjectChecklist(data.id);
await getProjectIssue(data.id);
await getProjectRisk(data.id);
await getProjectApproval(data.id);
// await getDataProjectCharter(data.id);
await getK3toProject(data.id);
await getProjectAssignHR(data.id);
await getProjectImage(data.id);
// await handleGetDataPm(data.id);
setPM(data.join_first_name);
setOpenDialogViewDetail(true);
};
@ -520,11 +558,37 @@ const CreatedProyek = ({ params, ...props }) => {
return;
} else if (result.status == 200 && result.data.data) {
history.push(
`/dashboard-project/${id}/${result.data.gantt.last_gantt_id}/1`
`/dashboard-project/${id}/${result.data.gantt}/1`
);
}
};
const getK3toProject = async (id) => {
const payload = {
"select": [
"id",
"proyek_id",
"checklist_k3_id"
],
"columns": [
{ "name": "proyek_id", "logic_operator": "=", "value": id, "operator": "AND" }
]
}
const URL = `${BASE_OSPRO}/api/project-to-checklist-k3/search`;
const result = await axios
.post(URL, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if(result && result.status==200){
console.log("cek get project to checklist k3",result.data.data)
let dataRes = result.data.data;
if (dataRes.length > 0) {
setK3Search(dataRes);
}
}
}
const handleSCurve = async (data) => {
getProjectDetail(data.id);
};
@ -537,8 +601,9 @@ const CreatedProyek = ({ params, ...props }) => {
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectCharter(dataRes);
const {kode_sortname,nama,mulai_proyek,rencana_biaya,keterangan,durasi_proyek,project_objectives,potential_risk,currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when} = result.data.data;
const dataToSend = {kode_sortname, nama, mulai_proyek, rencana_biaya, keterangan, durasi_proyek, project_objectives, potential_risk, currency_symbol, nama_divisi, late_consequence, assumtion, considered_success_when};
setProjectCharter(dataToSend);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -546,6 +611,13 @@ const CreatedProyek = ({ params, ...props }) => {
const getProjectMilestone = async (id) => {
const payload = {
select: [
'id',
'proyek_id',
'status',
'due_date',
'deadline'
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [],
orders: { columns: ["id"], ascending: true },
@ -559,20 +631,76 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectMilestone(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectMilestone(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectAssignHR = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"user_id",
"project_role"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [
{
name: "m_users",
column_join: "user_id",
column_results: ["name"],
},
{
name: "m_role_proyek",
column_join: "project_role",
column_results: ["name", "description"],
}
],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
// const url = PROJECT_MI(proyek_id)
const result = await axios
.post(ASSIGN_HR_PROJECT_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectAssignHR(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectImage = async (id) => {
const url = IMAGE_GET_BY_ID(id, "project_structure_organization");
const result = await axios
.get(url, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code === 200) {
setProjectImage(result.data.data);
}
}
const getProjectParticipant = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"tittle",
"name"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: id }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
// const url = PROJECT_MI(proyek_id)
const result = await axios
.post(PROJECT_PARTICIPANT_SEARCH, payload, HEADER)
.then((res) => res)
@ -580,7 +708,90 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectParticipant(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectParticipant(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectChecklist = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"item",
"status_exist"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_CHECKLIST_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectChecklist(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectIssue = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"description",
"level_issue"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_ISSUE_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectIssue(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
};
const getProjectRisk = async (id) => {
const payload = {
select: [
"id",
"proyek_id",
"description",
"preventive_risk",
"level_risk"
],
columns: [{ name: "proyek_id", logic_operator: "=", value: parseInt(id) }],
joins: [],
orders: { columns: ["id"], ascending: true },
paging: { start: 0, length: -1 },
};
const result = await axios
.post(PROJECT_RISK_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectRisk(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -601,7 +812,8 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data;
setProjectApproval(dataRes);
const filteredData = dataRes.filter(item => item.proyek_id === parseInt(id));
setProjectApproval(filteredData);
} else {
NotificationManager.error("Gagal Mengambil Data!!", "Failed");
}
@ -626,8 +838,14 @@ const CreatedProyek = ({ params, ...props }) => {
const handleCloseDialogView = () => {
setProjectApproval(null);
setProjectParticipant(null);
setProjectChecklist(null);
setProjectIssue(null);
setProjectRisk(null);
setProjectMilestone(null);
setProjectCharter(null);
setK3Search(null);
setProjectAssignHR(null);
setProjectImage(null);
setOpenDialogViewDetail(false);
};
@ -637,8 +855,14 @@ const CreatedProyek = ({ params, ...props }) => {
if (openDialogViewDetail) {
setProjectApproval(null);
setProjectParticipant(null);
setProjectChecklist(null);
setProjectIssue(null);
setProjectRisk(null);
setProjectMilestone(null);
setProjectCharter(null);
setK3Search(null);
setProjectAssignHR(null);
setProjectImage(null);
}
setOpenDialogViewDetail(!openDialogViewDetail);
};
@ -652,7 +876,8 @@ const CreatedProyek = ({ params, ...props }) => {
if (result && result.data && result.data.code === 200) {
role_id !== "44" ? getDataProyek() : getDataProyekByCustomer();
getProjectImage(idDelete);
deleteImage(idDelete);
setIdDelete(0);
setAlertDelete(false);
NotificationManager.success(`Data proyek berhasil dihapus`, "Success!!");
@ -671,11 +896,25 @@ const CreatedProyek = ({ params, ...props }) => {
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code === 200) {
const { participants, milestones, approval } = data.projectCharter;
const { checklist, issue, potentialRisks, participants, milestones, approval } = data.projectCharter;
const imageObject = data.imageStructureOrg;
const resultParticipant = await saveParticipant(
result.data.data_result.id,
participants
);
const resultChecklist = await saveChecklist(
result.data.data_result.id,
checklist
);
const resultIssue = await saveIssue(
result.data.data_result.id,
issue
);
const resultRisk = await saveRisk(
result.data.data_result.id,
potentialRisks
);
const resultMilestone = await saveMilestone(
result.data.data_result.id,
milestones
@ -684,12 +923,21 @@ const CreatedProyek = ({ params, ...props }) => {
result.data.data_result.id,
approval
);
if (imageObject) {
await saveImage(
result.data.data_result.id,
imageObject
);
}
if (
resultChecklist === "berhasil" &&
resultIssue === "berhasil" &&
resultRisk === "berhasil" &&
resultParticipant === "berhasil" &&
resultMilestone === "berhasil" &&
resultApproval === "berhasil"
) {
// getDataProyek();
NotificationManager.success(
`Data proyek berhasil ditambah`,
"Success!!"
@ -724,6 +972,67 @@ const CreatedProyek = ({ params, ...props }) => {
return "berhasil";
};
const saveChecklist = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
item: res.item,
status_exist: res.status_exist,
};
return axios.post(PROJECT_CHECKLIST_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveIssue = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
description: res.description,
level_issue: res.level_issue,
};
return axios.post(PROJECT_ISSUE_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveRisk = async (id, data) => {
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
level_risk: res.level_risk,
description: res.description,
preventive_risk: res.preventive_risk,
};
return axios.post(PROJECT_RISK_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code == 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const saveMilestone = async (id, data) => {
const request = data.map((res) => {
const payload = {
@ -766,8 +1075,33 @@ const CreatedProyek = ({ params, ...props }) => {
return "berhasil";
};
const saveImage = async (id, data) => {
const formData = new FormData;
formData.append('ref_id', id);
formData.append('category', 'project_structure_organization');
formData.append('files', data);
await axios
.post(IMAGE_UPLOAD, formData, HEADER_MULTIPART)
.then(res => res)
.catch((error) => error.response);
return "berhasil";
};
const deleteImage = async (id) => {
const URL = IMAGE_DELETE(id, 'project_structure_organization');
await axios
.delete(URL, HEADER)
.then(res => res)
.catch((error) => error.response);
return "berhasil";
};
const editProyek = async (data) => {
const { participants, milestones, approval } = data.projectCharter;
const { checklist, issue, potentialRisks, participants, milestones, approval } = data.projectCharter;
const imageObject = data.imageStructureOrg;
let urlEdit = PROYEK_EDIT(data.id);
const formData = data;
@ -778,6 +1112,18 @@ const CreatedProyek = ({ params, ...props }) => {
const resultParticipant = await editParticipant(data.id, participants);
const resultMilestone = await editMilestone(data.id, milestones);
const resultApproval = await editApproval(data.id, approval);
const resultChecklist = await editChecklist(data.id, checklist);
const resultIssue = await editIssue(data.id, issue);
const resultRisk = await editRisk(data.id, potentialRisks);
if (imageObject) {
await deleteImage(
data.id
);
await saveImage(
data.id,
imageObject
);
}
if (result && result.status === 200) {
role_id !== "44" ? getDataProyek() : getDataProyekByCustomer();
NotificationManager.success(`Data proyek berhasil Ubah`, "Success!!");
@ -786,13 +1132,76 @@ const CreatedProyek = ({ params, ...props }) => {
}
};
const editChecklist = async (id, data) => {
await axios.delete(PROJECT_CHECKLIST_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
item: res.item ? res.item : res.item,
status_exist: res.status_exist,
};
return axios.post(PROJECT_CHECKLIST_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editIssue = async (id, data) => {
await axios.delete(PROJECT_ISSUE_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
description: res.description ? res.description : res.description,
level_issue: res.level_issue,
};
return axios.post(PROJECT_ISSUE_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editRisk = async (id, data) => {
await axios.delete(PROJECT_RISK_DELETE_BY_PROYEK(id), HEADER);
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
level_risk: res.level_risk,
description: res.description ? res.description : res.description,
preventive_risk: res.preventive_risk ? res.preventive_risk : res.preventive_risk
};
return axios.post(PROJECT_RISK_ADD, payload, HEADER);
});
const arr = await Promise.all(request)
.then((values) => values)
.catch((err) => err.response);
const result = arr.map((res) => res.data.code !== 200);
if (result.length > 0) {
return "gagal";
}
return "berhasil";
};
const editParticipant = async (id, data) => {
await axios.delete(PROJECT_PARTICIPANT_DELETE_BY_PROYEK(id), HEADER);
// if (restDelete){
const request = data.map((res) => {
const payload = {
proyek_id: parseInt(id),
tittle: res.tittle ? res.tittle : res.title,
tittle: res.tittle ? res.tittle : res.tittle,
name: res.name,
};
return axios.post(PROJECT_PARTICIPANT_ADD, payload, HEADER);
@ -1081,12 +1490,16 @@ const CreatedProyek = ({ params, ...props }) => {
<span className="menu-text">Request Tools</span>
</div> */}
{/* <Link to={`/project-charter/${text.id}/gantt`}> */}
{
/*text.type_proyek_id != 9 ?*/
<div className="menu-list" onClick={() => handleOpenDialogGantt(text)}>
<span className="menu-icon">
<i className="fa fa-bars"></i>
</span>
<span className="menu-text">Gantt</span>
</div>
/*: null*/
}
<div className="menu-list" onClick={() => handleSCurve(text)}>
<span className="menu-icon">
<i className="fa fa-line-chart"></i>
@ -1338,6 +1751,7 @@ const CreatedProyek = ({ params, ...props }) => {
dataPhaseProject={dataPhaseProject}
dataDivisions={dataDivisions}
dataPM={dataPm}
projectImage={image}
/>
),
[
@ -1347,6 +1761,7 @@ const CreatedProyek = ({ params, ...props }) => {
dataPhaseProject,
dataTypeProyek,
idTask,
image
]
);
@ -1460,8 +1875,16 @@ const CreatedProyek = ({ params, ...props }) => {
toggleDialog={toggleAddDialogView}
projectCharter={projectCharter}
projectParticipant={projectParticipant}
projectChecklist={projectChecklist}
projectIssue={projectIssue}
projectRisk={projectRisk}
projectMilestone={projectMilestone}
projectApproval={projectApproval}
projectManager={projectPM}
projectK3={projectK3Search}
assignHR={projectAssignHR}
projectImage={image}
idTask={idTask}
/>
),
[openDialogViewDetail]

254
src/views/SimproV2/Divisi/DialogForm.js

@ -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;

732
src/views/SimproV2/Divisi/index.js

@ -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;

798
src/views/SimproV2/PanicButton/index.js

@ -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);

27
src/views/SimproV2/ResourceWorker/DialogForm.js

@ -135,6 +135,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
alert("Password doesn't match");
return;
}
if (password.length < 8) {
alert("Password minimum 8 character");
return;
}
data = {
id,
username,
@ -199,7 +203,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
</>
)
}
const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const renderForm = () => {
return (
<Form>
@ -213,7 +220,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<FormGroup>
<Label className="capitalize">{t('nik')} <span style={{ color: "red" }}>*</span></Label>
{/* <Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={`Input NIK (KTP)...`} maxLength="16" /> */}
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value)} placeholder={t('inputNik')} maxLength="16" />
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNik')} maxLength="16" />
</FormGroup>
</Col>
<Col md={6}>
@ -246,7 +253,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Col md={6}>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('inputEmail')} />
<Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder={t('inputEmail')}
onBlur={(e) => {
if (!isValidEmail(e.target.value)) {
alert("Masukkan email yang valid.");
}
}}
/>
</FormGroup>
</Col>
<Col md={6}>
@ -327,7 +340,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Col md={6}>
<FormGroup>
<Label className="capitalize">Email</Label>
<Input type="text" defaultValue={""} value={email} onChange={(e) => setEmail(e.target.value)} placeholder={`Email...`} />
<Input type="email" defaultValue={""} value={email} onChange={(e) => setEmail(e.target.value)} placeholder={`Email...`}
onBlur={(e) => {
if (!isValidEmail(e.target.value)) {
alert("Masukkan email yang valid.");
}
}}
/>
</FormGroup>
</Col>
<Col md={6}>

680
src/views/SimproV2/Satuan/index.js

@ -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…
Cancel
Save