1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

refactored notifications per detail

This commit is contained in:
diminator 2015-09-03 17:25:22 +02:00
parent 9334251fd3
commit 73ee0753c1
13 changed files with 60 additions and 177 deletions

View File

@ -160,7 +160,7 @@ let AccordionListItemTableEditions = React.createClass({
let content = item.acl; let content = item.acl;
return { return {
'content': content, 'content': content,
'requestAction': item.request_action 'notifications': item.notifications
}; }, }; },
'acl', 'acl',
getLangText('Actions'), getLangText('Actions'),

View File

@ -61,8 +61,7 @@ let AccordionListItemWallet = React.createClass({
}, },
getGlyphicon(){ getGlyphicon(){
if ((this.props.content.request_action && this.props.content.request_action.length > 0) || if ((this.props.content.notifications && this.props.content.notifications.length > 0)){
(this.props.content.request_action_editions)){
return ( return (
<OverlayTrigger <OverlayTrigger
delay={500} delay={500}

View File

@ -14,10 +14,7 @@ import CoaActions from '../../actions/coa_actions';
import CoaStore from '../../stores/coa_store'; import CoaStore from '../../stores/coa_store';
import PieceListActions from '../../actions/piece_list_actions'; import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store'; import PieceListStore from '../../stores/piece_list_store';
import EditionListActions from '../../actions/edition_list_actions'; import EditionListActions from '../../actions/edition_list_actions';;
import NotificationActions from '../../actions/notification_actions';
import NotificationStore from '../../stores/notification_store';
import HistoryIterator from './history_iterator'; import HistoryIterator from './history_iterator';
@ -211,25 +208,6 @@ let EditionSummary = React.createClass({
handleDeleteSuccess: React.PropTypes.func handleDeleteSuccess: React.PropTypes.func
}, },
getInitialState() {
return mergeOptions(
NotificationStore.getState()
);
},
componentDidMount() {
NotificationStore.listen(this.onChange);
NotificationActions.fetchEditionNotifications(this.props.edition.bitcoin_id);
},
componentWillUnmount() {
NotificationStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
getTransferWithdrawData(){ getTransferWithdrawData(){
return {'bitcoin_id': this.props.edition.bitcoin_id}; return {'bitcoin_id': this.props.edition.bitcoin_id};
}, },
@ -256,13 +234,15 @@ let EditionSummary = React.createClass({
getActions(){ getActions(){
let actions = null; let actions = null;
if (this.state.editionNotifications && this.state.editionNotifications.notification){ if (this.props.edition &&
this.props.edition.notifications &&
this.props.edition.notifications.length > 0){
actions = ( actions = (
<ListRequestActions <ListRequestActions
pieceOrEditions={[this.props.edition]} pieceOrEditions={[this.props.edition]}
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
handleSuccess={this.showNotification} handleSuccess={this.showNotification}
requestActions={this.state.editionNotifications.notification}/>); notifications={this.props.edition.notifications}/>);
} }
else { else {

View File

@ -9,9 +9,6 @@ import PieceStore from '../../stores/piece_store';
import PieceListActions from '../../actions/piece_list_actions'; import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store'; import PieceListStore from '../../stores/piece_list_store';
import NotificationActions from '../../actions/notification_actions';
import NotificationStore from '../../stores/notification_store';
import UserActions from '../../actions/user_actions'; import UserActions from '../../actions/user_actions';
import UserStore from '../../stores/user_store'; import UserStore from '../../stores/user_store';
@ -65,8 +62,6 @@ let PieceContainer = React.createClass({
UserActions.fetchCurrentUser(); UserActions.fetchCurrentUser();
PieceStore.listen(this.onChange); PieceStore.listen(this.onChange);
PieceActions.fetchOne(this.props.params.pieceId); PieceActions.fetchOne(this.props.params.pieceId);
NotificationStore.listen(this.onChange);
NotificationActions.fetchPieceNotifications(this.props.params.pieceId);
}, },
componentWillUnmount() { componentWillUnmount() {
@ -78,7 +73,6 @@ let PieceContainer = React.createClass({
PieceStore.unlisten(this.onChange); PieceStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
PieceListStore.unlisten(this.onChange); PieceListStore.unlisten(this.onChange);
NotificationStore.unlisten(this.onChange);
}, },
onChange(state) { onChange(state) {
@ -180,14 +174,14 @@ let PieceContainer = React.createClass({
getActions() { getActions() {
if (this.state.piece && if (this.state.piece &&
this.state.pieceNotifications && this.state.piece.notifications &&
this.state.pieceNotifications.notification) { this.state.piece.notifications.length > 0) {
return ( return (
<ListRequestActions <ListRequestActions
pieceOrEditions={this.state.piece} pieceOrEditions={this.state.piece}
currentUser={this.state.currentUser} currentUser={this.state.currentUser}
handleSuccess={this.loadPiece} handleSuccess={this.loadPiece}
requestActions={this.state.pieceNotifications.notification}/>); notifications={this.state.piece.notifications}/>);
} }
else { else {
return ( return (

View File

@ -22,8 +22,7 @@ let RequestActionForm = React.createClass({
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.array React.PropTypes.array
]).isRequired, ]).isRequired,
requestAction: React.PropTypes.string, notifications: React.PropTypes.object,
requestUser: React.PropTypes.string,
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,
handleSuccess: React.PropTypes.func handleSuccess: React.PropTypes.func
}, },
@ -35,19 +34,19 @@ let RequestActionForm = React.createClass({
getUrls() { getUrls() {
let urls = {}; let urls = {};
if (this.props.requestAction === 'consign'){ if (this.props.notifications.action === 'consign'){
urls.accept = ApiUrls.ownership_consigns_confirm; urls.accept = ApiUrls.ownership_consigns_confirm;
urls.deny = ApiUrls.ownership_consigns_deny; urls.deny = ApiUrls.ownership_consigns_deny;
} else if (this.props.requestAction === 'unconsign'){ } else if (this.props.notifications.action === 'unconsign'){
urls.accept = ApiUrls.ownership_unconsigns; urls.accept = ApiUrls.ownership_unconsigns;
urls.deny = ApiUrls.ownership_unconsigns_deny; urls.deny = ApiUrls.ownership_unconsigns_deny;
} else if (this.props.requestAction === 'loan' && !this.isPiece()){ } else if (this.props.notifications.action === 'loan' && !this.isPiece()){
urls.accept = ApiUrls.ownership_loans_confirm; urls.accept = ApiUrls.ownership_loans_confirm;
urls.deny = ApiUrls.ownership_loans_deny; urls.deny = ApiUrls.ownership_loans_deny;
} else if (this.props.requestAction === 'loan' && this.isPiece()){ } else if (this.props.notifications.action === 'loan' && this.isPiece()){
urls.accept = ApiUrls.ownership_loans_pieces_confirm; urls.accept = ApiUrls.ownership_loans_pieces_confirm;
urls.deny = ApiUrls.ownership_loans_pieces_deny; urls.deny = ApiUrls.ownership_loans_pieces_deny;
} else if (this.props.requestAction === 'loan_request' && this.isPiece()){ } else if (this.props.notifications.action === 'loan_request' && this.isPiece()){
urls.accept = ApiUrls.ownership_loans_pieces_request_confirm; urls.accept = ApiUrls.ownership_loans_pieces_request_confirm;
urls.deny = ApiUrls.ownership_loans_pieces_request_deny; urls.deny = ApiUrls.ownership_loans_pieces_request_deny;
} }
@ -70,8 +69,8 @@ let RequestActionForm = React.createClass({
return () => { return () => {
let message = getLangText('You have successfully') + ' ' + option + ' the ' + action + ' request ' + getLangText('from') + ' ' + owner; let message = getLangText('You have successfully') + ' ' + option + ' the ' + action + ' request ' + getLangText('from') + ' ' + owner;
let notification = new GlobalNotificationModel(message, 'success'); let notifications = new GlobalNotificationModel(message, 'success');
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notifications);
this.handleSuccess(); this.handleSuccess();
@ -81,11 +80,9 @@ let RequestActionForm = React.createClass({
handleSuccess() { handleSuccess() {
if (this.isPiece()){ if (this.isPiece()){
NotificationActions.fetchPieceListNotifications(); NotificationActions.fetchPieceListNotifications();
//NotificationActions.fetchPieceNotifications(this.props.pieceOrEditions.id);
} }
else { else {
NotificationActions.fetchEditionListNotifications(); NotificationActions.fetchEditionListNotifications();
NotificationActions.fetchEditionNotifications(this.props.pieceOrEditions[0].bitcoin_id);
} }
if(this.props.handleSuccess) { if(this.props.handleSuccess) {
this.props.handleSuccess(); this.props.handleSuccess();
@ -93,20 +90,15 @@ let RequestActionForm = React.createClass({
}, },
getContent() { getContent() {
let pieceOrEditionStr = this.isPiece() ? getLangText('this work%s', '.') : getLangText('this edition%s', '.');
let message = this.props.requestUser + ' ' + getLangText('requests you') + ' ' + this.props.requestAction + ' ' + pieceOrEditionStr;
if (this.props.requestAction === 'loan_request'){
message = this.props.requestUser + ' ' + getLangText('requests you to loan') + ' ' + pieceOrEditionStr;
}
return ( return (
<span> <span>
{message} {this.props.notifications.action_str + ' by ' + this.props.notifications.by}
</span> </span>
); );
}, },
getAcceptButtonForm(urls) { getAcceptButtonForm(urls) {
if(this.props.requestAction === 'unconsign') { if(this.props.notifications.action === 'unconsign') {
return ( return (
<AclButton <AclButton
availableAcls={{'acl_unconsign': true}} availableAcls={{'acl_unconsign': true}}
@ -116,7 +108,7 @@ let RequestActionForm = React.createClass({
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
handleSuccess={this.handleSuccess} /> handleSuccess={this.handleSuccess} />
); );
} else if(this.props.requestAction === 'loan_request') { } else if(this.props.notifications.action === 'loan_request') {
return ( return (
<AclButton <AclButton
availableAcls={{'acl_loan_request': true}} availableAcls={{'acl_loan_request': true}}
@ -133,7 +125,7 @@ let RequestActionForm = React.createClass({
url={urls.accept} url={urls.accept}
getFormData={this.getFormData} getFormData={this.getFormData}
handleSuccess={ handleSuccess={
this.showNotification(getLangText('accepted'), this.props.requestAction, this.props.requestUser) this.showNotification(getLangText('accepted'), this.props.notifications.action, this.props.notifications.by)
} }
isInline={true} isInline={true}
className='inline pull-right'> className='inline pull-right'>
@ -158,7 +150,7 @@ let RequestActionForm = React.createClass({
isInline={true} isInline={true}
getFormData={this.getFormData} getFormData={this.getFormData}
handleSuccess={ handleSuccess={
this.showNotification(getLangText('denied'), this.props.requestAction, this.props.requestUser) this.showNotification(getLangText('denied'), this.props.notifications.action, this.props.notifications.by)
} }
className='inline pull-right'> className='inline pull-right'>
<button <button

View File

@ -12,20 +12,19 @@ let ListRequestActions = React.createClass({
]).isRequired, ]).isRequired,
currentUser: React.PropTypes.object.isRequired, currentUser: React.PropTypes.object.isRequired,
handleSuccess: React.PropTypes.func.isRequired, handleSuccess: React.PropTypes.func.isRequired,
requestActions: React.PropTypes.array.isRequired notifications: React.PropTypes.array.isRequired
}, },
render () { render () {
if (this.props.requestActions && if (this.props.notifications &&
this.props.requestActions.length > 0) { this.props.notifications.length > 0) {
return ( return (
<div> <div>
{this.props.requestActions.map((requestAction) => {this.props.notifications.map((notification) =>
<RequestActionForm <RequestActionForm
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
pieceOrEditions={ this.props.pieceOrEditions } pieceOrEditions={ this.props.pieceOrEditions }
requestAction={requestAction.action} notifications={notification}
requestUser={requestAction.by}
handleSuccess={this.props.handleSuccess}/>)} handleSuccess={this.props.handleSuccess}/>)}
</div> </div>
); );

View File

@ -1,82 +0,0 @@
'use strict';
import React from 'react';
import PrizeListActions from '../../actions/prize_list_actions';
import PrizeListStore from '../../stores/prize_list_store';
import Table from '../ascribe_table/table';
import TableItem from '../ascribe_table/table_item';
import TableItemText from '../ascribe_table/table_item_text';
import { ColumnModel} from '../ascribe_table/models/table_models';
import { getLangText } from '../../utils/lang_utils';
let PrizesDashboard = React.createClass({
getInitialState() {
return PrizeListStore.getState();
},
componentDidMount() {
PrizeListStore.listen(this.onChange);
PrizeListActions.fetchPrizeList();
},
componentWillUnmount() {
PrizeListStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
getColumnList() {
return [
new ColumnModel(
(item) => {
return {
'content': item.name
}; },
'name',
getLangText('Name'),
TableItemText,
6,
false,
null
),
new ColumnModel(
(item) => {
return {
'content': item.domain
}; },
'domain',
getLangText('Domain'),
TableItemText,
1,
false,
null
)
];
},
render() {
return (
<Table
responsive
className="ascribe-table"
columnList={this.getColumnList()}
itemList={this.state.prizeList}>
{this.state.prizeList.map((item, i) => {
return (
<TableItem
className="ascribe-table-item-selectable"
key={i}/>
);
})}
</Table>
);
}
});
export default PrizesDashboard;

View File

@ -6,15 +6,15 @@ import React from 'react';
let TableItemAclFiltered = React.createClass({ let TableItemAclFiltered = React.createClass({
propTypes: { propTypes: {
content: React.PropTypes.object, content: React.PropTypes.object,
requestAction: React.PropTypes.string notifications: React.PropTypes.string
}, },
render() { render() {
var availableAcls = ['acl_consign', 'acl_loan', 'acl_transfer', 'acl_view', 'acl_share', 'acl_unshare', 'acl_delete']; var availableAcls = ['acl_consign', 'acl_loan', 'acl_transfer', 'acl_view', 'acl_share', 'acl_unshare', 'acl_delete'];
if (this.props.requestAction && this.props.requestAction.length > 0){ if (this.props.notifications && this.props.notifications.length > 0){
return ( return (
<span> <span>
{this.props.requestAction[0].action + ' request pending'} {this.props.notifications[0].action_str}
</span> </span>
); );
} }

View File

@ -180,6 +180,19 @@ let NotificationListItem = React.createClass({
onClick(event){ onClick(event){
this.props.onClick(event); this.props.onClick(event);
}, },
getNotificationText(){
let numNotifications = null;
if (this.props.notification.length > 1){
numNotifications = <div>+ {this.props.notification.length - 1} more...</div>;
}
return (
<div className="notification-action">
{this.props.notification[0].action_str}
{numNotifications}
</div>);
},
render() { render() {
if (this.props.pieceOrEdition) { if (this.props.pieceOrEdition) {
return ( return (
@ -193,9 +206,7 @@ let NotificationListItem = React.createClass({
<div className="col-xs-8 notification-list-item-header"> <div className="col-xs-8 notification-list-item-header">
<h1>{this.props.pieceOrEdition.title}</h1> <h1>{this.props.pieceOrEdition.title}</h1>
<div className="sub-header">by {this.props.pieceOrEdition.artist_name}</div> <div className="sub-header">by {this.props.pieceOrEdition.artist_name}</div>
<div className="notification-action"> {this.getNotificationText()}
{'Pending ' + this.props.notification[0].action + ' request'}
</div>
</div> </div>
</div> </div>
</Link>); </Link>);

View File

@ -15,9 +15,6 @@ import PieceListActions from '../../../../../actions/piece_list_actions';
import PrizeRatingActions from '../../actions/prize_rating_actions'; import PrizeRatingActions from '../../actions/prize_rating_actions';
import PrizeRatingStore from '../../stores/prize_rating_store'; import PrizeRatingStore from '../../stores/prize_rating_store';
import NotificationStore from '../../../../../stores/notification_store';
import NotificationActions from '../../../../../actions/notification_actions.js';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import Piece from '../../../../../components/ascribe_detail/piece'; import Piece from '../../../../../components/ascribe_detail/piece';
@ -53,8 +50,7 @@ let PieceContainer = React.createClass({
getInitialState() { getInitialState() {
return mergeOptions( return mergeOptions(
PieceStore.getState(), PieceStore.getState(),
UserStore.getState(), UserStore.getState()
NotificationStore.getState()
); );
}, },
@ -62,8 +58,6 @@ let PieceContainer = React.createClass({
PieceStore.listen(this.onChange); PieceStore.listen(this.onChange);
PieceActions.fetchOne(this.props.params.pieceId); PieceActions.fetchOne(this.props.params.pieceId);
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
NotificationStore.listen(this.onChange);
NotificationActions.fetchPieceNotifications(this.props.params.pieceId);
}, },
// This is done to update the container when the user clicks on the prev or next // This is done to update the container when the user clicks on the prev or next
@ -83,7 +77,6 @@ let PieceContainer = React.createClass({
PieceActions.updatePiece({}); PieceActions.updatePiece({});
PieceStore.unlisten(this.onChange); PieceStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
NotificationStore.unlisten(this.onChange);
}, },
@ -97,14 +90,14 @@ let PieceContainer = React.createClass({
getActions() { getActions() {
if (this.state.piece && if (this.state.piece &&
this.state.pieceNotifications && this.state.piece.notifications &&
this.state.pieceNotifications.notification) { this.state.piece.notifications.length > 0) {
return ( return (
<ListRequestActions <ListRequestActions
pieceOrEditions={this.state.piece} pieceOrEditions={this.state.piece}
currentUser={this.state.currentUser} currentUser={this.state.currentUser}
handleSuccess={this.loadPiece} handleSuccess={this.loadPiece}
requestActions={this.state.pieceNotifications.notification}/>); notifications={this.state.piece.notifications}/>);
} }
}, },

View File

@ -10,9 +10,6 @@ import PieceListStore from '../../../../../../stores/piece_list_store';
import UserStore from '../../../../../../stores/user_store'; import UserStore from '../../../../../../stores/user_store';
import NotificationStore from '../../../../../../stores/notification_store';
import NotificationActions from '../../../../../../actions/notification_actions.js';
import Piece from '../../../../../../components/ascribe_detail/piece'; import Piece from '../../../../../../components/ascribe_detail/piece';
import ListRequestActions from '../../../../../ascribe_forms/list_form_request_actions'; import ListRequestActions from '../../../../../ascribe_forms/list_form_request_actions';
@ -44,8 +41,7 @@ let IkonotvPieceContainer = React.createClass({
return mergeOptions( return mergeOptions(
PieceStore.getState(), PieceStore.getState(),
UserStore.getState(), UserStore.getState(),
PieceListStore.getState(), PieceListStore.getState()
NotificationStore.getState()
); );
}, },
@ -54,8 +50,6 @@ let IkonotvPieceContainer = React.createClass({
PieceActions.fetchOne(this.props.params.pieceId); PieceActions.fetchOne(this.props.params.pieceId);
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
PieceListStore.listen(this.onChange); PieceListStore.listen(this.onChange);
NotificationStore.listen(this.onChange);
NotificationActions.fetchPieceNotifications(this.props.params.pieceId);
}, },
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
@ -74,7 +68,6 @@ let IkonotvPieceContainer = React.createClass({
PieceStore.unlisten(this.onChange); PieceStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
PieceListStore.unlisten(this.onChange); PieceListStore.unlisten(this.onChange);
NotificationStore.unlisten(this.onChange);
}, },
onChange(state) { onChange(state) {
@ -96,14 +89,14 @@ let IkonotvPieceContainer = React.createClass({
getActions(){ getActions(){
if (this.state.piece && if (this.state.piece &&
this.state.pieceNotifications && this.state.piece.notifications &&
this.state.pieceNotifications.notification) { this.state.piece.notifications.length > 0) {
return ( return (
<ListRequestActions <ListRequestActions
pieceOrEditions={this.state.piece} pieceOrEditions={this.state.piece}
currentUser={this.state.currentUser} currentUser={this.state.currentUser}
handleSuccess={this.loadPiece} handleSuccess={this.loadPiece}
requestActions={this.state.pieceNotifications.notification}/>); notifications={this.state.piece.notifications}/>);
} }
else { else {

View File

@ -22,7 +22,6 @@ import CoaVerifyContainer from './components/coa_verify_container';
import RegisterPiece from './components/register_piece'; import RegisterPiece from './components/register_piece';
import PrizesDashboard from './components/ascribe_prizes_dashboard/prizes_dashboard';
import AppConstants from './constants/application_constants'; import AppConstants from './constants/application_constants';
@ -45,7 +44,6 @@ const COMMON_ROUTES = (
<Route name="password_reset" path="password_reset" handler={PasswordResetContainer} /> <Route name="password_reset" path="password_reset" handler={PasswordResetContainer} />
<Route name="settings" path="settings" handler={SettingsContainer} /> <Route name="settings" path="settings" handler={SettingsContainer} />
<Route name="coa_verify" path="verify" handler={CoaVerifyContainer} /> <Route name="coa_verify" path="verify" handler={CoaVerifyContainer} />
<Route name="prizes" path="prizes" handler={PrizesDashboard} />
</Route> </Route>
); );

View File

@ -45,9 +45,15 @@ $break-medium: 1200px;
margin-top: 0.3em; margin-top: 0.3em;
margin-bottom: 0.15em; margin-bottom: 0.15em;
font-size: 1.8em; font-size: 1.8em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.sub-header{ .sub-header{
margin-bottom: 1em; margin-bottom: 0.6em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.notification-action{ .notification-action{
color: $ascribe-color-green; color: $ascribe-color-green;