1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-23 01:39:36 +01:00

Merge remote-tracking branch 'remotes/origin/master' into AD-504-revive-coa-for-new-frontend

This commit is contained in:
diminator 2015-06-26 00:04:25 +02:00
commit 930982873a
8 changed files with 109 additions and 18 deletions

View File

@ -53,10 +53,12 @@ var config = {
] ]
}; };
var SERVER_URL = process.env.ONION_SERVER_URL || 'http://staging.ascribe.io/';
var constants = { var constants = {
BASE_URL: (function () { var baseUrl = process.env.ONION_BASE_URL || '/'; return baseUrl + (baseUrl.match(/\/$/) ? '' : '/'); })(), BASE_URL: (function () { var baseUrl = process.env.ONION_BASE_URL || '/'; return baseUrl + (baseUrl.match(/\/$/) ? '' : '/'); })(),
SERVER_URL: process.env.ONION_SERVER_URL || 'http://staging.ascribe.io/', SERVER_URL: SERVER_URL,
API_ENDPOINT: process.env.ONION_SERVER_URL + 'api/' || 'http://staging.ascribe.io/api/', API_ENDPOINT: SERVER_URL + 'api/' || 'http://staging.ascribe.io/api/',
DEBUG: !argv.production, DEBUG: !argv.production,
CREDENTIALS: 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw' // dimi@mailinator:0000000000 CREDENTIALS: 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw' // dimi@mailinator:0000000000
}; };

View File

@ -11,8 +11,8 @@
<link rel="stylesheet" href="<%= BASE_URL %>static/css/maps/main.css.map"> <link rel="stylesheet" href="<%= BASE_URL %>static/css/maps/main.css.map">
<script> <script>
window.BASE_URL = '<%= BASE_URL %>'; window.BASE_URL = '<%= BASE_URL %>';
window.API_ENDPOINT = '<%= API_ENDPOINT %>';
window.SERVER_URL = '<%= SERVER_URL %>'; window.SERVER_URL = '<%= SERVER_URL %>';
window.API_ENDPOINT = '<%= API_ENDPOINT %>';
<% DEBUG && print('window.DEBUG = true'); %> <% DEBUG && print('window.DEBUG = true'); %>
<% DEBUG && print('window.CREDENTIALS = \'' + CREDENTIALS + '\''); %> <% DEBUG && print('window.CREDENTIALS = \'' + CREDENTIALS + '\''); %>
</script> </script>

View File

