@plusscommunities/pluss-maintenance-app 6.0.11 → 6.0.12-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/module/actions/JobActions.js +44 -1
  2. package/dist/module/actions/JobActions.js.map +1 -1
  3. package/dist/module/actions/types.js +3 -0
  4. package/dist/module/actions/types.js.map +1 -1
  5. package/dist/module/apis/index.js +2 -0
  6. package/dist/module/apis/index.js.map +1 -1
  7. package/dist/module/apis/maintenanceActions.js +21 -6
  8. package/dist/module/apis/maintenanceActions.js.map +1 -1
  9. package/dist/module/components/FilterPopupMenu.js +34 -18
  10. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  11. package/dist/module/components/MaintenanceList.js +47 -56
  12. package/dist/module/components/MaintenanceList.js.map +1 -1
  13. package/dist/module/components/MaintenanceListItem.js +39 -26
  14. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  15. package/dist/module/components/MaintenanceWidgetItem.js +12 -12
  16. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  17. package/dist/module/components/PrioritySelectorPopup.js +82 -0
  18. package/dist/module/components/PrioritySelectorPopup.js.map +1 -0
  19. package/dist/module/components/StatusSelectorPopup.js +9 -14
  20. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  21. package/dist/module/components/WidgetSmall.js +7 -3
  22. package/dist/module/components/WidgetSmall.js.map +1 -1
  23. package/dist/module/helper.js +39 -25
  24. package/dist/module/helper.js.map +1 -1
  25. package/dist/module/reducers/JobsReducer.js +31 -2
  26. package/dist/module/reducers/JobsReducer.js.map +1 -1
  27. package/dist/module/screens/RequestDetail.js +90 -18
  28. package/dist/module/screens/RequestDetail.js.map +1 -1
  29. package/dist/module/screens/RequestNotes.js +335 -19
  30. package/dist/module/screens/RequestNotes.js.map +1 -1
  31. package/dist/module/values.config.a.js +6 -1
  32. package/dist/module/values.config.a.js.map +1 -1
  33. package/dist/module/values.config.default.js +6 -1
  34. package/dist/module/values.config.default.js.map +1 -1
  35. package/dist/module/values.config.forms.js +6 -1
  36. package/dist/module/values.config.forms.js.map +1 -1
  37. package/dist/module/values.config.js +6 -1
  38. package/dist/module/values.config.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/actions/JobActions.js +53 -1
  41. package/src/actions/types.js +4 -0
  42. package/src/apis/index.js +4 -0
  43. package/src/apis/maintenanceActions.js +18 -6
  44. package/src/components/FilterPopupMenu.js +40 -21
  45. package/src/components/MaintenanceList.js +38 -47
  46. package/src/components/MaintenanceListItem.js +35 -21
  47. package/src/components/MaintenanceWidgetItem.js +16 -12
  48. package/src/components/PrioritySelectorPopup.js +79 -0
  49. package/src/components/StatusSelectorPopup.js +8 -14
  50. package/src/components/WidgetSmall.js +5 -3
  51. package/src/helper.js +50 -21
  52. package/src/reducers/JobsReducer.js +25 -1
  53. package/src/screens/RequestDetail.js +89 -26
  54. package/src/screens/RequestNotes.js +348 -28
  55. package/src/values.config.a.js +5 -0
  56. package/src/values.config.default.js +5 -0
  57. package/src/values.config.forms.js +5 -0
  58. package/src/values.config.js +5 -0
@@ -4,19 +4,7 @@ import _ from 'lodash';
4
4
  import { Icon } from 'react-native-elements';
5
5
  import { connect } from 'react-redux';
6
6
  import moment from 'moment';
7
- // import {
8
- // getShadowStyle,
9
- // LINEGREY,
10
- // TEXT_DARK,
11
- // TEXT_LIGHT,
12
- // COLOUR_GREEN,
13
- // getMainBrandingColourFromState,
14
- // hexToRGBAstring,
15
- // getJobStatusProps,
16
- // jobStatusOptions,
17
- // } from '../../js';
18
- // import NavigationService from '../../js/NavigationService';
19
- import { getJobStatusProps, jobStatusOptions } from '../helper';
7
+ import { getJobStatus, getJobPriority } from '../helper';
20
8
  import { Services } from '../feature.config';
