@plusscommunities/pluss-maintenance-app 6.0.6-auth.0 → 6.0.6-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 (67) hide show
  1. package/dist/module/actions/JobActions.js.map +1 -1
  2. package/dist/module/actions/index.js.map +1 -1
  3. package/dist/module/actions/types.js +4 -3
  4. package/dist/module/actions/types.js.map +1 -1
  5. package/dist/module/apis/index.js.map +1 -1
  6. package/dist/module/apis/maintenanceActions.js +17 -15
  7. package/dist/module/apis/maintenanceActions.js.map +1 -1
  8. package/dist/module/components/FilterPopupMenu.js +2 -2
  9. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  10. package/dist/module/components/MaintenanceList.js +6 -5
  11. package/dist/module/components/MaintenanceList.js.map +1 -1
  12. package/dist/module/components/MaintenanceListItem.js +5 -4
  13. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  14. package/dist/module/components/MaintenanceWidgetItem.js +4 -3
  15. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  16. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  17. package/dist/module/components/WidgetLarge.js.map +1 -1
  18. package/dist/module/components/WidgetSmall.js +8 -5
  19. package/dist/module/components/WidgetSmall.js.map +1 -1
  20. package/dist/module/core.config.js.map +1 -1
  21. package/dist/module/feature.config.js +18 -33
  22. package/dist/module/feature.config.js.map +1 -1
  23. package/dist/module/helper.js.map +1 -1
  24. package/dist/module/index.js +15 -10
  25. package/dist/module/index.js.map +1 -1
  26. package/dist/module/reducers/JobsReducer.js.map +1 -1
  27. package/dist/module/screens/JobTypePicker.js +2 -2
  28. package/dist/module/screens/JobTypePicker.js.map +1 -1
  29. package/dist/module/screens/MaintenancePage.js +9 -5
  30. package/dist/module/screens/MaintenancePage.js.map +1 -1
  31. package/dist/module/screens/RequestDetail.js +121 -41
  32. package/dist/module/screens/RequestDetail.js.map +1 -1
  33. package/dist/module/screens/RequestNotes.js +7 -4
  34. package/dist/module/screens/RequestNotes.js.map +1 -1
  35. package/dist/module/screens/ServiceRequest.js +554 -86
  36. package/dist/module/screens/ServiceRequest.js.map +1 -1
  37. package/dist/module/values.config.a.js +30 -0
  38. package/dist/module/values.config.a.js.map +1 -0
  39. package/dist/module/values.config.b.js +30 -0
  40. package/dist/module/values.config.b.js.map +1 -0
  41. package/dist/module/values.config.c.js +30 -0
  42. package/dist/module/values.config.c.js.map +1 -0
  43. package/dist/module/values.config.d.js +30 -0
  44. package/dist/module/values.config.d.js.map +1 -0
  45. package/dist/module/values.config.default.js +30 -0
  46. package/dist/module/values.config.default.js.map +1 -0
  47. package/dist/module/values.config.js +30 -0
  48. package/dist/module/values.config.js.map +1 -0
  49. package/package.json +9 -6
  50. package/src/actions/types.js +5 -3
  51. package/src/apis/maintenanceActions.js +30 -14
  52. package/src/components/MaintenanceList.js +5 -3
  53. package/src/components/MaintenanceListItem.js +7 -2
  54. package/src/components/MaintenanceWidgetItem.js +2 -1
  55. package/src/components/WidgetSmall.js +6 -3
  56. package/src/feature.config.js +18 -30
  57. package/src/index.js +15 -8
  58. package/src/screens/MaintenancePage.js +5 -4
  59. package/src/screens/RequestDetail.js +113 -42
  60. package/src/screens/RequestNotes.js +5 -2
  61. package/src/screens/ServiceRequest.js +591 -149
  62. package/src/values.config.a.js +30 -0
  63. package/src/values.config.b.js +30 -0
  64. package/src/values.config.c.js +30 -0
  65. package/src/values.config.d.js +30 -0
  66. package/src/values.config.default.js +30 -0
  67. package/src/values.config.js +30 -0
@@ -11,6 +11,7 @@ import StatusSelectorPopup from '../components/StatusSelectorPopup';
11
11
  import { jobStatusOptions, getJobStatusProps } from '../helper';
12
12
  import { Services } from '../feature.config';
13
13
  import { Colours, Helper, Components, Config } from '../core.config';
