netzke-basepack 0.4.2 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.autotest +1 -0
  2. data/.gitignore +6 -0
  3. data/{CHANGELOG → CHANGELOG.rdoc} +26 -0
  4. data/README.rdoc +11 -11
  5. data/Rakefile +37 -11
  6. data/TODO.rdoc +8 -0
  7. data/VERSION +1 -0
  8. data/javascripts/basepack.js +71 -28
  9. data/lib/app/models/netzke_auto_column.rb +56 -0
  10. data/lib/netzke-basepack.rb +5 -3
  11. data/lib/netzke/accordion_panel.rb +69 -67
  12. data/lib/netzke/active_record/basepack.rb +104 -0
  13. data/lib/netzke/active_record/data_accessor.rb +33 -0
  14. data/lib/netzke/basic_app.rb +233 -124
  15. data/lib/netzke/border_layout_panel.rb +97 -98
  16. data/lib/netzke/configuration_panel.rb +24 -0
  17. data/lib/netzke/data_accessor.rb +71 -0
  18. data/lib/netzke/ext.rb +6 -0
  19. data/lib/netzke/field_model.rb +1 -1
  20. data/lib/netzke/fields_configurator.rb +62 -37
  21. data/lib/netzke/form_panel.rb +161 -51
  22. data/lib/netzke/form_panel_api.rb +74 -0
  23. data/lib/netzke/form_panel_js.rb +129 -0
  24. data/lib/netzke/grid_panel.rb +385 -80
  25. data/lib/netzke/grid_panel_api.rb +352 -0
  26. data/lib/netzke/grid_panel_extras/javascripts/rows-dd.js +280 -0
  27. data/lib/netzke/grid_panel_js.rb +721 -0
  28. data/lib/netzke/masquerade_selector.rb +53 -0
  29. data/lib/netzke/panel.rb +9 -0
  30. data/lib/netzke/plugins/configuration_tool.rb +121 -0
  31. data/lib/netzke/property_editor.rb +95 -7
  32. data/lib/netzke/property_editor_extras/helper_model.rb +55 -34
  33. data/lib/netzke/search_panel.rb +62 -0
  34. data/lib/netzke/tab_panel.rb +97 -37
  35. data/lib/netzke/table_editor.rb +49 -44
  36. data/lib/netzke/tree_panel.rb +15 -16
  37. data/lib/netzke/wrapper.rb +29 -5
  38. data/netzke-basepack.gemspec +151 -19
  39. data/stylesheets/basepack.css +5 -0
  40. data/test/app_root/app/models/book.rb +1 -1
  41. data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +1 -1
  42. data/test/unit/accordion_panel_test.rb +1 -2
  43. data/test/unit/active_record_basepack_test.rb +54 -0
  44. data/test/unit/grid_panel_test.rb +8 -12
  45. data/test/unit/helper_model_test.rb +30 -0
  46. metadata +69 -78
  47. data/Manifest +0 -86
  48. data/TODO +0 -3
  49. data/lib/app/models/netzke_hash_record.rb +0 -180
  50. data/lib/app/models/netzke_layout_item.rb +0 -11
  51. data/lib/netzke/ar_ext.rb +0 -269
  52. data/lib/netzke/configuration_tool.rb +0 -80
  53. data/lib/netzke/container.rb +0 -77
  54. data/lib/netzke/db_fields.rb +0 -44
  55. data/lib/netzke/fields_configurator_old.rb +0 -62
  56. data/lib/netzke/form_panel_extras/interface.rb +0 -56
  57. data/lib/netzke/form_panel_extras/js_builder.rb +0 -134
  58. data/lib/netzke/grid_panel_extras/interface.rb +0 -206
  59. data/lib/netzke/grid_panel_extras/js_builder.rb +0 -352
  60. data/test/unit/ar_ext_test.rb +0 -53
  61. data/test/unit/netzke_hash_record_test.rb +0 -52
  62. data/test/unit/netzke_layout_item_test.rb +0 -28
