fix #204, making sure focus/form is reset properly

This commit is contained in:
Cassie Tarakajian 2016-11-29 19:18:11 -05:00
parent 0a459246ac
commit 8cf313f6f9
8 changed files with 100 additions and 65 deletions

View file

@ -3,6 +3,7 @@ import axios from 'axios';
import objectID from 'bson-objectid'; import objectID from 'bson-objectid';
import blobUtil from 'blob-util'; import blobUtil from 'blob-util';
import { setUnsavedChanges } from './ide'; import { setUnsavedChanges } from './ide';
import { reset } from 'redux-form';
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api'; const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
@ -61,9 +62,10 @@ export function createFile(formProps) {
...response.data, ...response.data,
parentId parentId
}); });
dispatch({ dispatch(reset('new-file'));
type: ActionTypes.HIDE_MODAL // dispatch({
}); // type: ActionTypes.HIDE_MODAL
// });
dispatch(setUnsavedChanges(true)); dispatch(setUnsavedChanges(true));
}) })
.catch(response => dispatch({ .catch(response => dispatch({
@ -82,9 +84,10 @@ export function createFile(formProps) {
parentId, parentId,
children: [] children: []
}); });
dispatch({ dispatch(reset('new-file'));
type: ActionTypes.HIDE_MODAL // dispatch({
}); // type: ActionTypes.HIDE_MODAL
// });
dispatch(setUnsavedChanges(true)); dispatch(setUnsavedChanges(true));
} }
}; };

View file

