Commit 4cff47ae authored by ardiansyah's avatar ardiansyah

Merge branch 'ENV-DEV' into 'ENV-DEPLOYMENT'

Env dev

See merge request !2386
parents b2c9629a 25e3c70f
...@@ -87,6 +87,16 @@ const create = (type = "") => { ...@@ -87,6 +87,16 @@ const create = (type = "") => {
// console.tron.log(url) // console.tron.log(url)
}) })
api.addResponseTransform(response => {
const msg = response.data?.message || ""
if (msg.includes("Someone Logged In") || msg.includes("Token Expired")) {
localStorage.removeItem(Constant.TOKEN)
window.location.reload()
return
}
})
// ------ // ------
// STEP 2 // STEP 2
// ------ // ------
...@@ -155,6 +165,7 @@ const create = (type = "") => { ...@@ -155,6 +165,7 @@ const create = (type = "") => {
const getApprovedByAM = () => api.get('approval_matrix/get_all_approver') const getApprovedByAM = () => api.get('approval_matrix/get_all_approver')
const getTypeAM = () => api.get('approval_type/get_all_approval_type') const getTypeAM = () => api.get('approval_type/get_all_approval_type')
const getOperatorAM = () => api.get('operator_type/get_all_operator_type') const getOperatorAM = () => api.get('operator_type/get_all_operator_type')
const getMasterReportType = () => api.get('masterreporttype/get_all_master_report_type')
const getDetailAM = (id) => api.get(`approval_matrix/get_approval_matrix_by_id/${id}`) const getDetailAM = (id) => api.get(`approval_matrix/get_approval_matrix_by_id/${id}`)
const searchAM = (body) => api.post('/approval_matrix/search_approval_matrix', body) const searchAM = (body) => api.post('/approval_matrix/search_approval_matrix', body)
const createAM = (body) => api.post('/approval_matrix/create_approval_matrix', body) const createAM = (body) => api.post('/approval_matrix/create_approval_matrix', body)
...@@ -623,6 +634,7 @@ const create = (type = "") => { ...@@ -623,6 +634,7 @@ const create = (type = "") => {
getApprovedByAM, getApprovedByAM,
getTypeAM, getTypeAM,
getOperatorAM, getOperatorAM,
getMasterReportType,
getDetailAM, getDetailAM,
searchAM, searchAM,
createAM, createAM,
......
...@@ -8,6 +8,8 @@ import localeID from "date-fns/locale/id" ...@@ -8,6 +8,8 @@ import localeID from "date-fns/locale/id"
import api from "../../api"; import api from "../../api";
import Images from '../../assets/Images'; import Images from '../../assets/Images';
import Constant from '../../library/Constant'; import Constant from '../../library/Constant';
import AutocompleteField from '../../library/AutocompleteField';
import { fetchMasterReportType } from '../../utils/services';
export default class CreateApprovalMatrix extends Component { export default class CreateApprovalMatrix extends Component {
constructor(props) { constructor(props) {
...@@ -36,7 +38,12 @@ export default class CreateApprovalMatrix extends Component { ...@@ -36,7 +38,12 @@ export default class CreateApprovalMatrix extends Component {
errorStartDate: false, errorStartDate: false,
errorEndDate: false, errorEndDate: false,
msgErrorStartDate: "", msgErrorStartDate: "",
msgErrorEndDate: "" msgErrorEndDate: "",
master_report_type_id: null,
listMasterReportType: [],
errorMasterReportTypeId: false,
msgErrMasterReportTypeId: '',
} }
} }
...@@ -44,6 +51,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -44,6 +51,7 @@ export default class CreateApprovalMatrix extends Component {
this.getUserData() this.getUserData()
this.getTypeData() this.getTypeData()
this.getOperatorData() this.getOperatorData()
this.getMasterBudgetType()
let date = format(new Date, 'yyyy-MM-dd') let date = format(new Date, 'yyyy-MM-dd')
this.setState({ this.setState({
startDate: date, startDate: date,
...@@ -51,23 +59,37 @@ export default class CreateApprovalMatrix extends Component { ...@@ -51,23 +59,37 @@ export default class CreateApprovalMatrix extends Component {
}) })
} }
getMasterBudgetType = async () => {
const { data } = await fetchMasterReportType();
if (data) {
const list = data.map((item) => ({
id: item.master_report_type_id,
name: item.master_report_type_name
}));
this.setState({ listMasterReportType: list });
} else {
this.setState({ listMasterReportType: [] });
}
}
getUserData() { getUserData() {
api.create().getApprovedByAM().then((response) => { api.create().getApprovedByAM().then((response) => {
if(response.data) { if (response.data) {
if (response.ok) { if (response.ok) {
if (response.data.status == 'success') { if (response.data.status == 'success') {
let data = response.data.data let data = response.data.data
let userData = data.map((item) => { let userData = data.map((item) => {
return { return {
user_id: item.user_id, user_id: item.user_id,
fullname: item.fullname == null? "(NO_NAME)" : item.fullname fullname: item.fullname == null ? "(NO_NAME)" : item.fullname
} }
}) })
let defaultProps = { let defaultProps = {
options: userData, options: userData,
getOptionLabel: (option) => option.fullname, getOptionLabel: (option) => option.fullname,
}; };
this.setState({ approvedBy: defaultProps, userData: response.data.data}) this.setState({ approvedBy: defaultProps, userData: response.data.data })
} else { } else {
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }, () => { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }, () => {
...@@ -104,7 +126,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -104,7 +126,7 @@ export default class CreateApprovalMatrix extends Component {
let typeProps = { let typeProps = {
options: typeData, options: typeData,
getOptionLabel: (option) => option.approval_type_name, getOptionLabel: (option) => option.approval_type_name,
}; };
this.setState({ types: typeProps, typeData: response.data.data }) this.setState({ types: typeProps, typeData: response.data.data })
} else { } else {
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -142,7 +164,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -142,7 +164,7 @@ export default class CreateApprovalMatrix extends Component {
let operatorProps = { let operatorProps = {
options: operatorData, options: operatorData,
getOptionLabel: (option) => option.operator_type_name, getOptionLabel: (option) => option.operator_type_name,
}; };
this.setState({ operators: operatorProps, operatorData: response.data.data }) this.setState({ operators: operatorProps, operatorData: response.data.data })
} else { } else {
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -174,7 +196,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -174,7 +196,7 @@ export default class CreateApprovalMatrix extends Component {
// console.log(this.state.startDate) // console.log(this.state.startDate)
}) })
} else if (isDate && type == 'end_date') { } else if (isDate && type == 'end_date') {
this.setState({ endDate: format(e, 'yyyy-MM-dd')}, () => { this.setState({ endDate: format(e, 'yyyy-MM-dd') }, () => {
this.clearError() this.clearError()
// console.log(this.state.endDate) // console.log(this.state.endDate)
}) })
...@@ -184,6 +206,15 @@ export default class CreateApprovalMatrix extends Component { ...@@ -184,6 +206,15 @@ export default class CreateApprovalMatrix extends Component {
} }
handleChangeDropdown = (newValue, name) => {
this.setState(prevState => ({
...prevState,
[name]: newValue,
}), () => {
this.clearError();
})
}
clearError() { clearError() {
this.setState({ this.setState({
errorOrder: false, errorOrder: false,
...@@ -197,7 +228,9 @@ export default class CreateApprovalMatrix extends Component { ...@@ -197,7 +228,9 @@ export default class CreateApprovalMatrix extends Component {
errorStartDate: false, errorStartDate: false,
errorEndDate: false, errorEndDate: false,
msgErrorStartDate: "", msgErrorStartDate: "",
msgErrorEndDate: "" msgErrorEndDate: "",
errorMasterReportTypeId: false,
msgErrMasterReportTypeId: '',
}) })
} }
...@@ -206,14 +239,17 @@ export default class CreateApprovalMatrix extends Component { ...@@ -206,14 +239,17 @@ export default class CreateApprovalMatrix extends Component {
this.setState({ errorType: true, msgErrType: 'Approval Type Cannot be Empty' }) this.setState({ errorType: true, msgErrType: 'Approval Type Cannot be Empty' })
} }
else if (R.isEmpty(this.state.order)) { else if (R.isEmpty(this.state.order)) {
this.setState({ errorOrder: true, msgErrOrder: 'Order Cannot be Empty'}) this.setState({ errorOrder: true, msgErrOrder: 'Order Cannot be Empty' })
} }
else if (R.isNil(this.state.userId)) { else if (R.isNil(this.state.userId)) {
this.setState({ errorApproved: true, msgErrApproved: 'Approver Name Cannot be Empty' }) this.setState({ errorApproved: true, msgErrApproved: 'Approver Name Cannot be Empty' })
} }
else if (R.isNil(this.state.operatorId)) { else if (R.isNil(this.state.operatorId)) {
this.setState({ errorOperator: true, msgErrOperator: 'Operator Cannot be Empty. Please Choose - Option' }) this.setState({ errorOperator: true, msgErrOperator: 'Operator Cannot be Empty. Please Choose - Option' })
} }
else if (R.isNil(this.state.master_report_type_id)) {
this.setState({ errorMasterReportTypeId: true, msgErrMasterReportTypeId: 'Master Report Type Cannot be Empty. Please Choose - Option' })
}
else if (R.isNil(this.state.startDate)) { else if (R.isNil(this.state.startDate)) {
this.setState({ errorStartDate: true, msgErrorStartDate: 'Valid From Cannot be Empty' }) this.setState({ errorStartDate: true, msgErrorStartDate: 'Valid From Cannot be Empty' })
} else if (R.isNil(this.state.endDate)) { } else if (R.isNil(this.state.endDate)) {
...@@ -224,6 +260,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -224,6 +260,7 @@ export default class CreateApprovalMatrix extends Component {
"orders": this.state.order, "orders": this.state.order,
"user_id": this.state.userId.user_id, "user_id": this.state.userId.user_id,
"operator_type_id": this.state.operatorId.operator_type_id, "operator_type_id": this.state.operatorId.operator_type_id,
"master_report_type_id": this.state.master_report_type_id?.id ?? null,
"start_date": this.state.startDate, "start_date": this.state.startDate,
"end_date": this.state.endDate "end_date": this.state.endDate
} }
...@@ -247,7 +284,7 @@ export default class CreateApprovalMatrix extends Component { ...@@ -247,7 +284,7 @@ export default class CreateApprovalMatrix extends Component {
className="btn btn-circle btn-white" className="btn btn-circle btn-white"
onClick={() => this.props.onClickClose()} onClick={() => this.props.onClickClose()}
> >
<img src={Images.close}/> <img src={Images.close} />
</button> </button>
</div> </div>
</div> </div>
...@@ -281,11 +318,11 @@ export default class CreateApprovalMatrix extends Component { ...@@ -281,11 +318,11 @@ export default class CreateApprovalMatrix extends Component {
<Autocomplete <Autocomplete
{...this.state.types} {...this.state.types}
id="tipe" id="tipe"
onChange={(event, newInputValue) => this.setState({typeId:newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ typeId: newInputValue }, () => this.clearError())}
debug debug
renderInput={(params) => renderInput={(params) =>
<TextField <TextField
{...params} {...params}
label="Approval Type" label="Approval Type"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorType} error={this.state.errorType}
...@@ -318,11 +355,12 @@ export default class CreateApprovalMatrix extends Component { ...@@ -318,11 +355,12 @@ export default class CreateApprovalMatrix extends Component {
helperText={this.state.msgErrOrder} helperText={this.state.msgErrOrder}
// onChange={(e) => this.setState({ order: e.target.value }, () => this.clearError())} // onChange={(e) => this.setState({ order: e.target.value }, () => this.clearError())}
onChange={(e) => { onChange={(e) => {
let coba = String(e.target.value).replace(/[^\d]/g,''); let coba = String(e.target.value).replace(/[^\d]/g, '');
this.setState({ this.setState({
order: coba order: coba
}, },
() => this.clearError())} () => this.clearError())
}
// this.handleChange(coba, 'value')} // this.handleChange(coba, 'value')}
} }
inputProps={{ inputProps={{
...@@ -342,28 +380,28 @@ export default class CreateApprovalMatrix extends Component { ...@@ -342,28 +380,28 @@ export default class CreateApprovalMatrix extends Component {
</div> </div>
<div className="column-2"> <div className="column-2">
<div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}> <div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}>
<Autocomplete <Autocomplete
{...this.state.approvedBy} {...this.state.approvedBy}
id="approvedby" id="approvedby"
onChange={(event, newInputValue) => this.setState({userId:newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ userId: newInputValue }, () => this.clearError())}
// disableClearable // disableClearable
debug debug
renderInput={(params) => renderInput={(params) =>
<TextField {...params} <TextField {...params}
label="Approver Name" label="Approver Name"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorApproved} error={this.state.errorApproved}
helperText={this.state.msgErrApproved} helperText={this.state.msgErrApproved}
InputLabelProps={{ InputLabelProps={{
style: { style: {
fontSize: 11, fontSize: 11,
color: '#7e8085' color: '#7e8085'
} }
}} }}
InputProps={{ ...params.InputProps, style: { fontSize: 11 } }} InputProps={{ ...params.InputProps, style: { fontSize: 11 } }}
/>} />}
value={this.state.userId} value={this.state.userId}
/> />
</div> </div>
</div> </div>
</div> </div>
...@@ -375,10 +413,10 @@ export default class CreateApprovalMatrix extends Component { ...@@ -375,10 +413,10 @@ export default class CreateApprovalMatrix extends Component {
id="operator" id="operator"
// disableClearable // disableClearable
debug debug
onChange={(event, newInputValue) => this.setState({operatorId:newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ operatorId: newInputValue }, () => this.clearError())}
renderInput={(params) => renderInput={(params) =>
<TextField {...params} <TextField {...params}
label="Operator" label="Operator"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorOperator} error={this.state.errorOperator}
helperText={this.state.msgErrOperator} helperText={this.state.msgErrOperator}
...@@ -389,73 +427,84 @@ export default class CreateApprovalMatrix extends Component { ...@@ -389,73 +427,84 @@ export default class CreateApprovalMatrix extends Component {
} }
}} }}
InputProps={{ ...params.InputProps, style: { fontSize: 11 } }} InputProps={{ ...params.InputProps, style: { fontSize: 11 } }}
/>} />}
value={this.state.operatorId} value={this.state.operatorId}
/> />
</div> </div>
</div> </div>
<div className="column-2"> <div className="column-2">
<div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}>
<AutocompleteField
options={this.state.listMasterReportType}
value={this.state.master_report_type_id}
onChange={(event, newValue) => this.handleChangeDropdown(newValue, 'master_report_type_id')}
label="Master Report Type"
minSizeBox={true}
error={this.state.errorMasterReportTypeId}
helperText={this.state.msgErrMasterReportTypeId}
disableClearable={false}
/>
</div>
</div> </div>
</div> </div>
<div className="grid grid-2x grid-mobile-none gap-15px"> <div className="grid grid-2x grid-mobile-none gap-15px">
<div className="column-1"> <div className="column-1">
<div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}> <div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}>
<DatePicker <DatePicker
margin="normal" margin="normal"
id="startDate" id="startDate"
label="Valid From" label="Valid From"
format="dd MMMM yyyy" format="dd MMMM yyyy"
value={this.state.startDate == "" ? null : this.state.startDate} value={this.state.startDate == "" ? null : this.state.startDate}
onChange={(e) => this.handleChange(e, 'start_date')} onChange={(e) => this.handleChange(e, 'start_date')}
KeyboardButtonProps={{ KeyboardButtonProps={{
'aria-label': 'change date', 'aria-label': 'change date',
}} }}
inputProps={{ inputProps={{
style: { style: {
fontSize: 11 fontSize: 11
} }
}} }}
InputLabelProps={{ InputLabelProps={{
style: { style: {
fontSize: 11, fontSize: 11,
color: '#7e8085' color: '#7e8085'
} }
}} }}
error={this.state.errorStartDate} error={this.state.errorStartDate}
helperText={this.state.msgErrorStartDate} helperText={this.state.msgErrorStartDate}
style={{ padding: 0, margin: 0, width: '100%' }} style={{ padding: 0, margin: 0, width: '100%' }}
/> />
</div> </div>
</div> </div>
<div className="column-2"> <div className="column-2">
<div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}> <div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}>
<DatePicker <DatePicker
margin="normal" margin="normal"
id="endDate" id="endDate"
label="Valid To" label="Valid To"
format="dd MMMM yyyy" format="dd MMMM yyyy"
value={this.state.endDate == "" ? null : this.state.endDate} value={this.state.endDate == "" ? null : this.state.endDate}
error={this.state.errorEndDate} error={this.state.errorEndDate}
helperText={this.state.msgErrorEndDate} helperText={this.state.msgErrorEndDate}
onChange={(e) => this.handleChange(e, 'end_date')} onChange={(e) => this.handleChange(e, 'end_date')}
minDate={this.state.startDate} minDate={this.state.startDate}
KeyboardButtonProps={{ KeyboardButtonProps={{
'aria-label': 'change date', 'aria-label': 'change date',
}} }}
inputProps={{ inputProps={{
style: { style: {
fontSize: 11 fontSize: 11
} }
}} }}
InputLabelProps={{ InputLabelProps={{
style: { style: {
fontSize: 11, fontSize: 11,
color: '#7e8085' color: '#7e8085'
} }
}} }}
style={{ padding: 0, margin: 0, width: '100%' }} style={{ padding: 0, margin: 0, width: '100%' }}
/> />
</div> </div>
</div> </div>
</div> </div>
...@@ -502,12 +551,12 @@ export default class CreateApprovalMatrix extends Component { ...@@ -502,12 +551,12 @@ export default class CreateApprovalMatrix extends Component {
</div> </div>
<div className="border-top grid grid-2x" style={{ height: 56, backgroundColor: '#f5f5f5', paddingLeft: 20, paddingRight: 20 }}> <div className="border-top grid grid-2x" style={{ height: 56, backgroundColor: '#f5f5f5', paddingLeft: 20, paddingRight: 20 }}>
<div className="column-1" style={{ alignSelf: 'center' }}> <div className="column-1" style={{ alignSelf: 'center' }}>
<div onClick={() => this.props.onClickClose()} style={{ width: 102, height: 30, border: 'solid 1px #354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor:"pointer" }}> <div onClick={() => this.props.onClickClose()} style={{ width: 102, height: 30, border: 'solid 1px #354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor: "pointer" }}>
<span style={{ color: '#354960', fontSize: 11 }} >Cancel</span> <span style={{ color: '#354960', fontSize: 11 }} >Cancel</span>
</div> </div>
</div> </div>
<div className="column-2" style={{display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}> <div className="column-2" style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
<div onClick={() => this.validasi()} style={{ width: 102, height: 30, backgroundColor: '#354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor:"pointer" }}> <div onClick={() => this.validasi()} style={{ width: 102, height: 30, backgroundColor: '#354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor: "pointer" }}>
<span style={{ color: '#fff', fontSize: 11 }}>Save</span> <span style={{ color: '#fff', fontSize: 11 }}>Save</span>
</div> </div>
</div> </div>
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import { TextField, Typography } from '@material-ui/core'; import { TextField, Typography } from '@material-ui/core';
import { DateTimePicker, KeyboardDatePicker, DatePicker} from "@material-ui/pickers"; import { DateTimePicker, KeyboardDatePicker, DatePicker } from "@material-ui/pickers";
import Autocomplete from '@material-ui/lab/Autocomplete'; import Autocomplete from '@material-ui/lab/Autocomplete';
import * as R from 'ramda' import * as R from 'ramda'
import format from "date-fns/format"; import format from "date-fns/format";
import api from "../../api"; import api from "../../api";
import Images from '../../assets/Images'; import Images from '../../assets/Images';
import Constant from '../../library/Constant'; import Constant from '../../library/Constant';
import { fetchMasterReportType } from '../../utils/services';
import AutocompleteField from '../../library/AutocompleteField';
import { convertSelect } from '../../library/Utils';
export default class EditApprovalMatrix extends Component { export default class EditApprovalMatrix extends Component {
constructor(props) { constructor(props) {
...@@ -35,7 +38,12 @@ export default class EditApprovalMatrix extends Component { ...@@ -35,7 +38,12 @@ export default class EditApprovalMatrix extends Component {
errorStartDate: false, errorStartDate: false,
errorEndDate: false, errorEndDate: false,
msgErrorStartDate: "", msgErrorStartDate: "",
msgErrorEndDate: "" msgErrorEndDate: "",
master_report_type_id: null,
listMasterReportType: [],
errorMasterReportTypeId: false,
msgErrMasterReportTypeId: '',
} }
} }
...@@ -49,6 +57,21 @@ export default class EditApprovalMatrix extends Component { ...@@ -49,6 +57,21 @@ export default class EditApprovalMatrix extends Component {
} }
} }
getMasterBudgetType = async () => {
const { data } = await fetchMasterReportType();
if (data) {
const list = data.map((item) => ({
id: item.master_report_type_id,
name: item.master_report_type_name
}));
this.setState({ listMasterReportType: list });
} else {
this.setState({ listMasterReportType: [] });
}
}
getDetailAM() { getDetailAM() {
api.create().getDetailAM(this.props.data[1]).then(response => { api.create().getDetailAM(this.props.data[1]).then(response => {
console.log(response) console.log(response)
...@@ -66,8 +89,9 @@ export default class EditApprovalMatrix extends Component { ...@@ -66,8 +89,9 @@ export default class EditApprovalMatrix extends Component {
getOperatorId: data.operator_type_id, getOperatorId: data.operator_type_id,
status: data.status, status: data.status,
created: data.created, created: data.created,
updated: data.updated === null ? "" : data.updated updated: data.updated === null ? "" : data.updated,
}, () => this.getUserData(), this.getTypeData(), this.getOperatorData()) master_report_type_id: convertSelect(data?.master_report_type_id, data?.master_report_type_name)
}, () => this.getUserData(), this.getTypeData(), this.getOperatorData(), this.getMasterBudgetType())
} else { } else {
this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }, () => { this.setState({ alert: true, messageAlert: response.data.message, tipeAlert: 'warning' }, () => {
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -98,7 +122,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -98,7 +122,7 @@ export default class EditApprovalMatrix extends Component {
let userData = data.map((item) => { let userData = data.map((item) => {
return { return {
user_id: item.user_id, user_id: item.user_id,
fullname: item.fullname == null? "(NO_NAME)" : item.fullname fullname: item.fullname == null ? "(NO_NAME)" : item.fullname
} }
}) })
let index = userData.findIndex((val) => val.user_id == this.state.getUserId) let index = userData.findIndex((val) => val.user_id == this.state.getUserId)
...@@ -107,8 +131,8 @@ export default class EditApprovalMatrix extends Component { ...@@ -107,8 +131,8 @@ export default class EditApprovalMatrix extends Component {
getOptionLabel: (option) => option.fullname, getOptionLabel: (option) => option.fullname,
}; };
// this.setState({ approvedBy: defaultProps, userData: response.data.data, getApprovedBy: index == -1 ? userData[0]: userData[index] }) // this.setState({ approvedBy: defaultProps, userData: response.data.data, getApprovedBy: index == -1 ? userData[0]: userData[index] })
this.setState({ approvedBy: defaultProps, userData: response.data.data, getApprovedBy: index == -1 ? this.setState({ errorApproved: true, msgErrApproved: 'Approver Name has been Inactive.' }): userData[index] }) this.setState({ approvedBy: defaultProps, userData: response.data.data, getApprovedBy: index == -1 ? this.setState({ errorApproved: true, msgErrApproved: 'Approver Name has been Inactive.' }) : userData[index] })
} else { } else {
// alert('Pemberi Persetujuan: ' +response.data.message) // alert('Pemberi Persetujuan: ' +response.data.message)
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -119,7 +143,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -119,7 +143,7 @@ export default class EditApprovalMatrix extends Component {
}, 1000); }, 1000);
}) })
} else { } else {
this.setState({ alert: true, messageAlert: 'Pemberi Persetujuan: ' +response.data.message, tipeAlert: 'error' }) this.setState({ alert: true, messageAlert: 'Pemberi Persetujuan: ' + response.data.message, tipeAlert: 'error' })
} }
} }
} else { } else {
...@@ -148,7 +172,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -148,7 +172,7 @@ export default class EditApprovalMatrix extends Component {
options: operatorData, options: operatorData,
getOptionLabel: (option) => option.operator_type_name, getOptionLabel: (option) => option.operator_type_name,
}; };
this.setState({ operators: operatorProps, operatorData: response.data.data, getOperators: index == -1 ? operatorData[0]: operatorData[index] }) this.setState({ operators: operatorProps, operatorData: response.data.data, getOperators: index == -1 ? operatorData[0] : operatorData[index] })
} else { } else {
// alert('Operator: ' +response.data.message) // alert('Operator: ' +response.data.message)
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -159,7 +183,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -159,7 +183,7 @@ export default class EditApprovalMatrix extends Component {
}, 1000); }, 1000);
}) })
} else { } else {
this.setState({ alert: true, messageAlert: 'Operator: ' +response.data.message, tipeAlert: 'error' }) this.setState({ alert: true, messageAlert: 'Operator: ' + response.data.message, tipeAlert: 'error' })
} }
} }
} else { } else {
...@@ -188,7 +212,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -188,7 +212,7 @@ export default class EditApprovalMatrix extends Component {
options: typeData, options: typeData,
getOptionLabel: (option) => option.approval_type_name, getOptionLabel: (option) => option.approval_type_name,
}; };
this.setState({ types: typeProps, typeData: response.data.data, getTypes: index == -1 ? typeData[0]: typeData[index] }) this.setState({ types: typeProps, typeData: response.data.data, getTypes: index == -1 ? typeData[0] : typeData[index] })
} else { } else {
// alert('Approval Type: ' +response.data.message) // alert('Approval Type: ' +response.data.message)
if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) { if (response.data.message.includes("Someone Logged In") || response.data.message.includes("Token Expired")) {
...@@ -199,7 +223,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -199,7 +223,7 @@ export default class EditApprovalMatrix extends Component {
}, 1000); }, 1000);
}) })
} else { } else {
this.setState({ alert: true, messageAlert: 'Approval Type: ' +response.data.message, tipeAlert: 'error' }) this.setState({ alert: true, messageAlert: 'Approval Type: ' + response.data.message, tipeAlert: 'error' })
} }
} }
} else { } else {
...@@ -231,6 +255,15 @@ export default class EditApprovalMatrix extends Component { ...@@ -231,6 +255,15 @@ export default class EditApprovalMatrix extends Component {
} }
handleChangeDropdown = (newValue, name) => {
this.setState(prevState => ({
...prevState,
[name]: newValue,
}), () => {
this.clearError();
})
}
clearError() { clearError() {
this.setState({ this.setState({
errorType: false, errorType: false,
...@@ -244,7 +277,9 @@ export default class EditApprovalMatrix extends Component { ...@@ -244,7 +277,9 @@ export default class EditApprovalMatrix extends Component {
errorStartDate: false, errorStartDate: false,
errorEndDate: false, errorEndDate: false,
msgErrorStartDate: "", msgErrorStartDate: "",
msgErrorEndDate: "" msgErrorEndDate: "",
errorMasterReportTypeId: false,
msgErrMasterReportTypeId: '',
}) })
} }
...@@ -253,26 +288,30 @@ export default class EditApprovalMatrix extends Component { ...@@ -253,26 +288,30 @@ export default class EditApprovalMatrix extends Component {
this.setState({ errorType: true, msgErrType: 'Approval Type Cannot be Empty' }) this.setState({ errorType: true, msgErrType: 'Approval Type Cannot be Empty' })
} }
else if (R.isEmpty(this.state.order)) { else if (R.isEmpty(this.state.order)) {
this.setState({ errorOrder: true, msgErrOrder: 'Order Cannot be Empty'}) this.setState({ errorOrder: true, msgErrOrder: 'Order Cannot be Empty' })
} }
else if (R.isNil(this.state.getApprovedBy)) { else if (R.isNil(this.state.getApprovedBy)) {
this.setState({ errorApproved: true, msgErrApproved: 'Approver Name Cannot be Empty' }) this.setState({ errorApproved: true, msgErrApproved: 'Approver Name Cannot be Empty' })
} }
else if (R.isNil(this.state.getOperators)) { else if (R.isNil(this.state.getOperators)) {
this.setState({ errorOperator: true, msgErrOperator: 'Operator Cannot be Empty' }) this.setState({ errorOperator: true, msgErrOperator: 'Operator Cannot be Empty' })
} }
else if (R.isNil(this.state.master_report_type_id)) {
this.setState({ errorMasterReportTypeId: true, msgErrMasterReportTypeId: 'Master Report Type Cannot be Empty. Please Choose - Option' })
}
else if (R.isEmpty(this.state.startDate)) { else if (R.isEmpty(this.state.startDate)) {
this.setState({ errorStartDate: true, msgErrorStartDate: 'Valid From Cannot be Empty' }) this.setState({ errorStartDate: true, msgErrorStartDate: 'Valid From Cannot be Empty' })
} else if (R.isEmpty(this.state.endDate)) { } else if (R.isEmpty(this.state.endDate)) {
this.setState({ errorEndDate: true, msgErrorEndDate: 'Valid To Cannot be Empty' }) this.setState({ errorEndDate: true, msgErrorEndDate: 'Valid To Cannot be Empty' })
} else { } else {
if (this.props.type == 'edit') { if (this.props.type == 'edit') {
let payload = { let payload = {
"approval_matrix_id": this.state.id, "approval_matrix_id": this.state.id,
"approval_type_id": this.state.getTypes.approval_type_id, "approval_type_id": this.state.getTypes.approval_type_id,
"orders": this.state.order, "orders": this.state.order,
"user_id": this.state.getApprovedBy.user_id, "user_id": this.state.getApprovedBy.user_id,
"operator_type_id": this.state.getOperators.operator_type_id, "operator_type_id": this.state.getOperators.operator_type_id,
"master_report_type_id": this.state.master_report_type_id?.id ?? null,
"start_date": this.state.startDate, "start_date": this.state.startDate,
"end_date": this.state.endDate "end_date": this.state.endDate
} }
...@@ -297,7 +336,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -297,7 +336,7 @@ export default class EditApprovalMatrix extends Component {
className="btn btn-circle btn-white" className="btn btn-circle btn-white"
onClick={() => this.props.onClickClose()} onClick={() => this.props.onClickClose()}
> >
<img src={Images.close}/> <img src={Images.close} />
</button> </button>
</div> </div>
</div> </div>
...@@ -333,10 +372,10 @@ export default class EditApprovalMatrix extends Component { ...@@ -333,10 +372,10 @@ export default class EditApprovalMatrix extends Component {
option option
debug debug
id="tipe" id="tipe"
onChange={(event, newInputValue) => this.setState({getTypes:newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ getTypes: newInputValue }, () => this.clearError())}
renderInput={(params) => renderInput={(params) =>
<TextField {...params} <TextField {...params}
label="Approval Type" label="Approval Type"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorType} error={this.state.errorType}
helperText={this.state.msgErrType} helperText={this.state.msgErrType}
...@@ -347,7 +386,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -347,7 +386,7 @@ export default class EditApprovalMatrix extends Component {
} }
}} }}
InputProps={{ ...params.InputProps, style: { fontSize: 11 } }} InputProps={{ ...params.InputProps, style: { fontSize: 11 } }}
/>} />}
value={this.state.getTypes} value={this.state.getTypes}
/> />
</div> </div>
...@@ -365,11 +404,12 @@ export default class EditApprovalMatrix extends Component { ...@@ -365,11 +404,12 @@ export default class EditApprovalMatrix extends Component {
helperText={this.state.msgErrOrder} helperText={this.state.msgErrOrder}
// onChange={(e) => this.setState({ order: e.target.value }, () => this.clearError())} // onChange={(e) => this.setState({ order: e.target.value }, () => this.clearError())}
onChange={(e) => { onChange={(e) => {
let coba = String(e.target.value).replace(/[^\d]/g,''); let coba = String(e.target.value).replace(/[^\d]/g, '');
this.setState({ this.setState({
order: coba order: coba
}, },
() => this.clearError())} () => this.clearError())
}
// this.handleChange(coba, 'value')} // this.handleChange(coba, 'value')}
} }
inputProps={{ inputProps={{
...@@ -383,7 +423,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -383,7 +423,7 @@ export default class EditApprovalMatrix extends Component {
color: '#7e8085' color: '#7e8085'
} }
}} }}
// name="order" // name="order"
> >
</TextField> </TextField>
</div> </div>
...@@ -395,9 +435,9 @@ export default class EditApprovalMatrix extends Component { ...@@ -395,9 +435,9 @@ export default class EditApprovalMatrix extends Component {
option option
debug debug
id="approvedby" id="approvedby"
onChange={(event, newInputValue) => this.setState({getApprovedBy: newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ getApprovedBy: newInputValue }, () => this.clearError())}
renderInput={(params) => renderInput={(params) =>
<TextField {...params} <TextField {...params}
label="Approver Name" label="Approver Name"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorApproved} error={this.state.errorApproved}
...@@ -423,10 +463,10 @@ export default class EditApprovalMatrix extends Component { ...@@ -423,10 +463,10 @@ export default class EditApprovalMatrix extends Component {
option option
debug debug
id="operator" id="operator"
onChange={(event, newInputValue) => this.setState({getOperators: newInputValue}, ()=> this.clearError())} onChange={(event, newInputValue) => this.setState({ getOperators: newInputValue }, () => this.clearError())}
renderInput={(params) => renderInput={(params) =>
<TextField {...params} <TextField {...params}
label="Operator" label="Operator"
onChange={(e) => this.handleChange(e, '')} onChange={(e) => this.handleChange(e, '')}
error={this.state.errorOperator} error={this.state.errorOperator}
helperText={this.state.msgErrOperator} helperText={this.state.msgErrOperator}
...@@ -443,7 +483,18 @@ export default class EditApprovalMatrix extends Component { ...@@ -443,7 +483,18 @@ export default class EditApprovalMatrix extends Component {
</div> </div>
</div> </div>
<div className="column-2"> <div className="column-2">
<div className="margin-top-10px" style={{ padding: 10, borderRadius: 5 }}>
<AutocompleteField
options={this.state.listMasterReportType}
value={this.state.master_report_type_id}
onChange={(event, newValue) => this.handleChangeDropdown(newValue, 'master_report_type_id')}
label="Master Report Type"
minSizeBox={true}
error={this.state.errorMasterReportTypeId}
helperText={this.state.msgErrMasterReportTypeId}
disableClearable={false}
/>
</div>
</div> </div>
</div> </div>
<div className="grid grid-2x grid-mobile-none gap-15px"> <div className="grid grid-2x grid-mobile-none gap-15px">
...@@ -472,7 +523,7 @@ export default class EditApprovalMatrix extends Component { ...@@ -472,7 +523,7 @@ export default class EditApprovalMatrix extends Component {
}} }}
error={this.state.errorStartDate} error={this.state.errorStartDate}
helperText={this.state.msgErrorStartDate} helperText={this.state.msgErrorStartDate}
style={{padding: 0, margin: 0, width: '100%'}} style={{ padding: 0, margin: 0, width: '100%' }}
/> />
</div> </div>
</div> </div>
...@@ -502,8 +553,8 @@ export default class EditApprovalMatrix extends Component { ...@@ -502,8 +553,8 @@ export default class EditApprovalMatrix extends Component {
color: '#7e8085' color: '#7e8085'
} }
}} }}
style={{padding: 0, margin: 0, width: '100%'}} style={{ padding: 0, margin: 0, width: '100%' }}
/> />
</div> </div>
</div> </div>
</div> </div>
...@@ -568,12 +619,12 @@ export default class EditApprovalMatrix extends Component { ...@@ -568,12 +619,12 @@ export default class EditApprovalMatrix extends Component {
</div> </div>
<div className="border-top grid grid-2x" style={{ height: 56, backgroundColor: '#f5f5f5', paddingLeft: 20, paddingRight: 20 }}> <div className="border-top grid grid-2x" style={{ height: 56, backgroundColor: '#f5f5f5', paddingLeft: 20, paddingRight: 20 }}>
<div className="column-1" style={{ alignSelf: 'center' }}> <div className="column-1" style={{ alignSelf: 'center' }}>
<div onClick={() => this.props.onClickClose()} style={{ width: 102, height: 30, border: 'solid 1px #354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor:"pointer" }}> <div onClick={() => this.props.onClickClose()} style={{ width: 102, height: 30, border: 'solid 1px #354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor: "pointer" }}>
<span style={{ color: '#354960', fontSize: 11 }} >Cancel</span> <span style={{ color: '#354960', fontSize: 11 }} >Cancel</span>
</div> </div>
</div> </div>
<div className="column-2" style={{display: 'flex', justifyContent: 'flex-end', alignItems: 'center'}}> <div className="column-2" style={{ display: 'flex', justifyContent: 'flex-end', alignItems: 'center' }}>
<div onClick={() => this.validasi()} style={{ width: 102, height: 30, backgroundColor: '#354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor:"pointer" }}> <div onClick={() => this.validasi()} style={{ width: 102, height: 30, backgroundColor: '#354960', borderRadius: 5, alignItems: 'center', display: 'flex', justifyContent: 'center', cursor: "pointer" }}>
<span style={{ color: '#fff', fontSize: 11 }}>Save</span> <span style={{ color: '#fff', fontSize: 11 }}>Save</span>
</div> </div>
</div> </div>
......
...@@ -93,7 +93,7 @@ class ReportHistorical extends Component { ...@@ -93,7 +93,7 @@ class ReportHistorical extends Component {
})) }))
} }
showAlert = (message, severity = 'success') => { showAlert = (message, severity = Constant.ALERT_SEVIRITY.SUCCESS) => {
this.setState({ this.setState({
showAlert: true, showAlert: true,
alertMessage: message, alertMessage: message,
...@@ -107,8 +107,12 @@ class ReportHistorical extends Component { ...@@ -107,8 +107,12 @@ class ReportHistorical extends Component {
handleDownload = async () => { handleDownload = async () => {
try { try {
this.setLoading(true)
const { data } = this.state const { data } = this.state
if (!data?.company_id) {
this.showAlert('Data is not complete !', Constant.ALERT_SEVIRITY.WARNING);
return
}
this.setLoading(true)
const payload = { const payload = {
report_id: data.report_id?.id, report_id: data.report_id?.id,
company_id: data.company_id?.map(c => c.id).join(','), company_id: data.company_id?.map(c => c.id).join(','),
...@@ -125,12 +129,12 @@ class ReportHistorical extends Component { ...@@ -125,12 +129,12 @@ class ReportHistorical extends Component {
downloadFileBlob(fileName, blob) downloadFileBlob(fileName, blob)
} }
this.showAlert('Download Berhasil', 'success'); this.showAlert('Download Berhasil');
}) })
} catch (error) { } catch (error) {
// Show error alert // Show error alert
this.showAlert(`Gagal menyimpan: ${error.message}`, 'error'); this.showAlert(`Gagal menyimpan: ${error.message}`, Constant.ALERT_SEVIRITY.ERROR);
} }
}; };
......
...@@ -27,21 +27,29 @@ const AutocompleteField = ({ ...@@ -27,21 +27,29 @@ const AutocompleteField = ({
multiple = false, multiple = false,
showCheckbox = false, showCheckbox = false,
isLoading = false, isLoading = false,
minSizeBox = false,
...props ...props
}) => { }) => {
const defaultRenderInput = (params) => ( const defaultRenderInput = (params) => (
<TextField <TextField
{...params} {...params}
label={label} label={label}
margin={margin} margin={minSizeBox ? 'none' : margin}
style={{ marginTop: 7 }} style={minSizeBox ? {} : { marginTop: 7 }}
disabled={disabled} disabled={disabled}
required={required} required={required}
error={error} error={error}
helperText={helperText} helperText={helperText}
fullWidth fullWidth
InputLabelProps={minSizeBox ? {
style: {
fontSize: 11,
color: '#7e8085'
}
} : {}}
InputProps={{ InputProps={{
...params.InputProps, ...params.InputProps,
style: minSizeBox ? { fontSize: 11 } : {},
endAdornment: ( endAdornment: (
<> <>
{isLoading ? ( {isLoading ? (
...@@ -90,7 +98,7 @@ const AutocompleteField = ({ ...@@ -90,7 +98,7 @@ const AutocompleteField = ({
onChange={onChange} onChange={onChange}
value={multiple ? (value || []) : (value || null)} value={multiple ? (value || []) : (value || null)}
id={id} id={id}
disableClearable={!multiple && disableClearable} disableClearable={disableClearable}
disableCloseOnSelect={multiple} disableCloseOnSelect={multiple}
style={style} style={style}
disabled={disabled} disabled={disabled}
......
...@@ -29,9 +29,7 @@ class ContentContainer extends Component { ...@@ -29,9 +29,7 @@ class ContentContainer extends Component {
{isLoading && ( {isLoading && (
<OverlayLoader isLoading={isLoading} {...loaderProps} /> <OverlayLoader isLoading={isLoading} {...loaderProps} />
)} )}
<Header {title && <Header title={title} />}
title={title}
/>
{children} {children}
</div> </div>
); );
......
...@@ -4,96 +4,88 @@ import AutocompleteField from '../AutocompleteField'; ...@@ -4,96 +4,88 @@ import AutocompleteField from '../AutocompleteField';
import api from '../../api'; import api from '../../api';
class DDLCompany extends Component { class DDLCompany extends Component {
constructor(props) { state = {
super(props); companies: [],
this.state = { selectedValue: this.props.multiple ? [] : null,
selectedValue: props.multiple isLoading: false,
? (props.value || []) };
: (props.value || null),
companies: [],
isLoading: false,
};
}
componentDidMount() { componentDidMount() {
this.getCompanyActive(); this.getCompanyActive();
} }
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
// Value dikontrol parent // 🔁 value dari parent berubah ATAU companies selesai load
if (prevProps.value !== this.props.value) { if (
this.syncValueWithCompanies(this.props.value); prevProps.value !== this.props.value ||
} prevState.companies !== this.state.companies
) {
// Companies berubah (hasil API)
if (prevState.companies !== this.state.companies) {
this.syncValueWithCompanies(this.props.value); this.syncValueWithCompanies(this.props.value);
} }
} }
setLoading = (isLoading) => { setLoading = (isLoading) => {
this.setState({ isLoading }); this.setState({ isLoading });
} };
getCompanyActive = async () => { getCompanyActive = async () => {
try { try {
this.setLoading(true); this.setLoading(true);
const response = await api.create().getPerusahaanActive(); const res = await api.create().getPerusahaanActive();
const data = response?.data?.data || []; const data = res?.data?.data || [];
const companies = data.map(item => ({ const companies = data.map(item => ({
id: String(item.company_id), id: String(item.company_id),
name: item.company_name, name: item.company_name,
})); }));
this.setState({ companies }); this.setState({ companies }, () => {
} catch (err) { // ⭐ optional auto select index 0
console.error('Failed to load companies', err); if (
this.props.autoSelectFirst &&
!this.props.value &&
companies.length > 0
) {
this.handleChange(null, this.props.multiple ? [companies[0]] : companies[0]);
}
});
} catch (e) {
console.error(e);
this.setState({ companies: [] }); this.setState({ companies: [] });
} finally { } finally {
this.setLoading(false); this.setLoading(false);
} }
}; };
// Sinkron value → referensi object dari companies // 🔑 SINKRON VALUE ↔ OPTIONS (INI KUNCI UTAMA)
syncValueWithCompanies = (value) => { syncValueWithCompanies = (value) => {
const { companies } = this.state; const { companies } = this.state;
const { multiple } = this.props; const { multiple } = this.props;
if (!value || companies.length === 0) { if (!value || companies.length === 0) return;
this.setState({
selectedValue: multiple ? [] : null,
});
return;
}
if (multiple) { if (multiple) {
const synced = value const synced = value
.map(v => .map(v => companies.find(c => c.id === String(v.id)))
companies.find(c => String(c.id) === String(v.id))
)
.filter(Boolean); .filter(Boolean);
this.setState({ selectedValue: synced }); this.setState({ selectedValue: synced });
} else { } else {
const matched = companies.find( const matched = companies.find(c => c.id === String(value.id));
c => String(c.id) === String(value.id)
);
this.setState({ selectedValue: matched || null }); this.setState({ selectedValue: matched || null });
} }
}; };
// 🔁 SELALU KIRIM BALIK KE PARENT
handleChange = (event, newValue) => { handleChange = (event, newValue) => {
const { onChange, onCompanyChange, name, multiple } = this.props; const { onChange, onCompanyChange, name, multiple } = this.props;
this.setState({ selectedValue: newValue }); this.setState({ selectedValue: newValue });
// Standard handler
if (onChange) { if (onChange) {
onChange(event, newValue, name); onChange(event, newValue, name);
} }
// Backward compatibility
if (onCompanyChange) { if (onCompanyChange) {
if (multiple) { if (multiple) {
onCompanyChange(newValue.map(v => v.id)); onCompanyChange(newValue.map(v => v.id));
...@@ -103,29 +95,20 @@ class DDLCompany extends Component { ...@@ -103,29 +95,20 @@ class DDLCompany extends Component {
} }
}; };
getSelectedCompanyValue = () => {
const { selectedValue } = this.state;
const { multiple } = this.props;
return multiple
? selectedValue.map(v => v.id)
: selectedValue?.id || null;
};
render() { render() {
const { const {
label = 'Company', label,
placeholder = 'Select Company', placeholder,
disabled = false, disabled,
required = false, required,
error = false, error,
helperText, helperText,
style = { width: 250 }, style,
margin = 'normal', margin,
multiple, multiple,
} = this.props; } = this.props;
const { selectedValue, companies, isLoading } = this.state; const { companies, selectedValue, isLoading } = this.state;
return ( return (
<AutocompleteField <AutocompleteField
...@@ -142,17 +125,14 @@ class DDLCompany extends Component { ...@@ -142,17 +125,14 @@ class DDLCompany extends Component {
margin={margin} margin={margin}
multiple={multiple} multiple={multiple}
showCheckbox={multiple} showCheckbox={multiple}
isLoading={isLoading} loading={isLoading}
/> />
); );
} }
} }
DDLCompany.propTypes = { DDLCompany.propTypes = {
value: PropTypes.oneOfType([ value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
PropTypes.object,
PropTypes.array,
]),
onChange: PropTypes.func, onChange: PropTypes.func,
onCompanyChange: PropTypes.func, onCompanyChange: PropTypes.func,
name: PropTypes.string, name: PropTypes.string,
...@@ -168,13 +148,16 @@ DDLCompany.propTypes = { ...@@ -168,13 +148,16 @@ DDLCompany.propTypes = {
helperText: PropTypes.string, helperText: PropTypes.string,
multiple: PropTypes.bool, multiple: PropTypes.bool,
autoSelectFirst: PropTypes.bool,
}; };
DDLCompany.defaultProps = { DDLCompany.defaultProps = {
label: 'Company', label: 'Company',
placeholder: 'Select Company', placeholder: 'Select Company',
style: { width: 250 }, style: { width: 250 },
margin: 'normal',
multiple: false, multiple: false,
autoSelectFirst: false,
}; };
export default DDLCompany; export default DDLCompany;
...@@ -26,4 +26,58 @@ export function downloadFileBlob(fileName, blobData) { ...@@ -26,4 +26,58 @@ export function downloadFileBlob(fileName, blobData) {
a.click() a.click()
a.remove() a.remove()
window.URL.revokeObjectURL(url) window.URL.revokeObjectURL(url)
} }
\ No newline at end of file
/**
* @param {Object} location - Objek location dari props (this.props.location)
* @param {string} paramName - Nama key yang ingin diambil (misal: 'month')
* @param {any} defaultValue - Nilai kembalian jika data null/undefined
*/
export const getStateParam = (location, paramName = null, defaultValue = null) => {
if (!paramName) {
return location?.state ?? defaultValue;
}
return location?.state?.[paramName] ?? defaultValue;
};
export const formatters = {
// Untuk format Infinity
infinity: {
month: (val) => String(val === undefined || val === 'Infinity' || val === '-Infinity'
? "0.0"
: Number(val).toFixed(2)),
totalCY: (val) => String(val === undefined || val === 'Infinity' || val === '-Infinity'
? "0.0"
: Number(val).toFixed(2)),
totalOther: (val) => String(val !== '' && val !== 'Infinity' && val !== '-Infinity'
? Number(val).toFixed(2)
: val)
},
// Untuk format .value property
value: {
month: (val) => String(val?.value === undefined ? val : Number(val.value).toFixed(1)),
total: (val) => String(val !== '' ? Number(val).toFixed(1) : val)
}
};
// ===== HELPER FUNCTIONS =====
export const createMonthData = (item, startIdx, formatFn) => {
const monthNames = ['january', 'february', 'march', 'april', 'may', 'june',
'july', 'august', 'september', 'october', 'november', 'december'];
const months = {};
monthNames.forEach((month, idx) => {
months[month] = formatFn(item[startIdx + idx]);
});
return months;
};
export const convertSelect = (id, name) => {
const obj = id ? {
id,
name,
} : null
return obj
};
\ No newline at end of file
import api from "../api";
import Constant from "../library/Constant";
const handleResponse = (response) => {
// 1. Handling Sukses
if (response.ok && response.data?.status === "success") {
return response.data.data;
}
// 2. Ambil pesan asli
const serverMessage = response.data?.message || response.data?.error || response.problem || "Gagal";
// 3. Masking bahasa teknis backend
let finalMessage = serverMessage;
if (typeof serverMessage === 'string' && (
serverMessage.includes("java.lang") ||
serverMessage.includes("FormatException") ||
serverMessage.includes("sql")
)) {
finalMessage = "Terjadi kesalahan format data pada sistem.";
}
const error = new Error(finalMessage);
error.tipe = (response.status >= 400 && response.status < 500) ? 'warning' : 'error';
error.isApiError = true;
error.originalMessage = serverMessage;
throw error;
};
/**
* Wrapper agar komponen bisa memilih mau pakai data saja atau errornya juga.
* Menghilangkan kebutuhan try-catch di komponen.
*/
const wrapService = (promise) => {
return promise
.then(res => {
return { data: handleResponse(res), error: null };
})
.catch((err) => {
console.error("API_LOG:", err.originalMessage || err.message);
return {
data: null,
error: { message: err.message, tipe: err.tipe }
};
});
};
// --- EXPORTED SERVICES ---
export const fetchMenuPermission = (menuName) => wrapService(api.create().getPermission({ menu: menuName }));
export const fetchDetailRole = (roleId) => wrapService(api.create().getDetailRole(roleId));
export const fetchDetailUser = () => {
const userId = localStorage.getItem(Constant.USER);
return wrapService(api.create().getDetailUser(userId));
};
export const fetchApprover = () => wrapService(api.create().checkApprover());
export const fetchLastPeriod = (companyId) => wrapService(api.create().getLastPeriod(companyId));
export const fetchRevision = (payload) => wrapService(api.create().getRevision(payload));
export const fetchSubmission = (payload) => wrapService(api.create().getSubmission(payload));
export const fetchListApprover = (report, monthlyReportId) => {
return wrapService(api.create().getListApprover(report, monthlyReportId));
}
export const fetchDetailReportCF = (payload) => wrapService(api.create().getDetailReportCF(payload));
export const fetchPLID = (payload) => wrapService(api.create().getPLID(payload));
export const fetchHierarkiCreateReportPLMB = (payload) => wrapService(api.create().getHierarkiCreateReportPLMB(payload));
export const fetchFRID = (payload) => wrapService(api.create().getFRID(payload));
export const fetchDownloadFile = (payload) => wrapService(api.create().createDownloadFile(payload));
export const fetchZipReport = (downloadedFileReportId) => wrapService(api.create().createZipReport(downloadedFileReportId));
export const fetchMasterReportType = () => wrapService(api.create().getMasterReportType());
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment