@plusscommunities/pluss-maintenance-app-forms 6.0.8-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 (90) hide show
  1. package/dist/module/actions/JobActions.js +20 -0
  2. package/dist/module/actions/JobActions.js.map +1 -0
  3. package/dist/module/actions/index.js +2 -0
  4. package/dist/module/actions/index.js.map +1 -0
  5. package/dist/module/actions/types.js +5 -0
  6. package/dist/module/actions/types.js.map +1 -0
  7. package/dist/module/apis/index.js +2 -0
  8. package/dist/module/apis/index.js.map +1 -0
  9. package/dist/module/apis/maintenanceActions.js +171 -0
  10. package/dist/module/apis/maintenanceActions.js.map +1 -0
  11. package/dist/module/components/FilterPopupMenu.js +271 -0
  12. package/dist/module/components/FilterPopupMenu.js.map +1 -0
  13. package/dist/module/components/MaintenanceList.js +360 -0
  14. package/dist/module/components/MaintenanceList.js.map +1 -0
  15. package/dist/module/components/MaintenanceListItem.js +322 -0
  16. package/dist/module/components/MaintenanceListItem.js.map +1 -0
  17. package/dist/module/components/MaintenanceWidgetItem.js +149 -0
  18. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -0
  19. package/dist/module/components/StatusSelectorPopup.js +89 -0
  20. package/dist/module/components/StatusSelectorPopup.js.map +1 -0
  21. package/dist/module/components/WidgetLarge.js +9 -0
  22. package/dist/module/components/WidgetLarge.js.map +1 -0
  23. package/dist/module/components/WidgetSmall.js +171 -0
  24. package/dist/module/components/WidgetSmall.js.map +1 -0
  25. package/dist/module/core.config.js +17 -0
  26. package/dist/module/core.config.js.map +1 -0
  27. package/dist/module/feature.config.js +75 -0
  28. package/dist/module/feature.config.js.map +1 -0
  29. package/dist/module/helper.js +33 -0
  30. package/dist/module/helper.js.map +1 -0
  31. package/dist/module/images/speechbubble.png +0 -0
  32. package/dist/module/index.js +25 -0
  33. package/dist/module/index.js.map +1 -0
  34. package/dist/module/reducers/JobsReducer.js +63 -0
  35. package/dist/module/reducers/JobsReducer.js.map +1 -0
  36. package/dist/module/screens/JobTypePicker.js +130 -0
  37. package/dist/module/screens/JobTypePicker.js.map +1 -0
  38. package/dist/module/screens/MaintenancePage.js +92 -0
  39. package/dist/module/screens/MaintenancePage.js.map +1 -0
  40. package/dist/module/screens/RequestDetail.js +980 -0
  41. package/dist/module/screens/RequestDetail.js.map +1 -0
  42. package/dist/module/screens/RequestNotes.js +390 -0
  43. package/dist/module/screens/RequestNotes.js.map +1 -0
  44. package/dist/module/screens/ServiceRequest.js +1243 -0
  45. package/dist/module/screens/ServiceRequest.js.map +1 -0
  46. package/dist/module/values.config.a.js +30 -0
  47. package/dist/module/values.config.a.js.map +1 -0
  48. package/dist/module/values.config.b.js +30 -0
  49. package/dist/module/values.config.b.js.map +1 -0
  50. package/dist/module/values.config.c.js +30 -0
  51. package/dist/module/values.config.c.js.map +1 -0
  52. package/dist/module/values.config.d.js +30 -0
  53. package/dist/module/values.config.d.js.map +1 -0
  54. package/dist/module/values.config.default.js +35 -0
  55. package/dist/module/values.config.default.js.map +1 -0
  56. package/dist/module/values.config.forms.js +35 -0
  57. package/dist/module/values.config.forms.js.map +1 -0
  58. package/dist/module/values.config.js +35 -0
  59. package/dist/module/values.config.js.map +1 -0
  60. package/package.json +53 -0
  61. package/src/actions/JobActions.js +22 -0
  62. package/src/actions/index.js +1 -0
  63. package/src/actions/types.js +5 -0
  64. package/src/apis/index.js +1 -0
  65. package/src/apis/maintenanceActions.js +163 -0
  66. package/src/components/FilterPopupMenu.js +256 -0
  67. package/src/components/MaintenanceList.js +335 -0
  68. package/src/components/MaintenanceListItem.js +289 -0
  69. package/src/components/MaintenanceWidgetItem.js +132 -0
  70. package/src/components/StatusSelectorPopup.js +87 -0
  71. package/src/components/WidgetLarge.js +10 -0
  72. package/src/components/WidgetSmall.js +152 -0
  73. package/src/core.config.js +5 -0
  74. package/src/feature.config.js +73 -0
  75. package/src/helper.js +39 -0
  76. package/src/images/speechbubble.png +0 -0
  77. package/src/index.js +25 -0
  78. package/src/reducers/JobsReducer.js +51 -0
  79. package/src/screens/JobTypePicker.js +107 -0
  80. package/src/screens/MaintenancePage.js +96 -0
  81. package/src/screens/RequestDetail.js +915 -0
  82. package/src/screens/RequestNotes.js +418 -0
  83. package/src/screens/ServiceRequest.js +1219 -0
  84. package/src/values.config.a.js +30 -0
  85. package/src/values.config.b.js +30 -0
  86. package/src/values.config.c.js +30 -0
  87. package/src/values.config.d.js +30 -0
  88. package/src/values.config.default.js +35 -0
  89. package/src/values.config.forms.js +35 -0
  90. package/src/values.config.js +35 -0
