@plusscommunities/pluss-maintenance-app 6.0.5 → 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 (55) hide show
  1. package/dist/module/actions/types.js +4 -3
  2. package/dist/module/actions/types.js.map +1 -1
  3. package/dist/module/apis/maintenanceActions.js +17 -15
  4. package/dist/module/apis/maintenanceActions.js.map +1 -1
  5. package/dist/module/components/MaintenanceList.js +4 -3
  6. package/dist/module/components/MaintenanceList.js.map +1 -1
  7. package/dist/module/components/MaintenanceListItem.js +3 -2
  8. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  9. package/dist/module/components/MaintenanceWidgetItem.js +2 -1
  10. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  11. package/dist/module/components/WidgetSmall.js +6 -3
  12. package/dist/module/components/WidgetSmall.js.map +1 -1
  13. package/dist/module/feature.config.js +18 -33
  14. package/dist/module/feature.config.js.map +1 -1
  15. package/dist/module/index.js +15 -10
  16. package/dist/module/index.js.map +1 -1
  17. package/dist/module/screens/MaintenancePage.js +7 -3
  18. package/dist/module/screens/MaintenancePage.js.map +1 -1
  19. package/dist/module/screens/RequestDetail.js +105 -30
  20. package/dist/module/screens/RequestDetail.js.map +1 -1
  21. package/dist/module/screens/RequestNotes.js +2 -1
  22. package/dist/module/screens/RequestNotes.js.map +1 -1
  23. package/dist/module/screens/ServiceRequest.js +552 -84
  24. package/dist/module/screens/ServiceRequest.js.map +1 -1
  25. package/dist/module/values.config.a.js +30 -0
  26. package/dist/module/values.config.a.js.map +1 -0
  27. package/dist/module/values.config.b.js +30 -0
  28. package/dist/module/values.config.b.js.map +1 -0
  29. package/dist/module/values.config.c.js +30 -0
  30. package/dist/module/values.config.c.js.map +1 -0
  31. package/dist/module/values.config.d.js +30 -0
  32. package/dist/module/values.config.d.js.map +1 -0
  33. package/dist/module/values.config.default.js +30 -0
  34. package/dist/module/values.config.default.js.map +1 -0
  35. package/dist/module/values.config.js +30 -0
  36. package/dist/module/values.config.js.map +1 -0
  37. package/package.json +9 -3
  38. package/src/actions/types.js +5 -3
  39. package/src/apis/maintenanceActions.js +30 -14
  40. package/src/components/MaintenanceList.js +5 -3
  41. package/src/components/MaintenanceListItem.js +7 -2
  42. package/src/components/MaintenanceWidgetItem.js +2 -1
  43. package/src/components/WidgetSmall.js +6 -3
  44. package/src/feature.config.js +18 -30
  45. package/src/index.js +15 -8
  46. package/src/screens/MaintenancePage.js +5 -4
  47. package/src/screens/RequestDetail.js +100 -32
  48. package/src/screens/RequestNotes.js +2 -1
  49. package/src/screens/ServiceRequest.js +591 -149
  50. package/src/values.config.a.js +30 -0
  51. package/src/values.config.b.js +30 -0
  52. package/src/values.config.c.js +30 -0
  53. package/src/values.config.d.js +30 -0
  54. package/src/values.config.default.js +30 -0
  55. package/src/values.config.js +30 -0
@@ -1,24 +1,25 @@
1
1
  import { Helper, Session } from '../core.config';
2
+ import { values } from '../values.config';
2
3
 
