import React from 'react' ; import styled from 'styled-components' ; import { colors } from 'teleport/Console/colors' ; import * as Elements from './../Elements' ; type PropType = { onUpload : ( location : string , filename : string , blob : Blob ) => void ; } ; export default class UploadForm extends React . Component < PropType > { refDropzone = React . createRef < HTMLElement > ( ) ; refInput = React . createRef < HTMLElement > ( ) ; refFileSelector = React . createRef < HTMLInputElement > ( ) ; state = { files : [ ] , remoteLocation : '~/' , } ; componentWillUnmount ( ) { document . removeEventListener ( 'drop' , this . onDocumentDrop ) ; document . removeEventListener ( 'dragover' , this . preventDefault ) ; } componentDidMount ( ) { document . addEventListener ( 'dragover' , this . preventDefault , false ) ; document . addEventListener ( 'drop' , this . onDocumentDrop , false ) ; } preventDefault ( e ) { e . preventDefault ( ) ; } onDocumentDrop ( e ) { if ( this . refDropzone . current && this . refDropzone . current . contains ( e . target ) ) { return ; } e . preventDefault ( ) ; e . dataTransfer . effectAllowed = 'none' ; e . dataTransfer . dropEffect = 'none' ; } onFileSelected = e => { this . addFiles ( [ ] , e . target . files ) ; this . refInput . current . focus ( ) ; } ; onFilePathChanged = e => { this . setState ( { remoteLocation : e . target . value , } ) ; } ; onUpload = ( ) => { const { files , remoteLocation } = this . state ; for ( var i = 0 ; i < files . length ; i ++ ) { this . props . onUpload ( remoteLocation , files [ i ] . name , files [ i ] ) ; } this . setState ( { files : [ ] } ) ; this . setFocus ( ) ; } ; onOpenFilePicker = ( ) => { this . refFileSelector . current . value = '' ; this . refFileSelector . current . click ( ) ; } ; onDrop = e => { e . preventDefault ( ) ; e . stopPropagation ( ) ; this . addFiles ( this . state . files , e . dataTransfer . files ) ; this . setFocus ( ) ; } ; onKeyDown = event => { if ( event . key === 'Enter' ) { event . preventDefault ( ) ; event . stopPropagation ( ) ; this . onOpenFilePicker ( ) ; } } ; setFocus ( ) { this . refInput . current . focus ( ) ; } moveCaretAtEnd ( e ) { const tmp = e . target . value ; e . target . value = '' ; e . target . value = tmp ; } addFiles ( files , blobs = [ ] ) { for ( var i = 0 ; i < blobs . length ; i ++ ) { files . push ( blobs [ i ] ) ; } this . setState ( { files , } ) ; } render ( ) { const { remoteLocation , files } = this . state ; const isDldBtnDisabled = ! remoteLocation || files . length === 0 ; const hasFiles = files . length > 0 ; const dropZoneText = hasFiles ? `${ files . length } files selected` : `Select files to upload or drag & drop them here` ; return ( < Elements . Form color = "terminal" > < Elements . Header > ( SCP ) UPLOAD Files < /Elements.Header> < Elements . Label > Upload destination < /Elements.Label> < Elements . Input className = "grv-file-transfer-input m-r-sm" width = "100%" mb = { 0 } ref = { this . refInput } value = { remoteLocation } autoFocus onFocus = { this . moveCaretAtEnd } onChange = { this . onFilePathChanged } onKeyDown = { this . onKeyDown } / > < input ref = { this . refFileSelector } type = "file" multiple style = { { display : 'none' } } accept = "*.*" name = "file" onChange = { this . onFileSelected } / > < Dropzone ref = { this . refDropzone } onDragOver = { e => e . preventDefault ( ) } onDrop = { this . onDrop } onClick = { this . onOpenFilePicker } > { dropZoneText } < /Dropzone> < Elements . Button disabled = { isDldBtnDisabled } onClick = { this . onUpload } > Upload < /Elements.Button> < /Elements.Form>); } } const Dropzone = styled . div `
  background: ${ colors . bgTerminal };
  border: 1px dashed ${ colors . text };
  color: ${ colors . terminal };
  display: block;
  margin: 16px 0;
  height: 72px;
  line-height: 72px;
  text-align: center;
  text-transform: uppercase;
  cursor: pointer;
` ;