diff --git a/src/components/FileInput/FileInput.react.js b/src/components/FileInput/FileInput.react.js index 43cac1801e..1d59b78d23 100644 --- a/src/components/FileInput/FileInput.react.js +++ b/src/components/FileInput/FileInput.react.js @@ -49,7 +49,7 @@ export default class FileInput extends React.Component { } let label = this.renderLabel(); let buttonStyles = [styles.button]; - if (this.props.disabled) { + if (this.props.disabled || this.props.uploading) { buttonStyles.push(styles.disabled); } if (label) { @@ -58,10 +58,14 @@ export default class FileInput extends React.Component { return (
-
- {label ? - Change file : - Upload a file} +
+ {this.props.uploading ? ( +
+ ) : label ? ( + Change file + ) : ( + Upload a file + )}
{label} diff --git a/src/components/FileInput/FileInput.scss b/src/components/FileInput/FileInput.scss index 3a87747a9c..76984eb8e9 100644 --- a/src/components/FileInput/FileInput.scss +++ b/src/components/FileInput/FileInput.scss @@ -49,6 +49,17 @@ } } +.spinner { + display: inline-block; + width: 20px; + height: 20px; + border: .15em solid $blue; + vertical-align: bottom; + border-right-color: transparent; + border-radius: 50%; + @include animation('spinner-border .75s linear infinite'); +} + .disabled, .disabled:hover { background: #e0e0ea; border-color: #e0e0ea; @@ -75,4 +86,10 @@ a.label { color: $blue; +} + +@include keyframes(spinner-border) { + 100% { + @include transform(rotate(360deg)); + } } \ No newline at end of file diff --git a/src/dashboard/Data/Browser/AddColumnDialog.react.js b/src/dashboard/Data/Browser/AddColumnDialog.react.js index bf1cf6c33d..44ec8aff6b 100644 --- a/src/dashboard/Data/Browser/AddColumnDialog.react.js +++ b/src/dashboard/Data/Browser/AddColumnDialog.react.js @@ -39,7 +39,8 @@ export default class AddColumnDialog extends React.Component { name: '', required: false, defaultValue: undefined, - isDefaultValueValid: true + isDefaultValueValid: true, + uploadingFile: false }; this.renderDefaultValueInput = this.renderDefaultValueInput.bind(this) this.handleDefaultValueChange = this.handleDefaultValueChange.bind(this) @@ -77,8 +78,20 @@ export default class AddColumnDialog extends React.Component { if (file) { let base64 = await this.getBase64(file); const parseFile = new Parse.File(file.name, { base64 }); - await parseFile.save(); - return parseFile + this.setState({ + uploadingFile: true + }); + try { + await parseFile.save(); + return parseFile; + } catch (err) { + this.props.showNote(err.message, true); + return parseFile; + } finally { + this.setState({ + uploadingFile: false + }); + } } } @@ -167,7 +180,8 @@ export default class AddColumnDialog extends React.Component { onChange={async (defaultValue) => await this.handleDefaultValueChange(defaultValue)} /> case 'File': return await this.handleDefaultValueChange(defaultValue)} /> } } diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index 85043c01cd..7fafa2f704 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -1118,6 +1118,7 @@ class Browser extends DashboardView { classes={this.props.schema.data.get('classes').keySeq().toArray()} onCancel={() => this.setState({ showAddColumnDialog: false })} onConfirm={this.addColumn} + showNote={this.showNote} parseServerVersion={currentApp.serverInfo && currentApp.serverInfo.parseServerVersion} /> ); } else if (this.state.showRemoveColumnDialog) {