@plusscommunities/pluss-maintenance-app 8.0.6 → 8.0.7-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 +42 -34
  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 +18 -18
  44. package/dist/module/screens/MaintenanceUserPicker.js.map +1 -1
  45. package/dist/module/screens/RequestDetail.js +253 -138
  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 +34 -35
  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 +52 -52
  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 -172
  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 +116 -92
  88. package/src/screens/RequestDetail.js +1346 -1023
  89. package/src/screens/RequestNotes.js +946 -805
  90. package/src/screens/ServiceRequest.js +57 -34
  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,21 +1,21 @@
1
1
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
2
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
3
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
- import React, { Component } from 'react';
5
- import { ScrollView, View, StyleSheet, Text, KeyboardAvoidingView, TouchableOpacity, ImageBackground, Platform } from 'react-native';
6
- import DateTimePicker from 'react-native-modal-datetime-picker';
7
- import { Icon } from '@rneui/themed';
8
- import _ from 'lodash';
9
- import moment from 'moment';
10
- import { connect } from 'react-redux';
11
- import { maintenanceActions } from '../apis';
12
- import { jobAdded, jobStatusesUpdate, jobHideSeenUpdate } from '../actions';
13
- import StatusSelectorPopup from '../components/StatusSelectorPopup';
14
- import PrioritySelectorPopup from '../components/PrioritySelectorPopup';
15
- import { getJobStatus, getJobPriority } from '../helper';
16
- import { Services } from '../feature.config';
17
- import { Colours, Helper, Components, Config } from '../core.config';
18
- import { values } from '../values.config';
4
+ import React, { Component } from "react";
5
+ import { ScrollView, View, StyleSheet, Text, KeyboardAvoidingView, TouchableOpacity, ImageBackground, Platform } from "react-native";
6
+ import DateTimePicker from "react-native-modal-datetime-picker";
7
+ import { Icon } from "@rneui/themed";
8
+ import _ from "lodash";
9
+ import moment from "moment";
10
+ import { connect } from "react-redux";
11
+ import { maintenanceActions } from "../apis";
12
+ import { jobAdded, jobStatusesUpdate, jobHideSeenUpdate } from "../actions";
13
+ import StatusSelectorPopup from "../components/StatusSelectorPopup";
14
+ import PrioritySelectorPopup from "../components/PrioritySelectorPopup";
15
+ import { getJobStatus, getJobPriority } from "../helper";
16
+ import { Services } from "../feature.config";
17
+ import { Colours, Helper, Components, Config } from "../core.config";
18
+ import { values } from "../values.config";
19
19
  class RequestDetail extends Component {
20
20
  constructor(props) {
21
21
  super(props);
@@ -28,15 +28,17 @@ class RequestDetail extends Component {
28
28
  // console.log('getJob', JSON.stringify(res.data, null, 2));
29
29
  this.props.jobAdded(res.data);
30
30
  this.updateJobState(res.data);
31
+ // Refresh external sync data when job is refreshed
32
+ this.getExternalSync();
31
33
  } catch (error) {
32
- console.log('getJob error', error.toString());
34
+ console.log("getJob error", error.toString());
33
35
  // check for 403 or 404 error
34
36
  if (error.response.status === 403 || error.response.status === 404) {
35
37
  this.setState({
36
38
  forbidden: true
37
39
  });
38
40
  }
39
- console.log('getJob error', error);
41
+ console.log("getJob error", error);
40
42
  } finally {
41
43
  this.setState({
42
44
  loading: false
@@ -52,7 +54,32 @@ class RequestDetail extends Component {
52
54
  assignees: res.data.Users
53
55
  });
54
56
  } catch (error) {
55
- console.log('getAssignees error', error);
57
+ console.log("getAssignees error", error);
58
+ }
59
+ });
60
+ _defineProperty(this, "getExternalSync", async () => {
61
+ var _this$props$job;
62
+ // Only fetch if user has maintenance tracking permission
63
+ if (!this.hasPermission()) return;
64
+ if (!((_this$props$job = this.props.job) !== null && _this$props$job !== void 0 && _this$props$job.id)) return;
65
+ try {
66
+ this.setState({
67
+ loadingExternalSync: true
68
+ });
69
+ const res = await maintenanceActions.getExternalSync(this.props.job.id);
70
+ this.setState({
71
+ externalSync: res.data,
72
+ loadingExternalSync: false
73
+ });
74
+ } catch (error) {
75
+ var _error$response;
76
+ // 404 is expected if no sync - don't show error
77
+ if (((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) !== 404) {
78
+ console.log("getExternalSync error", error);
79
+ }
80
+ this.setState({
81
+ loadingExternalSync: false
82
+ });
56
83
  }
57
84
  });
58
85
  _defineProperty(this, "markSeen", () => {
@@ -74,7 +101,7 @@ class RequestDetail extends Component {
74
101
  const updated = {
75
102
  id: job.id,
76
103
  seen: true,
77
- status: job.status || 'Unassigned'
104
+ status: job.status || "Unassigned"
78
105
  };
79
106
  const res = await maintenanceActions.editJob(updated, user.site);
80
107
  // console.log('markSeen updated');
@@ -85,7 +112,7 @@ class RequestDetail extends Component {
85
112
  seen: true
86
113
  });
87
114
  } catch (error) {
88
- console.log('markSeen error', error);
115
+ console.log("markSeen error", error);
89
116
  this.setState({
90
117
  loading: false
91
118
  });
@@ -113,7 +140,7 @@ class RequestDetail extends Component {
113
140
  this.props.jobAdded(res.data.job);
114
141
  this.getJob();
115
142
  } catch (error) {
116
- console.log('updateJob error', error);
143
+ console.log("updateJob error", error);
117
144
  } finally {
118
145
  this.setState({
119
146
  loading: false
@@ -130,7 +157,7 @@ class RequestDetail extends Component {
130
157
  this.props.jobAdded(res.data.job);
131
158
  this.getJob();
132
159
  } catch (error) {
133
- console.log('updateJobStatus error', error);
160
+ console.log("updateJobStatus error", error);
134
161
  } finally {
135
162
  this.setState({
136
163
  loading: false
@@ -147,7 +174,7 @@ class RequestDetail extends Component {
147
174
  this.props.jobAdded(res.data.job);
148
175
  this.getJob();
149
176
  } catch (error) {
150
- console.log('updateJobPriority error', error);
177
+ console.log("updateJobPriority error", error);
151
178
  } finally {
152
179
  this.setState({
153
180
  loading: false
@@ -204,7 +231,7 @@ class RequestDetail extends Component {
204
231
  });
205
232
  _defineProperty(this, "onOpenDatePicker", () => {
206
233
  this.setState({
207
- popUpType: 'date',
234
+ popUpType: "date",
208
235
  isDateTimePickerVisible: true
209
236
  });
210
237
  });
@@ -214,11 +241,11 @@ class RequestDetail extends Component {
214
241
  });
215
242
  });
216
243
  _defineProperty(this, "onDateSelected", date => {
217
- if (this.state.popUpType === 'date') {
244
+ if (this.state.popUpType === "date") {
218
245
  date = moment(date);
219
246
  this.setState({
220
247
  expectedDate: date,
221
- expectedDateText: date.format('DD/MM/YYYY'),
248
+ expectedDateText: date.format("DD/MM/YYYY"),
222
249
  isDateTimePickerVisible: false
223
250
  }, () => {
224
251
  this.updateJob();
@@ -252,7 +279,7 @@ class RequestDetail extends Component {
252
279
  this.props.jobAdded(job.data);
253
280
  this.getJob();
254
281
  } catch (error) {
255
- console.log('onCommentAdded error', error);
282
+ console.log("onCommentAdded error", error);
256
283
  } finally {
257
284
  this.setState({
258
285
  loading: false
@@ -276,7 +303,7 @@ class RequestDetail extends Component {
276
303
  return false;
277
304
  });
278
305
  _defineProperty(this, "toggleFullscreenVideo", url => {
279
- if (typeof url !== 'string') url = '';
306
+ if (typeof url !== "string") url = "";
280
307
  this.setState({
281
308
  showFullscreenVideo: url.length > 0,
282
309
  currentVideoUrl: url
@@ -289,10 +316,10 @@ class RequestDetail extends Component {
289
316
  name: a.displayName
290
317
  };
291
318
  });
292
- Services.navigation.navigate('optionSelector', {
319
+ Services.navigation.navigate("optionSelector", {
293
320
  options,
294
321
  selection: this.state.job.AssigneeId,
295
- title: 'Assign request',
322
+ title: "Assign request",
296
323
  onSelect: this.onSelectAssignee
297
324
  });
298
325
  });
@@ -301,12 +328,12 @@ class RequestDetail extends Component {
301
328
  loading: true
302
329
  }, async () => {
303
330
  try {
304
- console.log('onSelectAssignee', this.props.job.id, assignee.key);
331
+ console.log("onSelectAssignee", this.props.job.id, assignee.key);
305
332
  const res = await maintenanceActions.assignJob(this.props.job.id, assignee.key);
306
333
  this.props.jobAdded(res.data.job);
307
334
  this.getJob();
308
335
  } catch (error) {
309
- console.log('onSelectAssignee error', error);
336
+ console.log("onSelectAssignee error", error);
310
337
  } finally {
311
338
  this.setState({
312
339
  loading: false
@@ -317,23 +344,25 @@ class RequestDetail extends Component {
317
344
  this.state = {
318
345
  job: {},
319
346
  isDateTimePickerVisible: false,
320
- popUpType: '',
321
- status: '',
322
- priority: '',
347
+ popUpType: "",
348
+ status: "",
349
+ priority: "",
323
350
  expectedDate: null,
324
- expectedDateText: '',
351
+ expectedDateText: "",
325
352
  seen: false,
326
353
  showMore: true,
327
354
  showStatusPopup: false,
328
355
  showPriorityPopup: false,
329
356
  loading: false,
330
357
  showFullscreenVideo: false,
331
- currentVideoUrl: '',
358
+ currentVideoUrl: "",
332
359
  galleryOpen: false,
333
360
  galleryImages: [],
334
361
  showMessages: false,
335
362
  assignees: [],
336
- selectedPDF: null
363
+ selectedPDF: null,
364
+ externalSync: null,
365
+ loadingExternalSync: false
337
366
  };
338
367
  this.scrollView = /*#__PURE__*/React.createRef();
339
368
  this.commentReply = /*#__PURE__*/React.createRef();
@@ -346,6 +375,7 @@ class RequestDetail extends Component {
346
375
  this.getJob();
347
376
  this.updateJobState(this.props.job);
348
377
  this.getAssignees();
378
+ this.getExternalSync();
349
379
  }
350
380
  updateJobState(defaultJob) {
351
381
  const job = _.find(this.props.jobs, j => j.id === this.props.job.id) || defaultJob;
@@ -359,7 +389,7 @@ class RequestDetail extends Component {
359
389
  };
360
390
  if (job.expectedDate) {
361
391
  newState.expectedDate = moment(job.expectedDate);
362
- newState.expectedDateText = newState.expectedDate.format('DD/MM/YYYY');
392
+ newState.expectedDateText = newState.expectedDate.format("DD/MM/YYYY");
363
393
  }
364
394
  if (job.seen) newState.seen = job.seen;
365
395
  this.setState(newState, () => {
@@ -371,7 +401,7 @@ class RequestDetail extends Component {
371
401
  galleryOpen: true,
372
402
  galleryImages
373
403
  });
374
- this.imagePopup.current.scrollTo(index);
404
+ this.refs.imagePopup.scrollTo(index);
375
405
  }
376
406
  closeGallery() {
377
407
  this.setState({
@@ -391,7 +421,7 @@ class RequestDetail extends Component {
391
421
  const statusOption = getJobStatus(status, this.props);
392
422
  const priority = getJobPriority(job.priority);
393
423
  const canEdit = this.hasPermission();
394
- const isStaff = this.props.user.category === 'staff';
424
+ const isStaff = this.props.user.category === "staff";
395
425
  const showSeen = !status || status === getJobStatus(null, this.props).text;
396
426
  return /*#__PURE__*/React.createElement(View, {
397
427
  style: {
@@ -436,7 +466,7 @@ class RequestDetail extends Component {
436
466
  style: styles.textSectionTextContainer
437
467
  }, /*#__PURE__*/React.createElement(Text, {
438
468
  style: styles.textSectionText
439
- }, moment(job.lastActivityUnix).format('ddd D MMMM, h:mm A'))))), /*#__PURE__*/React.createElement(View, {
469
+ }, moment(job.lastActivityUnix).format("ddd D MMMM, h:mm A"))))), /*#__PURE__*/React.createElement(View, {
440
470
  style: styles.jobInfoContainer
441
471
  }, /*#__PURE__*/React.createElement(View, {
442
472
  style: styles.jobStatusExpectedContainer
@@ -558,7 +588,7 @@ class RequestDetail extends Component {
558
588
  style: styles.documentTypeText
559
589
  }, document.ext)), /*#__PURE__*/React.createElement(Text, {
560
590
  style: styles.documentText
561
- }, `${document.name}${document.uploading ? ` - ${document.uploadProgress}` : ''}`));
591
+ }, `${document.name}${document.uploading ? ` - ${document.uploadProgress}` : ""}`));
562
592
  });
563
593
  }
564
594
  return null;
@@ -603,13 +633,56 @@ class RequestDetail extends Component {
603
633
  return /*#__PURE__*/React.createElement(Components.FormCardSectionOptionLauncher, {
604
634
  onPress: this.onOpenAssigneePicker,
605
635
  title: "Assigned To",
606
- value: job.Assignee ? job.Assignee.displayName : 'Unassigned',
636
+ value: job.Assignee ? job.Assignee.displayName : "Unassigned",
607
637
  textStyle: styles.detailsText,
608
638
  sectionStyle: styles.detailsSection
609
639
  }, content);
610
640
  }
611
641
  return content;
612
642
  }
643
+ renderExternalSync() {
644
+ const {
645
+ externalSync,
646
+ loadingExternalSync
647
+ } = this.state;
648
+
649
+ // Only show if user has permission and external sync data exists
650
+ if (!this.hasPermission()) return null;
651
+ if (!externalSync || loadingExternalSync) return null;
652
+ return /*#__PURE__*/React.createElement(View, {
653
+ style: [styles.externalSyncContainer, Helper.getShadowStyle()]
654
+ }, /*#__PURE__*/React.createElement(View, {
655
+ style: styles.externalSyncHeader
656
+ }, /*#__PURE__*/React.createElement(Text, {
657
+ style: styles.externalSyncTitle
658
+ }, "External Sync"), /*#__PURE__*/React.createElement(Icon, {
659
+ name: "sync",
660
+ type: "material",
661
+ iconStyle: [styles.externalSyncIcon, {
662
+ color: this.props.colourBrandingMain
663
+ }]
664
+ })), /*#__PURE__*/React.createElement(View, {
665
+ style: styles.externalSyncContent
666
+ }, externalSync.systemType && /*#__PURE__*/React.createElement(View, {
667
+ style: styles.externalSyncRow
668
+ }, /*#__PURE__*/React.createElement(Text, {
669
+ style: styles.externalSyncLabel
670
+ }, "System:"), /*#__PURE__*/React.createElement(Text, {
671
+ style: styles.externalSyncValue
672
+ }, externalSync.systemType)), externalSync.externalId && /*#__PURE__*/React.createElement(View, {
673
+ style: styles.externalSyncRow
674
+ }, /*#__PURE__*/React.createElement(Text, {
675
+ style: styles.externalSyncLabel
676
+ }, "External ID:"), /*#__PURE__*/React.createElement(Text, {
677
+ style: styles.externalSyncValue
678
+ }, externalSync.externalId)), externalSync.syncedAt && /*#__PURE__*/React.createElement(View, {
679
+ style: styles.externalSyncRow
680
+ }, /*#__PURE__*/React.createElement(Text, {
681
+ style: styles.externalSyncLabel
682
+ }, "Synced:"), /*#__PURE__*/React.createElement(Text, {
683
+ style: styles.externalSyncValue
684
+ }, moment(externalSync.syncedAt).format("D MMM YYYY h:mma")))));
685
+ }
613
686
  renderCustomFields() {
614
687
  const {
615
688
  job
@@ -619,27 +692,27 @@ class RequestDetail extends Component {
619
692
  } = job;
620
693
  const renderAnswer = field => {
621
694
  switch (field.type) {
622
- case 'date':
695
+ case "date":
623
696
  return /*#__PURE__*/React.createElement(Text, {
624
697
  style: styles.customText
625
- }, field.answer ? moment(field.answer, 'YYYY-MM-DD').format('DD MMM YYYY') : '');
626
- case 'time':
698
+ }, field.answer ? moment(field.answer, "YYYY-MM-DD").format("DD MMM YYYY") : "");
699
+ case "time":
627
700
  return /*#__PURE__*/React.createElement(Text, {
628
701
  style: styles.customText
629
- }, field.answer ? moment(field.answer, 'HH:mm').format('h:mm a') : '');
630
- case 'yn':
702
+ }, field.answer ? moment(field.answer, "HH:mm").format("h:mm a") : "");
703
+ case "yn":
631
704
  return /*#__PURE__*/React.createElement(Text, {
632
705
  style: styles.customText
633
- }, field.answer ? 'Yes' : 'No');
634
- case 'checkbox':
706
+ }, field.answer ? "Yes" : "No");
707
+ case "checkbox":
635
708
  return /*#__PURE__*/React.createElement(Text, {
636
709
  style: styles.customText
637
- }, field.answer && Array.isArray(field.answer) ? field.answer.join(', ') : '');
638
- case 'image':
710
+ }, field.answer && Array.isArray(field.answer) ? field.answer.join(", ") : "");
711
+ case "image":
639
712
  return /*#__PURE__*/React.createElement(View, {
640
713
  style: styles.customImage
641
714
  }, this.renderImage(field.answer));
642
- case 'document':
715
+ case "document":
643
716
  return /*#__PURE__*/React.createElement(View, {
644
717
  style: styles.customDocument
645
718
  }, this.renderDocument(field.answer));
@@ -650,8 +723,8 @@ class RequestDetail extends Component {
650
723
  }
651
724
  };
652
725
  return customFields.map((field, index) => {
653
- if (['staticTitle', 'staticText'].includes(field.type)) return null;
654
- if (_.isNil(field.answer) || field.answer === '' || Array.isArray(field.answer) && field.answer.length === 0) return null;
726
+ if (["staticTitle", "staticText"].includes(field.type)) return null;
727
+ if (_.isNil(field.answer) || field.answer === "" || Array.isArray(field.answer) && field.answer.length === 0) return null;
655
728
  return /*#__PURE__*/React.createElement(View, {
656
729
  key: index
657
730
  }, /*#__PURE__*/React.createElement(Text, {
@@ -670,7 +743,7 @@ class RequestDetail extends Component {
670
743
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(Components.FormCardSectionOptionLauncher, {
671
744
  onPress: this.onToggleDetails,
672
745
  title: "Details",
673
- icon: this.state.showMore ? 'angle-up' : 'angle-down',
746
+ icon: this.state.showMore ? "angle-up" : "angle-down",
674
747
  textStyle: styles.detailsText,
675
748
  sectionStyle: styles.detailsSection
676
749
  }), this.state.showMore && /*#__PURE__*/React.createElement(View, null, hasCustomFields ? this.renderCustomFields() : null, !hasCustomFields ? /*#__PURE__*/React.createElement(React.Fragment, null, this.renderImage(job.images, job.image), !_.isEmpty(job.description) && /*#__PURE__*/React.createElement(Text, {
@@ -699,7 +772,7 @@ class RequestDetail extends Component {
699
772
  style: styles.nameText
700
773
  }, job.userName), !_.isEmpty(job.phone) && /*#__PURE__*/React.createElement(Text, {
701
774
  style: styles.phoneText
702
- }, job.phone)))));
775
+ }, job.phone))), this.renderExternalSync()));
703
776
  }
704
777
  renderMessages() {
705
778
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(Components.CommentSection, {
@@ -713,7 +786,7 @@ class RequestDetail extends Component {
713
786
  site: this.state.job.site || this.state.job.location,
714
787
  live: true,
715
788
  refreshFrequency: 10000,
716
- placeHolder: '',
789
+ placeHolder: "",
717
790
  style: {
718
791
  flex: 1,
719
792
  paddingHorizontal: 0,
@@ -733,7 +806,7 @@ class RequestDetail extends Component {
733
806
  height: 36
734
807
  },
735
808
  textStyle: {
736
- color: '#fff'
809
+ color: "#fff"
737
810
  },
738
811
  fullWidth: true
739
812
  }, "Leave Message"));
@@ -771,7 +844,7 @@ class RequestDetail extends Component {
771
844
  return /*#__PURE__*/React.createElement(Components.Forbidden, null);
772
845
  }
773
846
  return /*#__PURE__*/React.createElement(KeyboardAvoidingView, {
774
- behavior: 'padding',
847
+ behavior: "padding",
775
848
  style: styles.container
776
849
  }, /*#__PURE__*/React.createElement(Components.Header, {
777
850
  leftIcon: "angle-left",
@@ -783,7 +856,7 @@ class RequestDetail extends Component {
783
856
  paddingBottom: 26
784
857
  },
785
858
  style: {
786
- height: '100%'
859
+ height: "100%"
787
860
  }
788
861
  }, /*#__PURE__*/React.createElement(View, {
789
862
  style: styles.innerContainer
@@ -800,7 +873,7 @@ class RequestDetail extends Component {
800
873
  const styles = StyleSheet.create({
801
874
  container: {
802
875
  flex: 1,
803
- backgroundColor: '#fff'
876
+ backgroundColor: "#fff"
804
877
  },
805
878
  innerContainer: {
806
879
  paddingTop: 23,
@@ -811,49 +884,49 @@ const styles = StyleSheet.create({
811
884
  paddingHorizontal: 12
812
885
  },
813
886
  jobIdText: {
814
- fontFamily: 'sf-medium',
887
+ fontFamily: "sf-medium",
815
888
  fontSize: 12,
816
889
  marginBottom: 4
817
890
  },
818
891
  jobTitleText: {
819
- fontFamily: 'sf-semibold',
892
+ fontFamily: "sf-semibold",
820
893
  fontSize: 20,
821
894
  color: Colours.TEXT_DARKEST,
822
895
  marginBottom: 8
823
896
  },
824
897
  jobTypeSeenContainer: {
825
- flexDirection: 'row',
826
- alignItems: 'center'
898
+ flexDirection: "row",
899
+ alignItems: "center"
827
900
  },
828
901
  jobTypeContainer: {
829
902
  padding: 4,
830
903
  minWidth: 80,
831
904
  maxWidth: 140,
832
905
  borderRadius: 4,
833
- justifyContent: 'center'
906
+ justifyContent: "center"
834
907
  },
835
908
  jobTypeText: {
836
- fontFamily: 'sf-semibold',
909
+ fontFamily: "sf-semibold",
837
910
  fontSize: 12,
838
- textAlign: 'center',
839
- maxWidth: '100%'
911
+ textAlign: "center",
912
+ maxWidth: "100%"
840
913
  },
841
914
  jobSeenContainer: {
842
- flexDirection: 'row',
843
- alignItems: 'center',
915
+ flexDirection: "row",
916
+ alignItems: "center",
844
917
  marginLeft: 10
845
918
  },
846
919
  jobSeenIcon: {
847
920
  fontSize: 12
848
921
  },
849
922
  jobSeenText: {
850
- fontFamily: 'sf-semibold',
923
+ fontFamily: "sf-semibold",
851
924
  fontSize: 12,
852
925
  marginLeft: 4
853
926
  },
854
927
  jobStatusDateText: {
855
928
  marginTop: 8,
856
- fontFamily: 'sf-medium',
929
+ fontFamily: "sf-medium",
857
930
  fontSize: 13,
858
931
  color: Colours.TEXT_LIGHT
859
932
  },
@@ -864,60 +937,60 @@ const styles = StyleSheet.create({
864
937
  paddingHorizontal: 12
865
938
  },
866
939
  jobStatusExpectedContainer: {
867
- flexDirection: 'row',
868
- alignItems: 'flex-start',
869
- justifyContent: 'space-between'
940
+ flexDirection: "row",
941
+ alignItems: "flex-start",
942
+ justifyContent: "space-between"
870
943
  },
871
944
  jobStatusOuterContainer: {
872
945
  // marginRight: 50,
873
946
  },
874
947
  jobStatusHeading: {
875
- fontFamily: 'sf-bold',
948
+ fontFamily: "sf-bold",
876
949
  fontSize: 11,
877
950
  letterSpacing: 0.8,
878
951
  color: Colours.TEXT_DARK,
879
952
  marginBottom: 6
880
953
  },
881
954
  jobStatusContainer: {
882
- flexDirection: 'row',
883
- alignItems: 'center',
955
+ flexDirection: "row",
956
+ alignItems: "center",
884
957
  width: 120,
885
958
  height: 30,
886
959
  paddingHorizontal: 8,
887
960
  borderRadius: 4
888
961
  },
889
962
  jobStatusIcon: {
890
- color: '#fff',
963
+ color: "#fff",
891
964
  fontSize: 14,
892
965
  marginRight: 8
893
966
  },
894
967
  jobStatusText: {
895
- color: '#fff',
896
- textAlign: 'center',
897
- fontFamily: 'sf-semibold',
968
+ color: "#fff",
969
+ textAlign: "center",
970
+ fontFamily: "sf-semibold",
898
971
  fontSize: 13,
899
972
  flex: 1,
900
- textAlign: 'center'
973
+ textAlign: "center"
901
974
  },
902
975
  jobPriorityOuterContainer: {
903
976
  marginTop: 12
904
977
  },
905
978
  jobExpectedDateContainer: {
906
979
  backgroundColor: Colours.BOXGREY,
907
- flexDirection: 'row',
980
+ flexDirection: "row",
908
981
  width: 115,
909
982
  height: 30,
910
983
  borderRadius: 4,
911
- alignItems: 'center',
984
+ alignItems: "center",
912
985
  paddingLeft: 8
913
986
  },
914
987
  jobExpectedDate: {
915
- fontFamily: 'sf-regular',
988
+ fontFamily: "sf-regular",
916
989
  fontSize: 13,
917
990
  color: Colours.hexToRGBAstring(Colours.TEXT_DARKEST, 0.5)
918
991
  },
919
992
  detailsText: {
920
- fontFamily: 'sf-semibold',
993
+ fontFamily: "sf-semibold",
921
994
  fontSize: 16,
922
995
  color: Colours.TEXT_DARKEST
923
996
  },
@@ -928,55 +1001,55 @@ const styles = StyleSheet.create({
928
1001
  },
929
1002
  sideBySideImages: {
930
1003
  flex: 1,
931
- flexDirection: 'row',
932
- justifyContent: 'space-between',
1004
+ flexDirection: "row",
1005
+ justifyContent: "space-between",
933
1006
  marginBottom: 16
934
1007
  },
935
1008
  sideBySideImageContainer: {
936
- backgroundColor: '#fff',
937
- width: '48%',
1009
+ backgroundColor: "#fff",
1010
+ width: "48%",
938
1011
  height: 150,
939
1012
  borderRadius: 2,
940
- overflow: 'hidden'
1013
+ overflow: "hidden"
941
1014
  },
942
1015
  singleImageContainer: {
943
- backgroundColor: '#fff',
944
- width: '100%',
1016
+ backgroundColor: "#fff",
1017
+ width: "100%",
945
1018
  height: 150,
946
1019
  flex: 1,
947
1020
  borderRadius: 2,
948
- overflow: 'hidden',
1021
+ overflow: "hidden",
949
1022
  marginBottom: 16
950
1023
  },
951
1024
  imageContainer: {
952
1025
  height: 150,
953
- width: 'auto',
954
- justifyContent: 'center'
1026
+ width: "auto",
1027
+ justifyContent: "center"
955
1028
  },
956
1029
  imagePlayContainer: {
957
- position: 'absolute',
1030
+ position: "absolute",
958
1031
  top: 0,
959
1032
  left: 0,
960
1033
  right: 0,
961
1034
  bottom: 0,
962
- alignItems: 'center',
963
- justifyContent: 'center'
1035
+ alignItems: "center",
1036
+ justifyContent: "center"
964
1037
  },
965
1038
  imageControlIcon: {
966
- color: '#fff',
1039
+ color: "#fff",
967
1040
  fontSize: 30,
968
- textShadowColor: 'rgba(0,0,0,0.3)',
1041
+ textShadowColor: "rgba(0,0,0,0.3)",
969
1042
  textShadowOffset: {
970
1043
  width: 2,
971
1044
  height: 2
972
1045
  }
973
1046
  },
974
1047
  plusImages: {
975
- fontFamily: 'sf-bold',
1048
+ fontFamily: "sf-bold",
976
1049
  fontSize: 32,
977
- textAlign: 'center',
978
- color: '#fff',
979
- textShadowColor: 'rgba(0, 0, 0, 0.5)',
1050
+ textAlign: "center",
1051
+ color: "#fff",
1052
+ textShadowColor: "rgba(0, 0, 0, 0.5)",
980
1053
  textShadowOffset: {
981
1054
  width: 0,
982
1055
  height: 2
@@ -984,64 +1057,64 @@ const styles = StyleSheet.create({
984
1057
  textShadowRadius: 8
985
1058
  },
986
1059
  jobDescriptionText: {
987
- fontFamily: 'sf-medium',
1060
+ fontFamily: "sf-medium",
988
1061
  fontSize: 14,
989
1062
  color: Colours.TEXT_LIGHT,
990
1063
  paddingBottom: 16
991
1064
  },
992
1065
  locationLabel: {
993
- fontFamily: 'sf-bold',
1066
+ fontFamily: "sf-bold",
994
1067
  fontSize: 14,
995
1068
  color: Colours.TEXT_DARKEST
996
1069
  },
997
1070
  locationText: {
998
- fontFamily: 'sf-regular',
1071
+ fontFamily: "sf-regular",
999
1072
  fontSize: 16,
1000
1073
  color: Colours.TEXT_DARKEST,
1001
1074
  paddingVertical: 8
1002
1075
  },
1003
1076
  requesterLabel: {
1004
- fontFamily: 'sf-bold',
1077
+ fontFamily: "sf-bold",
1005
1078
  fontSize: 14,
1006
1079
  color: Colours.TEXT_DARKEST,
1007
1080
  paddingVertical: 10
1008
1081
  },
1009
1082
  profileContainer: {
1010
- flexDirection: 'row',
1011
- alignItems: 'center'
1083
+ flexDirection: "row",
1084
+ alignItems: "center"
1012
1085
  },
1013
1086
  nameContainer: {
1014
1087
  marginLeft: 18
1015
1088
  },
1016
1089
  nameText: {
1017
- fontSize: 'sf-semibold',
1090
+ fontSize: "sf-semibold",
1018
1091
  fontSize: 14,
1019
1092
  color: Colours.TEXT_DARKEST,
1020
1093
  marginBottom: 4
1021
1094
  },
1022
1095
  phoneText: {
1023
- fontSize: 'sf-medium',
1096
+ fontSize: "sf-medium",
1024
1097
  fontSize: 14,
1025
1098
  color: Colours.TEXT_LIGHT
1026
1099
  },
1027
1100
  textSectionInner: {
1028
- flexDirection: 'row',
1029
- justifyContent: 'space-between',
1030
- alignItems: 'center',
1101
+ flexDirection: "row",
1102
+ justifyContent: "space-between",
1103
+ alignItems: "center",
1031
1104
  marginTop: 8
1032
1105
  },
1033
1106
  textSectionLabel: {
1034
- fontFamily: 'sf-semibold',
1107
+ fontFamily: "sf-semibold",
1035
1108
  fontSize: 12,
1036
1109
  lineHeight: 24,
1037
1110
  color: Colours.TEXT_DARKEST
1038
1111
  },
1039
1112
  textSectionTextContainer: {
1040
- flexDirection: 'row',
1041
- alignItems: 'center'
1113
+ flexDirection: "row",
1114
+ alignItems: "center"
1042
1115
  },
1043
1116
  textSectionText: {
1044
- fontFamily: 'sf-regular',
1117
+ fontFamily: "sf-regular",
1045
1118
  fontSize: 13,
1046
1119
  lineHeight: 24,
1047
1120
  color: Colours.TEXT_LIGHT
@@ -1052,12 +1125,12 @@ const styles = StyleSheet.create({
1052
1125
  lineHeight: 24
1053
1126
  },
1054
1127
  customLabel: {
1055
- fontFamily: 'sf-bold',
1128
+ fontFamily: "sf-bold",
1056
1129
  fontSize: 14,
1057
1130
  color: Colours.TEXT_DARKEST
1058
1131
  },
1059
1132
  customText: {
1060
- fontFamily: 'sf-regular',
1133
+ fontFamily: "sf-regular",
1061
1134
  fontSize: 16,
1062
1135
  color: Colours.TEXT_DARKEST,
1063
1136
  paddingVertical: 8
@@ -1071,41 +1144,83 @@ const styles = StyleSheet.create({
1071
1144
  },
1072
1145
  customStaticTitle: {
1073
1146
  fontSize: 20,
1074
- fontFamily: 'sf-semibold',
1147
+ fontFamily: "sf-semibold",
1075
1148
  color: Colours.TEXT_DARKEST,
1076
1149
  marginBottom: 10
1077
1150
  },
1078
1151
  customStaticText: {
1079
1152
  fontSize: 17,
1080
- fontFamily: 'sf-regular',
1153
+ fontFamily: "sf-regular",
1081
1154
  color: Colours.TEXT_DARKEST,
1082
1155
  lineHeight: 24,
1083
1156
  marginBottom: 10
1084
1157
  },
1085
1158
  documentContainer: {
1086
- flexDirection: 'row',
1087
- alignItems: 'center',
1088
- justifyContent: 'space-between',
1159
+ flexDirection: "row",
1160
+ alignItems: "center",
1161
+ justifyContent: "space-between",
1089
1162
  paddingVertical: 4
1090
1163
  },
1091
1164
  documentTypeContainer: {
1092
1165
  width: 50,
1093
1166
  height: 60,
1094
- justifyContent: 'center',
1095
- alignItems: 'center',
1167
+ justifyContent: "center",
1168
+ alignItems: "center",
1096
1169
  borderRadius: 5,
1097
1170
  marginRight: 8
1098
1171
  },
1099
1172
  documentTypeText: {
1100
- color: '#fff',
1101
- fontFamily: 'sf-semibold',
1102
- textAlign: 'center'
1173
+ color: "#fff",
1174
+ fontFamily: "sf-semibold",
1175
+ textAlign: "center"
1103
1176
  },
1104
1177
  documentText: {
1105
1178
  flex: 1,
1106
- fontFamily: 'sf-semibold',
1179
+ fontFamily: "sf-semibold",
1180
+ fontSize: 16,
1181
+ color: "#65686D"
1182
+ },
1183
+ externalSyncContainer: {
1184
+ backgroundColor: "#fff",
1185
+ marginTop: 16,
1186
+ borderRadius: 8,
1187
+ padding: 16
1188
+ },
1189
+ externalSyncHeader: {
1190
+ flexDirection: "row",
1191
+ justifyContent: "space-between",
1192
+ alignItems: "center",
1193
+ marginBottom: 12,
1194
+ paddingBottom: 12,
1195
+ borderBottomWidth: 1,
1196
+ borderBottomColor: Colours.LINEGREY
1197
+ },
1198
+ externalSyncTitle: {
1199
+ fontFamily: "sf-semibold",
1107
1200
  fontSize: 16,
1108
- color: '#65686D'
1201
+ color: Colours.TEXT_DARKEST
1202
+ },
1203
+ externalSyncIcon: {
1204
+ fontSize: 20
1205
+ },
1206
+ externalSyncContent: {
1207
+ paddingTop: 4
1208
+ },
1209
+ externalSyncRow: {
1210
+ flexDirection: "row",
1211
+ marginBottom: 10
1212
+ },
1213
+ externalSyncLabel: {
1214
+ fontFamily: "sf-semibold",
1215
+ fontSize: 14,
1216
+ color: Colours.TEXT_DARK,
1217
+ width: 100
1218
+ },
1219
+ externalSyncValue: {
1220
+ fontFamily: "sf-regular",
1221
+ fontSize: 14,
1222
+ color: Colours.TEXT_DARKEST,
1223
+ flex: 1
1109
1224
  }
1110
1225
  });
1111
1226
  const mapStateToProps = state => {