mirror of
https://github.com/ascribe/onion.git
synced 2025-01-03 18:35:09 +01:00
Merged in AD-538-users-and-even-devs-are-unsure-wh (pull request #94)
Ad 538 users and even devs are unsure wh
This commit is contained in:
commit
d0f6f1571d
@ -125,7 +125,6 @@ let AccordionListItemEditionWidget = React.createClass({
|
||||
);
|
||||
} else {
|
||||
let editionMapping = piece && piece.first_edition ? piece.first_edition.num_editions_available + '/' + piece.num_editions : '';
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={this.toggleTable}
|
||||
|
@ -169,7 +169,8 @@ let AclButton = React.createClass({
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={
|
||||
<button className={shouldDisplay ? 'btn btn-default btn-sm ' + buttonClassName : 'hidden'}>
|
||||
<button
|
||||
className={shouldDisplay ? 'btn btn-default btn-sm ' + buttonClassName : 'hidden'}>
|
||||
{this.sanitizeAction()}
|
||||
</button>
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import React from 'react/addons';
|
||||
|
||||
import UserActions from '../../actions/user_actions';
|
||||
import UserStore from '../../stores/user_store';
|
||||
|
||||
import AclButton from '../ascribe_buttons/acl_button';
|
||||
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
|
||||
|
||||
let AclButtonList = React.createClass({
|
||||
propTypes: {
|
||||
className: React.PropTypes.string,
|
||||
@ -15,6 +18,7 @@ let AclButtonList = React.createClass({
|
||||
React.PropTypes.array
|
||||
]),
|
||||
availableAcls: React.PropTypes.object,
|
||||
buttonsStyle: React.PropTypes.object,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||
@ -23,56 +27,97 @@ let AclButtonList = React.createClass({
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return UserStore.getState();
|
||||
return mergeOptions(
|
||||
UserStore.getState(),
|
||||
{
|
||||
buttonListSize: 0
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
},
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if(prevProps.availableAcls && prevProps.availableAcls !== this.props.availableAcls) {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
UserStore.unlisten(this.onChange);
|
||||
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
},
|
||||
|
||||
handleResize() {
|
||||
this.setState({
|
||||
buttonListSize: this.refs.buttonList.getDOMNode().offsetWidth
|
||||
});
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
renderChildren() {
|
||||
const { children } = this.props;
|
||||
const { buttonListSize } = this.state;
|
||||
|
||||
return React.Children.map(children, (child) => {
|
||||
return React.addons.cloneWithProps(child, { buttonListSize });
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
const { className,
|
||||
buttonsStyle,
|
||||
availableAcls,
|
||||
editions,
|
||||
handleSuccess } = this.props;
|
||||
|
||||
const { currentUser } = this.state;
|
||||
|
||||
return (
|
||||
<div className={this.props.className}>
|
||||
<div className={className}>
|
||||
<span ref="buttonList" style={buttonsStyle}>
|
||||
<AclButton
|
||||
availableAcls={this.props.availableAcls}
|
||||
action="acl_transfer"
|
||||
pieceOrEditions={this.props.editions}
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.props.handleSuccess}/>
|
||||
<AclButton
|
||||
availableAcls={this.props.availableAcls}
|
||||
action="acl_consign"
|
||||
pieceOrEditions={this.props.editions}
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={this.props.availableAcls}
|
||||
action="acl_unconsign"
|
||||
pieceOrEditions={this.props.editions}
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={this.props.availableAcls}
|
||||
action="acl_loan"
|
||||
pieceOrEditions={this.props.editions}
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={this.props.availableAcls}
|
||||
availableAcls={availableAcls}
|
||||
action="acl_share"
|
||||
pieceOrEditions={this.props.editions}
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
{this.props.children}
|
||||
pieceOrEditions={editions}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={availableAcls}
|
||||
action="acl_transfer"
|
||||
pieceOrEditions={editions}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={handleSuccess}/>
|
||||
<AclButton
|
||||
availableAcls={availableAcls}
|
||||
action="acl_consign"
|
||||
pieceOrEditions={editions}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={availableAcls}
|
||||
action="acl_unconsign"
|
||||
pieceOrEditions={editions}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={handleSuccess} />
|
||||
<AclButton
|
||||
availableAcls={availableAcls}
|
||||
action="acl_loan"
|
||||
pieceOrEditions={editions}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={handleSuccess} />
|
||||
{this.renderChildren()}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
133
js/components/ascribe_buttons/acl_information.js
Normal file
133
js/components/ascribe_buttons/acl_information.js
Normal file
@ -0,0 +1,133 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { InformationTexts } from '../../constants/information_text';
|
||||
import { replaceSubstringAtIndex, sanitize, intersectLists } from '../../utils/general_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
|
||||
let AclInformation = React.createClass({
|
||||
propTypes: {
|
||||
verbs: React.PropTypes.arrayOf(React.PropTypes.string),
|
||||
aim: React.PropTypes.string.isRequired,
|
||||
aclObject: React.PropTypes.object,
|
||||
|
||||
// Must be inserted from the outside
|
||||
buttonListSize: React.PropTypes.number.isRequired
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
buttonListSize: 400
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return { isVisible: false };
|
||||
},
|
||||
|
||||
onOff() {
|
||||
if(!this.state.isVisible) {
|
||||
this.setState({ isVisible: true });
|
||||
}
|
||||
else {
|
||||
this.setState({ isVisible: false });
|
||||
}
|
||||
},
|
||||
|
||||
getInfoText(title, info, example){
|
||||
let aim = this.props.aim;
|
||||
|
||||
if(aim) {
|
||||
if(aim === 'form') {
|
||||
return (
|
||||
<p>
|
||||
<span className="info">
|
||||
{replaceSubstringAtIndex(info.slice(2), 's ', ' ')}
|
||||
</span>
|
||||
<span className="example">
|
||||
{' ' + example}
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
else if(aim === 'button') {
|
||||
return (
|
||||
<p>
|
||||
<span className="title">
|
||||
{title}
|
||||
</span>
|
||||
<span className="info">
|
||||
{info + ' '}
|
||||
</span>
|
||||
<span className="example">
|
||||
{example}
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('Aim is required when you want to place information text');
|
||||
}
|
||||
},
|
||||
|
||||
produceInformationBlock() {
|
||||
const { titles, informationSentences, exampleSentences } = InformationTexts;
|
||||
const { verbs, aim } = this.props;
|
||||
|
||||
const availableInformations = intersectLists(verbs, Object.keys(titles));
|
||||
|
||||
// sorting is not needed, as `this.props.verbs` takes care of sorting already
|
||||
// So we assume a user of `AclInformationButton` puts an ordered version of
|
||||
// `verbs` into `propTypes`
|
||||
let verbsToDisplay = [];
|
||||
|
||||
|
||||
if(aim === 'form' && availableInformations.length > 0) {
|
||||
verbsToDisplay = verbsToDisplay.concat(verbs);
|
||||
} else if(aim === 'button' && this.props.aclObject) {
|
||||
const { aclObject } = this.props;
|
||||
const sanitizedAclObject = sanitize(aclObject, (val) => !val);
|
||||
verbsToDisplay = verbsToDisplay.concat(intersectLists(verbs, Object.keys(sanitizedAclObject)));
|
||||
}
|
||||
|
||||
return verbsToDisplay.map((verb) => {
|
||||
return this.getInfoText(getLangText(titles[verb]), getLangText(informationSentences[verb]), getLangText(exampleSentences[verb]));
|
||||
});
|
||||
},
|
||||
|
||||
getButton() {
|
||||
return this.props.aim === 'button' ?
|
||||
<button
|
||||
style={{ marginTop: 0 }}
|
||||
className="btn btn-transparent glyphicon glyphicon-question-sign" onClick={this.onOff} /> :
|
||||
null;
|
||||
},
|
||||
|
||||
render() {
|
||||
const { aim, buttonListSize, verbs } = this.props;
|
||||
const { isVisible } = this.state;
|
||||
|
||||
/* Lets just fucking get this widget out... */
|
||||
const aclInformationSize = buttonListSize - 30;
|
||||
|
||||
return (
|
||||
<span >
|
||||
{this.getButton()}
|
||||
<div
|
||||
style={{
|
||||
width: verbs.length > 1 && aclInformationSize > 300 ? aclInformationSize : verbs.length === 1 ? null : '100%',
|
||||
marginLeft: verbs.length === 1 ? '.25em' : null
|
||||
}}
|
||||
className={classnames({'acl-information-dropdown-list': true, 'hidden': aim === 'button' && !isVisible})}>
|
||||
<span>{this.produceInformationBlock()}</span>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default AclInformation;
|
@ -39,13 +39,13 @@ let DeleteButton = React.createClass({
|
||||
|
||||
if(this.props.piece && !this.props.editions) {
|
||||
content = <PieceDeleteForm pieceId={this.props.piece.id}/>;
|
||||
title = getLangText('Remove Piece');
|
||||
title = getLangText('Delete Piece');
|
||||
} else {
|
||||
content = <EditionDeleteForm editions={this.props.editions}/>;
|
||||
title = getLangText('Remove Edition');
|
||||
title = getLangText('Delete Edition');
|
||||
}
|
||||
|
||||
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('DELETE')}</Button>;
|
||||
btnDelete = <Button bsStyle="default" bsSize="small">{getLangText('DELETE')}</Button>;
|
||||
|
||||
} else if(availableAcls.acl_unshare){
|
||||
|
||||
@ -57,7 +57,7 @@ let DeleteButton = React.createClass({
|
||||
title = getLangText('Remove Piece from Collection');
|
||||
}
|
||||
|
||||
btnDelete = <Button bsStyle="danger" className="btn-delete" bsSize="small">{getLangText('REMOVE FROM COLLECTION')}</Button>;
|
||||
btnDelete = <Button bsStyle="default" bsSize="small">{getLangText('REMOVE FROM COLLECTION')}</Button>;
|
||||
|
||||
} else {
|
||||
return null;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
||||
let DetailProperty = React.createClass({
|
||||
propTypes: {
|
||||
label: React.PropTypes.string,
|
||||
@ -12,20 +13,29 @@ let DetailProperty = React.createClass({
|
||||
separator: React.PropTypes.string,
|
||||
labelClassName: React.PropTypes.string,
|
||||
valueClassName: React.PropTypes.string,
|
||||
ellipsis: React.PropTypes.bool
|
||||
ellipsis: React.PropTypes.bool,
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||
React.PropTypes.element
|
||||
])
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
separator: '',
|
||||
labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2 col-xs-height col-bottom ascribe-detail-property-label',
|
||||
labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2 col-xs-height ascribe-detail-property-label',
|
||||
valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-10 col-xs-height col-bottom ascribe-detail-property-value'
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
let value = this.props.value;
|
||||
let styles = {};
|
||||
const { labelClassName,
|
||||
label,
|
||||
separator,
|
||||
valueClassName,
|
||||
children,
|
||||
value } = this.props;
|
||||
|
||||
if(this.props.ellipsis) {
|
||||
styles = {
|
||||
@ -35,30 +45,16 @@ let DetailProperty = React.createClass({
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (this.props.children){
|
||||
value = (
|
||||
<div className="row-same-height">
|
||||
<div className="col-xs-6 col-xs-height col-bottom no-padding">
|
||||
{ this.props.value }
|
||||
</div>
|
||||
<div
|
||||
className="col-xs-6 col-xs-height"
|
||||
style={styles}>
|
||||
{ this.props.children }
|
||||
</div>
|
||||
</div>);
|
||||
}
|
||||
return (
|
||||
<div className="row ascribe-detail-property">
|
||||
<div className="row-same-height">
|
||||
<div className={this.props.labelClassName}>
|
||||
{ this.props.label } { this.props.separator}
|
||||
<div className={labelClassName}>
|
||||
{label} {separator}
|
||||
</div>
|
||||
<div
|
||||
className={this.props.valueClassName}
|
||||
className={valueClassName}
|
||||
style={styles}>
|
||||
{value}
|
||||
{children || value}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -145,7 +145,6 @@ let Edition = React.createClass({
|
||||
url={ApiUrls.note_public_edition}
|
||||
currentUser={this.state.currentUser}/>
|
||||
</CollapsibleParagraph>
|
||||
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Further Details')}
|
||||
show={this.props.edition.acl.acl_edit
|
||||
@ -159,7 +158,6 @@ let Edition = React.createClass({
|
||||
handleSuccess={this.props.loadEdition}
|
||||
location={this.props.location}/>
|
||||
</CollapsibleParagraph>
|
||||
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('SPOOL Details')}>
|
||||
<SpoolDetails
|
||||
@ -213,10 +211,13 @@ let EditionSummary = React.createClass({
|
||||
value={ edition.owner } />
|
||||
<LicenseDetail license={edition.license_type}/>
|
||||
{this.getStatus()}
|
||||
<EditionDetailProperty
|
||||
label={getLangText('ACTIONS')}>
|
||||
<EditionActionPanel
|
||||
edition={edition}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={this.handleSuccess} />
|
||||
</EditionDetailProperty>
|
||||
<hr/>
|
||||
</div>
|
||||
);
|
||||
|
@ -22,6 +22,8 @@ import DeleteButton from '../ascribe_buttons/delete_button';
|
||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
import AclProxy from '../acl_proxy';
|
||||
|
||||
import ApiUrls from '../../constants/api_urls';
|
||||
@ -103,7 +105,7 @@ let EditionActionPanel = React.createClass({
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<AclButtonList
|
||||
className="text-center ascribe-button-list"
|
||||
className="ascribe-button-list"
|
||||
availableAcls={edition.acl}
|
||||
editions={[edition]}
|
||||
handleSuccess={this.handleSuccess}>
|
||||
@ -122,7 +124,7 @@ let EditionActionPanel = React.createClass({
|
||||
type="text"
|
||||
value={edition.bitcoin_id} />
|
||||
</Property>
|
||||
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
|
||||
<Button bsStyle="default" className="pull-center" bsSize="small" type="submit">
|
||||
{getLangText('WITHDRAW TRANSFER')}
|
||||
</Button>
|
||||
</Form>
|
||||
@ -158,6 +160,10 @@ let EditionActionPanel = React.createClass({
|
||||
<DeleteButton
|
||||
handleSuccess={this.handleDeleteSuccess}
|
||||
editions={[edition]}/>
|
||||
<AclInformation
|
||||
aim="button"
|
||||
verbs={['acl_share', 'acl_consign', 'acl_loan', 'acl_delete']}
|
||||
aclObject={edition.acl}/>
|
||||
</AclButtonList>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -27,6 +27,8 @@ import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
import ListRequestActions from '../ascribe_forms/list_form_request_actions';
|
||||
|
||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||
@ -188,11 +190,11 @@ let PieceContainer = React.createClass({
|
||||
currentUser={this.state.currentUser}
|
||||
handleSuccess={this.loadPiece}
|
||||
notifications={this.state.piece.notifications}/>);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return (
|
||||
<DetailProperty label={getLangText('ACTIONS')}>
|
||||
<AclButtonList
|
||||
className="text-center ascribe-button-list"
|
||||
className="ascribe-button-list"
|
||||
availableAcls={this.state.piece.acl}
|
||||
editions={this.state.piece}
|
||||
handleSuccess={this.loadPiece}>
|
||||
@ -205,7 +207,12 @@ let PieceContainer = React.createClass({
|
||||
<DeleteButton
|
||||
handleSuccess={this.handleDeleteSuccess}
|
||||
piece={this.state.piece}/>
|
||||
<AclInformation
|
||||
aim="button"
|
||||
verbs={['acl_share', 'acl_create_editions', 'acl_loan', 'acl_delete', 'acl_consign']}
|
||||
aclObject={this.state.piece.acl}/>
|
||||
</AclButtonList>
|
||||
</DetailProperty>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -288,10 +288,8 @@ let Form = React.createClass({
|
||||
{this.renderChildren()}
|
||||
{this.getButtons()}
|
||||
</form>
|
||||
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default Form;
|
||||
|
@ -10,7 +10,7 @@ import InputTextAreaToggable from './input_textarea_toggable';
|
||||
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
let ConsignForm = React.createClass({
|
||||
propTypes: {
|
||||
@ -47,6 +47,7 @@ let ConsignForm = React.createClass({
|
||||
<AscribeSpinner color='dark-blue' size='md'/>
|
||||
</p>
|
||||
</div>}>
|
||||
<AclInformation aim={'form'} verbs={['acl_consign']}/>
|
||||
<Property
|
||||
name='consignee'
|
||||
label={getLangText('Email')}>
|
||||
|
@ -8,7 +8,7 @@ import ApiUrls from '../../constants/api_urls';
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
let EditionDeleteForm = React.createClass({
|
||||
|
||||
@ -60,6 +60,7 @@ let EditionDeleteForm = React.createClass({
|
||||
</p>
|
||||
</div>
|
||||
}>
|
||||
<AclInformation aim={'form'} verbs={['acl_delete']}/>
|
||||
<p>{getLangText('Are you sure you would like to permanently delete this edition')}?</p>
|
||||
<p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||
</Form>
|
||||
|
@ -4,6 +4,8 @@ import React from 'react';
|
||||
|
||||
import Form from '../ascribe_forms/form';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
import ApiUrls from '../../constants/api_urls';
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
|
||||
@ -51,6 +53,7 @@ let PieceDeleteForm = React.createClass({
|
||||
</p>
|
||||
</div>
|
||||
}>
|
||||
<AclInformation aim={'form'} verbs={['acl_delete']}/>
|
||||
<p>{getLangText('Are you sure you would like to permanently delete this piece')}?</p>
|
||||
<p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||
</Form>
|
||||
|
@ -19,7 +19,7 @@ import AscribeSpinner from '../ascribe_spinner';
|
||||
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
let LoanForm = React.createClass({
|
||||
propTypes: {
|
||||
@ -232,6 +232,7 @@ let LoanForm = React.createClass({
|
||||
<div className={classnames({'ascribe-form-header': true, 'hidden': !this.props.loanHeading})}>
|
||||
<h3>{this.props.loanHeading}</h3>
|
||||
</div>
|
||||
<AclInformation aim={'form'} verbs={['acl_loan']}/>
|
||||
<Property
|
||||
name='loanee'
|
||||
label={getLangText('Loanee Email')}
|
||||
|
@ -8,6 +8,8 @@ import InputTextAreaToggable from './input_textarea_toggable';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
@ -51,6 +53,7 @@ let ShareForm = React.createClass({
|
||||
<AscribeSpinner color='dark-blue' size='md'/>
|
||||
</p>
|
||||
</div>}>
|
||||
<AclInformation aim={'form'} verbs={['acl_share']}/>
|
||||
<Property
|
||||
name='share_emails'
|
||||
label={getLangText('Emails')}>
|
||||
|
@ -9,6 +9,8 @@ import Form from './form';
|
||||
import Property from './property';
|
||||
import InputTextAreaToggable from './input_textarea_toggable';
|
||||
|
||||
import AclInformation from '../ascribe_buttons/acl_information';
|
||||
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
@ -52,6 +54,7 @@ let TransferForm = React.createClass({
|
||||
<AscribeSpinner color='dark-blue' size='md'/>
|
||||
</p>
|
||||
</div>}>
|
||||
<AclInformation aim={'form'} verbs={['acl_transfer']}/>
|
||||
<Property
|
||||
name='transferee'
|
||||
label={getLangText('Email')}>
|
||||
|
@ -65,7 +65,7 @@ let ModalWrapper = React.createClass({
|
||||
{this.props.title}
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<div className="modal-body">
|
||||
<div className="modal-body" >
|
||||
{this.renderChildren()}
|
||||
</div>
|
||||
</Modal>
|
||||
|
@ -201,7 +201,7 @@ let Header = React.createClass({
|
||||
{this.getPoweredBy()}
|
||||
</Nav>
|
||||
<Nav navbar right>
|
||||
<HeaderNotificationDebug show={false}/>
|
||||
<HeaderNotificationDebug show = {false}/>
|
||||
{account}
|
||||
{signup}
|
||||
</Nav>
|
||||
|
33
js/constants/information_text.js
Normal file
33
js/constants/information_text.js
Normal file
@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
export const InformationTexts = {
|
||||
'titles': {
|
||||
'acl_consign': 'CONSIGN',
|
||||
'acl_loan': 'LOAN',
|
||||
'acl_share': 'SHARE',
|
||||
'acl_delete': 'DELETE',
|
||||
'acl_create_editions': 'CREATE EDITIONS',
|
||||
'acl_unconsign': 'UNCONSIGN',
|
||||
'acl_request_unconsign': 'REQUEST UNCONSIGN'
|
||||
},
|
||||
'informationSentences': {
|
||||
'acl_consign': ' - Lets someone represent you in dealing with the work, under the terms you agree to.',
|
||||
'acl_loan': ' - Lets someone use or put the Work on display for a limited amount of time.',
|
||||
'acl_share': ' - Lets someone view the Work or Edition, but does not give rights to publish or display it.',
|
||||
'acl_delete': ' - Removes the Work from your Wallet. Note that the previous registration and transfer ' +
|
||||
'history will still exist on the blockchain and cannot be deleted.',
|
||||
'acl_create_editions': ' Lets the artist set a fixed number of editions of a work which can then be transferred, guaranteeing each edition is authentic and from the artist.',
|
||||
'acl_unconsign': 'Ends the consignment agreement between the owner and a consignee.',
|
||||
'acl_request_unconsign': 'Lets the owner ask the consignee to confirm that they will no longer manage the work.'
|
||||
},
|
||||
'exampleSentences': {
|
||||
'acl_consign': '(e.g. an artist Consigns 10 Editions of her new Work to a gallery ' +
|
||||
'so the gallery can sell them on her behalf, under the terms the artist and the gallery have agreed to)',
|
||||
'acl_loan': '(e.g. a collector Loans a Work to a gallery for one month for display in the gallery\'s show)',
|
||||
'acl_share': '(e.g. a photographer Shares proofs of a graduation photo with the graduate\'s grandparents)',
|
||||
'acl_delete': '(e.g. an artist uploaded the wrong file and doesn\'t want it cluttering his Wallet, so he Deletes it)',
|
||||
'acl_create_editions': '(e.g. A company commissions a visual artists to create three limited edition prints for a giveaway)',
|
||||
'acl_unconsign': '(e.g. An artist regains full control over their work and releases the consignee of any rights or responsibilities)',
|
||||
'acl_request_unconsign': '(e.g. An artist submits an unconsign request to a gallery after his exhibition ends, as per their agreement)'
|
||||
}
|
||||
};
|
@ -1,10 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
import { sanitize } from './general_utils';
|
||||
|
||||
function intersectAcls(a, b) {
|
||||
return a.filter((val) => b.indexOf(val) > -1);
|
||||
}
|
||||
import { sanitize, intersectLists } from './general_utils';
|
||||
|
||||
export function getAvailableAcls(editions, filterFn) {
|
||||
let availableAcls = [];
|
||||
@ -44,7 +40,7 @@ export function getAvailableAcls(editions, filterFn) {
|
||||
}
|
||||
if(editionsCopy.length >= 2) {
|
||||
for(let i = 1; i < editionsCopy.length; i++) {
|
||||
availableAcls = intersectAcls(availableAcls, editionsCopy[i].acl);
|
||||
availableAcls = intersectLists(availableAcls, editionsCopy[i].acl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,6 +223,16 @@ export function truncateTextAtCharIndex(text, charIndex, replacement = '...') {
|
||||
return truncatedText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index, int, the starting index of the substring to be replaced
|
||||
* @param character, substring to be replaced
|
||||
* @returns {string}
|
||||
*/
|
||||
export function replaceSubstringAtIndex(baseString, substrToReplace, stringToBePut) {
|
||||
let index = baseString.indexOf(substrToReplace);
|
||||
return baseString.substr(0, index) + stringToBePut + baseString.substr(index + substrToReplace.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the user's subdomain from the browser's window.
|
||||
* If no subdomain is found (for example on a naked domain), the default "www" is just assumed.
|
||||
@ -234,3 +244,12 @@ export function getSubdomain() {
|
||||
return tokens.length > 2 ? tokens[0] : 'www';
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes two lists and returns their intersection as a list
|
||||
* @param {Array} a
|
||||
* @param {Array} b
|
||||
* @return {[Array]} Intersected list of a and b
|
||||
*/
|
||||
export function intersectLists(a, b) {
|
||||
return a.filter((val) => b.indexOf(val) > -1);
|
||||
}
|
||||
|
25
sass/ascribe_acl_information.scss
Normal file
25
sass/ascribe_acl_information.scss
Normal file
@ -0,0 +1,25 @@
|
||||
.acl-information-dropdown-list {
|
||||
text-align: justify;
|
||||
padding: .5em .5em .5em 0;
|
||||
|
||||
p {
|
||||
margin: 0 .5em 1em 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: $ascribe-dark-blue;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.example {
|
||||
color: #616161;
|
||||
}
|
||||
}
|
@ -18,7 +18,3 @@
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ascribe-button-list {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
.btn-transparent {
|
||||
color: black;
|
||||
background-color: transparent;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color:#424242;
|
||||
outline: none;
|
||||
}
|
||||
}
|
8
sass/lib/modals.scss
Normal file
8
sass/lib/modals.scss
Normal file
@ -0,0 +1,8 @@
|
||||
.modal-body {
|
||||
padding-top:0;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 15px 15px 0 15px;
|
||||
border-bottom: none;
|
||||
}
|
@ -35,6 +35,9 @@ $BASE_URL: '<%= BASE_URL %>';
|
||||
@import 'ascribe_form';
|
||||
@import 'ascribe_panel';
|
||||
@import 'ascribe_collapsible';
|
||||
@import 'ascribe_acl_information';
|
||||
@import 'lib/buttons';
|
||||
@import 'lib/modals';
|
||||
@import 'ascribe_custom_style';
|
||||
@import 'ascribe_spinner';
|
||||
|
||||
@ -155,6 +158,7 @@ hr {
|
||||
}
|
||||
|
||||
.ascribe-detail-property-label {
|
||||
vertical-align: top;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,7 @@ $modal-header-border-color: #e5e5e5 !default;
|
||||
$modal-footer-border-color: $modal-header-border-color !default;
|
||||
|
||||
$modal-lg: 900px !default;
|
||||
$modal-md: 600px !default;
|
||||
$modal-md: 500px !default;
|
||||
$modal-sm: 300px !default;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user