From 6563bf97b0e552e5f6e6a47e4a019a0edb9cd340 Mon Sep 17 00:00:00 2001 From: ddejongh Date: Tue, 9 Jun 2015 13:29:22 +0200 Subject: [PATCH] toggable textarea --- gulpfile.js | 2 +- .../ascribe_buttons/button_submit_close.js | 2 +- .../ascribe_forms/form_note_personal.js | 43 +++++++++++ .../ascribe_forms/input_textarea_toggable.js | 72 +++++++++++++++++++ js/components/edition.js | 33 ++++----- js/components/edition_container.js | 10 +-- js/constants/api_urls.js | 3 +- js/constants/application_constants.js | 4 +- js/mixins/form_mixin.js | 16 ++++- sass/ascribe_textarea.scss | 21 ++++++ sass/main.scss | 1 + 11 files changed, 179 insertions(+), 28 deletions(-) create mode 100644 js/components/ascribe_forms/form_note_personal.js create mode 100644 js/components/ascribe_forms/input_textarea_toggable.js create mode 100644 sass/ascribe_textarea.scss diff --git a/gulpfile.js b/gulpfile.js index bf9dd46d..424796da 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -45,7 +45,7 @@ gulp.task('build', function() { bundle(false); }); -gulp.task('serve', ['browser-sync', 'lint:watch', 'sass', 'sass:watch', 'copy'], function() { +gulp.task('serve', ['browser-sync', 'sass', 'sass:watch', 'copy'], function() { bundle(true); }); diff --git a/js/components/ascribe_buttons/button_submit_close.js b/js/components/ascribe_buttons/button_submit_close.js index d1939e35..2d70fb03 100644 --- a/js/components/ascribe_buttons/button_submit_close.js +++ b/js/components/ascribe_buttons/button_submit_close.js @@ -14,7 +14,7 @@ let ButtonSubmitOrClose = React.createClass({
- ) + ); } return (
diff --git a/js/components/ascribe_forms/form_note_personal.js b/js/components/ascribe_forms/form_note_personal.js new file mode 100644 index 00000000..282afcdf --- /dev/null +++ b/js/components/ascribe_forms/form_note_personal.js @@ -0,0 +1,43 @@ +'use strict'; + +import React from 'react'; + +import apiUrls from '../../constants/api_urls'; +import FormMixin from '../../mixins/form_mixin'; + +import InputTextAreaToggable from './input_textarea_toggable'; + + +let PersonalNoteForm = React.createClass({ + mixins: [FormMixin], + + url() { + return apiUrls.note_notes; + }, + + getFormData() { + return { + bitcoin_id: this.getBitcoinIds().join(), + note: this.refs.personalNote.state.value + }; + }, + + renderForm() { + + return ( +
+ + + ); + } +}); + +export default PersonalNoteForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/input_textarea_toggable.js b/js/components/ascribe_forms/input_textarea_toggable.js new file mode 100644 index 00000000..e7faea9c --- /dev/null +++ b/js/components/ascribe_forms/input_textarea_toggable.js @@ -0,0 +1,72 @@ +'use strict'; + +import React from 'react'; + +import AlertMixin from '../../mixins/alert_mixin'; +import TextareaAutosize from 'react-textarea-autosize'; +import Button from 'react-bootstrap/lib/Button'; + +let InputTextAreaToggable = React.createClass({ + + mixins: [AlertMixin], + + getInitialState() { + return { + value: this.props.defaultValue, + edited: false, + alerts: null // needed in AlertMixin + }; + }, + handleChange(event) { + this.setState({ + value: event.target.value, + edited: true + }); + }, + reset(){ + this.setState(this.getInitialState()); + }, + submit(){ + this.props.onSubmit(); + this.setState({edited: false}); + }, + render() { + let className = 'form-control ascribe-textarea'; + let buttons = null; + let textarea = null; + if (this.props.editable && this.state.edited){ + buttons = ( +
+ + +
+ ); + + } + if (this.props.editable){ + className = className + ' ascribe-textarea-editable'; + textarea = ( + + ); + } + else{ + textarea =
{this.state.value}
; + } + let alerts = (this.props.submitted) ? null : this.state.alerts; + return ( +
+ {alerts} + {textarea} + {buttons} +
+ ); + } +}); + +export default InputTextAreaToggable; \ No newline at end of file diff --git a/js/components/edition.js b/js/components/edition.js index 20e54990..deb53620 100644 --- a/js/components/edition.js +++ b/js/components/edition.js @@ -8,7 +8,8 @@ import Row from 'react-bootstrap/lib/Row'; import Col from 'react-bootstrap/lib/Col'; import Button from 'react-bootstrap/lib/Button'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; -import TextareaAutosize from 'react-textarea-autosize'; + +import PersonalNoteForm from './ascribe_forms/form_note_personal'; import EditionActions from '../actions/edition_actions'; import AclButtonList from './ascribe_buttons/acl_button_list'; @@ -23,7 +24,7 @@ let Edition = React.createClass({ edition: React.PropTypes.object, currentUser: React.PropTypes.object, deleteEdition: React.PropTypes.func, - savePersonalNote: React.PropTypes.func + loadEdition: React.PropTypes.func }, render() { @@ -39,10 +40,14 @@ let Edition = React.createClass({ {this.props.edition.bitcoin_id} ); - let hashOfArtwork = ( + let hashOfArtwork = ( {this.props.edition.hash_as_address} ); + let ownerAddress = ( + {this.props.edition.btc_owner_address_noprefix} + ); + return ( @@ -64,8 +69,9 @@ let Edition = React.createClass({ - + + value={ownerAddress} />
-
{ this.props.label }{this.props.separator}
+
{ this.props.label + this.props.separator}
{ this.props.value }
@@ -304,7 +310,7 @@ let EditionDetailHistoryIterator = React.createClass({ let EditionPersonalNote = React.createClass({ propTypes: { - savePersonalNote: React.PropTypes.func + edition: React.PropTypes.object }, prepareSavePersonalNote() { @@ -316,14 +322,9 @@ let EditionPersonalNote = React.createClass({ return ( - - + ); diff --git a/js/components/edition_container.js b/js/components/edition_container.js index 1f2461bd..b2d3bca0 100644 --- a/js/components/edition_container.js +++ b/js/components/edition_container.js @@ -4,6 +4,9 @@ import React from 'react'; import { mergeOptions } from '../utils/general_utils'; +import apiUrls from '../constants/api_urls'; +import fetch from '../utils/fetch'; + import EditionActions from '../actions/edition_actions'; import EditionStore from '../stores/edition_store'; import UserActions from '../actions/user_actions'; @@ -40,9 +43,8 @@ let EditionContainer = React.createClass({ // Delete Edition from server }, - savePersonalNote(note) { - console.log(note); - // Save personalNote to server + loadEdition() { + EditionActions.fetchOne(this.props.params.editionId); }, render() { @@ -52,7 +54,7 @@ let EditionContainer = React.createClass({ edition={this.state.edition} currentUser={this.state.currentUser} deleteEdition={this.deleteEdition} - savePersonalNote={this.savePersonalNote}/> + loadEdition={this.loadEdition}/> ); } else { return ( diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js index 7d466561..fb807cb9 100644 --- a/js/constants/api_urls.js +++ b/js/constants/api_urls.js @@ -13,7 +13,8 @@ let apiUrls = { 'ownership_loans': AppConstants.baseUrl + 'ownership/loans/', 'ownership_consigns': AppConstants.baseUrl + 'ownership/consigns/', 'ownership_unconsigns': AppConstants.baseUrl + 'ownership/unconsigns/', - 'ownership_unconsigns_request': AppConstants.baseUrl + 'ownership/unconsigns/request/' + 'ownership_unconsigns_request': AppConstants.baseUrl + 'ownership/unconsigns/request/', + 'note_notes': AppConstants.baseUrl + 'note/notes/' }; export default apiUrls; diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js index 25486919..778033b4 100644 --- a/js/constants/application_constants.js +++ b/js/constants/application_constants.js @@ -1,8 +1,8 @@ 'use strict'; let constants = { - //'baseUrl': 'http://localhost:8000/api/', - 'baseUrl': 'http://staging.ascribe.io/api/', + 'baseUrl': 'http://localhost:8000/api/', + //'baseUrl': 'http://staging.ascribe.io/api/', 'debugCredentialBase64': 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw', // dimi@mailinator:0000000000 'aclList': ['edit', 'consign', 'transfer', 'loan', 'share', 'download', 'view', 'delete', 'del_from_collection', 'add_to_collection'] }; diff --git a/js/mixins/form_mixin.js b/js/mixins/form_mixin.js index 9f5312fe..e0cc39f1 100644 --- a/js/mixins/form_mixin.js +++ b/js/mixins/form_mixin.js @@ -14,22 +14,32 @@ export const FormMixin = { }, submit(e) { - e.preventDefault(); + if (e) { + e.preventDefault(); + } this.setState({submitted: true}); this.clearErrors(); fetch .post(this.url(), { body: this.getFormData() }) - .then(() => this.props.handleSuccess()) + .then(() => this.handleSuccess() ) .catch(this.handleError); }, clearErrors(){ for (var ref in this.refs){ - this.refs[ref].clearAlerts(); + if ('clearAlerts' in this.refs[ref]){ + this.refs[ref].clearAlerts(); + } + } this.setState({errors: []}); }, + handleSuccess(){ + if ('handleSuccess' in this.props){ + this.props.handleSuccess(); + } + }, handleError(err){ if (err.json) { for (var input in err.json.errors){ diff --git a/sass/ascribe_textarea.scss b/sass/ascribe_textarea.scss new file mode 100644 index 00000000..f349628d --- /dev/null +++ b/sass/ascribe_textarea.scss @@ -0,0 +1,21 @@ +.ascribe-textarea { + border: none; + box-shadow: none; + margin-bottom: 1em; +} + +.ascribe-textarea-editable:hover { + border: 1px solid #AAA; +} + +.ascribe-pre{ + word-break: break-word; + /* white-space: pre-wrap; */ + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + /* word-wrap: break-word; */ + font-family: inherit; + text-align: justify; + background-color: white; +} diff --git a/sass/main.scss b/sass/main.scss index 58f43926..061e8a6e 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -10,6 +10,7 @@ @import 'ascribe_piece_list_bulk_modal'; @import 'ascribe_piece_list_toolbar'; @import 'ascribe_edition'; +@import 'ascribe_textarea'; @import 'ascribe_media_player'; @import 'offset_right';