@plusscommunities/pluss-maintenance-app 7.0.0-beta.0 → 7.0.0-beta.2

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 (58) hide show
  1. package/dist/module/actions/JobActions.js +44 -1
  2. package/dist/module/actions/JobActions.js.map +1 -1
  3. package/dist/module/actions/types.js +3 -0
  4. package/dist/module/actions/types.js.map +1 -1
  5. package/dist/module/apis/index.js +2 -0
  6. package/dist/module/apis/index.js.map +1 -1
  7. package/dist/module/apis/maintenanceActions.js +21 -6
  8. package/dist/module/apis/maintenanceActions.js.map +1 -1
  9. package/dist/module/components/FilterPopupMenu.js +34 -18
  10. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  11. package/dist/module/components/MaintenanceList.js +47 -56
  12. package/dist/module/components/MaintenanceList.js.map +1 -1
  13. package/dist/module/components/MaintenanceListItem.js +39 -26
  14. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  15. package/dist/module/components/MaintenanceWidgetItem.js +12 -12
  16. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  17. package/dist/module/components/PrioritySelectorPopup.js +82 -0
  18. package/dist/module/components/PrioritySelectorPopup.js.map +1 -0
  19. package/dist/module/components/StatusSelectorPopup.js +9 -14
  20. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  21. package/dist/module/components/WidgetSmall.js +7 -3
  22. package/dist/module/components/WidgetSmall.js.map +1 -1
  23. package/dist/module/helper.js +39 -25
  24. package/dist/module/helper.js.map +1 -1
  25. package/dist/module/reducers/JobsReducer.js +31 -2
  26. package/dist/module/reducers/JobsReducer.js.map +1 -1
  27. package/dist/module/screens/RequestDetail.js +90 -18
  28. package/dist/module/screens/RequestDetail.js.map +1 -1
  29. package/dist/module/screens/RequestNotes.js +430 -21
  30. package/dist/module/screens/RequestNotes.js.map +1 -1
  31. package/dist/module/values.config.a.js +6 -1
  32. package/dist/module/values.config.a.js.map +1 -1
  33. package/dist/module/values.config.default.js +6 -1
  34. package/dist/module/values.config.default.js.map +1 -1
  35. package/dist/module/values.config.forms.js +6 -1
  36. package/dist/module/values.config.forms.js.map +1 -1
  37. package/dist/module/values.config.js +6 -1
  38. package/dist/module/values.config.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/actions/JobActions.js +53 -1
  41. package/src/actions/types.js +4 -0
  42. package/src/apis/index.js +4 -0
  43. package/src/apis/maintenanceActions.js +18 -6
  44. package/src/components/FilterPopupMenu.js +40 -21
  45. package/src/components/MaintenanceList.js +38 -47
  46. package/src/components/MaintenanceListItem.js +35 -21
  47. package/src/components/MaintenanceWidgetItem.js +16 -12
  48. package/src/components/PrioritySelectorPopup.js +79 -0
  49. package/src/components/StatusSelectorPopup.js +8 -14
  50. package/src/components/WidgetSmall.js +5 -3
  51. package/src/helper.js +50 -21
  52. package/src/reducers/JobsReducer.js +25 -1
  53. package/src/screens/RequestDetail.js +87 -24
  54. package/src/screens/RequestNotes.js +429 -30
  55. package/src/values.config.a.js +5 -0
  56. package/src/values.config.default.js +5 -0
  57. package/src/values.config.forms.js +5 -0
  58. package/src/values.config.js +5 -0
@@ -1,5 +1,17 @@
1
1
  import React, { Component } from 'react';
2
- import { ScrollView, View, Text, TouchableOpacity, Modal, KeyboardAvoidingView, Platform } from 'react-native';
2
+ import {
3
+ ScrollView,
4
+ View,
5
+ Text,
6
+ TouchableOpacity,
7
+ Modal,
8
+ KeyboardAvoidingView,
9
+ Platform,
10
+ FlatList,
11
+ Dimensions,
12
+ ImageBackground,
13
+ Keyboard,
14
+ } from 'react-native';
3
15
  import { connect } from 'react-redux';
