diff --git a/package.json b/package.json index f6e19ba..c698e3b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ }, "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", diff --git a/src/const/ApiConst.js b/src/const/ApiConst.js index cbed48f..7e9365c 100644 --- a/src/const/ApiConst.js +++ b/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}`; +} diff --git a/src/views/Master/MasterBroadcast/DialogDetail.js b/src/views/Master/MasterBroadcast/DialogDetail.js index 0d5165f..b4b96cc 100644 --- a/src/views/Master/MasterBroadcast/DialogDetail.js +++ b/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 ( - - {this.props.t('broadcastDetail')} - - - - - - - - - - - - - {this.state.dataListDetail.map((val, index) => { - return ( - - - - - - - - ) - })} - -
{this.props.t('statusSend')}{this.props.t('dateSend')}{this.props.t('description')}{this.props.t('titleNotification')}{this.props.t('messageNotification')}
{val.status_send === "" ? "-" : val.status_send}{val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")}{val.description === "" ? "-" : val.description}{val.title_notif === "" ? "-" : val.title_notif}{val.message_notif === "" ? "-" : val.message_notif}
- -
- - - -
- ) - } -} -export default withTranslation()(DialogDetail); \ No newline at end of file +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 ( + + {this.props.t('broadcastDetail')} + + + + + + + + + + + + + + {this.state.dataListDetail.map((val, index) => { + const matchedUser = dataUser.find(item => item.id == val.send_to_id); + return ( + + + + + + + + + ) + })} + +
{this.props.t('statusSend')}{this.props.t('dateSend')}{this.props.t('description')}{this.props.t('receiver')}{this.props.t('titleNotification')}{this.props.t('messageNotification')}
{val.status_send === "" ? "-" : val.status_send}{val.created_at === "" ? "-" : moment(val.created_date).format("DD-MM-YYYY HH:mm:ss")}{val.description === "" ? "-" : val.description}{ matchedUser ? matchedUser.name : "-" }{val.title_notif === "" ? "-" : val.title_notif}{val.message_notif === "" ? "-" : val.message_notif}
+ +
+ + + +
+ ) + } +} +export default withTranslation()(DialogDetail); diff --git a/src/views/Master/MasterBroadcast/index.js b/src/views/Master/MasterBroadcast/index.js index 36e5193..9cadec4 100644 --- a/src/views/Master/MasterBroadcast/index.js +++ b/src/views/Master/MasterBroadcast/index.js @@ -1,635 +1,616 @@ -import * as XLSX from 'xlsx'; -import DialogDetail from './DialogDetail'; -import DialogForm from './DialogForm'; -import React, { Component } from 'react'; -import SweetAlert from 'react-bootstrap-sweetalert'; -import axios from 'axios'; -import moment from 'moment'; -import { API_BROADCAST_SIMPRO, BASE_SIMPRO, BASE_SIMPRO_LUMEN, BASE_URL_GEOHR_API2 } from '../../../const/ApiConst'; -import { Button, Card, CardBody, CardHeader, DropdownItem, DropdownMenu, DropdownToggle, Input, InputGroup, InputGroupButtonDropdown, Table, Row, Col } from 'reactstrap'; -import { DatePicker, Pagination } from 'antd'; -import { NotificationContainer, NotificationManager } from 'react-notifications'; -import { Tooltip } from 'reactstrap'; -import { withTranslation } from 'react-i18next'; - -const { RangePicker } = DatePicker; -const token = window.localStorage.getItem('token'); -const config = { - headers: - { - Authorization: `Bearer ${token}`, - "Content-type": `application/json` - } -}; - -const id_org = window.localStorage.getItem('id_org'); -const roleName = window.localStorage.getItem('role_name'); - - -const LENGTH_DATA = 10 - -class index extends Component { - constructor(props) { - super(props) - this.state = { - alertBroadcast: false, - alertDelete: false, - currentDay: 'today', - currentPage: 1, - dataDetail: [], - dataEdit: null, - dataExport: [], - dataExport: [], - dataGs: [], - dataIdHo: [], - dataTable: [], - endDate: moment(moment().format("YYYY-M-D")), - idDelete: 0, - idSend: 0, - openDialog: false, - openDialogDetail: false, - page: 0, - rowsPerPage: LENGTH_DATA, - search: "", - searchDetail: "Judul", - searchDetailField: "title_notif", - splitButtonOpen: false, - startDate: moment(moment().format("YYYY-M-D")), - statusSend: '', - toltipDetail: false, - tooltipDelete: false, - tooltipEdit: false, - tooltipExport: false, - tooltipTambah: false, - tooltipresend: false, - tooltipsend: false, - totalPage: 0, - typeClock: "All", - typeDialog: 'Save', - } - } - - async componentDidMount() { - await this.getDataBroadcast(); - } - - async componentDidUpdate(prevProps, prevState) { - const { search, startDate } = this.state - if (search !== prevState.search) this.getDataBroadcast() - if (startDate !== prevState.startDate) this.getDataBroadcast() - } - - handleSearch = e => { - const value = e.target.value - this.setState({ search: value, currentPage: 1 }) - }; - - getDataBroadcast = async () => { - let url = BASE_SIMPRO_LUMEN + `/broadcast/search`; - const { searchDetail } = this.state - - let start = 0; - if (this.state.currentPage !== 1 && 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 = { - "columns": [ - { - "logic_operator": "range", - "name": "created_at", - "operator": "AND", - "value": `${dateStart}`, - "value1": `${dateEnd}` - }, - { - "logic_operator": "ilike", - "name": "title_notif", - "operator": "AND", - "value": "" - } - ], - "orders": { - "ascending": false, - "columns": [ - "created_at" - ] - }, - "paging": { - "length": this.state.rowsPerPage, - "start": start - } - } - - if (this.state.search !== "" && this.state.search !== null) { - } - - const result = await axios - .post(url, payload, config) - .then(res => res) - .catch((error) => error.response); - if (result && result.data) { - if (result.data.code === 200) { - this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); - } else { - NotificationManager.error('Failed retreiving data!!', 'Failed'); - } - } else { - NotificationManager.error('Failed retreiving data!!', 'Failed'); - } - } - - handleOpenDialog = (type) => { - this.setState({ openDialog: true, typeDialog: type }) - this.showChildDialog(); - } - - handleCloseDialog = (type, data) => { - this.setState({ openDialog: false }) - } - handleSaveBroadcast = (type, data) => { - this.setState({ openDialog: false }) - this.saveBroadcast(type, data) - } - - toggleAddDialog = () => { - this.setState({ openDialog: !this.state.openDialog }) - } - - onConfirmBroadcast = async () => { - const { idSend, statusSend } = this.state - let url = `${API_BROADCAST_SIMPRO}/edit-status-send/${idSend}`; - let payload = { - "status_send": statusSend - } - const result = await axios - .put(url, payload, config) - .then(res => res) - .catch((error) => error.response); - if (result.status === 200) { - NotificationManager.success(`Broadcast berhasil di ${statusSend === 'send' ? 'Kirim' : 'Kirim Ulang'}`) - this.getDataBroadcast() - this.setState({ alertBroadcast: false }) - } else { - NotificationManager.error(result.message, 'Failed!!'); - this.setState({ alertBroadcast: false }) - } - } - - saveBroadcast = async (type, data) => { - let url = BASE_SIMPRO_LUMEN + `/broadcast/add`; - - const param = { - "title_notif": data.title, - "status_send": type, - "send_to_type": "all", - "message_notif": data.message, - "description": data.description, - } - - const paramRoles = { - "title_notif": data.title, - "status_send": type, - "send_to_type": "roles", - "message_notif": data.message, - "description": data.description, - "send_to_id": data.id - } - - const paramUsers = { - "title_notif": data.title, - "status_send": type, - "send_to_type": "users", - "message_notif": data.message, - "description": data.description, - "send_to_id": data.send_to_type == "users" ? data.id.map((id, index) => id) : null - } - - if (data.send_to_type === "all") { - const result = await axios.post(url, param, config) - .then(res => res) - .catch((error) => error.response); - if (result) { - if (result.data) { - if (result.data.code === 200) { - this.getDataBroadcast(); - NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else if (data.send_to_type === "roles") { - const result = await axios.post(url, paramRoles, config) - .then(res => res) - .catch((error) => error.response); - if (result) { - if (result.data) { - if (result.data.code === 200) { - this.getDataBroadcast(); - NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else if (data.send_to_type === "users") { - const result = await axios.post(url, paramUsers, config) - .then(res => res) - .catch((error) => error.response); - if (result) { - if (result.data) { - if (result.data.code === 200) { - this.getDataBroadcast(); - NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); - } - } - - } - - handleEdit = (id, type) => { - this.setState({ alertBroadcast: true, statusSend: type, idSend: id }) - } - - handleDelete = (id) => { - this.setState({ alertDelete: true, idDelete: id }); - } - - onShowSizeChange = (current, pageSize) => { - this.setState({ rowsPerPage: pageSize }, () => { - this.getDataBroadcast(); - }) - } - - onPagination = (current, pageSize) => { - this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { - this.getDataBroadcast(); - }) - } - - toggle = (param) => { - if (param === "edit") { - this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) - } else if (param === "delete") { - this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) - } else if (param === "tambah") { - this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) - } else if (param === "export") { - this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) - } - } - - handleDatePicker = (date, dateString) => { - this.setState({ startDate: date[0], endDate: date[1] }, () => { - this.getDataBroadcast(); - }) - } - - handleTipe = (e) => { - this.setState({ typeClock: e.target.value }, () => { - this.getDataBroadcast(); - }); - } - - handleExportExcel = async () => { - let url = BASE_SIMPRO + `/broadcast.php?act=get_data&role_name=${roleName}`; - const { searchDetail } = this.state - - let start = 0; - if (this.state.currentPage !== 1) { - start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage - } - - let dateStart = this.state.startDate; - let dateEnd = this.state.endDate; - - const formData = new FormData(); - formData.append("startDate", dateStart.format("YYYY-M-D") + " 00:00:00"); - formData.append("endDate", dateEnd.format("YYYY-M-D") + " 23:59:59"); - formData.append('field', this.state.searchDetailField); - formData.append("start", start); - formData.append("length", "all"); - if (this.state.search !== "" && this.state.search !== null) { - formData.append('value', this.state.search); - } - - const result = await axios - .post(url, formData) - .then(res => res) - .catch((error) => error.response); - if (result && result.data) { - if (result.data.code_status === 200) { - this.setState({ dataExport: result.data.data }, () => { - this.exportExcel(); - }); - } else { - } - } else { - } - } - - exportExcel = () => { - const dataExcel = this.state.dataExport || []; - const dataExport = []; - dataExcel.map((val) => { - let row = { - "Tanggal Broadcast": moment(val.created_date).format("YYYY-MM-DD HH:mm:ss"), - "Penerima": val.employee_name, - "Judul": val.title_notif, - "Pesan": val.message_notif, - "Deskripsi": val.description, - "Status": val.status_send - } - dataExport.push(row); - }); - const fileName = "Broadcast.xlsx"; - const ws = XLSX.utils.json_to_sheet(dataExport); - const wb = XLSX.utils.book_new(); - XLSX.utils.book_append_sheet(wb, ws, 'Broadcast'); - - XLSX.writeFile(wb, fileName); - } - - handleDetail = (data) => { - console.log("ceh handle detail", data) - this.setState({ dataDetail: data }, () => { - this.showDetailDialog(); - this.setState({ openDialogDetail: true }); - }); - } - - toggleTooltip = (type) => { - if (type === "detail") { - this.setState({ toltipDetail: !this.state.toltipDetail }) - } else if (type === "resend") { - this.setState({ tooltipresend: !this.state.tooltipresend }) - } else if (type === "send") { - this.setState({ tooltipsend: !this.state.tooltipsend }) - } - } - - renderBtnResend = (n) => { - return ( - - this.handleEdit(n, 'resend')}> - this.toggleTooltip("resend")}> - Kirim Ulang - - - ) - } - - renderBtnSend = (n) => { - return ( - - this.handleEdit(n, 'send')}> - this.toggleTooltip("send")}> - Kirim - - - ) - } - - renderTable = () => { - const column = [ - { name: this.props.t('action') }, - { name: this.props.t('title') }, - { name: this.props.t('message') }, - { name: this.props.t('description') }, - { name: "Status" }, - { name: this.props.t('date') }, - ] - const t = this.props - const dataTable2 = this.state.dataTable || []; - return ( - - {dataTable2.length !== 0 ? dataTable2.map((n) => { - return ( - - - - {n.status_send === 'completed' || n.status_send === 'failed' || n.status_send === 'send' ? - this.renderBtnResend(n.id) : - this.renderBtnSend(n.id) - } - - this.handleDetail(n)}> - this.toggleTooltip("detail")}> - Detail - - - - - - {n.title_notif} - {n.message_notif !== "" ? n.message_notif : "-"} - {n.description !== "" ? n.description : "-"} - {n.status_send !== "" ? n.status_send : "-"} - {n.created_date !== "" ? moment.utc(n.created_date).format("DD-MM-YYYY HH:mm:ss") : "-"} - - ) - }) : - {this.props.t('noData')} - - } - - ) - } - - toggleDropDown = () => { - this.setState({ splitButtonOpen: !this.state.splitButtonOpen }) - } - - handleCloseDetail = () => { - this.setState({ openDialogDetail: false }) - } - - toggleDialogDetail = () => { - this.setState({ openDialogDetail: !this.state.openDialogDetail }) - } - - 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 { - console.log("test 2 test", val); - 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('title') }, - { name: this.props.t('message') }, - { name: this.props.t('description') }, - { name: "Status" }, - { name: this.props.t('date') }, - ] - const t = this.props; - const { tooltipTambah, tooltipExport, dataTable, splitButtonOpen, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, statusSend } = this.state - return ( -
- - this.setState({ alertBroadcast: false })} - focusCancelBtn - > - {`Yakin ingin ${statusSend === 'send' ? 'Mengirimkan' : 'Mengirimkan Ulang'} Broadcast?`} - - this.toggleAddDialog} - typeDialog={this.state.typeDialog} - dataEdit={this.state.dataEdit} - showDialog={showDialog => this.showChildDialog = showDialog} - dataHs={this.state.dataIdHo} - /> - this.toggleDialogDetail} - dataDetail={this.state.dataDetail} - showDialog={showDialog => this.showDetailDialog = showDialog} - /> - - -

{this.props.params.name}

- - - - - this.toggle("tambah")}> - {this.props.t('broadcastAdd')} - - this.toggle("export")}> - {this.props.t('exprotExcel')} - - - -
- -
-
-
- this.handleChangeDay(e)} defaultValue={this.state.currentDay}> - - - - -
-
- {' '} - -
-
- - - - - - this.setState({ - searchDetail: this.props.t('title'), - searchDetailField: "title_notif" - })}>Judul - this.setState({ - searchDetail: this.props.t('description'), - searchDetailField: "description" - })}>Deskripsi - this.setState({ - searchDetail: this.props.t('message'), - searchDetailField: "message_notif" - })}>Pesan - this.setState({ - searchDetail: "Status", - searchDetailField: "status_send" - })}>Status - - - -
- - - - {column.map((i, index) => { - return ( - - ) - })} - - - {this.renderTable()} -
{i.name}
- -
-
-
- ) - } -} -export default withTranslation()(index); +import * as XLSX from 'xlsx'; +import DialogDetail from './DialogDetail'; +import DialogForm from './DialogForm'; +import React, { Component } from 'react'; +import SweetAlert from 'react-bootstrap-sweetalert'; +import axios from 'axios'; +import moment from 'moment'; +import { USER_LIST, BASE_SIMPRO_LUMEN } from '../../../const/ApiConst'; +import { Button, Card, CardBody, CardHeader, DropdownItem, DropdownMenu, DropdownToggle, Input, InputGroup, InputGroupButtonDropdown, Table, Row, Col } from 'reactstrap'; +import { DatePicker, Pagination } from 'antd'; +import { NotificationContainer, NotificationManager } from 'react-notifications'; +import { Tooltip } from 'reactstrap'; +import { withTranslation } from 'react-i18next'; + +const { RangePicker } = DatePicker; +const token = window.localStorage.getItem('token'); +const config = { + headers: + { + Authorization: `Bearer ${token}`, + "Content-type": `application/json` + } +}; + +const id_org = window.localStorage.getItem('id_org'); +const roleName = window.localStorage.getItem('role_name'); + + +const LENGTH_DATA = 10 + +class index extends Component { + constructor(props) { + super(props) + this.state = { + alertBroadcast: false, + alertDelete: false, + currentDay: 'today', + currentPage: 1, + dataDetail: [], + dataEdit: null, + dataExport: [], + dataExport: [], + dataGs: [], + dataIdHo: [], + dataTable: [], + endDate: moment(moment().format("YYYY-M-D")), + idDelete: 0, + idSend: 0, + openDialog: false, + openDialogDetail: false, + page: 0, + rowsPerPage: LENGTH_DATA, + search: "", + searchDetail: "Title", + searchDetailField: "title_notif", + splitButtonOpen: false, + startDate: moment(moment().format("YYYY-M-D")), + statusSend: '', + toltipDetail: false, + tooltipDelete: false, + tooltipEdit: false, + tooltipExport: false, + tooltipTambah: false, + tooltipresend: false, + tooltipsend: false, + totalPage: 0, + typeClock: "All", + typeDialog: 'Save', + } + } + + async componentDidMount() { + await this.getDataBroadcast(); + } + + async componentDidUpdate(prevProps, prevState) { + const { search, startDate } = this.state + if (search !== prevState.search) this.getDataBroadcast() + if (startDate !== prevState.startDate) this.getDataBroadcast() + } + + handleSearch = e => { + const value = e.target.value + this.setState({ search: value, currentPage: 1 }) + }; + + 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 }, () => { + }); + } + } + + getDataBroadcast = async () => { + let url = BASE_SIMPRO_LUMEN + `/broadcast/search`; + const { searchDetailField, search, currentPage, rowsPerPage, startDate, endDate } = this.state + let start = 0; + if (currentPage !== 1 && currentPage > 1) { + start = (currentPage * rowsPerPage) - rowsPerPage + } + + let dateStart = moment(startDate).format("YYYY-MM-DD 00:00:00"); + let dateEnd = moment(endDate).format("YYYY-MM-DD 23:59:59"); + + const payload = { + "columns": [ + { + "logic_operator": "range", + "name": "created_at", + "operator": "AND", + "value": `${dateStart}`, + "value1": `${dateEnd}` + }, + { + "logic_operator": "ilike", + "name": searchDetailField, + "operator": "AND", + "value": search + } + ], + "orders": { + "ascending": false, + "columns": [ + "created_at" + ] + }, + "paging": { + "length": this.state.rowsPerPage, + "start": start + } + } + + if (this.state.search !== "" && this.state.search !== null) { + } + + const result = await axios + .post(url, payload, config) + .then(res => res) + .catch((error) => error.response); + if (result && result.data) { + if (result.data.code === 200) { + this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); + this.getDataUsers() + } else { + NotificationManager.error('Failed retreiving data!!', 'Failed'); + } + } else { + NotificationManager.error('Failed retreiving data!!', 'Failed'); + } + } + + handleOpenDialog = (type) => { + this.setState({ openDialog: true, typeDialog: type }) + this.showChildDialog(); + } + + handleCloseDialog = (type, data) => { + this.setState({ openDialog: false }) + } + handleSaveBroadcast = (type, data) => { + this.setState({ openDialog: false }) + this.saveBroadcast(type, data) + } + + toggleAddDialog = () => { + this.setState({ openDialog: !this.state.openDialog }) + } + + onConfirmBroadcast = async () => { + const { idSend, statusSend } = this.state + let url = BASE_SIMPRO_LUMEN + `/broadcast/update/${idSend}`; + let payload = { + "status_send": statusSend + } + const result = await axios + .put(url, payload, config) + .then(res => res) + .catch((error) => error.response); + if (result.status === 200) { + NotificationManager.success(`Broadcast berhasil di ${statusSend === 'send' ? 'Kirim' : 'Kirim Ulang'}`) + this.getDataBroadcast() + this.setState({ alertBroadcast: false }) + } else { + NotificationManager.error(result.message, 'Failed!!'); + this.setState({ alertBroadcast: false }) + } + } + + saveBroadcast = async (type, data) => { + let url = BASE_SIMPRO_LUMEN + `/broadcast/add`; + + const param = { + "title_notif": data.title, + "status_send": type, + "send_to_type": "all", + "message_notif": data.message, + "description": data.description, + } + + const paramRoles = { + "title_notif": data.title, + "status_send": type, + "send_to_type": "roles", + "message_notif": data.message, + "description": data.description, + "send_to_id": data.id + } + + const paramUsers = { + "title_notif": data.title, + "status_send": type, + "send_to_type": "users", + "message_notif": data.message, + "description": data.description, + "send_to_id": data.send_to_type == "users" ? data.id.map((id, index) => id) : null + } + + if (data.send_to_type === "all") { + const result = await axios.post(url, param, config) + .then(res => res) + .catch((error) => error.response); + if (result) { + if (result.data) { + if (result.data.code === 200) { + this.getDataBroadcast(); + NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else if (data.send_to_type === "roles") { + const result = await axios.post(url, paramRoles, config) + .then(res => res) + .catch((error) => error.response); + if (result) { + if (result.data) { + if (result.data.code === 200) { + this.getDataBroadcast(); + NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else if (data.send_to_type === "users") { + const result = await axios.post(url, paramUsers, config) + .then(res => res) + .catch((error) => error.response); + if (result) { + if (result.data) { + if (result.data.code === 200) { + this.getDataBroadcast(); + NotificationManager.success('Broadcast berhasil terkirimkan', 'Success!!'); + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } else { + NotificationManager.error(`${result.data.message}`, 'Failed!!'); + } + } + + } + + handleEdit = (id, type) => { + this.setState({ alertBroadcast: true, statusSend: type, idSend: id }) + } + + handleDelete = (id) => { + this.setState({ alertDelete: true, idDelete: id }); + } + + onShowSizeChange = (current, pageSize) => { + this.setState({ rowsPerPage: pageSize }, () => { + this.getDataBroadcast(); + }) + } + + onPagination = (current, pageSize) => { + this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { + this.getDataBroadcast(); + }) + } + + toggle = (param) => { + if (param === "edit") { + this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) + } else if (param === "delete") { + this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) + } else if (param === "tambah") { + this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) + } else if (param === "export") { + this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) + } + } + + handleDatePicker = (date, dateString) => { + this.setState({ startDate: date[0], endDate: date[1] }, () => { + this.getDataBroadcast(); + }) + } + + handleTipe = (e) => { + this.setState({ typeClock: e.target.value }, () => { + this.getDataBroadcast(); + }); + } + + handleExportExcel = async () => { + const dataExcel = this.state.dataTable || []; + const dataUser = this.state.dataUser || []; + const dataExport = []; + dataExcel.map((val) => { + const matchedUser = dataUser.find(item => item.id == val.send_to_id); + let row = { + "Tanggal Broadcast": moment(val.created_at).format("YYYY-MM-DD HH:mm:ss"), + "Judul": val.title_notif, + "Penerima": matchedUser ? matchedUser.name : "-", + "Pesan": val.message_notif, + "Deskripsi": val.description, + "Status": val.status_send + } + dataExport.push(row); + }); + const fileName = "Broadcast.xlsx"; + const ws = XLSX.utils.json_to_sheet(dataExport); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, 'Broadcast'); + + XLSX.writeFile(wb, fileName); + } + + handleDetail = (data) => { + console.log("ceh handle detail", data) + this.setState({ dataDetail: data }, () => { + this.showDetailDialog(); + this.setState({ openDialogDetail: true }); + }); + } + + toggleTooltip = (type) => { + if (type === "detail") { + this.setState({ toltipDetail: !this.state.toltipDetail }) + } else if (type === "resend") { + this.setState({ tooltipresend: !this.state.tooltipresend }) + } else if (type === "send") { + this.setState({ tooltipsend: !this.state.tooltipsend }) + } + } + + renderBtnResend = (n) => { + return ( + + this.handleEdit(n, 'resend')}> + this.toggleTooltip("resend")}> + Kirim Ulang + + + ) + } + + renderBtnSend = (n) => { + return ( + + this.handleEdit(n, 'send')}> + this.toggleTooltip("send")}> + Kirim + + + ) + } + + renderTable = () => { + const column = [ + { name: this.props.t('action') }, + { name: this.props.t('title') }, + { name: this.props.t('message') }, + { name: this.props.t('description') }, + { name: this.props.t('receiver') }, + { name: "Status" }, + { name: this.props.t('date') }, + ] + const dataTable2 = this.state.dataTable || []; + const dataUser = this.state.dataUser || []; + + return ( + + {dataTable2.length !== 0 ? dataTable2.map((n) => { + const matchedUser = dataUser.find(item => item.id == n.send_to_id); + return ( + + + + {n.status_send === 'completed' || n.status_send === 'failed' || n.status_send === 'send' || n.status_send === 'resend' ? + this.renderBtnResend(n.id) : + this.renderBtnSend(n.id) + } + + this.handleDetail(n)}> + this.toggleTooltip("detail")}> + Detail + + + + {n.title_notif} + {n.message_notif !== "" ? n.message_notif : "-"} + {n.description !== "" ? n.description : "-"} + { matchedUser ? matchedUser.name : "-" } + {n.status_send !== "" ? n.status_send : "-"} + {n.created_at !== "" ? moment.utc(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"} + + ); + }) : + {this.props.t('noData')} + + } + + ) + } + + toggleDropDown = () => { + this.setState({ splitButtonOpen: !this.state.splitButtonOpen }) + } + + handleCloseDetail = () => { + this.setState({ openDialogDetail: false }) + } + + toggleDialogDetail = () => { + this.setState({ openDialogDetail: !this.state.openDialogDetail }) + } + + 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 { + console.log("test 2 test", val); + 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('title') }, + { name: this.props.t('message') }, + { name: this.props.t('description') }, + { name: this.props.t('receiver') }, + { name: "Status" }, + { name: this.props.t('date') }, + ] + const t = this.props; + const { tooltipTambah, tooltipExport, dataTable, splitButtonOpen, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, statusSend } = this.state + return ( +
+ + this.setState({ alertBroadcast: false })} + focusCancelBtn + > + {`Yakin ingin ${statusSend === 'send' ? 'Mengirimkan' : 'Mengirimkan Ulang'} Broadcast?`} + + this.toggleAddDialog} + typeDialog={this.state.typeDialog} + dataEdit={this.state.dataEdit} + showDialog={showDialog => this.showChildDialog = showDialog} + dataHs={this.state.dataIdHo} + /> + this.toggleDialogDetail} + dataDetail={this.state.dataDetail} + showDialog={showDialog => this.showDetailDialog = showDialog} + /> + + +

{this.props.params.name}

+ + + + + this.toggle("tambah")}> + {this.props.t('broadcastAdd')} + + this.toggle("export")}> + {this.props.t('exportExcel')} + + + +
+ +
+
+
+ this.handleChangeDay(e)} defaultValue={this.state.currentDay}> + + + + +
+
+ {' '} + +
+
+ + + + + + this.setState({ + searchDetail: this.props.t('title'), + searchDetailField: "title_notif" + })}>Judul + this.setState({ + searchDetail: this.props.t('description'), + searchDetailField: "description" + })}>Deskripsi + this.setState({ + searchDetail: this.props.t('message'), + searchDetailField: "message_notif" + })}>Pesan + this.setState({ + searchDetail: "Status", + searchDetailField: "status_send" + })}>Status + + + +
+ + + + {column.map((i, index) => { + return ( + + ) + })} + + + {this.renderTable()} +
{i.name}
+ +
+
+
+ ) + } +} +export default withTranslation()(index); diff --git a/src/views/Master/MasterMenu/DialogForm.js b/src/views/Master/MasterMenu/DialogForm.js index 759a56c..60b8134 100644 --- a/src/views/Master/MasterMenu/DialogForm.js +++ b/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 ( - - ) - })} - - ) - } - - const renderForm = () => { - return ( -
- - - - - setName(e.target.value)} placeholder={t('inputName')} /> - - - - setUrl(e.target.value)} placeholder={t('inputUrl')} /> - - - - setIcon(e.target.value)} placeholder={t('inputIcon')} /> - - - - - - setSequence(e.target.value)} placeholder={t('inputOrder')} /> - - - - - - - - setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} /> - - - - -
- ) - } - - - return ( - - {typeDialog == "Save" ? `Tambah` : "Edit"} Menu - - {renderForm()} - - - {' '} - - - - ) - -} - -export default DialogForm; \ No newline at end of file +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 ( + + ) + })} + + ) + } + + const renderForm = () => { + return ( +
+ + + * Wajib diisi. + + + + + + + setName(e.target.value)} placeholder={t('inputName')} /> + + + + setUrl(e.target.value)} placeholder={t('inputUrl')} /> + + + + setIcon(e.target.value)} placeholder={t('inputIcon')} /> + + + + + + setSequence(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputOrder')} /> + + + + + + + + setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} /> + + + + +
+ ) + } + + + return ( + + {typeDialog == "Save" ? `Tambah` : "Edit"} Menu + + {renderForm()} + + + {' '} + + + + ) + +} + +export default DialogForm; diff --git a/src/views/Master/MasterMenu/index.js b/src/views/Master/MasterMenu/index.js index bbb960d..3c78402 100644 --- a/src/views/Master/MasterMenu/index.js +++ b/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) => <> - - handleDelete(text.id)}> - - - handleEdit(text)}> - - , - }, - { 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 ( - - ) - }, [dataTable]) - - return ( -
- - cancelDelete()} - focusCancelBtn - > - {t('deleteMsg')} - - toggleAddDialog} - typeDialog={typeDialog} - dataEdit={dataEdit} - clickOpenModal={clickOpenModal} - dataMenu={allDataMenu} - /> - - -

{pageName}

- -
- - - - - - - - - - - - - - {renderTable} - - - - - ) -} - -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) => <> + + handleDelete(text.id)}> + + + handleEdit(text)}> + + , + }, + { 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 ( +
+ ) + }, [dataTable]) + + return ( +
+ + cancelDelete()} + focusCancelBtn + > + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + dataMenu={allDataMenu} + /> + + +

{pageName}

+ +
+ + + + + + + + + + + + + + {renderTable} + + + + + ) +} + +export default Index; diff --git a/src/views/Master/MasterRoles/DialogForm.js b/src/views/Master/MasterRoles/DialogForm.js index 76e6d12..a511605 100644 --- a/src/views/Master/MasterRoles/DialogForm.js +++ b/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 ( - - - - this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} /> - - - - this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> - - - ) - } - - render() { - return ( - - {this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('roles')} - - {this.renderForm()} - - - {' '} - - - - ) - } -} -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 ( + + + + * Wajib diisi. + + + + + + + this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} /> + + + + + + this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> + + + + + ) + } + + render() { + return ( + + {this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('roles')} + + {this.renderForm()} + + + {' '} + + + + ) + } +} +export default withTranslation()(DialogForm); diff --git a/src/views/Master/MasterRoles/index.js b/src/views/Master/MasterRoles/index.js index f68e362..e1b6546 100644 --- a/src/views/Master/MasterRoles/index.js +++ b/src/views/Master/MasterRoles/index.js @@ -165,9 +165,9 @@ class index extends Component { .catch((error) => error.response); if (result && result.data && result.data.code === 200) { - this.deleteCurrentRoleMenu(idDelete) - this.getDataRoles() - this.setState({ idDelete: 0, alertDelete: false }) + 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 }) @@ -188,9 +188,9 @@ class index extends Component { if (result && result.data && result.data.code === 200) { this.getDataRoles(); - NotificationManager.success(`Data role berhasil ditambah`, 'Success!!'); + NotificationManager.success(`Data role berhasil ditambahkan`, 'Success!!'); } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); + NotificationManager.error(`Data role gagal ditambahkan`, 'Failed!!'); } } @@ -207,9 +207,9 @@ class index extends Component { if (result && result.data && result.data.code === 200) { this.getDataRoles(); - NotificationManager.success(`Data role berhasil diedit`, 'Success!!'); + NotificationManager.success(`Data role berhasil diubah`, 'Success!!'); } else { - NotificationManager.error(`Data role gagal di edit`, `Failed!!`); + NotificationManager.error(`Data role gagal diubah`, `Failed!!`); } } diff --git a/src/views/SimproV2/ChecklistK3/index.js b/src/views/SimproV2/ChecklistK3/index.js index 4c13d00..1f6c540 100644 --- a/src/views/SimproV2/ChecklistK3/index.js +++ b/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 ( - - - - ) - } - } - - return ( -
- - cancelDelete()} - focusCancelBtn - > - {t('deleteMsg')} - - toggleAddDialog} - typeDialog={typeDialog} - dataEdit={dataEdit} - clickOpenModal={clickOpenModal} - dataParent={allDataMenu} - /> - - -

{pageName}

- -
- - - - - - - - - - - - - -
{t('noData')}
- - - - {column.map((i, index) => { - return ( - - ) - })} - - - - {dataNotAvailable()} - {dataTable.map((n, index) => { - return ( - - - - - - ) - })} - -
{t('action')}{i.name}
- - handleDelete(n.id)}> - - - handleEdit(n)}> - - {n.name}{n.description}
- - - - - ) -} - -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 ( + + {t('noData')} + + ) + } + } + + return ( +
+ + cancelDelete()} + focusCancelBtn + > + {t('deleteMsg')} + + toggleAddDialog} + typeDialog={typeDialog} + dataEdit={dataEdit} + clickOpenModal={clickOpenModal} + dataParent={allDataMenu} + /> + + +

{pageName}

+ + + + + + + + + + + + + +
+ + + + + + {column.map((i, index) => { + return ( + + ) + })} + + + + {dataNotAvailable()} + {dataTable.map((n, index) => { + return ( + + + + + + ) + })} + +
{t('action')}{i.name}
+ + handleDelete(n.id)}> + + + handleEdit(n)}> + + {n.name}{n.description}
+ +
+
+
+ ) +} + +export default ChecklistK3; diff --git a/src/views/SimproV2/CreatedProyek/AsignCustProject.js b/src/views/SimproV2/CreatedProyek/AsignCustProject.js index d845546..1b9a70c 100644 --- a/src/views/SimproV2/CreatedProyek/AsignCustProject.js +++ b/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) => <> + render: (text, record) => <> {" "}, }, - { 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; diff --git a/src/views/SimproV2/CreatedProyek/DialogAssignCust.js b/src/views/SimproV2/CreatedProyek/DialogAssignCust.js index 1bc885b..940250c 100644 --- a/src/views/SimproV2/CreatedProyek/DialogAssignCust.js +++ b/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 (
{ - 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 ( -
- - - setName(e.target.value)} placeholder='' /> - - - - setDesctription(e.target.value)} placeholder='' /> - - - -
- setName(e.target.value)}/> + + + + setDesctription(e.target.value)}/> + + + +
+ setName(e.target.value)} - /> - - - - - - setShortName(e.target.value)} - /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - let currentDate = moment(current).format("YYYY-MM-DD"); - let customDate = moment(startDate) - .add(1, "days") - .format("YYYY-MM-DD"); - return current && currentDate < customDate; - }} - format={"DD-MM-YYYY"} - style={{ width: "100%" }} - value={endDate} - onChange={handleDatePickerEnd} - /> - - - - - - - - setWorkArea(e.target.value)} - /> - - - - - - setCompany(e.target.value)} - /> - - - - - - - - - - - - - setBiaya(formatNumber(e.target.value))} - /> - - - - - - - - setDescription(e.target.value)} - /> - - - - - - - - - - - - - Info Dashboard - - - - - - - - - - - - - - - - - ); - }; - - const renderFormCharter = () => { - return ( -
- - - Project Objectives - - - - setObjectives(e.target.value)} - /> - - - - - - Project is considered successful when - - - - - setProjectIsConsideredSuccessful(e.target.value) - } - placeholder={`List of indicators`} - rows={5} - /> - - - - - - Project Participants - - - {/* - - - - */} - - - Title - - - Name - - - Action - - - - - -
{RenderParticipants()}
- -
- - - Testing Environment - - - - setTestingEnv(e.target.value)} - rows={5} - /> - - - - - - Milestones - - - {/* - - - - */} - - - Status - - {/* - Due - */} - - Deadline - - - Action - - - - - -
{RenderMilestones()}
- -
- - - Potential risks - - - - setPotentialRisks(e.target.value)} - placeholder={`List of risks`} - rows={5} - /> - - - - - - Approval - - - {/* - - - - */} - - - Title - - - Name - - - Date - - - Action - - - - - -
{RenderApproval()}
- -
-
- ); - }; - - const RenderParticipants = () => { - if (participants.length > 0) { - return participants.map((item, index) => { - return ( - - - handleInputChangeParticipants(e, index)} - /> - - - handleInputChangeParticipants(e, index)} - /> - - - - - - ); - }); - } else if (participants.length < 1) { - return ( -
- No participants found -
- ); - } - }; - - const RenderMilestones = () => { - if (milestones.length > 0) { - return milestones.map((item, index) => { - return ( - - - handleInputChangeMilestones(e, index)} - /> - - - - handleInputChangeMilestonesDate(date, "deadline", index) - } - /> - - - - - - ); - }); - } else if (milestones.length < 1) { - return ( -
- No milestones found -
- ); - } - }; - - const RenderApproval = () => { - if (approval.length > 0) { - return approval.map((item, index) => { - return ( - - - handleInputChangeApproval(e, index)} - /> - - - handleInputChangeApproval(e, index)} - /> - - - - handleInputChangeApprovalDate(date, "date", index) - } - /> - - - - - - ); - }); - } else if (approval.length < 1) { - return ( -
- No approval found -
- ); - } - }; - - return ( - <> - - - {step === 1 - ? idTask - ? "Update Project" - : "Add Project" - : "Project Charter"} - - {step === 1 ? renderForm() : renderFormCharter()} - - {step === 1 ? ( - <> - {" "} - - - ) : ( - <> - {" "} - - - )} - - - - ); -}; - -export default DialogFormProyek; +import React, { useEffect, useState, useMemo } from "react"; +import { Modal, ModalHeader, ModalBody, ModalFooter } from "reactstrap"; +import { Button, Form, FormGroup, Label, Input, Col, Row } from "reactstrap"; +import { DatePicker, Tooltip, Select, Divider } from "antd"; +import axios from "../../../const/interceptorApi"; +import moment from "moment"; +import { CKEditor } from '@ckeditor/ckeditor5-react'; +import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; +import { + NotificationContainer, + NotificationManager, +} from "react-notifications"; +import "antd/dist/antd.css"; +import { formatNumber } from "../../../const/CustomFunc"; +import { + PROYEK_GET_ID, + PROJECT_MILESTONE_WHERE_CUSTOM, + PROJECT_PARTICIPANT_WHERE_CUSTOM, + PROJECT_CHECKLIST_WHERE_CUSTOM, + PROJECT_ISSUE_WHERE_CUSTOM, + PROJECT_RISK_WHERE_CUSTOM, + PROJECT_APPROVAL_WHERE_CUSTOM, + CURRENCY_LIST, +} from "../../../const/ApiConst"; + +const { Option } = Select; + +const DialogFormProyek = ({ + openDialog, + closeDialog, + toggleDialog, + idTask, + dataTypeProyek, + dataPhaseProject, + dataDivisions, + dataPM, + projectImage +}) => { + 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 [shortName, setShortName] = useState(""); + const [description, setDescription] = useState(""); + const [late, setLateConsequence] = useState(""); + const [assumtion, setAssumtion] = useState(""); + const [biaya, setBiaya] = useState(""); + const [typeProject, setTypeproject] = useState(null); + const [phaseProject, setPhaseProject] = useState(null); + const [divisiProject, setDivisiProject] = useState(null); + const [budgetHealth, setHealthBudget] = useState(null); + const [sdm, setSdm] = useState(0); + const [pic, setPic] = useState(null); + const [startDate, setStartDate] = useState(moment()); + const [endDate, setEndDate] = useState(moment()); + const [workArea, setWorkArea] = useState(""); + const [duration, setProjectDuration] = useState(""); + const [organization, setProjectStructureOrg] = useState(null); + const [finance, setFinance] = useState(""); + const [investor, setInvestor] = useState(""); + const [company, setCompany] = useState(""); + const [step, setStep] = useState(1); + const [currencyList, setCurrencyList] = useState(null); + const [currency, setCurrency] = useState(""); // merge of code | symbol | name + const [currencyCode, setCurrencyCode] = useState(""); + const [currencySymbol, setCurrencySymbol] = useState(null); + const [currencyName, setCurrencyName] = useState(""); + const [objectives, setObjectives] = useState(""); + const [projectIsConsideredSuccessful, setProjectIsConsideredSuccessful] = useState(""); + const [participants, setParticipants] = useState([]); + const [checklist, setChecklist] = useState([]); + const [issue, setIssue] = useState([]); + const [image, setImage] = useState("") + const [availableResources, setAvailableResources] = useState(""); + const [milestones, setMilestones] = useState([]); + const [potentialRisks, setPotentialRisks] = useState([]); + const [approval, setApproval] = useState([]); + const [testingEnv, setTestingEnv] = useState(""); + + const [lastIdxParticipants, setLastIdxParticipants] = useState(0); + const [lastIdxChecklists, setLastIdxChecklists] = useState(0); + const [lastIdxIssues, setLastIdxIssues] = useState(0); + const [lastIdxRisks, setLastIdxRisks] = useState(0); + const [lastIdxMilestones, setLastIdxMilestones] = useState(0); + const [lastIdxApproval, setLastIdxApproval] = useState(0); + + const handleGetdataIdproyek = async (id) => { + const result = await axios + .get(`${PROYEK_GET_ID(id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + if (result && result.data && result.data.code === 200) { + const val = result.data.data; + setName(val.nama); + setShortName(val.kode_sortname); + setDescription(val.keterangan); + setLateConsequence(val.late_consequence ? val.late_consequence : ""); + setAssumtion(val.assumtion ? val.assumtion : ""); + setBiaya(val.rencana_biaya ? formatNumber(val.rencana_biaya) : ""); + setTypeproject(val.type_proyek_id); + setPhaseProject(val.phase_id); + setDivisiProject(val.divisi_id); + setHealthBudget(val.budget_health); + setPic(val.pm_id); + setStartDate(moment(val.mulai_proyek)); + setEndDate(moment(val.akhir_proyek)); + setWorkArea(val.area_kerja); + setProjectDuration(val.durasi_proyek); + setInvestor(val.investor); + setCompany(val.company); + setFinance(val.finance); + setObjectives(val.project_objectives ? val.project_objectives : ""); + setTestingEnv(val.testing_environment); + setProjectIsConsideredSuccessful( + val.considered_success_when ? val.considered_success_when : "" + ); + setCurrencyCode(val.currency_code); + setCurrencySymbol(val.currency_symbol); + setCurrencyName(val.currency_name); + } else { + NotificationManager.error(`Data proyek gagal di edit`, `Failed!!`); + } + }; + + const handleGetDataApproval = async (id) => { + const result = await axios + .get(`${PROJECT_APPROVAL_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setApproval(result.data.data); + }; + + const handleGetDataMileStone = async (id) => { + const result = await axios + .get(`${PROJECT_MILESTONE_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setMilestones(result.data.data); + }; + + const handleGetDataParticipants = async (id) => { + const result = await axios + .get(`${PROJECT_PARTICIPANT_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setParticipants(result.data.data); + }; + + const handleGetDataChecklist = async (id) => { + const result = await axios + .get(`${PROJECT_CHECKLIST_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setChecklist(result.data.data); + }; + + const handleGetDataIssue = async (id) => { + const result = await axios + .get(`${PROJECT_ISSUE_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setIssue(result.data.data); + }; + + const handleGetDataRisk = async (id) => { + const result = await axios + .get(`${PROJECT_RISK_WHERE_CUSTOM("proyek_id", id)}`, HEADER) + .then((res) => res) + .catch((err) => err.response); + setPotentialRisks(result.data.data); + }; + + const handleGetDataCurrency = async () => { + const result = await axios + .get(CURRENCY_LIST, HEADER) + .then((res) => res) + .catch((err) => err.response); + setCurrencyList(result.data.data); + }; + + const handleClearData = () => { + setName(""); + setShortName(""); + setBiaya(""); + setTypeproject(null); + setPhaseProject(null); + setHealthBudget(null); + setPic(null); + setStartDate(moment()); + setEndDate(moment()); + setDescription(""); + setLateConsequence(""); + setAssumtion(""); + setInvestor(""); + setFinance(""); + setWorkArea(""); + setProjectDuration(""); + setProjectStructureOrg(null); + setCompany(""); + setCurrency(""); + setCurrencyCode(""); + setCurrencySymbol(null); + setCurrencyName(""); + setObjectives(""); + setImage(""); + setProjectIsConsideredSuccessful(""); + setParticipants([]); + setChecklist([]); + setIssue([]); + setAvailableResources(""); + setMilestones([]); + setPotentialRisks([]); + setApproval([]); + setTestingEnv(""); + setLastIdxParticipants(0); + setLastIdxChecklists(0); + setLastIdxMilestones(0); + setLastIdxApproval(0); + setStep(1); + }; + + useEffect(() => { + if (openDialog) { + handleGetDataCurrency(); + } + + if (idTask && idTask > 0) { + handleGetdataIdproyek(idTask); + handleGetDataParticipants(idTask); + handleGetDataChecklist(idTask); + handleGetDataIssue(idTask); + handleGetDataRisk(idTask); + handleGetDataMileStone(idTask); + handleGetDataApproval(idTask); + } else { + handleClearData(); + } + }, [openDialog]); + + const handleSave = () => { + let data = ""; + if (idTask) { + data = { + id: idTask, + nama: name, + kode_sortname: shortName, + rencana_biaya: biaya.replaceAll(".", ""), + mulai_proyek: startDate, + akhir_proyek: endDate, + type_proyek_id: parseInt(typeProject), + phase_id: parseInt(phaseProject), + divisi_id: parseInt(divisiProject), + budget_health: budgetHealth, + pm_id: pic, + investor, + finance, + company, + area_kerja: workArea, + durasi_proyek: parseInt(duration), + late_consequence: late, + assumtion: assumtion, + keterangan: description, + project_objectives: objectives, + considered_success_when: projectIsConsideredSuccessful, + testing_environment: testingEnv, + currency_symbol: currencySymbol, + currency_code: currencyCode, + currency_name: currencyName, + }; + data.projectCharter = { checklist, issue, potentialRisks, participants, milestones, approval }; + data.imageStructureOrg = organization ? organization : null; + closeDialog("edit", data); + } else { + data = { + nama: name, + kode_sortname: shortName, + rencana_biaya: biaya.replaceAll(".", ""), + mulai_proyek: startDate, + akhir_proyek: endDate, + type_proyek_id: parseInt(typeProject), + phase_id: parseInt(phaseProject), + divisi_id: parseInt(divisiProject), + health_budget: budgetHealth, + pm_id: pic, + investor, + finance, + company, + area_kerja: workArea, + durasi_proyek: parseInt(duration), + late_consequence: late, + assumtion: assumtion, + keterangan: description, + project_objectives: objectives, + considered_success_when: projectIsConsideredSuccessful, + testing_environment: testingEnv, + currency_symbol: currencySymbol, + currency_code: currencyCode, + currency_name: currencyName, + }; + data.projectCharter = { checklist, issue, potentialRisks, participants, milestones, approval }; + data.imageStructureOrg = organization ? organization : null; + + closeDialog("add", data); + } + handleClearData(); + }; + + const handleCancel = () => { + closeDialog("cancel", "none"); + handleClearData(); + }; + + const onChangeTypeProject = (val) => { + setTypeproject(val); + }; + + const onChangePhaseProject = (val) => { + setPhaseProject(val); + }; + + const onChangeDivisiProject = (val) => { + setDivisiProject(val); + }; + + const onChangeBudgetHealth = (val) => { + setHealthBudget(val); + }; + + const onChangePm = (val) => { + let data = [...dataPM]; + var item = data.find((item) => item.id === val); + participants.push({ + id: lastIdxParticipants + 1, + title: "PM", + name: item.name, + }); + setParticipants(participants); + setLastIdxParticipants(lastIdxParticipants + 1); + setPic(val); + }; + + const onChangeCurrency = (val) => { + let curr = val.split("|"); // code|symbol|name + setCurrencyCode(curr[0]); + setCurrencySymbol(curr[1]); + setCurrencyName(curr[2]); + }; + + const handleDatePickerStart = (date, dateString) => { + setStartDate(date); + }; + + const handleDatePickerEnd = (date, dateString) => { + setEndDate(date); + }; + + const nextStep = () => { + if (!name || name === "") { + alert("Project Name cannot be empty!"); + return false; + } + if (!shortName || shortName === "") { + alert("Project Code cannot be empty!"); + return false; + } + if (!typeProject || typeProject === "") { + alert("Project Type cannot be empty!"); + return false; + } + if (!startDate || startDate === "") { + alert("Start Date cannot be empty!"); + return false; + } + if (!endDate || endDate === "") { + alert("End Date cannot be empty!"); + return false; + } + if (!biaya || biaya === "") { + alert("Budget cannot be empty!"); + return false; + } + if (!currencySymbol || currencySymbol === "") { + alert("Currency Symbol cannot be empty!"); + return false; + } + setStep(2); + }; + + const previousStep = () => { + setStep(1); + }; + + const addParticipant = () => { + participants.push({ + id: lastIdxParticipants + 1, + title: "", + name: "", + }); + setParticipants(participants); + setLastIdxParticipants(lastIdxParticipants + 1); + }; + + const addChecklist = () => { + checklist.push({ + id: lastIdxChecklists + 1, + item: "", + status_exist: "", + }); + setChecklist(checklist); + setLastIdxChecklists(lastIdxChecklists + 1); + }; + + const addIssue = () => { + issue.push({ + id: lastIdxIssues + 1, + description: "", + level_issue: "", + }); + setIssue(issue); + setLastIdxIssues(lastIdxIssues + 1); + }; + + const addRisk = () => { + potentialRisks.push({ + id: lastIdxRisks + 1, + level_risk: "", + description: "", + preventive_risk: "", + }); + setPotentialRisks(potentialRisks); + setLastIdxRisks(lastIdxRisks + 1); + }; + + const handleInputChangeParticipants = (e, index) => { + const { name, value } = e.target; + const newParticipants = [...participants]; + newParticipants[index][name] = value; + setParticipants(newParticipants); + }; + + const handleInputChangeChecklists = (e, index) => { + if (e === true || e === false) { + const value = e; + const name = "status_exist"; + const newChecklists = [...checklist]; + newChecklists[index][name] = value; + setChecklist(newChecklists); + } else { + const { name, value } = e.target; + const newChecklists = [...checklist]; + newChecklists[index][name] = value; + setChecklist(newChecklists); + } + }; + + const handleInputChangeIssues = (e, index) => { + if (e === 1 || e === 2|| e === 3|| e === 4|| e === 5|| e === 6|| e === 7) { + const value = e; + const name = "level_issue"; + const newIssues = [...issue]; + newIssues[index][name] = value; + setIssue(newIssues); + } else { + const { name, value } = e.target; + const newIssues = [...issue]; + newIssues[index][name] = value; + setIssue(newIssues); + } + }; + + const handleInputChangeRisks = (e, index) => { + if (e === 1 || e === 2 || e === 3 || e === 4 || e === 5 || e === 6 || e === 7) { + const value = e; + const name = "level_risk"; + const newRisks = [...potentialRisks]; + newRisks[index][name] = value; + setPotentialRisks(newRisks); + } else { + const { name, value } = e.target; + const newRisks = [...potentialRisks]; + newRisks[index][name] = value; + setPotentialRisks(newRisks); + } + }; + + const deleteParticipant = (id) => { + if (participants && participants.length > 0) { + let parIdx = participants.findIndex((o) => o.id === id); + if (parIdx > -1) { + participants.splice(parIdx, 1); + setParticipants(participants.filter((_, i2) => i2 !== id)); + } + } + }; + + const deleteChecklists = (id) => { + if (checklist && checklist.length > 0) { + let checkIdx = checklist.findIndex((o) => o.id === id); + if (checkIdx > -1) { + checklist.splice(checkIdx, 1); + setChecklist(checklist.filter((_, i2) => i2 !== id)); + } + } + }; + + const deleteIssues = (id) => { + if (issue && issue.length > 0) { + let issueIdx = issue.findIndex((o) => o.id === id); + if (issueIdx > -1) { + issue.splice(issueIdx, 1); + setIssue(issue.filter((_, i2) => i2 !== id)); + } + } + }; + + const deleteRisks = (id) => { + if (potentialRisks && potentialRisks.length > 0) { + let riskIdx = potentialRisks.findIndex((o) => o.id === id); + if (riskIdx > -1) { + potentialRisks.splice(riskIdx, 1); + setPotentialRisks(potentialRisks.filter((_, i2) => i2 !== id)); + } + } + }; + + const addMilestone = () => { + milestones.push({ + id: lastIdxMilestones + 1, + status: "", + due: moment(), + deadline: moment(), + }); + setMilestones(milestones); + setLastIdxMilestones(lastIdxMilestones + 1); + }; + + const handleInputChangeMilestones = (e, index) => { + const { name, value } = e.target; + const newMilestones = [...milestones]; + newMilestones[index][name] = value; + setMilestones(newMilestones); + }; + + const handleInputChangeMilestonesDate = (date, name, index) => { + const newMilestones = [...milestones]; + newMilestones[index][name] = date; + setMilestones(newMilestones); + }; + + const deleteMilestones = (id) => { + if (milestones && milestones.length > 0) { + let mileIdx = milestones.findIndex((o) => o.id === id); + if (mileIdx > -1) { + milestones.splice(mileIdx, 1); + setMilestones(milestones.filter((_, i2) => i2 !== id)); + } + } + }; + + const addApproval = () => { + approval.push({ + id: lastIdxApproval + 1, + title: "", + name: "", + date: moment(), + }); + setApproval(approval); + setLastIdxApproval(lastIdxApproval + 1); + }; + + const handleInputChangeApproval = (e, index) => { + const { name, value } = e.target; + const newApproval = [...approval]; + newApproval[index][name] = value; + setApproval(newApproval); + }; + + const handleInputChangeApprovalDate = (date, name, index) => { + const newApproval = [...approval]; + newApproval[index][name] = date; + setApproval(newApproval); + }; + + const deleteApproval = (id) => { + if (approval && approval.length > 0) { + let mileIdx = approval.findIndex((o) => o.id === id); + if (mileIdx > -1) { + approval.splice(mileIdx, 1); + setApproval(approval.filter((_, i2) => i2 !== id)); + } + } + }; + const editorConfig = { + height: '900px' + }; + + const RenderFormProject = () => { + return ( + <> +
+ + + * Wajib diisi. + + + + + + + setName(e.target.value)} + /> + + + + + + setShortName(e.target.value)} + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + let currentDate = moment(current).format("YYYY-MM-DD"); + let customDate = moment(startDate) + .add(1, "days") + .format("YYYY-MM-DD"); + return current && currentDate < customDate; + }} + format={"DD-MM-YYYY"} + style={{ width: "100%" }} + value={endDate} + onChange={handleDatePickerEnd} + /> + + + + + + + + setWorkArea(e.target.value)} + /> + + + + + + setCompany(e.target.value)} + /> + + + + + + + + + + + + + setBiaya(formatNumber(e.target.value))} + /> + + + + + + + + + + + + + + + + setProjectDuration(e.target.value)} + /> + + + + + + + + setProjectStructureOrg(e.target.files[0])} + /> + {projectImage ? projectImage.image :

Not found image

}
+
+ + + + + setDescription(e.target.value)} + /> + + +
+ + + + { + const data = editor.getData(); + setLateConsequence(data); + } } + /> + + + + + + { + const data = editor.getData(); + setAssumtion(data); + } } + /> + + + + + + + + Item + + + Availability + + + Action + + + + + + + +
{RenderChecklist()}
+ +
+ + + + + + + Issu Level + + + Description + + + Action + + + + + + + +
{RenderIssue()}
+ +
+ + Info Dashboard + + + + + + + + + + + + + + + +
+ +
+ + + Project Objectives + + + + setObjectives(e.target.value)} + /> + + + + + + Project is considered successful when + + + + + setProjectIsConsideredSuccessful(e.target.value) + } + placeholder={`List of indicators`} + rows={5} + /> + + + + + + Project Participants + + + + + Title + + + Name + + + Action + + + + + + + +
{RenderParticipants()}
+ +
+ + + Testing Environment + + + + setTestingEnv(e.target.value)} + rows={5} + /> + + + + + + Milestones + + + + + Status + + + Deadline + + + Action + + + + + + + +
{RenderMilestones()}
+ +
+ + + Potential Risk + + + + + Risk Level + + + Description + + + Prevention + + + Action + + + + + + + +
{RenderRisk()}
+ +
+ + + Approval + + + + + Title + + + Name + + + Date + + + Action + + + + + + + +
{RenderApproval()}
+ +
+
+ + ) + } + + const RenderChecklist = () => { + if (checklist.length > 0) { + return checklist.map((item, index) => { + return ( + + + handleInputChangeChecklists(e, index)} + /> + + + + + + + + + + + ); + }); + } else if (checklist.length < 1) { + return ( +
+ No checklist found +
+ ); + } + }; + + const RenderIssue = () => { + if (issue.length > 0) { + return issue.map((item, index) => { + return ( + + + + + + + + + handleInputChangeIssues(e, index)} + /> + + + + + + ); + }); + } else if (issue.length < 1) { + return ( +
+ No Issue found +
+ ); + } + }; + + const RenderRisk = () => { + if (potentialRisks.length > 0) { + return potentialRisks.map((item, index) => { + return ( + + + + + + + + + handleInputChangeRisks(e, index)} + /> + + + handleInputChangeRisks(e, index)} + /> + + + + + + ); + }); + } else if (potentialRisks.length < 1) { + return ( +
+ No Risk found +
+ ); + } + }; + + const RenderParticipants = () => { + if (participants.length > 0) { + return participants.map((item, index) => { + return ( + + + handleInputChangeParticipants(e, index)} + /> + + + handleInputChangeParticipants(e, index)} + /> + + + + + + ); + }); + } else if (participants.length < 1) { + return ( +
+ No participants found +
+ ); + } + }; + + const RenderMilestones = () => { + if (milestones.length > 0) { + return milestones.map((item, index) => { + return ( + + + handleInputChangeMilestones(e, index)} + /> + + + + handleInputChangeMilestonesDate(date, "deadline", index) + } + /> + + + + + + ); + }); + } else if (milestones.length < 1) { + return ( +
+ No milestones found +
+ ); + } + }; + + const RenderApproval = () => { + if (approval.length > 0) { + return approval.map((item, index) => { + return ( + + + handleInputChangeApproval(e, index)} + /> + + + handleInputChangeApproval(e, index)} + /> + + + + handleInputChangeApprovalDate(date, "date", index) + } + /> + + + + + + ); + }); + } else if (approval.length < 1) { + return ( +
+ No approval found +
+ ); + } + }; + + return ( + <> + + + {step === 1 + ? idTask + ? "Update Project" + : "Add Project" + : "Project Charter"} + + { RenderFormProject() } + + {step === 1 ? ( + <> + {" "} + + + ) : ( + <> + {" "} + + + )} + + + + ); +}; + +export default DialogFormProyek; diff --git a/src/views/SimproV2/CreatedProyek/DialogGantt.js b/src/views/SimproV2/CreatedProyek/DialogGantt.js index 9d2f776..fdce115 100644 --- a/src/views/SimproV2/CreatedProyek/DialogGantt.js +++ b/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) => - <> - - - {" "} - - - {" "} - - {" "} - - {" "} - - - - - - {" "} - - , - }, - { 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) => (
{text ? moment(text).format("D-M-YYYY") : "-"}
) }, - { title: 'Progress', dataIndex: 'progress', key: 'progress' } - - ]; - - return ( - - ) - }, [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 ( - <> - - - {hierarchyName ? - - Project - {hierarchyName} - - : -
Gantt Project {proyekName}
- } - {!hierarchyId && (<> - - )} -
- -
- {RenderTable} -
-
- {/* - - */} -
- - cancelDelete()} - focusCancelBtn - > - Delete this data - - - - - - ) - -} - -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) => + <> + + + {" "} + + + {" "} + + + {" "} + + {" "} + + {" "} + + + + + + {" "} + + , + }, + { 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) => (
{text ? moment(text).format("D-M-YYYY") : "-"}
) }, + { title: 'Progress', dataIndex: 'progress', key: 'progress' } + + ]; + + return ( +
+ ) + }, [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 ( + <> + + + {hierarchyName ? + + Project + {hierarchyName} + + : +
Gantt Project {proyekName}
+ } + {!hierarchyId && (<> + + )} +
+ +
+ {RenderTable} +
+
+ {/* + + */} +
+ + cancelDelete()} + focusCancelBtn + > + Delete this data + + + + + + ) + +} + +export default DialogGantt; diff --git a/src/views/SimproV2/CreatedProyek/ViewProject.js b/src/views/SimproV2/CreatedProyek/ViewProject.js index 580b34e..ef36f74 100644 --- a/src/views/SimproV2/CreatedProyek/ViewProject.js +++ b/src/views/SimproV2/CreatedProyek/ViewProject.js @@ -1,271 +1,735 @@ -import React, { useEffect, useState } from 'react' -import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import { Button } from 'reactstrap'; -import moment from 'moment'; -import 'antd/dist/antd.css'; -import _ from 'underscore' -import './style.css' -import { formatThousand, sortBy } from '../../../const/CustomFunc'; - -const createMarkup = (element) => { - return {__html: element}; -} - -const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectMilestone, projectApproval }) => { - - const [proyekName, setProyekName] = useState("") - const [description, setDescription] = useState("") - const [objectives, setObjective] = useState("") - const [projectSuccess, setProjectSuccess] = useState("") - const [participants, setParticipants] = useState("") - const [budget, setBudget] = useState("") - const [currency, setCurrency] = useState("") - const [testing, setTesting] = useState("") - const [milestone, setMilestone] = useState("") - const [potentialRisks, setPotentialRisks] = useState("") - const [approval, setApproval] = useState("") - const formatDate = "DD-MM-YYYY"; - useEffect(() => { - if(!openDialog){ - setProyekName("") - setDescription("") - setObjective("") - setProjectSuccess("") - setParticipants([]) - setBudget("") - setCurrency("") - setTesting("") - setMilestone([]) - setPotentialRisks("") - setApproval([]) - } - }, [openDialog]); - - useEffect(() => { - if(projectCharter && projectCharter!={}){ - setProyekName(projectCharter.nama); - setDescription(projectCharter.keterangan); - setObjective(projectCharter.project_objectives); - setProjectSuccess(projectCharter.considered_success_when); - setBudget(projectCharter.rencana_biaya); - setPotentialRisks(projectCharter.potential_risk); - setTesting(projectCharter.testing_environment); - setCurrency(projectCharter.currency_symbol); - } - }, [projectCharter]); - - useEffect(() => { - if(projectParticipant && projectParticipant.length > 0){ - setParticipants(projectParticipant) - } - }, [projectParticipant]); - - useEffect(() => { - if(projectMilestone && projectMilestone.length > 0){ - setMilestone(projectMilestone) - } - }, [projectMilestone]); - - useEffect(() => { - if(projectApproval && projectApproval.length > 0){ - console.log("cek projectApproval", projectApproval) - setApproval(projectApproval) - } - }, [projectApproval]); - - const RenderParticipant = () => { - if(participants && participants.length > 0){ - return ( - participants.map((val, index) => { - return( - - - - - ) - }) - ) - }else{ - return () - } - } - - const RenderMilestone = () => { - if(milestone && milestone.length > 0) { - let milestoneSorted = sortBy(milestone, { - prop: "deadline", - desc: false, - }); - return ( - milestoneSorted.map((val, index) => { - return( - - - {/* */} - - - ) - }) - ) - }else{ - return () - } - } - - const RenderApproval = () => { - if(approval && approval.length > 0){ - return ( - approval.map((val, index) => { - return( - - - - - ) - }) - ) - }else{ - return () - } - } - - - const renderForm = () => { - return ( -
-
{val.tittle ? val.tittle : val.title}{val.name}


{val.status}{moment(val.due_date).format(formatDate)}{moment(val.deadline).format(formatDate)}


{ (val.tittle ? val.tittle : val.title) +": "+val.name}

{"signature..............."}
{index==0 ? moment(val.date_approval).format(formatDate) : ""}


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Project name: - -
{proyekName}
-
- Project description: - -
{description}
-
- Project objectives: - -
{objectives}
-
- Project is considered successful when: - -
{projectSuccess}
-
- Project participants: - - - - - - - - - - - -
Title:Name:
-
- Budget: - -
{currency} {formatThousand(budget)}
-
- Testing Environment: - -
-
- Milestones: - - - - - - {/* */} - - - - - - -
Status:Due:Deadline:
-
- Potential risks: - -
-
- Approval: - - - - - - - - - - - -
Title and name:Date:
-
-
- ) - } - - return ( - <> - - Project - - {renderForm()} - - - - - - - ) - -} - -export default ViewProject; +import React, { useEffect, useState } from 'react' +import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { Button } from 'reactstrap'; +import moment from 'moment'; +import 'antd/dist/antd.css'; +import _ from 'underscore' +import './style.css' +import { formatThousand, sortBy } from '../../../const/CustomFunc'; +import { BASE_OSPRO } from "../../../const/ApiConst"; + +const createMarkup = (element) => { + return {__html: element}; +} + + const ViewProject = ({ openDialog, closeDialog, toggleDialog, projectCharter, projectParticipant, projectChecklist, projectIssue, projectRisk, projectMilestone, projectApproval, projectManager, projectK3, assignHR, projectImage }) => { + const [proyekName, setProyekName] = useState("") + const [description, setDescription] = useState("") + const [shortname, setKodeShortname] = useState("") + const [lokasi, setLokasiKantor] = useState("") + const [durasi, setDurasiProyek] = useState("") + const [mulaiProyek, setMulaiProyek] = useState("") + const [valueProyek, setValueProyek] = useState("") + const [scoupeProyek, setScoupeProyek] = useState("") + const [sponsorProyek, setSponsorProyek] = useState("") + const [lateProyek, setLateConsequenceProyek] = useState("") + const [assumtionProyek, setAssumtionProyek] = useState("") + const [objectives, setObjective] = useState("") + const [projectSuccess, setProjectSuccess] = useState("") + const [participants, setParticipants] = useState("") + const [checklists, setChecklists] = useState("") + const [risks, setRisks] = useState("") + const [issues, setIssues] = useState("") + const [image, setImage] = useState("") + const [budget, setBudget] = useState("") + const [currency, setCurrency] = useState("") + const [testing, setTesting] = useState("") + const [milestone, setMilestone] = useState("") + const [potentialRisks, setPotentialRisks] = useState("") + const [approval, setApproval] = useState("") + const [PM, setDataPM] = useState("") + const [K3Search, setDataK3Search] = useState("") + const [HR, setAssignHR] = useState("") + const formatDate = "DD-MM-YYYY"; + useEffect(() => { + if(!openDialog){ + setProyekName("") + setDescription("") + setKodeShortname("") + setLokasiKantor("") + setDurasiProyek("") + setMulaiProyek("") + setValueProyek("") + setScoupeProyek("") + setSponsorProyek("") + setLateConsequenceProyek("") + setAssumtionProyek("") + setObjective("") + setProjectSuccess("") + setParticipants([]) + setChecklists([]) + setIssues([]) + setRisks([]) + setDataK3Search([]) + setAssignHR([]) + setImage("") + setBudget("") + setCurrency("") + setTesting("") + setMilestone([]) + setPotentialRisks("") + setApproval([]) + } + }, [openDialog]); + + useEffect(() => { + if(projectCharter && projectCharter!={}){ + setProyekName(projectCharter.nama); + setDescription(projectCharter.keterangan); + setKodeShortname(projectCharter.kode_sortname); + setLokasiKantor(projectCharter.lokasi_kantor); + setDurasiProyek(projectCharter.durasi_proyek); + setMulaiProyek(projectCharter.mulai_proyek); + setValueProyek(projectCharter.value_proyek); + setScoupeProyek(projectCharter.scoupe_of_work); + setSponsorProyek(projectCharter.nama_divisi); + setLateConsequenceProyek(projectCharter.late_consequence); + setAssumtionProyek(projectCharter.assumtion); + setObjective(projectCharter.project_objectives); + setProjectSuccess(projectCharter.considered_success_when); + setBudget(projectCharter.rencana_biaya); + setPotentialRisks(projectCharter.potential_risk); + setTesting(projectCharter.testing_environment); + setCurrency(projectCharter.currency_symbol); + } + }, [projectCharter]); + + useEffect(() => { + if (projectImage && projectImage != {}) { + setImage(projectImage.image) + } + }, [projectImage]); + + useEffect(() => { + if(projectParticipant && projectParticipant.length > 0){ + setParticipants(projectParticipant) + } + }, [projectParticipant]); + + useEffect(() => { + if(projectChecklist && projectChecklist.length > 0){ + setChecklists(projectChecklist) + } + }, [projectChecklist]); + + useEffect(() => { + if(projectIssue && projectIssue.length > 0){ + setIssues(projectIssue) + } + }, [projectIssue]); + + useEffect(() => { + if(projectRisk && projectRisk.length > 0){ + setRisks(projectRisk) + } + }, [projectRisk]); + + useEffect(() => { + if(projectMilestone && projectMilestone.length > 0){ + setMilestone(projectMilestone) + } + }, [projectMilestone]); + + useEffect(() => { + if(projectApproval && projectApproval.length > 0){ + console.log("cek projectApproval", projectApproval) + setApproval(projectApproval) + } + }, [projectApproval]); + + useEffect(() => { + if(projectManager && projectManager.length > 0){ + console.log("cek data PM", projectManager) + setDataPM(projectManager) + } + }, [projectManager]); + + useEffect(() => { + if(projectK3 && projectK3.length > 0){ + setDataK3Search(projectK3) + } + }, [projectK3]); + + useEffect(() => { + if(assignHR && assignHR.length > 0){ + setAssignHR(assignHR) + } + }, [assignHR]); + + const RenderParticipant = () => { + if(participants && participants.length > 0){ + return ( + participants.map((val, index) => { + return( + + {val.tittle ? val.tittle : val.title} + : + {val.name} + + ) + }) + ) + }else{ + return (

) + } + } + + const RenderK3Project = () => { + if (K3Search && K3Search.length > 0) { + const number = "123456789"; + return ( + K3Search.map((val, index) => { + const K3Number = number[index]; + return( + +

{ K3Number }

+

{val.checklist_k3_name ? val.checklist_k3_name : "-"}

+ + ) + }) + ) + }else{ + return (

) + } + } + + const RenderChecklistProject = () => { + if (checklists && checklists.length > 0) { + const number = "123456789"; + return ( + checklists.map((val, index) => { + const ChecklistNumber = number[index]; + return( + +

{ ChecklistNumber }

+

{val.item ? val.item : "-"}

+ +

+ {val.status_exist === true ? "Tersedia" : "Tidak tersedia"} +

+ + + ) + }) + ) + }else{ + return (

) + } + } + + const RenderIssueProject = () => { + if (issues && issues.length > 0) { + return ( + issues.map((val, index) => { + return( + + +

+ {val.level_issue ? val.level_issue : "-"} +

+ +

{val.description ? val.description : "-"}

+ + ) + }) + ) + }else{ + return (

) + } + } + + const RenderRiskProject = () => { + if (risks && risks.length > 0) { + return ( + risks.map((val, index) => { + return( + + +

+ {val.level_risk ? val.level_risk : "-"} +

+ +

{val.description ? val.description : "-"}

+

{val.preventive_risk ? val.preventive_risk : "-"}

+ + ) + }) + ) + }else{ + return (

) + } + } + + const RenderAssignHR = () => { + if (HR && HR.length > 0) { + return ( + HR.map((val, index) => { + return( + + +

{val.join_first_name ? val.join_first_name : val.join_first_name}

+ + +

{val.join_second_name ? val.join_second_name : val.join_second_name}

+ + +

{val.join_second_description ? val.join_second_description : val.join_second_description}

+ + + ) + }) + ) + }else{ + return (

) + } + } + + const RenderMilestone = () => { + if (milestone && milestone.length > 0) { + let milestoneSorted = sortBy(milestone, { + prop: "deadline", + desc: false, + }); + const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + return ( + milestoneSorted.map((val, index) => { + const milestoneLetter = alphabet[index]; + + return ( + + +

{milestoneLetter}

+ + +

{val.status}

+ + +

 {moment(val.deadline).format(formatDate)}

+ + + ); + }) + ); + } else { + return (

); + } + } + + + const RenderApproval = () => { + if(approval && approval.length > 0){ + return ( + approval.map((val, index) => { + return( + + { (val.tittle ? val.tittle : val.title) +": "+val.name}

{"signature..............."} + {index==0 ? moment(val.date_approval).format(formatDate) : ""} + + ) + }) + ) + }else{ + return (

) + } + } + + const tableStyle = { + border: '1px solid black', + borderSpacing: '0px', + width: '100%' + }; + + const thStyle = { + border: '1px solid black', + padding: '2pt', + backgroundColor: '#F2F2F2', + }; + + const tdStyle = { + border: '1px solid black', + width: "250px" + }; + const pStyle = { + marginLeft: '5pt', + marginTop: '2pt', + marginBottom: '2pt', + fontFamily: 'Arial', + fontSize: '10pt', + fontWeight: 'bold', + }; + + const italicStyle = { + fontStyle: 'italic' + }; + const boldStyle = { + fontWeight: 'bold', + fontVariant: 'small-caps', + }; + + const emptyCellStyle = { + padding: '0', + }; + + const renderForm = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

1.0 Identifikasi PROYEK

+
+

Nama Proyek

+
+

{proyekName ?? '-'}

+
+

Project description

+
+

{description ?? '-'}

+
+

Nomor Proyek

+
+

 {shortname ?? '-'}

+
+

Lokasi Proyek

+
+

 {lokasi ?? '-' }

+
+

Durasi Proyek

+
+

 {durasi ?? '-'}

+
+

Tanggal Mulai Proyek

+
+

 {moment(mulaiProyek).format(formatDate) ?? "-"}

+
+

Nilai Kontrak Proyek

+
+

 {valueProyek ?? '-'}

+
+

Anggaran Proyek

+
+

{currency}. {formatThousand(budget)}

+
+

Sponsor Proyek

+
+

+ {sponsorProyek ?? '-'} +

+
+

 

+
+

Project Manager

+
+

 {PM}

+
+

Sumber Daya Manusia Untuk Proyek

+
+ +
+

 

+ + + + + + + + + +
+

2.0 OBJEKTIF PROYEK (TUJUAN)

+
+

{objectives ?? '-'}

+
+

 

+ + + + + + + + + +
+

3.0 RUANG LINGKUP PROYEK

+
+
    +
  • { scoupeProyek ?? '-' }
  • +
+
+

 

+ + + + + + + + + + + < RenderAssignHR/> + +
+

4.0 ANGGOTA PROYEK

+
+

Nama

+
+

Posisi

+
+

Tugas dan Tanggung Jawab

+
+

 

+ + + + + + + + + +
+

5.0 STRUKTUR ORGANISASI

+
+

  + {image ? ( + + ) : ( + '-' + )} +

+
+

 

+ + + + + + + + + + + + +
+

6.0 TARGET UTAMA & MILESTONE PENCAPAIAN

+
+

Item

+
+

Event Besar / Milestone

+
+

Tanggal

+
+

 

+ + + + + + + + + + + +
+

7.0 ISU & HAMBATAN UTAMA

+
+

Tingkat Kepelikan Isu

+
+

Penjelasan

+
+

*Skala 1 ke 7 (1 = kecil, 7 = besar)

+

 

+ + + + + + + + + + + + +
+

8.0 RESIKO

+
+

Tingkat Dampak Resiko

+
+

Penjelasan

+
+

Pencegahan

+
+

*Skala 1 ke 7 (1 = kecil, 7 = besar)

+

 

+ + + + + + +

+ + +
+

9.0 KONSEKUENSI DARI KETERLAMBATAN

+
+

 

+ + + + + + + + + +
+

10.0 KRITERIA SUSKSES DARI PROYEK (HARUS TERUKUR)

+
+

{projectSuccess ?? '-'}

+
+

 

+ + + + + + + + + +
+

11.0 ASUMSI (SUMBERDAYA UTAMA)

+
+

+
+

 

+ + + + + + + + + + + + +
+

12.0 CHECK LIST KESIAPAN PROYEK** item utama yang paling kritikal

+
+

NO

+
+

ITEM

+
+

KETERSEDIAAN

+
+

 

+ + + + + + + + + + + +
+

13.0 KESEHATAN & KESELAMATAN KERJA (K3)

+
+

NO

+
+

ITEM

+
+

 

+ + + + + + + + + +
+

13.0 KOMITMEN DISEPAKATI OLEH

+
+
+ ) + } + + return ( + <> + + Project + + {renderForm()} + + + + + + + ) + +} + +export default ViewProject; diff --git a/src/views/SimproV2/CreatedProyek/index.js b/src/views/SimproV2/CreatedProyek/index.js index bbe638a..6c2f44b 100644 --- a/src/views/SimproV2/CreatedProyek/index.js +++ b/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); @@ -222,13 +249,14 @@ const CreatedProyek = ({ params, ...props }) => { } }; - 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 { } }; @@ -426,9 +454,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 +525,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); }; @@ -525,6 +561,32 @@ const CreatedProyek = ({ params, ...props }) => { } }; + 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 +599,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 +609,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 +629,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 +706,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 +810,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 +836,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 +853,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 +874,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 +894,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 +921,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 +970,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 +1073,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 +1110,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 +1130,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); @@ -1342,6 +1749,7 @@ const CreatedProyek = ({ params, ...props }) => { dataPhaseProject={dataPhaseProject} dataDivisions={dataDivisions} dataPM={dataPm} + projectImage={image} /> ), [ @@ -1351,6 +1759,7 @@ const CreatedProyek = ({ params, ...props }) => { dataPhaseProject, dataTypeProyek, idTask, + image ] ); @@ -1464,8 +1873,15 @@ 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} /> ), [openDialogViewDetail] diff --git a/src/views/SimproV2/Divisi/DialogForm.js b/src/views/SimproV2/Divisi/DialogForm.js index 249e58b..c32e621 100644 --- a/src/views/SimproV2/Divisi/DialogForm.js +++ b/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 ( -
- - - - - setName(e.target.value)} placeholder={t('inputName')} /> - - - - - - - - - - - - - - - - setDescription(e.target.value)} placeholder={t('inputDescription')} /> - - - -
- ) - } - - - return ( - <> - - {typeDialog == "Save" ? `Add` : "Edit"} {t('division')} - - {renderForm()} - - - {' '} - - - - - ) - -} - -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 ( +
+ + + * Wajib diisi. + + + + + + + setName(e.target.value)} + placeholder={t('inputName')} + /> + + + + + + + + + + + + + + setDescription(e.target.value)} placeholder={t('inputDescription')} /> + + + +
+ ) + } + + + return ( + <> + + {typeDialog == "Save" ? `Add` : "Edit"} {t('division')} + + {renderForm()} + + + {' '} + + + + + ) + +} + +export default DialogForm; diff --git a/src/views/SimproV2/Divisi/index.js b/src/views/SimproV2/Divisi/index.js index 418f043..9ab06d3 100644 --- a/src/views/SimproV2/Divisi/index.js +++ b/src/views/SimproV2/Divisi/index.js @@ -47,18 +47,14 @@ const ProjectType = ({ params }) => { const [idDelete, setIdDelete] = useState(0) const [openDialog, setOpenDialog] = useState(false) const [rowsPerPage, setRowsPerPage] = useState(10) - const [search, setSearch] = useState('') + 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() + getDataProjectType(); }, [currentPage, rowsPerPage, search]) useEffect(() => { @@ -87,15 +83,15 @@ const ProjectType = ({ params }) => { const getDataProjectType = async () => { let start = 0; if (currentPage !== 1 && currentPage > 1) { - start = (currentPage * rowsPerPage) - rowsPerPage - } + start = currentPage * rowsPerPage - rowsPerPage; + } const payload = { - "columns": [ + columns: [ { - "name": "name", - "logic_operator": "ilike", - "value": search, - "operator": "AND" + name: "name", + logic_operator: "ilike", + value: search, + operator: "AND" } ], "orders": { @@ -115,11 +111,9 @@ const ProjectType = ({ params }) => { .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); + let dataRes = result.data.data || []; + setDatatable(dataRes); + setTotalPage(result.data.totalRecord); } else { NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); } @@ -220,9 +214,9 @@ const ProjectType = ({ params }) => { .catch((error) => error.response); if (result && result.data && result.data.code === 200) { getDataProjectType() - NotificationManager.success(`Data berhasil ditambah`, 'Success!!'); + NotificationManager.success(`Data berhasil ditambahkan`, 'Success!!'); } else { - NotificationManager.error(`${result.data.message}`, 'Failed!!'); + NotificationManager.error(`Data gagal ditambahkan`, 'Failed!!'); } } @@ -234,9 +228,9 @@ const ProjectType = ({ params }) => { .catch((error) => error.response); if (result && result.data && result.data.code === 200) { getDataProjectType(); - NotificationManager.success(`Data berhasil diedit`, 'Success!!'); + NotificationManager.success(`Data berhasil diubah`, 'Success!!'); } else { - NotificationManager.error(`Data gagal di edit`, `Failed!!`); + NotificationManager.error(`Data gagal diubah`, `Failed!!`); } } diff --git a/src/views/SimproV2/PanicButton/index.js b/src/views/SimproV2/PanicButton/index.js index aa2510c..00d2dd8 100644 --- a/src/views/SimproV2/PanicButton/index.js +++ b/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 ( - - {dataTable2.length !== 0 ? dataTable2.map((n) => { - return ( - - - - this.handleEdit(n)}> - - - this.handleMap(n)}> - - - {n.created_date !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"} - {n.join_first_name !== null ? n.join_first_name : "-"} - {n.status_response !== null ? n.status_response : "-"} - - ) - }) : - No Data Available - - } - - ) - } - - 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 ( -
- - this.toggleMapDialog} - dataMap={this.state.dataMap} - showDialog={showDialog => this.showChildDialog = showDialog} - /> - this.toggleEditDialog} - dataEdit={this.state.dataEdit} - showDialog={showDialog => this.showDialogEdit = showDialog} - /> - - -

{this.props.t('panicButton')}

-
- - - -
-
- -
-
-
- this.handleChangeDay(e)} defaultValue={this.state.currentDay}> - - - - -
-
- {' '} - -
-
-
- - - - {column.map((i, index) => { - return ( - - ) - })} - - - {this.renderTable()} -
{i.name}
- -
-
-
- ) - } -} -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 ( + + {dataTable2.length !== 0 ? dataTable2.map((n) => { + return ( + + + + this.handleEdit(n)}> + + + this.handleMap(n)}> + + + {n.created_at !== null ? moment(n.created_at).format("DD-MM-YYYY HH:mm:ss") : "-"} + {n.join_first_name !== null ? n.join_first_name : "-"} + {n.status_response !== null ? n.status_response : "-"} + + ) + }) : + No Data Available + + } + + ) + } + + 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 ( +
+ + this.toggleMapDialog} + dataMap={this.state.dataMap} + showDialog={showDialog => this.showChildDialog = showDialog} + /> + this.toggleEditDialog} + dataEdit={this.state.dataEdit} + showDialog={showDialog => this.showDialogEdit = showDialog} + /> + + +

{this.props.t('panicButton')}

+
+ + + +
+
+ +
+
+
+ this.handleChangeDay(e)} defaultValue={this.state.currentDay}> + + + + +
+
+ {' '} + +
+
+
+ + + + {column.map((i, index) => { + return ( + + ) + })} + + + {this.renderTable()} +
{i.name}
+ +
+
+
+ ) + } +} +export default withTranslation()(index); diff --git a/src/views/SimproV2/ResourceWorker/DialogForm.js b/src/views/SimproV2/ResourceWorker/DialogForm.js index 0c2ec55..5c4bb67 100644 --- a/src/views/SimproV2/ResourceWorker/DialogForm.js +++ b/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 (
@@ -213,7 +220,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi {/* setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={`Input NIK (KTP)...`} maxLength="16" /> */} - setKtpNumber(e.target.value)} placeholder={t('inputNik')} maxLength="16" /> + setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={t('inputNik')} maxLength="16" /> @@ -246,7 +253,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi - setEmail(e.target.value)} placeholder={t('inputEmail')} /> + setEmail(e.target.value)} placeholder={t('inputEmail')} + onBlur={(e) => { + if (!isValidEmail(e.target.value)) { + alert("Masukkan email yang valid."); + } + }} + /> @@ -327,7 +340,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi - setEmail(e.target.value)} placeholder={`Email...`} /> + setEmail(e.target.value)} placeholder={`Email...`} + onBlur={(e) => { + if (!isValidEmail(e.target.value)) { + alert("Masukkan email yang valid."); + } + }} + /> diff --git a/src/views/SimproV2/Satuan/index.js b/src/views/SimproV2/Satuan/index.js index 39527fe..b864493 100644 --- a/src/views/SimproV2/Satuan/index.js +++ b/src/views/SimproV2/Satuan/index.js @@ -175,7 +175,7 @@ const Satuan = ({ params }) => { if (result && result.data && result.data.code === 200) { getDataSatuan() - NotificationManager.success(`Data project type berhasil ditambah`, 'Success!!'); + NotificationManager.success(`Satuan berhasil ditambah`, 'Success!!'); } else { NotificationManager.error(`${result.data.message}`, 'Failed!!'); } @@ -191,9 +191,9 @@ const Satuan = ({ params }) => { if (result && result.data && result.data.code === 200) { getDataSatuan(); - NotificationManager.success(`Data project type berhasil diedit`, 'Success!!'); + NotificationManager.success(`Satuan berhasil diubah`, 'Success!!'); } else { - NotificationManager.error(`Data project type gagal di edit`, `Failed!!`); + NotificationManager.error(`Satuan gagal diubah`, `Failed!!`); } } @@ -212,11 +212,11 @@ const Satuan = ({ params }) => { getDataSatuan() setIdDelete(0) setAlertDelete(false) - NotificationManager.success(`Data project type berhasil dihapus!`, 'Success!!'); + NotificationManager.success(`Satuan berhasil dihapus!`, 'Success!!'); } else { setIdDelete(0) setAlertDelete(false) - NotificationManager.error(`Data project type gagal dihapus!}`, 'Failed!!'); + NotificationManager.error(`Satuan gagal dihapus!}`, 'Failed!!'); } }