learningtribes-studio-frontend 1.4.2-alpha.4 → 1.4.2-alpha.5

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.
@@ -14,7 +14,6 @@ import styles from './EditImageModal.scss';
14
14
  import WrappedAssetsClearSearchButton from '../AssetsClearSearchButton/container';
15
15
  import WrappedAssetsDropZone from '../AssetsDropZone/container';
16
16
  import WrappedAssetsList from '../AssetsList/container';
17
- import WrappedAssetsSearch from '../AssetsSearch/container';
18
17
  import WrappedMessage from '../../utils/i18n/formattedMessageWrapper';
19
18
 
20
19
 
@@ -56,9 +55,7 @@ const initialEditImageModalState = {
56
55
  isImageDimensionsValid: true,
57
56
  isModalOpen: false,
58
57
  isStatusAlertOpen: false,
59
- pageNumber: 1,
60
58
  editingExisting: false,
61
- shouldShowPreviousButton: false,
62
59
  };
63
60
 
64
61
  export default class EditImageModal extends React.Component {
@@ -74,8 +71,6 @@ export default class EditImageModal extends React.Component {
74
71
  this.onImageDimensionBlur = this.onImageDimensionBlur.bind(this);
75
72
  this.onInsertImageButtonClick = this.onInsertImageButtonClick.bind(this);
76
73
  this.onImageLoad = this.onImageLoad.bind(this);
77
- this.onNextPageButtonClick = this.onNextPageButtonClick.bind(this);
78
- this.onPreviousPageButtonClick = this.onPreviousPageButtonClick.bind(this);
79
74
  this.onStatusAlertClose = this.onStatusAlertClose.bind(this);
80
75
  // Create ref setters to minimize anonymous inline functions
81
76
  this.setDropZoneButtonRef = this.setDropZoneButtonRef.bind(this);
@@ -83,14 +78,12 @@ export default class EditImageModal extends React.Component {
83
78
  this.setImageFormRef = this.setImageFormRef.bind(this);
84
79
  this.setImageRef = this.setImageRef.bind(this);
85
80
  this.setModalWrapperRef = this.setModalWrapperRef.bind(this);
86
- this.setPreviousButtonRef = this.setPreviousButtonRef.bind(this);
87
81
  this.setStatusAlertRef = this.setStatusAlertRef.bind(this);
88
82
 
89
83
  this.dropZoneButtonRef = null;
90
84
  this.imageDescriptionInputRef = null;
91
85
  this.imageFormRef = null;
92
86
  this.imageRef = null;
93
- this.previousPageButtonRef = null;
94
87
  this.modalWrapperRef = null;
95
88
  this.statusAlertRef = null;
96
89
  }
@@ -108,8 +101,6 @@ export default class EditImageModal extends React.Component {
108
101
  nextProps.clearAssetsStatus();
109
102
  newState.currentUploadErrorMessage = null;
110
103
  newState.isStatusAlertOpen = false;
111
- // Stay on page 1 - the form fields are now shown on the same page
112
- newState.pageNumber = 1;
113
104
  break;
114
105
  }
115
106
  case assetActions.upload.UPLOAD_EXCEED_MAX_COUNT_ERROR: {
@@ -152,8 +143,6 @@ export default class EditImageModal extends React.Component {
152
143
 
153
144
  componentDidUpdate(prevProps, prevState) {
154
145
  this.didStatusAlertOpen(prevState);
155
- this.wasNextButtonClicked(prevState);
156
- this.wasPreviousButtonClicked(prevState);
157
146
  }
158
147
 
159
148
  componentWillUnmount() {
@@ -238,27 +227,6 @@ export default class EditImageModal extends React.Component {
238
227
  };
239
228
  }
240
229
 
241
- onNextPageButtonClick = () => {
242
- if (this.isAssetSelected()) {
243
- this.setState({
244
- currentUploadErrorMessage: null,
245
- isStatusAlertOpen: false,
246
- pageNumber: 2,
247
- });
248
- this.props.clearAssetsStatus();
249
- }
250
- }
251
-
252
- onPreviousPageButtonClick = () => {
253
- this.setState({
254
- currentValidationMessages: {},
255
- isImageDescriptionValid: true,
256
- isImageDimensionsValid: true,
257
- isStatusAlertOpen: false,
258
- pageNumber: 1,
259
- });
260
- }
261
-
262
230
  onInsertImageButtonClick = () => {
263
231
  const isValidImageDescription = this.validateImageDescription();
264
232
  const isValidImageDimensions = this.validateImageDimensions();
@@ -311,15 +279,16 @@ export default class EditImageModal extends React.Component {
311
279
  }
312
280
 
313
281
  onStatusAlertClose = () => {
314
- if (this.state.pageNumber === 1) {
315
- this.props.clearAssetsStatus();
316
- this.dropZoneButtonRef.focus();
317
- } else if (this.state.pageNumber === 2) {
318
- if (this.state.shouldShowPreviousButton) {
319
- this.previousPageButtonRef.focus();
320
- } else {
282
+ const hasValidationMessages = Object.keys(this.state.currentValidationMessages)
283
+ .some(key => this.state.currentValidationMessages[key]);
284
+
285
+ if (hasValidationMessages) {
286
+ if (this.imageDescriptionInputRef) {
321
287
  this.imageDescriptionInputRef.focus();
322
288
  }
289
+ } else if (this.dropZoneButtonRef) {
290
+ this.props.clearAssetsStatus();
291
+ this.dropZoneButtonRef.focus();
323
292
  }
324
293
 
325
294
  this.setState({
@@ -347,10 +316,6 @@ export default class EditImageModal extends React.Component {
347
316
  this.modalWrapperRef = ref;
348
317
  }
349
318
 
350
- setPreviousButtonRef(ref) {
351
- this.previousPageButtonRef = ref;
352
- }
353
-
354
319
  setStatusAlertRef(ref) {
355
320
  this.statusAlertRef = ref;
356
321
  }
@@ -424,8 +389,6 @@ export default class EditImageModal extends React.Component {
424
389
  <WrappedMessage message={messages.editImageModalImageDescriptionDescription} />
425
390
  {' '}
426
391
  {this.getLearnMoreLink()}
427
- {' '}
428
- <WrappedMessage message={messages.editImageModalImageDecorativeDescription} />
429
392
  </React.Fragment>
430
393
  );
431
394
 
@@ -489,78 +452,46 @@ export default class EditImageModal extends React.Component {
489
452
  rewriteStaticLinks(this.state.imageSource, '/static/', this.state.baseAssetURL)
490
453
  );
491
454
 
492
- getImage = () => (
493
- <img
494
- alt=""
495
- className={classNames(styles['image-preview-image'], { invisible: !this.state.isImageLoaded })}
496
- src={this.getImageAssetSource()}
497
- onLoad={this.onImageLoad}
498
- onError={this.onImageError}
499
- ref={this.setImageRef}
500
- />
501
- );
455
+ getValidationMessages = () => (
456
+ Object.keys(this.state.currentValidationMessages).reduce((accumulator, current) => {
457
+ const value = this.state.currentValidationMessages[current];
502
458
 
503
- /*
504
- image is conditionally displayed so that onImageError is not called on initial
505
- modal open, when image source is empty string
506
- */
507
- getImagePreviewPlaceholder = () => (
508
- <div className={styles['image-preview-placeholder']}>
509
- <WrappedMessage message={messages.editImageModalImagePreviewText} >
510
- {displayText =>
511
- (<span className={classNames({ invisible: this.state.isImageLoaded })}>
512
- {displayText}
513
- </span>)}
514
- </WrappedMessage>
515
- {this.state.imageSource && this.getImage()}
516
- </div>
517
- );
459
+ if (value) {
460
+ accumulator.push(
461
+ <li key={`Error-${current}`}>
462
+ <a href={`#${current}`}>{value} </a>
463
+ </li>,
464
+ );
465
+ }
518
466
 
519
- getImagePreview = () => (
520
- // image preview is decorative
521
- <div aria-hidden>
522
- <WrappedMessage message={messages.editImageModalImagePreviewText} />
523
- <div className={styles['image-preview-container']}>
524
- {this.getImagePreviewPlaceholder()}
525
- </div>
526
- </div>
467
+ return accumulator;
468
+ }, [])
527
469
  );
528
470
 
529
471
  getStatusAlertDialog = () => {
530
- let dialog;
472
+ const validationMessages = this.getValidationMessages();
531
473
 
532
- if (this.state.pageNumber === 1) {
533
- dialog = (
474
+ if (validationMessages.length === 0) {
475
+ return (
534
476
  <React.Fragment>
535
477
  {this.getUploadErrorStatusMessage()}
536
478
  </React.Fragment>
537
479
  );
538
- } else if (this.state.pageNumber === 2) {
539
- dialog = (
540
- <div>
541
- <WrappedMessage
542
- message={messages.editImageModalFormErrorMissingFields}
543
- tagName="div"
544
- />
545
- <div className="mt-3">
546
- <ul className="bullet-list">
547
- {(Object.keys(this.state.currentValidationMessages).reduce((accumulator, current) => {
548
- const value = this.state.currentValidationMessages[current];
549
-
550
- if (value) {
551
- const errorMessage = <li key={`Error-${current}`}>{<a href={`#${current}`}>{value} </a>}</li>;
552
- accumulator.push(errorMessage);
553
- }
554
-
555
- return accumulator;
556
- }, [])
557
- )}
558
- </ul>
559
- </div>
560
- </div>
561
- );
562
480
  }
563
- return dialog;
481
+
482
+ return (
483
+ <div>
484
+ <WrappedMessage
485
+ message={messages.editImageModalFormErrorMissingFields}
486
+ tagName="div"
487
+ />
488
+ <div className="mt-3">
489
+ <ul className="bullet-list">
490
+ {validationMessages}
491
+ </ul>
492
+ </div>
493
+ </div>
494
+ );
564
495
  };
565
496
 
566
497
  getStatusAlert = () => (
@@ -573,37 +504,17 @@ export default class EditImageModal extends React.Component {
573
504
  />
574
505
  )
575
506
 
576
- getModalHeader = () => {
577
- let header;
578
- if (this.state.pageNumber === 2 || this.state.editingExisting) {
579
- header = (
580
- <WrappedMessage
581
- message={messages.editImageModalEditTitle}
582
- />
583
- );
584
- } else {
585
- header = (
586
- <WrappedMessage
587
- message={messages.editImageModalInsertTitle}
588
- />
589
- );
590
- }
591
- return (
592
- <div aria-live="polite">
593
- { header }
594
- </div>
595
- );
596
- }
507
+ getModalHeader = () => (
508
+ <div aria-live="polite">
509
+ <WrappedMessage
510
+ message={this.state.editingExisting
511
+ ? messages.editImageModalEditTitle
512
+ : messages.editImageModalInsertTitle}
513
+ />
514
+ </div>
515
+ );
597
516
 
598
- getModalBody = () => {
599
- let body;
600
- if (this.state.pageNumber === 1) {
601
- body = this.getImageSelectionModalBody();
602
- } else if (this.state.pageNumber === 2) {
603
- body = this.getImageSettingsModalBody();
604
- }
605
- return body;
606
- }
517
+ getModalBody = () => this.getImageSelectionModalBody();
607
518
 
608
519
  getImageSelectionModalBodyAssetsList = (type) => {
609
520
  switch (type) {
@@ -685,61 +596,7 @@ export default class EditImageModal extends React.Component {
685
596
  </React.Fragment>
686
597
  );
687
598
 
688
- getImageSettingsModalBody = () => (
689
- <React.Fragment>
690
- {this.getStatusAlert()}
691
- <div className="row">
692
- {this.state.shouldShowPreviousButton && this.getPreviousPageButton()}
693
- </div>
694
- <div className="row">
695
- <div className="col-sm-4">
696
- {this.getImagePreview()}
697
- </div>
698
- <div className="col">
699
- <form className={styles['image-fields']} ref={this.setImageFormRef}>
700
- {this.getImageDescriptionInput()}
701
- {this.getImageDimensionsInput()}
702
- </form>
703
- </div>
704
- </div>
705
- </React.Fragment>
706
- );
707
-
708
- getModalButtons = () => {
709
- let buttons;
710
- if (this.state.pageNumber === 1) {
711
- buttons = this.getInsertImageButton();
712
- } else if (this.state.pageNumber === 2) {
713
- buttons = this.getInsertImageButton();
714
- }
715
- return buttons;
716
- }
717
-
718
- getNextPageButton = () => (
719
- <Button
720
- label={
721
- <WrappedMessage
722
- message={messages.editImageModalNextPageButton}
723
- />
724
- }
725
- buttonType="primary"
726
- disabled={!this.isAssetSelected()}
727
- onClick={this.onNextPageButtonClick}
728
- />
729
- );
730
-
731
- getPreviousPageButton = () => (
732
- <Button
733
- label={
734
- <WrappedMessage
735
- message={messages.editImageModalPreviousPageButton}
736
- />
737
- }
738
- buttonType="link"
739
- onClick={this.onPreviousPageButtonClick}
740
- inputRef={this.setPreviousButtonRef}
741
- />
742
- );
599
+ getModalButtons = () => this.getInsertImageButton();
743
600
 
744
601
  getInsertImageButton = () => (
745
602
  <Button
@@ -797,15 +654,27 @@ export default class EditImageModal extends React.Component {
797
654
  // if existing img had a source, assume it could be loaded and show the image preview
798
655
  isImageLoaded: !!eventSource,
799
656
  isModalOpen: true,
800
- pageNumber: 1,
801
- shouldShowPreviousButton: false,
802
657
  }));
803
658
 
804
659
  this.props.getAssets({ assetTypes: { Images: true }, pageSize: 1000 }, this.props.courseDetails);
805
660
  }
806
661
 
807
662
  validateImageDescription = () => {
808
- return { isValid: true };
663
+ let feedback = { isValid: true };
664
+
665
+ // Decorative images are no longer an explicit choice, so a description is required.
666
+ if (!this.state.imageDescription) {
667
+ feedback = {
668
+ isValid: false,
669
+ validationMessage:
670
+ (<WrappedMessage
671
+ message={messages.editImageModalFormValidImageDescription}
672
+ />),
673
+ dangerIconDescription: <WrappedMessage message={messages.editImageModalFormError} />,
674
+ };
675
+ }
676
+
677
+ return feedback;
809
678
  }
810
679
 
811
680
  validateImageDimensions = () => {
@@ -844,22 +713,9 @@ export default class EditImageModal extends React.Component {
844
713
  return false;
845
714
  }
846
715
 
847
- wasNextButtonClicked = (prevState) => {
848
- if (this.state.pageNumber === 2 && prevState.pageNumber === 1
849
- && this.state.shouldShowPreviousButton) {
850
- this.previousPageButtonRef.focus();
851
- }
852
- }
853
-
854
- wasPreviousButtonClicked = (prevState) => {
855
- if (this.state.pageNumber === 1 && prevState.pageNumber === 2
856
- && prevState.isModalOpen) {
857
- this.dropZoneButtonRef.focus();
858
- }
859
- }
860
-
861
716
  render = () => (
862
717
  <div
718
+ className={styles['edit-image-modal']}
863
719
  ref={this.setModalWrapperRef}
864
720
  id={modalWrapperID}
865
721
  >
@@ -40,6 +40,8 @@
40
40
  "assetsDropZoneAriaLabel": "Upload assets",
41
41
  "assetsDropZoneBrowseLabel": "Select from your computer",
42
42
  "assetsDropZoneHeader": "Drag & Drop",
43
+ "assetsDropZoneClickToUpload": "Click to upload",
44
+ "assetsDropZoneOrDragAndDrop": "or drag and drop",
43
45
  "assetsDropZoneMaxFileSizeLabel": "Size limit: {maxFileSizeMB} MB",
44
46
  "assetsDropZoneSupportedFileTypesLabel": "Supported file types: {filesTypesList}",
45
47
  "assetsDropZoneImageSizeRecommandationLabel": "Size recommendation: {imageSize}",
@@ -142,11 +144,10 @@
142
144
  "editImageModalCancelButton": "Cancel",
143
145
  "editImageModalFormError": "Error",
144
146
  "editImageModalFormErrorMissingFields": "Make sure to fill in all fields.",
145
- "editImageModalFormValidImageDescription": "Add an image description or specify that the image is decorative only.",
147
+ "editImageModalFormValidImageDescription": "Add an image description.",
146
148
  "editImageModalFormValidImageDimensions": "Image dimensions must be positive numbers.",
147
149
  "editImageModalImageDescriptionDescription": "Alternative text for users who cannot view the image, such as \"The sky with clouds\".",
148
150
  "editImageModalImageDescriptionLabel": "Image Description",
149
- "editImageModalImageDecorativeDescription": "If this image is purely decorative, it does not require alternative text.",
150
151
  "editImageModalImageDescriptionLegend": "Image Description",
151
152
  "editImageModalDimensionsLegend": "Image Dimensions",
152
153
  "editImageModalImageHeight": "Height",