@plusscommunities/pluss-maintenance-app 6.0.19 → 6.0.21-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 (97) hide show
  1. package/dist/module/actions/JobActions.js +4 -4
  2. package/dist/module/actions/JobActions.js.map +1 -1
  3. package/dist/module/actions/index.js +1 -1
  4. package/dist/module/actions/index.js.map +1 -1
  5. package/dist/module/actions/types.js +1 -1
  6. package/dist/module/actions/types.js.map +1 -1
  7. package/dist/module/apis/index.js +3 -3
  8. package/dist/module/apis/index.js.map +1 -1
  9. package/dist/module/apis/maintenanceActions.js +36 -36
  10. package/dist/module/apis/maintenanceActions.js.map +1 -1
  11. package/dist/module/apis/userActions.js +5 -5
  12. package/dist/module/apis/userActions.js.map +1 -1
  13. package/dist/module/components/FilterPopupMenu.js +49 -49
  14. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  15. package/dist/module/components/MaintenanceList.js +38 -38
  16. package/dist/module/components/MaintenanceList.js.map +1 -1
  17. package/dist/module/components/MaintenanceListItem.js +62 -62
  18. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  19. package/dist/module/components/MaintenanceWidgetItem.js +27 -27
  20. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  21. package/dist/module/components/PrioritySelectorPopup.js +15 -15
  22. package/dist/module/components/PrioritySelectorPopup.js.map +1 -1
  23. package/dist/module/components/StatusSelectorPopup.js +16 -16
  24. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  25. package/dist/module/components/WidgetLarge.js +2 -2
  26. package/dist/module/components/WidgetLarge.js.map +1 -1
  27. package/dist/module/components/WidgetSmall.js +19 -19
  28. package/dist/module/components/WidgetSmall.js.map +1 -1
  29. package/dist/module/core.config.js +1 -1
  30. package/dist/module/core.config.js.map +1 -1
  31. package/dist/module/feature.config.js +17 -17
  32. package/dist/module/feature.config.js.map +1 -1
  33. package/dist/module/helper.js +10 -10
  34. package/dist/module/helper.js.map +1 -1
  35. package/dist/module/index.js +11 -11
  36. package/dist/module/index.js.map +1 -1
  37. package/dist/module/reducers/JobsReducer.js +13 -13
  38. package/dist/module/reducers/JobsReducer.js.map +1 -1
  39. package/dist/module/screens/JobTypePicker.js +17 -17
  40. package/dist/module/screens/JobTypePicker.js.map +1 -1
  41. package/dist/module/screens/MaintenancePage.js +10 -10
  42. package/dist/module/screens/MaintenancePage.js.map +1 -1
  43. package/dist/module/screens/MaintenanceUserPicker.js +129 -22
  44. package/dist/module/screens/MaintenanceUserPicker.js.map +1 -1
  45. package/dist/module/screens/RequestDetail.js +146 -146
  46. package/dist/module/screens/RequestDetail.js.map +1 -1
  47. package/dist/module/screens/RequestNotes.js +59 -59
  48. package/dist/module/screens/RequestNotes.js.map +1 -1
  49. package/dist/module/screens/ServiceRequest.js +187 -187
  50. package/dist/module/screens/ServiceRequest.js.map +1 -1
  51. package/dist/module/values.config.a.js +30 -30
  52. package/dist/module/values.config.a.js.map +1 -1
  53. package/dist/module/values.config.default.js +34 -34
  54. package/dist/module/values.config.default.js.map +1 -1
  55. package/dist/module/values.config.enquiry.js +34 -34
  56. package/dist/module/values.config.enquiry.js.map +1 -1
  57. package/dist/module/values.config.feedback.js +34 -34
  58. package/dist/module/values.config.feedback.js.map +1 -1
  59. package/dist/module/values.config.food.js +34 -34
  60. package/dist/module/values.config.food.js.map +1 -1
  61. package/dist/module/values.config.forms.js +34 -34
  62. package/dist/module/values.config.forms.js.map +1 -1
  63. package/dist/module/values.config.js +34 -34
  64. package/dist/module/values.config.js.map +1 -1
  65. package/package.json +51 -51
  66. package/src/actions/JobActions.js +67 -60
  67. package/src/actions/index.js +1 -1
  68. package/src/actions/types.js +1 -2
  69. package/src/apis/index.js +3 -3
  70. package/src/apis/maintenanceActions.js +189 -178
  71. package/src/apis/userActions.js +17 -17
  72. package/src/components/FilterPopupMenu.js +313 -256
  73. package/src/components/MaintenanceList.js +396 -317
  74. package/src/components/MaintenanceListItem.js +347 -288
  75. package/src/components/MaintenanceWidgetItem.js +145 -124
  76. package/src/components/PrioritySelectorPopup.js +81 -68
  77. package/src/components/StatusSelectorPopup.js +81 -70
  78. package/src/components/WidgetLarge.js +5 -5
  79. package/src/components/WidgetSmall.js +153 -133
  80. package/src/core.config.js +27 -3
  81. package/src/feature.config.js +62 -62
  82. package/src/helper.js +58 -53
  83. package/src/index.js +22 -22
  84. package/src/reducers/JobsReducer.js +85 -66
  85. package/src/screens/JobTypePicker.js +115 -92
  86. package/src/screens/MaintenancePage.js +89 -80
  87. package/src/screens/MaintenanceUserPicker.js +252 -100
  88. package/src/screens/RequestDetail.js +1348 -1125
  89. package/src/screens/RequestNotes.js +950 -806
  90. package/src/screens/ServiceRequest.js +1778 -1550
  91. package/src/values.config.a.js +33 -33
  92. package/src/values.config.default.js +39 -39
  93. package/src/values.config.enquiry.js +39 -39
  94. package/src/values.config.feedback.js +39 -39
  95. package/src/values.config.food.js +39 -39
  96. package/src/values.config.forms.js +39 -39
  97. package/src/values.config.js +39 -39
