netzke-basepack 0.7.7 → 0.8.0
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/.travis.yml +15 -10
- data/{CHANGELOG.rdoc → CHANGELOG.md} +146 -110
- data/LICENSE +7 -1
- data/README.md +47 -56
- data/Rakefile +5 -5
- data/config/before-travis.sh +10 -0
- data/javascripts/basepack.js +0 -130
- data/javascripts/netzkeremotecombo.js +59 -0
- data/lib/netzke/basepack.rb +9 -14
- data/lib/netzke/basepack/accordion.rb +45 -0
- data/lib/netzke/basepack/active_record.rb +12 -0
- data/lib/netzke/basepack/active_record/relation_extensions.rb +27 -0
- data/lib/netzke/basepack/columns.rb +309 -0
- data/lib/netzke/basepack/data_accessor.rb +22 -12
- data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +75 -11
- data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +154 -49
- data/lib/netzke/basepack/fields.rb +162 -0
- data/lib/netzke/basepack/form.rb +136 -0
- data/lib/netzke/basepack/{form_panel → form}/javascripts/comma_list_cbg.js +0 -1
- data/lib/netzke/basepack/{form_panel/javascripts/form_panel.js → form/javascripts/form.js} +20 -26
- data/lib/netzke/basepack/{form_panel → form}/javascripts/n_radio_group.js +0 -1
- data/lib/netzke/basepack/{form_panel → form}/javascripts/readonly_mode.js +0 -0
- data/lib/netzke/basepack/form/services.rb +115 -0
- data/lib/netzke/basepack/{form_panel → form}/stylesheets/readonly_mode.css +0 -0
- data/lib/netzke/basepack/grid.rb +355 -0
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/advanced_search.js +1 -1
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/check_column_fix.js +0 -0
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/edit_in_form.js +3 -3
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/event_handling.js +5 -2
- data/lib/netzke/basepack/{grid_panel/javascripts/grid_panel.js → grid/javascripts/grid.js} +120 -132
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/misc.js +0 -0
- data/lib/netzke/basepack/grid/services.rb +216 -0
- data/lib/netzke/basepack/item_persistence.rb +44 -0
- data/lib/netzke/basepack/item_persistence/events_plugin.rb +47 -0
- data/lib/netzke/basepack/{paging_form_panel.rb → paging_form.rb} +24 -30
- data/lib/netzke/basepack/{paging_form_panel/javascripts/paging_form_panel.js → paging_form/javascripts/paging_form.js} +2 -4
- data/lib/netzke/basepack/query_builder.rb +44 -73
- data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +16 -2
- data/lib/netzke/basepack/record_form_window.rb +67 -0
- data/lib/netzke/basepack/search_panel.rb +22 -24
- data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +2 -2
- data/lib/netzke/basepack/search_window.rb +47 -53
- data/lib/netzke/basepack/simple_app.rb +10 -13
- data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +2 -8
- data/lib/netzke/basepack/tab_panel.rb +5 -4
- data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +5 -5
- data/lib/netzke/basepack/version.rb +2 -2
- data/lib/netzke/basepack/viewport.rb +16 -0
- data/lib/netzke/basepack/window.rb +27 -18
- data/lib/netzke/basepack/window/javascripts/window.js +7 -1
- data/lib/netzke/basepack/wrap_lazy_loaded.rb +18 -18
- data/locales/en.yml +40 -24
- data/netzke-basepack.gemspec +51 -82
- data/stylesheets/basepack.css +0 -41
- data/test/basepack_test_app/Gemfile +9 -46
- data/test/basepack_test_app/Gemfile.lock +61 -96
- data/test/basepack_test_app/app/components/author_form.rb +8 -5
- data/test/basepack_test_app/app/components/author_grid.rb +2 -2
- data/test/basepack_test_app/app/components/book_form.rb +34 -31
- data/test/basepack_test_app/app/components/book_form_with_defaults.rb +6 -7
- data/test/basepack_test_app/app/components/book_form_with_file_upload.rb +10 -0
- data/test/basepack_test_app/app/components/book_form_with_nested_attributes.rb +5 -6
- data/test/basepack_test_app/app/components/book_grid.rb +19 -8
- data/test/basepack_test_app/app/components/book_grid_filtering.rb +4 -7
- data/test/basepack_test_app/app/components/book_grid_loader.rb +28 -15
- data/test/basepack_test_app/app/components/book_grid_with_custom_columns.rb +45 -21
- data/test/basepack_test_app/app/components/book_grid_with_default_values.rb +26 -8
- data/test/basepack_test_app/app/components/book_grid_with_excluded_columns.rb +11 -0
- data/test/basepack_test_app/app/components/book_grid_with_extra_feedback.rb +2 -2
- data/test/basepack_test_app/app/components/book_grid_with_extra_filters.rb +7 -6
- data/test/basepack_test_app/app/components/book_grid_with_mass_assignment_security.rb +9 -0
- data/test/basepack_test_app/app/components/book_grid_with_nested_attributes.rb +9 -9
- data/test/basepack_test_app/app/components/book_grid_with_overridden_columns.rb +5 -3
- data/test/basepack_test_app/app/components/book_grid_with_paging.rb +6 -8
- data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +6 -4
- data/test/basepack_test_app/app/components/book_grid_with_scope.rb +6 -0
- data/test/basepack_test_app/app/components/book_grid_with_scoped_authors.rb +10 -7
- data/test/basepack_test_app/app/components/book_grid_with_virtual_attributes.rb +21 -13
- data/test/basepack_test_app/app/components/book_paging_form.rb +21 -0
- data/test/basepack_test_app/app/components/book_query_builder.rb +7 -6
- data/test/basepack_test_app/app/components/book_with_custom_primary_key_grid.rb +6 -7
- data/test/basepack_test_app/app/components/books_bound_to_author.rb +9 -7
- data/test/basepack_test_app/app/components/border_layout_panel_with_persistence.rb +12 -0
- data/test/basepack_test_app/app/components/double_book_grid.rb +19 -14
- data/test/basepack_test_app/app/components/form_without_model.rb +15 -16
- data/test/basepack_test_app/app/components/grid_with_initial_sorting.rb +7 -0
- data/test/basepack_test_app/app/components/grid_with_inline_data.rb +7 -0
- data/test/basepack_test_app/app/components/paging_form_with_search.rb +2 -2
- data/test/basepack_test_app/app/components/panel_with_persistent_regions.rb +35 -0
- data/test/basepack_test_app/app/components/query_builder.rb +7 -0
- data/test/basepack_test_app/app/components/simple_panel.rb +16 -11
- data/test/basepack_test_app/app/components/simple_window.rb +7 -6
- data/test/basepack_test_app/app/components/some_accordion.rb +18 -0
- data/test/basepack_test_app/app/components/some_auth_app.rb +5 -5
- data/test/basepack_test_app/app/components/some_border_layout.rb +20 -20
- data/test/basepack_test_app/app/components/some_search_panel.rb +6 -0
- data/test/basepack_test_app/app/components/some_simple_app.rb +30 -16
- data/test/basepack_test_app/app/components/some_tab_panel.rb +18 -15
- data/test/basepack_test_app/app/components/user_form.rb +18 -16
- data/test/basepack_test_app/app/components/user_form_with_default_fields.rb +5 -6
- data/test/basepack_test_app/app/components/user_grid.rb +11 -6
- data/test/basepack_test_app/app/components/user_grid_with_customized_form_fields.rb +5 -3
- data/test/basepack_test_app/app/components/window_component_loader.rb +25 -21
- data/test/basepack_test_app/app/models/address.rb +0 -26
- data/test/basepack_test_app/app/models/author.rb +0 -31
- data/test/basepack_test_app/app/models/book.rb +1 -42
- data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +1 -23
- data/test/basepack_test_app/app/models/role.rb +0 -21
- data/test/basepack_test_app/app/models/user.rb +0 -24
- data/test/basepack_test_app/app/views/layouts/components.html.erb +1 -1
- data/test/basepack_test_app/config/application.rb +1 -1
- data/test/basepack_test_app/config/database.yml.travis +2 -6
- data/test/basepack_test_app/config/initializers/netzke.rb +1 -6
- data/test/basepack_test_app/db/schema.rb +14 -14
- data/test/basepack_test_app/features/accordion_panel.feature +2 -2
- data/test/basepack_test_app/features/form_panel.feature +7 -7
- data/test/basepack_test_app/features/grid_panel.feature +93 -39
- data/test/basepack_test_app/features/grid_panel_with_custom_primary_key.feature +2 -1
- data/test/basepack_test_app/features/grid_sorting.feature +30 -6
- data/test/basepack_test_app/features/paging_form_panel.feature +7 -7
- data/test/basepack_test_app/features/persistent_regions.feature +30 -0
- data/test/basepack_test_app/features/search_in_grid.feature +5 -5
- data/test/basepack_test_app/features/simple_app.feature +6 -7
- data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +1 -1
- data/test/basepack_test_app/features/step_definitions/generic_steps.rb +109 -4
- data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +8 -10
- data/test/basepack_test_app/features/step_definitions/window_steps.rb +27 -0
- data/test/basepack_test_app/features/tab_panel.feature +1 -1
- data/test/basepack_test_app/features/window.feature +17 -0
- data/test/unit/accordion_panel_test.rb +2 -2
- data/test/unit/grid_panel_test.rb +4 -4
- metadata +57 -83
- data/TODO.rdoc +0 -8
- data/lib/generators/netzke/basepack_generator.rb +0 -10
- data/lib/generators/netzke/templates/assets/ts-checkbox.gif +0 -0
- data/lib/generators/netzke/templates/create_netzke_field_lists.rb +0 -18
- data/lib/netzke/active_record.rb +0 -20
- data/lib/netzke/active_record/attributes.rb +0 -259
- data/lib/netzke/active_record/combobox_options.rb +0 -16
- data/lib/netzke/active_record/relation_extensions.rb +0 -37
- data/lib/netzke/basepack/accordion_panel.rb +0 -39
- data/lib/netzke/basepack/action_column.rb +0 -68
- data/lib/netzke/basepack/action_column/javascripts/action_column.js +0 -61
- data/lib/netzke/basepack/auth_app.rb +0 -159
- data/lib/netzke/basepack/basic_app.rb +0 -7
- data/lib/netzke/basepack/border_layout_panel.rb +0 -53
- data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +0 -40
- data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +0 -264
- data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +0 -260
- data/lib/netzke/basepack/form_panel.rb +0 -144
- data/lib/netzke/basepack/form_panel/fields.rb +0 -208
- data/lib/netzke/basepack/form_panel/javascripts/misc.js +0 -4
- data/lib/netzke/basepack/form_panel/services.rb +0 -142
- data/lib/netzke/basepack/grid_panel.rb +0 -441
- data/lib/netzke/basepack/grid_panel/columns.rb +0 -400
- data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +0 -281
- data/lib/netzke/basepack/grid_panel/record_form_window.rb +0 -41
- data/lib/netzke/basepack/grid_panel/services.rb +0 -235
- data/lib/netzke/basepack/panel.rb +0 -11
- data/lib/netzke/basepack/wrapper.rb +0 -28
- data/lib/netzke/data_mapper.rb +0 -18
- data/lib/netzke/data_mapper/attributes.rb +0 -273
- data/lib/netzke/data_mapper/combobox_options.rb +0 -11
- data/lib/netzke/data_mapper/relation_extensions.rb +0 -38
- data/lib/netzke/sequel.rb +0 -18
- data/lib/netzke/sequel/attributes.rb +0 -274
- data/lib/netzke/sequel/combobox_options.rb +0 -10
- data/lib/netzke/sequel/relation_extensions.rb +0 -40
- data/locales/zh-cn.yml +0 -79
- data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +0 -21
- data/test/basepack_test_app/app/components/book_grid_with_column_actions.rb +0 -15
- data/test/basepack_test_app/app/components/book_grid_with_defaults.rb +0 -6
- data/test/basepack_test_app/app/components/book_paging_form_panel.rb +0 -22
- data/test/basepack_test_app/app/components/generic_user_form.rb +0 -12
- data/test/basepack_test_app/app/components/simple_accordion.rb +0 -11
- data/test/basepack_test_app/app/components/simple_tab_panel.rb +0 -11
- data/test/basepack_test_app/app/components/simple_wrapper.rb +0 -7
- data/test/basepack_test_app/app/components/some_accordion_panel.rb +0 -22
- data/test/basepack_test_app/app/presenters/forms/generic_user.rb +0 -6
- data/test/basepack_test_app/app/views/components/loadable_window.html.erb +0 -9
- data/test/basepack_test_app/app/views/components/simple_panel.html.erb +0 -1
- data/test/basepack_test_app/features/components_in_view.feature +0 -11
- data/test/basepack_test_app/features/simple_panel.feature +0 -11
- data/test/basepack_test_app/features/validations_in_grid.feature +0 -13
- data/test/basepack_test_app/features/virtual_attributes.feature +0 -16
- data/test/basepack_test_app/spec/components/form_panel_spec.rb +0 -53
- data/test/basepack_test_app/spec/components/grid_panel_spec.rb +0 -10
- data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +0 -68
- data/test/basepack_test_app/spec/data_adapter/attributes_spec.rb +0 -56
- data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +0 -125
- data/test/basepack_test_app/spec/factories.rb +0 -28
- data/test/basepack_test_app/spec/spec_helper.rb +0 -39
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module Basepack
|
|
3
|
-
class GridPanel < Netzke::Base
|
|
4
|
-
class RecordFormWindow < Window
|
|
5
|
-
|
|
6
|
-
js_properties :button_align => :right,
|
|
7
|
-
:width => 400,
|
|
8
|
-
:auto_height => true,
|
|
9
|
-
:modal => true,
|
|
10
|
-
:fbar => [:ok.action, :cancel.action]
|
|
11
|
-
|
|
12
|
-
action :ok do
|
|
13
|
-
{ :text => I18n.t('netzke.basepack.grid_panel.record_form_window.actions.ok')}
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
action :cancel do
|
|
17
|
-
{ :text => I18n.t('netzke.basepack.grid_panel.record_form_window.actions.cancel')}
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
js_method :init_component, <<-JS
|
|
21
|
-
function(params){
|
|
22
|
-
this.callParent();
|
|
23
|
-
this.items.first().on("submitsuccess", function(){ this.closeRes = "ok"; this.close(); }, this);
|
|
24
|
-
}
|
|
25
|
-
JS
|
|
26
|
-
|
|
27
|
-
js_method :on_ok, <<-JS
|
|
28
|
-
function(params){
|
|
29
|
-
this.items.first().onApply();
|
|
30
|
-
}
|
|
31
|
-
JS
|
|
32
|
-
|
|
33
|
-
js_method :on_cancel, <<-JS
|
|
34
|
-
function(params){
|
|
35
|
-
this.close();
|
|
36
|
-
}
|
|
37
|
-
JS
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module Basepack
|
|
3
|
-
class GridPanel < Netzke::Base
|
|
4
|
-
module Services
|
|
5
|
-
extend ActiveSupport::Concern
|
|
6
|
-
|
|
7
|
-
included do
|
|
8
|
-
|
|
9
|
-
endpoint :get_data do |params|
|
|
10
|
-
get_data(params)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
endpoint :post_data do |params|
|
|
14
|
-
mod_records = {}
|
|
15
|
-
[:create, :update].each do |operation|
|
|
16
|
-
data = ActiveSupport::JSON.decode(params["#{operation}d_records"]) if params["#{operation}d_records"]
|
|
17
|
-
if !data.nil? && !data.empty? # data may be nil for one of the operations
|
|
18
|
-
mod_records[operation] = process_data(data, operation)
|
|
19
|
-
mod_records[operation] = nil if mod_records[operation].empty?
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
on_data_changed
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
:update_new_records => mod_records[:create],
|
|
27
|
-
:update_mod_records => mod_records[:update] || {},
|
|
28
|
-
:netzke_feedback => @flash
|
|
29
|
-
}
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
endpoint :delete_data do |params|
|
|
33
|
-
if !config[:prohibit_delete]
|
|
34
|
-
record_ids = ActiveSupport::JSON.decode(params[:records])
|
|
35
|
-
data_adapter.destroy(record_ids)
|
|
36
|
-
on_data_changed
|
|
37
|
-
{:netzke_feedback => I18n.t('netzke.basepack.grid_panel.deleted_n_records', :n => record_ids.size), :load_store_data => get_data}
|
|
38
|
-
else
|
|
39
|
-
{:netzke_feedback => I18n.t('netzke.basepack.grid_panel.cannot_delete')}
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
endpoint :resize_column do |params|
|
|
44
|
-
raise "Called resize_column endpoint while not configured to do so" if !config[:persistence]
|
|
45
|
-
current_columns_order = state[:columns_order] || initial_columns_order
|
|
46
|
-
current_columns_order[normalize_index(params[:index].to_i)][:width] = params[:size].to_i
|
|
47
|
-
update_state(:columns_order, current_columns_order)
|
|
48
|
-
{}
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
endpoint :move_column do |params|
|
|
52
|
-
raise "Called move_column endpoint while not configured to do so" if !config[:persistence]
|
|
53
|
-
remove_from = normalize_index(params[:old_index].to_i)
|
|
54
|
-
insert_to = normalize_index(params[:new_index].to_i)
|
|
55
|
-
|
|
56
|
-
current_columns_order = state[:columns_order] || initial_columns_order
|
|
57
|
-
|
|
58
|
-
column_to_move = current_columns_order.delete_at(remove_from)
|
|
59
|
-
current_columns_order.insert(insert_to, column_to_move)
|
|
60
|
-
|
|
61
|
-
update_state(:columns_order, current_columns_order)
|
|
62
|
-
|
|
63
|
-
{}
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
endpoint :hide_column do |params|
|
|
67
|
-
raise "Called hide_column endpoint while not configured to do so" if !config[:persistence]
|
|
68
|
-
current_columns_order = state[:columns_order] || initial_columns_order
|
|
69
|
-
current_columns_order[normalize_index(params[:index].to_i)][:hidden] = params[:hidden]
|
|
70
|
-
update_state(:columns_order, current_columns_order)
|
|
71
|
-
{}
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# Returns choices for a column
|
|
75
|
-
endpoint :get_combobox_options do |params|
|
|
76
|
-
query = params[:query]
|
|
77
|
-
|
|
78
|
-
column = columns.detect{ |c| c[:name] == params[:column] }
|
|
79
|
-
scope = column.to_options[:scope] || column.to_options[:editor].try(:fetch, :scope, nil)
|
|
80
|
-
query = params[:query]
|
|
81
|
-
|
|
82
|
-
{:data => combobox_options_for_column(column, :query => query, :scope => scope, :record_id => params[:id])}
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
endpoint :move_rows do |params|
|
|
86
|
-
data_adapter.move_records(params)
|
|
87
|
-
{}
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
#
|
|
92
|
-
# Some components' overridden endpoints
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
## Edit in form specific endpoint
|
|
96
|
-
def add_form__form_panel0__netzke_submit_endpoint(params)
|
|
97
|
-
res = component_instance(:add_form__form_panel0).netzke_submit(params)
|
|
98
|
-
|
|
99
|
-
if res[:set_form_values]
|
|
100
|
-
# successful creation
|
|
101
|
-
on_data_changed
|
|
102
|
-
res[:set_form_values] = nil
|
|
103
|
-
end
|
|
104
|
-
res.to_nifty_json
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def edit_form__form_panel0__netzke_submit_endpoint(params)
|
|
108
|
-
res = component_instance(:edit_form__form_panel0).netzke_submit(params)
|
|
109
|
-
|
|
110
|
-
if res[:set_form_values]
|
|
111
|
-
on_data_changed
|
|
112
|
-
res[:set_form_values] = nil
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
res.to_nifty_json
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def multi_edit_form__multi_edit_form0__netzke_submit_endpoint(params)
|
|
119
|
-
ids = ActiveSupport::JSON.decode(params.delete(:ids))
|
|
120
|
-
data = ids.collect{ |id| ActiveSupport::JSON.decode(params[:data]).merge("id" => id) }
|
|
121
|
-
|
|
122
|
-
data.map!{|el| el.delete_if{ |k,v| v.is_a?(String) && v.blank? }} # only interested in set values
|
|
123
|
-
|
|
124
|
-
mod_records_count = process_data(data, :update).count
|
|
125
|
-
|
|
126
|
-
# remove duplicated flash messages
|
|
127
|
-
@flash = @flash.inject([]){ |r,hsh| r.include?(hsh) ? r : r.push(hsh) }
|
|
128
|
-
|
|
129
|
-
if mod_records_count > 0
|
|
130
|
-
on_data_changed
|
|
131
|
-
{:set_result => "ok", :netzke_feedback => @flash}.to_nifty_json
|
|
132
|
-
else
|
|
133
|
-
{:netzke_feedback => @flash}.to_nifty_json
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# When providing the edit_form component, fill in the form with the requested record
|
|
138
|
-
def deliver_component_endpoint(params)
|
|
139
|
-
components[:edit_form][:items].first.merge!(:record_id => params[:record_id].to_i) if params[:name] == 'edit_form'
|
|
140
|
-
super
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Implementation for the "get_data" endpoint
|
|
144
|
-
def get_data(*args)
|
|
145
|
-
params = args.first || {} # params are optional!
|
|
146
|
-
if !config[:prohibit_read]
|
|
147
|
-
{}.tap do |res|
|
|
148
|
-
records = get_records(params)
|
|
149
|
-
res[:data] = records.map{|r| r.netzke_array(columns(:with_meta => true))}
|
|
150
|
-
res[:total] = count_records(params) if config[:enable_pagination]
|
|
151
|
-
end
|
|
152
|
-
else
|
|
153
|
-
flash :error => "You don't have permissions to read data"
|
|
154
|
-
{ :netzke_feedback => @flash }
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
protected
|
|
159
|
-
|
|
160
|
-
# Returns an array of records.
|
|
161
|
-
def get_records(params)
|
|
162
|
-
params[:limit] = config[:rows_per_page] if config[:enable_pagination]
|
|
163
|
-
params[:scope] = config[:scope] # note, params[:scope] becomes ActiveSupport::HashWithIndifferentAccess
|
|
164
|
-
|
|
165
|
-
data_adapter.get_records(params, columns)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def count_records(params)
|
|
169
|
-
params[:scope] = config[:scope] # note, params[:scope] becomes ActiveSupport::HashWithIndifferentAccess
|
|
170
|
-
|
|
171
|
-
data_adapter.count_records(params, columns)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# Override this method to react on each operation that caused changing of data
|
|
175
|
-
def on_data_changed; end
|
|
176
|
-
|
|
177
|
-
# Given an index of a column among enabled (non-excluded) columns, provides the index (position) in the table
|
|
178
|
-
def normalize_index(index)
|
|
179
|
-
norm_index = 0
|
|
180
|
-
index.times do
|
|
181
|
-
while true do
|
|
182
|
-
norm_index += 1
|
|
183
|
-
break unless columns[norm_index][:included] == false
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
norm_index
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Params:
|
|
190
|
-
# <tt>:operation</tt>: :update or :create
|
|
191
|
-
def process_data(data, operation)
|
|
192
|
-
success = true
|
|
193
|
-
mod_records = {}
|
|
194
|
-
if !config[:"prohibit_#{operation}"]
|
|
195
|
-
modified_records = 0
|
|
196
|
-
data.each do |record_hash|
|
|
197
|
-
id = record_hash.delete('id')
|
|
198
|
-
record = operation == :create ? data_adapter.new_record : data_adapter.find_record(id)
|
|
199
|
-
success = true
|
|
200
|
-
|
|
201
|
-
# merge with strong default attirbutes
|
|
202
|
-
record_hash.merge!(config[:strong_default_attrs]) if config[:strong_default_attrs]
|
|
203
|
-
|
|
204
|
-
record_hash.each_pair do |k,v|
|
|
205
|
-
record.set_value_for_attribute(columns_hash[k.to_sym].nil? ? {:name => k} : columns_hash[k.to_sym], v)
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
# try to save
|
|
209
|
-
mod_records[id] = record.netzke_array(columns(:with_meta => true)) if success && record.save
|
|
210
|
-
|
|
211
|
-
# flash eventual errors
|
|
212
|
-
if !record.errors.empty?
|
|
213
|
-
success = false
|
|
214
|
-
record.errors.to_a.each do |msg|
|
|
215
|
-
flash :error => msg
|
|
216
|
-
end
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
else
|
|
220
|
-
success = false
|
|
221
|
-
flash :error => "You don't have permissions to #{operation} data"
|
|
222
|
-
end
|
|
223
|
-
mod_records
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def normalize_extra_conditions(conditions)
|
|
227
|
-
conditions.each_pair do |k,v|
|
|
228
|
-
conditions[k] = "%#{v}%" if ["like", "matches"].include?(k.to_s.split("__").last)
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module Basepack
|
|
3
|
-
# = Wrapper
|
|
4
|
-
#
|
|
5
|
-
# Simple Ext.Panel with layout 'fit' that wraps up another Netzke component. Can be useful in HTML pages where
|
|
6
|
-
# a component should be dynamically configured, to not reload the entire page after configuration (Wrapper
|
|
7
|
-
# will reload the component automatically).
|
|
8
|
-
#
|
|
9
|
-
# == Configuration
|
|
10
|
-
# * <tt>:item</tt> - configuration hash for wrapped component
|
|
11
|
-
#
|
|
12
|
-
# Example:
|
|
13
|
-
#
|
|
14
|
-
# netzke :wrapper, :item => {
|
|
15
|
-
# :class_name => "FormPanel",
|
|
16
|
-
# :model => "User"
|
|
17
|
-
# }
|
|
18
|
-
class Wrapper < Netzke::Base
|
|
19
|
-
js_properties(
|
|
20
|
-
:layout => 'fit',
|
|
21
|
-
|
|
22
|
-
# invisible
|
|
23
|
-
:header => false,
|
|
24
|
-
:border => false
|
|
25
|
-
)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
data/lib/netzke/data_mapper.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require 'netzke/data_mapper/attributes'
|
|
2
|
-
require 'netzke/data_mapper/combobox_options'
|
|
3
|
-
require 'netzke/data_mapper/relation_extensions'
|
|
4
|
-
|
|
5
|
-
module Netzke
|
|
6
|
-
module DataMapper
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
if defined? DataMapper
|
|
11
|
-
# Extend DataMapper
|
|
12
|
-
|
|
13
|
-
DataMapper::Model.append_extensions(Netzke::DataMapper::Attributes::ClassMethods)
|
|
14
|
-
DataMapper::Model.append_inclusions(Netzke::DataMapper::Attributes)
|
|
15
|
-
DataMapper::Model.append_extensions(Netzke::DataMapper::ComboboxOptions)
|
|
16
|
-
DataMapper::Model.append_extensions(Netzke::DataMapper::RelationExtensions)
|
|
17
|
-
end
|
|
18
|
-
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module DataMapper
|
|
3
|
-
module Attributes
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
|
|
6
|
-
included do
|
|
7
|
-
class_attribute :netzke_declared_attr
|
|
8
|
-
self.netzke_declared_attr = []
|
|
9
|
-
|
|
10
|
-
class_attribute :netzke_excluded_attr
|
|
11
|
-
self.netzke_excluded_attr = []
|
|
12
|
-
|
|
13
|
-
class_attribute :netzke_exposed_attr
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
module ClassMethods
|
|
17
|
-
def data_adapter
|
|
18
|
-
Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(self).new(self)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Define or configure an attribute.
|
|
22
|
-
# Example:
|
|
23
|
-
# netzke_attribute :recent, :type => :boolean, :read_only => true
|
|
24
|
-
def netzke_attribute(name, options = {})
|
|
25
|
-
name = name.to_s
|
|
26
|
-
options[:attr_type] = options.delete(:type) || options.delete(:attr_type) || :string
|
|
27
|
-
declared_attrs = self.netzke_declared_attr.dup
|
|
28
|
-
# if the attr was declared already, simply merge it with the new options
|
|
29
|
-
existing = declared_attrs.detect{ |va| va[:name] == name }
|
|
30
|
-
if existing
|
|
31
|
-
existing.merge!(options)
|
|
32
|
-
else
|
|
33
|
-
attr_config = {:name => name}.merge(options)
|
|
34
|
-
# if primary_key, insert in front, otherwise append
|
|
35
|
-
if name == self.primary_key
|
|
36
|
-
declared_attrs.insert(0, attr_config)
|
|
37
|
-
else
|
|
38
|
-
declared_attrs << {:name => name}.merge(options)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
self.netzke_declared_attr = declared_attrs
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Exclude attributes from being picked up by grids and forms.
|
|
45
|
-
# Accepts an array of attribute names (as symbols).
|
|
46
|
-
# Example:
|
|
47
|
-
# netzke_expose_attributes :created_at, :updated_at, :crypted_password
|
|
48
|
-
def netzke_exclude_attributes(*args)
|
|
49
|
-
self.netzke_excluded_attr = args.map(&:to_s)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# Explicitly expose attributes that should be picked up by grids and forms.
|
|
53
|
-
# Accepts an array of attribute names (as symbols).
|
|
54
|
-
# Takes precedence over <tt>netzke_exclude_attributes</tt>.
|
|
55
|
-
# Example:
|
|
56
|
-
# netzke_expose_attributes :name, :role__name
|
|
57
|
-
def netzke_expose_attributes(*args)
|
|
58
|
-
self.netzke_exposed_attr = args.map(&:to_s)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# Returns the attributes that will be picked up by grids and forms.
|
|
62
|
-
def netzke_attributes
|
|
63
|
-
exposed = netzke_exposed_attributes
|
|
64
|
-
exposed ? netzke_attrs_in_forced_order(exposed) : netzke_attrs_in_natural_order
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def netzke_attribute_hash
|
|
68
|
-
netzke_attributes.inject({}){ |r,a| r.merge(a[:name].to_sym => a) }
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def netzke_exposed_attributes
|
|
72
|
-
exposed = self.netzke_exposed_attr
|
|
73
|
-
if exposed && !exposed.include?(self.primary_key)
|
|
74
|
-
# automatically declare primary key as a netzke attribute
|
|
75
|
-
netzke_attribute(self.primary_key)
|
|
76
|
-
exposed.insert(0, self.primary_key)
|
|
77
|
-
end
|
|
78
|
-
exposed
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def primary_key
|
|
82
|
-
key.first.name.to_s
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def column_names
|
|
86
|
-
properties.map(&:name).map(&:to_s)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def columns
|
|
90
|
-
properties
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def columns_hash
|
|
94
|
-
properties.inject({}) { |hsh, prop|
|
|
95
|
-
hsh[prop.name.to_s] = prop
|
|
96
|
-
hsh
|
|
97
|
-
}
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def property_with(name)
|
|
101
|
-
properties.find{|p| p.name == name.to_sym}
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
private
|
|
105
|
-
def netzke_attrs_in_forced_order(attrs)
|
|
106
|
-
attrs.collect do |attr_name|
|
|
107
|
-
declared = self.netzke_declared_attr.detect { |va| va[:name] == attr_name } || {}
|
|
108
|
-
in_columns_hash = columns_hash[attr_name] && {:name => attr_name, :attr_type => data_adapter.map_type(columns_hash[attr_name].class), :default_value => columns_hash[attr_name].default} || {} # {:virtual => true} # if nothing found in columns, mark it as "virtual" or not?
|
|
109
|
-
if in_columns_hash.empty?
|
|
110
|
-
# If not among the model columns, it's either virtual, or an association
|
|
111
|
-
merged = association_attr?(attr_name) ? declared.merge!(:name => attr_name) : declared.merge(:virtual => true)
|
|
112
|
-
else
|
|
113
|
-
# .. otherwise merge with what's declared
|
|
114
|
-
merged = in_columns_hash.merge(declared)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# We didn't find it among declared, nor among the model columns, nor does it seem association attribute
|
|
118
|
-
merged[:name].nil? && raise(ArgumentError, "Unknown attribute '#{attr_name}' for model #{self.name}", caller)
|
|
119
|
-
|
|
120
|
-
merged
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Returns netzke attributes in the order of columns in the table, followed by extra declared attributes
|
|
125
|
-
# Detects one-to-many association columns and replaces the name of the column with association column name (Netzke style), e.g.:
|
|
126
|
-
#
|
|
127
|
-
# role_id => role__name
|
|
128
|
-
def netzke_attrs_in_natural_order
|
|
129
|
-
(
|
|
130
|
-
declared_attrs = self.netzke_declared_attr
|
|
131
|
-
|
|
132
|
-
column_names.map do |name|
|
|
133
|
-
c = {:name => name, :attr_type => data_adapter.map_type(property_with(name).class)}
|
|
134
|
-
|
|
135
|
-
# If it's named as foreign key of some association, then it's an association column
|
|
136
|
-
# assoc = reflect_on_all_associations.detect { |a| foreign_key_for_assoc(a) == c[:name] }
|
|
137
|
-
assoc = relationships.detect { |r| r.child_key.first.name.to_s == c[:name] }
|
|
138
|
-
if assoc
|
|
139
|
-
assoc_class = assoc.parent_model
|
|
140
|
-
candidates = %w{name title label} << c[:name]
|
|
141
|
-
assoc_method = candidates.detect{|m| (assoc_class.instance_methods.map(&:to_s) + assoc_class.column_names).include?(m) }
|
|
142
|
-
c[:name] = "#{assoc.name}__#{assoc_method}"
|
|
143
|
-
c[:attr_type] = data_adapter.map_type(columns_hash[assoc_method]).try(:class) || :string # when it's an instance method rather than a column, fall back to :string
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# auto set up the default value from the column settings
|
|
147
|
-
c.merge!(:default_value => property_with(name).default) if property_with(name).default
|
|
148
|
-
|
|
149
|
-
# if there's a declared attr with the same name, simply merge it with what's taken from the model's columns
|
|
150
|
-
if declared = declared_attrs.detect{ |va| va[:name] == c[:name] }
|
|
151
|
-
c.merge!(declared)
|
|
152
|
-
declared_attrs.delete(declared)
|
|
153
|
-
end
|
|
154
|
-
c
|
|
155
|
-
end +
|
|
156
|
-
declared_attrs
|
|
157
|
-
).reject { |attr| self.netzke_excluded_attr.include?(attr[:name]) }
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def association_attr?(attr_name)
|
|
161
|
-
!!attr_name.index("__") # probably we can't do much better than this, as we don't know at this moment if the associated model has a specific attribute, and we don't really want to find it out
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Transforms a record to array of values according to the passed attributes
|
|
166
|
-
def netzke_array(attributes = self.class.netzke_attributes)
|
|
167
|
-
res = []
|
|
168
|
-
for a in attributes
|
|
169
|
-
next if a[:included] == false
|
|
170
|
-
res << value_for_attribute(a, a[:nested_attribute])
|
|
171
|
-
end
|
|
172
|
-
res
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def netzke_json
|
|
176
|
-
netzke_hash.to_nifty_json
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# Accepts both hash and array of attributes
|
|
180
|
-
def netzke_hash(attributes = self.class.netzke_attributes)
|
|
181
|
-
res = {}
|
|
182
|
-
for a in (attributes.is_a?(Hash) ? attributes.values : attributes)
|
|
183
|
-
next if a[:included] == false
|
|
184
|
-
res[a[:name].to_sym] = self.value_for_attribute(a, a[:nested_attribute])
|
|
185
|
-
end
|
|
186
|
-
res
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Fetches the value specified by an (association) attribute
|
|
190
|
-
# If +through_association+ is true, get the value of the association by provided method, *not* the associated record's id
|
|
191
|
-
# E.g., author__name with through_association set to true may return "Vladimir Nabokov", while with through_association set to false, it'll return author_id for the current record
|
|
192
|
-
def value_for_attribute(a, through_association = false)
|
|
193
|
-
v = if a[:getter]
|
|
194
|
-
a[:getter].call(self)
|
|
195
|
-
elsif respond_to?("#{a[:name]}")
|
|
196
|
-
send("#{a[:name]}")
|
|
197
|
-
elsif is_association_attr?(a)
|
|
198
|
-
split = a[:name].to_s.split(/\.|__/)
|
|
199
|
-
assoc = self.class.relationships[split.first.to_sym]
|
|
200
|
-
|
|
201
|
-
if through_association
|
|
202
|
-
split.inject(self) do |r,m| # TODO: do we really need to descend deeper than 1 level?
|
|
203
|
-
if r.respond_to?(m)
|
|
204
|
-
r.send(m)
|
|
205
|
-
else
|
|
206
|
-
::Rails.logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
|
|
207
|
-
nil
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
else
|
|
211
|
-
self.send assoc.child_key.first.name
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
|
|
216
|
-
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone].include?(v.class)
|
|
217
|
-
v = v.to_s(:db) if [DateTime, Date].include?(v.class)
|
|
218
|
-
v
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
# Assigns new value to an (association) attribute
|
|
222
|
-
def set_value_for_attribute(a, v)
|
|
223
|
-
v = v.to_time_in_current_zone if v.is_a?(Date) # convert Date to Time
|
|
224
|
-
|
|
225
|
-
if a[:setter]
|
|
226
|
-
a[:setter].call(self, v)
|
|
227
|
-
elsif respond_to?("#{a[:name]}=")
|
|
228
|
-
send("#{a[:name]}=", v)
|
|
229
|
-
elsif is_association_attr?(a)
|
|
230
|
-
split = a[:name].to_s.split(/\.|__/)
|
|
231
|
-
if a[:nested_attribute]
|
|
232
|
-
# We want:
|
|
233
|
-
# set_value_for_attribute({:name => :assoc_1__assoc_2__method, :nested_attribute => true}, 100)
|
|
234
|
-
# =>
|
|
235
|
-
# self.assoc_1.assoc_2.method = 100
|
|
236
|
-
split.inject(self) { |r,m| m == split.last ? (r && r.send("#{m}=", v) && r.save) : r.send(m) }
|
|
237
|
-
else
|
|
238
|
-
if split.size == 2
|
|
239
|
-
# search for association and assign it to self
|
|
240
|
-
assoc_name, assoc_method = split
|
|
241
|
-
relationship=self.class.relationships[assoc_name]
|
|
242
|
-
|
|
243
|
-
if relationship
|
|
244
|
-
if relationship.kind_of? ::DataMapper::Associations::OneToOne::Relationship
|
|
245
|
-
assoc_instance=self.send(assoc_name)
|
|
246
|
-
if assoc_instance
|
|
247
|
-
assoc_instance.send("#{assoc_method}=", v)
|
|
248
|
-
assoc_instance.save # what should we do when this fails?..
|
|
249
|
-
else
|
|
250
|
-
# what should we do in this case?
|
|
251
|
-
end
|
|
252
|
-
else
|
|
253
|
-
self.send("#{self.class.data_adapter.foreign_key_for assoc_name}=", v)
|
|
254
|
-
end
|
|
255
|
-
else
|
|
256
|
-
::Rails.logger.debug "Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
|
|
257
|
-
end
|
|
258
|
-
else
|
|
259
|
-
::Rails.logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}"
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
protected
|
|
266
|
-
# Returns true if passed attribute is an "association attribute"
|
|
267
|
-
def is_association_attr?(a)
|
|
268
|
-
# maybe the check is too simplistic, but will do for now
|
|
269
|
-
!!a[:name].to_s.index("__")
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
end
|