@@ -0,0 +1,163 @@
1
+ import { Helper, Session } from '../core.config';
2
+ import { values } from '../values.config';
3
+
4
+ export const maintenanceActions = {
5
+ getJob: (site, id) => {
6
+ return Session.authedFunction({
7
+ method: 'POST',
8
+ url: Helper.getUrl(values.serviceKey, 'getJob'),
9
+ data: { site, id },
10
+ });
11
+ },
12
+ getJobByJobId: (site, jobId) => {
13
+ return Session.authedFunction({
14
+ method: 'POST',
15
+ url: Helper.getUrl(values.serviceKey, 'getJob'),
16
+ data: { site, jobId },
17
+ });
18
+ },
19
+ getJobs: (site, status = '', type = '') => {
20
+ return Session.authedFunction({
21
+ method: 'POST',
22
+ url: Helper.getUrl(values.serviceKey, 'getJobs'),
23
+ data: { site, status, type },
24
+ });
25
+ },
26
+ getJobs2: (site, status, type, lastKey) => {
27
+ const query = { site };
28
+ if (status) {
29
+ query.status = status;
30
+ }
31
+ if (type) {
32
+ query.type = type;
33
+ }
34
+ if (lastKey) {
35
+ query.lastKey = JSON.stringify(lastKey);
36
+ }
37
+ return Session.authedFunction({
38
+ method: 'GET',
39
+ url: Helper.getUrl(values.serviceKey, 'get/requests', query),
40
+ });
41
+ },
42
+ getJobsRecursive: (site, status, type, lastKey, jobs = []) => {
43
+ return new Promise(resolve => {
44
+ maintenanceActions.getJobs2(site, status, type, lastKey).then(jobRes => {
45
+ const newJobs = [...jobs, ...jobRes.data.Items];
46
+ if (!jobRes.data.LastKey) {
47
+ return resolve(newJobs);
48
+ }
49
+ return resolve(maintenanceActions.getJobsRecursive(site, status, type, jobRes.data.LastKey, newJobs));
50
+ });
51
+ });
52
+ },
53
+ sendMaintenanceRequest: (
54
+ userID,
55
+ userName,
56
+ phone,
57
+ room,
58
+ title,
59
+ description,
60
+ date,
61
+ type,
62
+ images,
63
+ location,
64
+ isHome,
65
+ homeText,
66
+ customFields,
67
+ ) => {
68
+ const request = {
69
+ method: 'POST',
70
+ url: Helper.getUrl(values.serviceKey, 'sendMaintenance'),
71
+ data: {
72
+ userID,
73
+ userName,
74
+ phone,
75
+ room,
76
+ title,
77
+ description,
78
+ date,
79
+ type,
80
+ images,
81
+ location,
82
+ isHome,
83
+ homeText,
84
+ customFields,
85
+ },
86
+ };
87
+ return Session.authedFunction(request);
88
+ },
89
+ editJob: (job, site) => {
90
+ return Session.authedFunction({
91
+ method: 'POST',
92
+ url: Helper.getUrl(values.serviceKey, 'editJob'),
93
+ data: { job, site },
94
+ });
95
+ },
96
+ editJobStatus: (id, status) => {
97
+ return Session.authedFunction({
98
+ method: 'POST',
99
+ url: Helper.getUrl(values.serviceKey, 'editJobStatus'),
100
+ data: { id, status },
101
+ });
102
+ },
103
+ assignJob: (jobId, userId) => {
104
+ return Session.authedFunction({
105
+ method: 'POST',
106
+ url: Helper.getUrl(values.serviceKey, 'update/assign'),
107
+ data: {
108
+ id: jobId,
109
+ userId,
110
+ },
111
+ });
112
+ },
113
+ getAssignees: site => {
114
+ return Session.authedFunction({
115
+ method: 'GET',
116
+ url: Helper.getUrl(values.serviceKey, 'get/assignees', { site }),
117
+ });
118
+ },
119
+ addNote: (jobId, note, attachments) => {
120
+ return Session.authedFunction({
121
+ method: 'POST',
122
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
123
+ data: {
124
+ id: jobId,
125
+ note,
126
+ attachments,
127
+ action: 'AddNote',
128
+ },
129
+ });
130
+ },
131
+ editNote: (jobId, noteId, note, attachments) => {
132
+ return Session.authedFunction({
133
+ method: 'POST',
134
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
135
+ data: {
136
+ id: jobId,
137
+ note,
138
+ attachments,
139
+ noteId,
140
+ action: 'EditNote',
141
+ },
142
+ });
143
+ },
144
+ deleteNote: (jobId, noteId) => {
145
+ return Session.authedFunction({
146
+ method: 'POST',
147
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
148
+ data: {
149
+ id: jobId,
150
+ noteId,
151
+ action: 'DeleteNote',
152
+ },
153
+ });
154
+ },
155
+ getJobTypes: async site => {
156
+ const url = Helper.getUrl(values.serviceKey, 'getjobtypes');
157
+ return Session.authedFunction({
158
+ method: 'POST',
159
+ url,
160
+ data: { site },
161
+ });
162
+ },
163
+ };
@@ -0,0 +1,256 @@
1
+ import React, { Component } from 'react';
2
+ import { View, Text, TouchableOpacity, Modal, ScrollView, Dimensions } from 'react-native';
3
+ import { connect } from 'react-redux';
4
+ import _ from 'lodash';
5
+ import { maintenanceActions } from '../apis';
6
+ import { Colours, Helper } from '../core.config';
7
+
8
+ const SCREEN_HEIGHT = Dimensions.get('window').height;
9
+
10
+ class FilterPopupMenu extends Component {
11
+ constructor(props) {
12
+ super(props);
13
+
14
+ this.state = {
15
+ types: props.types || [],
16
+ selectedStatus: props.status || '',
17
+ selectedType: props.type || '',
18
+ selectedAssignee: props.assignee || '',
19
+ assignees: [],
20
+ };
21
+ this.statusOptions = [
22
+ {
23
+ label: 'All',
24
+ value: '',
25
+ },
26
+ {
27
+ label: 'Incomplete',
28
+ value: 'Unassigned|In Progress',
29
+ },
30
+ {
31
+ label: 'Open',
32
+ value: 'Unassigned',
33
+ },
34
+ {
35
+ label: 'In Progress',
36
+ value: 'In Progress',
37
+ },
38
+ {
39
+ label: 'Completed',
40
+ value: 'Completed',
41
+ },
42
+ ];
43
+ }
44
+
45
+ componentDidMount() {
46
+ this.getAssignees();
47
+ if (_.isEmpty(this.state.types)) this.refreshTypes();
48
+ }
49
+
50
+ componentDidUpdate(prevProps) {
51
+ if (prevProps.site !== this.props.site) {
52
+ this.refreshTypes();
53
+ }
54
+ }
55
+
56
+ getAssignees = async () => {
57
+ try {
58
+ const res = await maintenanceActions.getAssignees(this.props.site);
59
+ let assignees = res.data.Users.map(t => {
60
+ return { label: t.displayName, value: t.id };
61
+ });
62
+ assignees = _.orderBy(assignees, 'label');
63
+
64
+ assignees.splice(0, 0, { label: 'All', value: '' });
65
+
66
+ const newState = { assignees };
67
+
68
+ if (!assignees.some(a => a.value === this.state.selectedAssignee)) {
69
+ newState.selectedAssignee = '';
70
+ }
71
+ // console.log('refreshassignees', assignees);
72
+ this.setState(newState);
73
+ } catch (error) {
74
+ console.error('getAssignees', error);
75
+ }
76
+ };
77
+
78
+ refreshTypes = async () => {
79
+ const { data } = await maintenanceActions.getJobTypes(Helper.getSite(this.props.site));
80
+ const types = data.map(t => {
81
+ return { label: t.typeName, value: t.typeName };
82
+ });
83
+ types.splice(0, 0, { label: 'All', value: '' });
84
+ // console.log('refreshTypes', types);
85
+ this.setState({ types });
86
+ };
87
+
88
+ onSelectOption = (key, value) => {
89
+ const newState = {};
90
+ newState[key] = value;
91
+ this.setState(newState);
92
+ };
93
+
94
+ onDone = () => {
95
+ const { onClose } = this.props;
96
+ const { selectedStatus, selectedType, selectedAssignee } = this.state;
97
+ if (onClose)
98
+ onClose({
99
+ status: selectedStatus,
100
+ statusText: this.statusOptions.find(o => o.value === selectedStatus)?.label,
101
+ type: selectedType,
102
+ assignee: selectedAssignee,
103
+ assigneeName: this.state.assignees.find(a => a.value === selectedAssignee)?.label,
104
+ });
105
+ };
106
+
107
+ renderTitle() {
108
+ const { title } = this.props;
109
+ return (
110
+ <View style={styles.titleContainer}>
111
+ <Text style={styles.titleText}>{title || 'Filter By'}</Text>
112
+ </View>
113
+ );
114
+ }
115
+
116
+ renderCancel() {
117
+ const { colourBrandingMain, cancelText } = this.props;
118
+ return (
119
+ <TouchableOpacity onPress={this.onDone}>
120
+ <View style={styles.cancelContainer}>
121
+ <Text style={[styles.cancelText, { color: colourBrandingMain }]}>{cancelText || 'Done'}</Text>
122
+ </View>
123
+ </TouchableOpacity>
124
+ );
125
+ }
126
+
127
+ renderOptions(title, options, selectedKey) {
128
+ const { colourBrandingMain } = this.props;
129
+ return (
130
+ <View style={styles.optionsContainer}>
131
+ <Text style={styles.optionsTitle}>{title}</Text>
132
+ <View style={styles.options}>
133
+ {options.map(o => {
134
+ const selected = this.state[selectedKey];
135
+ const backgroundColor = o.value === selected ? colourBrandingMain : '#fff';
136
+ const color = o.value === selected ? '#fff' : colourBrandingMain;
137
+ return (
138
+ <TouchableOpacity key={o.label} onPress={() => this.onSelectOption(selectedKey, o.value)}>
139
+ <View style={[styles.optionContainer, { backgroundColor, borderColor: colourBrandingMain }]}>
140
+ <Text style={[styles.optionText, { color }]}>{o.label}</Text>
141
+ </View>
142
+ </TouchableOpacity>
143
+ );
144
+ })}
145
+ </View>
146
+ </View>
147
+ );
148
+ }
149
+
150
+ render() {
151
+ return (
152
+ <Modal visible transparent animationType="slide" onRequestClose={this.onDone}>
153
+ <View style={styles.container}>
154
+ <View style={styles.menu}>
155
+ {this.renderTitle()}
156
+ <ScrollView style={styles.optionContent}>
157
+ {this.renderOptions('Status', this.statusOptions, 'selectedStatus')}
158
+ {this.renderOptions('Type', this.state.types, 'selectedType')}
159
+ {this.renderOptions('Assigned To', this.state.assignees, 'selectedAssignee')}
160
+ </ScrollView>
161
+ {this.renderCancel()}
162
+ </View>
163
+ </View>
164
+ </Modal>
165
+ );
166
+ }
167
+ }
168
+
169
+ const styles = {
170
+ container: {
171
+ position: 'absolute',
172
+ bottom: 0,
173
+ left: 0,
174
+ right: 0,
175
+ top: 0,
176
+ backgroundColor: 'rgba(0,0,0,0.5)',
177
+ zIndex: 1000,
178
+ },
179
+ menu: {
180
+ position: 'absolute',
181
+ bottom: 0,
182
+ left: 0,
183
+ right: 0,
184
+ backgroundColor: '#fff',
185
+ borderTopLeftRadius: 12,
186
+ borderTopRightRadius: 12,
187
+ maxHeight: SCREEN_HEIGHT * 0.8,
188
+ },
189
+ cancelContainer: {
190
+ paddingVertical: 16,
191
+ borderColor: Colours.LINEGREY,
192
+ borderTopWidth: 1,
193
+ paddingHorizontal: 16,
194
+ },
195
+ cancelText: {
196
+ fontFamily: 'sf-medium',
197
+ fontSize: 16,
198
+ textAlign: 'center',
199
+ color: Colours.TEXT_DARK,
200
+ },
201
+ titleContainer: {
202
+ padding: 16,
203
+ borderColor: Colours.LINEGREY,
204
+ borderBottomWidth: 1,
205
+ },
206
+ titleText: {
207
+ fontFamily: 'sf-semibold',
208
+ fontSize: 16,
209
+ textAlign: 'center',
210
+ color: Colours.TEXT_DARK,
211
+ },
212
+ optionContent: {
213
+ paddingVertical: 10,
214
+ },
215
+ optionsContainer: {
216
+ marginHorizontal: 14,
217
+ },
218
+ optionsTitle: {
219
+ fontFamily: 'sf-semibold',
220
+ marginBottom: 4,
221
+ },
222
+ options: {
223
+ flex: 1,
224
+ flexDirection: 'row',
225
+ flexWrap: 'wrap',
226
+ },
227
+ optionContainer: {
228
+ flexDirection: 'row',
229
+ alignItems: 'center',
230
+ justifyContent: 'center',
231
+ minWidth: 50,
232
+ height: 30,
233
+ paddingHorizontal: 8,
234
+ borderRadius: 4,
235
+ borderWidth: 1,
236
+ marginRight: 8,
237
+ marginBottom: 8,
238
+ },
239
+ optionText: {
240
+ color: '#fff',
241
+ textAlign: 'center',
242
+ fontFamily: 'sf-semibold',
243
+ fontSize: 13,
244
+ },
245
+ };
246
+
247
+ const mapStateToProps = state => {
248
+ const { user } = state;
249
+
250
+ return {
251
+ site: user.site,
252
+ colourBrandingMain: Colours.getMainBrandingColourFromState(state),
253
+ };
254
+ };
255
+
256
+ export default connect(mapStateToProps, {})(FilterPopupMenu);