21
9
  import { Helper, Colours } from '../core.config';
22
10
  import { values } from '../values.config';
@@ -47,9 +35,9 @@ class MaintenanceListItem extends Component {
47
35
  }
48
36
 
49
37
  renderSeen() {
50
- const { job } = this.props;
51
- const showSeen = !job.status || job.status === jobStatusOptions[0].name;
52
- if (!showSeen || !job.seen) {
38
+ const { job, hideSeen } = this.props;
39
+ const showSeen = !job.status || job.status === getJobStatus(null, this.props).text;
40
+ if (hideSeen || !showSeen || !job.seen) {
53
41
  return null;
54
42
  }
55
43
  return (
@@ -65,7 +53,9 @@ class MaintenanceListItem extends Component {
65
53
  const createdTime = moment(job.createdUnix);
66
54
  const createdTimeText = `${createdTime.format('ddd, D MMMM')} • ${createdTime.format('h:mma')}`;
67
55
  const assigneeText = job.Assignee ? `Assigned to\n${job.Assignee.displayName}` : '';
68
- const { statusText, statusColor } = getJobStatusProps(job.status);
56
+ const status = getJobStatus(job.status, this.props);
57
+ const priority = getJobPriority(job.priority);
58
+ const isStaff = this.props.user.category === 'staff'
69
59
 
70
60
  return (
71
61
  <TouchableOpacity onPress={this.onPressJob}>
@@ -98,16 +88,21 @@ class MaintenanceListItem extends Component {
98
88
  {/* {this.renderDescription()} */}
99
89
  <Text style={styles.jobCreatedText}>{createdTimeText}</Text>
100
90
  <View style={styles.jobActivityContainer}>
101
- <View style={[styles.jobStatusContainer, { backgroundColor: statusColor }]}>
91
+ <View style={[styles.jobStatusContainer, { backgroundColor: status?.color }]}>
102
92
  {/* <Icon name="wrench" type="font-awesome" iconStyle={styles.jobStatusIcon} /> */}
103
- <Text style={styles.jobStatusText}>{statusText}</Text>
93
+ <Text style={styles.jobStatusText}>{status?.text}</Text>
104
94
  </View>
105
- <View style={[styles.jobStatusLine, { borderColor: statusColor }]}>
95
+ <View style={[styles.jobStatusLine, { borderColor: status?.color }]}>
106
96
  <View style={styles.jobStatusLineMask} />
107
97
  </View>
108
- <View style={[styles.jobStatusCircle, { backgroundColor: statusColor }]} />
98
+ <View style={[styles.jobStatusCircle, { backgroundColor: status?.color }]} />
109
99
  <Text style={styles.jobStatusDateText}>{assigneeText}</Text>
110
100
  </View>
101
+ {isStaff && (
102
+ <View style={[styles.jobPriorityContainer, { backgroundColor: priority.color }]}>
103
+ <Text style={styles.jobPriorityText}>{priority.label}</Text>
104
+ </View>
105
+ )}
111
106
  </View>
112
107
  </View>
113
108
  </View>
@@ -278,11 +273,30 @@ const styles = StyleSheet.create({
278
273
  fontSize: 14,
279
274
  color: Colours.TEXT_DARK,
280
275
  },
276
+ jobPriorityContainer: {
277
+ flexDirection: 'row',
278
+ alignItems: 'center',
279
+ justifyContent: 'center',
280
+ width: 105,
281
+ height: 24,
282
+ paddingHorizontal: 8,
283
+ borderRadius: 4,
284
+ marginTop: 8,
285
+ },
286
+ jobPriorityText: {
287
+ color: '#fff',
288
+ textAlign: 'center',
289
+ fontFamily: 'sf-semibold',
290
+ fontSize: 13,
291
+ },
281
292
  });
282
293
 
283
294
  const mapStateToProps = state => {
284
295
  return {
296
+ user: state.user,
285
297
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
298
+ statusTypes: state[values.reducerKey].jobstatuses,
299
+ hideSeen: state[values.reducerKey].hideSeen,
286
300
  };
287
301
  };
288
302
 
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
4
4
  import { Icon } from 'react-native-elements';
5
5
  import moment from 'moment';
6
6
  import _ from 'lodash';
7
- import { getJobStatusProps, jobStatusOptions } from '../helper';
7
+ import { getJobStatus } from '../helper';
8
8
  import { Services } from '../feature.config';
9
9
  import { Colours, Helper } from '../core.config';
10
10
  import { values } from '../values.config';
@@ -15,12 +15,12 @@ class MaintenanceWidgetItem extends Component {
15
15
  };
16
16
 
17
17
  render() {
18
- const { job } = this.props;
18
+ const { job, hideSeen } = this.props;
19
19
  const createdTime = moment(job.createdUnix);
20
20
  const createdTimeText = `${createdTime.format('ddd, D MMMM')} • ${createdTime.format('h:mma')}`;
21
- const { statusText, statusColor } = getJobStatusProps(job.status);
21
+ const status = getJobStatus(job.status, this.props);
22
22
  const seenText = (() => {
23
- if (!job.status || job.status === jobStatusOptions[0].name) {
23
+ if (!job.status || job.status === getJobStatus(null, this.props).text) {
24
24
  return job.seen ? 'Seen' : 'Unseen';
25
25
  }
26
26
  return '';
@@ -35,17 +35,19 @@ class MaintenanceWidgetItem extends Component {
35
35
  {job.title}
36
36
  </Text>
37
37
  <Text style={styles.jobCreatedTimeText}>{createdTimeText}</Text>
38
- <View style={styles.jobSeenContainer}>
39
- {job.seen && !_.isEmpty(seenText) && (
40
- <Icon name="check" type="font-awesome" iconStyle={[styles.jobSeenIcon, { color: this.props.colourBrandingMain }]} />
41
- )}
42
- <Text style={[styles.jobSeenText, job.seen && { color: this.props.colourBrandingMain }]}>{seenText}</Text>
43
- </View>
38
+ {!hideSeen ? (
39
+ <View style={styles.jobSeenContainer}>
40
+ {job.seen && !_.isEmpty(seenText) && (
41
+ <Icon name="check" type="font-awesome" iconStyle={[styles.jobSeenIcon, { color: this.props.colourBrandingMain }]} />
42
+ )}
43
+ <Text style={[styles.jobSeenText, job.seen && { color: this.props.colourBrandingMain }]}>{seenText}</Text>
44
+ </View>
45
+ ) : null}
44
46
  </View>
45
47
  <View style={styles.jobBottomSection}>
46
- <View style={[styles.jobStatusContainer, { backgroundColor: statusColor }]}>
48
+ <View style={[styles.jobStatusContainer, { backgroundColor: status?.color }]}>
47
49
  {/* <Icon name="wrench" type="font-awesome" iconStyle={styles.jobStatusIcon} /> */}
48
- <Text style={styles.jobStatusText}>{statusText}</Text>
50
+ <Text style={styles.jobStatusText}>{status?.text}</Text>
49
51
  </View>
50
52
  </View>
51
53
  </View>
@@ -126,6 +128,8 @@ const styles = StyleSheet.create({
126
128
  const mapStateToProps = state => {
127
129
  return {
128
130
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
131
+ statusTypes: state[values.reducerKey].jobstatuses,
132
+ hideSeen: state[values.reducerKey].hideSeen,
129
133
  };
130
134
  };
131
135
 
@@ -0,0 +1,79 @@
1
+ import React, { PureComponent } from 'react';
2
+ import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
3
+ import { connect } from 'react-redux';
4
+ import { jobPriorityOptions } from '../helper';
5
+ import { Components, Colours } from '../core.config';
6
+
7
+ class PrioritySelectorPopup extends PureComponent {
8
+ render() {
9
+ const { title, includeAll, allText, onClose, onSelect } = this.props;
10
+ let priorities = jobPriorityOptions;
11
+ if (includeAll)
12
+ priorities = [
13
+ {
14
+ label: allText || 'Show All',
15
+ color: this.props.colourBrandingMain,
16
+ },
17
+ ...priorities,
18
+ ];
19
+
20
+ return (
21
+ <Components.MiddlePopup style={[styles.statusPopup, { height: priorities.length * 50 + 40 }]} onClose={onClose}>
22
+ <Text style={styles.statusPopupTitle}>{title || 'Select Priority'}</Text>
23
+ <View style={styles.statusPopupOptionsContainer}>
24
+ {priorities.map(priority => {
25
+ return (
26
+ <TouchableOpacity key={priority.label} onPress={() => onSelect(priority.label)}>
27
+ <View style={[styles.jobStatusContainer, { backgroundColor: priority.color }]}>
28
+ <Text style={styles.jobStatusText}>{priority.label}</Text>
29
+ </View>
30
+ </TouchableOpacity>
31
+ );
32
+ })}
33
+ </View>
34
+ </Components.MiddlePopup>
35
+ );
36
+ }
37
+ }
38
+
39
+ const styles = StyleSheet.create({
40
+ statusPopup: {
41
+ width: 160,
42
+ padding: 16,
43
+ borderRadius: 12,
44
+ },
45
+ statusPopupTitle: {
46
+ fontFamily: 'sf-bold',
47
+ color: Colours.TEXT_DARK,
48
+ fontSize: 18,
49
+ marginBottom: 16,
50
+ },
51
+ statusPopupOptionsContainer: {
52
+ flex: 1,
53
+ justifyContent: 'space-between',
54
+ },
55
+ jobStatusContainer: {
56
+ flexDirection: 'row',
57
+ alignItems: 'center',
58
+ justifyContent: 'space-between',
59
+ width: 105,
60
+ height: 30,
61
+ paddingHorizontal: 8,
62
+ borderRadius: 4,
63
+ },
64
+ jobStatusText: {
65
+ color: '#fff',
66
+ textAlign: 'center',
67
+ fontFamily: 'sf-semibold',
68
+ fontSize: 13,
69
+ flex: 1,
70
+ },
71
+ });
72
+
73
+ const mapStateToProps = state => {
74
+ return {
75
+ colourBrandingMain: Colours.getMainBrandingColourFromState(state),
76
+ };
77
+ };
78
+
79
+ export default connect(mapStateToProps, {})(PrioritySelectorPopup);
@@ -1,25 +1,18 @@
1
1
  import React, { PureComponent } from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
3
3
  import { connect } from 'react-redux';
4
- import { jobStatusOptions, getJobStatusColour } from '../helper';
4
+ import { getJobStatusOptions } from '../helper';
5
5
  import { Components, Colours } from '../core.config';
6
+ import { values } from '../values.config';
6
7
 
7
8
  class StatusSelectorPopup extends PureComponent {
8
9
  render() {
9
- const { title, filter, includeAll, allText, onClose, onSelect } = this.props;
10
- let statuses = filter
11
- ? filter.map(status => {
12
- return {
13
- name: status,
14
- label: getJobStatusLabel(status),
15
- color: getJobStatusColour(status),
16
- };
17
- })
18
- : jobStatusOptions;
10
+ const { title, includeAll, allText, onClose, onSelect } = this.props;
11
+ let statuses = getJobStatusOptions(this.props);
19
12
  if (includeAll)
20
13
  statuses = [
21
14
  {
22
- name: allText || 'Show All',
15
+ text: allText || 'Show All',
23
16
  color: this.props.colourBrandingMain,
24
17
  },
25
18
  ...statuses,
@@ -31,9 +24,9 @@ class StatusSelectorPopup extends PureComponent {
31
24
  <View style={styles.statusPopupOptionsContainer}>
32
25
  {statuses.map(status => {
33
26
  return (
34
- <TouchableOpacity key={status.name} onPress={() => onSelect(status.name)}>
27
+ <TouchableOpacity key={status.text} onPress={() => onSelect(status.text)}>
35
28
  <View style={[styles.jobStatusContainer, { backgroundColor: status.color }]}>
36
- <Text style={styles.jobStatusText}>{status.label}</Text>
29
+ <Text style={styles.jobStatusText}>{status.text}</Text>
37
30
  </View>
38
31
  </TouchableOpacity>
39
32
  );
@@ -81,6 +74,7 @@ const styles = StyleSheet.create({
81
74
  const mapStateToProps = state => {
82
75
  return {
83
76
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
77
+ statusTypes: state[values.reducerKey].jobstatuses,
84
78
  };
85
79
  };
86
80
 
@@ -3,10 +3,10 @@ import { Text, View, ScrollView, StyleSheet } from 'react-native';
3
3
  import { connect } from 'react-redux';
4
4
  import _ from 'lodash';
5
5
  import { maintenanceActions } from '../apis';
6
- import { jobsLoaded } from '../actions';
6
+ import { jobsLoaded, jobStatusesUpdate, jobHideSeenUpdate } from '../actions';
7
7
  import MaintenanceWidgetItem from './MaintenanceWidgetItem';
8
8
  import { Services } from '../feature.config';
9
- import { Colours, Components, Config } from '../core.config';
9
+ import { Colours, Components } from '../core.config';
10
10
  import { values } from '../values.config';
11
11
 
12
12
  const MAX_ITEMS = 10;
@@ -18,6 +18,8 @@ class WidgetSmall extends Component {
18
18
  }
19
19
 
20
20
  componentDidMount() {
21
+ this.props.jobStatusesUpdate(this.props.site);
22
+ this.props.jobHideSeenUpdate(this.props.site);
21
23
  this.refresh();
22
24
  }
23
25
 
@@ -149,4 +151,4 @@ const mapStateToProps = state => {
149
151
  };
150
152
  };
151
153
 
152
- export default connect(mapStateToProps, { jobsLoaded }, null, { forwardRef: true })(WidgetSmall);
154
+ export default connect(mapStateToProps, { jobsLoaded, jobStatusesUpdate, jobHideSeenUpdate }, null, { forwardRef: true })(WidgetSmall);
package/src/helper.js CHANGED
@@ -1,39 +1,68 @@
1
- import { label } from 'aws-amplify';
2
1
  import { Colours } from './core.config';
3
2
 
3
+ const STATUS_NOT_ACTIONED = 'Not Actioned';
4
+ const STATUS_IN_PROGRESS = 'In Progress';
5
+ const STATUS_COMPLETED = 'Completed';
6
+
4
7
  const jobStatusOptions = [
5
8
  {
6
- name: 'Unassigned',
7
- label: 'Open',
9
+ text: 'Open',
10
+ order: 0,
8
11
  color: Colours.LINEGREY,
12
+ category: STATUS_NOT_ACTIONED,
9
13
  },
10
14
  {
11
- name: 'In Progress',
12
- label: 'In Progress',
15
+ text: 'In Progress',
16
+ order: 1,
13
17
  color: Colours.COLOUR_TEAL,
18
+ category: STATUS_IN_PROGRESS,
14
19
  },
15
20
  {
16
- name: 'Completed',
17
- label: 'Completed',
21
+ text: 'Completed',
22
+ order: 2,
18
23
  color: Colours.COLOUR_GREEN_LIGHT,
24
+ category: STATUS_COMPLETED,
19
25
  },
20
26
  ];
21
27
 
22
- const getJobStatusColour = status => {
23
- const option = jobStatusOptions.find(item => item.name === status);
24
- return option ? option.color : jobStatusOptions[0].color;
25
- };
28
+ const jobPriorityOptions = [
29
+ {
30
+ label: 'Low',
31
+ color: Colours.COLOUR_GREEN,
32
+ default: true,
33
+ },
34
+ {
35
+ label: 'Medium',
36
+ color: Colours.COLOUR_TANGERINE,
37
+ },
38
+ {
39
+ label: 'High',
40
+ color: Colours.COLOUR_RED,
41
+ },
42
+ ];
26
43
 
27
- const getJobStatusLabel = status => {
28
- const option = jobStatusOptions.find(item => item.name === status);
29
- return option ? option.label : jobStatusOptions[0].label;
30
- };
44
+ const getJobStatusOptions = props => props?.statusTypes?.length ? props?.statusTypes : jobStatusOptions;
31
45
 
32
- const getJobStatusProps = status => {
33
- const statusText = getJobStatusLabel(status) || jobStatusOptions[0].label;
34
- const statusColor = getJobStatusColour(statusText);
46
+ const getDefaultJobStatuses = props => getJobStatusOptions(props).filter(s => s.category === STATUS_NOT_ACTIONED);
35
47
 
36
- return { statusText, statusColor };
37
- };
48
+ const getIncompleteJobStatuses = props => getJobStatusOptions(props).filter(s => s.category === STATUS_IN_PROGRESS);
38
49
 
39
- export { jobStatusOptions, getJobStatusColour, getJobStatusProps, getJobStatusLabel };
50
+ const getJobStatus = (status, props) => {
51
+ const statusOptions = getJobStatusOptions(props);
52
+ // console.log('getJobStatus', JSON.stringify({ status, statusOptions }, null, 2));
53
+ let statusOption = null;
54
+ if (status) statusOption = statusOptions.find(s => s.text === status);
55
+ return statusOption || getDefaultJobStatuses(props)[0];
56
+ }
57
+
58
+ const getJobPriority = priority => jobPriorityOptions.find(p => p.label === priority) || jobPriorityOptions.find(p => p.default);
59
+
60
+ export {
61
+ jobStatusOptions,
62
+ jobPriorityOptions,
63
+ getJobStatusOptions,
64
+ getDefaultJobStatuses,
65
+ getIncompleteJobStatuses,
66
+ getJobStatus,
67
+ getJobPriority,
68
+ };
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-param-reassign */
2
2
  import _ from 'lodash';
3
3
  import { REHYDRATE } from 'redux-persist';
4
- import { JOBS_LOADED, JOB_ADDED, JOBS_ADDED } from '../actions/types';
4
+ import { JOBS_LOADED, JOB_ADDED, JOBS_ADDED, JOBS_STATUSES_LOADED, JOBS_HIDE_SEEN, JOB_FILTER_LOADED } from '../actions/types';
5
5
  import { ActionTypes } from '../core.config';
6
6
  import { values } from '../values.config';
7
7
 
@@ -9,11 +9,22 @@ const REDUCER_KEY = values.reducerKey;
9
9
 
10
10
  const INITIAL_STATE = {
11
11
  jobs: [],
12
+ jobstatuses: [],
13
+ hideSeen: false,
14
+ jobfilters: {
15
+ status: '',
16
+ statusText: '',
17
+ priority: '',
18
+ type: '',
19
+ assignee: '',
20
+ assigneeName: '',
21
+ },
12
22
  };
13
23
 
14
24
  export default (state = INITIAL_STATE, action) => {
15
25
  let updateJobs = [];
16
26
  let index = 0;
27
+ let jobstatuses = [];
17
28
 
18
29
  switch (action.type) {
19
30
  case ActionTypes.LOGOUT:
@@ -36,6 +47,19 @@ export default (state = INITIAL_STATE, action) => {
36
47
  updateJobs.push(action.payload);
37
48
  }
38
49
  return { ...state, jobs: updateJobs };
50
+ case JOBS_STATUSES_LOADED:
51
+ jobstatuses = _.orderBy(
52
+ _.unionWith(action.payload, state.jobstatuses, (v1, v2) => {
53
+ return v1 != null && v2 != null && v1.text === v2.text;
54
+ }),
55
+ 'order',
56
+ 'asc',
57
+ );
58
+ return { ...state, jobstatuses };
59
+ case JOBS_HIDE_SEEN:
60
+ return { ...state, hideSeen: action.payload };
61
+ case JOB_FILTER_LOADED:
62
+ return { ...state, jobfilters: action.payload };
39
63
  case REHYDRATE:
40
64
  if (!action.payload) return state;
41
65
  if (action.payload[REDUCER_KEY]) {