61 changed files with 2065 additions and 3360 deletions
File diff suppressed because it is too large
Load Diff
@ -1,434 +1,387 @@
|
||||
import 'antd/dist/antd.css'; |
||||
import React, { Component } from 'react'; |
||||
import { Button, Form, FormFeedback, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; |
||||
import Select from 'react-select'; |
||||
import axios from 'axios'; |
||||
import { BASE_URL_GEOHR_API2, ROLE_SEARCH, USER_WASPANG, USER_LIST, USER_SEARCH } 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/"; |
||||
const roleName = window.localStorage.getItem('role_name'); |
||||
let countError = 0; |
||||
class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
title: "", |
||||
description: "", |
||||
message: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
errorTitle: "", |
||||
errorMessage: "", |
||||
errorDivision: "", |
||||
errorEmployee: "", |
||||
penerima: "all", |
||||
displayKaryawan: "none", |
||||
displayDivisi: "none", |
||||
listOrganizationSelect: [], |
||||
currentSelectDiv: null, |
||||
dataEmployee: [], |
||||
dataSourceEmployee: [], |
||||
idOrganization: 0, |
||||
targetKeys: [], |
||||
selectedKeys: [], |
||||
allEmployeeId: [], |
||||
idEmployeeDivision: [], |
||||
idOrganization: [], |
||||
disableTransfer: true, |
||||
listCompany: [], |
||||
company_id: this.props.company_id, |
||||
role_name: '' |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
if (this.props.company_id !== null) { |
||||
this.getDataRole(); |
||||
this.getDataUsers(); |
||||
} |
||||
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, |
||||
title: dataEdit.title_notif, |
||||
description: dataEdit.description, |
||||
message: dataEdit.message_notif, |
||||
company_id: dataEdit.company_id |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
id: 0, |
||||
title: "", |
||||
description: "", |
||||
message: "", |
||||
company_id: 0 |
||||
}) |
||||
} |
||||
this.setState({ isParentClick: false }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
|
||||
|
||||
validate = () => { |
||||
let isError = false |
||||
const { title, message, penerima } = this.state |
||||
if (title === "") { |
||||
isError = true |
||||
this.setState({ errorTitle: ERROR_TITLE }) |
||||
} else if (title.length < 3 || title.length > 100) { |
||||
isError = true |
||||
this.setState({ errorTitle: "Title minimum 3-100 karakter!" }) |
||||
} |
||||
|
||||
if (message === "") { |
||||
isError = true |
||||
this.setState({ errorMessage: ERROR_MESSAGE }) |
||||
} else if (message.length < 3 || message.length > 200) { |
||||
isError = true |
||||
this.setState({ errorMessage: "message minimum 3-200 karakter!" }) |
||||
} |
||||
|
||||
if (penerima === "division") { |
||||
if (this.state.idOrganization === 0) { |
||||
this.setState({ errorDivision: "Silahkan pilih divisi penerima!" }) |
||||
} |
||||
} else if (penerima === "karyawan") { |
||||
if (this.state.selectedKeys.length === 0) { |
||||
this.setState({ errorEmployee: "Silahkan pilih karyawan penerima!" }) |
||||
} |
||||
} |
||||
return isError |
||||
} |
||||
handleSave = (param) => { |
||||
let err = this.validate() |
||||
if (!err) { |
||||
const { |
||||
id, |
||||
title, |
||||
description, |
||||
message, |
||||
penerima, |
||||
|
||||
} = this.state |
||||
let { |
||||
company_id |
||||
} = this.state |
||||
let idSend = []; |
||||
let send_to_type = "all"; |
||||
if (penerima === "all") { |
||||
idSend = this.state.allEmployeeId; |
||||
send_to_type = "all"; |
||||
} else if (penerima === "organization") { |
||||
idSend = this.state.idOrganization; |
||||
send_to_type = "roles"; |
||||
} else if (penerima === "karyawan") { |
||||
idSend = this.state.targetKeys; |
||||
send_to_type = "users"; |
||||
} |
||||
|
||||
if (Array.isArray(idSend)) { |
||||
idSend = idSend.map(function (e) { |
||||
return e.toString() |
||||
}); |
||||
} else { |
||||
idSend = idSend; |
||||
} |
||||
if (this.props.role_name !== 'Super Admin') { |
||||
company_id = parseInt(this.props.company_id) |
||||
} |
||||
const data = { |
||||
title, |
||||
description, |
||||
message, |
||||
send_to_type, |
||||
id: idSend, |
||||
company_id: company_id |
||||
} |
||||
if (param === 'registered' || param === 'send') { |
||||
this.props.handleSaveBroadcast(param, data) |
||||
} |
||||
this.setState({ id: 0, idOrganization: 0, currentSelectDiv: null, targetKeys: [], penerima: "all", displayKaryawan: "none", displayDivisi: "none", disableTransfer: true }); |
||||
} |
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.handleSaveBroadcast('cancel', 'none') |
||||
} |
||||
|
||||
handleChangePenerima = type => { |
||||
if (type === "organization") { |
||||
this.setState({ displayDivisi: "block", displayKaryawan: "none", disableTransfer: true, errorDivision: "", targetKeys: [] }) |
||||
} else if (type === "karyawan") { |
||||
this.setState({ displayKaryawan: "block", displayDivisi: "none", disableTransfer: false, errorEmployee: "", idEmployeeDivision: [], currentSelectDiv: null }) |
||||
} else { |
||||
this.setState({ displayKaryawan: "none", displayDivisi: "none", disableTransfer: true, errorDivision: "", errorEmployee: "", targetKeys: [], idEmployeeDivision: [], currentSelectDiv: null }) |
||||
} |
||||
this.setState({ penerima: type }); |
||||
} |
||||
|
||||
handleSelectOrganization = (inputValue, actionMeta) => { |
||||
this.setState({ idOrganization: inputValue.value, currentSelectDiv: { value: inputValue.value, label: inputValue.label }, errorDivision: "" }, () => { |
||||
this.setEmployeeOrganization(); |
||||
}); |
||||
} |
||||
|
||||
setEmployeeOrganization = () => { |
||||
let arrEd = this.state.dataEmployee.data; |
||||
let cek = arrEd.filter(this.filterId) |
||||
|
||||
this.setState({ idEmployeeDivision: cek }) |
||||
} |
||||
|
||||
filterId = (val) => { |
||||
return val.organization_id == this.state.idOrganization |
||||
} |
||||
|
||||
getDataRole = async () => { |
||||
const payload = { |
||||
"paging": { |
||||
"start": 0, |
||||
"length": -1 |
||||
}, |
||||
"columns": [ |
||||
{ |
||||
"name": "company_id", |
||||
"logic_operator": "=", |
||||
"value": this.state.company_id, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
this.setState({ dataDivision: result.data.data }, () => { |
||||
this.setDataOrganization(); |
||||
}) |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
setDataOrganization = () => { |
||||
const { dataDivision } = this.state |
||||
const listOrganization = [] |
||||
dataDivision.map((val, index) => { |
||||
listOrganization.push({ |
||||
value: val.id, |
||||
label: val.name |
||||
}) |
||||
}) |
||||
this.setState({ listOrganizationSelect: listOrganization }) |
||||
} |
||||
|
||||
getDataUsers = async () => { |
||||
const payload = { |
||||
"paging": { |
||||
"start": 0, |
||||
"length": -1 |
||||
}, |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "like", |
||||
"value": "", |
||||
"operator": "AND", |
||||
"table_name": "m_users" |
||||
}, |
||||
{ |
||||
"name": "company_id", |
||||
"logic_operator": "=", |
||||
"value": this.state.company_id, |
||||
"operator": "AND" |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
//TODO should use search instead
|
||||
const result = await axios |
||||
.post(USER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.status == 200) { |
||||
this.setState({ dataEmployee: result.data }, () => { |
||||
this.setDataEmployee(); |
||||
}); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
setDataEmployee = () => { |
||||
const listEmployee = []; |
||||
const allIdEmployee = []; |
||||
this.state.dataEmployee.data.map((val, index) => { |
||||
allIdEmployee.push(val.id); |
||||
listEmployee.push({ |
||||
key: val.id, |
||||
id: val.id, |
||||
title: val.name |
||||
}); |
||||
}) |
||||
|
||||
this.setState({ dataSourceEmployee: listEmployee, allEmployeeId: allIdEmployee }) |
||||
} |
||||
|
||||
handleChangeTransfer = (nextTargetKeys, direction, moveKeys) => { |
||||
this.setState({ targetKeys: nextTargetKeys, errorEmployee: "" }); |
||||
|
||||
}; |
||||
|
||||
handleSelectChangeTransfer = (sourceSelectedKeys, targetSelectedKeys) => { |
||||
this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys], errorEmployee: "" }); |
||||
|
||||
}; |
||||
|
||||
handleSelectCompany = (selectedOption) => { |
||||
const selectedCompanyId = selectedOption.value; |
||||
this.setState({ company_id: selectedCompanyId }, () => { |
||||
this.getDataRole(); |
||||
this.getDataUsers(); |
||||
}); |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const t = this.props |
||||
const { errorTitle, errorMessage } = this.state |
||||
return ( |
||||
<Form> |
||||
{this.props.role_name === 'Super Admin' && ( |
||||
<FormGroup> |
||||
<Label>{this.props.t('company')}</Label> |
||||
<Select |
||||
options={this.props.listCompany.map(company => ({ value: company.id, label: company.company_name }))} |
||||
onChange={this.handleSelectCompany} |
||||
value={this.state.company_id} |
||||
/> |
||||
</FormGroup> |
||||
)} |
||||
<FormGroup> |
||||
<Label>{this.props.t('receiver')}</Label> |
||||
<Input type="select" value={this.state.penerima} onChange={(e) => this.handleChangePenerima(e.target.value)}> |
||||
<option value="all">{this.props.t('all')}</option> |
||||
<option value="organization">{this.props.t('roles')}</option> |
||||
<option value="karyawan">{this.props.t('user')}</option> |
||||
</Input> |
||||
</FormGroup> |
||||
<FormGroup style={{ display: this.state.displayDivisi }}> |
||||
<Label>{this.props.t('roles')}</Label> |
||||
<Select options={this.state.listOrganizationSelect} onChange={this.handleSelectOrganization} value={this.state.currentSelectDiv} /> |
||||
{this.state.errorDivision && <FormFeedback>{this.state.errorDivision}</FormFeedback>} |
||||
</FormGroup> |
||||
<FormGroup style={{ display: this.state.displayKaryawan }}> |
||||
<Label>{this.props.t('user')}</Label> |
||||
{!this.state.disableTransfer && |
||||
<Transfer |
||||
dataSource={this.state.dataSourceEmployee} |
||||
showSearch |
||||
titles={['', 'Terpilih']} |
||||
targetKeys={this.state.targetKeys} |
||||
selectedKeys={this.state.selectedKeys} |
||||
onChange={this.handleChangeTransfer} |
||||
onSelectChange={this.handleSelectChangeTransfer} |
||||
render={item => item.title} |
||||
disabled={this.state.disableTransfer} |
||||
/> |
||||
} |
||||
{this.state.errorEmployee && <FormFeedback>{this.state.errorEmployee}</FormFeedback>} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('title')}</Label> |
||||
<Input invalid={errorTitle} type="text" value={this.state.title} |
||||
onChange={(e) => |
||||
this.setState( |
||||
{ |
||||
errorTitle: e.target.value !== "" ? "" : ERROR_TITLE, |
||||
title: e.target.value |
||||
})} |
||||
placeholder={this.props.t('inputTitle')} /> |
||||
{errorTitle && ( |
||||
<FormFeedback>{errorTitle}</FormFeedback> |
||||
)} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('messageBroadcast')}</Label> |
||||
<Input |
||||
invalid={errorMessage} |
||||
style={{ minHeight: "100px" }} |
||||
type="textarea" |
||||
value={this.state.message} |
||||
onChange={(e) => this.setState({ errorMessage: e.target.value !== "" ? "" : ERROR_MESSAGE, message: e.target.value })} placeholder={this.props.t('inputMsg')} /> |
||||
{errorMessage && ( |
||||
<FormFeedback>{errorMessage}</FormFeedback> |
||||
)} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('broadcastDescription')}</Label> |
||||
<Input style={{ minHeight: "100px" }} type="textarea" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Form > |
||||
) |
||||
} |
||||
handleCloseDialog = () => { |
||||
this.props.closeDialog() |
||||
this.setState({ |
||||
errorTitle: "", |
||||
errorMessage: "", |
||||
errorDivision: "", |
||||
errorEmployee: "" |
||||
}) |
||||
} |
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.handleCloseDialog}>{this.props.t('broadcastDetail')}</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave("send")}>{this.props.t('saveSend')}</Button>{' '} |
||||
<Button color="primary" onClick={() => this.handleSave("registered")}>{this.props.t('save')}</Button>{' '} |
||||
<Button color="secondary" onClick={this.handleCloseDialog}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogForm); |
||||
import 'antd/dist/antd.css'; |
||||
import React, { Component } from 'react'; |
||||
import { Button, Form, FormFeedback, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; |
||||
import Select from 'react-select'; |
||||
import axios from 'axios'; |
||||
import { BASE_URL_GEOHR_API2, ROLE_SEARCH, USER_WASPANG, USER_LIST, USER_SEARCH } 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/"; |
||||
const roleName = window.localStorage.getItem('role_name'); |
||||
let countError = 0; |
||||
class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
title: "", |
||||
description: "", |
||||
message: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
errorTitle: "", |
||||
errorMessage: "", |
||||
errorDivision: "", |
||||
errorEmployee: "", |
||||
penerima: "all", |
||||
displayKaryawan: "none", |
||||
displayDivisi: "none", |
||||
listOrganizationSelect: [], |
||||
currentSelectDiv: null, |
||||
dataEmployee: [], |
||||
dataSourceEmployee: [], |
||||
idOrganization: 0, |
||||
targetKeys: [], |
||||
selectedKeys: [], |
||||
allEmployeeId: [], |
||||
idEmployeeDivision: [], |
||||
idOrganization: [], |
||||
disableTransfer: true, |
||||
role_name: '' |
||||
} |
||||
} |
||||
|
||||
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, |
||||
title: dataEdit.title_notif, |
||||
description: dataEdit.description, |
||||
message: dataEdit.message_notif |
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
id: 0, |
||||
title: "", |
||||
description: "", |
||||
message: "" |
||||
}) |
||||
} |
||||
this.setState({ isParentClick: false }); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick: true }); |
||||
} |
||||
|
||||
|
||||
|
||||
validate = () => { |
||||
let isError = false |
||||
const { title, message, penerima } = this.state |
||||
if (title === "") { |
||||
isError = true |
||||
this.setState({ errorTitle: ERROR_TITLE }) |
||||
} else if (title.length < 3 || title.length > 100) { |
||||
isError = true |
||||
this.setState({ errorTitle: "Title minimum 3-100 karakter!" }) |
||||
} |
||||
|
||||
if (message === "") { |
||||
isError = true |
||||
this.setState({ errorMessage: ERROR_MESSAGE }) |
||||
} else if (message.length < 3 || message.length > 200) { |
||||
isError = true |
||||
this.setState({ errorMessage: "message minimum 3-200 karakter!" }) |
||||
} |
||||
|
||||
if (penerima === "division") { |
||||
if (this.state.idOrganization === 0) { |
||||
this.setState({ errorDivision: "Silahkan pilih divisi penerima!" }) |
||||
} |
||||
} else if (penerima === "karyawan") { |
||||
if (this.state.selectedKeys.length === 0) { |
||||
this.setState({ errorEmployee: "Silahkan pilih karyawan penerima!" }) |
||||
} |
||||
} |
||||
return isError |
||||
} |
||||
handleSave = (param) => { |
||||
let err = this.validate() |
||||
if (!err) { |
||||
const { |
||||
id, |
||||
title, |
||||
description, |
||||
message, |
||||
penerima, |
||||
|
||||
} = this.state |
||||
let idSend = []; |
||||
let send_to_type = "all"; |
||||
if (penerima === "all") { |
||||
idSend = this.state.allEmployeeId; |
||||
send_to_type = "all"; |
||||
} else if (penerima === "organization") { |
||||
idSend = this.state.idOrganization; |
||||
send_to_type = "roles"; |
||||
} else if (penerima === "karyawan") { |
||||
idSend = this.state.targetKeys; |
||||
send_to_type = "users"; |
||||
} |
||||
|
||||
if (Array.isArray(idSend)) { |
||||
idSend = idSend.map(function (e) { |
||||
return e.toString() |
||||
}); |
||||
} else { |
||||
idSend = idSend; |
||||
} |
||||
const data = { |
||||
title, |
||||
description, |
||||
message, |
||||
send_to_type, |
||||
id: idSend |
||||
} |
||||
if (param === 'registered' || param === 'send') { |
||||
this.props.handleSaveBroadcast(param, data) |
||||
} |
||||
this.setState({ id: 0, idOrganization: 0, currentSelectDiv: null, targetKeys: [], penerima: "all", displayKaryawan: "none", displayDivisi: "none", disableTransfer: true }); |
||||
} |
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.handleSaveBroadcast('cancel', 'none') |
||||
} |
||||
|
||||
handleChangePenerima = type => { |
||||
if (type === "organization") { |
||||
this.setState({ displayDivisi: "block", displayKaryawan: "none", disableTransfer: true, errorDivision: "", targetKeys: [] }) |
||||
} else if (type === "karyawan") { |
||||
this.setState({ displayKaryawan: "block", displayDivisi: "none", disableTransfer: false, errorEmployee: "", idEmployeeDivision: [], currentSelectDiv: null }) |
||||
} else { |
||||
this.setState({ displayKaryawan: "none", displayDivisi: "none", disableTransfer: true, errorDivision: "", errorEmployee: "", targetKeys: [], idEmployeeDivision: [], currentSelectDiv: null }) |
||||
} |
||||
this.setState({ penerima: type }); |
||||
} |
||||
|
||||
handleSelectOrganization = (inputValue, actionMeta) => { |
||||
this.setState({ idOrganization: inputValue.value, currentSelectDiv: { value: inputValue.value, label: inputValue.label }, errorDivision: "" }, () => { |
||||
this.setEmployeeOrganization(); |
||||
}); |
||||
} |
||||
|
||||
setEmployeeOrganization = () => { |
||||
let arrEd = this.state.dataEmployee.data; |
||||
let cek = arrEd.filter(this.filterId) |
||||
|
||||
this.setState({ idEmployeeDivision: cek }) |
||||
} |
||||
|
||||
filterId = (val) => { |
||||
return val.organization_id == this.state.idOrganization |
||||
} |
||||
|
||||
getDataRole = async () => { |
||||
const payload = { |
||||
"paging": { |
||||
"start": 0, |
||||
"length": -1 |
||||
}, |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
this.setState({ dataDivision: result.data.data }, () => { |
||||
this.setDataOrganization(); |
||||
}) |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
setDataOrganization = () => { |
||||
const { dataDivision } = this.state |
||||
const listOrganization = [] |
||||
dataDivision.map((val, index) => { |
||||
listOrganization.push({ |
||||
value: val.id, |
||||
label: val.name |
||||
}) |
||||
}) |
||||
this.setState({ listOrganizationSelect: listOrganization }) |
||||
} |
||||
|
||||
getDataUsers = async () => { |
||||
const payload = { |
||||
"paging": { |
||||
"start": 0, |
||||
"length": -1 |
||||
}, |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "like", |
||||
"value": "", |
||||
"operator": "AND", |
||||
"table_name": "m_users" |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
//TODO should use search instead
|
||||
const result = await axios |
||||
.post(USER_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.status == 200) { |
||||
this.setState({ dataEmployee: result.data }, () => { |
||||
this.setDataEmployee(); |
||||
}); |
||||
} else { |
||||
} |
||||
} |
||||
|
||||
setDataEmployee = () => { |
||||
const listEmployee = []; |
||||
const allIdEmployee = []; |
||||
this.state.dataEmployee.data.map((val, index) => { |
||||
allIdEmployee.push(val.id); |
||||
listEmployee.push({ |
||||
key: val.id, |
||||
id: val.id, |
||||
title: val.name |
||||
}); |
||||
}) |
||||
|
||||
this.setState({ dataSourceEmployee: listEmployee, allEmployeeId: allIdEmployee }) |
||||
} |
||||
|
||||
handleChangeTransfer = (nextTargetKeys, direction, moveKeys) => { |
||||
this.setState({ targetKeys: nextTargetKeys, errorEmployee: "" }); |
||||
|
||||
}; |
||||
|
||||
handleSelectChangeTransfer = (sourceSelectedKeys, targetSelectedKeys) => { |
||||
this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys], errorEmployee: "" }); |
||||
|
||||
}; |
||||
|
||||
renderForm = () => { |
||||
const t = this.props |
||||
const { errorTitle, errorMessage } = this.state |
||||
return ( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label>{this.props.t('receiver')}</Label> |
||||
<Input type="select" value={this.state.penerima} onChange={(e) => this.handleChangePenerima(e.target.value)}> |
||||
<option value="all">{this.props.t('all')}</option> |
||||
<option value="organization">{this.props.t('roles')}</option> |
||||
<option value="karyawan">{this.props.t('user')}</option> |
||||
</Input> |
||||
</FormGroup> |
||||
<FormGroup style={{ display: this.state.displayDivisi }}> |
||||
<Label>{this.props.t('roles')}</Label> |
||||
<Select options={this.state.listOrganizationSelect} onChange={this.handleSelectOrganization} value={this.state.currentSelectDiv} /> |
||||
{this.state.errorDivision && <FormFeedback>{this.state.errorDivision}</FormFeedback>} |
||||
</FormGroup> |
||||
<FormGroup style={{ display: this.state.displayKaryawan }}> |
||||
<Label>{this.props.t('user')}</Label> |
||||
{!this.state.disableTransfer && |
||||
<Transfer |
||||
dataSource={this.state.dataSourceEmployee} |
||||
showSearch |
||||
titles={['', 'Terpilih']} |
||||
targetKeys={this.state.targetKeys} |
||||
selectedKeys={this.state.selectedKeys} |
||||
onChange={this.handleChangeTransfer} |
||||
onSelectChange={this.handleSelectChangeTransfer} |
||||
render={item => item.title} |
||||
disabled={this.state.disableTransfer} |
||||
/> |
||||
} |
||||
{this.state.errorEmployee && <FormFeedback>{this.state.errorEmployee}</FormFeedback>} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('title')}</Label> |
||||
<Input invalid={errorTitle} type="text" value={this.state.title} |
||||
onChange={(e) => |
||||
this.setState( |
||||
{ |
||||
errorTitle: e.target.value !== "" ? "" : ERROR_TITLE, |
||||
title: e.target.value |
||||
})} |
||||
placeholder={this.props.t('inputTitle')} /> |
||||
{errorTitle && ( |
||||
<FormFeedback>{errorTitle}</FormFeedback> |
||||
)} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('messageBroadcast')}</Label> |
||||
<Input |
||||
invalid={errorMessage} |
||||
style={{ minHeight: "100px" }} |
||||
type="textarea" |
||||
value={this.state.message} |
||||
onChange={(e) => this.setState({ errorMessage: e.target.value !== "" ? "" : ERROR_MESSAGE, message: e.target.value })} placeholder={this.props.t('inputMsg')} /> |
||||
{errorMessage && ( |
||||
<FormFeedback>{errorMessage}</FormFeedback> |
||||
)} |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>{this.props.t('broadcastDescription')}</Label> |
||||
<Input style={{ minHeight: "100px" }} type="textarea" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Form > |
||||
) |
||||
} |
||||
handleCloseDialog = () => { |
||||
this.props.closeDialog() |
||||
this.setState({ |
||||
errorTitle: "", |
||||
errorMessage: "", |
||||
errorDivision: "", |
||||
errorEmployee: "" |
||||
}) |
||||
} |
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.handleCloseDialog}>{this.props.t('broadcastDetail')}</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave("send")}>{this.props.t('saveSend')}</Button>{' '} |
||||
<Button color="primary" onClick={() => this.handleSave("registered")}>{this.props.t('save')}</Button>{' '} |
||||
<Button color="secondary" onClick={this.handleCloseDialog}>{this.props.t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
||||
export default withTranslation()(DialogForm); |
||||
|
@ -1,132 +1,91 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import InputColor from "./InputColor"; |
||||
import "./styles.css"; |
||||
import "rc-color-picker/assets/index.css"; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import { Select } from 'antd'; |
||||
const { Option } = Select |
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, company_id, listCompany, role_name }) => { |
||||
const [id, setId] = useState(0) |
||||
const [projectType, setProjectType] = useState('') |
||||
const [color, setColor] = useState('') |
||||
const [selectedCompany, setSelectedCompany] = useState(null) |
||||
const { t } = useTranslation(); |
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setProjectType(dataEdit.name) |
||||
setColor(dataEdit.color) |
||||
setSelectedCompany(dataEdit.company_id) |
||||
} else { |
||||
setId(0) |
||||
setColor('') |
||||
setProjectType('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
if (role_name === 'Super Admin') { |
||||
company_id = selectedCompany |
||||
} |
||||
data = { |
||||
name: projectType, |
||||
color, |
||||
company_id: company_id |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
if (role_name === 'Super Admin') { |
||||
company_id = selectedCompany |
||||
} |
||||
data = { |
||||
id, |
||||
name: projectType, |
||||
color, |
||||
company_id: company_id |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
} |
||||
|
||||
const onChangeCompany = (val) => { |
||||
setSelectedCompany(val); |
||||
}; |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('phase')}</Label> |
||||
<Input type="text" value={projectType} onChange={(e) => setProjectType(e.target.value)} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('color')}</Label> |
||||
<InputColor value={color} color={color} onChange={(e) => setColor(e.color)} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
{role_name === 'Super Admin' && |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize"> |
||||
{t('company')}<span style={{ color: "red" }}>*</span> |
||||
</Label> |
||||
<Select |
||||
showSearch |
||||
filterOption={(inputValue, option) => |
||||
option.children.toLowerCase().includes(inputValue.toLowerCase()) |
||||
} |
||||
value={selectedCompany} |
||||
defaultValue={selectedCompany} |
||||
onChange={onChangeCompany} |
||||
style={{ width: "100%" }} |
||||
> |
||||
{listCompany.map((res) => ( |
||||
<Option key={res.id} value={res.id}> |
||||
{res.company_name} |
||||
</Option> |
||||
))} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
} |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} data</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
export default DialogForm; |
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import InputColor from "./InputColor"; |
||||
import "./styles.css"; |
||||
import "rc-color-picker/assets/index.css"; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import { Select } from 'antd'; |
||||
const { Option } = Select |
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, role_name }) => { |
||||
const [id, setId] = useState(0) |
||||
const [projectType, setProjectType] = useState('') |
||||
const [color, setColor] = useState('') |
||||
const { t } = useTranslation(); |
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setProjectType(dataEdit.name) |
||||
setColor(dataEdit.color) |
||||
} else { |
||||
setId(0) |
||||
setColor('') |
||||
setProjectType('') |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: projectType, |
||||
color |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name: projectType, |
||||
color |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('phase')}</Label> |
||||
<Input type="text" value={projectType} onChange={(e) => setProjectType(e.target.value)} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('color')}</Label> |
||||
<InputColor value={color} color={color} onChange={(e) => setColor(e.color)} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} data</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
export default DialogForm; |
||||
|
@ -1,140 +1,97 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import { Select } from 'antd'; |
||||
const { Option } = Select; |
||||
|
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, company_id, listCompany, role_name }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [description, setDescription] = useState('') |
||||
const [selectedCompany, setSelectedCompany] = useState(null) |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setDescription(dataEdit.description) |
||||
setName(dataEdit.name) |
||||
setSelectedCompany(dataEdit.company_id); |
||||
|
||||
} else { |
||||
handleClearData() |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (role_name === 'Super Admin') { |
||||
company_id = selectedCompany |
||||
} |
||||
|
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: name, |
||||
description: description, |
||||
company_id: parseInt(company_id), |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
if (role_name === 'Super Admin') { |
||||
company_id = selectedCompany |
||||
} |
||||
data = { |
||||
id, |
||||
name: name, |
||||
description: description, |
||||
company_id: company_id, |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
handleClearData() |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
handleClearData() |
||||
} |
||||
|
||||
const handleClearData = () => { |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
setSelectedCompany(null) |
||||
} |
||||
|
||||
const onChangeCompany = (val) => { |
||||
setSelectedCompany(val); |
||||
}; |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')}</Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('description')}</Label> |
||||
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
{role_name === 'Super Admin' && |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize"> |
||||
{t('company')}<span style={{ color: "red" }}>*</span> |
||||
</Label> |
||||
<Select |
||||
showSearch |
||||
filterOption={(inputValue, option) => |
||||
option.children.toLowerCase().includes(inputValue.toLowerCase()) |
||||
} |
||||
value={selectedCompany} |
||||
defaultValue={selectedCompany} |
||||
onChange={onChangeCompany} |
||||
style={{ width: "100%" }} |
||||
> |
||||
{listCompany.map((res) => ( |
||||
<Option key={res.id} value={res.id}> |
||||
{res.company_name} |
||||
</Option> |
||||
))} |
||||
</Select> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
} |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Checlist K3</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
import React, { useEffect, useState } from 'react' |
||||
import { |
||||
Modal, ModalHeader, ModalBody, ModalFooter, |
||||
Button, Form, FormGroup, Label, Input, Col, Row |
||||
} from 'reactstrap'; |
||||
import 'antd/dist/antd.css'; |
||||
import { useTranslation } from 'react-i18next'; |
||||
import { Select } from 'antd'; |
||||
const { Option } = Select; |
||||
|
||||
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, role_name }) => { |
||||
const [id, setId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [description, setDescription] = useState('') |
||||
const { t } = useTranslation() |
||||
|
||||
useEffect(() => { |
||||
if (typeDialog === "Edit") { |
||||
setId(dataEdit.id) |
||||
setDescription(dataEdit.description) |
||||
setName(dataEdit.name) |
||||
|
||||
} else { |
||||
handleClearData() |
||||
} |
||||
}, [dataEdit, openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if (typeDialog === "Save") { |
||||
data = { |
||||
name: name, |
||||
description: description |
||||
} |
||||
closeDialog('save', data); |
||||
} else { |
||||
data = { |
||||
id, |
||||
name: name, |
||||
description: description |
||||
} |
||||
closeDialog('edit', data); |
||||
} |
||||
handleClearData() |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
handleClearData() |
||||
} |
||||
|
||||
const handleClearData = () => { |
||||
setId(0) |
||||
setName('') |
||||
setDescription('') |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('name')}</Label> |
||||
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label className="capitalize">{t('description')}</Label> |
||||
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Checlist K3</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
||||
|
@ -1,357 +1,355 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import { DownloadOutlined } from '@ant-design/icons'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import * as XLSX from 'xlsx'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Table, Button, Tooltip } from 'antd'; |
||||
import { |
||||
BASE_SIMPRO, PROYEK_ADD, PROYEK_SEARCH, PROYEK_EDIT, PROYEK_DELETE, |
||||
USER_ADD, USER_SEARCH, USER_EDIT, USER_DELETE, |
||||
USERROLE_SEARCH, ROLE_SEARCH |
||||
} from '../../../const/ApiConst'; |
||||
import moment from 'moment' |
||||
|
||||
const url = ""; |
||||
const proyek_id = localStorage.getItem('proyek_id'); |
||||
const role_id = localStorage.getItem('role_id'); |
||||
const format = "DD-MM-YYYY"; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const PlanningHarian = ({ params }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const pageName = params.name; |
||||
const [search, setSearch] = useState('') |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [roleList, setRoleList] = useState([]) |
||||
|
||||
useEffect(() => { |
||||
getDataUser() |
||||
getRoleList() |
||||
}, []) |
||||
|
||||
const getRoleList = async () => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setRoleList(result.data.data); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataUser = 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_roles", |
||||
"column_join": "role_id", |
||||
"column_results": [ |
||||
"name", |
||||
"description" |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(USER_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 }, |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
if (parseInt(role_id) !== 1) { |
||||
payload["columns"] = [ |
||||
{ "name": "id", "logic_operator": "=", "value": proyek_id, "operator": "AND" } |
||||
] |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PROYEK_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((n, index) => { |
||||
let dataRow = { |
||||
"Nama Proyek": n.nama, |
||||
"Biaya": n.biaya, |
||||
"Color Progress": n.color_progress, |
||||
"Jumlah Pekerja": n.jumlah_pekerja, |
||||
"Tanggal Mulai": n.mulai_proyek ? moment(n.mulai_proyek).format(format) : "-", |
||||
"Tanggal Selesai": n.akhir_proyek ? moment(n.akhir_proyek).format(format) : "-", |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveUser(data); |
||||
} else if (type === "edit") { |
||||
editUser(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveUser = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(USER_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editUser = async (data) => { |
||||
|
||||
let urlEdit = USER_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) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data resource gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = USER_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data user gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const RenderTable = useMemo(() => { |
||||
const columns = [ |
||||
|
||||
{ title: 'Subproject Name', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Activity', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Target', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Unit', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Resource Name', dataIndex: 'name', key: 'name' }, |
||||
{ |
||||
title: 'Planning Start Date', |
||||
dataIndex: 'name', |
||||
key: 'name', |
||||
render: (text, record) => <>{text}</>, |
||||
}, |
||||
{ |
||||
title: 'Planning End Date', |
||||
dataIndex: 'name', |
||||
key: 'name', |
||||
render: (text, record) => <>{text}</>, |
||||
}, |
||||
{ title: 'Address', dataIndex: 'name', key: 'name' }, |
||||
{ |
||||
title: 'Action', |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
{/* <Tooltip title="Tambah Sub"> |
||||
<Button size="small" type="link" style={{color:'green'}} onClick={() => handleOpenDialogSub('Save', text)}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> */} |
||||
<Tooltip title="Edit"> |
||||
<Button size="small" type="link" style={{ color: 'orange' }} onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Hapus"> |
||||
<Button size="small" type="link" style={{ color: 'red' }} onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={`Are you sure?`} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
Delete this data |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
roleList={roleList} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search...`} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title="Add Resource"> |
||||
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Export Excel"> |
||||
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
|
||||
{RenderTable} |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default PlanningHarian; |
||||
import React, { useState, useEffect, useMemo } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap'; |
||||
import { DownloadOutlined } from '@ant-design/icons'; |
||||
import axios from "../../../const/interceptorApi" |
||||
import * as XLSX from 'xlsx'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Table, Button, Tooltip } from 'antd'; |
||||
import { |
||||
PROYEK_SEARCH,USER_ADD, USER_SEARCH, USER_EDIT, USER_DELETE,ROLE_SEARCH |
||||
} from '../../../const/ApiConst'; |
||||
import moment from 'moment' |
||||
|
||||
const url = ""; |
||||
const proyek_id = localStorage.getItem('proyek_id'); |
||||
const role_id = localStorage.getItem('role_id'); |
||||
const format = "DD-MM-YYYY"; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers: |
||||
{ |
||||
Authorization: `Bearer ${token}`, |
||||
"Content-type": `application/json` |
||||
} |
||||
}; |
||||
|
||||
const PlanningHarian = ({ params }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const pageName = params.name; |
||||
const [search, setSearch] = useState('') |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [roleList, setRoleList] = useState([]) |
||||
|
||||
useEffect(() => { |
||||
getDataUser() |
||||
getRoleList() |
||||
}, []) |
||||
|
||||
const getRoleList = async () => { |
||||
const formData = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
setRoleList(result.data.data); |
||||
} else { |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const getDataUser = 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_roles", |
||||
"column_join": "role_id", |
||||
"column_results": [ |
||||
"name", |
||||
"description" |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"id" |
||||
], |
||||
"ascending": false |
||||
} |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(USER_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 }, |
||||
"joins": [], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
if (parseInt(role_id) !== 1) { |
||||
payload["columns"] = [ |
||||
{ "name": "id", "logic_operator": "=", "value": proyek_id, "operator": "AND" } |
||||
] |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PROYEK_SEARCH, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((n, index) => { |
||||
let dataRow = { |
||||
"Nama Proyek": n.nama, |
||||
"Biaya": n.biaya, |
||||
"Color Progress": n.color_progress, |
||||
"Jumlah Pekerja": n.jumlah_pekerja, |
||||
"Tanggal Mulai": n.mulai_proyek ? moment(n.mulai_proyek).format(format) : "-", |
||||
"Tanggal Selesai": n.akhir_proyek ? moment(n.akhir_proyek).format(format) : "-", |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleEdit = (data) => { |
||||
setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveUser(data); |
||||
} else if (type === "edit") { |
||||
editUser(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const saveUser = async (data) => { |
||||
const formData = data |
||||
const result = await axios.post(USER_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const editUser = async (data) => { |
||||
|
||||
let urlEdit = USER_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) { |
||||
getDataUser(); |
||||
NotificationManager.success(`Data resource berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`Data resource gagal di edit`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = USER_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data user gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const RenderTable = useMemo(() => { |
||||
const columns = [ |
||||
|
||||
{ title: 'Subproject Name', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Activity', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Target', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Unit', dataIndex: 'name', key: 'name' }, |
||||
{ title: 'Resource Name', dataIndex: 'name', key: 'name' }, |
||||
{ |
||||
title: 'Planning Start Date', |
||||
dataIndex: 'name', |
||||
key: 'name', |
||||
render: (text, record) => <>{text}</>, |
||||
}, |
||||
{ |
||||
title: 'Planning End Date', |
||||
dataIndex: 'name', |
||||
key: 'name', |
||||
render: (text, record) => <>{text}</>, |
||||
}, |
||||
{ title: 'Address', dataIndex: 'name', key: 'name' }, |
||||
{ |
||||
title: 'Action', |
||||
dataIndex: '', |
||||
key: 'x', |
||||
render: (text, record) => <> |
||||
{/* <Tooltip title="Tambah Sub"> |
||||
<Button size="small" type="link" style={{color:'green'}} onClick={() => handleOpenDialogSub('Save', text)}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> */} |
||||
<Tooltip title="Edit"> |
||||
<Button size="small" type="link" style={{ color: 'orange' }} onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Hapus"> |
||||
<Button size="small" type="link" style={{ color: 'red' }} onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button> |
||||
</Tooltip> |
||||
</>, |
||||
}, |
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={dataTable} |
||||
/> |
||||
) |
||||
}, [dataTable]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={`Are you sure?`} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
Delete this data |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
roleList={roleList} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4 className="capitalize">{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search...`} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title="Add Resource"> |
||||
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Export Excel"> |
||||
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
|
||||
{RenderTable} |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default PlanningHarian; |
||||
|
@ -1,243 +1,243 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react'; |
||||
import Timeline from 'react-calendar-timeline' |
||||
import 'react-calendar-timeline/lib/Timeline.css' |
||||
import moment from 'moment'; |
||||
import { BASE_SIMPRO, PROYEK_ADD, PROYEK_SEARCH_DETAIL, PROYEK_EDIT, PROYEK_DELETE } from '../../const/ApiConst'; |
||||
import axios from 'axios'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Button } from 'antd'; |
||||
import { |
||||
Container, Col, Row, UncontrolledTooltip, |
||||
Card, |
||||
CardBody, |
||||
CardHeader, |
||||
Table, |
||||
Modal, ModalHeader, ModalBody, ModalFooter |
||||
} from 'reactstrap'; |
||||
import GanttFull from './GanttDhtmlx2'; |
||||
import DialogForm from '../Master/Proyek/DialogForm'; |
||||
import DialogFormSub from '../Master/Proyek/DialogFormSub'; |
||||
import Iframe from "@nicholasadamou/react-iframe"; |
||||
|
||||
const GanttTimeLine = () => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const [dataGantt, setDataGantt] = useState([]); |
||||
const [prevProyekId, setPrevProyekId] = useState(0); |
||||
const [dataGroupGantt, setDataGroupGantt] = useState([]); |
||||
const [maxDateGantt, setMaxDateGantt] = useState(null); |
||||
const [minDateGantt, setMinDateGantt] = useState(null); |
||||
const [dataAllTimeLine, setDataAllTimeLine] = useState([]); |
||||
const [prevDataAllTimeLine, setPrevDataAllTimeLine] = useState(null); |
||||
|
||||
const [idTask, setidTask] = useState(0); |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [search, setSearch] = useState('') |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [openDialogSub, setOpenDialogSub] = useState(false) |
||||
const [typeDialog, setTypeDialog] = useState('Save'); |
||||
const [typeDialogSub, setTypeDialogSub] = useState('Save') |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataEditSub, setDataEditSub] = useState([]) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [idSubtask, setIdSubtask] = useState(0); |
||||
|
||||
const handleMappingDataGantt = (data) => { |
||||
const minDates = data.map(res => moment(res.mulai_proyek)), |
||||
minDate = moment.min(minDates) |
||||
const maxDates = data.map(res => moment(res.akhir_proyek)), |
||||
maxDate = moment.max(maxDates) |
||||
|
||||
let groups = [] |
||||
let items = [] |
||||
data.map((res, idx) => { |
||||
let group = { |
||||
id: res.id, |
||||
title: res.nama, |
||||
stackItems: true, |
||||
height: 50 |
||||
} |
||||
let item = { |
||||
id: res.id, |
||||
group: res.id, |
||||
title: res.pic, |
||||
start_time: moment(res.mulai_proyek), |
||||
end_time: moment(res.akhir_proyek), |
||||
} |
||||
groups.push(group) |
||||
items.push(item) |
||||
}) |
||||
setDataGantt(items) |
||||
setDataGroupGantt(groups) |
||||
setMaxDateGantt(maxDate) |
||||
setMinDateGantt(minDate) |
||||
} |
||||
|
||||
const handleGetDataProyek = async () => { |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"joins": [ |
||||
{ "name": "subproyeks.m_proyek", "column_join": "proyek_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual", "lat", "lon", "buffer_radius", "geom"] }, |
||||
{ "name": "subproyeks.m_subproyek", "column_join": "parent_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual", "lat", "lon", "buffer_radius", "geom"] } |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PROYEK_SEARCH_DETAIL, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
const { data } = result.data |
||||
setDataAllTimeLine(data) |
||||
setPrevDataAllTimeLine(data) |
||||
handleMappingDataGantt(data) |
||||
|
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
useEffect(() => { |
||||
|
||||
handleGetDataProyek() |
||||
}, []); |
||||
|
||||
const handleClickGroupGantt = param => { |
||||
const row = prevDataAllTimeLine.filter(res => res.id === param) |
||||
if (row.length > 0) { |
||||
const { subproyeks, proyek_id, parent_id } = row[0] |
||||
setPrevProyekId(parent_id || proyek_id) |
||||
handleMappingDataGantt(subproyeks) |
||||
setDataAllTimeLine(subproyeks) |
||||
} |
||||
|
||||
} |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleOpenDialogSub = (type, param) => { |
||||
const { id, parent_id, proyek_id, parent } = param |
||||
const idParent = parent == 0 ? 0 : parent == proyek_id ? id : parent_id |
||||
setidTask(proyek_id) |
||||
setIdSubtask(idParent) |
||||
setOpenDialogSub(true) |
||||
setTypeDialogSub(type) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveProyek(data); |
||||
} |
||||
|
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const handleCloseDialogSub = (type, data) => { |
||||
setDataEditSub([]) |
||||
setOpenDialogSub(false) |
||||
if (type !== "cancel") { |
||||
handleGetDataProyek() |
||||
} |
||||
|
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const toggleAddDialogSub = () => { |
||||
setOpenDialogSub(!openDialogSub) |
||||
} |
||||
|
||||
const saveProyek = async (data) => { |
||||
const formData = data |
||||
|
||||
const result = await axios.post(PROYEK_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
handleGetDataProyek() |
||||
NotificationManager.success(`Data proyek berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
const RenderGantt = useMemo(() => ( |
||||
<GanttFull |
||||
handleOpenDialogSub={handleOpenDialogSub} |
||||
data={dataAllTimeLine} |
||||
startDate={minDateGantt ? minDateGantt.format("YYYY-MM-DD HH:mm:ss") : moment().add(-40, 'days').format("YYYY-MM-DD HH:mm:ss")} |
||||
endDate={maxDateGantt ? maxDateGantt.format("YYYY-MM-DD HH:mm:ss") : moment().add(40, 'days').format("YYYY-MM-DD HH:mm:ss")} |
||||
/> |
||||
), [dataAllTimeLine, maxDateGantt, minDateGantt]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
{/* time line gantt */} |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataParent={allDataMenu} |
||||
/> |
||||
<DialogFormSub |
||||
openDialog={openDialogSub} |
||||
closeDialog={handleCloseDialogSub} |
||||
toggleDialog={() => toggleAddDialogSub} |
||||
typeDialog={typeDialogSub} |
||||
dataEdit={dataEditSub} |
||||
idTask={idTask} |
||||
idSubtask={idSubtask} |
||||
/> |
||||
{/* <Row> |
||||
<Col md={6} /> |
||||
<Col md={6}> |
||||
<Button style={{ float: 'right' }} onClick={() => handleOpenDialog('Save')} type="primary">Add Proyek</Button> |
||||
</Col> |
||||
</Row> */} |
||||
{/* {RenderGantt} */} |
||||
<Iframe |
||||
src="http://siopas.co.id/simpro-gantt/gantt.html" |
||||
headers={{ |
||||
}} |
||||
style={{ |
||||
width: '100%', |
||||
height: '75vh', |
||||
}} |
||||
scrolling="no" |
||||
frameBorder="0" |
||||
/> |
||||
|
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default GanttTimeLine; |
||||
import React, { useEffect, useMemo, useState } from 'react'; |
||||
import Timeline from 'react-calendar-timeline' |
||||
import 'react-calendar-timeline/lib/Timeline.css' |
||||
import moment from 'moment'; |
||||
import { BASE_SIMPRO, PROYEK_ADD, PROYEK_SEARCH_DETAIL } from '../../const/ApiConst'; |
||||
import axios from 'axios'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Button } from 'antd'; |
||||
import { |
||||
Container, Col, Row, UncontrolledTooltip, |
||||
Card, |
||||
CardBody, |
||||
CardHeader, |
||||
Table, |
||||
Modal, ModalHeader, ModalBody, ModalFooter |
||||
} from 'reactstrap'; |
||||
import GanttFull from './GanttDhtmlx2'; |
||||
import DialogForm from '../Master/Proyek/DialogForm'; |
||||
import DialogFormSub from '../Master/Proyek/DialogFormSub'; |
||||
import Iframe from "@nicholasadamou/react-iframe"; |
||||
|
||||
const GanttTimeLine = () => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const [dataGantt, setDataGantt] = useState([]); |
||||
const [prevProyekId, setPrevProyekId] = useState(0); |
||||
const [dataGroupGantt, setDataGroupGantt] = useState([]); |
||||
const [maxDateGantt, setMaxDateGantt] = useState(null); |
||||
const [minDateGantt, setMinDateGantt] = useState(null); |
||||
const [dataAllTimeLine, setDataAllTimeLine] = useState([]); |
||||
const [prevDataAllTimeLine, setPrevDataAllTimeLine] = useState(null); |
||||
|
||||
const [idTask, setidTask] = useState(0); |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [search, setSearch] = useState('') |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [openDialogSub, setOpenDialogSub] = useState(false) |
||||
const [typeDialog, setTypeDialog] = useState('Save'); |
||||
const [typeDialogSub, setTypeDialogSub] = useState('Save') |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [dataEditSub, setDataEditSub] = useState([]) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [allDataMenu, setAllDataMenu] = useState([]) |
||||
const [idSubtask, setIdSubtask] = useState(0); |
||||
|
||||
const handleMappingDataGantt = (data) => { |
||||
const minDates = data.map(res => moment(res.mulai_proyek)), |
||||
minDate = moment.min(minDates) |
||||
const maxDates = data.map(res => moment(res.akhir_proyek)), |
||||
maxDate = moment.max(maxDates) |
||||
|
||||
let groups = [] |
||||
let items = [] |
||||
data.map((res, idx) => { |
||||
let group = { |
||||
id: res.id, |
||||
title: res.nama, |
||||
stackItems: true, |
||||
height: 50 |
||||
} |
||||
let item = { |
||||
id: res.id, |
||||
group: res.id, |
||||
title: res.pic, |
||||
start_time: moment(res.mulai_proyek), |
||||
end_time: moment(res.akhir_proyek), |
||||
} |
||||
groups.push(group) |
||||
items.push(item) |
||||
}) |
||||
setDataGantt(items) |
||||
setDataGroupGantt(groups) |
||||
setMaxDateGantt(maxDate) |
||||
setMinDateGantt(minDate) |
||||
} |
||||
|
||||
const handleGetDataProyek = async () => { |
||||
|
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"joins": [ |
||||
{ "name": "subproyeks.m_proyek", "column_join": "proyek_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual", "lat", "lon", "buffer_radius", "geom"] }, |
||||
{ "name": "subproyeks.m_subproyek", "column_join": "parent_id", "column_results": ["nama", "biaya", "color_progress", "jumlah_pekerja", "pic", "mulai_proyek", "akhir_proyek", "biaya_actual", "persentase_progress_plan", "persentase_progress_actual", "lat", "lon", "buffer_radius", "geom"] } |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PROYEK_SEARCH_DETAIL, payload, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if (result && result.data && result.data.code == 200) { |
||||
const { data } = result.data |
||||
setDataAllTimeLine(data) |
||||
setPrevDataAllTimeLine(data) |
||||
handleMappingDataGantt(data) |
||||
|
||||
} else { |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
useEffect(() => { |
||||
|
||||
handleGetDataProyek() |
||||
}, []); |
||||
|
||||
const handleClickGroupGantt = param => { |
||||
const row = prevDataAllTimeLine.filter(res => res.id === param) |
||||
if (row.length > 0) { |
||||
const { subproyeks, proyek_id, parent_id } = row[0] |
||||
setPrevProyekId(parent_id || proyek_id) |
||||
handleMappingDataGantt(subproyeks) |
||||
setDataAllTimeLine(subproyeks) |
||||
} |
||||
|
||||
} |
||||
|
||||
const handleOpenDialog = (type) => { |
||||
setOpenDialog(true) |
||||
setTypeDialog(type) |
||||
} |
||||
|
||||
const handleOpenDialogSub = (type, param) => { |
||||
const { id, parent_id, proyek_id, parent } = param |
||||
const idParent = parent == 0 ? 0 : parent == proyek_id ? id : parent_id |
||||
setidTask(proyek_id) |
||||
setIdSubtask(idParent) |
||||
setOpenDialogSub(true) |
||||
setTypeDialogSub(type) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveProyek(data); |
||||
} |
||||
|
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const handleCloseDialogSub = (type, data) => { |
||||
setDataEditSub([]) |
||||
setOpenDialogSub(false) |
||||
if (type !== "cancel") { |
||||
handleGetDataProyek() |
||||
} |
||||
|
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const toggleAddDialogSub = () => { |
||||
setOpenDialogSub(!openDialogSub) |
||||
} |
||||
|
||||
const saveProyek = async (data) => { |
||||
const formData = data |
||||
|
||||
const result = await axios.post(PROYEK_ADD, formData, HEADER) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
handleGetDataProyek() |
||||
NotificationManager.success(`Data proyek berhasil ditambah`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
|
||||
} |
||||
|
||||
const RenderGantt = useMemo(() => ( |
||||
<GanttFull |
||||
handleOpenDialogSub={handleOpenDialogSub} |
||||
data={dataAllTimeLine} |
||||
startDate={minDateGantt ? minDateGantt.format("YYYY-MM-DD HH:mm:ss") : moment().add(-40, 'days').format("YYYY-MM-DD HH:mm:ss")} |
||||
endDate={maxDateGantt ? maxDateGantt.format("YYYY-MM-DD HH:mm:ss") : moment().add(40, 'days').format("YYYY-MM-DD HH:mm:ss")} |
||||
/> |
||||
), [dataAllTimeLine, maxDateGantt, minDateGantt]) |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
{/* time line gantt */} |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataParent={allDataMenu} |
||||
/> |
||||
<DialogFormSub |
||||
openDialog={openDialogSub} |
||||
closeDialog={handleCloseDialogSub} |
||||
toggleDialog={() => toggleAddDialogSub} |
||||
typeDialog={typeDialogSub} |
||||
dataEdit={dataEditSub} |
||||
idTask={idTask} |
||||
idSubtask={idSubtask} |
||||
/> |
||||
{/* <Row> |
||||
<Col md={6} /> |
||||
<Col md={6}> |
||||
<Button style={{ float: 'right' }} onClick={() => handleOpenDialog('Save')} type="primary">Add Proyek</Button> |
||||
</Col> |
||||
</Row> */} |
||||
{/* {RenderGantt} */} |
||||
<Iframe |
||||
src="http://siopas.co.id/simpro-gantt/gantt.html" |
||||
headers={{ |
||||
}} |
||||
style={{ |
||||
width: '100%', |
||||
height: '75vh', |
||||
}} |
||||
scrolling="no" |
||||
frameBorder="0" |
||||
/> |
||||
|
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default GanttTimeLine; |
||||
|
Loading…
Reference in new issue