@@ -1,80 +0,0 @@
1
- module Netzke
2
- #
3
- # Include this module into any widget if you want a "Properties" tool button in the top toolbar which will triggger a modal window, which will load the Accordion widgets, which in its turn will contain all the aggregatees specified in "configuration_widgets" method (*must* be defined)
4
- #
5
- module ConfigurationTool
6
- def self.included(base)
7
- base.extend ClassMethods
8
-
9
- base.class_eval do
10
- # replacing instance methods
11
- [:tools, :initial_aggregatees].each{ |m| alias_method_chain m, :properties }
12
-
13
- # replacing class methods
14
- class << self
15
- alias_method_chain :js_extend_properties, :properties
16
- end
17
- end
18
-
19
- # if you include ConfigurationTool, you must define configuration_widgets method which will returns an array of arrgeratees that will be included in the property window (each in its own tab or accordion pane)
20
- raise "configuration_widgets method undefined" unless base.instance_methods.include?("configuration_widgets")
21
- end
22
-
23
- module ClassMethods
24
- def js_extend_properties_with_properties
25
- js_extend_properties_without_properties.merge({
26
- :gear => <<-JS.l
27
- function(){
28
- var w = new Ext.Window({
29
- title:'Config',
30
- layout:'fit',
31
- modal:true,
32
- width: Ext.lib.Dom.getViewWidth() *0.9,
33
- height: Ext.lib.Dom.getViewHeight() *0.9,
34
- closeAction:'destroy',
35
- buttons:[{
36
- text:'Submit',
37
- handler:function(){
38
- this.ownerCt.closeRes = 'OK';
39
- this.ownerCt.close();
40
- }
41
- }]
42
-
43
- });
44
-
45
- w.show(null, function(){
46
- w.loadWidget(this.initialConfig.id+"__properties__get_widget");
47
- }, this);
48
-
49
- w.on('close', function(){
50
- if (w.closeRes == 'OK'){
51
- widget = this;
52
- if (widget.ownerCt) {
53
- widget.ownerCt.loadWidget(widget.initialConfig.interface.getWidget);
54
- } else {
55
- this.feedback('Reload current window'); // we are embedded directly in HTML
56
- }
57
- }
58
- }, this);
59
- }
60
- JS
61
- })
62
- end
63
- end
64
-
65
- def initial_aggregatees_with_properties
66
- res = initial_aggregatees_without_properties
67
- # Add the accordion as aggregatee, which in its turn aggregates widgets from the configuration_widgets method
68
- res.merge!(:properties => {:widget_class_name => 'TabPanel', :items => configuration_widgets, :ext_config => {:title => false}, :late_aggregation => true}) if config[:ext_config][:config_tool]
69
- res
70
- end
71
-
72
- def tools_with_properties
73
- tools = tools_without_properties
74
- # Add the toolbutton
75
- tools << 'gear' if config[:ext_config][:config_tool]
76
- tools
77
- end
78
-
79
- end
80
- end
@@ -1,77 +0,0 @@
1
- module Netzke
2
- #
3
- # Base class for Accordion and TabPanel widgets, it shouldn't be used as a stand-alone class.
4
- #
5
- class Container < Base
6
- def initialize(*args)
7
- super
8
- for item in initial_items do
9
- add_aggregatee item
10
- items << item.keys.first
11
- end
12
- end
13
-
14
- def initial_dependencies
15
- dep = super
16
- for item in items
17
- candidate_dependency = aggregatees[item][:widget_class_name]
18
- dep << candidate_dependency unless dep.include?(candidate_dependency)
19
- end
20
- dep
21
- end
22
-
23
- def self.js_before_constructor
24
- js_widget_items
25
- end
26
-
27
- def items
28
- @items ||= []
29
- end
30
-
31
- def initial_items
32
- config[:items] || []
33
- end
34
-
35
- def self.js_widget_items
36
- res = ""
37
- item_aggregatees.each_pair do |k,v|
38
- next if v[:late_aggregation]
39
- res << <<-JS
40
- var #{k.to_js} = new Ext.netzke.cache['#{v[:widget_class_name]}'](config.#{k.to_js}Config);
41
- JS
42
- end
43
- res
44
- end
45
-
46
- def self.js_items
47
- items.inject([]) do |a,i|
48
- a << {
49
- :title => i.to_s.humanize,
50
- :layout => 'fit',
51
- :id => i.to_s,
52
- :items => ([i.to_s.to_js.l] if !aggregatees[i][:late_aggregation]),
53
- :collapsed => !aggregatees[i][:active],
54
- :listeners => {
55
- :expand => {:fn => "this.loadItemWidget".l, :scope => this}
56
- }
57
- }
58
- end
59
- end
60
-
61
- def self.js_extend_properties
62
- {
63
- # loads widget into the panel if it's not loaded yet
64
- :load_item_widget => <<-JS.l,
65
- function(panel) {
66
- if (!panel.getWidget()) panel.loadWidget(this.id + "__" + panel.id + "__get_widget");
67
- }
68
- JS
69
- }
70
- end
71
-
72
- protected
73
- def self.item_aggregatees
74
- aggregatees.delete_if{|k,v| !@items.include?(k)}
75
- end
76
- end
77
- end
@@ -1,44 +0,0 @@
1
- module Netzke
2
- module DbFields
3
- #
4
- # Default fields for a widget of class GridPanel or FormPanel
5
- # It is a synthesis of 1) columns declared in the model, 2) columns provided in the configuration for the widget
6
- #
7
- def default_db_fields
8
- config[:data_class_name].nil? && raise(ArgumentError, "No data_class_name specified for widget #{config[:name]}")
9
-
10
- data_class = config[:data_class_name].constantize
11
- exposed_columns = normalize_columns(data_class.exposed_columns) # columns exposed from the data class
12
- columns_from_config = (config[:fields] || config[:columns]) && normalize_columns(config[:fields] || config[:columns]) # columns specified in widget's config
13
-
14
- if columns_from_config
15
- # reverse-merge each column hash from config with each column hash from exposed_columns (columns from config have higher priority)
16
- for c in columns_from_config
17
- corresponding_exposed_column = exposed_columns.find{ |k| k[:name] == c[:name] }
18
- c.reverse_merge!(corresponding_exposed_column) if corresponding_exposed_column
19
- end
20
- columns_for_create = columns_from_config
21
- else
22
- # we didn't have columns configured in widget's config, so, use the columns from the data class
23
- columns_for_create = exposed_columns
24
- end
25
-
26
- res = []
27
- for c in columns_for_create
28
- # finally reverse-merge them with the defaults from the data_class
29
- res << (self.class.widget_type == :grid ? data_class.default_column_config(c) : data_class.default_field_config(c))
30
- end
31
-
32
- res
33
- end
34
-
35
- protected
36
-
37
- # [:col1, {:name => :col2}, :col3]
38
- # => [{:name => :col1}, {:name => :col2}, {:name => :col3}]
39
- def normalize_columns(items)
40
- items.map{|c| c.is_a?(Symbol) ? {:name => c} : c}
41
- end
42
-
43
- end
44
- end
@@ -1,62 +0,0 @@
1
- module Netzke
2
- class FieldsConfigurator < GridPanel
3
- interface :load_defaults
4
-
5
- def self.js_base_class
6
- GridPanel
7
- end
8
-
9
- def initialize(*args)
10
- super
11
-
12
- config[:conditions] = {:layout_id => config[:layout].id}
13
- config[:data_class_name] = config[:layout].items_class
14
- # config[:persistent_layout] = false
15
- end
16
-
17
- def initial_config
18
- super.recursive_merge({
19
- :name => 'columns',
20
- :widget_class_name => "GridPanel",
21
- :ext_config => {:title => false}
22
- })
23
- end
24
-
25
- def actions
26
- super.merge(
27
- :defaults => {:text => 'Restore defaults'}
28
- )
29
- end
30
-
31
- def bbar
32
- super << "-" << "defaults"
33
- end
34
-
35
- def self.js_extend_properties
36
- super.merge({
37
- :defaults => <<-JS.l,
38
- function(){
39
- Ext.Msg.confirm('Confirm', 'Are you sure?', function(btn){
40
- if (btn == 'yes') {
41
- Ext.Ajax.request({
42
- url:this.initialConfig.interface.loadDefaults,
43
- callback:function(){
44
- this.store.reload();
45
- },
46
- scope:this
47
- })
48
- }
49
- }, this);
50
- }
51
- JS
52
- })
53
- end
54
-
55
- def load_defaults(params)
56
- NetzkeLayout.destroy(config[:layout].id)
57
- config[:data_class_name].constantize.create_layout_for_widget(parent.parent)
58
- {}
59
- end
60
-
61
- end
62
- end
@@ -1,56 +0,0 @@
1
- module Netzke
2
- module FormPanelExtras
3
- module Interface
4
- def submit(params)
5
- params.delete(:authenticity_token)
6
- params.delete(:controller)
7
- params.delete(:action)
8
-
9
- klass = config[:data_class_name].constantize
10
- record = klass.find_by_id(params[:id])
11
- success = true
12
-
13
- record = klass.new if record.nil?
14
-
15
- params.each_pair do |k,v|
16
- begin
17
- record.send("#{k}=",v)
18
- rescue StandardError => exc
19
- flash :error => exc.message
20
- success = false
21
- break
22
- end
23
- end
24
-
25
- if success && record.save
26
- {:data => [record.to_array(fields)], :success => true}
27
- else
28
- # flash eventual errors
29
- record.errors.each_full do |msg|
30
- flash :error => msg
31
- end
32
- {:success => false, :flash => @flash}
33
- end
34
- end
35
-
36
- def load(params)
37
- klass = config[:data_class_name].constantize
38
- case params[:neighbour]
39
- when "previous" then record = klass.previous(params[:id])
40
- when "next" then record = klass.next(params[:id])
41
- else record = klass.find(params[:id])
42
- end
43
- {:data => [record && record.to_array(fields)]}
44
- end
45
-
46
- # Return the choices for the column
47
- def get_cb_choices(params)
48
- column = params[:column]
49
- query = params[:query]
50
-
51
- {:data => config[:data_class_name].constantize.choices_for(column, query).map{|s| [s]}}
52
- end
53
-
54
- end
55
- end
56
- end
@@ -1,134 +0,0 @@
1
- module Netzke
2
- module FormPanelExtras
3
- module JsBuilder
4
- def self.included(base)
5
- base.extend ClassMethods
6
- end
7
-
8
- module ClassMethods
9
- def js_base_class
10
- "Ext.FormPanel"
11
- end
12
-
13
- def js_before_constructor
14
- <<-JS
15
- var fields = config.fields;
16
- var recordFields = [];
17
- var index = 0;
18
- Ext.each(fields, function(field){
19
- recordFields.push({
20
- name:field.name,
21
- mapping:index++
22
- });
23
- field.hideLabel = field.hidden; // completely hide fields marked "hidden"
24
- var extConfig;
25
- try{
26
- extConfig = Ext.decode(field.extConfig)
27
- }
28
- catch(err){
29
- extConfig = {}
30
- }
31
- delete(field.extConfig);
32
- Ext.apply(field, extConfig);
33
-
34
- field.parentConfig = config;
35
- field.fieldConfig = field;
36
- }, this);
37
- var Record = Ext.data.Record.create(recordFields);
38
- this.reader = new Ext.data.RecordArrayReader({root:"data"}, Record);
39
- JS
40
- end
41
-
42
- def js_default_config
43
- super.merge({
44
- :auto_scroll => true,
45
- :bbar => "config.actions".l,
46
- # :plugins => "plugins".l,
47
- :items => "fields".l,
48
- :default_type => 'textfield',
49
- :body_style => 'padding:5px 5px 0',
50
- :label_width => 150,
51
- :listeners => {
52
- :afterlayout => {
53
- :fn => "this.afterlayoutHandler".l,
54
- :scope => this
55
- }
56
- },
57
- :defaults => {
58
- # :anchor => '-20', # to leave some space for the scrollbar
59
- :width => 180,
60
- :listeners => {
61
- :specialkey => {
62
- :fn => <<-JS.l,
63
- function(field, event){
64
- if (event.getKey() == 13) this.apply();
65
- }
66
- JS
67
- :scope => this
68
- }
69
- }
70
- }
71
- })
72
- end
73
-
74
- def js_extend_properties
75
- {
76
- :load_record => <<-JS.l,
77
- function(id, neighbour){
78
- var proxy = new Ext.data.HttpProxy({url:this.initialConfig.interface.load});
79
- proxy.load({id:id, neighbour:neighbour}, this.reader, function(data){
80
- if (data){
81
- this.form.loadRecord(data.records[0])
82
- }
83
- }, this)
84
- }
85
- JS
86
- :afterlayout_handler => <<-JS.l,
87
- function() {
88
- // Load initial data into the form
89
- if (this.initialConfig.recordData){
90
- var record = this.reader.readRecord(this.initialConfig.recordData);
91
- this.form.loadRecord(record);
92
- }
93
- }
94
- JS
95
- :refresh=> <<-JS.l,
96
- function() {
97
- this.feedback('Implement me!');
98
- }
99
- JS
100
- :previous => <<-JS.l,
101
- function() {
102
- var currentId = this.form.getValues().id;
103
- this.loadRecord(currentId, 'previous');
104
- }
105
- JS
106
- :next => <<-JS.l,
107
- function() {
108
- var currentId = this.form.getValues().id;
109
- this.loadRecord(currentId, 'next');
110
- }
111
- JS
112
- :apply => <<-JS.l,
113
- function() {
114
- this.form.submit({
115
- url:this.initialConfig.interface.submit,
116
- success :function(form, action){
117
- if (action.result.flash) this.feedback(action.result.flash);
118
- this.form.loadRecord(this.reader.readRecord(action.result.data[0]));
119
- },
120
- failure :function(form, action){
121
- this.feedback(action.result.flash)
122
- },
123
- scope :this
124
- })
125
- }
126
- JS
127
- }
128
- end
129
-
130
- end
131
-
132
- end
133
- end
134
- end