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
data/TODO.rdoc
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
== Priority
|
|
2
|
-
* Commit persistence migrations in the test app
|
|
3
|
-
* DataAccessor#to_array should not rescue exceptions, but rather check the availability of the attributes; `respond_to_with_basepack?` should be extended to also return true for association columns
|
|
4
|
-
* GridPanel's read_only vs editable (doesn't work now) options
|
|
5
|
-
* Find a way to print the grid nicely (along with the column and rows that don't fit on the screen)
|
|
6
|
-
|
|
7
|
-
== Foolproof
|
|
8
|
-
* Should not be possible to put the "ID" field on any place but first for grids (otherwise record ID is not correct)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
class BasepackGenerator < ::Rails::Generators::Base
|
|
3
|
-
source_root File.expand_path('../templates', __FILE__)
|
|
4
|
-
|
|
5
|
-
desc 'Copies necessary assets to public/netzke/basepack'
|
|
6
|
-
def execute
|
|
7
|
-
copy_file 'assets/ts-checkbox.gif', "public/netzke/basepack/ts-checkbox.gif"
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
end
|
|
Binary file
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
class CreateNetzkeFieldLists < ActiveRecord::Migration
|
|
2
|
-
def self.up
|
|
3
|
-
create_table :netzke_field_lists do |t|
|
|
4
|
-
t.string :name
|
|
5
|
-
t.text :value
|
|
6
|
-
t.string :model_name
|
|
7
|
-
t.integer :user_id
|
|
8
|
-
t.integer :role_id
|
|
9
|
-
t.string :type
|
|
10
|
-
|
|
11
|
-
t.timestamps
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def self.down
|
|
16
|
-
drop_table :netzke_field_lists
|
|
17
|
-
end
|
|
18
|
-
end
|
data/lib/netzke/active_record.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require 'netzke/active_record/attributes'
|
|
2
|
-
require 'netzke/active_record/combobox_options'
|
|
3
|
-
require 'netzke/active_record/relation_extensions'
|
|
4
|
-
|
|
5
|
-
module Netzke
|
|
6
|
-
module ActiveRecord
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
if defined? ActiveRecord
|
|
11
|
-
# Extend ActiveRecord
|
|
12
|
-
ActiveRecord::Base.class_eval do
|
|
13
|
-
include ::Netzke::ActiveRecord::Attributes
|
|
14
|
-
include ::Netzke::ActiveRecord::ComboboxOptions
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
ActiveRecord::Relation.class_eval do
|
|
18
|
-
include ::Netzke::ActiveRecord::RelationExtensions
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module ActiveRecord
|
|
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
|
-
@data_adapter = 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
|
-
private
|
|
82
|
-
|
|
83
|
-
def netzke_attrs_in_forced_order(attrs)
|
|
84
|
-
attrs.collect do |attr_name|
|
|
85
|
-
declared = self.netzke_declared_attr.detect { |va| va[:name] == attr_name } || {}
|
|
86
|
-
in_columns_hash = columns_hash[attr_name] && {:name => attr_name, :attr_type => columns_hash[attr_name].type, :default_value => columns_hash[attr_name].default} || {} # {:virtual => true} # if nothing found in columns, mark it as "virtual" or not?
|
|
87
|
-
if in_columns_hash.empty?
|
|
88
|
-
# If not among the model columns, it's either virtual, or an association
|
|
89
|
-
merged = association_attr?(attr_name) ? declared.merge!(:name => attr_name) : declared.merge(:virtual => true)
|
|
90
|
-
else
|
|
91
|
-
# .. otherwise merge with what's declared
|
|
92
|
-
merged = in_columns_hash.merge(declared)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# We didn't find it among declared, nor among the model columns, nor does it seem association attribute
|
|
96
|
-
merged[:name].nil? && raise(ArgumentError, "Unknown attribute '#{attr_name}' for model #{self.name}", caller)
|
|
97
|
-
|
|
98
|
-
merged
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Returns netzke attributes in the order of columns in the table, followed by extra declared attributes
|
|
103
|
-
# Detects one-to-many association columns and replaces the name of the column with association column name (Netzke style), e.g.:
|
|
104
|
-
#
|
|
105
|
-
# role_id => role__name
|
|
106
|
-
def netzke_attrs_in_natural_order
|
|
107
|
-
(
|
|
108
|
-
declared_attrs = self.netzke_declared_attr
|
|
109
|
-
|
|
110
|
-
column_names.map do |name|
|
|
111
|
-
c = {:name => name, :attr_type => columns_hash[name].type}
|
|
112
|
-
|
|
113
|
-
# If it's named as foreign key of some association, then it's an association column
|
|
114
|
-
assoc = reflect_on_all_associations.detect { |a| foreign_key_for_assoc(a) == c[:name] }
|
|
115
|
-
|
|
116
|
-
if assoc && !assoc.options[:polymorphic]
|
|
117
|
-
candidates = %w{name title label} << foreign_key_for_assoc(assoc)
|
|
118
|
-
assoc_method = candidates.detect{|m| (assoc.klass.instance_methods.map(&:to_s) + assoc.klass.column_names).include?(m) }
|
|
119
|
-
c[:name] = "#{assoc.name}__#{assoc_method}"
|
|
120
|
-
c[:attr_type] = :integer # when it's an instance method rather than a column, fall back to :string
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# auto set up the default value from the column settings
|
|
124
|
-
c.merge!(:default_value => columns_hash[name].default) if columns_hash[name].default
|
|
125
|
-
|
|
126
|
-
# if there's a declared attr with the same name, simply merge it with what's taken from the model's columns
|
|
127
|
-
if declared = declared_attrs.detect{ |va| va[:name] == c[:name] }
|
|
128
|
-
c.merge!(declared)
|
|
129
|
-
declared_attrs.delete(declared)
|
|
130
|
-
end
|
|
131
|
-
c
|
|
132
|
-
end +
|
|
133
|
-
declared_attrs
|
|
134
|
-
).reject { |attr| self.netzke_excluded_attr.include?(attr[:name]) }
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# Returns foreign key for given association (Rails >= 3.0)
|
|
138
|
-
def foreign_key_for_assoc(assoc)
|
|
139
|
-
assoc.respond_to?(:foreign_key) ? assoc.foreign_key : assoc.primary_key_name
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def association_attr?(attr_name)
|
|
143
|
-
!!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
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Transforms a record to array of values according to the passed attributes
|
|
149
|
-
def netzke_array(attributes = self.class.netzke_attributes)
|
|
150
|
-
res = []
|
|
151
|
-
for a in attributes
|
|
152
|
-
next if a[:included] == false
|
|
153
|
-
res << value_for_attribute(a, a[:nested_attribute])
|
|
154
|
-
end
|
|
155
|
-
res
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def netzke_json
|
|
159
|
-
netzke_hash.to_nifty_json
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
# Accepts both hash and array of attributes
|
|
163
|
-
def netzke_hash(attributes = self.class.netzke_attributes)
|
|
164
|
-
res = {}
|
|
165
|
-
for a in (attributes.is_a?(Hash) ? attributes.values : attributes)
|
|
166
|
-
next if a[:included] == false
|
|
167
|
-
res[a[:name].to_sym] = self.value_for_attribute(a, a[:nested_attribute])
|
|
168
|
-
end
|
|
169
|
-
res
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# Fetches the value specified by an (association) attribute
|
|
173
|
-
# If +through_association+ is true, get the value of the association by provided method, *not* the associated record's id
|
|
174
|
-
# 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
|
|
175
|
-
def value_for_attribute(a, through_association = false)
|
|
176
|
-
v = if a[:getter]
|
|
177
|
-
a[:getter].call(self)
|
|
178
|
-
elsif respond_to?("#{a[:name]}")
|
|
179
|
-
send("#{a[:name]}")
|
|
180
|
-
elsif is_association_attr?(a)
|
|
181
|
-
split = a[:name].to_s.split(/\.|__/)
|
|
182
|
-
assoc = self.class.reflect_on_association(split.first.to_sym)
|
|
183
|
-
if through_association
|
|
184
|
-
split.inject(self) do |r,m| # TODO: do we really need to descend deeper than 1 level?
|
|
185
|
-
if r.respond_to?(m)
|
|
186
|
-
r.send(m)
|
|
187
|
-
else
|
|
188
|
-
logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
|
|
189
|
-
nil
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
else
|
|
193
|
-
self.send("#{assoc.options[:foreign_key] || assoc.name.to_s.foreign_key}")
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
|
|
198
|
-
v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone].include?(v.class)
|
|
199
|
-
|
|
200
|
-
v
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# Assigns new value to an (association) attribute
|
|
204
|
-
def set_value_for_attribute(a, v)
|
|
205
|
-
v = v.to_time_in_current_zone if v.is_a?(Date) # convert Date to Time
|
|
206
|
-
|
|
207
|
-
if a[:setter]
|
|
208
|
-
a[:setter].call(self, v)
|
|
209
|
-
elsif respond_to?("#{a[:name]}=")
|
|
210
|
-
send("#{a[:name]}=", v)
|
|
211
|
-
elsif is_association_attr?(a)
|
|
212
|
-
split = a[:name].to_s.split(/\.|__/)
|
|
213
|
-
if a[:nested_attribute]
|
|
214
|
-
# We want:
|
|
215
|
-
# set_value_for_attribute({:name => :assoc_1__assoc_2__method, :nested_attribute => true}, 100)
|
|
216
|
-
# =>
|
|
217
|
-
# self.assoc_1.assoc_2.method = 100
|
|
218
|
-
split.inject(self) { |r,m| m == split.last ? (r && r.send("#{m}=", v) && r.save) : r.send(m) }
|
|
219
|
-
else
|
|
220
|
-
if split.size == 2
|
|
221
|
-
# search for association and assign it to self
|
|
222
|
-
assoc = self.class.reflect_on_association(split.first.to_sym)
|
|
223
|
-
assoc_method = split.last
|
|
224
|
-
if assoc
|
|
225
|
-
if assoc.macro == :has_one
|
|
226
|
-
assoc_instance = self.send(assoc.name)
|
|
227
|
-
if assoc_instance
|
|
228
|
-
assoc_instance.send("#{assoc_method}=", v)
|
|
229
|
-
assoc_instance.save # what should we do when this fails?..
|
|
230
|
-
else
|
|
231
|
-
# what should we do in this case?
|
|
232
|
-
end
|
|
233
|
-
else
|
|
234
|
-
|
|
235
|
-
# set the foreign key to the passed value
|
|
236
|
-
# not that if a negative value is passed, we reset the association (set it to nil)
|
|
237
|
-
self.send("#{assoc.foreign_key}=", v.to_i < 0 ? nil : v)
|
|
238
|
-
end
|
|
239
|
-
else
|
|
240
|
-
logger.debug "Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
|
|
241
|
-
end
|
|
242
|
-
else
|
|
243
|
-
logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}"
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
protected
|
|
250
|
-
|
|
251
|
-
# Returns true if passed attribute is an "association attribute"
|
|
252
|
-
def is_association_attr?(a)
|
|
253
|
-
# maybe the check is too simplistic, but will do for now
|
|
254
|
-
!!a[:name].to_s.index("__")
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module ActiveRecord
|
|
3
|
-
module ComboboxOptions
|
|
4
|
-
module ClassMethods
|
|
5
|
-
def netzke_combo_options_for(column, query = "")
|
|
6
|
-
records = query.empty? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
|
|
7
|
-
records.map{|r| r.send(column)}
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def self.included(receiver)
|
|
12
|
-
receiver.extend ClassMethods
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module ActiveRecord
|
|
3
|
-
module RelationExtensions
|
|
4
|
-
|
|
5
|
-
def extend_with(*params)
|
|
6
|
-
scope = params.shift
|
|
7
|
-
case scope.class.name
|
|
8
|
-
when "Symbol" # model's scope
|
|
9
|
-
self.send(scope, *params)
|
|
10
|
-
when "String" # SQL query or SQL query with params (e.g. ["created_at < ?", 1.day.ago])
|
|
11
|
-
params.empty? ? self.where(scope) : self.where([scope, *params])
|
|
12
|
-
when "Array"
|
|
13
|
-
self.extend_with(*scope)
|
|
14
|
-
when "Hash" # conditions hash
|
|
15
|
-
self.where(scope)
|
|
16
|
-
when "ActiveSupport::HashWithIndifferentAccess" # conditions hash
|
|
17
|
-
self.where(scope)
|
|
18
|
-
when "Proc" # receives a relation, must return a relation
|
|
19
|
-
scope.call(self)
|
|
20
|
-
else
|
|
21
|
-
raise ArgumentError, "Wrong parameter type for ActiveRecord::Relation#extend_with"
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Non-destructively extends itself whith a hash of double-underscore'd conditions,
|
|
26
|
-
# where the last part "__" is MetaWhere operator (which is required), e.g.:
|
|
27
|
-
# {:role__name__like => "%admin"}
|
|
28
|
-
def extend_with_netzke_conditions(cond)
|
|
29
|
-
cond.each_pair.inject(self) do |r, (k,v)|
|
|
30
|
-
assoc, method, *operator = k.to_s.split("__")
|
|
31
|
-
operator.empty? ? r.where(assoc.to_sym.send(method) => v) : r.where(assoc.to_sym => {method.to_sym.send(operator.last) => v}).joins(assoc.to_sym)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module Basepack
|
|
3
|
-
# = AccordionPanel
|
|
4
|
-
#
|
|
5
|
-
# A panel with the 'accordion' layout. Can lazily load its nested components. For example:
|
|
6
|
-
#
|
|
7
|
-
# netzke :my_accordion, :items => [{
|
|
8
|
-
# :html => "I'm a simple Ext.Panel",
|
|
9
|
-
# :title => "Panel One"
|
|
10
|
-
# },{
|
|
11
|
-
# :class_name => "SimplePanel",
|
|
12
|
-
# :update_text => "Update for Panel Two",
|
|
13
|
-
# :title => "Panel Two",
|
|
14
|
-
# :lazy_loading => true
|
|
15
|
-
# }]
|
|
16
|
-
class AccordionPanel < Netzke::Base
|
|
17
|
-
|
|
18
|
-
include WrapLazyLoaded
|
|
19
|
-
|
|
20
|
-
js_property :layout, 'accordion'
|
|
21
|
-
js_property :component_load_mask, {:msg => null} # due to a probable bug in Ext's Accordion Layout (mask message is mis-layed-out), disabling mask message
|
|
22
|
-
|
|
23
|
-
js_method :init_component, <<-JS
|
|
24
|
-
function(params){
|
|
25
|
-
#{js_full_class_name}.superclass.initComponent.call(this);
|
|
26
|
-
this.items.each(function(item){
|
|
27
|
-
item.on('expand', function(i){
|
|
28
|
-
if (i && i.wrappedComponent && !i.items.first() && !i.beingLoaded) {
|
|
29
|
-
i.beingLoaded = true; // prevent more than one request per panel in case of fast clicking
|
|
30
|
-
this.loadNetzkeComponent({name: i.wrappedComponent, container: i.id}, function(){i.beingLoaded = false});
|
|
31
|
-
}
|
|
32
|
-
}, this);
|
|
33
|
-
}, this);
|
|
34
|
-
}
|
|
35
|
-
JS
|
|
36
|
-
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
module Netzke
|
|
2
|
-
module Basepack
|
|
3
|
-
module ActionColumn
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
|
|
6
|
-
included do |base|
|
|
7
|
-
|
|
8
|
-
# Returns registered actions
|
|
9
|
-
class_attribute :registered_column_actions
|
|
10
|
-
self.registered_column_actions = []
|
|
11
|
-
|
|
12
|
-
js_include :action_column
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
module ClassMethods
|
|
16
|
-
# Register an action
|
|
17
|
-
def register_column_action(name)
|
|
18
|
-
self.registered_column_actions |= [name]
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Use this method to define column actions in your component, e.g.:
|
|
22
|
-
#
|
|
23
|
-
# column_action :edit, :icon => "/images/icons/edit.png"
|
|
24
|
-
#
|
|
25
|
-
# TODO: List all options.
|
|
26
|
-
# TODO: think how it'll be possible to override individual column_actions (if need to bother at all)
|
|
27
|
-
def column_action(name, params = {})
|
|
28
|
-
params[:name] = name
|
|
29
|
-
params[:column] ||= "actions"
|
|
30
|
-
params[:icon] ||= "/extjs/examples/shared/icons/fam/cog.png"
|
|
31
|
-
params[:tooltip] = params[:tooltip].presence || name.to_s.humanize
|
|
32
|
-
params[:handler] ||= "on_#{name}"
|
|
33
|
-
register_column_action(name);
|
|
34
|
-
define_method "#{name}_column_action" do |record=nil| # TODO: this won't work in Ruby 1.8.7
|
|
35
|
-
params[:row_config] && record ? params.merge(params[:row_config].call(record, self)) : params
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def initial_columns(with_excluded = false)
|
|
41
|
-
orig_columns = super
|
|
42
|
-
|
|
43
|
-
action_column_names = column_actions.map{ |action| action[:column] }.uniq
|
|
44
|
-
action_columns = orig_columns.select{ |c| action_column_names.include? c[:name] }
|
|
45
|
-
|
|
46
|
-
# Append the column if none found AND no explicit column configuration was provided
|
|
47
|
-
if action_columns.empty? && !config[:columns]
|
|
48
|
-
action_columns = [{:name => "actions"}.merge(config[:override_columns].try(:fetch, :actions, nil) || {})]
|
|
49
|
-
orig_columns += action_columns
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
action_columns.each do |c|
|
|
53
|
-
c[:xtype] = :netzkeactioncolumn
|
|
54
|
-
c[:getter] = lambda do |r|
|
|
55
|
-
self.class.registered_column_actions.select{ |action_name| self.send("#{action_name}_column_action")[:column] == c[:name] }.map{ |action_name| self.send("#{action_name}_column_action", r) }.to_nifty_json
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
orig_columns
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def column_actions
|
|
63
|
-
self.class.registered_column_actions.map{ |action_name| self.send("#{action_name}_column_action")}
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|