netzke-basepack 0.5.14 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. data/.gitignore +3 -2
  2. data/CHANGELOG.rdoc +15 -0
  3. data/README.rdoc +45 -50
  4. data/Rakefile +8 -8
  5. data/TODO.rdoc +1 -6
  6. data/app/components/netzke/basepack/accordion_panel.rb +37 -0
  7. data/app/components/netzke/basepack/basic_app.rb +267 -0
  8. data/{lib/netzke → app/components/netzke/basepack}/basic_app/statusbar_ext.js +0 -0
  9. data/app/components/netzke/basepack/border_layout_panel.rb +39 -0
  10. data/app/components/netzke/basepack/form_panel.rb +102 -0
  11. data/app/components/netzke/basepack/form_panel/fields.rb +206 -0
  12. data/{lib/netzke → app/components/netzke/basepack}/form_panel/javascripts/netzkefileupload.js +0 -0
  13. data/app/components/netzke/basepack/form_panel/javascripts/pre.js +76 -0
  14. data/{lib/netzke → app/components/netzke/basepack}/form_panel/javascripts/xcheckbox.js +0 -0
  15. data/app/components/netzke/basepack/form_panel/services.rb +99 -0
  16. data/app/components/netzke/basepack/grid_panel.rb +374 -0
  17. data/app/components/netzke/basepack/grid_panel/columns.rb +233 -0
  18. data/app/components/netzke/basepack/grid_panel/javascript.rb +69 -0
  19. data/app/components/netzke/basepack/grid_panel/javascripts/advanced_search.js +96 -0
  20. data/{lib/netzke → app/components/netzke/basepack}/grid_panel/javascripts/edit_in_form.js +5 -4
  21. data/{lib/netzke/grid_panel/javascripts/grid_panel_pre.js → app/components/netzke/basepack/grid_panel/javascripts/pre.js} +17 -37
  22. data/{lib/netzke → app/components/netzke/basepack}/grid_panel/javascripts/rows-dd.js +0 -0
  23. data/app/components/netzke/basepack/grid_panel/multi_edit_form.rb +16 -0
  24. data/app/components/netzke/basepack/grid_panel/record_form_window.rb +36 -0
  25. data/app/components/netzke/basepack/grid_panel/search_window.rb +56 -0
  26. data/app/components/netzke/basepack/grid_panel/services.rb +356 -0
  27. data/app/components/netzke/basepack/panel.rb +11 -0
  28. data/app/components/netzke/basepack/search_panel.rb +59 -0
  29. data/app/components/netzke/basepack/tab_panel.rb +32 -0
  30. data/app/components/netzke/basepack/window.rb +73 -0
  31. data/app/components/netzke/basepack/wrapper.rb +28 -0
  32. data/{lib/app → app}/models/netzke_field_list.rb +1 -1
  33. data/{lib/app → app}/models/netzke_model_attr_list.rb +0 -0
  34. data/{lib/app → app}/models/netzke_persistent_array_auto_model.rb +0 -0
  35. data/config/database.yml +35 -0
  36. data/features/accordion_panel.feature +15 -0
  37. data/features/basic_app.feature +12 -0
  38. data/features/form_panel.feature +40 -0
  39. data/features/grid_panel.feature +62 -0
  40. data/features/search_in_grid.feature +35 -0
  41. data/features/simple_panel.feature +15 -0
  42. data/features/step_definitions/accordion_steps.rb +9 -0
  43. data/features/step_definitions/generic_steps.rb +15 -0
  44. data/features/step_definitions/grid_panel_steps.rb +26 -0
  45. data/features/step_definitions/pickle_steps.rb +100 -0
  46. data/features/step_definitions/web_steps.rb +219 -0
  47. data/features/support/env.rb +66 -0
  48. data/features/support/paths.rb +59 -0
  49. data/features/support/pickle.rb +25 -0
  50. data/features/tab_panel.feature +15 -0
  51. data/features/window.feature +11 -0
  52. data/from_05_to_06.rdoc +2 -0
  53. data/javascripts/basepack.js +54 -2
  54. data/lib/netzke-basepack.rb +38 -25
  55. data/lib/netzke/active_record.rb +12 -4
  56. data/lib/netzke/active_record/attributes.rb +60 -5
  57. data/lib/netzke/active_record/combobox_options.rb +3 -2
  58. data/lib/netzke/active_record/relation_extensions.rb +35 -0
  59. data/lib/netzke/basepack.rb +27 -0
  60. data/lib/netzke/basepack/version.rb +11 -0
  61. data/lib/netzke/basepack/wrap_lazy_loaded.rb +26 -0
  62. data/lib/netzke/data_accessor.rb +60 -32
  63. data/lib/netzke/fields_configurator.rb +5 -9
  64. data/lib/netzke/masquerade_selector.rb +1 -1
  65. data/locale/en.yml +16 -0
  66. data/netzke-basepack.gemspec +298 -0
  67. data/spec/active_record/attributes_spec.rb +14 -0
  68. data/spec/active_record/relation_extensions_spec.rb +44 -0
  69. data/spec/components/form_panel_spec.rb +70 -0
  70. data/spec/components/grid_panel_spec.rb +10 -0
  71. data/spec/factories.rb +9 -0
  72. data/spec/spec_helper.rb +35 -0
  73. data/test/rails_app/.gitignore +4 -0
  74. data/test/rails_app/Gemfile +32 -0
  75. data/test/rails_app/Gemfile.lock +171 -0
  76. data/test/rails_app/README +256 -0
  77. data/test/rails_app/Rakefile +7 -0
  78. data/test/rails_app/app/components/generic_user_form.rb +12 -0
  79. data/test/rails_app/app/components/simple_accordion.rb +11 -0
  80. data/test/rails_app/app/components/simple_basic_app.rb +32 -0
  81. data/test/rails_app/app/components/simple_panel.rb +17 -0
  82. data/test/rails_app/app/components/simple_tab_panel.rb +11 -0
  83. data/test/rails_app/app/components/simple_wrapper.rb +7 -0
  84. data/test/rails_app/app/components/some_border_layout.rb +24 -0
  85. data/test/rails_app/app/components/some_search_panel.rb +34 -0
  86. data/test/rails_app/app/components/some_tab_panel.rb +15 -0
  87. data/test/rails_app/app/components/user_form.rb +21 -0
  88. data/test/rails_app/app/components/user_form_with_default_fields.rb +8 -0
  89. data/test/rails_app/app/components/user_grid.rb +4 -0
  90. data/test/rails_app/app/components/window_component_loader.rb +17 -0
  91. data/test/{app_root/app/controllers/application.rb → rails_app/app/controllers/application_controller.rb} +1 -0
  92. data/test/rails_app/app/controllers/components_controller.rb +6 -0
  93. data/test/rails_app/app/controllers/welcome_controller.rb +5 -0
  94. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  95. data/test/{app_root → rails_app}/app/models/role.rb +0 -0
  96. data/test/rails_app/app/models/user.rb +6 -0
  97. data/test/rails_app/app/presenters/forms/generic_user.rb +6 -0
  98. data/test/rails_app/app/views/layouts/application.html.erb +13 -0
  99. data/test/rails_app/config.ru +4 -0
  100. data/test/rails_app/config/application.rb +45 -0
  101. data/test/rails_app/config/boot.rb +13 -0
  102. data/test/rails_app/config/database.yml +35 -0
  103. data/test/rails_app/config/environment.rb +6 -0
  104. data/test/rails_app/config/environments/development.rb +22 -0
  105. data/test/rails_app/config/environments/production.rb +49 -0
  106. data/test/rails_app/config/environments/test.rb +35 -0
  107. data/test/rails_app/config/initializers/backtrace_silencers.rb +8 -0
  108. data/test/rails_app/config/initializers/inflections.rb +10 -0
  109. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  110. data/test/rails_app/config/initializers/netzke.rb +7 -0
  111. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  112. data/test/rails_app/config/initializers/session_store.rb +8 -0
  113. data/test/rails_app/config/locales/es.yml +12 -0
  114. data/test/rails_app/config/routes.rb +65 -0
  115. data/test/rails_app/db/development_structure.sql +39 -0
  116. data/test/{app_root/db/migrate/20081222035855_create_netzke_preferences.rb → rails_app/db/migrate/20100905214933_create_netzke_preferences.rb} +2 -4
  117. data/test/{app_root/db/migrate/20090423222114_create_users.rb → rails_app/db/migrate/20100914104207_create_users.rb} +4 -1
  118. data/test/{app_root/db/migrate/20090423214303_create_roles.rb → rails_app/db/migrate/20100914104236_create_roles.rb} +2 -0
  119. data/test/rails_app/db/schema.rb +38 -0
  120. data/test/rails_app/db/seeds.rb +20 -0
  121. data/test/rails_app/features/support/paths.rb +47 -0
  122. data/test/{app_root/config/environments/in_memory.rb → rails_app/lib/tasks/.gitkeep} +0 -0
  123. data/test/rails_app/public/404.html +26 -0
  124. data/test/rails_app/public/422.html +26 -0
  125. data/test/rails_app/public/500.html +26 -0
  126. data/test/{app_root/config/environments/mysql.rb → rails_app/public/favicon.ico} +0 -0
  127. data/test/rails_app/public/images/header-deco.gif +0 -0
  128. data/test/rails_app/public/images/rails.png +0 -0
  129. data/test/rails_app/public/javascripts/application.js +2 -0
  130. data/test/rails_app/public/javascripts/controls.js +965 -0
  131. data/test/rails_app/public/javascripts/dragdrop.js +974 -0
  132. data/test/rails_app/public/javascripts/effects.js +1123 -0
  133. data/test/rails_app/public/javascripts/prototype.js +6001 -0
  134. data/test/rails_app/public/javascripts/rails.js +175 -0
  135. data/test/rails_app/public/robots.txt +5 -0
  136. data/test/{app_root/config/environments/postgresql.rb → rails_app/public/stylesheets/.gitkeep} +0 -0
  137. data/test/rails_app/script/rails +6 -0
  138. data/test/rails_app/spec/models/role_spec.rb +5 -0
  139. data/test/rails_app/spec/models/user_spec.rb +5 -0
  140. data/test/rails_app/test/performance/browsing_test.rb +9 -0
  141. data/test/rails_app/test/test_helper.rb +13 -0
  142. data/test/{app_root/config/environments/sqlite.rb → rails_app/vendor/plugins/.gitkeep} +0 -0
  143. data/test/unit/accordion_panel_test.rb +3 -3
  144. data/test/unit/active_record_basepack_test.rb +4 -4
  145. data/test/unit/tab_panel_test.rb +4 -4
  146. metadata +199 -119
  147. data/lib/netzke/accordion_panel.rb +0 -115
  148. data/lib/netzke/active_record/data_accessor.rb +0 -25
  149. data/lib/netzke/attributes_configurator.rb +0 -195
  150. data/lib/netzke/basic_app.rb +0 -368
  151. data/lib/netzke/border_layout_panel.rb +0 -130
  152. data/lib/netzke/configuration_panel.rb +0 -24
  153. data/lib/netzke/form_panel.rb +0 -138
  154. data/lib/netzke/form_panel/form_panel_api.rb +0 -81
  155. data/lib/netzke/form_panel/form_panel_fields.rb +0 -149
  156. data/lib/netzke/form_panel/form_panel_js.rb +0 -163
  157. data/lib/netzke/grid_panel.rb +0 -367
  158. data/lib/netzke/grid_panel/grid_panel_api.rb +0 -364
  159. data/lib/netzke/grid_panel/grid_panel_columns.rb +0 -232
  160. data/lib/netzke/grid_panel/grid_panel_js.rb +0 -73
  161. data/lib/netzke/grid_panel/javascripts/advanced_search.js +0 -65
  162. data/lib/netzke/grid_panel/multi_edit_form.rb +0 -14
  163. data/lib/netzke/grid_panel/record_form_window.rb +0 -50
  164. data/lib/netzke/panel.rb +0 -11
  165. data/lib/netzke/plugins/configuration_tool.rb +0 -121
  166. data/lib/netzke/property_editor.rb +0 -111
  167. data/lib/netzke/property_editor/helper_model.rb +0 -122
  168. data/lib/netzke/search_panel.rb +0 -199
  169. data/lib/netzke/tab_panel.rb +0 -174
  170. data/lib/netzke/table_editor.rb +0 -118
  171. data/lib/netzke/tree_panel.rb +0 -25
  172. data/lib/netzke/window.rb +0 -82
  173. data/lib/netzke/wrapper.rb +0 -42
  174. data/test/app_root/app/models/book.rb +0 -9
  175. data/test/app_root/app/models/category.rb +0 -2
  176. data/test/app_root/app/models/city.rb +0 -3
  177. data/test/app_root/app/models/continent.rb +0 -2
  178. data/test/app_root/app/models/country.rb +0 -3
  179. data/test/app_root/app/models/genre.rb +0 -3
  180. data/test/app_root/app/models/user.rb +0 -3
  181. data/test/app_root/config/boot.rb +0 -114
  182. data/test/app_root/config/database.yml +0 -21
  183. data/test/app_root/config/environment.rb +0 -14
  184. data/test/app_root/config/environments/sqlite3.rb +0 -0
  185. data/test/app_root/config/routes.rb +0 -4
  186. data/test/app_root/db/migrate/20081222033343_create_books.rb +0 -15
  187. data/test/app_root/db/migrate/20081222033440_create_genres.rb +0 -15
  188. data/test/app_root/db/migrate/20081223024935_create_categories.rb +0 -13
  189. data/test/app_root/db/migrate/20081223025635_create_countries.rb +0 -14
  190. data/test/app_root/db/migrate/20081223025653_create_continents.rb +0 -13
  191. data/test/app_root/db/migrate/20081223025732_create_cities.rb +0 -15
  192. data/test/app_root/db/migrate/20090102223630_create_netzke_field_lists.rb +0 -18
  193. data/test/app_root/script/console +0 -7
  194. data/test/app_root/vendor/plugins/acts_as_list/README +0 -23
  195. data/test/app_root/vendor/plugins/acts_as_list/init.rb +0 -3
  196. data/test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +0 -256