@@ -1,326 +1,405 @@
1
- import React, { Component } from 'react';
2
- import { View, StyleSheet, FlatList, TouchableOpacity, Text } from 'react-native';
3
- import _ from 'lodash';
4
- import { connect } from 'react-redux';
5
- import { maintenanceActions } from '../apis';
6
- import { jobsLoaded, jobAdded, jobsAdded, jobStatusesUpdate, jobHideSeenUpdate, jobsFilterLoaded } from '../actions';
7
- import MaintenanceListItem from '../components/MaintenanceListItem';
8
- import FilterPopupMenu from './FilterPopupMenu';
9
- import { Components, Colours, Helper } from '../core.config';
10
- import { values } from '../values.config';
1
+ import React, { Component } from "react";
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ FlatList,
6
+ TouchableOpacity,
7
+ Text,
8
+ } from "react-native";
9
+ import _ from "lodash";
10
+ import { connect } from "react-redux";
11
+ import { maintenanceActions } from "../apis";
12
+ import {
13
+ jobsLoaded,
14
+ jobAdded,
15
+ jobsAdded,
16
+ jobStatusesUpdate,
17
+ jobHideSeenUpdate,
18
+ jobsFilterLoaded,
19
+ } from "../actions";
20
+ import MaintenanceListItem from "../components/MaintenanceListItem";
21
+ import FilterPopupMenu from "./FilterPopupMenu";
22
+ import { Components, Colours, Helper } from "../core.config";
23
+ import { values } from "../values.config";
11
24
 
