mirror of
https://github.com/flarum/core.git
synced 2025-05-07 16:05:25 +02:00
Add alert messages
This commit is contained in:
parent
b18534882b
commit
0552cae1ab
@ -1,9 +1,44 @@
|
|||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
import TaggedArray from '../utils/tagged-array';
|
||||||
|
import ActionButton from 'flarum/components/ui/controls/action-button';
|
||||||
|
|
||||||
close: function() {
|
export default Ember.Component.extend(Ember.Evented, {
|
||||||
this.sendAction('closeAction');
|
message: '',
|
||||||
|
type: '',
|
||||||
|
dismissable: true,
|
||||||
|
|
||||||
|
layoutName: 'components/alert-message',
|
||||||
|
classNames: ['alert'],
|
||||||
|
classNameBindings: ['classForType'],
|
||||||
|
|
||||||
|
classForType: function() {
|
||||||
|
return 'alert-'+this.get('type');
|
||||||
|
}.property('type'),
|
||||||
|
|
||||||
|
didInsertElement: function() {
|
||||||
|
var controls = TaggedArray.create();
|
||||||
|
this.trigger('populateControls', controls);
|
||||||
|
this.set('controls', controls);
|
||||||
|
},
|
||||||
|
|
||||||
|
populateControls: function(controls) {
|
||||||
|
if (this.get('dismissable')) {
|
||||||
|
var component = this;
|
||||||
|
var dismiss = ActionButton.create({
|
||||||
|
icon: 'times',
|
||||||
|
className: 'btn btn-icon btn-link',
|
||||||
|
action: function() {
|
||||||
|
component.send('dismiss');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
controls.pushObjectWithTag(dismiss, 'dismiss');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
dismiss: function() {
|
||||||
|
this.sendAction('dismiss', this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -27,9 +27,20 @@ export default Ember.Controller.extend({
|
|||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
searchActive: false,
|
searchActive: false,
|
||||||
|
|
||||||
|
alerts: [],
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
search: function(query) {
|
search: function(query) {
|
||||||
this.transitionToRoute('index', {queryParams: {searchQuery: query, sort: query ? 'relevance' : 'recent'}});
|
this.transitionToRoute('index', {queryParams: {searchQuery: query, sort: query ? 'relevance' : 'recent'}});
|
||||||
|
},
|
||||||
|
alert: function(message) {
|
||||||
|
this.get('alerts').pushObject(message);
|
||||||
|
},
|
||||||
|
dismissAlert: function(message) {
|
||||||
|
this.get('alerts').removeObject(message);
|
||||||
|
},
|
||||||
|
clearAlerts: function() {
|
||||||
|
this.get('alerts').clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import Ember from 'ember';
|
|||||||
import PostStream from '../models/post-stream';
|
import PostStream from '../models/post-stream';
|
||||||
import ComposerReply from '../components/discussions/composer-reply';
|
import ComposerReply from '../components/discussions/composer-reply';
|
||||||
import ActionButton from '../components/ui/controls/action-button';
|
import ActionButton from '../components/ui/controls/action-button';
|
||||||
|
import AlertMessage from '../components/alert-message';
|
||||||
|
|
||||||
export default Ember.ObjectController.extend(Ember.Evented, {
|
export default Ember.ObjectController.extend(Ember.Evented, {
|
||||||
|
|
||||||
@ -40,35 +41,62 @@ export default Ember.ObjectController.extend(Ember.Evented, {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Save a reply. This may be called by a composer-reply component that was
|
||||||
|
// set up on a different discussion, so we require a discussion model to
|
||||||
|
// be explicitly passed rather than using the controller's implicit one.
|
||||||
saveReply: function(discussion, content) {
|
saveReply: function(discussion, content) {
|
||||||
var controller = this;
|
var controller = this;
|
||||||
var composer = this.get('controllers.composer');
|
var composer = this.get('controllers.composer');
|
||||||
var stream = this.get('stream');
|
var stream = this.get('stream');
|
||||||
|
|
||||||
composer.set('content.loading', true);
|
composer.set('content.loading', true);
|
||||||
|
controller.get('controllers.application').send('clearAlerts');
|
||||||
|
|
||||||
var post = this.store.createRecord('post', {
|
var post = this.store.createRecord('post', {
|
||||||
content: content,
|
content: content,
|
||||||
discussion: discussion
|
discussion: discussion
|
||||||
});
|
});
|
||||||
|
|
||||||
var promise = post.save().then(function(post) {
|
return post.save().then(function(post) {
|
||||||
if (discussion == controller.get('model')) {
|
|
||||||
discussion.set('posts', discussion.get('posts')+','+post.get('id'));
|
|
||||||
stream.set('ids', controller.get('model.postIds'));
|
|
||||||
stream.addPostToEnd(post);
|
|
||||||
}
|
|
||||||
composer.send('hide');
|
composer.send('hide');
|
||||||
}, function(reason) {
|
|
||||||
var error = reason.errors[0].detail;
|
|
||||||
alert(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
promise.finally(function() {
|
// If we're currently viewing the discussion which this reply was
|
||||||
|
// made in, then we can add the post to the end of the post
|
||||||
|
// stream.
|
||||||
|
discussion.set('posts', discussion.get('posts')+','+post.get('id'));
|
||||||
|
if (discussion == controller.get('model')) {
|
||||||
|
stream.set('ids', discussion.get('postIds'));
|
||||||
|
stream.addPostToEnd(post);
|
||||||
|
} else {
|
||||||
|
// Otherwise, we'll create an alert message to inform the user
|
||||||
|
// that their reply has been posted, containing a button which
|
||||||
|
// will transition to their new post when clicked.
|
||||||
|
var message = AlertMessage.create({
|
||||||
|
type: 'success',
|
||||||
|
message: 'Your reply was posted.'
|
||||||
|
});
|
||||||
|
message.on('populateControls', function(controls) {
|
||||||
|
controls.pushObjectWithTag(ActionButton.extend({
|
||||||
|
label: 'View',
|
||||||
|
action: function() {
|
||||||
|
controller.transitionToRoute('discussion', post.get('discussion'), {queryParams: {start: post.get('number')}});
|
||||||
|
message.send('dismiss');
|
||||||
|
}
|
||||||
|
}), 'view');
|
||||||
|
});
|
||||||
|
controller.get('controllers.application').send('alert', message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(reason) {
|
||||||
|
var message = AlertMessage.create({
|
||||||
|
type: 'warning',
|
||||||
|
message: reason.errors[0].detail
|
||||||
|
});
|
||||||
|
controller.get('controllers.application').send('alert', message);
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
composer.set('content.loading', false);
|
composer.set('content.loading', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
return promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -76,15 +104,19 @@ export default Ember.ObjectController.extend(Ember.Evented, {
|
|||||||
var controller = this;
|
var controller = this;
|
||||||
var discussion = this.get('model');
|
var discussion = this.get('model');
|
||||||
var composer = this.get('controllers.composer');
|
var composer = this.get('controllers.composer');
|
||||||
|
|
||||||
|
// If the composer is already set up for this discussion, then we
|
||||||
|
// don't need to change its content - we can just show it.
|
||||||
if (composer.get('content.discussion') != discussion) {
|
if (composer.get('content.discussion') != discussion) {
|
||||||
composer.switchContent(ComposerReply.create({
|
composer.switchContent(ComposerReply.create({
|
||||||
user: controller.get('session.user'),
|
user: controller.get('session.user'),
|
||||||
discussion: discussion,
|
discussion: discussion,
|
||||||
submit: function(value) {
|
submit: function(value) {
|
||||||
controller.saveReply(this.get('discussion'), value);
|
controller.saveReply(discussion, value);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
composer.send('show');
|
composer.send('show');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
// Finally, with our vendor CSS loaded, we can import Flarum-specific stuff.
|
// Finally, with our vendor CSS loaded, we can import Flarum-specific stuff.
|
||||||
@import "@{flarum-base}components.less";
|
@import "@{flarum-base}components.less";
|
||||||
|
@import "@{flarum-base}alerts.less";
|
||||||
@import "@{flarum-base}modals.less";
|
@import "@{flarum-base}modals.less";
|
||||||
@import "@{flarum-base}layout.less";
|
@import "@{flarum-base}layout.less";
|
||||||
@import "@{flarum-base}composer.less";
|
@import "@{flarum-base}composer.less";
|
||||||
|
57
ember/app/styles/flarum/alerts.less
Normal file
57
ember/app/styles/flarum/alerts.less
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
.alerts {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 20px;
|
||||||
|
|
||||||
|
& .alert {
|
||||||
|
display: inline-block;
|
||||||
|
.box-shadow(0 2px 6px rgba(0, 0, 0, 0.3));
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert {
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: @border-radius-base;
|
||||||
|
background: #FFF2AE;
|
||||||
|
&, & a, & a:hover {
|
||||||
|
color: #AD6C00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert-warning {
|
||||||
|
background: #D83E3E;
|
||||||
|
&, & a, & a:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.alert-controls {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 -8px 0 8px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
& li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
& a {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
& .btn {
|
||||||
|
margin: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-group { // probably move this elsewhere
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.form-alert {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
& .alert {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,12 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.btn-user {
|
||||||
|
& .avatar {
|
||||||
|
margin: -2px 5px -2px -5px;
|
||||||
|
.avatar-size(24px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Redefine Bootstrap's mixin to make some general changes
|
// Redefine Bootstrap's mixin to make some general changes
|
||||||
.button-variant(@color; @background; @border) {
|
.button-variant(@color; @background; @border) {
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
.modal-login {
|
|
||||||
& .form-group {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.form-group {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.form-alert {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 100%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
& .alert {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.alert-warning {
|
|
||||||
background: #D83E3E;
|
|
||||||
.box-shadow(0 2px 6px rgba(0, 0, 0, 0.3));
|
|
||||||
color: #fff;
|
|
||||||
padding: 12px 16px;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-user {
|
|
||||||
& .avatar {
|
|
||||||
margin: -2px 5px -2px -5px;
|
|
||||||
.avatar-size(24px);
|
|
||||||
}
|
|
||||||
}
|
|
@ -51,6 +51,8 @@
|
|||||||
|
|
||||||
<div class="alerts">
|
<div class="alerts">
|
||||||
{{#each alert in alerts}}
|
{{#each alert in alerts}}
|
||||||
{{alert-message message=alert}}
|
<div class="alert-wrapper">
|
||||||
|
{{view alert dismiss="dismissAlert"}}
|
||||||
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
@ -1,9 +1,2 @@
|
|||||||
<div {{bind-attr class=":alert alert.class"}}>
|
<span class="alert-text">{{message}}</span>
|
||||||
<span class="alert-text">{{alert.text}}</span>
|
{{ui/controls/item-list items=controls class="alert-controls"}}
|
||||||
<span class="alert-actions">
|
|
||||||
<a href="#">Undo</a> <!-- menu -->
|
|
||||||
{{#if alert.dismissable}}
|
|
||||||
<a href="#" {{action "close"}}>{{fa-icon "times"}}</a>
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
Loading…
x
Reference in New Issue
Block a user