diff --git a/ghost/admin/app.js b/ghost/admin/app.js
index b7160f4698..a3cfa02189 100755
--- a/ghost/admin/app.js
+++ b/ghost/admin/app.js
@@ -1,6 +1,7 @@
import Resolver from 'ember/resolver';
import initFixtures from 'ghost/fixtures/init';
import {currentUser, injectCurrentUser} from 'ghost/initializers/current-user';
+import {registerNotifications, injectNotifications} from 'ghost/initializers/notifications';
import 'ghost/utils/link-view';
import 'ghost/utils/text-field';
@@ -21,5 +22,7 @@ initFixtures();
App.initializer(currentUser);
App.initializer(injectCurrentUser);
+App.initializer(registerNotifications);
+App.initializer(injectNotifications);
export default App;
diff --git a/ghost/admin/components/ghost-notification.js b/ghost/admin/components/ghost-notification.js
new file mode 100644
index 0000000000..26e442f774
--- /dev/null
+++ b/ghost/admin/components/ghost-notification.js
@@ -0,0 +1,21 @@
+var NotificationComponent = Ember.Component.extend({
+ classNames: ['js-bb-notification'],
+
+ didInsertElement: function () {
+ var self = this;
+
+ self.$().on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function (event) {
+ /* jshint unused: false */
+ self.notifications.removeObject(self.get('message'));
+ });
+ },
+
+ actions: {
+ closeNotification: function () {
+ var self = this;
+ self.notifications.removeObject(self.get('message'));
+ }
+ }
+});
+
+export default NotificationComponent;
\ No newline at end of file
diff --git a/ghost/admin/components/ghost-notifications.js b/ghost/admin/components/ghost-notifications.js
new file mode 100644
index 0000000000..8533234c25
--- /dev/null
+++ b/ghost/admin/components/ghost-notifications.js
@@ -0,0 +1,7 @@
+var NotificationsComponent = Ember.Component.extend({
+ tagName: 'aside',
+ classNames: 'notifications',
+ messages: Ember.computed.alias('notifications')
+});
+
+export default NotificationsComponent;
\ No newline at end of file
diff --git a/ghost/admin/initializers/notifications.js b/ghost/admin/initializers/notifications.js
new file mode 100644
index 0000000000..554818fda4
--- /dev/null
+++ b/ghost/admin/initializers/notifications.js
@@ -0,0 +1,21 @@
+import Notifications from 'ghost/utils/notifications';
+
+var registerNotifications = {
+ name: 'registerNotifications',
+
+ initialize: function (container, application) {
+ application.register('notifications:main', Notifications);
+ }
+};
+
+var injectNotifications = {
+ name: 'injectNotifications',
+
+ initialize: function (container, application) {
+ application.inject('controller', 'notifications', 'notifications:main');
+ application.inject('component', 'notifications', 'notifications:main');
+ application.inject('route', 'notifications', 'notifications:main');
+ }
+};
+
+export {registerNotifications, injectNotifications};
\ No newline at end of file
diff --git a/ghost/admin/routes/application.js b/ghost/admin/routes/application.js
index a7403b0b4c..e625d5b6ee 100644
--- a/ghost/admin/routes/application.js
+++ b/ghost/admin/routes/application.js
@@ -18,6 +18,17 @@ var ApplicationRoute = Ember.Route.extend({
outlet: 'modal',
parentView: 'application'
});
+ },
+
+ handleErrors: function (errors) {
+ this.notifications.clear();
+ errors.forEach(function (errorObj) {
+ this.notifications.showError(errorObj.message || errorObj);
+
+ if (errorObj.hasOwnProperty('el')) {
+ errorObj.el.addClass('input-error');
+ }
+ });
}
}
});
diff --git a/ghost/admin/routes/signin.js b/ghost/admin/routes/signin.js
index ed4da83e91..3adbe6b175 100644
--- a/ghost/admin/routes/signin.js
+++ b/ghost/admin/routes/signin.js
@@ -23,7 +23,9 @@ var SigninRoute = Ember.Route.extend(styleBody, {
}
);
} else {
- window.alert('Must enter email + passwort. Todo: Must show as notification'); // Todo Show notification
+ this.notifications.clear();
+
+ this.notifications.showError('Must enter email + password');
}
}
}
diff --git a/ghost/admin/templates/application.hbs b/ghost/admin/templates/application.hbs
index 94e993d2f8..bbcced109b 100644
--- a/ghost/admin/templates/application.hbs
+++ b/ghost/admin/templates/application.hbs
@@ -3,7 +3,8 @@
{{/unless}}
+ {{ghost-notifications}}
+
{{outlet}}
-
{{outlet modal}}
\ No newline at end of file
diff --git a/ghost/admin/templates/components/ghost-notification.hbs b/ghost/admin/templates/components/ghost-notification.hbs
new file mode 100644
index 0000000000..5492303702
--- /dev/null
+++ b/ghost/admin/templates/components/ghost-notification.hbs
@@ -0,0 +1,4 @@
+
+ {{message.message}}
+ Close
+
\ No newline at end of file
diff --git a/ghost/admin/templates/components/ghost-notifications.hbs b/ghost/admin/templates/components/ghost-notifications.hbs
new file mode 100644
index 0000000000..c69fd54f25
--- /dev/null
+++ b/ghost/admin/templates/components/ghost-notifications.hbs
@@ -0,0 +1,3 @@
+{{#each messages}}
+ {{ghost-notification message=this}}
+{{/each}}
\ No newline at end of file
diff --git a/ghost/admin/utils/notifications.js b/ghost/admin/utils/notifications.js
new file mode 100644
index 0000000000..beb2190b3b
--- /dev/null
+++ b/ghost/admin/utils/notifications.js
@@ -0,0 +1,38 @@
+var Notifications = Ember.ArrayProxy.extend({
+ content: Ember.A(),
+ timeout: 3000,
+ pushObject: function (object) {
+ object.typeClass = 'notification-' + object.type;
+ // This should be somewhere else.
+ if (object.type === 'success') {
+ object.typeClass = object.typeClass + " notification-passive";
+ }
+ this._super(object);
+ },
+ showError: function (message) {
+ this.pushObject({
+ type: 'error',
+ message: message
+ });
+ },
+ showInfo: function (message) {
+ this.pushObject({
+ type: 'info',
+ message: message
+ });
+ },
+ showSuccess: function (message) {
+ this.pushObject({
+ type: 'success',
+ message: message
+ });
+ },
+ showWarn: function (message) {
+ this.pushObject({
+ type: 'warn',
+ message: message
+ });
+ }
+});
+
+export default Notifications;
\ No newline at end of file