@ -1,3 +1,5 @@
'use strict';
import React from 'react'; import React from 'react';
import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator'; import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator';
@ -7,12 +9,16 @@ var FileDragAndDrop = React.createClass({
propTypes: { propTypes: {
onDragStart: React.PropTypes.func, onDragStart: React.PropTypes.func,
onDrop: React.PropTypes.func.isRequired, onDrop: React.PropTypes.func.isRequired,
onDrag: React.PropTypes.func,
onDragEnter: React.PropTypes.func, onDragEnter: React.PropTypes.func,
onLeave: React.PropTypes.func, onLeave: React.PropTypes.func,
onDragLeave: React.PropTypes.func,
onDragOver: React.PropTypes.func, onDragOver: React.PropTypes.func,
onDragEnd: React.PropTypes.func, onDragEnd: React.PropTypes.func,
filesToUpload: React.PropTypes.array, filesToUpload: React.PropTypes.array,
handleDeleteFile: React.PropTypes.func handleDeleteFile: React.PropTypes.func,
multiple: React.PropTypes.bool,
dropzoneInactive: React.PropTypes.bool
}, },
handleDragStart(event) { handleDragStart(event) {
@ -80,6 +86,12 @@ var FileDragAndDrop = React.createClass({
}, },
handleOnClick() { handleOnClick() {
// when multiple is set to false and the user already uploaded a piece,
// do not propagate event
if(this.props.dropzoneInactive) {
return;
}
// Simulate click on hidden file input // Simulate click on hidden file input
var event = document.createEvent('HTMLEvents'); var event = document.createEvent('HTMLEvents');
event.initEvent('click', false, true); event.initEvent('click', false, true);
@ -87,11 +99,14 @@ var FileDragAndDrop = React.createClass({
}, },
render: function () { render: function () {
console.log(this.props.dropzoneInactive);
let hasFiles = this.props.filesToUpload.length > 0; let hasFiles = this.props.filesToUpload.length > 0;
let className = hasFiles ? 'file-drag-and-drop has-files ' : 'file-drag-and-drop ';
className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone';
return ( return (
<div <div
className={hasFiles ? 'file-drag-and-drop has-files' : 'file-drag-and-drop' } className={className}
onClick={this.handleOnClick} onClick={this.handleOnClick}
onDragStart={this.handleDragStart} onDragStart={this.handleDragStart}
onDrag={this.handleDrop} onDrag={this.handleDrop}
@ -100,12 +115,12 @@ var FileDragAndDrop = React.createClass({
onDragOver={this.handleDragOver} onDragOver={this.handleDragOver}
onDrop={this.handleDrop} onDrop={this.handleDrop}
onDragEnd={this.handleDragEnd}> onDragEnd={this.handleDragEnd}>
{hasFiles ? null : <span>Click or drag to add files</span>} {hasFiles ? null : this.props.multiple ? <span>Click or drag to add files</span> : <span>Click or drag to add a file</span>}
<FileDragAndDropPreviewIterator <FileDragAndDropPreviewIterator
files={this.props.filesToUpload} files={this.props.filesToUpload}
handleDeleteFile={this.handleDeleteFile}/> handleDeleteFile={this.handleDeleteFile}/>
<input <input
multiple multiple={this.props.multiple}
ref="fileinput" ref="fileinput"
type="file" type="file"
style={{ style={{
@ -119,4 +134,4 @@ var FileDragAndDrop = React.createClass({
} }
}); });
module.exports = FileDragAndDrop; export default FileDragAndDrop;

View File

@ -10,6 +10,9 @@ import fetch from 'isomorphic-fetch';
import fineUploader from 'fineUploader'; import fineUploader from 'fineUploader';
import FileDragAndDrop from './file_drag_and_drop'; import FileDragAndDrop from './file_drag_and_drop';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
var ReactS3FineUploader = React.createClass({ var ReactS3FineUploader = React.createClass({
propTypes: { propTypes: {
@ -118,7 +121,6 @@ var ReactS3FineUploader = React.createClass({
}, },
getCookie(name) { getCookie(name) {
//console.log(document);
let value = '; ' + document.cookie; let value = '; ' + document.cookie;
let parts = value.split('; ' + name + '='); let parts = value.split('; ' + name + '=');
if (parts.length === 2) { if (parts.length === 2) {
@ -126,7 +128,6 @@ var ReactS3FineUploader = React.createClass({
} }
}, },
requestKey(fileId) { requestKey(fileId) {
//console.log(this.getCookie('csrftoken'));
let filename = this.state.uploader.getName(fileId); let filename = this.state.uploader.getName(fileId);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch(this.props.keyRoutine.url, { fetch(this.props.keyRoutine.url, {
@ -261,6 +262,26 @@ var ReactS3FineUploader = React.createClass({
}, },
handleUploadFile(files) { handleUploadFile(files) {
// If multiple set and user already uploaded its work,
// cancel upload
if(!this.props.multiple && this.state.filesToUpload.length > 0) {
return;
}
// if multiple is set to false and user drops multiple files into the dropzone,
// take the first one and notify user that only one file can be submitted
if(!this.props.multiple && files.length > 1) {
let tempFilesList = [];
tempFilesList.push(files[0]);
// replace filelist with first-element file list
files = tempFilesList;
let notification = new GlobalNotificationModel('Only one file allowed (took first one)', 'danger', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
}
this.state.uploader.addFiles(files); this.state.uploader.addFiles(files);
let oldFiles = this.state.filesToUpload; let oldFiles = this.state.filesToUpload;
let oldAndNewFiles = this.state.uploader.getUploads(); let oldAndNewFiles = this.state.uploader.getUploads();
@ -298,7 +319,9 @@ var ReactS3FineUploader = React.createClass({
<FileDragAndDrop <FileDragAndDrop
onDrop={this.handleUploadFile} onDrop={this.handleUploadFile}
filesToUpload={this.state.filesToUpload} filesToUpload={this.state.filesToUpload}
handleDeleteFile={this.handleDeleteFile}/> handleDeleteFile={this.handleDeleteFile}
multiple={this.props.multiple}
dropzoneInactive={!this.props.multiple && this.state.filesToUpload.length > 0} />
); );
} }

View File

@ -6,6 +6,8 @@ import Router from 'react-router';
import GlobalNotificationModel from '../models/global_notification_model'; import GlobalNotificationModel from '../models/global_notification_model';
import GlobalNotificationActions from '../actions/global_notification_actions'; import GlobalNotificationActions from '../actions/global_notification_actions';
import UserStore from '../stores/user_store';
import Form from './ascribe_forms/form'; import Form from './ascribe_forms/form';
import Property from './ascribe_forms/property'; import Property from './ascribe_forms/property';
@ -16,6 +18,27 @@ import AppConstants from '../constants/application_constants';
let LoginContainer = React.createClass({ let LoginContainer = React.createClass({
mixins: [Router.Navigation], mixins: [Router.Navigation],
getInitialState() {
return UserStore.getState();
},
componentDidMount() {
UserStore.listen(this.onChange);
},
componentWillUnmount() {
UserStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
// if user is already logged in, redirect him to piece list
if(this.state.currentUser && this.state.currentUser.email) {
this.transitionTo('pieces');
}
},
render() { render() {
return ( return (
<div className="ascribe-login-wrapper"> <div className="ascribe-login-wrapper">
@ -32,9 +55,6 @@ let LoginContainer = React.createClass({
let LoginForm = React.createClass({ let LoginForm = React.createClass({
mixins: [Router.Navigation],
handleSuccess(){ handleSuccess(){
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000); let notification = new GlobalNotificationModel('Login successsful', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);

View File

@ -187,7 +187,8 @@ let FileUploader = React.createClass( {
let InputDate = React.createClass({ let InputDate = React.createClass({
propTypes: { propTypes: {
placeholderText: React.PropTypes.string placeholderText: React.PropTypes.string,
onChange: React.PropTypes.func
}, },
getInitialState() { getInitialState() {

View File

@ -3,6 +3,9 @@
import React from 'react'; import React from 'react';
import Router from 'react-router'; import Router from 'react-router';
import { mergeOptions } from '../utils/general_utils';
import UserStore from '../stores/user_store';
import GlobalNotificationModel from '../models/global_notification_model'; import GlobalNotificationModel from '../models/global_notification_model';
import GlobalNotificationActions from '../actions/global_notification_actions'; import GlobalNotificationActions from '../actions/global_notification_actions';
@ -17,18 +20,37 @@ import apiUrls from '../constants/api_urls';
let SignupContainer = React.createClass({ let SignupContainer = React.createClass({
mixins: [Router.Navigation], mixins: [Router.Navigation],
getInitialState(){ getInitialState() {
return ({ return mergeOptions({
submitted: false, submitted: false,
message: null message: null
}); }, UserStore.getState());
}, },
componentDidMount() {
UserStore.listen(this.onChange);
},
componentWillUnmount() {
UserStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
// if user is already logged in, redirect him to piece list
if(this.state.currentUser && this.state.currentUser.email) {
this.transitionTo('pieces');
}
},
handleSuccess(message){ handleSuccess(message){
this.setState({ this.setState({
submitted: true, submitted: true,
message: message message: message
}); });
}, },
render() { render() {
if (this.state.submitted){ if (this.state.submitted){
return ( return (

View File

@ -10,6 +10,14 @@
transition: .1s linear background-color; transition: .1s linear background-color;
} }
.inactive-dropzone {
cursor: default !important;
}
.inactive-dropzone:hover {
background-color: #FAFAFA !important;
}
.file-drag-and-drop:hover { .file-drag-and-drop:hover {
background-color: rgba(72, 218, 203, 0.2); background-color: rgba(72, 218, 203, 0.2);
} }