@plusscommunities/pluss-maintenance-app 6.1.2-beta.0 → 7.0.0-beta.1

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 (78) 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 +3 -1
  6. package/dist/module/apis/index.js.map +1 -1
  7. package/dist/module/apis/{generalActions.js → maintenanceActions.js} +44 -45
  8. package/dist/module/apis/maintenanceActions.js.map +1 -0
  9. package/dist/module/components/FilterPopupMenu.js +78 -26
  10. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  11. package/dist/module/components/MaintenanceList.js +70 -45
  12. package/dist/module/components/MaintenanceList.js.map +1 -1
  13. package/dist/module/components/MaintenanceListItem.js +54 -42
  14. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  15. package/dist/module/components/MaintenanceWidgetItem.js +16 -20
  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 -13
  20. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  21. package/dist/module/components/WidgetSmall.js +13 -9
  22. package/dist/module/components/WidgetSmall.js.map +1 -1
  23. package/dist/module/feature.config.js +3 -3
  24. package/dist/module/feature.config.js.map +1 -1
  25. package/dist/module/helper.js +39 -17
  26. package/dist/module/helper.js.map +1 -1
  27. package/dist/module/reducers/JobsReducer.js +33 -3
  28. package/dist/module/reducers/JobsReducer.js.map +1 -1
  29. package/dist/module/screens/JobTypePicker.js +3 -3
  30. package/dist/module/screens/JobTypePicker.js.map +1 -1
  31. package/dist/module/screens/MaintenancePage.js +2 -2
  32. package/dist/module/screens/RequestDetail.js +340 -88
  33. package/dist/module/screens/RequestDetail.js.map +1 -1
  34. package/dist/module/screens/RequestNotes.js +437 -26
  35. package/dist/module/screens/RequestNotes.js.map +1 -1
  36. package/dist/module/screens/ServiceRequest.js +596 -93
  37. package/dist/module/screens/ServiceRequest.js.map +1 -1
  38. package/dist/module/values.config.a.js +9 -1
  39. package/dist/module/values.config.a.js.map +1 -1
  40. package/dist/module/values.config.default.js +15 -1
  41. package/dist/module/values.config.default.js.map +1 -1
  42. package/dist/module/values.config.forms.js +42 -0
  43. package/dist/module/values.config.forms.js.map +1 -0
  44. package/dist/module/values.config.js +34 -20
  45. package/dist/module/values.config.js.map +1 -1
  46. package/package.json +11 -11
  47. package/src/actions/JobActions.js +53 -1
  48. package/src/actions/types.js +4 -0
  49. package/src/apis/index.js +5 -1
  50. package/src/apis/{generalActions.js → maintenanceActions.js} +51 -43
  51. package/src/components/FilterPopupMenu.js +75 -24
  52. package/src/components/MaintenanceList.js +64 -33
  53. package/src/components/MaintenanceListItem.js +53 -31
  54. package/src/components/MaintenanceWidgetItem.js +18 -14
  55. package/src/components/PrioritySelectorPopup.js +79 -0
  56. package/src/components/StatusSelectorPopup.js +8 -13
  57. package/src/components/WidgetSmall.js +9 -7
  58. package/src/feature.config.js +15 -13
  59. package/src/helper.js +51 -13
  60. package/src/reducers/JobsReducer.js +27 -2
  61. package/src/screens/JobTypePicker.js +1 -1
  62. package/src/screens/RequestDetail.js +324 -75
  63. package/src/screens/RequestNotes.js +434 -33
  64. package/src/screens/ServiceRequest.js +642 -157
  65. package/src/values.config.a.js +8 -0
  66. package/src/values.config.default.js +14 -0
  67. package/src/values.config.forms.js +42 -0
  68. package/src/values.config.js +34 -20
  69. package/dist/module/apis/generalActions.js.map +0 -1
  70. package/dist/module/values.config.b.js +0 -28
  71. package/dist/module/values.config.b.js.map +0 -1
  72. package/dist/module/values.config.c.js +0 -28
  73. package/dist/module/values.config.c.js.map +0 -1
  74. package/dist/module/values.config.d.js +0 -28
  75. package/dist/module/values.config.d.js.map +0 -1
  76. package/src/values.config.b.js +0 -28
  77. package/src/values.config.c.js +0 -28
  78. package/src/values.config.d.js +0 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-maintenance-app",
