allow fees edit; track changes; focus last changed input field
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Loader, Button } from 'semantic-ui-react';
|
import { Loader, Button } from 'semantic-ui-react';
|
||||||
import 'react-table/react-table.css';
|
import 'react-table/react-table.css';
|
||||||
|
import './style.css';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
|
|
||||||
import SelectTable from "../../SelectTable";
|
import SelectTable from "../../SelectTable";
|
||||||
@@ -12,7 +13,8 @@ import {
|
|||||||
incidentDescriptions,
|
incidentDescriptions,
|
||||||
incidentLevelDescriptions,
|
incidentLevelDescriptions,
|
||||||
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
||||||
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
|
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, BOOKING_CANCELED_LATE, BOOKING_MOVED_TO_ANOTHER_DAY,
|
||||||
|
BOOKING_SHORTENED
|
||||||
} from '../../../constants/enums';
|
} from '../../../constants/enums';
|
||||||
import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
|
import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
|
||||||
import { deleteIncidents } from "../../../store/actions";
|
import { deleteIncidents } from "../../../store/actions";
|
||||||
@@ -21,7 +23,11 @@ class SingleIncidentsTable extends Component {
|
|||||||
state = {
|
state = {
|
||||||
selectedUnlockedIncidentIds: [],
|
selectedUnlockedIncidentIds: [],
|
||||||
selectedUnscheduledIncidentIds: [],
|
selectedUnscheduledIncidentIds: [],
|
||||||
selectedBookingChangeIncidentIds: []
|
selectedBookingChangeIncidentIds: [],
|
||||||
|
changedUnlockedIncidentIds: {},
|
||||||
|
changedUnscheduledIncidentIds: {},
|
||||||
|
changedBookingChangeIncidentIds: {},
|
||||||
|
inputIdToFocus: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectChange = (selectedIncidents) => {
|
onSelectChange = (selectedIncidents) => {
|
||||||
@@ -94,12 +100,33 @@ class SingleIncidentsTable extends Component {
|
|||||||
const {
|
const {
|
||||||
selectedUnlockedIncidentIds,
|
selectedUnlockedIncidentIds,
|
||||||
selectedUnscheduledIncidentIds,
|
selectedUnscheduledIncidentIds,
|
||||||
selectedBookingChangeIncidentIds
|
selectedBookingChangeIncidentIds,
|
||||||
|
changedUnlockedIncidentIds,
|
||||||
|
changedUnscheduledIncidentIds,
|
||||||
|
changedBookingChangeIncidentIds,
|
||||||
|
inputIdToFocus
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
|
const changedIncidentsProxy = {
|
||||||
|
[UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION]: changedUnlockedIncidentIds,
|
||||||
|
[UNLOCKED_INCIDENT_STANDALONE]: changedUnlockedIncidentIds,
|
||||||
|
[UNSCHEDULED_INCIDENT_BEFORE_RESERVATION]: changedUnscheduledIncidentIds,
|
||||||
|
[UNSCHEDULED_INCIDENT_AFTER_RESERVATION]: changedUnscheduledIncidentIds,
|
||||||
|
[UNSCHEDULED_INCIDENT_STANDALONE]: changedUnscheduledIncidentIds,
|
||||||
|
[BOOKING_SHORTENED]: changedBookingChangeIncidentIds,
|
||||||
|
[BOOKING_MOVED_TO_ANOTHER_DAY]: changedBookingChangeIncidentIds,
|
||||||
|
[BOOKING_CANCELED_LATE]: changedBookingChangeIncidentIds
|
||||||
|
};
|
||||||
|
|
||||||
const totalSelected = selectedUnlockedIncidentIds.length + selectedUnscheduledIncidentIds.length + selectedBookingChangeIncidentIds.length;
|
const totalSelected = selectedUnlockedIncidentIds.length + selectedUnscheduledIncidentIds.length + selectedBookingChangeIncidentIds.length;
|
||||||
const numberOfSelectedText = totalSelected > 0 ? ` (${totalSelected})` : '';
|
const numberOfSelectedText = totalSelected > 0 ? ` (${totalSelected})` : '';
|
||||||
|
|
||||||
|
const totalChanged =
|
||||||
|
Object.keys(changedUnlockedIncidentIds).length +
|
||||||
|
Object.keys(changedUnscheduledIncidentIds).length +
|
||||||
|
Object.keys(changedBookingChangeIncidentIds).length;
|
||||||
|
const numberOfChangedText = totalChanged > 0 ? ` (${totalChanged})` : '';
|
||||||
|
|
||||||
const incidents = this.props.incidents ? this.props.incidents : [];
|
const incidents = this.props.incidents ? this.props.incidents : [];
|
||||||
incidents.forEach(incident => {
|
incidents.forEach(incident => {
|
||||||
incident.id = `${incident.incidentType}-${incident.incidentId}`;
|
incident.id = `${incident.incidentType}-${incident.incidentId}`;
|
||||||
@@ -122,6 +149,44 @@ class SingleIncidentsTable extends Component {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const priceChangeHandler = (element) => {
|
||||||
|
if (element && element.target){
|
||||||
|
const {value: newValue, id: incidentDescriptionID} = element.target;
|
||||||
|
const newValueFloat = parseFloat(newValue);
|
||||||
|
const incidentData = incidentDescriptionID.split('-');
|
||||||
|
const incidentType = parseInt(incidentData[0]) || null;
|
||||||
|
const incidentID = parseInt(incidentData[1]) || null;
|
||||||
|
|
||||||
|
if ((newValueFloat || (newValueFloat === 0)) && incidentType && incidentID){
|
||||||
|
const changedUnlockedIncidentIdsCopy = Object.assign({}, changedUnlockedIncidentIds);
|
||||||
|
const changedUnscheduledIncidentIdsCopy = Object.assign({}, changedUnscheduledIncidentIds);
|
||||||
|
const changedBookingChangeIncidentIdsCopy = Object.assign({}, changedBookingChangeIncidentIds);
|
||||||
|
|
||||||
|
switch (incidentType) {
|
||||||
|
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
||||||
|
case UNLOCKED_INCIDENT_STANDALONE:
|
||||||
|
changedUnlockedIncidentIdsCopy[incidentID] = newValueFloat;
|
||||||
|
this.setState({changedUnlockedIncidentIds: changedUnlockedIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_STANDALONE:
|
||||||
|
changedUnscheduledIncidentIdsCopy[incidentID] = newValueFloat;
|
||||||
|
this.setState({changedUnscheduledIncidentIds: changedUnscheduledIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BOOKING_MOVED_TO_ANOTHER_DAY:
|
||||||
|
case BOOKING_SHORTENED:
|
||||||
|
case BOOKING_CANCELED_LATE:
|
||||||
|
changedBookingChangeIncidentIdsCopy[incidentID] = newValueFloat;
|
||||||
|
this.setState({changedBookingChangeIncidentIds: changedBookingChangeIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
tableHeaders.forEach((header) => {
|
tableHeaders.forEach((header) => {
|
||||||
const columnTitle = incidentsReportHeaderTitles[header];
|
const columnTitle = incidentsReportHeaderTitles[header];
|
||||||
|
|
||||||
@@ -143,6 +208,10 @@ class SingleIncidentsTable extends Component {
|
|||||||
Cell: props => {
|
Cell: props => {
|
||||||
let cellValue = '';
|
let cellValue = '';
|
||||||
let urlValue = undefined;
|
let urlValue = undefined;
|
||||||
|
let clickablePrice = undefined;
|
||||||
|
let priceAsNumber = undefined;
|
||||||
|
let priceInputID = undefined;
|
||||||
|
let priceFontColor = 'black';
|
||||||
|
|
||||||
switch (props.column.id) {
|
switch (props.column.id) {
|
||||||
case 'memberName':
|
case 'memberName':
|
||||||
@@ -198,8 +267,18 @@ class SingleIncidentsTable extends Component {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'totalChargeFee':
|
case 'totalChargeFee':
|
||||||
const totalFee = (props.row['_original'].incidentPrice || props.value) || 0;
|
clickablePrice = true;
|
||||||
|
let totalFee = 0;
|
||||||
|
const changedFee = changedIncidentsProxy[props.row['_original'].incidentType][props.row['_original'].incidentId];
|
||||||
|
if (changedFee || (changedFee === 0)){
|
||||||
|
totalFee = changedFee;
|
||||||
|
priceFontColor = 'red';
|
||||||
|
}else{
|
||||||
|
totalFee = (props.row['_original'].incidentPrice || props.value) || 0;
|
||||||
|
}
|
||||||
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
|
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
|
||||||
|
priceAsNumber = totalFee;
|
||||||
|
priceInputID = `${props.row['_original'].incidentType || ''}-${props.row['_original'].incidentId || ''}`;
|
||||||
cellValue = `$ ${totalFeeFormatted}`;
|
cellValue = `$ ${totalFeeFormatted}`;
|
||||||
columnContentsAlignment = columnAlignments.right;
|
columnContentsAlignment = columnAlignments.right;
|
||||||
break;
|
break;
|
||||||
@@ -217,10 +296,22 @@ class SingleIncidentsTable extends Component {
|
|||||||
cellValue = props.value;
|
cellValue = props.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openMemberSummaryOnMemberClick && urlValue){
|
if (clickablePrice){
|
||||||
return <NavLink to={urlValue}>{cellValue}</NavLink>
|
return <p>$ <input
|
||||||
|
id={priceInputID}
|
||||||
|
style={{ color: priceFontColor }}
|
||||||
|
type={'number'}
|
||||||
|
onChange={priceChangeHandler}
|
||||||
|
defaultValue={priceAsNumber}
|
||||||
|
autoFocus={priceInputID === inputIdToFocus}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
}else{
|
}else{
|
||||||
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
|
if (openMemberSummaryOnMemberClick && urlValue){
|
||||||
|
return <NavLink to={urlValue}>{cellValue}</NavLink>
|
||||||
|
}else{
|
||||||
|
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -235,6 +326,9 @@ class SingleIncidentsTable extends Component {
|
|||||||
{
|
{
|
||||||
<Button disabled={loading || totalSelected === 0} onClick={this.deleteSelectedFees}>{`Delete selected ${numberOfSelectedText}`}</Button>
|
<Button disabled={loading || totalSelected === 0} onClick={this.deleteSelectedFees}>{`Delete selected ${numberOfSelectedText}`}</Button>
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
<Button disabled={loading || totalChanged === 0}>{`Save changed ${numberOfChangedText}`}</Button>
|
||||||
|
}
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
{
|
{
|
||||||
!loading && incidents &&
|
!loading && incidents &&
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
::placeholder{
|
||||||
|
color: black;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user