3
4
  export const maintenanceActions = {
4
5
  getJob: (site, id) => {
5
6
  return Session.authedFunction({
6
7
  method: 'POST',
7
- url: Helper.getUrl('maintenance', 'getJob'),
8
+ url: Helper.getUrl(values.serviceKey, 'getJob'),
8
9
  data: { site, id },
9
10
  });
10
11
  },
11
12
  getJobByJobId: (site, jobId) => {
12
13
  return Session.authedFunction({
13
14
  method: 'POST',
14
- url: Helper.getUrl('maintenance', 'getJob'),
15
+ url: Helper.getUrl(values.serviceKey, 'getJob'),
15
16
  data: { site, jobId },
16
17
  });
17
18
  },
18
19
  getJobs: (site, status = '', type = '') => {
19
20
  return Session.authedFunction({
20
21
  method: 'POST',
21
- url: Helper.getUrl('maintenance', 'getJobs'),
22
+ url: Helper.getUrl(values.serviceKey, 'getJobs'),
22
23
  data: { site, status, type },
23
24
  });
24
25
  },
@@ -35,7 +36,7 @@ export const maintenanceActions = {
35
36
  }
36
37
  return Session.authedFunction({
37
38
  method: 'GET',
38
- url: Helper.getUrl('maintenance', 'get/requests', query),
39
+ url: Helper.getUrl(values.serviceKey, 'get/requests', query),
39
40
  });
40
41
  },
41
42
  getJobsRecursive: (site, status, type, lastKey, jobs = []) => {
@@ -49,10 +50,24 @@ export const maintenanceActions = {
49
50
  });
50
51
  });
51
52
  },
