netzke-basepack 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -1
- data/CHANGELOG.rdoc +13 -0
- data/README.rdoc +18 -9
- data/Rakefile +6 -7
- data/TODO.rdoc +4 -2
- data/javascripts/basepack.js +32 -1
- data/lib/app/models/netzke_auto_column.rb +2 -2
- data/lib/netzke-basepack.rb +2 -1
- data/lib/netzke/accordion_panel.rb +6 -4
- data/lib/netzke/basic_app.rb +222 -231
- data/lib/netzke/border_layout_panel.rb +4 -2
- data/lib/netzke/fields_configurator.rb +2 -2
- data/lib/netzke/form_panel.rb +6 -4
- data/lib/netzke/form_panel_api.rb +20 -16
- data/lib/netzke/form_panel_extras/javascripts/netzkefileupload.js +5 -0
- data/lib/netzke/form_panel_js.rb +26 -7
- data/lib/netzke/grid_panel.rb +31 -10
- data/lib/netzke/grid_panel_api.rb +46 -40
- data/lib/netzke/grid_panel_extras/record_form_window.rb +46 -0
- data/lib/netzke/grid_panel_js.rb +9 -32
- data/lib/netzke/property_editor.rb +1 -1
- data/lib/netzke/property_editor_extras/helper_model.rb +2 -6
- data/lib/netzke/tab_panel.rb +5 -4
- data/lib/netzke/table_editor.rb +1 -1
- data/lib/netzke/tree_panel.rb +1 -1
- data/lib/netzke/window.rb +77 -0
- data/lib/netzke/wrapper.rb +1 -1
- data/test/unit/accordion_panel_test.rb +1 -1
- data/test/unit/grid_panel_test.rb +11 -2
- data/test/unit/tab_panel_test.rb +1 -1
- metadata +8 -6
- data/VERSION +0 -1
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
= v0.5.5.1 - 2009-11-09
|
2
|
+
* Compatibility with latest netzke-core
|
3
|
+
|
4
|
+
= v0.5.5 - 2009-11-09
|
5
|
+
* Compatibility with latest netzke-core
|
6
|
+
* Regression: pressing "enter" was not submitting the form (FormPanel)
|
7
|
+
* Regression: "Restore defaults" button was not working in FieldsConfigurator and PropertyEditor
|
8
|
+
* Fix: excluding columns in FieldConfigurator was causing inconsistent column behavior (move/hide/resize)
|
9
|
+
* Fix: resolving conflicts with Ext.form.FormPanel's <tt>submit</tt> and <tt>load</tt> methods
|
10
|
+
* New: rudimentary FileUploadField support in FormPanel (it will do a normal, non-AJAX, form submit)
|
11
|
+
* New: Netzke::Window widget, supports persistent moving/resizing.
|
12
|
+
* New: (experimental) GridPanel's "Add in form" button now opens the new Window widget. Later all other windows will be slowly rewritten to do the same.
|
13
|
+
|
1
14
|
= v0.5.4 - 2009-10-12
|
2
15
|
* Dependencies updated
|
3
16
|
|
data/README.rdoc
CHANGED
@@ -5,35 +5,44 @@ Note that if you would like to modify this code or experiment with it, you may b
|
|
5
5
|
|
6
6
|
= Prerequisites
|
7
7
|
1. Rails >= 2.2
|
8
|
-
2. Ext JS >= 3.0: its root
|
8
|
+
2. Ext JS >= 3.0: its root by default must be accessible as RAILS_ROOT/public/extjs. You may symlink your Ext JS library here like this (from your app folder):
|
9
|
+
|
9
10
|
cd public && ln -s ~/Developer/extjs/ext-3.0 extjs
|
10
11
|
|
11
12
|
3. acts_as_list plugin must be installed:
|
12
|
-
./script/plugin install git://github.com/rails/acts_as_list.git
|
13
13
|
|
14
|
-
|
15
|
-
gem sources -a http://gems.github.com/
|
16
|
-
sudo gem install mislav-will_paginate
|
14
|
+
./script/plugin install git://github.com/rails/acts_as_list.git
|
17
15
|
|
18
16
|
= Installation
|
19
|
-
|
17
|
+
The gem is hosted on gemcutter. If you haven't yet enabled gemcutter, run the following:
|
18
|
+
|
19
|
+
sudo gem install gemcutter && gem tumble
|
20
|
+
|
21
|
+
Install the gem:
|
22
|
+
|
20
23
|
gem install netzke-basepack
|
21
24
|
|
22
25
|
Include it into environment.rb:
|
26
|
+
|
23
27
|
config.gem "netzke-basepack"
|
24
28
|
|
25
29
|
Include mapping for Netzke controller providing *.js and *.css (in routes.rb):
|
30
|
+
|
26
31
|
map.netzke
|
27
32
|
|
28
33
|
= Usage
|
29
34
|
First, run the generators to have the necessary migrations:
|
35
|
+
|
30
36
|
./script/generate netzke_core
|
31
37
|
|
32
38
|
Do the migrations:
|
39
|
+
|
33
40
|
rake db:migrate
|
34
41
|
|
35
42
|
The following example will provide you with a grid-based scaffold for ActiveRecord-model called Book. You may generate it like this:
|
43
|
+
|
36
44
|
./script/generate model Book title:string amount:integer
|
45
|
+
|
37
46
|
(don't forget to re-run the migrations after it)
|
38
47
|
|
39
48
|
In the controller declare the widget:
|
@@ -57,7 +66,7 @@ Declaring a widget in the controller provides you with a couple of helpers that
|
|
57
66
|
|
58
67
|
1. books_class_definition will contain the JavaScript code defining the code for the JS class.
|
59
68
|
2. books_widget_instance will declare a local JavaScript variable called 'book'.
|
60
|
-
3. books_widget_render will provide the JavaScript code that calls the "render" method on the variable declared by books_widget_instance.
|
69
|
+
3. books_widget_render will provide the JavaScript code that calls the "render" method on the variable declared by books_widget_instance; the widget will be rendered into a div with id "books-div".
|
61
70
|
|
62
71
|
Use these helpers inside of the script-tag like the following (in the view):
|
63
72
|
|
@@ -68,7 +77,7 @@ Use these helpers inside of the script-tag like the following (in the view):
|
|
68
77
|
<%= books_widget_render %>
|
69
78
|
})
|
70
79
|
</script>
|
71
|
-
<div id="books">the widget will be rendered in this div</div>
|
80
|
+
<div id="books-div">the widget will be rendered in this div</div>
|
72
81
|
|
73
82
|
If your layout already calls yield :javascripts wrapped in the <script>-tag, you can have all javascript-code in one place on the page:
|
74
83
|
|
@@ -80,7 +89,7 @@ If your layout already calls yield :javascripts wrapped in the <script>-tag, you
|
|
80
89
|
})
|
81
90
|
<% end %>
|
82
91
|
<p>... your page content here ...</p>
|
83
|
-
<div id="books">the widget will be rendered in this div</div>
|
92
|
+
<div id="books-div">the widget will be rendered in this div</div>
|
84
93
|
|
85
94
|
== Dynamic loading of widgets
|
86
95
|
TODO: this part will be covered later
|
data/Rakefile
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
3
|
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.version = "0.5.5"
|
4
5
|
gemspec.name = "netzke-basepack"
|
5
|
-
gemspec.summary = "Pre-built
|
6
|
-
gemspec.description = "
|
6
|
+
gemspec.summary = "Pre-built Rails + ExtJS widgets for your RIA"
|
7
|
+
gemspec.description = "A set of full-featured extendible Netzke widgets (such as FormPanel, GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for your RIA"
|
7
8
|
gemspec.email = "sergei@playcode.nl"
|
8
9
|
gemspec.homepage = "http://github.com/skozlov/netzke-basepack"
|
9
10
|
gemspec.rubyforge_project = "netzke-basepack"
|
10
11
|
gemspec.authors = ["Sergei Kozlov"]
|
11
|
-
gemspec.add_dependency("netzke-core", ">=0.4.
|
12
|
+
gemspec.add_dependency("netzke-core", ">=0.4.5.2")
|
12
13
|
gemspec.add_dependency("searchlogic", ">=2.0.0")
|
13
14
|
gemspec.add_dependency("will_paginate", ">=2.0.0")
|
14
15
|
end
|
15
|
-
Jeweler::
|
16
|
-
rubyforge.doc_task = "rdoc"
|
17
|
-
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
18
17
|
rescue LoadError
|
19
|
-
puts "Jeweler not available. Install it with: sudo gem install
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
19
|
end
|
21
20
|
|
22
21
|
require 'rake/rdoctask'
|
data/TODO.rdoc
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
== Priority
|
2
|
-
* Make column/fields configuration fool-proof
|
3
2
|
* Introduce three-state checkbox for SearchPanel
|
4
3
|
* Add icons to buttons to actions (toolbars/menus)
|
5
4
|
* On grid refresh, reset the dirty fields, so that the "Apply" button doesn't do anything
|
6
5
|
|
6
|
+
== Foolproof
|
7
|
+
* Should not be possible delete the "ID" field from grids/forms
|
8
|
+
|
7
9
|
== Optimizations
|
8
|
-
*
|
10
|
+
* Check persistent_config-related queries (aren't they too many?)
|
9
11
|
|
10
12
|
== One day
|
11
13
|
* Replace xcheckbox with checkbox in FormPanel
|
data/javascripts/basepack.js
CHANGED
@@ -794,4 +794,35 @@ Ext.grid.HeaderDropZone.prototype.onNodeDrop = function(n, dd, e, data){
|
|
794
794
|
return true;
|
795
795
|
}
|
796
796
|
return false;
|
797
|
-
}
|
797
|
+
}
|
798
|
+
|
799
|
+
// Feedback Ghost
|
800
|
+
Netzke.FeedbackGhost = function(){};
|
801
|
+
Ext.apply(Netzke.FeedbackGhost.prototype, {
|
802
|
+
showFeedback: function(msg){
|
803
|
+
var createBox = function(s, l){
|
804
|
+
return ['<div class="msg">',
|
805
|
+
'<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
|
806
|
+
'<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">', s, '</div></div></div>',
|
807
|
+
'<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
|
808
|
+
'</div>'].join('');
|
809
|
+
}
|
810
|
+
|
811
|
+
var showBox = function(msg, lvl){
|
812
|
+
if (!lvl) {lvl = 'notice'};
|
813
|
+
var msgCt = Ext.DomHelper.insertFirst(document.body, {'class':'netzke-feedback'}, true);
|
814
|
+
var m = Ext.DomHelper.append(msgCt, {html:createBox(msg,lvl)}, true);
|
815
|
+
m.slideIn('t').pause(2).ghost("b", {remove:true});
|
816
|
+
}
|
817
|
+
|
818
|
+
if (typeof msg != 'string') {
|
819
|
+
var compoundMsg = "";
|
820
|
+
Ext.each(msg, function(m){
|
821
|
+
compoundMsg += m.msg + '<br>';
|
822
|
+
});
|
823
|
+
if (compoundMsg != "") showBox(compoundMsg, null); // the second parameter will be level
|
824
|
+
} else {
|
825
|
+
showBox(msg);
|
826
|
+
}
|
827
|
+
}
|
828
|
+
});
|
@@ -48,9 +48,9 @@ class NetzkeAutoColumn < ActiveRecord::Base
|
|
48
48
|
|
49
49
|
def self.widget=(widget)
|
50
50
|
@@widget = widget
|
51
|
-
if Netzke::Base.session["netzke_auto_column_last_widget"] != @@widget.
|
51
|
+
if Netzke::Base.session["netzke_auto_column_last_widget"] != @@widget.global_id
|
52
52
|
rebuild_table
|
53
|
-
Netzke::Base.session["netzke_auto_column_last_widget"] = @@widget.
|
53
|
+
Netzke::Base.session["netzke_auto_column_last_widget"] = @@widget.global_id
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
data/lib/netzke-basepack.rb
CHANGED
@@ -19,4 +19,5 @@ ActiveSupport::Dependencies.load_once_paths.delete(File.join(File.dirname(__FILE
|
|
19
19
|
# Include javascript & styles required by all basepack widgets.
|
20
20
|
# These files will get loaded at the initial load of the framework (along with Ext and Netzke-core).
|
21
21
|
Netzke::Base.config[:javascripts] << "#{File.dirname(__FILE__)}/../javascripts/basepack.js"
|
22
|
-
Netzke::Base.config[:stylesheets] << "#{File.dirname(__FILE__)}/../stylesheets/basepack.css"
|
22
|
+
Netzke::Base.config[:stylesheets] << "#{File.dirname(__FILE__)}/../stylesheets/basepack.css"
|
23
|
+
Netzke::Base.config[:stylesheets] << Netzke::Base.config[:ext_location] + "/examples/form/file-upload.css"
|
@@ -16,7 +16,7 @@ module Netzke
|
|
16
16
|
:defaults => {:layout => 'fit'},
|
17
17
|
:init_component => <<-END_OF_JAVASCRIPT.l,
|
18
18
|
function(){
|
19
|
-
|
19
|
+
#{js_full_class_name}.superclass.initComponent.call(this);
|
20
20
|
|
21
21
|
// Set events
|
22
22
|
this.items.each(function(i){
|
@@ -26,7 +26,8 @@ module Netzke
|
|
26
26
|
// If not collapsed, add the active aggregatee (item) into it
|
27
27
|
if (!i.collapsed) {
|
28
28
|
var preloadedItemConfig = this[i.widget.camelize(true) + "Config"];
|
29
|
-
|
29
|
+
var klass = this.classifyScopedName(preloadedItemConfig.scopedClassName);
|
30
|
+
i.add(new klass(preloadedItemConfig));
|
30
31
|
i.doLayout(); // always needed after adding a component
|
31
32
|
}
|
32
33
|
}, this);
|
@@ -41,7 +42,8 @@ module Netzke
|
|
41
42
|
|
42
43
|
if (preloadedItemConfig){
|
43
44
|
// preloaded widget only needs to be instantiated, as its class and configuration have already been loaded
|
44
|
-
|
45
|
+
var klass = this.classifyScopedName(preloadedItemConfig.scopedClassName);
|
46
|
+
panel.add(new klass(preloadedItemConfig));
|
45
47
|
panel.doLayout(); // always needed after adding a component
|
46
48
|
} else {
|
47
49
|
// load the widget from the server
|
@@ -89,7 +91,7 @@ module Netzke
|
|
89
91
|
res = []
|
90
92
|
config[:items].each_with_index do |item, i|
|
91
93
|
res << {
|
92
|
-
# :id => item[:active] &&
|
94
|
+
# :id => item[:active] && global_id + '_active', # to mark the fit-panel which will contain the active widget
|
93
95
|
:title => item[:title] || (item[:name] && item[:name].to_s.humanize),
|
94
96
|
:widget => item[:name], # to know which fit panel will load which widget
|
95
97
|
:collapsed => !(item[:active] || false)
|
data/lib/netzke/basic_app.rb
CHANGED
@@ -11,233 +11,246 @@ module Netzke
|
|
11
11
|
# * masquerade support
|
12
12
|
# * AJAX activity indicator
|
13
13
|
class BasicApp < Base
|
14
|
-
|
14
|
+
def self.include_js
|
15
|
+
res = []
|
16
|
+
ext_examples = Netzke::Base.config[:ext_location] + "/examples/"
|
17
|
+
res << ext_examples + "ux/StatusBar.js"
|
18
|
+
res << "#{File.dirname(__FILE__)}/basic_app_extras/statusbar_ext.js"
|
19
|
+
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
def self.js_base_class
|
22
|
+
"Ext.Viewport"
|
23
|
+
end
|
19
24
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
masq = %Q{user "#{user.login}"}
|
45
|
-
elsif session[:masq_role]
|
46
|
-
role = Role.find(session[:masq_role])
|
47
|
-
masq = %Q{role "#{role.name}"}
|
48
|
-
elsif session[:masq_world]
|
49
|
-
masq = %Q{World}
|
50
|
-
end
|
51
|
-
|
52
|
-
[{
|
53
|
-
:id => 'main-panel',
|
54
|
-
:region => 'center',
|
55
|
-
:layout => 'fit'
|
56
|
-
},{
|
57
|
-
:id => 'main-toolbar',
|
58
|
-
:xtype => 'toolbar',
|
59
|
-
:region => 'north',
|
60
|
-
:height => 25
|
61
|
-
# :items => ["-"]
|
62
|
-
},{
|
63
|
-
:id => 'main-statusbar',
|
64
|
-
:xtype => 'statusbar',
|
65
|
-
:region => 'south',
|
66
|
-
:height => 22,
|
67
|
-
:statusAlign => 'right',
|
68
|
-
:busyText => 'Busy...',
|
69
|
-
:default_text => masq.nil? ? "Ready #{"(config mode)" if session[:config_mode]}" : "Masquerading as #{masq}",
|
70
|
-
:default_icon_cls => ""
|
71
|
-
}]
|
25
|
+
# Global BasicApp configuration
|
26
|
+
def self.config
|
27
|
+
set_default_config({
|
28
|
+
:logout_url => "/logout" # default logout url
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# def self.include_css
|
34
|
+
# res = []
|
35
|
+
# res << Netzke::Base.config[:ext_location] + "/examples/ux/css/StatusBar.css"
|
36
|
+
# res
|
37
|
+
# end
|
38
|
+
|
39
|
+
def self.js_panels
|
40
|
+
# In status bar we want to show what we are masquerading as
|
41
|
+
if session[:masq_user]
|
42
|
+
user = User.find(session[:masq_user])
|
43
|
+
masq = %Q{user "#{user.login}"}
|
44
|
+
elsif session[:masq_role]
|
45
|
+
role = Role.find(session[:masq_role])
|
46
|
+
masq = %Q{role "#{role.name}"}
|
47
|
+
elsif session[:masq_world]
|
48
|
+
masq = %Q{World}
|
72
49
|
end
|
73
|
-
|
74
|
-
def js_extend_properties
|
75
|
-
{
|
76
|
-
:layout => 'border',
|
77
|
-
|
78
|
-
:panels => js_panels,
|
79
|
-
|
80
|
-
:init_component => <<-END_OF_JAVASCRIPT.l,
|
81
|
-
function(){
|
82
|
-
this.items = this.panels; // a bit weird, but working; can't assign it straight
|
83
50
|
|
84
|
-
|
51
|
+
[{
|
52
|
+
:id => 'main-panel',
|
53
|
+
:region => 'center',
|
54
|
+
:layout => 'fit'
|
55
|
+
},{
|
56
|
+
:id => 'main-toolbar',
|
57
|
+
:xtype => 'toolbar',
|
58
|
+
:region => 'north',
|
59
|
+
:height => 25
|
60
|
+
# :items => ["-"]
|
61
|
+
},{
|
62
|
+
:id => 'main-statusbar',
|
63
|
+
:xtype => 'statusbar',
|
64
|
+
:region => 'south',
|
65
|
+
:height => 22,
|
66
|
+
:statusAlign => 'right',
|
67
|
+
:busyText => 'Busy...',
|
68
|
+
:default_text => masq.nil? ? "Ready #{"(config mode)" if session[:config_mode]}" : "Masquerading as #{masq}",
|
69
|
+
:default_icon_cls => ""
|
70
|
+
}]
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.js_extend_properties
|
74
|
+
{
|
75
|
+
:layout => 'border',
|
85
76
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
}
|
77
|
+
:panels => js_panels,
|
78
|
+
|
79
|
+
:init_component => <<-END_OF_JAVASCRIPT.l,
|
80
|
+
function(){
|
81
|
+
this.items = this.panels; // a bit weird, but working; can't assign it straight
|
82
|
+
|
83
|
+
#{js_full_class_name}.superclass.initComponent.call(this);
|
94
84
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
this.
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
Ext.Ajax.on('requestcomplete', function(){this.findById('main-statusbar').hideBusy()}, this);
|
103
|
-
Ext.Ajax.on('requestexception', function(){this.findById('main-statusbar').hideBusy()}, this);
|
85
|
+
// If we are given a token, load the corresponding widget, otherwise load the last loaded widget
|
86
|
+
var currentToken = Ext.History.getToken();
|
87
|
+
if (currentToken != "") {
|
88
|
+
this.processHistory(currentToken);
|
89
|
+
} else {
|
90
|
+
var lastLoaded = this.initialConfig.widgetToLoad; // passed from the server
|
91
|
+
if (lastLoaded) Ext.History.add(lastLoaded);
|
104
92
|
}
|
105
|
-
END_OF_JAVASCRIPT
|
106
|
-
|
107
|
-
:host_menu => <<-END_OF_JAVASCRIPT.l,
|
108
|
-
function(menu, owner){
|
109
|
-
var toolbar = this.findById('main-toolbar');
|
110
|
-
if (!this.menus[owner.id]) this.menus[owner.id] = [];
|
111
|
-
Ext.each(menu, function(item) {
|
112
|
-
// var newMenu = new Ext.Toolbar.Button(item);
|
113
|
-
// var position = toolbar.items.getCount() - 2;
|
114
|
-
// position = position < 0 ? 0 : position;
|
115
|
-
// toolbar.insertButton(position, newMenu);
|
116
93
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
94
|
+
Ext.History.on('change', this.processHistory, this);
|
95
|
+
|
96
|
+
// Hosted menus
|
97
|
+
this.menus = {};
|
98
|
+
|
99
|
+
// Setting the "busy" indicator for Ajax requests
|
100
|
+
Ext.Ajax.on('beforerequest', function(){this.findById('main-statusbar').showBusy()}, this);
|
101
|
+
Ext.Ajax.on('requestcomplete', function(){this.findById('main-statusbar').hideBusy()}, this);
|
102
|
+
Ext.Ajax.on('requestexception', function(){this.findById('main-statusbar').hideBusy()}, this);
|
103
|
+
|
104
|
+
// Initialize history
|
105
|
+
Ext.History.init();
|
106
|
+
}
|
107
|
+
END_OF_JAVASCRIPT
|
108
|
+
|
109
|
+
:host_menu => <<-END_OF_JAVASCRIPT.l,
|
110
|
+
function(menu, owner){
|
111
|
+
var toolbar = this.findById('main-toolbar');
|
112
|
+
if (!this.menus[owner.id]) this.menus[owner.id] = [];
|
113
|
+
Ext.each(menu, function(item) {
|
114
|
+
// var newMenu = new Ext.Toolbar.Button(item);
|
115
|
+
// var position = toolbar.items.getCount() - 2;
|
116
|
+
// position = position < 0 ? 0 : position;
|
117
|
+
// toolbar.insertButton(position, newMenu);
|
122
118
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
// toolbar.items.remove(menu); // remove the item from the toolbar
|
129
|
-
// menu.destroy(); // ... and destroy it
|
130
|
-
// });
|
131
|
-
// }
|
132
|
-
}
|
133
|
-
END_OF_JAVASCRIPT
|
119
|
+
toolbar.add(item);
|
120
|
+
// this.menus[owner.id].push(newMenu); // TODO: remember the menus from this owner in some other way
|
121
|
+
}, this);
|
122
|
+
}
|
123
|
+
END_OF_JAVASCRIPT
|
134
124
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
125
|
+
:unhost_menu => <<-END_OF_JAVASCRIPT.l,
|
126
|
+
function(owner){
|
127
|
+
// var toolbar = this.findById('main-toolbar');
|
128
|
+
// if (this.menus[owner.id]) {
|
129
|
+
// Ext.each(this.menus[owner.id], function(menu){
|
130
|
+
// toolbar.items.remove(menu); // remove the item from the toolbar
|
131
|
+
// menu.destroy(); // ... and destroy it
|
132
|
+
// });
|
133
|
+
// }
|
134
|
+
}
|
135
|
+
END_OF_JAVASCRIPT
|
140
136
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
function(config){
|
153
|
-
this.findById('main-panel').instantiateChild(config);
|
154
|
-
}
|
155
|
-
END_OF_JAVASCRIPT
|
156
|
-
|
157
|
-
# Loads widget by name
|
158
|
-
:app_load_widget => <<-END_OF_JAVASCRIPT.l,
|
159
|
-
function(name){
|
160
|
-
Ext.History.add(name);
|
161
|
-
}
|
162
|
-
END_OF_JAVASCRIPT
|
137
|
+
:on_login => <<-END_OF_JAVASCRIPT.l,
|
138
|
+
function(){
|
139
|
+
window.location = "/login"
|
140
|
+
}
|
141
|
+
END_OF_JAVASCRIPT
|
142
|
+
|
143
|
+
:on_logout => <<-END_OF_JAVASCRIPT.l,
|
144
|
+
function(){
|
145
|
+
window.location = "#{config[:logout_url]}"
|
146
|
+
}
|
147
|
+
END_OF_JAVASCRIPT
|
163
148
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
149
|
+
# Event handler for history change
|
150
|
+
:process_history => <<-END_OF_JAVASCRIPT.l,
|
151
|
+
function(token){
|
152
|
+
if (token){
|
153
|
+
this.loadAggregatee({id:token, container:'main-panel'});
|
154
|
+
} else {
|
155
|
+
Ext.getCmp('main-panel').removeChild();
|
168
156
|
}
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
157
|
+
}
|
158
|
+
END_OF_JAVASCRIPT
|
159
|
+
|
160
|
+
:instantiate_aggregatee => <<-END_OF_JAVASCRIPT.l,
|
161
|
+
function(config){
|
162
|
+
this.findById('main-panel').instantiateChild(config);
|
163
|
+
}
|
164
|
+
END_OF_JAVASCRIPT
|
165
|
+
|
166
|
+
# Loads widget by name
|
167
|
+
:app_load_widget => <<-END_OF_JAVASCRIPT.l,
|
168
|
+
function(name){
|
169
|
+
Ext.History.add(name);
|
170
|
+
}
|
171
|
+
END_OF_JAVASCRIPT
|
172
|
+
|
173
|
+
# Loads widget by action
|
174
|
+
:load_widget_by_action => <<-END_OF_JAVASCRIPT.l,
|
175
|
+
function(action){
|
176
|
+
this.appLoadWidget(action.widget || action.name);
|
177
|
+
}
|
178
|
+
END_OF_JAVASCRIPT
|
179
|
+
|
180
|
+
:on_toggle_config_mode => <<-END_OF_JAVASCRIPT.l,
|
181
|
+
function(){
|
182
|
+
this.toggleConfigMode();
|
183
|
+
}
|
184
|
+
END_OF_JAVASCRIPT
|
185
|
+
|
186
|
+
|
187
|
+
# Masquerade selector window
|
188
|
+
:show_masquerade_selector => <<-END_OF_JAVASCRIPT.l
|
189
|
+
function(){
|
190
|
+
var w = new Ext.Window({
|
191
|
+
title: 'Masquerade as',
|
192
|
+
modal: true,
|
193
|
+
width: Ext.lib.Dom.getViewWidth() * 0.6,
|
194
|
+
height: Ext.lib.Dom.getViewHeight() * 0.6,
|
195
|
+
layout: 'fit',
|
196
|
+
closeAction :'destroy',
|
197
|
+
buttons: [{
|
198
|
+
text: 'Select',
|
199
|
+
handler : function(){
|
200
|
+
if (role = w.getWidget().masquerade.role) {
|
201
|
+
Ext.Msg.confirm("Masquerading as a role", "Individual preferences for all users with this role will get overwritten as you make changes. Continue?", function(btn){
|
202
|
+
if (btn === 'yes') {
|
201
203
|
w.close();
|
202
204
|
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
scope:this
|
206
|
-
},{
|
207
|
-
text:'No masquerading',
|
208
|
-
handler:function(){
|
209
|
-
this.masquerade = {};
|
205
|
+
});
|
206
|
+
} else {
|
210
207
|
w.close();
|
211
|
-
}
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
208
|
+
}
|
209
|
+
},
|
210
|
+
scope:this
|
211
|
+
},{
|
212
|
+
text:'As World',
|
213
|
+
handler:function(){
|
214
|
+
Ext.Msg.confirm("Masquerading as World", "Caution! All settings that you will modify will be overwritten for all roles and all users. Are you sure you know what you're doing?", function(btn){
|
215
|
+
if (btn === "yes") {
|
216
|
+
this.masquerade = {world:true};
|
217
|
+
w.close();
|
218
|
+
}
|
219
|
+
}, this);
|
220
|
+
},
|
221
|
+
scope:this
|
222
|
+
},{
|
223
|
+
text:'No masquerading',
|
224
|
+
handler:function(){
|
225
|
+
this.masquerade = {};
|
226
|
+
w.close();
|
227
|
+
},
|
228
|
+
scope:this
|
229
|
+
},{
|
230
|
+
text:'Cancel',
|
231
|
+
handler:function(){
|
232
|
+
w.hide();
|
233
|
+
},
|
234
|
+
scope:this
|
235
|
+
}],
|
236
|
+
listeners : {close: {fn: function(){
|
237
|
+
this.masqueradeAs(this.masquerade || w.getWidget().masquerade || {});
|
238
|
+
}, scope: this}}
|
239
|
+
});
|
224
240
|
|
225
|
-
|
226
|
-
|
227
|
-
|
241
|
+
w.show(null, function(){
|
242
|
+
this.loadAggregatee({id:"masqueradeSelector", container:w.id})
|
243
|
+
}, this);
|
228
244
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
end
|
245
|
+
}
|
246
|
+
END_OF_JAVASCRIPT
|
247
|
+
}
|
233
248
|
end
|
234
249
|
|
235
|
-
extend ClassMethods
|
236
|
-
|
237
250
|
# Set the Logout button if Netzke::Base.user is set
|
238
251
|
def menu
|
239
252
|
res = []
|
240
|
-
user =
|
253
|
+
user = User.find_by_id(session[:netzke_user_id])
|
241
254
|
if !user.nil?
|
242
255
|
user_name = user.respond_to?(:name) ? user.name : user.login # try to display user's name, fallback to login
|
243
256
|
res << "->" <<
|
@@ -246,22 +259,13 @@ module Netzke
|
|
246
259
|
:menu => user_menu
|
247
260
|
}
|
248
261
|
else
|
249
|
-
res << "->" <<
|
250
|
-
{
|
251
|
-
:text => "Login",
|
252
|
-
:handler => <<-END_OF_JAVASCRIPT.l,
|
253
|
-
function(){
|
254
|
-
window.location = "/login"
|
255
|
-
}
|
256
|
-
END_OF_JAVASCRIPT
|
257
|
-
:scope => this
|
258
|
-
}
|
262
|
+
res << "->" << :login
|
259
263
|
end
|
260
264
|
res
|
261
265
|
end
|
262
266
|
|
263
267
|
def user_menu
|
264
|
-
[
|
268
|
+
[:logout]
|
265
269
|
end
|
266
270
|
|
267
271
|
def initialize(*args)
|
@@ -281,8 +285,9 @@ module Netzke
|
|
281
285
|
def actions
|
282
286
|
{
|
283
287
|
:masquerade_selector => {:text => "Masquerade as ...", :fn => "showMasqueradeSelector"},
|
284
|
-
:toggle_config_mode => {:text => "#{session[:config_mode] ? "Leave" : "Enter"} config mode"
|
285
|
-
:
|
288
|
+
:toggle_config_mode => {:text => "#{session[:config_mode] ? "Leave" : "Enter"} config mode"},
|
289
|
+
:login => {:text => "Login"},
|
290
|
+
:logout => {:text => "Logout"}
|
286
291
|
}
|
287
292
|
end
|
288
293
|
|
@@ -297,20 +302,6 @@ module Netzke
|
|
297
302
|
}
|
298
303
|
end
|
299
304
|
|
300
|
-
# We rely on the FeedbackGhost (to not need to implement our own feedback management)
|
301
|
-
def initial_aggregatees
|
302
|
-
{:feedback_ghost => {:widget_class_name => "FeedbackGhost"}}
|
303
|
-
end
|
304
|
-
|
305
|
-
# Besides instantiating ourselves, also instantiate the FeedbackGhost
|
306
|
-
def js_widget_instance
|
307
|
-
<<-END_OF_JAVASCRIPT << super
|
308
|
-
new Ext.netzke.cache['FeedbackGhost']({id:'feedback_ghost'})
|
309
|
-
// Initialize history (can't say why it's not working well inside the appLoaded handler)
|
310
|
-
Ext.History.init();
|
311
|
-
END_OF_JAVASCRIPT
|
312
|
-
end
|
313
|
-
|
314
305
|
#
|
315
306
|
# Interface section
|
316
307
|
#
|