@ -17,13 +17,12 @@ class FileUploader extends React.Component {
method: 'post', method: 'post',
autoProcessQueue: true, autoProcessQueue: true,
clickable: true, clickable: true,
maxFiles: 1, maxFiles: 6,
parallelUploads: 1, parallelUploads: 2,
maxFilesize: 5, // in mb maxFilesize: 5, // in mb
maxThumbnailFilesize: 8, // 3MB maxThumbnailFilesize: 8, // 8 mb
thumbnailWidth: 200, thumbnailWidth: 200,
thumbnailHeight: 200, thumbnailHeight: 200,
addRemoveLinks: true,
// TODO what is a good list of MIME types???? // TODO what is a good list of MIME types????
acceptedFiles: `image/*,audio/*,text/javascript,text/html,text/css, acceptedFiles: `image/*,audio/*,text/javascript,text/html,text/css,
application/json,application/x-font-ttf,application/x-font-truetype, application/json,application/x-font-ttf,application/x-font-truetype,

View file

@ -7,21 +7,22 @@ class NewFileForm extends React.Component {
this.createFile = this.props.createFile.bind(this); this.createFile = this.props.createFile.bind(this);
} }
componentDidMount() {
this.refs.fileName.focus();
}
render() { render() {
const { fields: { name }, handleSubmit } = this.props; const { fields: { name }, handleSubmit } = this.props;
return ( return (
<form className="new-file-form" onSubmit={handleSubmit(this.createFile)}> <form
className="new-file-form"
onSubmit={(data) => {
this.props.focusOnModal();
handleSubmit(this.createFile)(data);
}}
>
<label className="new-file-form__name-label" htmlFor="name">Name:</label> <label className="new-file-form__name-label" htmlFor="name">Name:</label>
<input <input
className="new-file-form__name-input" className="new-file-form__name-input"
id="name" id="name"
type="text" type="text"
placeholder="Name" placeholder="Name"
ref="fileName"
{...domOnlyProps(name)} {...domOnlyProps(name)}
/> />
<input type="submit" value="Add File" aria-label="add file" /> <input type="submit" value="Add File" aria-label="add file" />
@ -36,7 +37,8 @@ NewFileForm.propTypes = {
name: PropTypes.object.isRequired name: PropTypes.object.isRequired
}).isRequired, }).isRequired,
handleSubmit: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired,
createFile: PropTypes.func.isRequired createFile: PropTypes.func.isRequired,
focusOnModal: PropTypes.func.isRequired
}; };
export default NewFileForm; export default NewFileForm;

View file

@ -10,35 +10,53 @@ import FileUploader from './FileUploader';
// At some point this will probably be generalized to a generic modal // At some point this will probably be generalized to a generic modal
// in which you can insert different content // in which you can insert different content
// but for now, let's just make this work // but for now, let's just make this work
function NewFileModal(props) { class NewFileModal extends React.Component {
const modalClass = classNames({ constructor(props) {
modal: true, super(props);
'modal--reduced': !props.canUploadMedia this.focusOnModal = this.focusOnModal.bind(this);
}); }
return (
<section className={modalClass}> componentDidMount() {
<div className="modal-content"> this.focusOnModal();
<div className="modal__header"> }
<h2 className="modal__title">Add File</h2>
<button className="modal__exit-button" onClick={props.closeModal}> focusOnModal() {
<InlineSVG src={exitUrl} alt="Close New File Modal" /> this.refs.modal.focus();
</button> }
render() {
const modalClass = classNames({
modal: true,
'modal--reduced': !this.props.canUploadMedia
});
return (
<section className={modalClass} tabIndex="0" ref="modal">
<div className="modal-content">
<div className="modal__header">
<h2 className="modal__title">Add File</h2>
<button className="modal__exit-button" onClick={this.props.closeModal}>
<InlineSVG src={exitUrl} alt="Close New File Modal" />
</button>
</div>
<NewFileForm
focusOnModal={this.focusOnModal}
{...this.props}
/>
{(() => {
if (this.props.canUploadMedia) {
return (
<div>
<p className="modal__divider">OR</p>
<FileUploader />
</div>
);
}
return '';
})()}
</div> </div>
<NewFileForm {...props} /> </section>
{(() => { );
if (props.canUploadMedia) { }
return (
<div>
<p className="modal__divider">OR</p>
<FileUploader />
</div>
);
}
return '';
})()}
</div>
</section>
);
} }
NewFileModal.propTypes = { NewFileModal.propTypes = {

View file

@ -14,7 +14,13 @@ class NewFolderForm extends React.Component {
render() { render() {
const { fields: { name }, handleSubmit } = this.props; const { fields: { name }, handleSubmit } = this.props;
return ( return (
<form className="new-folder-form" onSubmit={handleSubmit(this.createFolder)}> <form
className="new-folder-form"
onSubmit={(data) => {
handleSubmit(this.createFolder)(data);
this.props.closeModal();
}}
>
<label className="new-folder-form__name-label" htmlFor="name">Name:</label> <label className="new-folder-form__name-label" htmlFor="name">Name:</label>
<input <input
className="new-folder-form__name-input" className="new-folder-form__name-input"
@ -35,7 +41,8 @@ NewFolderForm.propTypes = {
name: PropTypes.object.isRequired name: PropTypes.object.isRequired
}).isRequired, }).isRequired,
handleSubmit: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired,
createFolder: PropTypes.func.isRequired createFolder: PropTypes.func.isRequired,
closeModal: PropTypes.func.isRequired
}; };
export default NewFolderForm; export default NewFolderForm;

View file

@ -4,20 +4,26 @@ import InlineSVG from 'react-inlinesvg';
const exitUrl = require('../../../images/exit.svg'); const exitUrl = require('../../../images/exit.svg');
import NewFolderForm from './NewFolderForm'; import NewFolderForm from './NewFolderForm';
function NewFolderModal(props) { class NewFolderModal extends React.Component {
return ( componentDidMount() {
<section className="modal"> this.refs.modal.focus();
<div className="modal-content-folder"> }
<div className="modal__header">
<h2 className="modal__title">Add Folder</h2> render() {
<button className="modal__exit-button" onClick={props.closeModal}> return (
<InlineSVG src={exitUrl} alt="Close New Folder Modal" /> <section className="modal" ref="modal" tabIndex="0">
</button> <div className="modal-content-folder">
<div className="modal__header">
<h2 className="modal__title">Add Folder</h2>
<button className="modal__exit-button" onClick={this.props.closeModal}>
<InlineSVG src={exitUrl} alt="Close New Folder Modal" />
</button>
</div>
<NewFolderForm {...this.props} />
</div> </div>
<NewFolderForm {...props} /> </section>
</div> );
</section> }
);
} }
NewFolderModal.propTypes = { NewFolderModal.propTypes = {

View file

@ -1,17 +1,17 @@
.modal { .modal {
position: absolute; position: absolute;
top: #{66 / $base-font-size}rem; top: #{60 / $base-font-size}rem;
right: #{400 / $base-font-size}rem; right: #{400 / $base-font-size}rem;
z-index: 100; z-index: 100;
} }
.modal-content { .modal-content {
@extend %modal; @extend %modal;
height: #{400 / $base-font-size}rem; min-height: #{150 / $base-font-size}rem;
width: #{400 / $base-font-size}rem; width: #{400 / $base-font-size}rem;
padding: #{20 / $base-font-size}rem; padding: #{20 / $base-font-size}rem;
.modal--reduced & { .modal--reduced & {
height: #{150 / $base-font-size}rem; //min-height: #{150 / $base-font-size}rem;
} }
} }
@ -51,7 +51,7 @@
} }
.uploader { .uploader {
height: #{200 / $base-font-size}rem; min-height: #{200 / $base-font-size}rem;
width: 100%; width: 100%;
text-align: center; text-align: center;
} }

View file

@ -1,7 +1,7 @@
.preferences { .preferences {
@extend %modal; @extend %modal;
position: absolute; position: absolute;
top: #{66 / $base-font-size}rem; top: #{60 / $base-font-size}rem;
right: #{40 / $base-font-size}rem; right: #{40 / $base-font-size}rem;
width: #{336 / $base-font-size}rem; width: #{336 / $base-font-size}rem;
display: none; display: none;