QuickLaunchTarget.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { SVGIcon } from 'ca-ui-toolkit';
  4. import './QuickLaunchTarget.scss';
  5. import filter from 'lodash/filter';
  6. export class QuickLaunchTarget extends Component {
  7. static propTypes = {
  8. /** Custom class name(s) */
  9. className: PropTypes.string,
  10. /** A function used to set the text in the Quick Launch content bar */
  11. setUploadText: PropTypes.func,
  12. /** A reference to the ES5 homeView object */
  13. homeView: PropTypes.object,
  14. /** An object containing the strings and icons for the quick launch target */
  15. content: PropTypes.object,
  16. /** Hides the quick launch when called */
  17. hideQuickLaunch: PropTypes.func,
  18. /** a reference to the glass context from homeView */
  19. glassContext: PropTypes.object
  20. };
  21. goals = {
  22. 'uploadedFile': 'upload',
  23. 'module': 'createModule'
  24. }
  25. constructor (props) {
  26. super(props);
  27. this.state = {
  28. hover: false,
  29. dragCounter: 0 /* Drag counter to check if over target or it's children */
  30. };
  31. }
  32. _onDragEnter (e) {
  33. e.preventDefault();
  34. const counter = this.state.dragCounter + 1;
  35. this.setState({ hover: true, dragCounter: counter });
  36. this.props.setUploadText && this.props.setUploadText(`: ${this.props.content.label}`);
  37. }
  38. _onDragLeave (e) {
  39. e.preventDefault();
  40. const counter = this.state.dragCounter - 1;
  41. let hover = true;
  42. if (counter === 0) {
  43. hover = false;
  44. this.props.setUploadText && this.props.setUploadText();
  45. }
  46. this.setState({ hover, dragCounter: counter });
  47. }
  48. /**
  49. * Filters supported file objects from list, leaving only unsupported ones
  50. * @param droppedFiles {array} array of dropped file objects
  51. * @param supportedTypes {array} array of supported file extensions
  52. * @returns {array} filtered list of file objects
  53. */
  54. _getUnsupportedFiles (droppedFiles) {
  55. const { content } = this.props;
  56. return filter(droppedFiles, file => content.fileTypes.indexOf(this._getFileExtension(file.name)) === -1);
  57. }
  58. /**
  59. * Extracts extension portion of a filename
  60. * @param filename {string} name of file
  61. * @returns {string} extension of file or blank string if no extension was found
  62. */
  63. _getFileExtension (filename) {
  64. const lastPeriod = filename && filename.lastIndexOf('.');
  65. return (!lastPeriod || lastPeriod < 1) ? '' : filename.substring(filename.lastIndexOf('.')+1, filename.length).toLowerCase();
  66. }
  67. /**
  68. * Drop event-handler
  69. * @param event {object} mouse event object
  70. */
  71. onDrop (event) {
  72. event.stopPropagation();
  73. event.preventDefault();
  74. const { content, hideQuickLaunch, homeView, glassContext } = this.props;
  75. let data;
  76. hideQuickLaunch();
  77. // Check to see if drop has files for dataTransfer
  78. if ((data = event.dataTransfer) && data.files) {
  79. let unsupportedFiles = this._getUnsupportedFiles(data.files);
  80. if (unsupportedFiles.length === 0) {
  81. if (homeView.allowUploadFiles && homeView.canUploadFiles() && homeView._hasFiles(data)) {
  82. return homeView.uploadThenLaunch(content, this.goals[content.requiredType], data);
  83. }
  84. return Promise.resolve();
  85. } else {
  86. const fileNames = unsupportedFiles.map(file => file.name);
  87. const numDroppedFiles = data.files.length;
  88. let unsupportedFilesMsg;
  89. if (numDroppedFiles === 1) {
  90. unsupportedFilesMsg = homeView.stringGetter.get('unsupportedFilesSingle', {
  91. files: fileNames[0]
  92. });
  93. } else {
  94. const msgKey = (fileNames.length === 1) ? 'unsupportedFilesSingleInvalid' : 'unsupportedFilesMultipleInvalid';
  95. unsupportedFilesMsg = homeView.stringGetter.get('unsupportedFilesMultiple') + ' ' + homeView.stringGetter.get(msgKey, {
  96. files: fileNames.join(', ')
  97. });
  98. }
  99. const supportedFileTypesMsg = homeView.stringGetter.get('supportedFileTypes', {
  100. extensions: content.fileTypes.join(', ')
  101. });
  102. glassContext.appController.showToast(unsupportedFilesMsg + ' ' + supportedFileTypesMsg, { 'type':'error' });
  103. }
  104. }
  105. }
  106. render() {
  107. const { content } = this.props;
  108. const className = this.state.hover ? 'quickLaunchTarget hover' : 'quickLaunchTarget';
  109. return (
  110. <div>
  111. <div className={ className } onDragEnter={ this._onDragEnter.bind(this) } onDragLeave={ this._onDragLeave.bind(this) } onDrop={ this.onDrop.bind(this) }>
  112. <SVGIcon className="quickLaunchTargetIcon" iconId={ content.icon }></SVGIcon>
  113. <div className="quickLaunchTargetName">{ content.label }</div>
  114. </div>
  115. </div>
  116. );
  117. }
  118. }