@plusscommunities/pluss-maintenance-app-forms 8.0.12 → 8.0.13
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.
- package/dist/module/apis/maintenanceActions.js +12 -4
- package/dist/module/apis/maintenanceActions.js.map +1 -1
- package/dist/module/components/MaintenanceList.js +84 -16
- package/dist/module/components/MaintenanceList.js.map +1 -1
- package/dist/module/screens/RequestDetail.js +12 -5
- package/dist/module/screens/RequestDetail.js.map +1 -1
- package/dist/module/screens/ServiceRequest.js +2 -1
- package/dist/module/screens/ServiceRequest.js.map +1 -1
- package/package.json +1 -1
- package/src/apis/maintenanceActions.js +17 -7
- package/src/components/MaintenanceList.js +82 -29
- package/src/screens/RequestDetail.js +9 -3
- package/src/screens/ServiceRequest.js +5 -1
|
@@ -23,7 +23,7 @@ export const maintenanceActions = {
|
|
|
23
23
|
data: { site, status, type },
|
|
24
24
|
});
|
|
25
25
|
},
|
|
26
|
-
getJobs2: (site, status, priority, type, lastKey) => {
|
|
26
|
+
getJobs2: (site, status, priority, type, lastKey, assignee) => {
|
|
27
27
|
const query = { site };
|
|
28
28
|
if (status) {
|
|
29
29
|
query.status = status;
|
|
@@ -37,13 +37,21 @@ export const maintenanceActions = {
|
|
|
37
37
|
if (lastKey) {
|
|
38
38
|
query.lastKey = JSON.stringify(lastKey);
|
|
39
39
|
}
|
|
40
|
+
if (assignee) {
|
|
41
|
+
query.assignee = assignee;
|
|
42
|
+
}
|
|
40
43
|
return Session.authedFunction({
|
|
41
44
|
method: "GET",
|
|
42
45
|
url: Helper.getUrl(values.serviceKey, "get/requests", query),
|
|
43
46
|
});
|
|
44
47
|
},
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Use getJobs2 with pagination instead.
|
|
50
|
+
* This method recursively fetches ALL pages which can be slow for large datasets.
|
|
51
|
+
* For better performance, use getJobs2 directly and implement pagination in the UI.
|
|
52
|
+
*/
|
|
45
53
|
getJobsRecursive: (site, status, priority, type, lastKey, jobs = []) => {
|
|
46
|
-
return new Promise((resolve) => {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
47
55
|
maintenanceActions
|
|
48
56
|
.getJobs2(site, status, priority, type, lastKey)
|
|
49
57
|
.then((jobRes) => {
|
|
@@ -51,17 +59,19 @@ export const maintenanceActions = {
|
|
|
51
59
|
if (!jobRes.data.LastKey) {
|
|
52
60
|
return resolve(newJobs);
|
|
53
61
|
}
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
maintenanceActions
|
|
63
|
+
.getJobsRecursive(
|
|
56
64
|
site,
|
|
57
65
|
status,
|
|
58
66
|
priority,
|
|
59
67
|
type,
|
|
60
68
|
jobRes.data.LastKey,
|
|
61
69
|
newJobs,
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
)
|
|
71
|
+
.then(resolve)
|
|
72
|
+
.catch(reject);
|
|
73
|
+
})
|
|
74
|
+
.catch(reject);
|
|
65
75
|
});
|
|
66
76
|
},
|
|
67
77
|
sendMaintenanceRequest: (
|
|
@@ -25,6 +25,9 @@ class MaintenanceList extends Component {
|
|
|
25
25
|
types: [],
|
|
26
26
|
filteredList: props.jobs,
|
|
27
27
|
loading: false,
|
|
28
|
+
loadingMore: false,
|
|
29
|
+
hasMore: true,
|
|
30
|
+
lastKey: null,
|
|
28
31
|
searchText: "",
|
|
29
32
|
showFilterPopup: false,
|
|
30
33
|
};
|
|
@@ -51,22 +54,25 @@ class MaintenanceList extends Component {
|
|
|
51
54
|
this.onLoadingChanged(true, async () => {
|
|
52
55
|
try {
|
|
53
56
|
const { jobfilters } = this.props;
|
|
54
|
-
const res = await maintenanceActions.
|
|
57
|
+
const res = await maintenanceActions.getJobs2(
|
|
55
58
|
this.props.site,
|
|
56
59
|
jobfilters.status,
|
|
57
60
|
jobfilters.priority,
|
|
58
61
|
jobfilters.type,
|
|
62
|
+
null, // No lastKey = first page
|
|
63
|
+
jobfilters.assignee,
|
|
59
64
|
);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
|
|
66
|
+
const jobs = res.data.Items;
|
|
67
|
+
const lastKey = res.data.LastKey;
|
|
68
|
+
|
|
69
|
+
// Always replace jobs on refresh (filters are server-side)
|
|
70
|
+
this.props.jobsLoaded(jobs);
|
|
71
|
+
|
|
72
|
+
this.setState({
|
|
73
|
+
lastKey,
|
|
74
|
+
hasMore: !!lastKey,
|
|
75
|
+
});
|
|
70
76
|
} catch (error) {
|
|
71
77
|
console.log("refresh error", error);
|
|
72
78
|
} finally {
|
|
@@ -75,6 +81,42 @@ class MaintenanceList extends Component {
|
|
|
75
81
|
});
|
|
76
82
|
};
|
|
77
83
|
|
|
84
|
+
loadMore = () => {
|
|
85
|
+
const { loading, loadingMore, hasMore, lastKey, searchText } = this.state;
|
|
86
|
+
|
|
87
|
+
// Don't load if already loading, no more pages, or during search
|
|
88
|
+
if (loading || loadingMore || !hasMore || !lastKey || searchText) return;
|
|
89
|
+
|
|
90
|
+
this.setState({ loadingMore: true }, async () => {
|
|
91
|
+
try {
|
|
92
|
+
const { jobfilters } = this.props;
|
|
93
|
+
const res = await maintenanceActions.getJobs2(
|
|
94
|
+
this.props.site,
|
|
95
|
+
jobfilters.status,
|
|
96
|
+
jobfilters.priority,
|
|
97
|
+
jobfilters.type,
|
|
98
|
+
lastKey,
|
|
99
|
+
jobfilters.assignee,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const newJobs = res.data.Items;
|
|
103
|
+
const newLastKey = res.data.LastKey;
|
|
104
|
+
|
|
105
|
+
// Append to existing jobs
|
|
106
|
+
this.props.jobsAdded(newJobs);
|
|
107
|
+
|
|
108
|
+
this.setState({
|
|
109
|
+
lastKey: newLastKey,
|
|
110
|
+
hasMore: !!newLastKey,
|
|
111
|
+
});
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.log("loadMore error", error);
|
|
114
|
+
} finally {
|
|
115
|
+
this.setState({ loadingMore: false });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
78
120
|
refreshTypes = async () => {
|
|
79
121
|
const { data } = await maintenanceActions.getJobTypes(
|
|
80
122
|
Helper.getSite(this.props.site),
|
|
@@ -116,12 +158,13 @@ class MaintenanceList extends Component {
|
|
|
116
158
|
}
|
|
117
159
|
|
|
118
160
|
resetDataSource = (source = "") => {
|
|
119
|
-
const { jobfilters } = this.props;
|
|
120
161
|
const { searchText } = this.state;
|
|
121
162
|
const { jobs } = this.props;
|
|
122
163
|
|
|
123
164
|
let filteredList = jobs;
|
|
124
165
|
let jobIdMatch = null;
|
|
166
|
+
|
|
167
|
+
// Client-side search filtering (search is not supported server-side)
|
|
125
168
|
if (searchText) {
|
|
126
169
|
jobIdMatch = _.find(jobs, (j) => j.jobId === searchText);
|
|
127
170
|
filteredList = jobs.filter((j) => {
|
|
@@ -135,22 +178,10 @@ class MaintenanceList extends Component {
|
|
|
135
178
|
});
|
|
136
179
|
if (!jobIdMatch) this.fetchJob(searchText);
|
|
137
180
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (jobfilters.priority)
|
|
143
|
-
filteredList = filteredList.filter((j) =>
|
|
144
|
-
jobfilters.priority.includes(j.priority),
|
|
145
|
-
);
|
|
146
|
-
if (jobfilters.type)
|
|
147
|
-
filteredList = filteredList.filter((j) =>
|
|
148
|
-
jobfilters.type.includes(j.type),
|
|
149
|
-
);
|
|
150
|
-
if (jobfilters.assignee)
|
|
151
|
-
filteredList = filteredList.filter((j) =>
|
|
152
|
-
jobfilters.assignee.includes(j.AssigneeId),
|
|
153
|
-
);
|
|
181
|
+
|
|
182
|
+
// Note: status, priority, type, and assignee filters are applied server-side
|
|
183
|
+
// via getJobs2, so no client-side filtering needed for those
|
|
184
|
+
|
|
154
185
|
if (jobIdMatch) {
|
|
155
186
|
const jobIndex = filteredList.indexOf(jobIdMatch);
|
|
156
187
|
if (jobIndex > -1) {
|
|
@@ -158,7 +189,8 @@ class MaintenanceList extends Component {
|
|
|
158
189
|
}
|
|
159
190
|
filteredList.unshift(jobIdMatch);
|
|
160
191
|
}
|
|
161
|
-
|
|
192
|
+
// Only refresh on initial load, not on filter changes (pagination handles data)
|
|
193
|
+
if (source !== "search" && source !== "filter") this.refresh();
|
|
162
194
|
|
|
163
195
|
this.setState({ filteredList });
|
|
164
196
|
};
|
|
@@ -188,6 +220,10 @@ class MaintenanceList extends Component {
|
|
|
188
220
|
onSelectFilter = (selected) => {
|
|
189
221
|
this.props.jobsFilterLoaded(selected);
|
|
190
222
|
this.onToggleFilter();
|
|
223
|
+
// Reset pagination and clear existing list before refresh
|
|
224
|
+
this.setState({ lastKey: null, hasMore: true, filteredList: [] }, () => {
|
|
225
|
+
this.refresh();
|
|
226
|
+
});
|
|
191
227
|
};
|
|
192
228
|
|
|
193
229
|
getFilterButtonText = () => {
|
|
@@ -286,10 +322,23 @@ class MaintenanceList extends Component {
|
|
|
286
322
|
)}
|
|
287
323
|
ListEmptyComponent={this.renderEmptyList()}
|
|
288
324
|
ListHeaderComponent={this.renderListHeader()}
|
|
325
|
+
ListFooterComponent={this.renderListFooter()}
|
|
326
|
+
onEndReached={this.loadMore}
|
|
327
|
+
onEndReachedThreshold={0.5}
|
|
289
328
|
/>
|
|
290
329
|
);
|
|
291
330
|
}
|
|
292
331
|
|
|
332
|
+
renderListFooter = () => {
|
|
333
|
+
if (!this.state.loadingMore) return null;
|
|
334
|
+
|
|
335
|
+
return (
|
|
336
|
+
<View style={styles.loadingMore}>
|
|
337
|
+
<Components.LoadingIndicator visible={true} />
|
|
338
|
+
</View>
|
|
339
|
+
);
|
|
340
|
+
};
|
|
341
|
+
|
|
293
342
|
renderFilterPopup() {
|
|
294
343
|
const { jobfilters } = this.props;
|
|
295
344
|
const { showFilterPopup, types } = this.state;
|
|
@@ -363,6 +412,10 @@ const styles = StyleSheet.create({
|
|
|
363
412
|
fontFamily: "sf-semibold",
|
|
364
413
|
fontSize: 16,
|
|
365
414
|
},
|
|
415
|
+
loadingMore: {
|
|
416
|
+
paddingVertical: 20,
|
|
417
|
+
alignItems: "center",
|
|
418
|
+
},
|
|
366
419
|
});
|
|
367
420
|
|
|
368
421
|
const mapStateToProps = (state) => {
|
|
@@ -80,13 +80,19 @@ class RequestDetail extends Component {
|
|
|
80
80
|
this.getExternalSync();
|
|
81
81
|
} catch (error) {
|
|
82
82
|
console.log("getJob error", error.toString());
|
|
83
|
-
//
|
|
84
|
-
|
|
83
|
+
// Log full error details for debugging
|
|
84
|
+
console.log("getJob error details:", {
|
|
85
|
+
message: error.message,
|
|
86
|
+
code: error.code,
|
|
87
|
+
responseStatus: error.response?.status,
|
|
88
|
+
responseData: error.response?.data,
|
|
89
|
+
});
|
|
90
|
+
// check for 403 or 404 error (use optional chaining to prevent crash)
|
|
91
|
+
if (error.response?.status === 403 || error.response?.status === 404) {
|
|
85
92
|
this.setState({
|
|
86
93
|
forbidden: true,
|
|
87
94
|
});
|
|
88
95
|
}
|
|
89
|
-
console.log("getJob error", error);
|
|
90
96
|
} finally {
|
|
91
97
|
this.setState({ loading: false });
|
|
92
98
|
}
|
|
@@ -572,9 +572,13 @@ class MaintenanceRequest extends Component {
|
|
|
572
572
|
return field;
|
|
573
573
|
});
|
|
574
574
|
|
|
575
|
+
const userID = this.state.canCreateOnBehalf && this.state.selectedUser
|
|
576
|
+
? (this.state.selectedUser.userId || this.state.selectedUser.Id)
|
|
577
|
+
: this.props.uid;
|
|
578
|
+
|
|
575
579
|
maintenanceActions
|
|
576
580
|
.sendMaintenanceRequest(
|
|
577
|
-
|
|
581
|
+
userID,
|
|
578
582
|
this.state.userName,
|
|
579
583
|
this.state.phone,
|
|
580
584
|
this.state.roomNumber,
|