github.com/replicatedhq/ship@v0.55.0/web/init/src/components/config_render/FileInput.jsx (about)

     1  import React from "react";
     2  import map from "lodash/map";
     3  import after from "lodash/after";
     4  import forEach from "lodash/forEach";
     5  
     6  export default class FileInput extends React.Component {
     7  
     8    constructor(props) {
     9      super(props);
    10      this.state = {
    11        errText: "",
    12        fileAdded: false,
    13        fileName: "",
    14        fileNames: []
    15      }
    16    }
    17  
    18    handleOnChange = (ev) => {
    19      this.setState({ errText: "" });
    20  
    21      let files = [];
    22      let error;
    23  
    24      const done = after(ev.target.files.length, () => {
    25        // this.refs.file.getDOMNode().value = "";
    26        if (error) {
    27          this.setState({ errText: error });
    28        } else if (this.props.onChange) {
    29          this.setState({ fileAdded: true })
    30          this.props.onChange(
    31            map(files, "value"),
    32            map(files, "data")
    33          );
    34        }
    35      });
    36  
    37      forEach(ev.target.files, (file) => {
    38        var reader = new FileReader();
    39        reader.onload = () => {
    40          var vals = reader.result.split(",");
    41          if (vals.length !== 2) {
    42            error = "Invalid file data";
    43          } else {
    44            files.push({ value: file.name, data: vals[1] });
    45            if (this.props.multiple) {
    46              this.setState({ fileNames: files.map(file => file.value) })
    47            } else {
    48              this.setState({ fileName: files[0].value })
    49            }
    50          }
    51          done();
    52        };
    53        reader.readAsDataURL(file);
    54      });
    55    }
    56  
    57    render() {
    58      let label;
    59      this.props.label ? label = this.props.label : this.props.multiple
    60        ? label = "Upload files" : label = "Upload a file";
    61  
    62  
    63      return (
    64        <div>
    65          <div className={`${this.props.readonly ? "readonly" : ""} ${this.props.disabled ? "disabled" : ""}`}>
    66            <p className="sub-header-color field-section-sub-header u-marginTop--small u-marginBottom--small u-marginTop--15">{label}</p>
    67            <div className="flex flex-row">
    68              <div className={`${this.state.fileAdded || this.props.value ? "file-uploaded" : "custom-file-upload"}`}>
    69                <input
    70                  ref={(file) => this.file = file}
    71                  type="file"
    72                  name={this.props.name}
    73                  className="inputfile"
    74                  id={`${this.props.name} selector`}
    75                  onChange={this.handleOnChange}
    76                  readOnly={this.props.readOnly}
    77                  multiple={this.props.multiple}
    78                  disabled={this.props.disabled}
    79                />
    80                <label htmlFor={`${this.props.name} selector`} className="u-position--relative">
    81                  <span className={`icon clickable ${this.state.fileAdded || this.props.value ? "u-smallCheckGreen" : "u-ovalIcon"} u-marginRight--normal u-top--3`}></span>
    82                  {this.state.fileAdded || this.props.value ? this.props.multiple ? this.state.fileNames.join(",") : this.state.fileName : `Browse files for ${this.props.title}`}
    83                  {this.state.fileAdded || this.props.value ? 
    84                    <p className="u-color--astral u-textDecoration--underlineOnHover u-fontSize--small u-marginLeft--30 u-marginTop--5">Select a different file</p>
    85                  : null }
    86                </label>
    87              </div>
    88            </div>
    89          </div>
    90          <small className="text-danger"> {this.state.errText}</small>
    91        </div>
    92      );
    93    }
    94  }