Fixed column names and the report

This commit is contained in:
Senad Uka
2019-07-07 07:02:42 +02:00
parent 2fcb10522c
commit 1e1c61882f
16 changed files with 455 additions and 115 deletions

View File

@@ -0,0 +1,119 @@
import React from 'react';
import { Loader } from 'semantic-ui-react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { NavLink } from 'react-router-dom';
import {incidentsReportHeaderTitles} from '../../../constants/menuItems';
import {
incidentDescriptions,
incidentLevelDescriptions,
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
} from '../../../constants/enums';
const SingleIncidentsTable = props => {
const { loading, title, openMemberSummaryOnMemberClick, showBookingTimes, showDoorLockEntryTimes, hideMemberName } = props;
const incidents = props.incidents ? props.incidents : [];
const columns = [];
if (incidents && incidents.length > 0){
const incidentHeaders = Object.keys(incidentsReportHeaderTitles);
incidentHeaders.forEach((header) => {
const columnTitle = incidentsReportHeaderTitles[header];
let showColumn = true;
if ((header === 'bookingStart' || header === 'bookingEnd') && !showBookingTimes){
showColumn = false;
}
if ((header === 'unlockTimestamp' || header === 'lockTimestamp') && !showDoorLockEntryTimes){
showColumn = false;
}
if (header === 'memberName' && hideMemberName){
showColumn = false;
}
if (columnTitle && showColumn){
const columnAlignments = {
left: 'left',
right: 'right',
};
let columnContentsAlignment = columnAlignments.left;
columns.push({
Header: incidentsReportHeaderTitles[header],
accessor: header,
Cell: props => {
let cellValue = '';
let urlValue = undefined;
switch (props.column.id) {
case 'memberName':
const memberId = props.row['_original'].memberId;
urlValue = `/practice-summary-report/${memberId}`;
cellValue = props.value;
break;
case 'incidentType':
cellValue = incidentDescriptions[props.value];
break;
case 'incidentLevel':
cellValue = incidentLevelDescriptions[props.value];
break;
case 'feeDescription':
const { incidentType, incidentLevel, timeIntervalsToCharge } = props.row['_original'];
switch (incidentType) {
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
case UNLOCKED_INCIDENT_STANDALONE:
cellValue = `${incidentLevelDescriptions[incidentLevel]}`;
break;
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
case UNSCHEDULED_INCIDENT_STANDALONE:
cellValue = `${timeIntervalsToCharge} x 5 min`;
break;
default:
cellValue = '';
break;
}
break;
case 'totalChargeFee':
const totalFee = props.value ? props.value : props.row['_original'].incidentPrice;
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
cellValue = `$ ${totalFeeFormatted}`;
columnContentsAlignment = columnAlignments.right;
break;
default:
cellValue = props.value;
}
if (openMemberSummaryOnMemberClick && urlValue){
return <NavLink to={urlValue}>{cellValue}</NavLink>
}else{
return <div style={{ textAlign: columnContentsAlignment }}>{cellValue}</div>
}
}
});
}
});
}
return (
<div>
<h4>{title}</h4>
<Loader active={loading} />
{
!loading && incidents &&
<ReactTable
data={incidents}
multiSort={false}
columns={columns}
/>
}
</div>
);
};
export default SingleIncidentsTable;

View File

@@ -0,0 +1,78 @@
import React from 'react';
import {Accordion, Label} from 'semantic-ui-react';
import SingleIncidentsTable from './components/SingleIncidentsTable';
import {
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
} from '../../constants/enums';
export default function MemberIncidentsTables (props) {
const { pendingIncidents, incidents, hideMemberName } = props;
const incidentsRelatedToReservations = [];
const standaloneIncidents = [];
if (Array.isArray(incidents)){
incidents.forEach((incident) => {
if (incident && incident.incidentType){
switch (incident.incidentType) {
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
incidentsRelatedToReservations.push(incident);
break;
case UNLOCKED_INCIDENT_STANDALONE:
case UNSCHEDULED_INCIDENT_STANDALONE:
standaloneIncidents.push(incident);
break;
}
}
});
}
const incidentsRelatedToReservationsTable = (
<SingleIncidentsTable
loading={pendingIncidents}
incidents={incidentsRelatedToReservations}
openMemberSummaryOnMemberClick
showBookingTimes
hideMemberName={hideMemberName}
/>
);
const standaloneIncidentsTable = (
<SingleIncidentsTable
loading={pendingIncidents}
incidents={standaloneIncidents}
openMemberSummaryOnMemberClick
showDoorLockEntryTimes
hideMemberName={hideMemberName}
/>
);
const accordionPanels = [
{
key: 'related-door-lock-incidents',
title : { content: <Label color='blue' content={'Door Lock Charges - Related to reservations'} /> },
content: { content : incidentsRelatedToReservationsTable },
},
{
key: 'standalone-door-lock-incidents',
title : { content: <Label color='blue' content={'Door Lock Charges - Standalone'} /> },
content: { content: standaloneIncidentsTable },
},
{
key: 'reservation-modification-incidents',
title: {content: <Label color='blue' content={'Cancellation charges'}/>},
}
];
return (
<Accordion
panels={accordionPanels}
exclusive={false}
defaultActiveIndex={[0]}
fluid
/>
);
}

View File