@@ -1,115 +0,0 @@
1
- module Netzke
2
- # == AccordionPanel
3
- #
4
- # == Features:
5
- # * Dynamically loads widgets for the panels that get expanded for the first time
6
- # * Is loaded along with the active widget - saves a request to the server
7
- #
8
- # Future features:
9
- # * Stores the last active panel in persistent_config
10
- class AccordionPanel < Base
11
-
12
- # JavaScript part
13
- def self.js_extend_properties
14
- {
15
- :layout => 'accordion',
16
- :defaults => {:layout => 'fit'},
17
- :init_component => <<-END_OF_JAVASCRIPT.l,
18
- function(){
19
- #{js_full_class_name}.superclass.initComponent.call(this);
20
-
21
- // Set events
22
- this.items.each(function(i){
23
- // Set the expand event
24
- i.on('expand', this.loadItemWidget, this);
25
-
26
- // If not collapsed, add the active aggregatee (item) into it
27
- if (!i.collapsed) {
28
- var preloadedItemConfig = this[i.widget.camelize(true) + "Config"];
29
- var klass = this.classifyScopedName(preloadedItemConfig.scopedClassName);
30
- i.add(new klass(preloadedItemConfig));
31
- i.doLayout(); // always needed after adding a component
32
- }
33
- }, this);
34
- }
35
- END_OF_JAVASCRIPT
36
-
37
- # Loads widget into the panel if it wasn't loaded yet
38
- :load_item_widget => <<-END_OF_JAVASCRIPT.l,
39
- function(panel) {
40
- // if (!panel.getWidget()) panel.loadWidget(this.id + "__" + panel.widget + "__get_widget");
41
- var preloadedItemConfig = this[panel.widget.camelize(true) + "Config"];
42
-
43
- if (preloadedItemConfig){
44
- // preloaded widget only needs to be instantiated, as its class and configuration have already been loaded
45
- var klass = this.classifyScopedName(preloadedItemConfig.scopedClassName);
46
- panel.add(new klass(preloadedItemConfig));
47
- panel.doLayout(); // always needed after adding a component
48
- } else {
49
- // load the widget from the server
50
- this.loadAggregatee({id:panel.widget, container:panel.id});
51
- }
52
-
53
- }
54
- END_OF_JAVASCRIPT
55
- }
56
- end
57
-
58
- # Some normalization of config
59
- def initialize(*args)
60
- super
61
-
62
- seen_active = false
63
-
64
- config[:items].each_with_index do |item, i|
65
- # if some items are provided without names, give them generated names
66
- item[:name] ||= "item#{i}"
67
-
68
- # remove duplucated :active configuration
69
- if item[:active]
70
- item[:active] = nil if seen_active
71
- seen_active ||= true
72
- end
73
- end
74
- end
75
-
76
- # Returns items configs
77
- def items
78
- @items ||= config[:items]
79
- end
80
-
81
- # Provides configs for fit panels (which will effectively be accordion panels)
82
- def js_config
83
- super.merge({
84
- # these "items" are not related to the "items" of the config, rather these are the items required by the the accordion panel
85
- :items => fit_panels
86
- })
87
- end
88
-
89
- # "Fit-panels" - panels of layout 'fit' (effectively the accordion panels) that will contain the widgets ("items")
90
- def fit_panels
91
- res = []
92
- config[:items].each_with_index do |item, i|
93
- res << {
94
- # :id => item[:active] && global_id + '_active', # to mark the fit-panel which will contain the active widget
95
- :title => item[:title] || (item[:name] && item[:name].to_s.humanize),
96
- :widget => item[:name], # to know which fit panel will load which widget
97
- :collapsed => !(item[:active] || false)
98
- }
99
- end
100
- res
101
- end
102
-
103
- # All items become *late* aggregatees, besides the ones that are marked "active"
104
- def initial_aggregatees
105
- res = {}
106
- config[:items].each_with_index do |item, i|
107
- item[:late_aggregation] = !item[:active] && !item[:preloaded]
108
- res.merge!(item[:name].to_sym => item)
109
- end
110
- res
111
- end
112
-
113
-
114
- end
115
- end
@@ -1,25 +0,0 @@
1
- module Netzke::ActiveRecord
2
- # Provides extensions to those ActiveRecord-based models that provide data to the "data accessor" widgets,
3
- # like GridPanel, FormPanel, etc
4
- module DataAccessor
5
- # Transforms a record to array of values according to the passed columns.
6
- def to_array(columns, widget = nil)
7
- # self.netzke_widget = widget
8
- res = []
9
- for c in columns
10
- begin
11
- next if c[:included] == false
12
- v = send(c[:name])
13
- # a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
14
- v = v.to_datetime.to_s(:db) if v.is_a?(ActiveSupport::TimeWithZone)
15
- res << v
16
- rescue NoMethodError
17
- # So that we don't crash at a badly configured column
18
- res << "UNDEF"
19
- end
20
- end
21
- res
22
- end
23
- end
24
- end
25
-
@@ -1,195 +0,0 @@
1
- module Netzke
2
- # == AttributesConfigurator
3
- # Provides dynamic configuring of attributes for a specific model. This will be picked up by Grid/FormPanels as defaults.
4
- # Configuration parameters:
5
- # * <tt>:model</tt> - model to configure attributes for
6
- class AttributesConfigurator < JsonArrayEditor
7
- api :load_defaults
8
-
9
- def default_columns
10
- [{
11
- :name => "id",
12
- :attr_type => :integer
13
- },{
14
- :name => "included",
15
- :attr_type => :boolean,
16
- :default_value => true
17
- },{
18
- :name => "name",
19
- :attr_type => :string,
20
- :width => 200,
21
- :editor => {
22
- :xtype => :combo,
23
- :store => config[:model].constantize.netzke_attributes.map{ |attr| attr[:name] },
24
- :force_selection => true
25
- }
26
- },{
27
- :name => "label",
28
- :attr_type => :string,
29
- :width => 200
30
- },{
31
- :name => "default_value",
32
- :attr_type => :string,
33
- :width => 200
34
- },{
35
- :name => "combobox_options",
36
- :attr_type => :string,
37
- :width => 200,
38
- :editor => :textarea
39
- },{
40
- :name => "read_only",
41
- :attr_type => :boolean,
42
- :default_value => false,
43
- :header => "R/O"
44
- },{
45
- :name => "position",
46
- :attr_type => :integer,
47
- :included => false
48
- },{
49
- :name => "attr_type",
50
- :attr_type => :string,
51
- :meta => :true
52
- }]
53
- end
54
-
55
- def default_config
56
- super.deep_merge({
57
- :name => 'columns',
58
- :ext_config => {
59
- :header => false,
60
- :enable_extended_search => false,
61
- :enable_edit_in_form => false,
62
- :enable_pagination => false,
63
- :enable_rows_reordering => GridPanel.config[:rows_reordering_available]
64
- }
65
- })
66
- end
67
-
68
- def config_tool_needed?
69
- false
70
- end
71
-
72
- def actions
73
- super.merge(
74
- :defaults => {:text => 'Restore defaults', :icon => Netzke::Base.config[:with_icons] && (Netzke::Base.config[:icons_uri] + "wand.png")}
75
- )
76
- end
77
-
78
- def default_bbar
79
- %w{ add edit apply del - defaults }
80
- end
81
-
82
- def self.js_extend_properties
83
- {
84
- :init_component => <<-END_OF_JAVASCRIPT.l,
85
- function(){
86
- #{js_full_class_name}.superclass.initComponent.call(this);
87
-
88
- // Automatically set the correct editor for the default_value column
89
- this.on('beforeedit', function(e){
90
- var column = this.getColumnModel().getColumnById(this.getColumnModel().getColumnId(e.column));
91
- var record = this.getStore().getAt(e.row);
92
-
93
- if (column.dataIndex === "default_value") {
94
- if (record.get("name") === this.pri) {
95
- // Don't allow setting default value for the primary key
96
- column.setEditor(null);
97
- } else {
98
- // Auto set the editor, dependent on the field type
99
- var attrType = record.get("attr_type");
100
- column.setEditor(Ext.create({xtype: this.attrTypeEditorMap[attrType] || "textfield"}));
101
- }
102
- }
103
- }, this);
104
-
105
- // Add push menu item to column context menus
106
- this.on("viewready", this.extendColumnMenu, this);
107
- }
108
- END_OF_JAVASCRIPT
109
-
110
- :extend_column_menu => <<-END_OF_JAVASCRIPT.l,
111
- function(){
112
- this.getView().hmenu.add("-", {text: "Propagate", handler: this.onPushToViews, scope: this});
113
- }
114
- END_OF_JAVASCRIPT
115
-
116
- :on_push_to_views => <<-END_OF_JAVASCRIPT.l,
117
- function(){
118
- var columnIndex = this.getView().hdCtxIndex,
119
- dataIndex = this.getColumnModel().getDataIndex(columnIndex);
120
-
121
- this.pushDefaultsForAttr({name: dataIndex});
122
- }
123
- END_OF_JAVASCRIPT
124
-
125
- :on_defaults => <<-END_OF_JAVASCRIPT.l,
126
- function(){
127
- Ext.Msg.confirm('Confirm', 'Are you sure?', function(btn){
128
- if (btn == 'yes') {
129
- this.loadDefaults();
130
- }
131
- }, this);
132
- }
133
- END_OF_JAVASCRIPT
134
- }
135
- end
136
-
137
- api :push_defaults_for_attr
138
- def push_defaults_for_attr(params)
139
- NetzkeFieldList.update_children_on_attr(config[:model], params[:name])
140
- {:feedback => "Done."}
141
- end
142
-
143
- def load_defaults(params)
144
- data_class.replace_data(default_model_attrs)
145
- on_data_changed
146
- {:load_store_data => get_data}
147
- end
148
-
149
- private
150
- # An override
151
- def process_data(data, operation)
152
- if operation == :update
153
- meta_attrs_to_update = data.inject({}) do |r,el|
154
- r.merge({
155
- data_class.find(el["id"]).name => el.reject{ |k,v| k == "id" }
156
- })
157
- end
158
-
159
- res = super
160
- NetzkeModelAttrList.update_fields(config[:model], meta_attrs_to_update)
161
- # NetzkeFieldList.update_children(config[:model], meta_attrs_to_update)
162
- res
163
- else
164
- # NetzkeModelAttrList.add_attrs(config[:model], data.reject{ |k,v| k == "id" })
165
- super
166
- end
167
- end
168
-
169
- # An override
170
- def store_data(data)
171
- NetzkeModelAttrList.update_list_for_current_authority(config[:model], data)
172
- # Let's try to do it through process_data
173
- # NetzkeFieldList.write_attrs_for_model(config[:model], data)
174
- end
175
-
176
- # An override
177
- def initial_data
178
- # NetzkeModelAttrList.attrs_for_model(config[:model])
179
- NetzkeModelAttrList.read_list(config[:model]) || default_model_attrs
180
- # NetzkeModelAttrList.read_attrs_for_model(config[:model]) || default_model_attrs
181
- end
182
-
183
- # Default model attributes, along with their defaults meta-attributes (like :label)
184
- def default_model_attrs
185
- @default_model_attrs ||= begin
186
- config[:model].constantize.netzke_attributes.map do |attr|
187
- attr.merge(
188
- :label => attr[:label] || attr[:name].humanize,
189
- :attr_type => attr[:attr_type].to_s
190
- )
191
- end
192
- end
193
- end
194
- end
195
- end
@@ -1,368 +0,0 @@
1
- module Netzke
2
- # == BasicApp
3
- # Basis for a Ext.Viewport-based application
4
- #
5
- # Features:
6
- # * dynamic loading of widgets
7
- # * authentification support
8
- # * browser history support (press the "Back"-button to go to the previously loaded widget)
9
- # * FeedbackGhost-powered feedback
10
- # * aggregation of widget's own menus
11
- # * masquerade support
12
- # * AJAX activity indicator
13
- class BasicApp < Base
14
- def self.include_js
15
- res = []
16
- ext_examples = Netzke::Base.config[:ext_location] + "/examples/"
17
- res << ext_examples + "ux/statusbar/StatusBar.js"
18
- res << "#{File.dirname(__FILE__)}/basic_app/statusbar_ext.js"
19
- end
20
-
21
- def self.js_base_class
22
- "Ext.Viewport"
23
- end
24
-
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}
49
- end
50
-
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
- },{
61
- :id => 'main-statusbar',
62
- :xtype => 'statusbar',
63
- :region => 'south',
64
- :height => 22,
65
- :statusAlign => 'right',
66
- :busyText => 'Busy...',
67
- :default_text => masq.nil? ? "Ready #{"(config mode)" if session[:config_mode]}" : "Masquerading as #{masq}",
68
- :default_icon_cls => ""
69
- }]
70
- end
71
-
72
- def self.js_extend_properties
73
- {
74
- :layout => 'border',
75
-
76
- :panels => js_panels,
77
-
78
- :init_component => <<-END_OF_JAVASCRIPT.l,
79
- function(){
80
- this.items = this.panels; // a bit weird, but working; can't assign it straight
81
-
82
- #{js_full_class_name}.superclass.initComponent.call(this);
83
-
84
- // If we are given a token, load the corresponding widget, otherwise load the last loaded widget
85
- var currentToken = Ext.History.getToken();
86
- if (currentToken != "") {
87
- this.processHistory(currentToken);
88
- } else {
89
- var lastLoaded = this.initialConfig.widgetToLoad; // passed from the server
90
- if (lastLoaded) Ext.History.add(lastLoaded);
91
- }
92
-
93
- Ext.History.on('change', this.processHistory, this);
94
-
95
- // Hosted menus
96
- this.menus = {};
97
-
98
- // Setting the "busy" indicator for Ajax requests
99
- Ext.Ajax.on('beforerequest', function(){this.findById('main-statusbar').showBusy()}, this);
100
- Ext.Ajax.on('requestcomplete', function(){this.findById('main-statusbar').hideBusy()}, this);
101
- Ext.Ajax.on('requestexception', function(){this.findById('main-statusbar').hideBusy()}, this);
102
-
103
- // Initialize history
104
- Ext.History.init();
105
- }
106
- END_OF_JAVASCRIPT
107
-
108
- :host_menu => <<-END_OF_JAVASCRIPT.l,
109
- function(menu, owner){
110
- var toolbar = this.findById('main-toolbar');
111
- if (!this.menus[owner.id]) this.menus[owner.id] = [];
112
- Ext.each(menu, function(item) {
113
- // var newMenu = new Ext.Toolbar.Button(item);
114
- // var position = toolbar.items.getCount() - 2;
115
- // position = position < 0 ? 0 : position;
116
- // toolbar.insertButton(position, newMenu);
117
- toolbar.add(item);
118
- // this.menus[owner.id].push(newMenu); // TODO: remember the menus from this owner in some other way
119
- }, this);
120
- toolbar.doLayout(); // required since Ext 3.0.3
121
- }
122
- END_OF_JAVASCRIPT
123
-
124
- :unhost_menu => <<-END_OF_JAVASCRIPT.l,
125
- function(owner){
126
- // var toolbar = this.findById('main-toolbar');
127
- // if (this.menus[owner.id]) {
128
- // Ext.each(this.menus[owner.id], function(menu){
129
- // toolbar.items.remove(menu); // remove the item from the toolbar
130
- // menu.destroy(); // ... and destroy it
131
- // });
132
- // }
133
- }
134
- END_OF_JAVASCRIPT
135
-
136
- :on_login => <<-END_OF_JAVASCRIPT.l,
137
- function(){
138
- window.location = "/login"
139
- }
140
- END_OF_JAVASCRIPT
141
-
142
- :on_logout => <<-END_OF_JAVASCRIPT.l,
143
- function(){
144
- window.location = "#{config[:logout_url]}"
145
- }
146
- END_OF_JAVASCRIPT
147
-
148
- # Event handler for history change
149
- :process_history => <<-END_OF_JAVASCRIPT.l,
150
- function(token){
151
- if (token){
152
- this.loadAggregatee({id:token, container:'main-panel'});
153
- } else {
154
- Ext.getCmp('main-panel').removeChild();
155
- }
156
- }
157
- END_OF_JAVASCRIPT
158
-
159
- :instantiate_aggregatee => <<-END_OF_JAVASCRIPT.l,
160
- function(config){
161
- this.findById('main-panel').instantiateChild(config);
162
- }
163
- END_OF_JAVASCRIPT
164
-
165
- # Loads widget by name
166
- :app_load_widget => <<-END_OF_JAVASCRIPT.l,
167
- function(name){
168
- Ext.History.add(name);
169
- }
170
- END_OF_JAVASCRIPT
171
-
172
- # Loads widget by action
173
- :load_widget_by_action => <<-END_OF_JAVASCRIPT.l,
174
- function(action){
175
- this.appLoadWidget(action.widget || action.name);
176
- }
177
- END_OF_JAVASCRIPT
178
-
179
- :on_toggle_config_mode => <<-END_OF_JAVASCRIPT.l,
180
- function(){
181
- this.toggleConfigMode();
182
- }
183
- END_OF_JAVASCRIPT
184
-
185
- # NOT USED
186
- :show_login_window => <<-END_OF_JAVASCRIPT.l,
187
- function(){
188
- var w = new Ext.Window({
189
- title: "Please, login",
190
- modal: true,
191
- width: 350,
192
- height: 200,
193
- layout: 'fit',
194
- items: [{
195
- xtype: 'form',
196
- padding: 20,
197
- defaults: {anchor: '100%'},
198
- frame: true,
199
- border: false,
200
- items: [
201
- {xtype: 'textfield', fieldLabel: 'Username', name: 'login'},
202
- {name: 'password', xtype: 'textfield', inputType: 'password', fieldLabel: "Password"}
203
- ],
204
- buttons: [{
205
- name: "submit",
206
- text: "Login",
207
- app: this,
208
- handler: function() {
209
- this.ownerCt.ownerCt.getForm().submit({
210
- url: this.app.buildApiUrl("submit_login")
211
- });
212
- }
213
- }]
214
- }]
215
- });
216
-
217
- w.show();
218
- }
219
- END_OF_JAVASCRIPT
220
-
221
-
222
- # Masquerade selector window
223
- :show_masquerade_selector => <<-END_OF_JAVASCRIPT.l
224
- function(){
225
- var w = new Ext.Window({
226
- title: 'Masquerade as',
227
- modal: true,
228
- width: Ext.lib.Dom.getViewWidth() * 0.6,
229
- height: Ext.lib.Dom.getViewHeight() * 0.6,
230
- layout: 'fit',
231
- closeAction :'destroy',
232
- buttons: [{
233
- text: 'Select',
234
- handler : function(){
235
- if (role = w.getWidget().masquerade.role) {
236
- 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){
237
- if (btn === 'yes') {
238
- w.close();
239
- }
240
- });
241
- } else {
242
- w.close();
243
- }
244
- },
245
- scope:this
246
- },{
247
- text:'As World',
248
- handler:function(){
249
- 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){
250
- if (btn === "yes") {
251
- this.masquerade = {world:true};
252
- w.close();
253
- }
254
- }, this);
255
- },
256
- scope:this
257
- },{
258
- text:'No masquerading',
259
- handler:function(){
260
- this.masquerade = {};
261
- w.close();
262
- },
263
- scope:this
264
- },{
265
- text:'Cancel',
266
- handler:function(){
267
- w.hide();
268
- },
269
- scope:this
270
- }],
271
- listeners : {close: {fn: function(){
272
- this.masqueradeAs(this.masquerade || w.getWidget().masquerade || {});
273
- }, scope: this}}
274
- });
275
-
276
- w.show(null, function(){
277
- this.loadAggregatee({id:"masqueradeSelector", container:w.id})
278
- }, this);
279
-
280
- }
281
- END_OF_JAVASCRIPT
282
- }
283
- end
284
-
285
- # Set the Logout button if Netzke::Base.user is set
286
- def menu
287
- res = []
288
- user = User.find_by_id(session[:netzke_user_id])
289
- if !user.nil?
290
- user_name = user.respond_to?(:name) ? user.name : user.login # try to display user's name, fallback to login
291
- res << "->" <<
292
- {
293
- :text => "#{user_name}",
294
- :menu => user_menu
295
- }
296
- else
297
- res << "->" << :login
298
- end
299
- res
300
- end
301
-
302
- def user_menu
303
- [:logout]
304
- end
305
-
306
- def initialize(*args)
307
- super
308
-
309
- if session[:netzke_just_logged_in] || session[:netzke_just_logged_out]
310
- session[:config_mode] = false
311
- session[:masq_world] = session[:masq_user] = session[:masq_roles] = nil
312
- end
313
-
314
- strong_children_config.deep_merge!({:ext_config => {:mode => :config}}) if session[:config_mode]
315
- end
316
-
317
- #
318
- # Available actions
319
- #
320
- def actions
321
- {
322
- :masquerade_selector => {:text => "Masquerade as ...", :fn => "showMasqueradeSelector"},
323
- :toggle_config_mode => {:text => "#{session[:config_mode] ? "Leave" : "Enter"} config mode"},
324
- :login => {:text => "Login"},
325
- :logout => {:text => "Logout"}
326
- }
327
- end
328
-
329
-
330
- # Html required for Ext.History to work
331
- def js_widget_html
332
- super << %Q{
333
- <form id="history-form" class="x-hidden">
334
- <input type="hidden" id="x-history-field" />
335
- <iframe id="x-history-frame"></iframe>
336
- </form>
337
- }
338
- end
339
-
340
- #
341
- # Interface section
342
- #
343
-
344
- api :toggle_config_mode
345
- def toggle_config_mode(params)
346
- session = Netzke::Base.session
347
- session[:config_mode] = !session[:config_mode]
348
- {:js => "window.location.reload();"}
349
- end
350
-
351
- api :masquerade_as
352
- def masquerade_as(params)
353
- session = Netzke::Base.session
354
- session[:masq_world] = params[:world] == "true"
355
- session[:masq_role] = params[:role].try(:to_i)
356
- session[:masq_user] = params[:user].try(:to_i)
357
- {:js => "window.location.reload();"}
358
- end
359
-
360
- # Login request from the in-app login form
361
- api :submit_login
362
- def submit_login(params)
363
- # TODO: implement me
364
- {:feedback => "OK"}
365
- end
366
-
367
- end
368
- end