12
25
  class MaintenanceList extends Component {
13
- constructor(props) {
14
- super(props);
15
-
16
- this.state = {
17
- types: [],
18
- filteredList: props.jobs,
19
- loading: false,
20
- searchText: '',
21
- showFilterPopup: false,
22
- };
23
- }
24
-
25
- componentDidMount() {
26
- this.props.jobStatusesUpdate(this.props.site);
27
- this.props.jobHideSeenUpdate(this.props.site);
28
- this.refresh();
29
- this.refreshTypes();
30
- this.resetDataSource();
31
- }
32
-
33
- componentDidUpdate(prevProps) {
34
- if (!prevProps.dataUpdated && this.props.dataUpdated) this.refresh();
35
- if (!_.isEqual(prevProps.jobs, this.props.jobs) || !_.isEqual(prevProps.jobfilters, this.props.jobfilters)) this.resetDataSource();
36
- }
37
-
38
- refresh = () => {
39
- this.onLoadingChanged(true, async () => {
40
- try {
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)) {
45
- this.props.jobsAdded(res);
46
- } else {
47
- this.props.jobsLoaded(res);
48
- }
49
- } catch (error) {
50
- console.log('refresh error', error);
51
- } finally {
52
- this.onLoadingChanged(false);
53
- }
54
- });
55
- };
56
-
57
- refreshTypes = async () => {
58
- const { data } = await maintenanceActions.getJobTypes(Helper.getSite(this.props.site));
59
- const types = data.map(t => {
60
- return { label: t.typeName, value: t.typeName };
61
- });
62
- types.splice(0, 0, { label: 'All', value: '' });
63
- // console.log('refreshTypes', types);
64
- this.setState({ types });
65
- };
66
-
67
- fetchJob = jobId => {
68
- if (this.state.loading) return;
69
-
70
- this.onLoadingChanged(true, async () => {
71
- try {
72
- const job = await maintenanceActions.getJobByJobId(this.props.site, jobId);
73
- // console.log('fetchJob', job?.data);
74
- this.props.jobAdded(job.data);
75
- } catch (error) {
76
- console.log('fetchJob error', error);
77
- } finally {
78
- this.onLoadingChanged(false);
79
- }
80
- });
81
- };
82
-
83
- getEmptyStateText() {
84
- if (this.props.options && !_.isEmpty(this.props.options.EmptyText)) {
85
- return this.props.options.EmptyText;
86
- }
87
- return this.props.userCategory === 'staff' ? values.emptyRequestsStaff : values.emptyRequestsUser;
88
- }
89
-
90
- resetDataSource = (source = '') => {
91
- const { jobfilters } = this.props;
92
- const { searchText } = this.state;
93
- const { jobs } = this.props;
94
-
95
- let filteredList = jobs;
96
- let jobIdMatch = null;
97
- if (searchText) {
98
- jobIdMatch = _.find(jobs, j => j.jobId === searchText);
99
- filteredList = jobs.filter(j => {
100
- if (j.room && j.room.toLowerCase().indexOf(searchText.toLowerCase()) > -1) {
101
- return true;
102
- }
103
- return false;
104
- });
105
- if (!jobIdMatch) this.fetchJob(searchText);
106
- }
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));
111
- if (jobIdMatch) {
112
- const jobIndex = filteredList.indexOf(jobIdMatch);
113
- if (jobIndex > -1) {
114
- filteredList.splice(jobIndex, 1);
115
- }
116
- filteredList.unshift(jobIdMatch);
117
- }
118
- if (source !== 'search') this.refresh();
119
-
120
- this.setState({ filteredList });
121
- };
122
-
123
- onLoadingChanged = (loading, callback) => {
124
- this.setState({ loading }, () => {
125
- if (this.props.onLoadingChanged) this.props.onLoadingChanged(this.state.loading);
126
- if (callback) callback();
127
- });
128
- };
129
-
130
- onSearchText = value => {
131
- this.setState({ searchText: value }, () => {
132
- if (_.isEmpty(this.state.searchText)) this.resetDataSource('search');
133
- });
134
- };
135
-
136
- onSearchSubmit = () => {
137
- this.resetDataSource('search');
138
- };
139
-
140
- onToggleFilter = () => {
141
- this.setState({ showFilterPopup: !this.state.showFilterPopup });
142
- };
143
-
144
- onSelectFilter = selected => {
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.priorityText);
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(', ')}`;
168
- };
169
-
170
- renderEmptyList() {
171
- return this.state.loading ? null : <Components.EmptyStateMain title={this.getEmptyStateText()} style={{ marginHorizontal: 16 }} />;
172
- }
173
-
174
- renderFilterButton() {
175
- return (
176
- <TouchableOpacity onPress={this.onToggleFilter}>
177
- <View style={styles.filterButton}>
178
- <Text style={[styles.filterButtonText, { color: this.props.colourBrandingMain }]}>{this.getFilterButtonText()}</Text>
179
- </View>
180
- </TouchableOpacity>
181
- );
182
- }
183
-
184
- renderSearch() {
185
- if (!this.props.hasPermission) return null;
186
-
187
- return (
188
- <View style={styles.searchContainer}>
189
- <Components.GenericInput
190
- placeholder={`Search by ${values.textEntityName} ID or Address`}
191
- value={this.state.searchText}
192
- onChangeText={this.onSearchText}
193
- onSubmitEditing={this.onSearchSubmit}
194
- squaredCorners
195
- hasClear
196
- // keyboardType={'numeric'}
197
- returnKeyType={'done'}
198
- />
199
- </View>
200
- );
201
- }
202
-
203
- renderListHeader() {
204
- const { ListHeaderComponent } = this.props;
205
- return (
206
- <View>
207
- {ListHeaderComponent ? ListHeaderComponent : <View style={{ height: 8 }} />}
208
- {this.renderFilterButton()}
209
- {this.renderSearch()}
210
- </View>
211
- );
212
- }
213
-
214
- renderList() {
215
- const { filteredList } = this.state;
216
-
217
- return (
218
- <FlatList
219
- keyboardShouldPersistTaps="always"
220
- style={{ flex: 1 }}
221
- contentContainerStyle={{ paddingBottom: 16 }}
222
- data={filteredList}
223
- keyExtractor={item => item.id}
224
- renderItem={({ item }) => <MaintenanceListItem style={this.props.itemStyle} job={item} />}
225
- ListEmptyComponent={this.renderEmptyList()}
226
- ListHeaderComponent={this.renderListHeader()}
227
- />
228
- );
229
- }
230
-
231
- renderFilterPopup() {
232
- const { jobfilters } = this.props;
233
- const { showFilterPopup, types } = this.state;
234
- if (!showFilterPopup) return null;
235
-
236
- return (
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
- />
246
- );
247
- }
248
-
249
- render() {
250
- return (
251
- <View style={[styles.container, this.props.style]}>
252
- {this.renderList()}
253
- {this.renderFilterPopup()}
254
- </View>
255
- );
256
- }
26
+ constructor(props) {
27
+ super(props);
28
+
29
+ this.state = {
30
+ types: [],
31
+ filteredList: props.jobs,
32
+ loading: false,
33
+ searchText: "",
34
+ showFilterPopup: false,
35
+ };
36
+ }
37
+
38
+ componentDidMount() {
39
+ this.props.jobStatusesUpdate(this.props.site);
40
+ this.props.jobHideSeenUpdate(this.props.site);
41
+ this.refresh();
42
+ this.refreshTypes();
43
+ this.resetDataSource();
44
+ }
45
+
46
+ componentDidUpdate(prevProps) {
47
+ if (!prevProps.dataUpdated && this.props.dataUpdated) this.refresh();
48
+ if (
49
+ !_.isEqual(prevProps.jobs, this.props.jobs) ||
50
+ !_.isEqual(prevProps.jobfilters, this.props.jobfilters)
51
+ )
52
+ this.resetDataSource();
53
+ }
54
+
55
+ refresh = () => {
56
+ this.onLoadingChanged(true, async () => {
57
+ try {
58
+ const { jobfilters } = this.props;
59
+ const res = await maintenanceActions.getJobsRecursive(
60
+ this.props.site,
61
+ jobfilters.status,
62
+ jobfilters.priority,
63
+ jobfilters.type,
64
+ );
65
+ // console.log('refresh', res ? JSON.stringify(res[0], null, 2) : null);
66
+ if (
67
+ !_.isEmpty(jobfilters.status) ||
68
+ !_.isEmpty(jobfilters.priority) ||
69
+ !_.isEmpty(jobfilters.type)
70
+ ) {
71
+ this.props.jobsAdded(res);
72
+ } else {
73
+ this.props.jobsLoaded(res);
74
+ }
75
+ } catch (error) {
76
+ console.log("refresh error", error);
77
+ } finally {
78
+ this.onLoadingChanged(false);
79
+ }
80
+ });
81
+ };
82
+
83
+ refreshTypes = async () => {
84
+ const { data } = await maintenanceActions.getJobTypes(
85
+ Helper.getSite(this.props.site),
86
+ );
87
+ const types = data.map((t) => {
88
+ return { label: t.typeName, value: t.typeName };
89
+ });
90
+ types.splice(0, 0, { label: "All", value: "" });
91
+ // console.log('refreshTypes', types);
92
+ this.setState({ types });
93
+ };
94
+
95
+ fetchJob = (jobId) => {
96
+ if (this.state.loading) return;
97
+
98
+ this.onLoadingChanged(true, async () => {
99
+ try {
100
+ const job = await maintenanceActions.getJobByJobId(
101
+ this.props.site,
102
+ jobId,
103
+ );
104
+ // console.log('fetchJob', job?.data);
105
+ this.props.jobAdded(job.data);
106
+ } catch (error) {
107
+ console.log("fetchJob error", error);
108
+ } finally {
109
+ this.onLoadingChanged(false);
110
+ }
111
+ });
112
+ };
113
+
114
+ getEmptyStateText() {
115
+ if (this.props.options && !_.isEmpty(this.props.options.EmptyText)) {
116
+ return this.props.options.EmptyText;
117
+ }
118
+ return this.props.userCategory === "staff"
119
+ ? values.emptyRequestsStaff
120
+ : values.emptyRequestsUser;
121
+ }
122
+
123
+ resetDataSource = (source = "") => {
124
+ const { jobfilters } = this.props;
125
+ const { searchText } = this.state;
126
+ const { jobs } = this.props;
127
+
128
+ let filteredList = jobs;
129
+ let jobIdMatch = null;
130
+ if (searchText) {
131
+ jobIdMatch = _.find(jobs, (j) => j.jobId === searchText);
132
+ filteredList = jobs.filter((j) => {
133
+ if (
134
+ j.room &&
135
+ j.room.toLowerCase().indexOf(searchText.toLowerCase()) > -1
136
+ ) {
137
+ return true;
138
+ }
139
+ return false;
140
+ });
141
+ if (!jobIdMatch) this.fetchJob(searchText);
142
+ }
143
+ if (jobfilters.status)
144
+ filteredList = filteredList.filter((j) =>
145
+ jobfilters.status.includes(j.status),
146
+ );
147
+ if (jobfilters.priority)
148
+ filteredList = filteredList.filter((j) =>
149
+ jobfilters.priority.includes(j.priority),
150
+ );
151
+ if (jobfilters.type)
152
+ filteredList = filteredList.filter((j) =>
153
+ jobfilters.type.includes(j.type),
154
+ );
155
+ if (jobfilters.assignee)
156
+ filteredList = filteredList.filter((j) =>
157
+ jobfilters.assignee.includes(j.AssigneeId),
158
+ );
159
+ if (jobIdMatch) {
160
+ const jobIndex = filteredList.indexOf(jobIdMatch);
161
+ if (jobIndex > -1) {
162
+ filteredList.splice(jobIndex, 1);
163
+ }
164
+ filteredList.unshift(jobIdMatch);
165
+ }
166
+ if (source !== "search") this.refresh();
167
+
168
+ this.setState({ filteredList });
169
+ };
170
+
171
+ onLoadingChanged = (loading, callback) => {
172
+ this.setState({ loading }, () => {
173
+ if (this.props.onLoadingChanged)
174
+ this.props.onLoadingChanged(this.state.loading);
175
+ if (callback) callback();
176
+ });
177
+ };
178
+
179
+ onSearchText = (value) => {
180
+ this.setState({ searchText: value }, () => {
181
+ if (_.isEmpty(this.state.searchText)) this.resetDataSource("search");
182
+ });
183
+ };
184
+
185
+ onSearchSubmit = () => {
186
+ this.resetDataSource("search");
187
+ };
188
+
189
+ onToggleFilter = () => {
190
+ this.setState({ showFilterPopup: !this.state.showFilterPopup });
191
+ };
192
+
193
+ onSelectFilter = (selected) => {
194
+ this.props.jobsFilterLoaded(selected);
195
+ this.onToggleFilter();
196
+ };
197
+
198
+ getFilterButtonText = () => {
199
+ const { jobfilters } = this.props;
200
+ const filterTexts = [];
201
+ if (!_.isEmpty(jobfilters.status)) {
202
+ filterTexts.push(jobfilters.statusText);
203
+ }
204
+ if (!_.isEmpty(jobfilters.priority)) {
205
+ filterTexts.push(jobfilters.priorityText);
206
+ }
207
+ if (!_.isEmpty(jobfilters.type)) {
208
+ filterTexts.push(jobfilters.type);
209
+ }
210
+ if (!_.isEmpty(jobfilters.assignee)) {
211
+ filterTexts.push(jobfilters.assigneeName);
212
+ }
213
+ if (_.isEmpty(filterTexts)) {
214
+ return "Filter";
215
+ }
216
+ return `Filtering by ${filterTexts.join(", ")}`;
217
+ };
218
+
219
+ renderEmptyList() {
220
+ return this.state.loading ? null : (
221
+ <Components.EmptyStateMain
222
+ title={this.getEmptyStateText()}
223
+ style={{ marginHorizontal: 16 }}
224
+ />
225
+ );
226
+ }
227
+
228
+ renderFilterButton() {
229
+ return (
230
+ <TouchableOpacity onPress={this.onToggleFilter}>
231
+ <View style={styles.filterButton}>
232
+ <Text
233
+ style={[
234
+ styles.filterButtonText,
235
+ { color: this.props.colourBrandingMain },
236
+ ]}
237
+ >
238
+ {this.getFilterButtonText()}
239
+ </Text>
240
+ </View>
241
+ </TouchableOpacity>
242
+ );
243
+ }
244
+
245
+ renderSearch() {
246
+ if (!this.props.hasPermission) return null;
247
+
248
+ return (
249
+ <View style={styles.searchContainer}>
250
+ <Components.GenericInput
251
+ placeholder={`Search by ${values.textEntityName} ID or Address`}
252
+ value={this.state.searchText}
253
+ onChangeText={this.onSearchText}
254
+ onSubmitEditing={this.onSearchSubmit}
255
+ squaredCorners
256
+ hasClear
257
+ // keyboardType={'numeric'}
258
+ returnKeyType={"done"}
259
+ />
260
+ </View>
261
+ );
262
+ }
263
+
264
+ renderListHeader() {
265
+ const { ListHeaderComponent } = this.props;
266
+ return (
267
+ <View>
268
+ {ListHeaderComponent ? (
269
+ ListHeaderComponent
270
+ ) : (
271
+ <View style={{ height: 8 }} />
272
+ )}
273
+ {this.renderFilterButton()}
274
+ {this.renderSearch()}
275
+ </View>
276
+ );
277
+ }
278
+
279
+ renderList() {
280
+ const { filteredList } = this.state;
281
+
282
+ return (
283
+ <FlatList
284
+ keyboardShouldPersistTaps="always"
285
+ style={{ flex: 1 }}
286
+ contentContainerStyle={{ paddingBottom: 16 }}
287
+ data={filteredList}
288
+ keyExtractor={(item) => item.id}
289
+ renderItem={({ item }) => (
290
+ <MaintenanceListItem style={this.props.itemStyle} job={item} />
291
+ )}
292
+ ListEmptyComponent={this.renderEmptyList()}
293
+ ListHeaderComponent={this.renderListHeader()}
294
+ />
295
+ );
296
+ }
297
+
298
+ renderFilterPopup() {
299
+ const { jobfilters } = this.props;
300
+ const { showFilterPopup, types } = this.state;
301
+ if (!showFilterPopup) return null;
302
+
303
+ return (
304
+ <FilterPopupMenu
305
+ site={this.props.site}
306
+ types={types}
307
+ status={jobfilters.status}
308
+ priority={jobfilters.priority}
309
+ assignee={jobfilters.assignee}
310
+ type={jobfilters.type}
311
+ onClose={this.onSelectFilter}
312
+ />
313
+ );
314
+ }
315
+
316
+ render() {
317
+ return (
318
+ <View style={[styles.container, this.props.style]}>
319
+ {this.renderList()}
320
+ {this.renderFilterPopup()}
321
+ </View>
322
+ );
323
+ }
257
324
  }
258
325
 
259
326
  const styles = StyleSheet.create({
260
- container: {
261
- flex: 1,
262
- backgroundColor: '#fff',
263
- },
264
- filterContainerOuter: {
265
- flexDirection: 'row',
266
- justifyContent: 'space-between',
267
- alignItems: 'center',
268
- paddingHorizontal: 16,
269
- paddingVertical: 16,
270
- },
271
- filterTitle: {
272
- fontFamily: 'sf-bold',
273
- fontSize: 11,
274
- letterSpacing: 0.8,
275
- color: '#4d4d4d',
276
- },
277
- filterContainer: {
278
- flexDirection: 'row',
279
- alignItems: 'center',
280
- },
281
- filterText: {
282
- fontFamily: 'sf-semibold',
283
- fontSize: 16,
284
- marginRight: 6,
285
- },
286
- filterIcon: {
287
- fontSize: 20,
288
- },
289
- searchContainer: {
290
- flexDirection: 'row',
291
- alignItems: 'center',
292
- paddingBottom: 8,
293
- paddingHorizontal: 16,
294
- },
295
- filterButton: {
296
- paddingBottom: 8,
297
- paddingHorizontal: 16,
298
- flexDirection: 'row-reverse',
299
- },
300
- filterButtonText: {
301
- fontFamily: 'sf-semibold',
302
- fontSize: 16,
303
- },
327
+ container: {
328
+ flex: 1,
329
+ backgroundColor: "#fff",
330
+ },
331
+ filterContainerOuter: {
332
+ flexDirection: "row",
333
+ justifyContent: "space-between",
334
+ alignItems: "center",
335
+ paddingHorizontal: 16,
336
+ paddingVertical: 16,
337
+ },
338
+ filterTitle: {
339
+ fontFamily: "sf-bold",
340
+ fontSize: 11,
341
+ letterSpacing: 0.8,
342
+ color: "#4d4d4d",
343
+ },
344
+ filterContainer: {
345
+ flexDirection: "row",
346
+ alignItems: "center",
347
+ },
348
+ filterText: {
349
+ fontFamily: "sf-semibold",
350
+ fontSize: 16,
351
+ marginRight: 6,
352
+ },
353
+ filterIcon: {
354
+ fontSize: 20,
355
+ },
356
+ searchContainer: {
357
+ flexDirection: "row",
358
+ alignItems: "center",
359
+ paddingBottom: 8,
360
+ paddingHorizontal: 16,
361
+ },
362
+ filterButton: {
363
+ paddingBottom: 8,
364
+ paddingHorizontal: 16,
365
+ flexDirection: "row-reverse",
366
+ },
367
+ filterButtonText: {
368
+ fontFamily: "sf-semibold",
369
+ fontSize: 16,
370
+ },
304
371
  });
305
372
 
306
- const mapStateToProps = state => {
307
- const { user, notifications } = state;
308
- const jobs = state[values.reducerKey];
309
- const jobsOrdered = _.orderBy(jobs.jobs, ['createdUnix'], ['desc']);
310
- const hasPermission = _.includes(user.permissions, 'maintenanceTracking');
311
-
312
- return {
313
- hasPermission,
314
- jobs: jobsOrdered,
315
- site: user.site,
316
- userCategory: user.category,
317
- colourBrandingMain: Colours.getMainBrandingColourFromState(state),
318
- dataUpdated: notifications.dataUpdated[values.updateKey],
319
- statusTypes: state[values.reducerKey].jobstatuses,
320
- jobfilters: state[values.reducerKey].jobfilters || {},
321
- };
373
+ const mapStateToProps = (state) => {
374
+ const { user, notifications } = state;
375
+ const jobs = state[values.reducerKey];
376
+ const jobsOrdered = _.orderBy(jobs.jobs, ["createdUnix"], ["desc"]);
377
+ const hasPermission = _.includes(user.permissions, "maintenanceTracking");
378
+
379
+ return {
380
+ hasPermission,
381
+ jobs: jobsOrdered,
382
+ site: user.site,
383
+ userCategory: user.category,
384
+ colourBrandingMain: Colours.getMainBrandingColourFromState(state),
385
+ dataUpdated: notifications.dataUpdated[values.updateKey],
386
+ statusTypes: state[values.reducerKey].jobstatuses,
387
+ jobfilters: state[values.reducerKey].jobfilters || {},
388
+ };
322
389
  };
323
390
 
324
- export default connect(mapStateToProps, { jobsLoaded, jobAdded, jobsAdded, jobStatusesUpdate, jobHideSeenUpdate, jobsFilterLoaded }, null, {
325
- forwardRef: true,
326
- })(MaintenanceList);
391
+ export default connect(
392
+ mapStateToProps,
393
+ {
394
+ jobsLoaded,
395
+ jobAdded,
396
+ jobsAdded,
397
+ jobStatusesUpdate,
398
+ jobHideSeenUpdate,
399
+ jobsFilterLoaded,
400
+ },
401
+ null,
402
+ {
403
+ forwardRef: true,
404
+ },
405
+ )(MaintenanceList);