@@ -1,10 +1,16 @@
export const UNLOCKED_INCIDENT = 2;
export const UNSCHEDULED_INCIDENT = 3;
export const UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION = 2;
export const UNSCHEDULED_INCIDENT_BEFORE_RESERVATION = 3;
export const UNSCHEDULED_INCIDENT_AFTER_RESERVATION = 4;
export const UNLOCKED_INCIDENT_STANDALONE = 5;
export const UNSCHEDULED_INCIDENT_STANDALONE = 6;
export const incidentDescriptions = {};
incidentDescriptions[UNLOCKED_INCIDENT] = 'User left door unlocked';
incidentDescriptions[UNSCHEDULED_INCIDENT] = 'Unscheduled use';
incidentDescriptions[UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION] = 'User left door unlocked';
incidentDescriptions[UNSCHEDULED_INCIDENT_BEFORE_RESERVATION] = 'Unscheduled use - before';
incidentDescriptions[UNSCHEDULED_INCIDENT_AFTER_RESERVATION] = 'Unscheduled use - after';
incidentDescriptions[UNLOCKED_INCIDENT_STANDALONE] = 'User left door unlocked';
incidentDescriptions[UNSCHEDULED_INCIDENT_STANDALONE] = 'Unscheduled use';
export const incidentLevelDescriptions = {
UNLOCKED_0: 'First month',
@@ -13,5 +19,4 @@ export const incidentLevelDescriptions = {
UNLOCKED_3: 'Fourth month',
UNLOCKED_4: 'Fifth month',
UNLOCKED_5: 'Sixth month',
};

View File

@@ -45,6 +45,8 @@ export const incidentsReportHeaderTitles = {
resourceName: 'Room',
bookingStart: 'Reservation Start',
bookingEnd: 'Reservation End',
unlockTimestamp: 'Unlock Time',
lockTimestamp: 'Lock Time',
memberName: 'Member Name',
incidentType: 'Incident Type',
feeDescription: 'Fee description',

View File

@@ -4,7 +4,7 @@ import { Container } from 'semantic-ui-react';
import MainMenu from '../../components/MainMenu';
import DateRangePicker from '../../components/DateRangePicker';
import MemberIncidentsTable from '../../components/MemberIncidentsTable';
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
import { fetchIncidents } from '../../store/actions';
@@ -24,7 +24,7 @@ class IncidentsReport extends Component {
<hr/>
<DateRangePicker buttonLabel="Show report" onDatesUpdate={this.onDatesUpdate.bind(this)} />
<br/>
<MemberIncidentsTable loading={pendingIncidents} incidents={incidents} openMemberSummaryOnMemberClick />
<MemberIncidentsTables pendingIncidents={pendingIncidents} incidents={incidents} />
</Container>
);
}

View File

@@ -22,7 +22,7 @@ class MemberSelector extends Component {
}
render(){
const { members } = this.props;
const { members, defaultMemberId } = this.props;
const dropdownOptions = members && Array.isArray(members) ? members.map(member => ({
key: member.memberId,
@@ -41,6 +41,7 @@ class MemberSelector extends Component {
search
fluid
onChange={this.onMemberSelectionChange.bind(this)}
value={defaultMemberId ? defaultMemberId : null}
/>
</Form>
);

View File

@@ -1,7 +1,11 @@
import React from 'react';
import { Loader, Grid } from 'semantic-ui-react';
import { UNSCHEDULED_INCIDENT, UNLOCKED_INCIDENT } from '../../../constants/enums';
import {
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION,
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
UNSCHEDULED_INCIDENT_AFTER_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, UNLOCKED_INCIDENT_STANDALONE
} from '../../../constants/enums';
const MemberSummary = props => {
const { loading } = props;
@@ -12,10 +16,13 @@ const MemberSummary = props => {
incidents.forEach((incident) => {
switch (incident.incidentType) {
case UNSCHEDULED_INCIDENT:
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
case UNSCHEDULED_INCIDENT_STANDALONE:
totalUnscheduledFees += parseFloat(incident.totalChargeFee);
break;
case UNLOCKED_INCIDENT:
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
case UNLOCKED_INCIDENT_STANDALONE:
totalUnlockedFees += parseFloat(incident.incidentPrice);
break;
default:

View File

@@ -6,7 +6,7 @@ import MainMenu from '../../components/MainMenu';
import DateRangePicker from '../../components/DateRangePicker';
import MemberSelector from './components/MemberSelector';
import MemberSummary from './components/MemberSummary';
import MemberIncidentsTable from '../../components/MemberIncidentsTable';
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
import { fetchMemberIncidents } from '../../store/actions';
@@ -40,6 +40,7 @@ class PracticeSummaryReport extends Component {
render () {
const { memberIncidents, loading } = this.props;
const { memberId } = this.state;
return (
<Container>
@@ -49,7 +50,7 @@ class PracticeSummaryReport extends Component {
<Grid stackable columns="equal">
<Grid.Row>
<Grid.Column>
<MemberSelector onMemberSelect={this.onMemberSelectionUpdate.bind(this)} />
<MemberSelector onMemberSelect={this.onMemberSelectionUpdate.bind(this)} defaultMemberId={memberId} />
</Grid.Column>
<Grid.Column>
<DateRangePicker inlineButton onDatesUpdate={this.onDateRangeUpdate.bind(this)}/>
@@ -66,11 +67,7 @@ class PracticeSummaryReport extends Component {
<Grid.Row/>
<Grid.Row>
<Grid.Column>
<MemberIncidentsTable
title="Detail list"
incidents={memberIncidents}
loading={loading}
/>
<MemberIncidentsTables incidents={memberIncidents} pendingIncidents={loading} hideMemberName/>
</Grid.Column>
</Grid.Row>
</Grid>