From dbb43f18d5023b259ff848cf902f1e1ac97619da Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Mon, 25 Jan 2016 16:18:39 -0800 Subject: [PATCH 01/14] FileUploader --- .gitignore | 10 +++ .nvmrc | 1 + .travis.yml | 8 ++ LICENSE.md | 21 ++++++ README.md | 52 ++++++++++++- components/ExampleApp/ExampleApp.cjsx | 17 +++++ components/ExampleApp/ExampleApp.scss | 18 +++++ components/ExampleNav/ExampleNav.cjsx | 23 ++++++ components/ExampleNav/ExampleNav.scss | 15 ++++ components/FileUploader/FileUploader.cjsx | 24 ++++++ .../FileUploader/FileUploaderContainer.cjsx | 40 ++++++++++ .../FileUploaderContainerExamples.cjsx | 13 ++++ .../FileUploader/FileUploaderExamples.cjsx | 17 +++++ .../FileUploader/FileUploaderStyles.scss | 7 ++ components/Router/Router.cjsx | 45 ++++++++++++ components/UploadedFile/UploadedFile.cjsx | 53 ++++++++++++++ .../UploadedFile/UploadedFileContainer.cjsx | 24 ++++++ .../UploadedFile/UploadedFileExamples.cjsx | 43 +++++++++++ .../UploadedFile/UploadedFileStyles.scss | 73 +++++++++++++++++++ components/UploadedFile/example.txt | 1 + components/UploadedFile/icon-alert-red.svg | 26 +++++++ components/UploadedFile/icon-document.svg | 23 ++++++ components/UploadedFiles/UploadedFiles.cjsx | 30 ++++++++ .../UploadedFiles/UploadedFilesContainer.cjsx | 46 ++++++++++++ .../UploadedFiles/UploadedFilesExamples.cjsx | 17 +++++ .../UploadedFiles/UploadedFilesStyles.scss | 10 +++ example.coffee | 8 ++ example/example.coffee | 28 +++++++ example/index.html | 30 ++++++++ example/nav.jade | 12 +++ example/scripts/example-app.controller.js | 71 ++++++++++++++++++ example/scripts/example-app.module.js | 9 +++ example/scripts/file.example.coffee | 41 +++++++++++ example/scripts/routes.coffee | 28 +++++++ example/scripts/uploaded-files.example.coffee | 41 +++++++++++ example/scripts/uploader.example.coffee | 46 ++++++++++++ example/styles/main.scss | 23 ++++++ example/views/file.example.jade | 14 ++++ example/views/home.example.jade | 5 ++ example/views/uploaded-files.example.jade | 1 + index.coffee | 2 + index.html | 22 ++++++ package.json | 24 ++++++ webpack.config.coffee | 10 +++ 44 files changed, 1070 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 .travis.yml create mode 100644 LICENSE.md create mode 100644 components/ExampleApp/ExampleApp.cjsx create mode 100644 components/ExampleApp/ExampleApp.scss create mode 100644 components/ExampleNav/ExampleNav.cjsx create mode 100644 components/ExampleNav/ExampleNav.scss create mode 100644 components/FileUploader/FileUploader.cjsx create mode 100644 components/FileUploader/FileUploaderContainer.cjsx create mode 100644 components/FileUploader/FileUploaderContainerExamples.cjsx create mode 100644 components/FileUploader/FileUploaderExamples.cjsx create mode 100644 components/FileUploader/FileUploaderStyles.scss create mode 100644 components/Router/Router.cjsx create mode 100644 components/UploadedFile/UploadedFile.cjsx create mode 100644 components/UploadedFile/UploadedFileContainer.cjsx create mode 100644 components/UploadedFile/UploadedFileExamples.cjsx create mode 100644 components/UploadedFile/UploadedFileStyles.scss create mode 100644 components/UploadedFile/example.txt create mode 100644 components/UploadedFile/icon-alert-red.svg create mode 100644 components/UploadedFile/icon-document.svg create mode 100644 components/UploadedFiles/UploadedFiles.cjsx create mode 100644 components/UploadedFiles/UploadedFilesContainer.cjsx create mode 100644 components/UploadedFiles/UploadedFilesExamples.cjsx create mode 100644 components/UploadedFiles/UploadedFilesStyles.scss create mode 100644 example.coffee create mode 100644 example/example.coffee create mode 100644 example/index.html create mode 100644 example/nav.jade create mode 100644 example/scripts/example-app.controller.js create mode 100644 example/scripts/example-app.module.js create mode 100644 example/scripts/file.example.coffee create mode 100644 example/scripts/routes.coffee create mode 100644 example/scripts/uploaded-files.example.coffee create mode 100644 example/scripts/uploader.example.coffee create mode 100644 example/styles/main.scss create mode 100644 example/views/file.example.jade create mode 100644 example/views/home.example.jade create mode 100644 example/views/uploaded-files.example.jade create mode 100644 index.coffee create mode 100644 index.html create mode 100644 package.json create mode 100644 webpack.config.coffee diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f319765 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Build files +.tmp +bower_components +node_modules +coverage +.sass-cache +.idea +.env +npm-debug.log +.DS_Store \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..7cbea07 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +5.2.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..722c560 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: +- 5.2.0 +before_install: +- npm install +script: +- webpack +sudo: false diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..c2001b2 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Appirio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 28170cf..30db798 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,50 @@ -# file-uploader -File uploader component built in ReactJS +# Appirio File Uploader + + +## Using the repo in your app + +### Install + +- Install the bower component: + +``` +> bower install --save ap-file-uploader +``` + +- Include the ``main.js`` file in your app. +- Require the ``ap-file-upload`` module in the parent app. +- Place the ``ap-uploader`` directive where you want it to show up in your app. + +### Configure + +The ``ap-uploader`` directive takes two parameters passed as attributes to the directive. They are both passed as two-way ("=") bindings: + +status (required) - [string]: Gives the parent scope access to the status of the uploader. Useful for external validation (e.g. preventing form submission while uploads are in progress). + +config (required) - [object]: Contains all the config information need to run and integrate the directive: + +- name (required) - [string]: A name for this uploader. Used internally for retrieval from the service. **Must be unique for your app.** +- fileEndpoint (required) - [string]: This should be the endpoint to create/delete records after successful upload to S3. ``:name`` will be replaced with the actual filename at query time. +- urlPresigner (required) - [string]: This is the URL to create/delete records after successful upload to S3. ``:name`` will be replaced with the actual filename at query time. +- multiple - [true|**false**]: Should this instance of the uploader allow multiple files. If not, adding a file will prompt the user to replace. If the user confirms, the previous file will be deleted before the new one is uploaded. +- queryUrl - [string]: If present, the uploader will use this URL to retrieve file meta-data and prepopulate the uploader. +- saveParams - [object]: After uploading the file a call will be made to your fileEndpoint to create a record in your system. The saveParams is a hash of additional parameters you wish to include with this call. + +## Developing on the repo + +### Install + +``` +> nvm use +> npm install +``` + +### Using the example app + +``npm run dev`` will start a local Browsersync server. + +### Comitting changes + +The bower component served by this repo only includes the dist folder, which is committed. + + diff --git a/components/ExampleApp/ExampleApp.cjsx b/components/ExampleApp/ExampleApp.cjsx new file mode 100644 index 0000000..85e31fe --- /dev/null +++ b/components/ExampleApp/ExampleApp.cjsx @@ -0,0 +1,17 @@ +require './ExampleApp.scss' + +React = require 'react' +ExampleNav = require '../ExampleNav/ExampleNav.cjsx' + +component = + render: -> +
+
{this.props.children}
+ + +
+ + + +module.exports = React.createClass component + diff --git a/components/ExampleApp/ExampleApp.scss b/components/ExampleApp/ExampleApp.scss new file mode 100644 index 0000000..703006c --- /dev/null +++ b/components/ExampleApp/ExampleApp.scss @@ -0,0 +1,18 @@ +@import "work/work-styles"; + +body { + background-color: $grey-lighter; + padding: 15px; + + .invisible { + opacity: .3; + visibility: visible; + } + + h1 { + margin : 80px 0 40px 0; + text-align : center; + padding-bottom: 10px; + border-bottom : 1px solid $grey-light; + } +} diff --git a/components/ExampleNav/ExampleNav.cjsx b/components/ExampleNav/ExampleNav.cjsx new file mode 100644 index 0000000..ec1a88c --- /dev/null +++ b/components/ExampleNav/ExampleNav.cjsx @@ -0,0 +1,23 @@ +'use strict' + +require './ExampleNav.scss' + +React = require 'react' +classNames = require 'classnames' + +{ Link } = require 'react-router' + +component = ({data, state}) -> + + +module.exports = component \ No newline at end of file diff --git a/components/ExampleNav/ExampleNav.scss b/components/ExampleNav/ExampleNav.scss new file mode 100644 index 0000000..7f6e441 --- /dev/null +++ b/components/ExampleNav/ExampleNav.scss @@ -0,0 +1,15 @@ +.ExampleNav { + position: fixed; + bottom: 0; + background-color: #fff; + opacity: 0.6; + + li { + display: inline-block; + } + + a { + margin: 10px; + display: inline-block; + } +} \ No newline at end of file diff --git a/components/FileUploader/FileUploader.cjsx b/components/FileUploader/FileUploader.cjsx new file mode 100644 index 0000000..3238261 --- /dev/null +++ b/components/FileUploader/FileUploader.cjsx @@ -0,0 +1,24 @@ +'use strict' + +require './FileUploaderStyles' + +React = require 'react' +UploadedFilesContainer = require '../UploadedFiles/UploadedFilesContainer' +Dropzone = require 'react-dropzone' + +FileUploader = ({ multiple, onChange, requestingUploadUrl}) -> +
+ { + if requestingUploadUrl +

requestingUploadUrl...

+ } + + + + + +
+ +module.exports = FileUploader + + diff --git a/components/FileUploader/FileUploaderContainer.cjsx b/components/FileUploader/FileUploaderContainer.cjsx new file mode 100644 index 0000000..e950860 --- /dev/null +++ b/components/FileUploader/FileUploaderContainer.cjsx @@ -0,0 +1,40 @@ +'use strict' + +React = require 'react' +{ connect } = require 'react-redux' +{ uploadFile } = require 'appirio-tech-client-app-layer' +classnames = require 'classnames' +FileUploader = require './FileUploader' + +{ createClass, createElement, PropTypes } = React + +mapStateToProps = (state) -> + { id, assetType, category, requestingUploadUrl } = state?.fileUploader + + { id, assetType, category, requestingUploadUrl } + +container = + propTypes: + id : PropTypes.string.isRequired + assetType: PropTypes.string.isRequired + category : PropTypes.string.isRequired + dispatch : PropTypes.func.isRequired + + onChange: (files) -> + { dispatch, id, assetType, category } = this.props + + files.map (file) -> + dispatch uploadFile({ id, assetType, category, file }) + + componentWillMount: -> + { dispatch, id, assetType, category, requestingUploadUrl } = this.props + + render: -> + { onChange } = this + + { requestingUploadUrl } = this.props + + createElement FileUploader, { onChange, requestingUploadUrl } + +module.exports = connect(mapStateToProps)(createClass(container)) + diff --git a/components/FileUploader/FileUploaderContainerExamples.cjsx b/components/FileUploader/FileUploaderContainerExamples.cjsx new file mode 100644 index 0000000..cfc09e5 --- /dev/null +++ b/components/FileUploader/FileUploaderContainerExamples.cjsx @@ -0,0 +1,13 @@ +'use strict' + +FileUploaderContainer = require './FileUploaderContainer' +React = require 'react' + +FileUploaderContainerExamples = -> +
+

Default

+ + +
+ +module.exports = FileUploaderContainerExamples diff --git a/components/FileUploader/FileUploaderExamples.cjsx b/components/FileUploader/FileUploaderExamples.cjsx new file mode 100644 index 0000000..8f13193 --- /dev/null +++ b/components/FileUploader/FileUploaderExamples.cjsx @@ -0,0 +1,17 @@ +'use strict' + +FileUploader = require './FileUploader' +React = require 'react' + +FileUploaderExamples = -> +
+

Default

+ + + +

multiple is true

+ + +
+ +module.exports = FileUploaderExamples diff --git a/components/FileUploader/FileUploaderStyles.scss b/components/FileUploader/FileUploaderStyles.scss new file mode 100644 index 0000000..30358ad --- /dev/null +++ b/components/FileUploader/FileUploaderStyles.scss @@ -0,0 +1,7 @@ +@import "work/work-includes"; + +.FileUploader { + .UploadedFiles { + margin-bottom: 20px; + } +} \ No newline at end of file diff --git a/components/Router/Router.cjsx b/components/Router/Router.cjsx new file mode 100644 index 0000000..e774534 --- /dev/null +++ b/components/Router/Router.cjsx @@ -0,0 +1,45 @@ +'use strict' + +React = require 'react' +{ Provider } = require 'react-redux' +configureStore = require('appirio-tech-client-app-layer').default +ExampleApp = require '../ExampleApp/ExampleApp.cjsx' +Router = require '../Router/Router.cjsx' +UploadedFileExamples = require '../UploadedFile/UploadedFileExamples.cjsx' +UploadedFilesExamples = require '../UploadedFiles/UploadedFilesExamples.cjsx' +FileUploaderExamples = require '../FileUploader/FileUploaderExamples.cjsx' +FileUploaderContainerExamples = require '../FileUploader/FileUploaderContainerExamples.cjsx' + +{ Router, Route, Link, IndexRoute, browserHistory } = require 'react-router' + +store = configureStore + attachments: + 'mockDataInRouter.jpg': + assetType : 'specs' + category :'work' + fileName : 'mockDataInRouter.jpg' + filePath : 'some/unique/path' + fileType : 'image/jpeg' + id : 'workid' + fileUploader: + id : 'workid' # has to match schemas + assetType: 'specs' # has to match schemas + category : 'work' # has to match schemas + +component = -> + + + + + + + + + + + + + + + +module.exports = component \ No newline at end of file diff --git a/components/UploadedFile/UploadedFile.cjsx b/components/UploadedFile/UploadedFile.cjsx new file mode 100644 index 0000000..342f8e3 --- /dev/null +++ b/components/UploadedFile/UploadedFile.cjsx @@ -0,0 +1,53 @@ +'use strict' + +require './UploadedFileStyles' + +React = require 'react' +classnames = require 'classnames' + +UploadedFile = ({status, imageSrc, progress, fileName, onRemove, enableCaptions, captions}) -> +
+
+ { + if status == 'failed' +
+ + + +
+ else + if imageSrc +
+ else + + } + { + if status == 'uploading' +
+ + {progress}% + +
+ } +
+ +
+

{ fileName }

+ { + unless status == 'uploading' + + } +
+ + { + if enableCaptions +