@plusscommunities/pluss-maintenance-app 7.0.0-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.
- package/dist/module/actions/JobActions.js +44 -1
- package/dist/module/actions/JobActions.js.map +1 -1
- package/dist/module/actions/types.js +3 -0
- package/dist/module/actions/types.js.map +1 -1
- package/dist/module/apis/index.js +2 -0
- package/dist/module/apis/index.js.map +1 -1
- package/dist/module/apis/maintenanceActions.js +21 -6
- package/dist/module/apis/maintenanceActions.js.map +1 -1
- package/dist/module/components/FilterPopupMenu.js +34 -18
- package/dist/module/components/FilterPopupMenu.js.map +1 -1
- package/dist/module/components/MaintenanceList.js +47 -56
- package/dist/module/components/MaintenanceList.js.map +1 -1
- package/dist/module/components/MaintenanceListItem.js +39 -26
- package/dist/module/components/MaintenanceListItem.js.map +1 -1
- package/dist/module/components/MaintenanceWidgetItem.js +12 -12
- package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
- package/dist/module/components/PrioritySelectorPopup.js +82 -0
- package/dist/module/components/PrioritySelectorPopup.js.map +1 -0
- package/dist/module/components/StatusSelectorPopup.js +9 -14
- package/dist/module/components/StatusSelectorPopup.js.map +1 -1
- package/dist/module/components/WidgetSmall.js +7 -3
- package/dist/module/components/WidgetSmall.js.map +1 -1
- package/dist/module/helper.js +39 -25
- package/dist/module/helper.js.map +1 -1
- package/dist/module/reducers/JobsReducer.js +31 -2
- package/dist/module/reducers/JobsReducer.js.map +1 -1
- package/dist/module/screens/RequestDetail.js +90 -18
- package/dist/module/screens/RequestDetail.js.map +1 -1
- package/dist/module/screens/RequestNotes.js +430 -21
- package/dist/module/screens/RequestNotes.js.map +1 -1
- package/dist/module/values.config.a.js +6 -1
- package/dist/module/values.config.a.js.map +1 -1
- package/dist/module/values.config.default.js +6 -1
- package/dist/module/values.config.default.js.map +1 -1
- package/dist/module/values.config.forms.js +6 -1
- package/dist/module/values.config.forms.js.map +1 -1
- package/dist/module/values.config.js +34 -29
- package/dist/module/values.config.js.map +1 -1
- package/package.json +2 -2
- package/src/actions/JobActions.js +53 -1
- package/src/actions/types.js +4 -0
- package/src/apis/index.js +4 -0
- package/src/apis/maintenanceActions.js +18 -6
- package/src/components/FilterPopupMenu.js +40 -21
- package/src/components/MaintenanceList.js +38 -47
- package/src/components/MaintenanceListItem.js +35 -21
- package/src/components/MaintenanceWidgetItem.js +16 -12
- package/src/components/PrioritySelectorPopup.js +79 -0
- package/src/components/StatusSelectorPopup.js +8 -14
- package/src/components/WidgetSmall.js +5 -3
- package/src/helper.js +50 -21
- package/src/reducers/JobsReducer.js +25 -1
- package/src/screens/RequestDetail.js +87 -24
- package/src/screens/RequestNotes.js +429 -30
- package/src/values.config.a.js +5 -0
- package/src/values.config.default.js +5 -0
- package/src/values.config.forms.js +5 -0
- package/src/values.config.js +34 -29
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
|
-
|
7
|
-
|
9
|
+
text: 'Open',
|
10
|
+
order: 0,
|
8
11
|
color: Colours.LINEGREY,
|
12
|
+
category: STATUS_NOT_ACTIONED,
|
9
13
|
},
|
10
14
|
{
|
11
|
-
|
12
|
-
|
15
|
+
text: 'In Progress',
|
16
|
+
order: 1,
|
13
17
|
color: Colours.COLOUR_TEAL,
|
18
|
+
category: STATUS_IN_PROGRESS,
|
14
19
|
},
|
15
20
|
{
|
16
|
-
|
17
|
-
|
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
|
23
|
-
|
24
|
-
|
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
|
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
|
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
|
-
|
37
|
-
};
|
48
|
+
const getIncompleteJobStatuses = props => getJobStatusOptions(props).filter(s => s.category === STATUS_IN_PROGRESS);
|
38
49
|
|
39
|
-
|
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]) {
|
@@ -6,9 +6,10 @@ import _ from 'lodash';
|
|
6
6
|
import moment from 'moment';
|
7
7
|
import { connect } from 'react-redux';
|
8
8
|
import { maintenanceActions } from '../apis';
|
9
|
-
import { jobAdded } from '../actions';
|
9
|
+
import { jobAdded, jobStatusesUpdate, jobHideSeenUpdate } from '../actions';
|
10
10
|
import StatusSelectorPopup from '../components/StatusSelectorPopup';
|
11
|
-
import
|
11
|
+
import PrioritySelectorPopup from '../components/PrioritySelectorPopup';
|
12
|
+
import { getJobStatus, getJobPriority } from '../helper';
|
12
13
|
import { Services } from '../feature.config';
|
13
14
|
import { Colours, Helper, Components, Config } from '../core.config';
|
14
15
|
import { values } from '../values.config';
|
@@ -22,11 +23,13 @@ class RequestDetail extends Component {
|
|
22
23
|
isDateTimePickerVisible: false,
|
23
24
|
popUpType: '',
|
24
25
|
status: '',
|
26
|
+
priority: '',
|
25
27
|
expectedDate: null,
|
26
28
|
expectedDateText: '',
|
27
29
|
seen: false,
|
28
30
|
showMore: true,
|
29
31
|
showStatusPopup: false,
|
32
|
+
showPriorityPopup: false,
|
30
33
|
loading: false,
|
31
34
|
showFullscreenVideo: false,
|
32
35
|
currentVideoUrl: '',
|
@@ -42,6 +45,8 @@ class RequestDetail extends Component {
|
|
42
45
|
}
|
43
46
|
|
44
47
|
componentDidMount() {
|
48
|
+
this.props.jobStatusesUpdate(this.props.job.site);
|
49
|
+
this.props.jobHideSeenUpdate(this.props.job.site);
|
45
50
|
this.getJob();
|
46
51
|
this.updateJobState(this.props.job);
|
47
52
|
this.getAssignees();
|
@@ -51,6 +56,7 @@ class RequestDetail extends Component {
|
|
51
56
|
this.setState({ loading: true }, async () => {
|
52
57
|
try {
|
53
58
|
const res = await maintenanceActions.getJob(this.props.job.site, this.props.job.id);
|
59
|
+
// console.log('getJob', JSON.stringify(res.data, null, 2));
|
54
60
|
this.props.jobAdded(res.data);
|
55
61
|
this.updateJobState(res.data);
|
56
62
|
} catch (error) {
|
@@ -155,6 +161,20 @@ class RequestDetail extends Component {
|
|
155
161
|
});
|
156
162
|
};
|
157
163
|
|
164
|
+
updateJobPriority = () => {
|
165
|
+
this.setState({ loading: true }, async () => {
|
166
|
+
try {
|
167
|
+
const res = await maintenanceActions.editJobPriority(this.props.job.id, this.state.priority);
|
168
|
+
this.props.jobAdded(res.data.job);
|
169
|
+
this.getJob();
|
170
|
+
} catch (error) {
|
171
|
+
console.log('updateJobPriority error', error);
|
172
|
+
} finally {
|
173
|
+
this.setState({ loading: false });
|
174
|
+
}
|
175
|
+
});
|
176
|
+
};
|
177
|
+
|
158
178
|
onPressBack = () => {
|
159
179
|
Services.navigation.goBack();
|
160
180
|
};
|
@@ -168,11 +188,27 @@ class RequestDetail extends Component {
|
|
168
188
|
};
|
169
189
|
|
170
190
|
onSelectStatus = status => {
|
191
|
+
if (this.state.loading) return;
|
171
192
|
this.setState({ status, showStatusPopup: false }, () => {
|
172
193
|
this.updateJobStatus();
|
173
194
|
});
|
174
195
|
};
|
175
196
|
|
197
|
+
onOpenPriorityPicker = () => {
|
198
|
+
this.setState({ showPriorityPopup: true });
|
199
|
+
};
|
200
|
+
|
201
|
+
onClosePriorityPopup = () => {
|
202
|
+
this.setState({ showPriorityPopup: false });
|
203
|
+
};
|
204
|
+
|
205
|
+
onSelectPriority = priority => {
|
206
|
+
if (this.state.loading) return;
|
207
|
+
this.setState({ priority, showPriorityPopup: false }, () => {
|
208
|
+
this.updateJobPriority();
|
209
|
+
});
|
210
|
+
};
|
211
|
+
|
176
212
|
openStaffNotes = () => {
|
177
213
|
Services.navigation.navigate(values.screenRequestNotes, { job: this.state.job, onChange: this.getJob });
|
178
214
|
};
|
@@ -294,9 +330,11 @@ class RequestDetail extends Component {
|
|
294
330
|
|
295
331
|
renderTop() {
|
296
332
|
const { status, job } = this.state;
|
297
|
-
const
|
333
|
+
const statusOption = getJobStatus(status, this.props);
|
334
|
+
const priority = getJobPriority(job.priority);
|
298
335
|
const canEdit = this.hasPermission();
|
299
|
-
const
|
336
|
+
const isStaff = this.props.user.category === 'staff'
|
337
|
+
const showSeen = !status || status === getJobStatus(null, this.props).text;
|
300
338
|
|
301
339
|
return (
|
302
340
|
<View style={{ ...Helper.getShadowStyle() }}>
|
@@ -311,7 +349,7 @@ class RequestDetail extends Component {
|
|
311
349
|
{job.type}
|
312
350
|
</Text>
|
313
351
|
</View>
|
314
|
-
{showSeen && this.state.seen && (
|
352
|
+
{!this.props.hideSeen && showSeen && this.state.seen && (
|
315
353
|
<View style={styles.jobSeenContainer}>
|
316
354
|
<Icon name="check" type="font-awesome" iconStyle={[styles.jobSeenIcon, { color: this.props.colourBrandingMain }]} />
|
317
355
|
<Text style={[styles.jobSeenText, { color: this.props.colourBrandingMain }]}>Seen</Text>
|
@@ -341,22 +379,34 @@ class RequestDetail extends Component {
|
|
341
379
|
</TouchableOpacity>
|
342
380
|
</View> */}
|
343
381
|
</View>
|
344
|
-
<View style={styles.
|
345
|
-
<View style={styles.
|
346
|
-
<
|
347
|
-
|
348
|
-
<
|
349
|
-
<
|
382
|
+
<View style={styles.jobInfoContainer}>
|
383
|
+
<View style={styles.jobStatusExpectedContainer}>
|
384
|
+
<View style={styles.jobStatusOuterContainer}>
|
385
|
+
<Text style={styles.jobStatusHeading}>STATUS</Text>
|
386
|
+
<TouchableOpacity onPress={canEdit ? this.onOpenStatusPicker : null}>
|
387
|
+
<View style={[styles.jobStatusContainer, { backgroundColor: statusOption.color }]}>
|
388
|
+
<Text style={styles.jobStatusText}>{statusOption?.text}</Text>
|
389
|
+
</View>
|
390
|
+
</TouchableOpacity>
|
391
|
+
</View>
|
392
|
+
{this.hasPermission() && (
|
393
|
+
<View style={styles.jobStatusOuterContainer}>
|
394
|
+
<Text style={styles.jobStatusHeading}>STAFF NOTES</Text>
|
395
|
+
<TouchableOpacity onPress={this.openStaffNotes}>
|
396
|
+
<View style={[styles.jobStatusContainer, { backgroundColor: this.props.colourBrandingMain }]}>
|
397
|
+
<Icon name="pencil-square-o" type="font-awesome" iconStyle={styles.jobStatusIcon} />
|
398
|
+
<Text style={styles.jobStatusText}>Notes ({(job.Notes || []).length})</Text>
|
399
|
+
</View>
|
400
|
+
</TouchableOpacity>
|
350
401
|
</View>
|
351
|
-
|
402
|
+
)}
|
352
403
|
</View>
|
353
|
-
{
|
354
|
-
<View style={styles.
|
355
|
-
<Text style={styles.jobStatusHeading}>
|
356
|
-
<TouchableOpacity onPress={this.
|
357
|
-
<View style={[styles.jobStatusContainer, { backgroundColor:
|
358
|
-
<
|
359
|
-
<Text style={styles.jobStatusText}>Notes ({(job.Notes || []).length})</Text>
|
404
|
+
{isStaff && (
|
405
|
+
<View style={styles.jobPriorityOuterContainer}>
|
406
|
+
<Text style={styles.jobStatusHeading}>PRIORITY</Text>
|
407
|
+
<TouchableOpacity onPress={canEdit ? this.onOpenPriorityPicker : null}>
|
408
|
+
<View style={[styles.jobStatusContainer, { backgroundColor: priority.color }]}>
|
409
|
+
<Text style={styles.jobStatusText}>{priority.label}</Text>
|
360
410
|
</View>
|
361
411
|
</TouchableOpacity>
|
362
412
|
</View>
|
@@ -603,6 +653,11 @@ class RequestDetail extends Component {
|
|
603
653
|
return <StatusSelectorPopup onClose={this.onCloseStatusPopup} onSelect={this.onSelectStatus} />;
|
604
654
|
}
|
605
655
|
|
656
|
+
renderPriorityPopup() {
|
657
|
+
if (!this.state.showPriorityPopup) return null;
|
658
|
+
return <PrioritySelectorPopup onClose={this.onClosePriorityPopup} onSelect={this.onSelectPriority} />;
|
659
|
+
}
|
660
|
+
|
606
661
|
render() {
|
607
662
|
if (this.state.forbidden) {
|
608
663
|
return <Components.Forbidden />;
|
@@ -621,6 +676,7 @@ class RequestDetail extends Component {
|
|
621
676
|
</ScrollView>
|
622
677
|
{this.renderMessagesReply()}
|
623
678
|
{this.renderStatusPopup()}
|
679
|
+
{this.renderPriorityPopup()}
|
624
680
|
{this.renderImagePopup()}
|
625
681
|
<DateTimePicker
|
626
682
|
isVisible={this.state.isDateTimePickerVisible}
|
@@ -694,15 +750,17 @@ const styles = StyleSheet.create({
|
|
694
750
|
fontSize: 13,
|
695
751
|
color: Colours.TEXT_LIGHT,
|
696
752
|
},
|
697
|
-
|
698
|
-
flexDirection: 'row',
|
699
|
-
alignItems: 'flex-start',
|
700
|
-
justifyContent: 'space-between',
|
753
|
+
jobInfoContainer: {
|
701
754
|
borderTopWidth: 1,
|
702
755
|
borderTopColor: Colours.LINEGREY,
|
703
756
|
paddingVertical: 14,
|
704
757
|
paddingHorizontal: 12,
|
705
758
|
},
|
759
|
+
jobStatusExpectedContainer: {
|
760
|
+
flexDirection: 'row',
|
761
|
+
alignItems: 'flex-start',
|
762
|
+
justifyContent: 'space-between',
|
763
|
+
},
|
706
764
|
jobStatusOuterContainer: {
|
707
765
|
// marginRight: 50,
|
708
766
|
},
|
@@ -734,6 +792,9 @@ const styles = StyleSheet.create({
|
|
734
792
|
flex: 1,
|
735
793
|
textAlign: 'center',
|
736
794
|
},
|
795
|
+
jobPriorityOuterContainer: {
|
796
|
+
marginTop: 12,
|
797
|
+
},
|
737
798
|
jobExpectedDateContainer: {
|
738
799
|
backgroundColor: Colours.BOXGREY,
|
739
800
|
flexDirection: 'row',
|
@@ -908,7 +969,9 @@ const mapStateToProps = state => {
|
|
908
969
|
user: state.user,
|
909
970
|
colourBrandingMain: Colours.getMainBrandingColourFromState(state),
|
910
971
|
jobs: state[values.reducerKey].jobs,
|
972
|
+
statusTypes: state[values.reducerKey].jobstatuses,
|
973
|
+
hideSeen: state[values.reducerKey].hideSeen,
|
911
974
|
};
|
912
975
|
};
|
913
976
|
|
914
|
-
export default connect(mapStateToProps, { jobAdded })(RequestDetail);
|
977
|
+
export default connect(mapStateToProps, { jobAdded, jobStatusesUpdate, jobHideSeenUpdate })(RequestDetail);
|