14
+ import { values } from '../values.config';
14
15
 
15
16
  class RequestDetail extends Component {
16
17
  constructor(props) {
@@ -30,6 +31,7 @@ class RequestDetail extends Component {
30
31
  showFullscreenVideo: false,
31
32
  currentVideoUrl: '',
32
33
  galleryOpen: false,
34
+ galleryImages: [],
33
35
  showMessages: false,
34
36
  assignees: [],
35
37
  };
@@ -41,23 +43,17 @@ class RequestDetail extends Component {
41
43
 
42
44
  componentDidMount() {
43
45
  this.getJob();
44
- this.updateJobState();
46
+ this.updateJobState(this.props.job);
45
47
  this.getAssignees();
46
48
  }
47
49
 
48
- componentDidUpdate(prevProps) {
49
- if (prevProps.jobs !== this.props.jobs) {
50
- this.updateJobState();
51
- }
52
- }
53
-
54
50
  getJob = async () => {
55
51
  console.log('getting job');
56
52
  this.setState({ loading: true }, async () => {
57
53
  try {
58
54
  const res = await maintenanceActions.getJob(this.props.job.site, this.props.job.id);
59
55
  this.props.jobAdded(res.data);
60
- console.log('got the job');
56
+ this.updateJobState(res.data);
61
57
  } catch (error) {
62
58
  console.log('getJob error', error.toString());
63
59
  // check for 403 or 404 error
@@ -83,8 +79,12 @@ class RequestDetail extends Component {
83
79
  }
84
80
  };
85
81
 
86
- updateJobState() {
87
- const job = _.find(this.props.jobs, j => j.id === this.props.job.id) || this.props.job;
82
+ updateJobState(defaultJob) {
83
+ const job = _.find(this.props.jobs, j => j.id === this.props.job.id) || defaultJob;
84
+ if (!job) {
85
+ this.getJob();
86
+ return;
87
+ }
88
88
  const newState = { job, status: job.status };
89
89
  if (job.expectedDate) {
90
90
  newState.expectedDate = moment(job.expectedDate);
@@ -111,6 +111,7 @@ class RequestDetail extends Component {
111
111
  const res = await maintenanceActions.editJob(updated, user.site);
112
112
  // console.log('markSeen updated');
113
113
  this.props.jobAdded(res.data.job);
114
+ this.getJob();
114
115
  this.setState({ loading: false, seen: true });
115
116
  } catch (error) {
116
117
  console.log('markSeen error', error);
@@ -132,6 +133,7 @@ class RequestDetail extends Component {
132
133
  }
133
134
  const res = await maintenanceActions.editJob(updated, user.site);
134
135
  this.props.jobAdded(res.data.job);
136
+ this.getJob();
135
137
  } catch (error) {
136
138
  console.log('updateJob error', error);
137
139
  } finally {
@@ -145,6 +147,7 @@ class RequestDetail extends Component {
145
147
  try {
146
148
  const res = await maintenanceActions.editJobStatus(this.props.job.id, this.state.status);
147
149
  this.props.jobAdded(res.data.job);
150
+ this.getJob();
148
151
  } catch (error) {
149
152
  console.log('updateJobStatus error', error);
150
153
  } finally {
@@ -172,7 +175,7 @@ class RequestDetail extends Component {
172
175
  };
173
176
 
174
177
  openStaffNotes = () => {
175
- Services.navigation.navigate('requestNotes', { job: this.state.job });
178
+ Services.navigation.navigate(values.screenRequestNotes, { job: this.state.job, onChange: this.getJob });
176
179
  };
177
180
 
178
181
  onOpenDatePicker = () => {
@@ -219,6 +222,7 @@ class RequestDetail extends Component {
219
222
  const job = await maintenanceActions.getJob(this.props.user.site, this.props.job.id);
220
223
  // console.log('onCommentAdded', job?.data);
221
224
  this.props.jobAdded(job.data);
225
+ this.getJob();
222
226
  } catch (error) {
223
227
  console.log('onCommentAdded error', error);
224
228
  } finally {
@@ -230,10 +234,10 @@ class RequestDetail extends Component {
230
234
  hasPermission = () => {
231
235
  const { job } = this.state;
232
236
  const { permissions } = this.props.user;
233
- if (_.includes(permissions, 'maintenanceTracking')) {
237
+ if (_.includes(permissions, values.permissionMaintenanceTracking)) {
234
238
  return true;
235
239
  }
236
- if (_.includes(permissions, 'maintenanceAssignment')) {
240
+ if (_.includes(permissions, values.permissionMaintenanceAssign)) {
237
241
  return job.AssigneeId === this.props.user.Id;
238
242
  }
239
243
  return false;
@@ -244,9 +248,10 @@ class RequestDetail extends Component {
244
248
  this.setState({ showFullscreenVideo: url.length > 0, currentVideoUrl: url });
245
249
  };
246
250
 
247
- openGallery(index) {
251
+ openGallery(galleryImages, index) {
248
252
  this.setState({
249
253
  galleryOpen: true,
254
+ galleryImages,
250
255
  });
251
256
  this.refs.imagePopup.scrollTo(index);
252
257
  }
@@ -275,6 +280,7 @@ class RequestDetail extends Component {
275
280
  console.log('onSelectAssignee', this.props.job.id, assignee.key);
276
281
  const res = await maintenanceActions.assignJob(this.props.job.id, assignee.key);
277
282
  this.props.jobAdded(res.data.job);
283
+ this.getJob();
278
284
  } catch (error) {
279
285
  console.log('onSelectAssignee error', error);
280
286
  } finally {
@@ -296,7 +302,9 @@ class RequestDetail extends Component {
296
302
  return (
297
303
  <View style={{ ...Helper.getShadowStyle() }}>
298
304
  <View style={styles.jobTitleContainer}>
299
- {job.jobId ? <Text style={[styles.jobIdText, { color: this.props.colourBrandingMain }]}>{`Job #${job.jobId}`}</Text> : null}
305
+ {job.jobId ? (
306
+ <Text style={[styles.jobIdText, { color: this.props.colourBrandingMain }]}>{`${values.textEntityName} #${job.jobId}`}</Text>
307
+ ) : null}
300
308
  <Text style={styles.jobTitleText}>{job.title}</Text>
301
309
  <View style={styles.jobTypeSeenContainer}>
302
310
  <View style={[styles.jobTypeContainer, { backgroundColor: Colours.hexToRGBAstring(this.props.colourBrandingMain, 0.2) }]}>
@@ -359,7 +367,8 @@ class RequestDetail extends Component {
359
367
  );
360
368
  }
361
369
 
362
- renderPlayableImageUrl(url, index, containerStyle, showMore) {
370
+ renderPlayableImageUrl(images, index, containerStyle, showMore) {
371
+ const url = images[index || 0];
363
372
  const thumbUrl = Helper.getThumb300(url);
364
373
 
365
374
  if (Helper.isVideo(url)) {
@@ -376,7 +385,7 @@ class RequestDetail extends Component {
376
385
 
377
386
  const imageUrl = Helper.get1400(url);
378
387
  return (
379
- <TouchableOpacity style={containerStyle} onPress={this.openGallery.bind(this, index || 0)}>
388
+ <TouchableOpacity style={containerStyle} onPress={this.openGallery.bind(this, images, index || 0)}>
380
389
  <ImageBackground style={styles.imageContainer} source={{ uri: imageUrl }}>
381
390
  {showMore && <Text style={styles.plusImages}>+{this.state.job.images.length - 2}</Text>}
382
391
  </ImageBackground>
@@ -384,26 +393,24 @@ class RequestDetail extends Component {
384
393
  );
385
394
  }
386
395
 
387
- renderPlayableImage(index, containerStyle, showMore) {
388
- const url = this.state.job.images[index];
389
- return this.renderPlayableImageUrl(url, index, containerStyle, showMore);
396
+ renderPlayableImage(images, index, containerStyle, showMore) {
397
+ return this.renderPlayableImageUrl(images, index, containerStyle, showMore);
390
398
  }
391
399
 
392
- renderImage() {
393
- const { job } = this.state;
394
- if (!_.isNil(job.images) && !_.isEmpty(job.images)) {
395
- if (job.images.length >= 2) {
400
+ renderImage(images, image = null) {
401
+ if (!_.isNil(images) && !_.isEmpty(images)) {
402
+ if (images.length >= 2) {
396
403
  return (
397
404
  <View style={styles.sideBySideImages}>
398
- {this.renderPlayableImage(0, styles.sideBySideImageContainer)}
399
- {this.renderPlayableImage(1, styles.sideBySideImageContainer, job.images.length > 2)}
405
+ {this.renderPlayableImage(images, 0, styles.sideBySideImageContainer)}
406
+ {this.renderPlayableImage(images, 1, styles.sideBySideImageContainer, images.length > 2)}
400
407
  </View>
401
408
  );
402
409
  } else {
403
- return <View style={styles.singleImageContainer}>{this.renderPlayableImage(0)}</View>;
410
+ return <View style={styles.singleImageContainer}>{this.renderPlayableImage(images, 0)}</View>;
404
411
  }
405
- } else if (!_.isNil(job.image)) {
406
- return <View style={styles.singleImageContainer}>{this.renderPlayableImageUrl(job.image)}</View>;
412
+ } else if (!_.isNil(image)) {
413
+ return <View style={styles.singleImageContainer}>{this.renderPlayableImageUrl([image], 0)}</View>;
407
414
  }
408
415
  return null;
409
416
  }
@@ -412,7 +419,7 @@ class RequestDetail extends Component {
412
419
  return (
413
420
  <Components.ImagePopup
414
421
  visible={this.state.galleryOpen}
415
- images={this.state.job.images || [this.state.job.image]}
422
+ images={this.state.galleryImages}
416
423
  onClose={this.closeGallery.bind(this)}
417
424
  ref="imagePopup"
418
425
  />
@@ -455,8 +462,43 @@ class RequestDetail extends Component {
455
462
  return content;
456
463
  }
457
464
 
465
+ renderCustomFields() {
466
+ const { job } = this.state;
467
+ const { customFields } = job;
468
+
469
+ const renderAnswer = field => {
470
+ switch (field.type) {
471
+ case 'date':
472
+ return <Text style={styles.customText}>{field.answer ? moment(field.answer, 'YYYY-MM-DD').format('DD MMM YYYY') : ''}</Text>;
473
+ case 'time':
474
+ return <Text style={styles.customText}>{field.answer ? moment(field.answer, 'HH:mm').format('h:mm a') : ''}</Text>;
475
+ case 'yn':
476
+ return <Text style={styles.customText}>{field.answer ? 'Yes' : 'No'}</Text>;
477
+ case 'checkbox':
478
+ return <Text style={styles.customText}>{field.answer && Array.isArray(field.answer) ? field.answer.join(', ') : ''}</Text>;
479
+ case 'image':
480
+ return <View style={{ marginTop: 8 }}>{this.renderImage(field.answer)}</View>;
481
+ default:
482
+ return <Text style={styles.customText}>{field.answer}</Text>;
483
+ }
484
+ };
485
+
486
+ return customFields.map((field, index) => {
487
+ if (['staticTitle', 'staticText'].includes(field.type)) return null;
488
+ if (_.isNil(field.answer) || field.answer === '' || (Array.isArray(field.answer) && field.answer.length === 0)) return null;
489
+ return (
490
+ <View key={index}>
491
+ <Text style={styles.customLabel}>{field.label}</Text>
492
+ {renderAnswer(field)}
493
+ </View>
494
+ );
495
+ });
496
+ }
497
+
458
498
  rendeDetails() {
459
499
  const { job } = this.state;
500
+ const { customFields } = job;
501
+ const hasCustomFields = customFields && customFields.length > 0;
460
502
 
461
503
  return (
462
504
  <View>
@@ -469,15 +511,20 @@ class RequestDetail extends Component {
469
511
  />
470
512
  {this.state.showMore && (
471
513
  <View>
472
- {this.renderImage()}
473
- {!_.isEmpty(job.description) && (
474
- <Text numberOfLines={10} style={styles.jobDescriptionText}>
475
- {job.description}
476
- </Text>
477
- )}
478
- <Text style={styles.locationLabel}>Location</Text>
514
+ {hasCustomFields ? this.renderCustomFields() : null}
515
+ {!hasCustomFields ? (
516
+ <>
517
+ {this.renderImage(job.images, job.image)}
518
+ {!_.isEmpty(job.description) && (
519
+ <Text numberOfLines={10} style={styles.jobDescriptionText}>
520
+ {job.description}
521
+ </Text>
522
+ )}
523
+ </>
524
+ ) : null}
525
+ <Text style={styles.locationLabel}>Address</Text>
479
526
  <Text style={styles.locationText}>{job.room}</Text>
480
- {job.isHome ? (
527
+ {!hasCustomFields && job.isHome ? (
481
528
  <View style={styles.detailsSection}>
482
529
  <Text style={styles.locationLabel}>Must be home</Text>
483
530
  <Text style={styles.locationText}>{job.homeText}</Text>
@@ -504,8 +551,8 @@ class RequestDetail extends Component {
504
551
  ref={this.commentSection}
505
552
  commentReply={this.commentReply}
506
553
  scrollView={this.scrollView}
507
- adminPermission="maintenanceTracking"
508
- entityType="maintenancerequest"
554
+ adminPermission={values.permissionMaintenanceTracking}
555
+ entityType={values.featureKey}
509
556
  entityId={this.props.job.id}
510
557
  entityName={this.props.job.title}
511
558
  site={this.state.job.site || this.state.job.location}
@@ -542,7 +589,7 @@ class RequestDetail extends Component {
542
589
  ref={this.commentReply}
543
590
  commentSection={this.commentSection}
544
591
  scrollView={this.scrollView}
545
- entityType="maintenancerequest"
592
+ entityType={values.featureKey}
546
593
  entityId={this.props.job.id}
547
594
  entityName={this.props.job.title}
548
595
  site={this.state.job.site || this.state.job.location}
@@ -831,13 +878,37 @@ const styles = StyleSheet.create({
831
878
  marginLeft: 10,
832
879
  lineHeight: 24,
833
880
  },
881
+ customLabel: {
882
+ fontFamily: 'sf-bold',
883
+ fontSize: 14,
884
+ color: Colours.TEXT_DARKEST,
885
+ },
886
+ customText: {
887
+ fontFamily: 'sf-regular',
888
+ fontSize: 16,
889
+ color: Colours.TEXT_DARKEST,
890
+ paddingVertical: 8,
891
+ },
892
+ customStaticTitle: {
893
+ fontSize: 20,
894
+ fontFamily: 'sf-semibold',
895
+ color: Colours.TEXT_DARKEST,
896
+ marginBottom: 10,
897
+ },
898
+ customStaticText: {
899
+ fontSize: 17,
900
+ fontFamily: 'sf-regular',
901
+ color: Colours.TEXT_DARKEST,
902
+ lineHeight: 24,
903
+ marginBottom: 10,
904
+ },
834
905
  });
835
906
 
836
907
  const mapStateToProps = state => {
837
908
  return {
838
909
  user: state.user,
839
910
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
840
- jobs: state.jobs.jobs,
911
+ jobs: state[values.reducerKey].jobs,
841
912
  };
842
913
  };
843
914
 
@@ -1,5 +1,5 @@
1
1
  import React, { Component } from 'react';
2
- import { ScrollView, View, Text, TouchableOpacity, Modal, KeyboardAvoidingView } from 'react-native';
2
+ import { ScrollView, View, Text, TouchableOpacity, Modal, KeyboardAvoidingView, Platform } from 'react-native';
3
3
  import { connect } from 'react-redux';
4
4
  import { Icon } from 'react-native-elements';
5
5
  import _ from 'lodash';
@@ -9,6 +9,7 @@ import { maintenanceActions } from '../apis';
9
9
  import { getBottomSpace } from 'react-native-iphone-x-helper';
10
10
  import { Services } from '../feature.config';
11
11
  import { Components, Colours, Helper } from '../core.config';
12
+ import { values } from '../values.config';
12
13
 
13
14
  class RequestNotes extends Component {
14
15
  constructor(props) {
@@ -68,6 +69,7 @@ class RequestNotes extends Component {
68
69
  const newJob = { ...this.props.job };
69
70
  newJob.Notes = newNotes;
70
71
  this.props.jobAdded(newJob);
72
+ this.props.onChange && this.props.onChange();
71
73
  this.setState({
72
74
  job: newJob,
73
75
  noteToDelete: null,
@@ -158,6 +160,7 @@ class RequestNotes extends Component {
158
160
  },
159
161
  () => {
160
162
  this.props.jobAdded(res.data.job);
163
+ this.props.onChange && this.props.onChange();
161
164
  },
162
165
  );
163
166
  } catch (err) {
@@ -408,7 +411,7 @@ const mapStateToProps = state => {
408
411
  user: state.user,
409
412
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
410
413
  colourBrandingLight: Colours.getLightBrandingColourFromState(state),
411
- jobs: state.jobs.jobs,
414
+ jobs: state[values.reducerKey].jobs,
412
415
  };
413
416
  };
414
417