52
- sendMaintenanceRequest: (userID, userName, phone, room, title, description, date, type, images, location, isHome, homeText) => {
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
+ ) => {
53
68
  const request = {
54
69
  method: 'POST',
55
- url: Helper.getUrl('maintenance', 'sendMaintenance'),
70
+ url: Helper.getUrl(values.serviceKey, 'sendMaintenance'),
56
71
  data: {
57
72
  userID,
58
73
  userName,
@@ -66,6 +81,7 @@ export const maintenanceActions = {
66
81
  location,
67
82
  isHome,
68
83
  homeText,
84
+ customFields,
69
85
  },
70
86
  };
71
87
  return Session.authedFunction(request);
@@ -73,21 +89,21 @@ export const maintenanceActions = {
73
89
  editJob: (job, site) => {
74
90
  return Session.authedFunction({
75
91
  method: 'POST',
76
- url: Helper.getUrl('maintenance', 'editJob'),
92
+ url: Helper.getUrl(values.serviceKey, 'editJob'),
77
93
  data: { job, site },
78
94
  });
79
95
  },
80
96
  editJobStatus: (id, status) => {
81
97
  return Session.authedFunction({
82
98
  method: 'POST',
83
- url: Helper.getUrl('maintenance', 'editJobStatus'),
99
+ url: Helper.getUrl(values.serviceKey, 'editJobStatus'),
84
100
  data: { id, status },
85
101
  });
86
102
  },
87
103
  assignJob: (jobId, userId) => {
88
104
  return Session.authedFunction({
89
105
  method: 'POST',
90
- url: Helper.getUrl('maintenance', 'update/assign'),
106
+ url: Helper.getUrl(values.serviceKey, 'update/assign'),
91
107
  data: {
92
108
  id: jobId,
93
109
  userId,
@@ -97,13 +113,13 @@ export const maintenanceActions = {
97
113
  getAssignees: site => {
98
114
  return Session.authedFunction({
99
115
  method: 'GET',
100
- url: Helper.getUrl('maintenance', 'get/assignees', { site }),
116
+ url: Helper.getUrl(values.serviceKey, 'get/assignees', { site }),
101
117
  });
102
118
  },
103
119
  addNote: (jobId, note, attachments) => {
104
120
  return Session.authedFunction({
105
121
  method: 'POST',
106
- url: Helper.getUrl('maintenance', 'requests/note'),
122
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
107
123
  data: {
108
124
  id: jobId,
109
125
  note,
@@ -115,7 +131,7 @@ export const maintenanceActions = {
115
131
  editNote: (jobId, noteId, note, attachments) => {
116
132
  return Session.authedFunction({
117
133
  method: 'POST',
118
- url: Helper.getUrl('maintenance', 'requests/note'),
134
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
119
135
  data: {
120
136
  id: jobId,
121
137
  note,
@@ -128,7 +144,7 @@ export const maintenanceActions = {
128
144
  deleteNote: (jobId, noteId) => {
129
145
  return Session.authedFunction({
130
146
  method: 'POST',
131
- url: Helper.getUrl('maintenance', 'requests/note'),
147
+ url: Helper.getUrl(values.serviceKey, 'requests/note'),
132
148
  data: {
133
149
  id: jobId,
134
150
  noteId,
@@ -137,7 +153,7 @@ export const maintenanceActions = {
137
153
  });
138
154
  },
139
155
  getJobTypes: async site => {
140
- const url = Helper.getUrl('maintenance', 'getjobtypes');
156
+ const url = Helper.getUrl(values.serviceKey, 'getjobtypes');
141
157
  return Session.authedFunction({
142
158
  method: 'POST',
143
159
  url,
@@ -7,6 +7,7 @@ import { jobsLoaded, jobAdded, jobsAdded } from '../actions';
7
7
  import MaintenanceListItem from '../components/MaintenanceListItem';
8
8
  import FilterPopupMenu from './FilterPopupMenu';
9
9
  import { Components, Colours, Config, Helper } from '../core.config';
10
+ import { values } from '../values.config';
10
11
 
11
12
  class MaintenanceList extends Component {
12
13
  constructor(props) {
@@ -201,7 +202,7 @@ class MaintenanceList extends Component {
201
202
  return (
202
203
  <View style={styles.searchContainer}>
203
204
  <Components.GenericInput
204
- placeholder="Search by Job ID or Location"
205
+ placeholder={`Search by ${values.textEntityName} ID or Address`}
205
206
  value={this.state.searchText}
206
207
  onChangeText={this.onSearchText}
207
208
  onSubmitEditing={this.onSearchSubmit}
@@ -316,7 +317,8 @@ const styles = StyleSheet.create({
316
317
  });
317
318
 
318
319
  const mapStateToProps = state => {
319
- const { user, jobs, notifications } = state;
320
+ const { user, notifications } = state;
321
+ const jobs = state[values.reducerKey];
320
322
  const jobsOrdered = _.orderBy(jobs.jobs, ['createdUnix'], ['desc']);
321
323
  const hasPermission = _.includes(user.permissions, 'maintenanceTracking');
322
324
 
@@ -326,7 +328,7 @@ const mapStateToProps = state => {
326
328
  site: user.site,
327
329
  userCategory: user.category,
328
330
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
329
- dataUpdated: notifications.dataUpdated['jobs'],
331
+ dataUpdated: notifications.dataUpdated[values.updateKey],
330
332
  };
331
333
  };
332
334
 
@@ -19,10 +19,11 @@ import moment from 'moment';
19
19
  import { getJobStatusProps, jobStatusOptions } from '../helper';
20
20
  import { Services } from '../feature.config';
21
21
  import { Helper, Colours } from '../core.config';
22
+ import { values } from '../values.config';
22
23
 
23
24
  class MaintenanceListItem extends Component {
24
25
  onPressJob = () => {
25
- Services.navigation.navigate('requestDetail', { job: this.props.job });
26
+ Services.navigation.navigate(values.screenRequestDetail, { job: this.props.job });
26
27
  };
27
28
 
28
29
  renderCommentCount() {
@@ -72,7 +73,11 @@ class MaintenanceListItem extends Component {
72
73
  <View style={styles.jobInnerContainer}>
73
74
  <View style={styles.jobTopSection}>
74
75
  <View style={styles.jobTopLeft}>
75
- {job.jobId ? <Text style={[styles.jobIdText, { color: this.props.colourBrandingMain }]}>{`Job #${job.jobId}`}</Text> : null}
76
+ {job.jobId ? (
77
+ <Text
78
+ style={[styles.jobIdText, { color: this.props.colourBrandingMain }]}
79
+ >{`${values.textEntityName} #${job.jobId}`}</Text>
80
+ ) : null}
76
81
  <Text style={styles.jobTitleText}>{job.title}</Text>
77
82
  {job.room ? <Text style={styles.jobLocationText}>{job.room}</Text> : null}
78
83
  <View style={styles.jobTypeSeenContainer}>
@@ -7,10 +7,11 @@ import _ from 'lodash';
7
7
  import { getJobStatusProps, jobStatusOptions } from '../helper';
8
8
  import { Services } from '../feature.config';
9
9
  import { Colours, Helper } from '../core.config';
10
+ import { values } from '../values.config';
10
11
 
11
12
  class MaintenanceWidgetItem extends Component {
12
13
  onPressJob = () => {
13
- Services.navigation.navigate('requestDetail', { job: this.props.job });
14
+ Services.navigation.navigate(values.screenRequestDetail, { job: this.props.job });
14
15
  };
15
16
 
16
17
  render() {
@@ -7,6 +7,7 @@ import { jobsLoaded } from '../actions';
7
7
  import MaintenanceWidgetItem from './MaintenanceWidgetItem';
8
8
  import { Services } from '../feature.config';
9
9
  import { Colours, Components, Config } from '../core.config';
10
+ import { values } from '../values.config';
10
11
 
11
12
  const MAX_ITEMS = 10;
12
13
 
@@ -27,7 +28,7 @@ class WidgetSmall extends Component {
27
28
  getTitle = () => {
28
29
  const { options } = this.props;
29
30
  if (options && !_.isEmpty(options.Title)) return options.Title;
30
- return Config.env.strings.MAINTENANCE;
31
+ return this.props.strings[`${values.featureKey}_textFeatureTitle`] || values.textFeatureTitle;
31
32
  };
32
33
 
33
34
  getEmptyStateText = () => {
@@ -136,13 +137,15 @@ const styles = StyleSheet.create({
136
137
  });
137
138
 
138
139
  const mapStateToProps = state => {
139
- const { user, jobs, notifications } = state;
140
+ const { user, notifications } = state;
141
+ const jobs = state[values.reducerKey];
140
142
  return {
141
143
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
142
144
  jobs: _.orderBy(jobs.jobs, ['createdUnix'], ['desc']),
143
145
  site: user.site,
144
146
  userCategory: user.category,
145
- dataUpdated: notifications.dataUpdated.jobs,
147
+ dataUpdated: notifications.dataUpdated[values.updateKey],
148
+ strings: state.strings?.config || {},
146
149
  };
147
150
  };
148
151
 
@@ -1,5 +1,6 @@
1
1
  // import * as PlussCore from '../../pluss-core/src';
2
2
  import * as PlussCore from '@plusscommunities/pluss-core-app';
3
+ import { values } from './values.config';
3
4
 
4
5
  export const Services = {
5
6
  navigation: null,
@@ -10,25 +11,25 @@ export const BaseComponents = {
10
11
  };
11
12
 
12
13
  const FeatureConfig = {
13
- key: 'maintenance',
14
- aliases: ['maintenanceRequest'],
15
- title: 'Request',
14
+ key: values.featureKey,
15
+ aliases: values.aliases,
16
+ title: values.textFeatureTitle,
16
17
  gridMenu: {
17
- icon: 'maintenance',
18
+ icon: values.iconGridMenu,
18
19
  viewBox: '0 0 30 30',
19
- navigate: 'maintenance',
20
+ navigate: values.screenMaintenance,
20
21
  },
21
22
  addMenu: {
22
- order: 5,
23
- icon: 'request',
24
- title: 'Request',
25
- navigate: 'serviceRequest',
26
- visibleExps: { type: 'feature', value: 'maintenance' },
23
+ order: values.orderAddMenu,
24
+ icon: values.iconAddMenu,
25
+ title: values.textAddMenuTitle,
26
+ navigate: values.screenServiceRequest,
27
+ visibleExps: { type: 'feature', value: values.featureKey },
27
28
  },
28
29
  moreMenu: {
29
- order: 4,
30
- title: 'Request',
31
- navigate: 'maintenance',
30
+ order: values.orderMoreMenu,
31
+ title: values.textMoreMenuTitle,
32
+ navigate: values.screenMaintenance,
32
33
  visibleExps: {
33
34
  type: 'and',
34
35
  exps: [
@@ -38,10 +39,10 @@ const FeatureConfig = {
38
39
  },
39
40
  },
40
41
  kioskAction: {
41
- order: 1,
42
- icon: 'wrench',
43
- title: 'Request',
44
- navigate: 'serviceRequest',
42
+ order: values.orderKioskAction,
43
+ icon: values.iconKioskAction,
44
+ title: values.textKioskActionTitle,
45
+ navigate: values.screenServiceRequest,
45
46
  },
46
47
  hideTabBar: [],
47
48
  env: {
@@ -65,19 +66,6 @@ const FeatureConfig = {
65
66
  Services.navigation = navigation;
66
67
  BaseComponents.NotificationBell = notificationBell;
67
68
  PlussCore.Config.init(environment, navigation);
68
-
69
- // Override strings
70
- if (environment && environment.strings) {
71
- const { MAINTENANCE, MAINTENANCE_REQUEST } = environment.strings;
72
- if (MAINTENANCE) {
73
- FeatureConfig.addMenu.title = MAINTENANCE;
74
- }
75
- if (MAINTENANCE_REQUEST) {
76
- FeatureConfig.title = MAINTENANCE_REQUEST;
77
- FeatureConfig.moreMenu.title = MAINTENANCE_REQUEST;
78
- FeatureConfig.kioskAction.title = MAINTENANCE_REQUEST;
79
- }
80
- }
81
69
  },
82
70
  };
83
71
  export default FeatureConfig;
package/src/index.js CHANGED
@@ -4,15 +4,22 @@ import ServiceRequest from './screens/ServiceRequest';
4
4
  import JobTypePicker from './screens/JobTypePicker';
5
5
  import RequestNotes from './screens/RequestNotes';
6
6
  import JobsReducer from './reducers/JobsReducer';
7
+ import { values } from './values.config';
7
8
 
8
- export const Reducers = { jobs: JobsReducer };
9
- export const Screens = {
10
- maintenance: MaintenancePage,
11
- requestDetail: RequestDetail,
12
- serviceRequest: ServiceRequest,
13
- jobTypePicker: JobTypePicker,
14
- requestNotes: RequestNotes,
15
- };
9
+ export const Reducers = (() => {
10
+ const reducers = {};
11
+ reducers[values.reducerKey] = JobsReducer;
12
+ return reducers;
13
+ })();
14
+ export const Screens = (() => {
15
+ const screens = {};
16
+ screens[values.screenMaintenance] = MaintenancePage;
17
+ screens[values.screenRequestDetail] = RequestDetail;
18
+ screens[values.screenServiceRequest] = ServiceRequest;
19
+ screens[values.screenJobTypePicker] = JobTypePicker;
20
+ screens[values.screenRequestNotes] = RequestNotes;
21
+ return screens;
22
+ })();
16
23
  export { default as Config } from './feature.config';
17
24
  export { default as WidgetSmall } from './components/WidgetSmall';
18
25
  export { default as WidgetLarge } from './components/WidgetLarge';
@@ -5,6 +5,7 @@ import _ from 'lodash';
5
5
  import MaintenanceList from '../components/MaintenanceList';
6
6
  import { Services, BaseComponents } from '../feature.config';
7
7
  import { Components, Helper, Styles, Config } from '../core.config';
8
+ import { values } from '../values.config';
8
9
 
9
10
  class MaintenancePage extends Component {
10
11
  constructor(props) {
@@ -29,10 +30,11 @@ class MaintenancePage extends Component {
29
30
  };
30
31
 
31
32
  renderHeader() {
33
+ const title = this.props.title || this.props.strings[`${values.featureKey}_textFeatureTitle`] || values.textFeatureTitle;
32
34
  if (this.state.isHomeTab) {
33
35
  return (
34
36
  <Components.Header
35
- text={this.props.title || Config.env.strings.MAINTENANCE}
37
+ text={title}
36
38
  rightContent={
37
39
  _.includes(this.props.user.hidden, 'notifications') ? null : (
38
40
  <View style={styles.notificationContainer}>
@@ -46,9 +48,7 @@ class MaintenancePage extends Component {
46
48
  />
47
49
  );
48
50
  }
49
- return (
50
- <Components.Header leftIcon="angle-left" onPressLeft={this.onPressBack} text={this.props.title || Config.env.strings.MAINTENANCE} />
51
- );
51
+ return <Components.Header leftIcon="angle-left" onPressLeft={this.onPressBack} text={values.textFeatureTitle} />;
52
52
  }
53
53
 
54
54
  render() {
@@ -89,6 +89,7 @@ const styles = StyleSheet.create({
89
89
  const mapStateToProps = state => {
90
90
  return {
91
91
  user: state.user,
92
+ strings: state.strings?.config || {},
92
93
  };
93
94
  };
94
95
 
@@ -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
  };
@@ -173,7 +175,7 @@ class RequestDetail extends Component {
173
175
  };
174
176
 
175
177
  openStaffNotes = () => {
176
- Services.navigation.navigate('requestNotes', { job: this.state.job, onChange: this.getJob });
178
+ Services.navigation.navigate(values.screenRequestNotes, { job: this.state.job, onChange: this.getJob });
177
179
  };
178
180
 
179
181
  onOpenDatePicker = () => {
@@ -232,10 +234,10 @@ class RequestDetail extends Component {
232
234
  hasPermission = () => {
233
235
  const { job } = this.state;
234
236
  const { permissions } = this.props.user;
235
- if (_.includes(permissions, 'maintenanceTracking')) {
237
+ if (_.includes(permissions, values.permissionMaintenanceTracking)) {
236
238
  return true;
237
239
  }
238
- if (_.includes(permissions, 'maintenanceAssignment')) {
240
+ if (_.includes(permissions, values.permissionMaintenanceAssign)) {
239
241
  return job.AssigneeId === this.props.user.Id;
240
242
  }
241
243
  return false;
@@ -246,9 +248,10 @@ class RequestDetail extends Component {
246
248
  this.setState({ showFullscreenVideo: url.length > 0, currentVideoUrl: url });
247
249
  };
248
250
 
249
- openGallery(index) {
251
+ openGallery(galleryImages, index) {
250
252
  this.setState({
251
253
  galleryOpen: true,
254
+ galleryImages,
252
255
  });
253
256
  this.refs.imagePopup.scrollTo(index);
254
257
  }
@@ -299,7 +302,9 @@ class RequestDetail extends Component {
299
302
  return (
300
303
  <View style={{ ...Helper.getShadowStyle() }}>
301
304
  <View style={styles.jobTitleContainer}>
302
- {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}
303
308
  <Text style={styles.jobTitleText}>{job.title}</Text>
304
309
  <View style={styles.jobTypeSeenContainer}>
305
310
  <View style={[styles.jobTypeContainer, { backgroundColor: Colours.hexToRGBAstring(this.props.colourBrandingMain, 0.2) }]}>
@@ -362,7 +367,8 @@ class RequestDetail extends Component {
362
367
  );
363
368
  }
364
369
 
365
- renderPlayableImageUrl(url, index, containerStyle, showMore) {
370
+ renderPlayableImageUrl(images, index, containerStyle, showMore) {
371
+ const url = images[index || 0];
366
372
  const thumbUrl = Helper.getThumb300(url);
367
373
 
368
374
  if (Helper.isVideo(url)) {
@@ -379,7 +385,7 @@ class RequestDetail extends Component {
379
385
 
380
386
  const imageUrl = Helper.get1400(url);
381
387
  return (
382
- <TouchableOpacity style={containerStyle} onPress={this.openGallery.bind(this, index || 0)}>
388
+ <TouchableOpacity style={containerStyle} onPress={this.openGallery.bind(this, images, index || 0)}>
383
389
  <ImageBackground style={styles.imageContainer} source={{ uri: imageUrl }}>
384
390
  {showMore && <Text style={styles.plusImages}>+{this.state.job.images.length - 2}</Text>}
385
391
  </ImageBackground>
@@ -387,26 +393,24 @@ class RequestDetail extends Component {
387
393
  );
388
394
  }
389
395
 
390
- renderPlayableImage(index, containerStyle, showMore) {
391
- const url = this.state.job.images[index];
392
- return this.renderPlayableImageUrl(url, index, containerStyle, showMore);
396
+ renderPlayableImage(images, index, containerStyle, showMore) {
397
+ return this.renderPlayableImageUrl(images, index, containerStyle, showMore);
393
398
  }
394
399
 
395
- renderImage() {
396
- const { job } = this.state;
397
- if (!_.isNil(job.images) && !_.isEmpty(job.images)) {
398
- if (job.images.length >= 2) {
400
+ renderImage(images, image = null) {
401
+ if (!_.isNil(images) && !_.isEmpty(images)) {
402
+ if (images.length >= 2) {
399
403
  return (
400
404
  <View style={styles.sideBySideImages}>
401
- {this.renderPlayableImage(0, styles.sideBySideImageContainer)}
402
- {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)}
403
407
  </View>
404
408
  );
405
409
  } else {
406
- return <View style={styles.singleImageContainer}>{this.renderPlayableImage(0)}</View>;
410
+ return <View style={styles.singleImageContainer}>{this.renderPlayableImage(images, 0)}</View>;
407
411
  }
408
- } else if (!_.isNil(job.image)) {
409
- 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>;
410
414
  }
411
415
  return null;
412
416
  }
@@ -415,7 +419,7 @@ class RequestDetail extends Component {
415
419
  return (
416
420
  <Components.ImagePopup
417
421
  visible={this.state.galleryOpen}
418
- images={this.state.job.images || [this.state.job.image]}
422
+ images={this.state.galleryImages}
419
423
  onClose={this.closeGallery.bind(this)}
420
424
  ref="imagePopup"
421
425
  />
@@ -458,8 +462,43 @@ class RequestDetail extends Component {
458
462
  return content;
459
463
  }
460
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
+
461
498
  rendeDetails() {
462
499
  const { job } = this.state;
500
+ const { customFields } = job;
501
+ const hasCustomFields = customFields && customFields.length > 0;
463
502
 
464
503
  return (
465
504
  <View>
@@ -472,15 +511,20 @@ class RequestDetail extends Component {
472
511
  />
473
512
  {this.state.showMore && (
474
513
  <View>
475
- {this.renderImage()}
476
- {!_.isEmpty(job.description) && (
477
- <Text numberOfLines={10} style={styles.jobDescriptionText}>
478
- {job.description}
479
- </Text>
480
- )}
481
- <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>
482
526
  <Text style={styles.locationText}>{job.room}</Text>
483
- {job.isHome ? (
527
+ {!hasCustomFields && job.isHome ? (
484
528
  <View style={styles.detailsSection}>
485
529
  <Text style={styles.locationLabel}>Must be home</Text>
486
530
  <Text style={styles.locationText}>{job.homeText}</Text>
@@ -507,8 +551,8 @@ class RequestDetail extends Component {
507
551
  ref={this.commentSection}
508
552
  commentReply={this.commentReply}
509
553
  scrollView={this.scrollView}
510
- adminPermission="maintenanceTracking"
511
- entityType="maintenancerequest"
554
+ adminPermission={values.permissionMaintenanceTracking}
555
+ entityType={values.featureKey}
512
556
  entityId={this.props.job.id}
513
557
  entityName={this.props.job.title}
514
558
  site={this.state.job.site || this.state.job.location}
@@ -545,7 +589,7 @@ class RequestDetail extends Component {
545
589
  ref={this.commentReply}
546
590
  commentSection={this.commentSection}
547
591
  scrollView={this.scrollView}
548
- entityType="maintenancerequest"
592
+ entityType={values.featureKey}
549
593
  entityId={this.props.job.id}
550
594
  entityName={this.props.job.title}
551
595
  site={this.state.job.site || this.state.job.location}
@@ -834,13 +878,37 @@ const styles = StyleSheet.create({
834
878
  marginLeft: 10,
835
879
  lineHeight: 24,
836
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
+ },
837
905
  });
838
906
 
839
907
  const mapStateToProps = state => {
840
908
  return {
841
909
  user: state.user,
842
910
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
843
- jobs: state.jobs.jobs,
911
+ jobs: state[values.reducerKey].jobs,
844
912
  };
845
913
  };
846
914
 
@@ -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) {
@@ -410,7 +411,7 @@ const mapStateToProps = state => {
410
411
  user: state.user,
411
412
  colourBrandingMain: Colours.getMainBrandingColourFromState(state),
412
413
  colourBrandingLight: Colours.getLightBrandingColourFromState(state),
413
- jobs: state.jobs.jobs,
414
+ jobs: state[values.reducerKey].jobs,
414
415
  };
415
416
  };
416
417