4
16
  import { Icon } from '@rneui/themed';
5
17
  import _ from 'lodash';
@@ -11,6 +23,9 @@ import { Services } from '../feature.config';
11
23
  import { Components, Colours, Helper } from '../core.config';
12
24
  import { values } from '../values.config';
13
25
 
26
+ const SCREEN_WIDTH = Dimensions.get('window').width;
27
+ const PHOTO_SIZE = (SCREEN_WIDTH - 64) / 3;
28
+
14
29
  class RequestNotes extends Component {
15
30
  constructor(props) {
16
31
  super(props);
@@ -21,7 +36,13 @@ class RequestNotes extends Component {
21
36
  noteAttachments: [],
22
37
  noteInput: '',
23
38
  addNoteOpen: false,
39
+ noteImages: [{ add: true }],
40
+ uploadingImage: false,
41
+ galleryOpen: false,
42
+ galleryImages: [],
43
+ galleryIndex: 0,
24
44
  };
45
+ this.checkThumb = null;
25
46
  }
26
47
 
27
48
  componentDidMount() {
@@ -34,6 +55,10 @@ class RequestNotes extends Component {
34
55
  }
35
56
  }
36
57
 
58
+ componentWillUnmount() {
59
+ clearInterval(this.checkThumb);
60
+ }
61
+
37
62
  updateJobState() {
38
63
  const job = _.find(this.props.jobs, j => j.id === this.props.job.id) || this.props.job;
39
64
  this.setState({ job });
@@ -81,14 +106,14 @@ class RequestNotes extends Component {
81
106
  };
82
107
 
83
108
  isReadyToSaveNote = () => {
84
- if (
85
- _.some(this.state.noteAttachments, n => {
86
- return n.Uploading;
87
- })
88
- ) {
89
- return false;
90
- }
91
- return !_.isEmpty(this.state.noteInput) || !_.isEmpty(this.state.noteAttachments);
109
+ const uploadingAttachments = _.some(this.state.noteAttachments, n => n.Uploading);
110
+ const uploadingImages = _.some(this.state.noteImages, n => n.uploading);
111
+ if (uploadingAttachments || uploadingImages) return false;
112
+ return (
113
+ !_.isEmpty(this.state.noteInput) ||
114
+ !_.isEmpty(this.state.noteAttachments) ||
115
+ !_.isEmpty(this.state.noteImages.filter(img => !img.add))
116
+ );
92
117
  };
93
118
 
94
119
  openAddNote = () => {
@@ -106,13 +131,16 @@ class RequestNotes extends Component {
106
131
  if (!!this.state.editingNote) {
107
132
  newState.noteInput = '';
108
133
  newState.noteAttachments = [];
134
+ newState.noteImages = [];
109
135
  }
110
136
  this.setState(newState);
111
137
  };
112
138
 
113
139
  openEditNote = n => {
140
+ const noteImages = [...(n.Images || []).map(i => ({ url: i, thumbNailUrl: Helper.getThumb300(i) })), { add: true }];
114
141
  this.setState({
115
142
  noteAttachments: n.Attachments || [],
143
+ noteImages,
116
144
  noteInput: n.Note || '',
117
145
  addNoteOpen: true,
118
146
  editingNote: n.Id,
@@ -127,28 +155,18 @@ class RequestNotes extends Component {
127
155
 
128
156
  try {
129
157
  this.setState({ submittingNote: true });
158
+ const attachments = this.state.noteAttachments
159
+ .filter(a => !a.add)
160
+ .map(a => {
161
+ return {
162
+ Title: a.Title,
163
+ Source: a.Source,
164
+ };
165
+ });
166
+ const images = this.state.noteImages.filter(img => !img.add).map(img => img.url);
130
167
  const res = await (this.state.editingNote
131
- ? maintenanceActions.editNote(
132
- this.props.job.id,
133
- this.state.editingNote,
134
- this.state.noteInput,
135
- this.state.noteAttachments.map(a => {
136
- return {
137
- Title: a.Title,
138
- Source: a.Source,
139
- };
140
- }),
141
- )
142
- : maintenanceActions.addNote(
143
- this.props.job.id,
144
- this.state.noteInput,
145
- this.state.noteAttachments.map(a => {
146
- return {
147
- Title: a.Title,
148
- Source: a.Source,
149
- };
150
- }),
151
- ));
168
+ ? maintenanceActions.editNote(this.props.job.id, this.state.editingNote, this.state.noteInput, attachments, images)
169
+ : maintenanceActions.addNote(this.props.job.id, this.state.noteInput, attachments, images));
152
170
  this.setState(
153
171
  {
154
172
  job: res.data.job,
@@ -156,6 +174,8 @@ class RequestNotes extends Component {
156
174
  addNoteOpen: false,
157
175
  noteInput: '',
158
176
  noteAttachments: [],
177
+ noteImages: [{ add: true }],
178
+ uploadingImage: false,
159
179
  editingNote: null,
160
180
  },
161
181
  () => {
@@ -168,10 +188,156 @@ class RequestNotes extends Component {
168
188
  console.log(err);
169
189
  this.setState({
170
190
  submittingNote: false,
191
+ uploadingImage: false,
171
192
  });
172
193
  }
173
194
  };
174
195
 
196
+ setImages = (noteImages, uploadingImage = false, callback = null) => {
197
+ this.setState({ noteImages, uploadingImage }, callback);
198
+ };
199
+
200
+ getImages = () => {
201
+ const { noteImages } = this.state;
202
+ const imagesList = _.cloneDeep(noteImages);
203
+ if (!imagesList || !Array.isArray(imagesList) || imagesList.length === 0) {
204
+ return [{ add: true }];
205
+ }
206
+ return imagesList;
207
+ };
208
+
209
+ getImageUrls = () => {
210
+ const imagesList = this.getImages();
211
+ return _.filter(imagesList, img => {
212
+ return !img.uploading && !img.add;
213
+ }).map(img => {
214
+ return img.url;
215
+ });
216
+ };
217
+
218
+ waitForThumbnails = () => {
219
+ if (this.checkThumb) return;
220
+
221
+ this.checkThumb = setInterval(async () => {
222
+ const imagesList = this.getImages();
223
+ const imagesUpdate = [];
224
+ await Promise.all(
225
+ imagesList.map(image => {
226
+ return new Promise(async resolve => {
227
+ const newImage = { ...image };
228
+ imagesUpdate.push(newImage);
229
+ if (newImage.url && !newImage.thumbNailExists) {
230
+ newImage.uploading = false;
231
+ newImage.allowRetry = false;
232
+ newImage.thumbNailExists = await Helper.imageExists(newImage.thumbNailUrl);
233
+ resolve(newImage.thumbNailExists);
234
+ }
235
+ resolve(true);
236
+ });
237
+ }),
238
+ );
239
+ const thumbnailsExist = imagesUpdate.every(image => !image.url || image.thumbNailExists);
240
+ if (thumbnailsExist) {
241
+ clearInterval(this.checkThumb);
242
+ this.checkThumb = null;
243
+ this.setImages(imagesUpdate);
244
+ }
245
+ }, 2000);
246
+ };
247
+
248
+ removeImage = index => {
249
+ const imagesUpdate = this.getImages();
250
+ imagesUpdate.splice(index, 1);
251
+
252
+ this.setImages(imagesUpdate);
253
+ };
254
+
255
+ showUploadMenu = () => {
256
+ Keyboard.dismiss();
257
+ const { uploadingImage, submittingNote } = this.state;
258
+ if (uploadingImage || submittingNote) return;
259
+ this.imageUploader.showUploadMenu();
260
+ };
261
+
262
+ toggleFullscreenVideo = url => {
263
+ if (typeof url !== 'string') url = '';
264
+ this.setState({ showFullscreenVideo: url.length > 0, currentVideoUrl: url });
265
+ };
266
+
267
+ openGallery(images, index) {
268
+ this.setState({ galleryOpen: true, galleryImages: images, galleryIndex: index });
269
+ }
270
+
271
+ closeGallery() {
272
+ this.setState({ galleryOpen: false, galleryImages: [], galleryIndex: 0 });
273
+ }
274
+
275
+ onUploadStarted = (uploadUri, imageUri) => {
276
+ const imagesUpdate = this.getImages();
277
+ imagesUpdate.splice(imagesUpdate.length - 1, 0, {
278
+ uploading: true,
279
+ uploadProgress: '0%',
280
+ uploadUri,
281
+ imageUri,
282
+ allowRetry: true,
283
+ });
284
+
285
+ this.setImages(imagesUpdate, true);
286
+ };
287
+
288
+ onUploadProgress = progress => {
289
+ const imagesUpdate = this.getImages();
290
+ imagesUpdate.map(img => {
291
+ if (img.uploadUri === progress.uri) {
292
+ img.uploadProgress = progress.percentage;
293
+ img.uploading = true;
294
+ img.allowRetry = true;
295
+ }
296
+ });
297
+
298
+ this.setImages(imagesUpdate, true);
299
+ };
300
+
301
+ onUploadSuccess = async (uri, uploadUri) => {
302
+ const imagesUpdate = this.getImages();
303
+ imagesUpdate.map(img => {
304
+ if (img.uploadUri === uploadUri && img.uploading) {
305
+ img.url = uri.replace('/general/', '/general1400/');
306
+ img.thumbNailExists = false;
307
+ img.thumbNailUrl = Helper.getThumb300(img.url);
308
+ img.allowRetry = true;
309
+ }
310
+ });
311
+
312
+ this.setImages(imagesUpdate, false, () => this.waitForThumbnails());
313
+ };
314
+
315
+ onUploadFailed = uploadUri => {
316
+ const imagesUpdate = this.getImages();
317
+ imagesUpdate.map(img => {
318
+ if (img.uploadUri === uploadUri) {
319
+ img.uploading = true; // Requried for retry
320
+ img.uploadProgress = '';
321
+ img.allowRetry = true;
322
+ }
323
+ });
324
+
325
+ this.setImages(imagesUpdate);
326
+ };
327
+
328
+ onLibrarySelected = uri => {
329
+ const imagesUpdate = this.getImages();
330
+ imagesUpdate.splice(imagesUpdate.length - 1, 0, {
331
+ uploading: false,
332
+ allowRetry: false,
333
+ url: Helper.get1400(uri),
334
+ thumbNailExists: true,
335
+ thumbNailUrl: Helper.getThumb300(uri),
336
+ });
337
+
338
+ this.setImages(imagesUpdate);
339
+ };
340
+
175
341
  renderAttachment(a, i) {
176
342
  return (
177
343
  <Components.Attachment
@@ -184,6 +350,50 @@ class RequestNotes extends Component {
184
350
  );
185
351
  }
186
352
 
353
+ renderPlayableImageUrl(images, index, containerStyle) {
354
+ const url = images[index];
355
+ const thumbUrl = Helper.getThumb300(url);
356
+
357
+ if (Helper.isVideo(url)) {
358
+ return (
359
+ <ImageBackground style={[{ flex: 1 }, containerStyle]} source={{ uri: thumbUrl }}>
360
+ <View style={styles.imagePlayContainer}>
361
+ <TouchableOpacity onPress={this.toggleFullscreenVideo.bind(this, url)}>
362
+ <Icon name="play" type="font-awesome" iconStyle={styles.imageControlIcon} />
363
+ </TouchableOpacity>
364
+ </View>
365
+ </ImageBackground>
366
+ );
367
+ }
368
+
369
+ const imageUrl = Helper.get1400(url);
370
+ return (
371
+ <TouchableOpacity style={containerStyle} onPress={this.openGallery.bind(this, images, index || 0)}>
372
+ <ImageBackground resizeMode="cover" style={styles.imageContainer} source={{ uri: imageUrl }} />
373
+ </TouchableOpacity>
374
+ );
375
+ }
376
+
377
+ renderImages(note) {
378
+ if (!note) return null;
379
+ if (!_.isNil(note.Images) && !_.isEmpty(note.Images)) {
380
+ return (
381
+ <ScrollView horizontal style={styles.sideBySideImages}>
382
+ {note.Images.map((_p, index) => this.renderPlayableImageUrl(note.Images, index, styles.sideBySideImageContainer))}
383
+ </ScrollView>
384
+ );
385
+ }
386
+ return null;
387
+ }
388
+
389
+ renderImagePopup() {
390
+ const { galleryOpen, galleryImages, galleryIndex } = this.state;
391
+ console.log('renderimagepopup', { galleryOpen, galleryImages, galleryIndex });
392
+ return (
393
+ <Components.ImagePopup visible={galleryOpen} images={galleryImages} index={galleryIndex} onClose={this.closeGallery.bind(this)} />
394
+ );
395
+ }
396
+
187
397
  renderNote(n) {
188
398
  return (
189
399
  <View style={styles.noteContainer} key={n.Id}>
@@ -219,6 +429,7 @@ class RequestNotes extends Component {
219
429
  </View>
220
430
  <Text style={styles.noteContainerText}>{n.Note}</Text>
221
431
  {(n.Attachments || []).map((a, i) => this.renderAttachment(a, i))}
432
+ {this.renderImages(n)}
222
433
  <Text style={styles.noteTimestamp}>
223
434
  {moment
224
435
  .utc(n.Timestamp)
@@ -272,10 +483,118 @@ class RequestNotes extends Component {
272
483
  );
273
484
  }
274
485
 
486
+ renderUploadMenu() {
487
+ return (
488
+ <Components.ImageUploader
489
+ ref={ref => (this.imageUploader = ref)}
490
+ onUploadStarted={this.onUploadStarted}
491
+ onUploadSuccess={this.onUploadSuccess}
492
+ onUploadFailed={this.onUploadFailed}
493
+ onUploadProgress={this.onUploadProgress}
494
+ onLibrarySelected={this.onLibrarySelected}
495
+ size={{ width: 1400 }}
496
+ quality={0.8}
497
+ fileName={'serviceNoteImage'}
498
+ popupTitle={'Upload Image'}
499
+ userId={this.props.user.uid}
500
+ allowsEditing={false}
501
+ multiple
502
+ hideLibrary
503
+ />
504
+ );
505
+ }
506
+
507
+ renderImage(item, index) {
508
+ const isVideoUrl = Helper.isVideo(item.url);
509
+ const imagesList = this.getImages();
510
+
511
+ if (item.add) {
512
+ return (
513
+ <TouchableOpacity activeOpacity={0.8} onPress={() => this.showUploadMenu()}>
514
+ <View
515
+ style={[
516
+ styles.imageContainer,
517
+ imagesList.length > 1 && styles.imageContainerNotEmpty,
518
+ index % 3 === 0 && { marginLeft: 0 },
519
+ index > 2 && { marginTop: 8 },
520
+ ]}
521
+ >
522
+ <View style={styles.imageCircle}>
523
+ <Icon name="camera" type="font-awesome" iconStyle={styles.addImageIcon} />
524
+ </View>
525
+ </View>
526
+ </TouchableOpacity>
527
+ );
528
+ }
529
+ return (
530
+ <View
531
+ style={[
532
+ styles.imageContainer,
533
+ imagesList.length > 1 && styles.imageContainerNotEmpty,
534
+ index % 3 === 0 && { marginLeft: 0 },
535
+ index > 2 && { marginTop: 8 },
536
+ ]}
537
+ >
538
+ {item.uploading ? (
539
+ <Components.ImageUploadProgress uploader={this.imageUploader} image={item} color={this.props.colourBrandingMain} />
540
+ ) : (
541
+ <ImageBackground
542
+ style={styles.imageBackground}
543
+ source={Helper.getImageSource(item.thumbNailExists ? item.thumbNailUrl : item.url || item)}
544
+ >
545
+ {isVideoUrl && (
546
+ <View style={styles.imagePlayContainer}>
547
+ <TouchableOpacity onPress={this.toggleFullscreenVideo.bind(this, item.url)}>
548
+ <Icon name="play" type="font-awesome" iconStyle={styles.imageControlIcon} />
549
+ </TouchableOpacity>
550
+ </View>
551
+ )}
552
+ <TouchableOpacity style={styles.removeImage} onPress={() => this.removeImage(index)}>
553
+ <Icon name="remove" type="font-awesome" iconStyle={styles.imageControlIcon} style={styles.removeImage} />
554
+ </TouchableOpacity>
555
+ </ImageBackground>
556
+ )}
557
+ </View>
558
+ );
559
+ }
560
+
561
+ renderImageList() {
562
+ const imagesList = this.getImages();
563
+
564
+ return (
565
+ <View style={styles.imageListContainer}>
566
+ <FlatList
567
+ keyboardShouldPersistTaps="always"
568
+ enableEmptySections
569
+ data={imagesList}
570
+ renderItem={({ item, index }) => this.renderImage(item, index)}
571
+ keyExtractor={(item, index) => index}
572
+ numColumns={3}
573
+ scrollEnabled={false}
574
+ />
575
+ </View>
576
+ );
577
+ }
578
+
579
+ renderVideoPlayerPopup() {
580
+ const { showFullscreenVideo, currentVideoUrl } = this.state;
581
+ if (!currentVideoUrl) return;
582
+
583
+ return (
584
+ <Components.VideoPopup
585
+ uri={currentVideoUrl}
586
+ visible={showFullscreenVideo}
587
+ showFullscreenButton={false}
588
+ onClose={this.toggleFullscreenVideo}
589
+ />
590
+ );
591
+ }
592
+
275
593
  renderAdd() {
276
594
  return (
277
595
  <Modal animationType="slide" visible={this.state.addNoteOpen}>
278
596
  <KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' && 'padding'}>
597
+ {this.renderUploadMenu()}
279
598
  <Components.Header leftText="Cancel" onPressLeft={this.closeAddNote} text="" />
280
599
  <ScrollView style={styles.scrollContainer} contentContainerStyle={styles.innerContainer}>
281
600
  <Components.TextStyle type="pageHeading">Add Staff Note</Components.TextStyle>
@@ -297,6 +616,7 @@ class RequestNotes extends Component {
297
616
  sectionStyle={styles.inputSection}
298
617
  />
299
618
  <Components.GenericInputSection label="Attachments" sectionStyle={styles.inputSection}>
619
+ {this.renderImageList()}
300
620
  {this.state.editingNote ? (
301
621
  (this.state.noteAttachments || []).map((a, i) => this.renderAttachment(a, i))
302
622
  ) : (
@@ -307,6 +627,7 @@ class RequestNotes extends Component {
307
627
  </Components.GenericInputSection>
308
628
  </ScrollView>
309
629
  <View style={styles.popupFooter}>{this.renderFooterContent()}</View>
630
+ {this.renderVideoPlayerPopup()}
310
631
  </KeyboardAvoidingView>
311
632
  </Modal>
312
633
  );
@@ -323,6 +644,7 @@ class RequestNotes extends Component {
323
644
  {this.renderNotes()}
324
645
  </ScrollView>
325
646
  <Components.AddButton onPress={this.openAddNote} />
647
+ {this.renderImagePopup()}
326
648
  </View>
327
649
  );
328
650
  }
@@ -404,6 +726,83 @@ const styles = {
404
726
  attachmentInfo: {
405
727
  marginTop: 8,
406
728
  },
729
+ imageListContainer: {
730
+ marginVertical: 8,
731
+ },
732
+ imageContainer: {
733
+ width: PHOTO_SIZE,
734
+ height: PHOTO_SIZE,
735
+ borderStyle: 'dashed',
736
+ justifyContent: 'center',
737
+ alignItems: 'center',
738
+ borderWidth: 1,
739
+ borderColor: Colours.LINEGREY,
740
+ backgroundColor: Colours.BOXGREY,
741
+ borderRadius: 4,
742
+ marginLeft: 8,
743
+ },
744
+ imageContainerNotEmpty: {
745
+ borderWidth: 1,
746
+ borderColor: Colours.LINEGREY,
747
+ backgroundColor: '#fff',
748
+ borderStyle: 'dashed',
749
+ },
750
+ imageBackground: {
751
+ flex: 1,
752
+ height: '100%',
753
+ width: '100%',
754
+ borderRadius: 4,
755
+ },
756
+ imageCircle: {
757
+ width: 90,
758
+ height: 90,
759
+ borderRadius: 45,
760
+ backgroundColor: Colours.PINKISH_GREY,
761
+ justifyContent: 'center',
762
+ },
763
+ addImageIcon: {
764
+ color: '#fff',
765
+ fontSize: 32,
766
+ },
767
+ imagePlayContainer: {
768
+ position: 'absolute',
769
+ top: 0,
770
+ left: 0,
771
+ right: 0,
772
+ bottom: 0,
773
+ alignItems: 'center',
774
+ justifyContent: 'center',
775
+ },
776
+ imageControlIcon: {
777
+ color: '#fff',
778
+ fontSize: 20,
779
+ textShadowColor: 'rgba(0,0,0,0.3)',
780
+ textShadowOffset: { width: 2, height: 2 },
781
+ },
782
+ removeImage: {
783
+ position: 'absolute',
784
+ top: 0,
785
+ right: 0,
786
+ padding: 4,
787
+ width: 40,
788
+ height: 40,
789
+ alignItems: 'center',
790
+ justifyContent: 'center',
791
+ },
792
+ sideBySideImages: {
793
+ flex: 1,
794
+ flexDirection: 'row',
795
+ marginTop: 12,
796
+ marginHorizontal: -8,
797
+ },
798
+ sideBySideImageContainer: {
799
+ backgroundColor: '#fff',
800
+ width: 60,
801
+ height: 50,
802
+ borderRadius: 2,
803
+ overflow: 'hidden',
804
+ marginRight: 2,
805
+ },
407
806
  };
408
807
 
409
808
  const mapStateToProps = state => {
@@ -8,6 +8,9 @@ const values = {
8
8
  actionJobsLoaded: 'JOBS_LOADEDA',
9
9
  actionJobAdded: 'JOB_ADDEDA',
10
10
  actionJobsAdded: 'JOBS_ADDEDA',
11
+ actionJobsStatusesLoaded: 'JOBS_STATUSES_LOADEDA',
12
+ actionJobsHideSeen: 'JOBS_HIDE_SEENA',
13
+ actionJobFilterLoaded: 'JOBS_FILTER_LOADEDA',
11
14
  screenMaintenance: 'maintenanceA',
12
15
  screenRequestDetail: 'requestDetailA',
13
16
  screenServiceRequest: 'serviceRequestA',
@@ -26,6 +29,8 @@ const values = {
26
29
  textMoreMenuTitle: 'Request A',
27
30
  textKioskActionTitle: 'Request A',
28
31
  textEntityName: 'Job',
32
+ stringConfigJobStatus: 'maintenanceJobStatusA',
33
+ stringConfigHideSeen: 'maintenanceDisableSeenA',
29
34
  };
30
35
 
31
36
  export { values };
@@ -8,6 +8,9 @@ const values = {
8
8
  actionJobsLoaded: 'JOBS_LOADED',
9
9
  actionJobAdded: 'JOB_ADDED',
10
10
  actionJobsAdded: 'JOBS_ADDED',
11
+ actionJobsStatusesLoaded: 'JOBS_STATUSES_LOADED',
12
+ actionJobsHideSeen: 'JOBS_HIDE_SEEN',
13
+ actionJobFilterLoaded: 'JOBS_FILTER_LOADED',
11
14
  screenMaintenance: 'maintenance',
12
15
  screenRequestDetail: 'requestDetail',
13
16
  screenServiceRequest: 'serviceRequest',
@@ -32,6 +35,8 @@ const values = {
32
35
  emptyRequestsStaff: 'No active Requests',
33
36
  emptyRequestsUser: 'Your Requests will show here',
34
37
  forceCustomFields: false,
38
+ stringConfigJobStatus: 'maintenanceJobStatus',
39
+ stringConfigHideSeen: 'maintenanceDisableSeen',
35
40
  };
36
41
 
37
42
  export { values };
@@ -8,6 +8,9 @@ const values = {
8
8
  actionJobsLoaded: 'JOBS_LOADEDForms',
9
9
  actionJobAdded: 'JOB_ADDEDForms',
10
10
  actionJobsAdded: 'JOBS_ADDEDForms',
11
+ actionJobsStatusesLoaded: 'JOBS_STATUSES_LOADEDForms',
12
+ actionJobsHideSeen: 'JOBS_HIDE_SEENForms',
13
+ actionJobFilterLoaded: 'JOBS_FILTER_LOADEDForms',
11
14
  screenMaintenance: 'maintenanceForms',
12
15
  screenRequestDetail: 'requestDetailForms',
13
16
  screenServiceRequest: 'serviceRequestForms',
@@ -32,6 +35,8 @@ const values = {
32
35
  emptyRequestsStaff: 'No active Form Submissions',
33
36
  emptyRequestsUser: 'Your Form Submissions will show here',
34
37
  forceCustomFields: true,
38
+ stringConfigJobStatus: 'maintenanceJobStatusForms',
39
+ stringConfigHideSeen: 'maintenanceDisableSeenForms',
35
40
  };
36
41
 
37
42
  export { values };
@@ -8,6 +8,9 @@ const values = {
8
8
  actionJobsLoaded: 'JOBS_LOADED',
9
9
  actionJobAdded: 'JOB_ADDED',
10
10
  actionJobsAdded: 'JOBS_ADDED',
11
+ actionJobsStatusesLoaded: 'JOBS_STATUSES_LOADED',
12
+ actionJobsHideSeen: 'JOBS_HIDE_SEEN',
13
+ actionJobFilterLoaded: 'JOBS_FILTER_LOADED',
11
14
  screenMaintenance: 'maintenance',
12
15
  screenRequestDetail: 'requestDetail',
13
16
  screenServiceRequest: 'serviceRequest',
@@ -32,6 +35,8 @@ const values = {
32
35
  emptyRequestsStaff: 'No active Requests',
33
36
  emptyRequestsUser: 'Your Requests will show here',
34
37
  forceCustomFields: false,
38
+ stringConfigJobStatus: 'maintenanceJobStatus',
39
+ stringConfigHideSeen: 'maintenanceDisableSeen',
35
40
  };
36
41
 
37
42
  export { values };