mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
toggable textarea
This commit is contained in:
parent
b49f3fe9f2
commit
6563bf97b0
@ -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);
|
||||
});
|
||||
|
||||
|
@ -14,7 +14,7 @@ let ButtonSubmitOrClose = React.createClass({
|
||||
<div className="modal-footer">
|
||||
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="modal-footer">
|
||||
|
43
js/components/ascribe_forms/form_note_personal.js
Normal file
43
js/components/ascribe_forms/form_note_personal.js
Normal file
@ -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 (
|
||||
<form id="personal_note_content" role="form" key="personal_note_content">
|
||||
<InputTextAreaToggable
|
||||
ref="personalNote"
|
||||
className="form-control"
|
||||
defaultValue={this.props.editions[0].note_from_user}
|
||||
rows={3}
|
||||
editable={true}
|
||||
required=""
|
||||
onSubmit={this.submit}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PersonalNoteForm;
|
72
js/components/ascribe_forms/input_textarea_toggable.js
Normal file
72
js/components/ascribe_forms/input_textarea_toggable.js
Normal file
@ -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 = (
|
||||
<div className="pull-right">
|
||||
<Button className="ascribe-btn" onClick={this.submit}>Save</Button>
|
||||
<Button className="ascribe-btn" onClick={this.reset}>Cancel</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
if (this.props.editable){
|
||||
className = className + ' ascribe-textarea-editable';
|
||||
textarea = (
|
||||
<TextareaAutosize
|
||||
className={className}
|
||||
value={this.state.value}
|
||||
rows={this.props.rows}
|
||||
required={this.props.required}
|
||||
onChange={this.handleChange}
|
||||
placeholder='Write something...' />
|
||||
);
|
||||
}
|
||||
else{
|
||||
textarea = <pre className="ascribe-pre">{this.state.value}</pre>;
|
||||
}
|
||||
let alerts = (this.props.submitted) ? null : this.state.alerts;
|
||||
return (
|
||||
<div className="form-group">
|
||||
{alerts}
|
||||
{textarea}
|
||||
{buttons}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default InputTextAreaToggable;
|
@ -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({
|
||||
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.bitcoin_id}>{this.props.edition.bitcoin_id}</a>
|
||||
);
|
||||
|
||||
let hashOfArtwork = (
|
||||
let hashOfArtwork = (
|
||||
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.hash_as_address}>{this.props.edition.hash_as_address}</a>
|
||||
);
|
||||
|
||||
let ownerAddress = (
|
||||
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.btc_owner_address_noprefix}>{this.props.edition.btc_owner_address_noprefix}</a>
|
||||
);
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col md={6}>
|
||||
@ -64,8 +69,9 @@ let Edition = React.createClass({
|
||||
<CollapsibleEditionDetails
|
||||
title="Personal Note"
|
||||
iconName="pencil">
|
||||
<EditionPersonalNote
|
||||
savePersonalNote={this.props.savePersonalNote}/>
|
||||
<EditionPersonalNote
|
||||
handleSuccess={this.props.loadEdition}
|
||||
edition={this.props.edition}/>
|
||||
</CollapsibleEditionDetails>
|
||||
|
||||
<CollapsibleEditionDetails
|
||||
@ -92,7 +98,7 @@ let Edition = React.createClass({
|
||||
value={hashOfArtwork} />
|
||||
<EditionDetailProperty
|
||||
label="Owned by SPOOL address"
|
||||
value="MISSING IN /editions/<id> RESOURCE!" />
|
||||
value={ownerAddress} />
|
||||
</CollapsibleEditionDetails>
|
||||
|
||||
<CollapsibleEditionDetails
|
||||
@ -267,7 +273,7 @@ let EditionDetailProperty = React.createClass({
|
||||
<div className="row ascribe-detail-property">
|
||||
<div className="row-same-height">
|
||||
<div className={this.props.labelClassName + ' col-xs-height col-bottom'}>
|
||||
<div>{ this.props.label }{this.props.separator}</div>
|
||||
<div>{ this.props.label + this.props.separator}</div>
|
||||
</div>
|
||||
<div className={this.props.valueClassName + ' col-xs-height col-bottom'}>
|
||||
<div>{ this.props.value }</div>
|
||||
@ -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 (
|
||||
<Row>
|
||||
<Col md={12} className="ascribe-edition-personal-note">
|
||||
<TextareaAutosize
|
||||
ref="personalNote"
|
||||
className="form-control"
|
||||
rows={3}
|
||||
placeholder='Write something...' />
|
||||
<Button
|
||||
onClick={this.prepareSavePersonalNote}
|
||||
className="pull-right">Save</Button>
|
||||
<PersonalNoteForm
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
editions={[this.props.edition]} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -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 (
|
||||
|
@ -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;
|
||||
|
@ -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']
|
||||
};
|
||||
|
@ -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){
|
||||
|
21
sass/ascribe_textarea.scss
Normal file
21
sass/ascribe_textarea.scss
Normal file
@ -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;
|
||||
}
|
@ -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';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user