netzke-basepack 0.7.7 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,400 +0,0 @@
|
|
1
|
-
module Netzke
|
2
|
-
module Basepack
|
3
|
-
class GridPanel < Netzke::Base
|
4
|
-
module Columns
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
extend ActiveSupport::Memoizable
|
7
|
-
|
8
|
-
# module ClassMethods
|
9
|
-
# # Columns to be displayed by the FieldConfigurator, "meta-columns". Each corresponds to a configuration
|
10
|
-
# # option for each column in the grid.
|
11
|
-
# def meta_columns
|
12
|
-
# [
|
13
|
-
# # Whether the column will be present in the grid, also in :hidden or :meta state. The value for this column will
|
14
|
-
# # always be sent to/from the JS grid to the server
|
15
|
-
# {:name => "included", :attr_type => :boolean, :width => 40, :header => "Incl", :default_value => true},
|
16
|
-
#
|
17
|
-
# # The name of the column. May be any accessible method or attribute of the data_class.
|
18
|
-
# {:name => "name", :attr_type => :string, :width => 200},
|
19
|
-
#
|
20
|
-
# # The header for the column.
|
21
|
-
# {:name => "label", :attr_type => :string, :width => 200, :header => "Header"},
|
22
|
-
#
|
23
|
-
# # The default value of this column. Is used when a new row in the grid gets created.
|
24
|
-
# {:name => "default_value", :attr_type => :string, :width => 200},
|
25
|
-
#
|
26
|
-
# # Options for drop-downs
|
27
|
-
# {:name => "combobox_options", :attr_type => :string, :editor => :textarea, :width => 200},
|
28
|
-
#
|
29
|
-
# # Whether the column is editable in the grid.
|
30
|
-
# {:name => "read_only", :attr_type => :boolean, :header => "R/O", :tooltip => "Read-only"},
|
31
|
-
#
|
32
|
-
# # Whether the column will be in the hidden state (hide/show columns from the column menu, if it's enabled).
|
33
|
-
# {:name => "hidden", :attr_type => :boolean},
|
34
|
-
#
|
35
|
-
# # Whether the column should have "grid filters" enabled
|
36
|
-
# # (see here: http://www.extjs.com/deploy/dev/examples/grid-filtering/grid-filter-local.html)
|
37
|
-
# {:name => "with_filters", :attr_type => :boolean, :default_value => true, :header => "Filters"},
|
38
|
-
#
|
39
|
-
# #
|
40
|
-
# # Below some rarely used parameters, hidden by default (you can always un-hide them from the column menu).
|
41
|
-
# #
|
42
|
-
#
|
43
|
-
# # The column's width
|
44
|
-
# {:name => "width", :attr_type => :integer, :hidden => true},
|
45
|
-
#
|
46
|
-
# # Whether the column should be hideable
|
47
|
-
# {:name => "hideable", :attr_type => :boolean, :default_value => true, :hidden => true},
|
48
|
-
#
|
49
|
-
# # Whether the column should be sortable (why change it? normally it's hardcoded)
|
50
|
-
# {:name => "sortable", :attr_type => :boolean, :default_value => true, :hidden => true},
|
51
|
-
# ]
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# end
|
55
|
-
|
56
|
-
# Normalized columns for the grid, e.g.:
|
57
|
-
# [{:name => :id, :hidden => true, ...}, {:name => :name, :editable => false, ...}, ...]
|
58
|
-
# Possible options:
|
59
|
-
# * +with_excluded+ - when set to true, also excluded columns will be returned (handy for dynamic column configuration)
|
60
|
-
# * +with_meta+ - when set to true, the meta column will be included as the last column
|
61
|
-
def columns(options = {})
|
62
|
-
[].tap do |cols|
|
63
|
-
if loaded_columns = load_columns
|
64
|
-
filter_out_excluded_columns(loaded_columns) unless options[:with_excluded]
|
65
|
-
cols.concat(reverse_merge_equally_named_columns(loaded_columns, initial_columns(options[:with_excluded])))
|
66
|
-
else
|
67
|
-
cols.concat(initial_columns(options[:with_excluded]))
|
68
|
-
end
|
69
|
-
|
70
|
-
append_meta_column(cols) if options[:with_meta]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
memoize :columns
|
75
|
-
|
76
|
-
def append_meta_column(cols)
|
77
|
-
cols << {}.tap do |c|
|
78
|
-
c.merge!(
|
79
|
-
:name => "meta",
|
80
|
-
:meta => true,
|
81
|
-
:getter => lambda do |r|
|
82
|
-
meta_data(r)
|
83
|
-
end
|
84
|
-
)
|
85
|
-
c[:default_value] = meta_default_data if meta_default_data.present?
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# default_value for the meta column; used when a new record is being created in the grid
|
90
|
-
def meta_default_data
|
91
|
-
get_default_association_values.present? ? { :association_values => get_default_association_values.literalize_keys } : {}
|
92
|
-
end
|
93
|
-
|
94
|
-
# Override it when you need extra meta data to be passed through the meta column
|
95
|
-
def meta_data(r)
|
96
|
-
{ :association_values => get_association_values(r).literalize_keys }
|
97
|
-
end
|
98
|
-
|
99
|
-
# Columns as a hash, for easier access to a specific column
|
100
|
-
def columns_hash
|
101
|
-
@columns_hash ||= columns.inject({}){|r,c| r.merge(c[:name].to_sym => c)}
|
102
|
-
end
|
103
|
-
|
104
|
-
# Columns that we fall back to when neither persistent columns, nor configured columns are present.
|
105
|
-
# If there's a model-level field configuration, it's being used.
|
106
|
-
# Otherwise the defaults straight from the ActiveRecord model ("netzke_attributes").
|
107
|
-
# Override this method if you want to provide a fix set of columns in your subclass.
|
108
|
-
def default_columns
|
109
|
-
@default_columns ||= load_model_level_attrs || data_class.netzke_attributes
|
110
|
-
end
|
111
|
-
|
112
|
-
def set_default_attr_type(c)
|
113
|
-
c[:attr_type] ||= association_attr?(c) ? :integer : data_adapter.attr_type(c.name)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Columns that were overridden with :override_columns config option.
|
117
|
-
def overridden_default_columns
|
118
|
-
if config[:override_columns].present?
|
119
|
-
result = []
|
120
|
-
default_columns.each do |col|
|
121
|
-
result << col.merge(config[:override_columns][col[:name].to_sym] || {})
|
122
|
-
end
|
123
|
-
result
|
124
|
-
else
|
125
|
-
default_columns
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# Columns that represent a smart merge of default_columns and columns passed during the configuration.
|
130
|
-
def initial_columns(with_excluded = false)
|
131
|
-
# Normalize here, as from the config we can get symbols (names) instead of hashes
|
132
|
-
columns_from_config = config[:columns] && normalize_attrs(config[:columns])
|
133
|
-
|
134
|
-
if columns_from_config
|
135
|
-
# automatically add a column that reflects the primary key (unless specified in the config)
|
136
|
-
columns_from_config.insert(0, {:name => data_class.primary_key.to_s}) unless columns_from_config.any?{ |c| c[:name] == data_class.primary_key }
|
137
|
-
|
138
|
-
# reverse-merge each column hash from config with each column hash from exposed_attributes
|
139
|
-
# (columns from config have higher priority)
|
140
|
-
for c in columns_from_config
|
141
|
-
corresponding_default_column = overridden_default_columns.find{ |k| k[:name] == c[:name] }
|
142
|
-
c.reverse_merge!(corresponding_default_column) if corresponding_default_column
|
143
|
-
end
|
144
|
-
columns_for_create = columns_from_config
|
145
|
-
else
|
146
|
-
# we didn't have columns configured in component's config, so, use the columns from the data class
|
147
|
-
columns_for_create = overridden_default_columns
|
148
|
-
end
|
149
|
-
|
150
|
-
filter_out_excluded_columns(columns_for_create) unless with_excluded
|
151
|
-
|
152
|
-
# Make the column config complete with the defaults.
|
153
|
-
# Note: dup is needed to avoid modifying original hashes.
|
154
|
-
columns_for_create.map { |c| c.dup.tap { |c| augment_column_config c } }
|
155
|
-
end
|
156
|
-
|
157
|
-
memoize :initial_columns
|
158
|
-
|
159
|
-
private
|
160
|
-
|
161
|
-
# Based on initial column config, e.g.:
|
162
|
-
#
|
163
|
-
# {:name=>"author__name", :attr_type=>:string}
|
164
|
-
#
|
165
|
-
# augment it with additional configuration params, e.g.:
|
166
|
-
#
|
167
|
-
# {:name=>"author__name", :attr_type=>:string, :editor=>{:xtype=>:netzkeremotecombo}, :assoc=>true, :virtual=>true, :header=>"Author name", :editable=>true, :sortable=>false, :filterable=>false}
|
168
|
-
#
|
169
|
-
# It may be handy to override it.
|
170
|
-
def augment_column_config(c)
|
171
|
-
# note: the order of these calls is important, as consequent calls may depend on the result of previous ones
|
172
|
-
set_default_xtype(c)
|
173
|
-
set_default_virtual(c)
|
174
|
-
set_default_text(c)
|
175
|
-
set_default_editable(c)
|
176
|
-
set_default_editor(c)
|
177
|
-
set_default_width(c)
|
178
|
-
set_default_hidden(c)
|
179
|
-
set_default_sortable(c)
|
180
|
-
set_default_filterable(c)
|
181
|
-
c[:assoc] = association_attr?(c)
|
182
|
-
end
|
183
|
-
|
184
|
-
def set_default_xtype(c)
|
185
|
-
return if c[:renderer] || c[:editor] # if user set those manually, we don't mess with column xtype
|
186
|
-
c[:xtype] ||= attr_type_to_xtype_map[c[:attr_type]]
|
187
|
-
end
|
188
|
-
|
189
|
-
def set_default_text(c)
|
190
|
-
c[:text] ||= c[:label] || data_class.human_attribute_name(c[:name])
|
191
|
-
end
|
192
|
-
|
193
|
-
def set_default_editor(c)
|
194
|
-
# if shouldn't be editable, don't set any default editor; also, specifying xtype takes care of the editor
|
195
|
-
return if c[:read_only] || c[:editable] == false
|
196
|
-
|
197
|
-
if association_attr?(c)
|
198
|
-
set_default_association_editor(c)
|
199
|
-
else
|
200
|
-
c[:editor] ||= editor_for_attr_type(c[:attr_type])
|
201
|
-
end
|
202
|
-
|
203
|
-
end
|
204
|
-
|
205
|
-
def set_default_width(c)
|
206
|
-
c[:width] ||= 50 if c[:attr_type] == :boolean
|
207
|
-
c[:width] ||= 150 if c[:attr_type] == :datetime
|
208
|
-
end
|
209
|
-
|
210
|
-
def set_default_hidden(c)
|
211
|
-
c[:hidden] = true if primary_key_attr?(c) && c[:hidden].nil?
|
212
|
-
end
|
213
|
-
|
214
|
-
def set_default_editable(c)
|
215
|
-
if c[:editable].nil?
|
216
|
-
c[:editable] = is_editable_column?(c)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def set_default_sortable(c)
|
221
|
-
# this *has* to be set to false if we don't want the column to be sortable (it's sortable by default in Ext)
|
222
|
-
c[:sortable] = !(c[:virtual] && !c[:sorting_scope]) if c[:sortable].nil?
|
223
|
-
end
|
224
|
-
|
225
|
-
def set_default_filterable(c)
|
226
|
-
c[:filterable] = !c[:virtual] if c[:filterable].nil?
|
227
|
-
end
|
228
|
-
|
229
|
-
|
230
|
-
# Detects an association column and sets up the proper editor.
|
231
|
-
def set_default_association_editor(c)
|
232
|
-
assoc, assoc_method = c[:name].split('__')
|
233
|
-
return unless assoc
|
234
|
-
|
235
|
-
assoc_method_type = data_adapter.get_assoc_property_type assoc, assoc_method
|
236
|
-
|
237
|
-
# if association column is boolean, display a checkbox (or alike), otherwise - a combobox (or alike)
|
238
|
-
if c[:nested_attribute]
|
239
|
-
c[:editor] ||= editor_for_attr_type(assoc_method_type)
|
240
|
-
else
|
241
|
-
c[:editor] ||= assoc_method_type == :boolean ? editor_for_attr_type(:boolean) : editor_for_association
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
# If the column should be editable
|
246
|
-
def is_editable_column?(c)
|
247
|
-
not_editable_if = primary_key_attr?(c)
|
248
|
-
not_editable_if ||= c[:virtual] && !association_attr?(c[:name])
|
249
|
-
not_editable_if ||= c[:read_only]
|
250
|
-
|
251
|
-
editable_if = data_class.column_names.include?(c[:name])
|
252
|
-
editable_if ||= data_class.instance_methods.map(&:to_s).include?("#{c[:name]}=")
|
253
|
-
editable_if ||= association_attr?(c[:name])
|
254
|
-
|
255
|
-
editable_if && !not_editable_if
|
256
|
-
end
|
257
|
-
|
258
|
-
def initial_columns_order
|
259
|
-
columns.map do |c|
|
260
|
-
{
|
261
|
-
:name => c[:name],
|
262
|
-
:width => c[:width],
|
263
|
-
:hidden => c[:hidden]
|
264
|
-
}
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def columns_order
|
269
|
-
if config[:persistence]
|
270
|
-
update_state(:columns_order, initial_columns_order) if columns_have_changed?
|
271
|
-
state[:columns_order] || initial_columns_order
|
272
|
-
else
|
273
|
-
initial_columns_order
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def columns_have_changed?
|
278
|
-
init_column_names = initial_columns_order.map{ |c| c[:name].to_s }.sort
|
279
|
-
stored_column_names = (state[:columns_order] || initial_columns_order).map{ |c| c[:name].to_s }.sort
|
280
|
-
init_column_names != stored_column_names
|
281
|
-
end
|
282
|
-
|
283
|
-
def filter_out_excluded_columns(cols)
|
284
|
-
cols.reject!{ |c| c[:included] == false }
|
285
|
-
end
|
286
|
-
|
287
|
-
# Stores modified columns in persistent storage
|
288
|
-
def save_columns!
|
289
|
-
# NetzkeFieldList.update_list_for_current_authority(global_id, columns(false), original_data_class.name) if persistent_config_enabled?
|
290
|
-
end
|
291
|
-
|
292
|
-
def load_columns
|
293
|
-
# NetzkeFieldList.read_list(global_id) if persistent_config_enabled?
|
294
|
-
end
|
295
|
-
|
296
|
-
def load_model_level_attrs
|
297
|
-
# NetzkeModelAttrList.read_list(data_class.name) if persistent_config_enabled?
|
298
|
-
end
|
299
|
-
|
300
|
-
# Column editor config for attribute type.
|
301
|
-
def editor_for_attr_type(type)
|
302
|
-
{:xtype => attr_type_to_editor_xtype_map[type] || :textfield}
|
303
|
-
end
|
304
|
-
|
305
|
-
# Column editor config for one-to-many association
|
306
|
-
def editor_for_association
|
307
|
-
{:xtype => :netzkeremotecombo}
|
308
|
-
end
|
309
|
-
|
310
|
-
# Hash that maps a column type to the editor xtype. Override if you want different editors.
|
311
|
-
def attr_type_to_editor_xtype_map
|
312
|
-
{
|
313
|
-
:integer => :numberfield,
|
314
|
-
:boolean => :checkbox,
|
315
|
-
:date => :datefield,
|
316
|
-
:datetime => :xdatetime,
|
317
|
-
:text => :textarea,
|
318
|
-
:string => :textfield
|
319
|
-
}
|
320
|
-
end
|
321
|
-
|
322
|
-
def attr_type_to_xtype_map
|
323
|
-
{
|
324
|
-
# :integer => :numbercolumn, # don't like the default formatter
|
325
|
-
:boolean => :checkcolumn,
|
326
|
-
:date => :datecolumn,
|
327
|
-
#:datetime => :datecolumn # TODO: replace with datetimepicker
|
328
|
-
}
|
329
|
-
end
|
330
|
-
|
331
|
-
# Default fields that will be displayed in the Add/Edit/Search forms
|
332
|
-
# When overriding this method, keep in mind that the fields inside the layout must be expanded (each field represented by a hash, not just a symbol)
|
333
|
-
def default_fields_for_forms
|
334
|
-
selected_columns = columns.select do |c|
|
335
|
-
data_class.column_names.include?(c[:name]) ||
|
336
|
-
data_class.instance_methods.include?("#{c[:name]}=") ||
|
337
|
-
association_attr?(c[:name])
|
338
|
-
end
|
339
|
-
|
340
|
-
selected_columns.map do |c|
|
341
|
-
field_config = {
|
342
|
-
:name => c[:name],
|
343
|
-
:field_label => c[:text] || c[:header],
|
344
|
-
:read_only => c[:read_only],
|
345
|
-
:editable => c[:editable]
|
346
|
-
}
|
347
|
-
|
348
|
-
# scopes for combobox options
|
349
|
-
field_config[:scopes] = c[:editor][:scopes] if c[:editor].is_a?(Hash)
|
350
|
-
|
351
|
-
field_config.merge!(c[:editor] || {})
|
352
|
-
|
353
|
-
field_config
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
# default_fields_for_forms extended with default values (for new-record form)
|
358
|
-
# def default_fields_for_forms_with_default_values
|
359
|
-
# res = default_fields_for_forms.dup
|
360
|
-
# each_attr_in(res) do |a|
|
361
|
-
# attr_name = a[:name].to_sym
|
362
|
-
# a[:value] = a[:default_value] || columns_hash[attr_name].try(:fetch, :default_value, nil) || data_class.netzke_attribute_hash[attr_name].try(:fetch, :default_value, nil)
|
363
|
-
# end
|
364
|
-
# res
|
365
|
-
# end
|
366
|
-
|
367
|
-
def columns_default_values
|
368
|
-
columns.inject({}) do |r,c|
|
369
|
-
assoc_name, assoc_method = c[:name].split '__'
|
370
|
-
if c[:default_value].nil?
|
371
|
-
r
|
372
|
-
else
|
373
|
-
if assoc_method
|
374
|
-
r.merge(data_adapter.foreign_key_for(assoc_name) || data_adapter.foreign_key_for(assoc_name) => c[:default_value])
|
375
|
-
else
|
376
|
-
r.merge(c[:name] => c[:default_value])
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
# Recursively traversess items (an array) and yields each found field (a hash with :name set)
|
383
|
-
def each_attr_in(items)
|
384
|
-
items.each do |item|
|
385
|
-
if item.is_a?(Hash)
|
386
|
-
each_attr_in(item[:items]) if item[:items].is_a?(Array)
|
387
|
-
yield(item) if item[:name]
|
388
|
-
end
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
# Receives 2 arrays of columns. Merges the missing config from the +source+ into +dest+, matching columns by name
|
393
|
-
def reverse_merge_equally_named_columns(dest, source)
|
394
|
-
dest.each{ |dc| dc.reverse_merge!(source.detect{ |sc| sc[:name] == dc[:name] } || {}) }
|
395
|
-
end
|
396
|
-
|
397
|
-
end
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
@@ -1,281 +0,0 @@
|
|
1
|
-
Ext.namespace('Ext.ux.dd');
|
2
|
-
|
3
|
-
Ext.ux.dd.GridDragDropRowOrder = Ext.extend(Ext.util.Observable,
|
4
|
-
{
|
5
|
-
copy: false,
|
6
|
-
|
7
|
-
scrollable: false,
|
8
|
-
|
9
|
-
constructor : function(config)
|
10
|
-
{
|
11
|
-
Ext.ux.dd.GridDragDropRowOrder.superclass.constructor.call(this);
|
12
|
-
if (config)
|
13
|
-
Ext.apply(this, config);
|
14
|
-
|
15
|
-
this.addEvents(
|
16
|
-
{
|
17
|
-
beforerowmove: true,
|
18
|
-
afterrowmove: true,
|
19
|
-
beforerowcopy: true,
|
20
|
-
afterrowcopy: true
|
21
|
-
});
|
22
|
-
},
|
23
|
-
|
24
|
-
init : function (grid)
|
25
|
-
{
|
26
|
-
this.grid = grid;
|
27
|
-
grid.enableDragDrop = true;
|
28
|
-
|
29
|
-
grid.on({
|
30
|
-
render: { fn: this.onGridRender, scope: this, single: true }
|
31
|
-
});
|
32
|
-
},
|
33
|
-
|
34
|
-
onGridRender : function (grid)
|
35
|
-
{
|
36
|
-
var self = this;
|
37
|
-
|
38
|
-
this.target = new Ext.dd.DropTarget(grid.getEl(),
|
39
|
-
{
|
40
|
-
ddGroup: grid.ddGroup || 'GridDD',
|
41
|
-
grid: grid,
|
42
|
-
gridDropTarget: this,
|
43
|
-
|
44
|
-
notifyDrop: function(dd, e, data)
|
45
|
-
{
|
46
|
-
// Remove drag lines. The 'if' condition prevents null error when drop occurs without dragging out of the selection area
|
47
|
-
if (this.currentRowEl)
|
48
|
-
{
|
49
|
-
this.currentRowEl.removeClass('grid-row-insert-below');
|
50
|
-
this.currentRowEl.removeClass('grid-row-insert-above');
|
51
|
-
}
|
52
|
-
|
53
|
-
// determine the row
|
54
|
-
var t = Ext.lib.Event.getTarget(e);
|
55
|
-
var rindex = this.grid.getView().findRowIndex(t);
|
56
|
-
if (rindex === false || rindex == data.rowIndex)
|
57
|
-
{
|
58
|
-
return false;
|
59
|
-
}
|
60
|
-
// fire the before move/copy event
|
61
|
-
if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
|
62
|
-
{
|
63
|
-
return false;
|
64
|
-
}
|
65
|
-
|
66
|
-
// update the store
|
67
|
-
var ds = this.grid.getStore();
|
68
|
-
|
69
|
-
// Changes for multiselction by Spirit
|
70
|
-
var selections = new Array();
|
71
|
-
var keys = ds.data.keys;
|
72
|
-
for (var key in keys)
|
73
|
-
{
|
74
|
-
for (var i = 0; i < data.selections.length; i++)
|
75
|
-
{
|
76
|
-
if (keys[key] == data.selections[i].id)
|
77
|
-
{
|
78
|
-
// Exit to prevent drop of selected records on itself.
|
79
|
-
if (rindex == key)
|
80
|
-
{
|
81
|
-
return false;
|
82
|
-
}
|
83
|
-
selections.push(data.selections[i]);
|
84
|
-
}
|
85
|
-
}
|
86
|
-
}
|
87
|
-
|
88
|
-
// fix rowindex based on before/after move
|
89
|
-
if (rindex > data.rowIndex && this.rowPosition < 0)
|
90
|
-
{
|
91
|
-
rindex--;
|
92
|
-
}
|
93
|
-
if (rindex < data.rowIndex && this.rowPosition > 0)
|
94
|
-
{
|
95
|
-
rindex++;
|
96
|
-
}
|
97
|
-
|
98
|
-
// fix rowindex for multiselection
|
99
|
-
if (rindex > data.rowIndex && data.selections.length > 1)
|
100
|
-
{
|
101
|
-
rindex = rindex - (data.selections.length - 1);
|
102
|
-
}
|
103
|
-
|
104
|
-
// we tried to move this node before the next sibling, we stay in place
|
105
|
-
if (rindex == data.rowIndex)
|
106
|
-
{
|
107
|
-
return false;
|
108
|
-
}
|
109
|
-
|
110
|
-
// fire the before move/copy event
|
111
|
-
/* dupe - does it belong here or above???
|
112
|
-
if (this.gridDropTarget.fireEvent(self.copy ? 'beforerowcopy' : 'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections, 123) === false)
|
113
|
-
{
|
114
|
-
return false;
|
115
|
-
}
|
116
|
-
*/
|
117
|
-
|
118
|
-
if (!self.copy)
|
119
|
-
{
|
120
|
-
for (var i = 0; i < data.selections.length; i++)
|
121
|
-
{
|
122
|
-
ds.remove(ds.getById(data.selections[i].id));
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
for (var i = selections.length - 1; i >= 0; i--)
|
127
|
-
{
|
128
|
-
var insertIndex = rindex;
|
129
|
-
ds.insert(insertIndex, selections[i]);
|
130
|
-
}
|
131
|
-
|
132
|
-
// re-select the row(s)
|
133
|
-
var sm = this.grid.getSelectionModel();
|
134
|
-
if (sm)
|
135
|
-
{
|
136
|
-
sm.selectRecords(data.selections);
|
137
|
-
}
|
138
|
-
|
139
|
-
// console.info(this.gridDropTarget);
|
140
|
-
|
141
|
-
// fire the after move/copy event
|
142
|
-
this.gridDropTarget.fireEvent(self.copy ? 'afterrowcopy' : 'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);
|
143
|
-
return true;
|
144
|
-
},
|
145
|
-
|
146
|
-
notifyOver: function(dd, e, data)
|
147
|
-
{
|
148
|
-
// WIP: todo - rewrite Ext.lib call to Ext 4
|
149
|
-
var t = Ext.lib.Event.getTarget(e);
|
150
|
-
var rindex = this.grid.getView().findRowIndex(t);
|
151
|
-
|
152
|
-
// Similar to the code in notifyDrop. Filters for selected rows and quits function if any one row matches the current selected row.
|
153
|
-
var ds = this.grid.getStore();
|
154
|
-
var keys = ds.data.keys;
|
155
|
-
for (var key in keys)
|
156
|
-
{
|
157
|
-
for (var i = 0; i < data.selections.length; i++)
|
158
|
-
{
|
159
|
-
if (keys[key] == data.selections[i].id)
|
160
|
-
{
|
161
|
-
if (rindex == key)
|
162
|
-
{
|
163
|
-
if (this.currentRowEl)
|
164
|
-
{
|
165
|
-
this.currentRowEl.removeClass('grid-row-insert-below');
|
166
|
-
this.currentRowEl.removeClass('grid-row-insert-above');
|
167
|
-
}
|
168
|
-
return this.dropNotAllowed;
|
169
|
-
}
|
170
|
-
}
|
171
|
-
}
|
172
|
-
}
|
173
|
-
|
174
|
-
// If on first row, remove upper line. Prevents negative index error as a result of rindex going negative.
|
175
|
-
if (rindex < 0 || rindex === false)
|
176
|
-
{
|
177
|
-
this.currentRowEl.removeClass('grid-row-insert-above');
|
178
|
-
return this.dropNotAllowed;
|
179
|
-
}
|
180
|
-
|
181
|
-
try
|
182
|
-
{
|
183
|
-
var currentRow = this.grid.getView().getRow(rindex);
|
184
|
-
// Find position of row relative to page (adjusting for grid's scroll position)
|
185
|
-
var resolvedRow = new Ext.Element(currentRow).getY() - this.grid.getView().scroller.dom.scrollTop;
|
186
|
-
var rowHeight = currentRow.offsetHeight;
|
187
|
-
|
188
|
-
// Cursor relative to a row. -ve value implies cursor is above the row's middle and +ve value implues cursor is below the row's middle.
|
189
|
-
this.rowPosition = e.getPageY() - resolvedRow - (rowHeight/2);
|
190
|
-
|
191
|
-
// Clear drag line.
|
192
|
-
if (this.currentRowEl)
|
193
|
-
{
|
194
|
-
this.currentRowEl.removeClass('grid-row-insert-below');
|
195
|
-
this.currentRowEl.removeClass('grid-row-insert-above');
|
196
|
-
}
|
197
|
-
|
198
|
-
if (this.rowPosition > 0)
|
199
|
-
{
|
200
|
-
// If the pointer is on the bottom half of the row.
|
201
|
-
this.currentRowEl = new Ext.Element(currentRow);
|
202
|
-
this.currentRowEl.addClass('grid-row-insert-below');
|
203
|
-
}
|
204
|
-
else
|
205
|
-
{
|
206
|
-
// If the pointer is on the top half of the row.
|
207
|
-
if (rindex - 1 >= 0)
|
208
|
-
{
|
209
|
-
var previousRow = this.grid.getView().getRow(rindex - 1);
|
210
|
-
this.currentRowEl = new Ext.Element(previousRow);
|
211
|
-
this.currentRowEl.addClass('grid-row-insert-below');
|
212
|
-
}
|
213
|
-
else
|
214
|
-
{
|
215
|
-
// If the pointer is on the top half of the first row.
|
216
|
-
this.currentRowEl.addClass('grid-row-insert-above');
|
217
|
-
}
|
218
|
-
}
|
219
|
-
}
|
220
|
-
catch (err)
|
221
|
-
{
|
222
|
-
console.warn(err);
|
223
|
-
rindex = false;
|
224
|
-
}
|
225
|
-
return (rindex === false)? this.dropNotAllowed : this.dropAllowed;
|
226
|
-
},
|
227
|
-
|
228
|
-
notifyOut: function(dd, e, data)
|
229
|
-
{
|
230
|
-
// Remove drag lines when pointer leaves the gridView.
|
231
|
-
if (this.currentRowEl)
|
232
|
-
{
|
233
|
-
this.currentRowEl.removeClass('grid-row-insert-above');
|
234
|
-
this.currentRowEl.removeClass('grid-row-insert-below');
|
235
|
-
}
|
236
|
-
}
|
237
|
-
});
|
238
|
-
|
239
|
-
if (this.targetCfg)
|
240
|
-
{
|
241
|
-
Ext.apply(this.target, this.targetCfg);
|
242
|
-
}
|
243
|
-
|
244
|
-
if (this.scrollable)
|
245
|
-
{
|
246
|
-
Ext.dd.ScrollManager.register(grid.getView().getEditorParent());
|
247
|
-
grid.on({
|
248
|
-
beforedestroy: this.onBeforeDestroy,
|
249
|
-
scope: this,
|
250
|
-
single: true
|
251
|
-
});
|
252
|
-
}
|
253
|
-
},
|
254
|
-
|
255
|
-
getTarget: function()
|
256
|
-
{
|
257
|
-
return this.target;
|
258
|
-
},
|
259
|
-
|
260
|
-
getGrid: function()
|
261
|
-
{
|
262
|
-
return this.grid;
|
263
|
-
},
|
264
|
-
|
265
|
-
getCopy: function()
|
266
|
-
{
|
267
|
-
return this.copy ? true : false;
|
268
|
-
},
|
269
|
-
|
270
|
-
setCopy: function(b)
|
271
|
-
{
|
272
|
-
this.copy = b ? true : false;
|
273
|
-
},
|
274
|
-
|
275
|
-
onBeforeDestroy : function (grid)
|
276
|
-
{
|
277
|
-
// if we previously registered with the scroll manager, unregister
|
278
|
-
// it (if we don't it will lead to problems in IE)
|
279
|
-
Ext.dd.ScrollManager.unregister(grid.getView().getEditorParent());
|
280
|
-
}
|
281
|
-
});
|