Skip to content

Commit

Permalink
Rework notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Max Gorin committed Dec 25, 2015
1 parent 4f1a738 commit ba29bd6
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 94 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@

action :do_something, :do_something_else

* `netzkeNotify` (former `netzkeFeedback`) may now accept the `title` option

### Backward incompatible changes
* `netzkeFeedback` has been renamed to `netzkeNotify`

* `Core.js_feedback_delay` has been renamed to `Core.client_notification_delay`

* `js_configure` method has been renamed to `configure_client`

* Specifying bbar and other toolbars in `configure_client` (former `js_configure`) no longer works. Move this to
Expand Down
57 changes: 24 additions & 33 deletions javascripts/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ Ext.define("Netzke.Core.Component", {
},

/**
* This distinguishes Netzke components from regular Ext JS components.
* This is `true` for all Netzke components.
* @property isNetzke
* @type boolean
* @default true
*/
isNetzke: true,

// Component used for notifications (to be reworked)
feedbackGhost: Ext.create("Netzke.FeedbackGhost"),
/**
* Override this property globally if you to use a custom notifier class.
* @property netzkeNotifier
* @type Netzke.Notifier
*/
netzkeNotifier: Ext.create('Netzke.Notifier'),

/**
* Called before constructor. Implements all kinds of Netzke component initializations. Override as needed.
Expand Down Expand Up @@ -384,7 +387,7 @@ Ext.define("Netzke.Core.Component", {
* Dynamically loads child Netzke component
* @method netzkeLoadComponent
* @param {String} name Component name as declared in the Ruby class with `component` DSL
* @param {Object} [config] May contain the following optional keys:
* @param {Object} [params] May contain the following optional keys:
* * **container** {Ext.container.Container|Integer}
*
* The instance (or id) of a container with the "fit" layout where the loaded component will be added to; the previously existing component will be destroyed
Expand Down Expand Up @@ -461,7 +464,7 @@ Ext.define("Netzke.Core.Component", {
* @method netzkeHandleLoadingError
*/
netzkeHandleLoadingError: function(error){
this.netzkeFeedback(error);
this.netzkeNotify(error);
},

/**
Expand Down Expand Up @@ -493,7 +496,7 @@ Ext.define("Netzke.Core.Component", {
*/
netzkeHandleLoadingResponse: function(container, result, params){
if (result.error) {
this.netzkeFeedback(result.error);
this.netzkeNotify(result.error);
} else {
this.netzkeProcessDeliveredComponent(container, result, params);
}
Expand Down Expand Up @@ -624,45 +627,33 @@ Ext.define("Netzke.Core.Component", {
},

/**
* Returns *instantiated* child component by its relative path, which may contain the 'parent' part to walk _up_ the hierarchy
* Returns *instantiated* child component by its relative path
* @method netzkeGetComponent
* @param id {String} If empty, returns `this`
* @param path {String} Component path, which may contain the 'parent' for walking up the hierarchy, e.g.
* `parent__sibling`. If this is empty, the method will return `this`.
*/
netzkeGetComponent: function(id){
if (id === "") {return this};
id = id.underscore();
var split = id.split("__"), res;
netzkeGetComponent: function(path){
if (path === "") {return this};
path = path.underscore();
var split = path.split("__"), res;
if (split[0] === 'parent') {
split.shift();
var childInParentScope = split.join("__");
res = this.netzkeGetParentComponent().netzkeGetComponent(childInParentScope);
} else {
res = Ext.getCmp(this.id+"__"+id);
res = Ext.getCmp(this.id+"__"+path);
}
return res;
},

/**
* Provides a visual feedback.
* @method netzkeFeedback
* @param {String|Array|Object} msg Can be a string, an array of strings, an object in form {msg: 'Message'}, or an array of such objects.
* Triggers a notification unless `quiet` config option is `true`.
* @method netzkeNotify
* @param {String} msg Notification body
* @param {Object} options Notification options (such as `title`, `delay`)
*/
netzkeFeedback: function(msg, options){
if (this.initialConfig && this.initialConfig.quiet) return false;

options = options || {};

if (typeof msg == 'string'){ msg = [msg]; }

var feedback = "";

Ext.each(msg, function(m){
feedback += (m.msg || m) + "<br/>"
});

if (feedback != "") {
this.feedbackGhost.showFeedback(feedback, {delay: options.delay});
}
netzkeNotify: function(msg, options){
if (this.quiet !== true) this.netzkeNotifier.msg(msg, options);
},

/**
Expand Down
65 changes: 38 additions & 27 deletions javascripts/notifications.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
// FeedbackGhost is a little class that displays unified feedback from Netzke components.
Ext.define('Netzke.FeedbackGhost', {
showFeedback: function(msg, options){
options = options || {};
options.delay = options.delay || Netzke.Core.FeedbackDelay;
if (Ext.isObject(msg)) {
this.msg(msg.level.camelize(), msg.msg, options.delay);
} else if (Ext.isArray(msg)) {
Ext.each(msg, function(m) { this.showFeedback(m); }, this);
} else {
this.msg(null, msg, options.delay); // no header for now
}
},
/**
* Class creating simple notifications. Borrowed from http://dev.sencha.com/extjs/5.1.0/examples/shared/examples.js
* @class Netzke.Notifier
*/
Ext.define('Netzke.Notifier', function(){
var msgCt;

function createBox(t, s){
return t ?
'<div class="msg ' + Ext.baseCSSPrefix + 'border-box"><h3>' + t + '</h3><p>' + s + '</p></div>'
:
'<div class="msg ' + Ext.baseCSSPrefix + 'border-box"><p>' + s + '</p></div>';
}


return {
/**
* Shows notification on the screen.
* @method msg
* @param {String} msg Notification body HTML
* @param {Object} options May contain the following keys:
*
* * **title** - title of notification
* * **delay** (ms) - time notification should stay on the screen
*/
msg: function(msg, options){
if (options == undefined) options = {};

msg: function(title, format, delay){
if(!this.msgCt){
this.msgCt = Ext.core.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
if (Ext.isArray(msg)) {
msg = msg.join("<br>")
}
var s = Ext.String.format.apply(String, Array.prototype.slice.call(arguments, 1));
var m = Ext.core.DomHelper.append(this.msgCt, this.createBox(title, s), true);
m.hide();
m.slideIn('t').ghost("t", { delay: delay, remove: true});
},

createBox: function(t, s){
if (t) {
return '<div class="msg"><h3>' + t + '</h3><p>' + s + '</p></div>';
} else {
return '<div class="msg"><p>' + s + '</p></div>';
if (msgCt) {
document.body.appendChild(msgCt.dom);
} else {
msgCt = Ext.DomHelper.append(document.body, {id:'msg-div'}, true);
}
var m = Ext.DomHelper.append(msgCt, createBox(options.title, msg), true);
m.hide();
m.slideIn('t').ghost("t", { delay: options.delay || Netzke.Core.NotificationDelay, remove: true});
}
}
};
});
4 changes: 2 additions & 2 deletions lib/netzke/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ module Core
@@js_direct_max_retries = 0

# Amount of time feedback delay is being shown
mattr_accessor :js_feedback_delay
@@js_feedback_delay = 2000
mattr_accessor :client_notification_delay
@@client_notification_delay = 2000

mattr_accessor :with_icons

Expand Down
2 changes: 1 addition & 1 deletion lib/netzke/core/dynamic_assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def initial_dynamic_javascript(form_authenticity_token)
Netzke.ControllerUrl = '#{url_root}#{Rails.application.routes.url_helpers.netzke_path}/';
Netzke.RelativeExtUrl = '#{url_root}#{Netzke::Core.ext_uri}';
Netzke.Core.directMaxRetries = #{Netzke::Core.js_direct_max_retries};
Netzke.Core.FeedbackDelay = #{Netzke::Core.js_feedback_delay};
Netzke.Core.NotificationDelay = #{Netzke::Core.client_notification_delay};
)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/netzke/core/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def has_endpoint?(endpoint)
# Called when the method_missing tries to processes a non-existing component. Override when needed.
# Note: this should actually never happen unless you mess up with Netzke component loading mechanisms.
def component_missing(missing_component, *params)
client.netzke_feedback "Unknown component '#{missing_component}' in '#{name}'"
client.netzke_notify "Unknown component '#{missing_component}' in '#{name}'"
end

private
Expand Down
15 changes: 15 additions & 0 deletions spec/features/javascripts/notifier_spec.js.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
describe "Notifier component", ->
it "fires various notifications", (done) ->
click button "Notify"
expectToSee somewhere "Local feedback"
expectToSee somewhere "Local notification"

click button "Multiple notify"
expectToSee somewhere "Line one"
expectToSee somewhere "Line two"

click button "Server notify"
wait ->
expectToSee somewhere "Message from server"
expectToSee somewhere "Server notification"
done()
27 changes: 0 additions & 27 deletions spec/rails_app/app/components/feedback.rb

This file was deleted.

Empty file.
14 changes: 14 additions & 0 deletions spec/rails_app/app/components/notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Notifier < Netzke::Base
action :notify
action :multiple_notify
action :server_notify

def configure(c)
super
c.bbar = [:notify, :multiple_notify, :server_notify]
end

endpoint :notify do
client.netzke_notify("Message from server", delay: 3000, title: 'Server notification')
end
end
13 changes: 13 additions & 0 deletions spec/rails_app/app/components/notifier/client/notifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
handleNotify: function(){
this.netzkeNotify('Local' + ' feedback', {title: 'Local' + ' notification'});
},

handleServerNotify: function(){
this.server.notify();
},

handleMultipleNotify: function(){
this.netzkeNotify(['Line' + ' one', 'Line' + ' two']);
}
}
2 changes: 1 addition & 1 deletion spec/rails_app/config/initializers/netzke.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
config.ext_javascripts << "#{File.dirname(__FILE__)}/javascripts/session_expiration.js"

# feedback delay
# config.js_feedback_delay = 2000
# config.client_notification_delay = 2000
end

ConfigurableOnClassLevel.title = "Overridden"
Expand Down
4 changes: 2 additions & 2 deletions stylesheets/core.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This file gets loaded along with the rest of Ext library at the initial load
*/

/* FeedbackGhost */
/* NetzkeNotifier */
.msg .x-box-mc {
font-size:14px;
}
Expand All @@ -29,4 +29,4 @@ This file gets loaded along with the rest of Ext library at the initial load
}
#msg-div .msg p {
margin: 0;
}
}

0 comments on commit ba29bd6

Please sign in to comment.