3
- "version": "6.1.2-beta.0",
3
+ "version": "7.0.0-beta.1",
4
4
  "description": "Extension package to enable maintenance on Pluss Communities Platform",
5
5
  "main": "dist/module/index.js",
6
6
  "module": "dist/module/index.js",
@@ -10,7 +10,7 @@
10
10
  "src/"
11
11
  ],
12
12
  "scripts": {
13
- "build": "npm i --legacy-peer-deps && bob build",
13
+ "build": "npm i && bob build",
14
14
  "betapatch": "npm version prepatch --preid=beta",
15
15
  "patch": "npm version patch",
16
16
  "betaupload": "npm run build && npm publish --access public --tag beta",
@@ -26,19 +26,19 @@
26
26
  },
27
27
  "author": "Thorbjorn Kappel Davis",
28
28
  "license": "ISC",
29
- "dependencies": {
30
- "@plusscommunities/pluss-core-app": "^6.0.3",
29
+ "dependencies": {},
30
+ "peerDependencies": {
31
+ "@plusscommunities/pluss-core-app": "7.0.0-beta.0",
31
32
  "axios": "^1.6.8",
32
33
  "lodash": "^4.17.4",
33
34
  "moment": "^2.30.1",
34
- "react": "18.2.0",
35
- "react-native": "0.73.6",
36
- "react-native-elements": "^0.17.0",
35
+ "react": "18.3.1",
36
+ "react-native": "0.76.9",
37
+ "@rneui/base": "^4.0.0-rc.8",
38
+ "@rneui/themed": "^4.0.0-rc.8",
37
39
  "react-native-iphone-x-helper": "^1.3.1",
38
- "react-native-webview": "13.6.4",
39
- "react-redux": "^7.2.6"
40
- },
41
- "peerDependencies": {
40
+ "react-native-webview": "13.12.5",
41
+ "react-redux": "^7.2.6",
42
42
  "redux-persist": "^6.0.0"
43
43
  },
44
44
  "devDependencies": {
@@ -1,4 +1,7 @@
1
- import { JOBS_LOADED, JOB_ADDED, JOBS_ADDED } from './types';
1
+ import { JOBS_LOADED, JOB_ADDED, JOBS_ADDED, JOBS_STATUSES_LOADED, JOBS_HIDE_SEEN, JOB_FILTER_LOADED } from './types';
2
+ import { stringActions } from '../apis';
3
+ import { values } from '../values.config';
4
+ import { jobStatusOptions } from '../helper';
2
5
 
3
6
  export const jobsLoaded = jobs => {
4
7
  return {
@@ -20,3 +23,52 @@ export const jobsAdded = jobs => {
20
23
  payload: jobs,
21
24
  };
22
25
  };
26
+
27
+ export const jobStatusesUpdate = (site, callback = null) => {
28
+ return dispatch => {
29
+ stringActions
30
+ .getString(site, values.stringConfigJobStatus)
31
+ .then(res => {
32
+ dispatch({
33
+ type: JOBS_STATUSES_LOADED,
34
+ payload: res.data,
35
+ });
36
+ if (callback) callback(res.data);
37
+ })
38
+ .catch(() => {
39
+ dispatch({
40
+ type: JOBS_STATUSES_LOADED,
41
+ payload: jobStatusOptions,
42
+ });
43
+ if (callback) callback(jobStatusOptions);
44
+ });
45
+ };
46
+ };
47
+
48
+ export const jobHideSeenUpdate = (site, callback = null) => {
49
+ return (dispatch) => {
50
+ stringActions
51
+ .getString(site, values.stringConfigHideSeen)
52
+ .then((res) => {
53
+ dispatch({
54
+ type: JOBS_HIDE_SEEN,
55
+ payload: res.data,
56
+ });
57
+ if (callback) callback(res.data);
58
+ })
59
+ .catch((_error) => {
60
+ dispatch({
61
+ type: JOBS_HIDE_SEEN,
62
+ payload: false,
63
+ });
64
+ if (callback) callback(false);
65
+ });
66
+ };
67
+ };
68
+
69
+ export const jobsFilterLoaded = filters => {
70
+ return {
71
+ type: JOB_FILTER_LOADED,
72
+ payload: filters,
73
+ };
74
+ };
@@ -3,3 +3,7 @@ import { values } from '../values.config';
3
3
  export const JOBS_LOADED = values.actionJobsLoaded;
4
4
  export const JOB_ADDED = values.actionJobAdded;
5
5
  export const JOBS_ADDED = values.actionJobsAdded;
6
+ export const JOBS_STATUSES_LOADED = values.actionJobsStatusesLoaded;
7
+ export const JOBS_HIDE_SEEN = values.actionJobsHideSeen;
8
+ export const JOB_FILTER_LOADED = values.actionJobFilterLoaded;
9
+
package/src/apis/index.js CHANGED
@@ -1 +1,5 @@
1
- export * from './generalActions';
1
+ import { Apis } from '../core.config';
2
+
3
+ export const stringActions = Apis.stringActions;
4
+
5
+ export * from './maintenanceActions';
@@ -1,10 +1,7 @@
1
- // import axios from 'axios';
2
- // import { getUrl } from './helper';
3
- // import { authedFunction } from '../js';
4
1
  import { Helper, Session } from '../core.config';
5
2
  import { values } from '../values.config';
6
3
 
7
- export const generalActions = {
4
+ export const maintenanceActions = {
8
5
  getJob: (site, id) => {
9
6
  return Session.authedFunction({
10
7
  method: 'POST',
@@ -26,11 +23,14 @@ export const generalActions = {
26
23
  data: { site, status, type },
27
24
  });
28
25
  },
29
- getJobs2: (site, status, type, lastKey) => {
26
+ getJobs2: (site, status, priority, type, lastKey) => {
30
27
  const query = { site };
31
28
  if (status) {
32
29
  query.status = status;
33
30
  }
31
+ if (priority) {
32
+ query.priority = priority;
33
+ }
34
34
  if (type) {
35
35
  query.type = type;
36
36
  }
@@ -42,18 +42,32 @@ export const generalActions = {
42
42
  url: Helper.getUrl(values.serviceKey, 'get/requests', query),
43
43
  });
44
44
  },
45
- getJobsRecursive: (site, status, type, lastKey, jobs = []) => {
45
+ getJobsRecursive: (site, status, priority, type, lastKey, jobs = []) => {
46
46
  return new Promise(resolve => {
47
- generalActions.getJobs2(site, status, type, lastKey).then(jobRes => {
47
+ maintenanceActions.getJobs2(site, status, priority, type, lastKey).then(jobRes => {
48
48
  const newJobs = [...jobs, ...jobRes.data.Items];
49
49
  if (!jobRes.data.LastKey) {
50
50
  return resolve(newJobs);
51
51
  }
52
- return resolve(generalActions.getJobsRecursive(site, status, type, jobRes.data.LastKey, newJobs));
52
+ return resolve(maintenanceActions.getJobsRecursive(site, status, priority, type, jobRes.data.LastKey, newJobs));
53
53
  });
54
54
  });
55
55
  },
56
- sendMaintenanceRequest: (userID, userName, phone, room, title, description, date, type, images, location, isHome, homeText) => {
56
+ sendMaintenanceRequest: (
57
+ userID,
58
+ userName,
59
+ phone,
60
+ room,
61
+ title,
62
+ description,
63
+ date,
64
+ type,
65
+ images,
66
+ location,
67
+ isHome,
68
+ homeText,
69
+ customFields,
70
+ ) => {
57
71
  const request = {
58
72
  method: 'POST',
59
73
  url: Helper.getUrl(values.serviceKey, 'sendMaintenance'),
@@ -70,6 +84,7 @@ export const generalActions = {
70
84
  location,
71
85
  isHome,
72
86
  homeText,
87
+ customFields,
73
88
  },
74
89
  };
75
90
  return Session.authedFunction(request);
@@ -88,7 +103,30 @@ export const generalActions = {
88
103
  data: { id, status },
89
104
  });
90
105
  },
91
- addNote: (jobId, note, attachments) => {
106
+ editJobPriority: (id, priority) => {
107
+ return Session.authedFunction({
108
+ method: 'POST',
109
+ url: Helper.getUrl(values.serviceKey, 'update/priority'),
110
+ data: { id, priority },
111
+ });
112
+ },
113
+ assignJob: (jobId, userId) => {
114
+ return Session.authedFunction({
115
+ method: 'POST',
116
+ url: Helper.getUrl(values.serviceKey, 'update/assign'),
117
+ data: {
118
+ id: jobId,
119
+ userId,
120
+ },
121
+ });
122
+ },
123
+ getAssignees: site => {
124
+ return Session.authedFunction({
125
+ method: 'GET',
126
+ url: Helper.getUrl(values.serviceKey, 'get/assignees', { site }),
127
+ });
128
+ },
129
+ addNote: (jobId, note, attachments, images) => {
92
130
  return Session.authedFunction({
93
131
  method: 'POST',
94
132
  url: Helper.getUrl(values.serviceKey, 'requests/note'),
@@ -96,11 +134,12 @@ export const generalActions = {
96
134
  id: jobId,
97
135
  note,
98
136
  attachments,
137
+ images,
99
138
  action: 'AddNote',
100
139
  },
101
140
  });
102
141
  },
103
- editNote: (jobId, noteId, note, attachments) => {
142
+ editNote: (jobId, noteId, note, attachments, images) => {
104
143
  return Session.authedFunction({
105
144
  method: 'POST',
106
145
  url: Helper.getUrl(values.serviceKey, 'requests/note'),
@@ -108,6 +147,7 @@ export const generalActions = {
108
147
  id: jobId,
109
148
  note,
110
149
  attachments,
150
+ images,
111
151
  noteId,
112
152
  action: 'EditNote',
113
153
  },
@@ -124,10 +164,6 @@ export const generalActions = {
124
164
  },
125
165
  });
126
166
  },
127
- // getWeeklyMenu: async time => {
128
- // //deprecated
129
- // return null;
130
- // },
131
167
  getJobTypes: async site => {
132
168
  const url = Helper.getUrl(values.serviceKey, 'getjobtypes');
133
169
  return Session.authedFunction({
@@ -136,32 +172,4 @@ export const generalActions = {
136
172
  data: { site },
137
173
  });
138
174
  },
139
- // sendBookingRequest: async bookingInfo => {
140
- // return authedFunction({
141
- // method: 'POST',
142
- // data: {
143
- // bookingInfo,
144
- // },
145
- // url: getUrl('utility', 'sendBookingRequest'),
146
- // });
147
- // },
148
- // getString: async (site, id, useDefault) => {
149
- // return axios({
150
- // method: 'GET',
151
- // url: getUrl('strings', `get/${site}_${id}`, useDefault ? { useDefault } : undefined),
152
- // }).catch(error => {
153
- // console.log('getString error', error);
154
- // throw error;
155
- // });
156
- // },
157
- // getGeneralTerms: async () => {
158
- // return axios({
159
- // method: 'GET',
160
- // url: 'https://pluss.plussapp.com.au/strings-prd/get/plussSpace_termsofuse',
161
- // });
162
- // },
163
- // declineTerms: async (site, userID) => {
164
- // //deprecated
165
- // return null;
166
- // },
167
175
  };
@@ -1,9 +1,13 @@
1
1
  import React, { Component } from 'react';
2
- import { View, Text, TouchableOpacity, Modal } from 'react-native';
2
+ import { View, Text, TouchableOpacity, Modal, ScrollView, Dimensions } from 'react-native';
3
3
  import { connect } from 'react-redux';
4
4
  import _ from 'lodash';
5
- import { generalActions } from '../apis';
5
+ import { maintenanceActions } from '../apis';
6
6
  import { Colours, Helper } from '../core.config';
7
+ import { getJobStatusOptions, getIncompleteJobStatuses, jobPriorityOptions } from '../helper';
8
+ import { values } from '../values.config';
9
+
10
+ const SCREEN_HEIGHT = Dimensions.get('window').height;
7
11
 
8
12
  class FilterPopupMenu extends Component {
9
13
  constructor(props) {
@@ -12,33 +16,25 @@ class FilterPopupMenu extends Component {
12
16
  this.state = {
13
17
  types: props.types || [],
14
18
  selectedStatus: props.status || '',
19
+ selectedPriority: props.priority || '',
15
20
  selectedType: props.type || '',
21
+ selectedAssignee: props.assignee || '',
22
+ assignees: [],
16
23
  };
17
- this.statusOptions = [
24
+ this.priorityOptions = [
18
25
  {
19
26
  label: 'All',
20
27
  value: '',
21
28
  },
22
- {
23
- label: 'Incomplete',
24
- value: 'Unassigned|In Progress',
25
- },
26
- {
27
- label: 'Unassigned',
28
- value: 'Unassigned',
29
- },
30
- {
31
- label: 'In Progress',
32
- value: 'In Progress',
33
- },
34
- {
35
- label: 'Completed',
36
- value: 'Completed',
37
- },
29
+ ...jobPriorityOptions.map(p => ({
30
+ label: p.label,
31
+ value: p.label,
32
+ }))
38
33
  ];
39
34
  }
40
35
 
41
36
  componentDidMount() {
37
+ this.getAssignees();
42
38
  if (_.isEmpty(this.state.types)) this.refreshTypes();
43
39
  }
44
40
 
@@ -48,8 +44,50 @@ class FilterPopupMenu extends Component {
48
44
  }
49
45
  }
50
46
 
47
+ getStatusOptions = () => {
48
+ const statusOptions = getJobStatusOptions(this.props);
49
+ const options = [
50
+ {
51
+ label: 'All',
52
+ value: '',
53
+ },
54
+ {
55
+ label: 'Incomplete',
56
+ value: `Unassigned|${getIncompleteJobStatuses(this.props).map(s => s.text).join('|')}`,
57
+ },
58
+ ...statusOptions.map(s => ({
59
+ label: s.text,
60
+ value: s.text,
61
+ })),
62
+ ];
63
+ // console.log('getStatusOptions', options);
64
+ return options;
65
+ }
66
+
67
+ getAssignees = async () => {
68
+ try {
69
+ const res = await maintenanceActions.getAssignees(this.props.site);
70
+ let assignees = res.data.Users.map(t => {
71
+ return { label: t.displayName, value: t.id };
72
+ });
73
+ assignees = _.orderBy(assignees, 'label');
74
+
75
+ assignees.splice(0, 0, { label: 'All', value: '' });
76
+
77
+ const newState = { assignees };
78
+
79
+ if (!assignees.some(a => a.value === this.state.selectedAssignee)) {
80
+ newState.selectedAssignee = '';
81
+ }
82
+ // console.log('refreshassignees', assignees);
83
+ this.setState(newState);
84
+ } catch (error) {
85
+ console.error('getAssignees', error);
86
+ }
87
+ };
88
+
51
89
  refreshTypes = async () => {
52
- const { data } = await generalActions.getJobTypes(Helper.getSite(this.props.site));
90
+ const { data } = await maintenanceActions.getJobTypes(Helper.getSite(this.props.site));
53
91
  const types = data.map(t => {
54
92
  return { label: t.typeName, value: t.typeName };
55
93
  });
@@ -66,11 +104,15 @@ class FilterPopupMenu extends Component {
66
104
 
67
105
  onDone = () => {
68
106
  const { onClose } = this.props;
69
- const { selectedStatus, selectedType } = this.state;
107
+ const { selectedStatus, selectedPriority, selectedType, selectedAssignee } = this.state;
70
108
  if (onClose)
71
109
  onClose({
72
110
  status: selectedStatus,
111
+ statusText: this.getStatusOptions().find(o => o.value === selectedStatus)?.label,
112
+ priority: selectedPriority,
73
113
  type: selectedType,
114
+ assignee: selectedAssignee,
115
+ assigneeName: this.state.assignees.find(a => a.value === selectedAssignee)?.label,
74
116
  });
75
117
  };
76
118
 
@@ -118,15 +160,21 @@ class FilterPopupMenu extends Component {
118
160
  }
119
161
 
120
162
  render() {
163
+ // console.log('FilterPopupMenu', JSON.stringify({ category: this.props.user.category, permissions: this.props.user.permissions }, null, 2))
164
+ const isStaff = this.props.user.category === 'staff'
165
+ const canFilterAssignee = !_.includes(this.props.user.permissions, values.permissionMaintenanceAssignment);
166
+
121
167
  return (
122
168
  <Modal visible transparent animationType="slide" onRequestClose={this.onDone}>
123
169
  <View style={styles.container}>
124
170
  <View style={styles.menu}>
125
171
  {this.renderTitle()}
126
- <View style={styles.optionContent}>
127
- {this.renderOptions('Status', this.statusOptions, 'selectedStatus')}
172
+ <ScrollView style={styles.optionContent}>
173
+ {this.renderOptions('Status', this.getStatusOptions(), 'selectedStatus')}
174
+ {isStaff ? this.renderOptions('Priority', this.priorityOptions, 'selectedPriority') : null}
128
175
  {this.renderOptions('Type', this.state.types, 'selectedType')}
129
- </View>
176
+ {canFilterAssignee ? this.renderOptions('Assigned To', this.state.assignees, 'selectedAssignee') : null}
177
+ </ScrollView>
130
178
  {this.renderCancel()}
131
179
  </View>
132
180
  </View>
@@ -153,6 +201,7 @@ const styles = {
153
201
  backgroundColor: '#fff',
154
202
  borderTopLeftRadius: 12,
155
203
  borderTopRightRadius: 12,
204
+ maxHeight: SCREEN_HEIGHT * 0.8,
156
205
  },
157
206
  cancelContainer: {
158
207
  paddingVertical: 16,
@@ -216,8 +265,10 @@ const mapStateToProps = state => {
216
265
  const { user } = state;
217
266
 
218
267
  return {
268
+ user,
219
269
  site: user.site,
220
270
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
271
+ statusTypes: state[values.reducerKey].jobstatuses,
221
272
  };
222
273
  };
223
274
 
@@ -2,50 +2,46 @@ import React, { Component } from 'react';
2
2
  import { View, StyleSheet, FlatList, TouchableOpacity, Text } from 'react-native';
3
3
  import _ from 'lodash';
4
4
  import { connect } from 'react-redux';
5
- import { generalActions } from '../apis';
6
- import { jobsLoaded, jobAdded, jobsAdded } from '../actions';
5
+ import { maintenanceActions } from '../apis';
6
+ import { jobsLoaded, jobAdded, jobsAdded, jobStatusesUpdate, jobHideSeenUpdate, jobsFilterLoaded } from '../actions';
7
7
  import MaintenanceListItem from '../components/MaintenanceListItem';
8
8
  import FilterPopupMenu from './FilterPopupMenu';
9
- import { Components, Colours, Config, Helper } from '../core.config';
9
+ import { Components, Colours, Helper } from '../core.config';
10
10
  import { values } from '../values.config';
11
11
 
12
12
  class MaintenanceList extends Component {
13
13
  constructor(props) {
14
14
  super(props);
15
15
 
16
- this.initialStatus = props.hasPermission ? 'Unassigned|In Progress' : '';
17
-
18
16
  this.state = {
19
17
  types: [],
20
18
  filteredList: props.jobs,
21
19
  loading: false,
22
20
  searchText: '',
23
21
  showFilterPopup: false,
24
- selectedStatus: this.initialStatus,
25
- selectedType: '',
26
22
  };
27
23
  }
28
24
 
29
25
  componentDidMount() {
26
+ this.props.jobStatusesUpdate(this.props.site);
27
+ this.props.jobHideSeenUpdate(this.props.site);
30
28
  this.refresh();
31
29
  this.refreshTypes();
32
-
33
30
  this.resetDataSource();
34
31
  }
35
32
 
36
33
  componentDidUpdate(prevProps) {
37
34
  if (!prevProps.dataUpdated && this.props.dataUpdated) this.refresh();
38
- if (!_.isEqual(prevProps.jobs, this.props.jobs)) this.resetDataSource();
35
+ if (!_.isEqual(prevProps.jobs, this.props.jobs) || !_.isEqual(prevProps.jobfilters, this.props.jobfilters)) this.resetDataSource();
39
36
  }
40
37
 
41
38
  refresh = () => {
42
39
  this.onLoadingChanged(true, async () => {
43
40
  try {
44
- const { selectedStatus, selectedType } = this.state;
45
- // console.log('filters', { selectedStatus, selectedType });
46
- const res = await generalActions.getJobsRecursive(this.props.site, selectedStatus, selectedType);
47
- // console.log('refresh', JSON.stringify(res, null, 2));
48
- if (selectedStatus !== this.initialStatus || !_.isEmpty(selectedType)) {
41
+ const { jobfilters } = this.props;
42
+ const res = await maintenanceActions.getJobsRecursive(this.props.site, jobfilters.status, jobfilters.priority, jobfilters.type);
43
+ // console.log('refresh', res ? JSON.stringify(res[0], null, 2) : null);
44
+ if (!_.isEmpty(jobfilters.status) || !_.isEmpty(jobfilters.priority) || !_.isEmpty(jobfilters.type)) {
49
45
  this.props.jobsAdded(res);
50
46
  } else {
51
47
  this.props.jobsLoaded(res);
@@ -59,7 +55,7 @@ class MaintenanceList extends Component {
59
55
  };
60
56
 
61
57
  refreshTypes = async () => {
62
- const { data } = await generalActions.getJobTypes(Helper.getSite(this.props.site));
58
+ const { data } = await maintenanceActions.getJobTypes(Helper.getSite(this.props.site));
63
59
  const types = data.map(t => {
64
60
  return { label: t.typeName, value: t.typeName };
65
61
  });
@@ -73,7 +69,7 @@ class MaintenanceList extends Component {
73
69
 
74
70
  this.onLoadingChanged(true, async () => {
75
71
  try {
76
- const job = await generalActions.getJobByJobId(this.props.site, jobId);
72
+ const job = await maintenanceActions.getJobByJobId(this.props.site, jobId);
77
73
  // console.log('fetchJob', job?.data);
78
74
  this.props.jobAdded(job.data);
79
75
  } catch (error) {
@@ -88,11 +84,12 @@ class MaintenanceList extends Component {
88
84
  if (this.props.options && !_.isEmpty(this.props.options.EmptyText)) {
89
85
  return this.props.options.EmptyText;
90
86
  }
91
- return this.props.userCategory === 'staff' ? Config.env.strings.EMPTY_REQUESTS_STAFF : Config.env.strings.EMPTY_REQUESTS_USER;
87
+ return this.props.userCategory === 'staff' ? values.emptyRequestsStaff : values.emptyRequestsUser;
92
88
  }
93
89
 
94
90
  resetDataSource = (source = '') => {
95
- const { searchText, selectedStatus, selectedType } = this.state;
91
+ const { jobfilters } = this.props;
92
+ const { searchText } = this.state;
96
93
  const { jobs } = this.props;
97
94
 
98
95
  let filteredList = jobs;
@@ -107,8 +104,10 @@ class MaintenanceList extends Component {
107
104
  });
108
105
  if (!jobIdMatch) this.fetchJob(searchText);
109
106
  }
110
- if (selectedStatus) filteredList = filteredList.filter(j => selectedStatus.includes(j.status));
111
- if (selectedType) filteredList = filteredList.filter(j => selectedType.includes(j.type));
107
+ if (jobfilters.status) filteredList = filteredList.filter(j => jobfilters.status.includes(j.status));
108
+ if (jobfilters.priority) filteredList = filteredList.filter(j => jobfilters.priority.includes(j.priority));
109
+ if (jobfilters.type) filteredList = filteredList.filter(j => jobfilters.type.includes(j.type));
110
+ if (jobfilters.assignee) filteredList = filteredList.filter(j => jobfilters.assignee.includes(j.AssigneeId));
112
111
  if (jobIdMatch) {
113
112
  const jobIndex = filteredList.indexOf(jobIdMatch);
114
113
  if (jobIndex > -1) {
@@ -143,10 +142,29 @@ class MaintenanceList extends Component {
143
142
  };
144
143
 
145
144
  onSelectFilter = selected => {
146
- this.setState({ selectedStatus: selected.status, selectedType: selected.type }, () => {
147
- this.resetDataSource();
148
- this.onToggleFilter();
149
- });
145
+ this.props.jobsFilterLoaded(selected);
146
+ this.onToggleFilter();
147
+ };
148
+
149
+ getFilterButtonText = () => {
150
+ const { jobfilters } = this.props;
151
+ const filterTexts = [];
152
+ if (!_.isEmpty(jobfilters.status)) {
153
+ filterTexts.push(jobfilters.statusText);
154
+ }
155
+ if (!_.isEmpty(jobfilters.priority)) {
156
+ filterTexts.push(jobfilters.priority);
157
+ }
158
+ if (!_.isEmpty(jobfilters.type)) {
159
+ filterTexts.push(jobfilters.type);
160
+ }
161
+ if (!_.isEmpty(jobfilters.assignee)) {
162
+ filterTexts.push(jobfilters.assigneeName);
163
+ }
164
+ if (_.isEmpty(filterTexts)) {
165
+ return 'Filter';
166
+ }
167
+ return `Filtering by ${filterTexts.join(', ')}`;
150
168
  };
151
169
 
152
170
  renderEmptyList() {
@@ -157,7 +175,7 @@ class MaintenanceList extends Component {
157
175
  return (
158
176
  <TouchableOpacity onPress={this.onToggleFilter}>
159
177
  <View style={styles.filterButton}>
160
- <Text style={[styles.filterButtonText, { color: this.props.colourBrandingMain }]}>Filter</Text>
178
+ <Text style={[styles.filterButtonText, { color: this.props.colourBrandingMain }]}>{this.getFilterButtonText()}</Text>
161
179
  </View>
162
180
  </TouchableOpacity>
163
181
  );
@@ -169,7 +187,7 @@ class MaintenanceList extends Component {
169
187
  return (
170
188
  <View style={styles.searchContainer}>
171
189
  <Components.GenericInput
172
- placeholder="Search by Job ID or Location"
190
+ placeholder={`Search by ${values.textEntityName} ID or Address`}
173
191
  value={this.state.searchText}
174
192
  onChangeText={this.onSearchText}
175
193
  onSubmitEditing={this.onSearchSubmit}
@@ -186,7 +204,7 @@ class MaintenanceList extends Component {
186
204
  const { ListHeaderComponent } = this.props;
187
205
  return (
188
206
  <View>
189
- {ListHeaderComponent ? ListHeaderComponent : <View style={{ height: 32 }} />}
207
+ {ListHeaderComponent ? ListHeaderComponent : <View style={{ height: 8 }} />}
190
208
  {this.renderFilterButton()}
191
209
  {this.renderSearch()}
192
210
  </View>
@@ -211,11 +229,20 @@ class MaintenanceList extends Component {
211
229
  }
212
230
 
213
231
  renderFilterPopup() {
214
- const { showFilterPopup, types, selectedStatus, selectedType } = this.state;
232
+ const { jobfilters } = this.props;
233
+ const { showFilterPopup, types } = this.state;
215
234
  if (!showFilterPopup) return null;
216
235
 
217
236
  return (
218
- <FilterPopupMenu site={this.props.site} types={types} status={selectedStatus} type={selectedType} onClose={this.onSelectFilter} />
237
+ <FilterPopupMenu
238
+ site={this.props.site}
239
+ types={types}
240
+ status={jobfilters.status}
241
+ priority={jobfilters.priority}
242
+ assignee={jobfilters.assignee}
243
+ type={jobfilters.type}
244
+ onClose={this.onSelectFilter}
245
+ />
219
246
  );
220
247
  }
221
248
 
@@ -266,9 +293,9 @@ const styles = StyleSheet.create({
266
293
  paddingHorizontal: 16,
267
294
  },
268
295
  filterButton: {
269
- position: 'absolute',
270
- right: 20,
271
- top: -32,
296
+ paddingBottom: 8,
297
+ paddingHorizontal: 16,
298
+ flexDirection: 'row-reverse',
272
299
  },
273
300
  filterButtonText: {
274
301
  fontFamily: 'sf-semibold',
@@ -289,7 +316,11 @@ const mapStateToProps = state => {
289
316
  userCategory: user.category,
290
317
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
291
318
  dataUpdated: notifications.dataUpdated[values.updateKey],
319
+ statusTypes: state[values.reducerKey].jobstatuses,
320
+ jobfilters: state[values.reducerKey].jobfilters,
292
321
  };
293
322
  };
294
323
 
295
- export default connect(mapStateToProps, { jobsLoaded, jobAdded, jobsAdded }, null, { forwardRef: true })(MaintenanceList);
324
+ export default connect(mapStateToProps, { jobsLoaded, jobAdded, jobsAdded, jobStatusesUpdate, jobHideSeenUpdate, jobsFilterLoaded }, null, { forwardRef: true })(
325
+ MaintenanceList,
326
+ );