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
File without changes
|
@@ -3,7 +3,7 @@
|
|
3
3
|
var selModel = this.getSelectionModel();
|
4
4
|
if (selModel.getCount() > 1) {
|
5
5
|
var recordId = selModel.selected.first().getId();
|
6
|
-
this.
|
6
|
+
this.netzkeLoadComponent("multi_edit_window", {
|
7
7
|
params: {record_id: recordId},
|
8
8
|
callback: function(w){
|
9
9
|
w.show();
|
@@ -25,7 +25,7 @@
|
|
25
25
|
}, scope: this});
|
26
26
|
} else {
|
27
27
|
var recordId = selModel.selected.first().getId();
|
28
|
-
this.
|
28
|
+
this.netzkeLoadComponent("edit_window", {
|
29
29
|
params: {record_id: recordId},
|
30
30
|
callback: function(w){
|
31
31
|
w.show();
|
@@ -39,7 +39,7 @@
|
|
39
39
|
},
|
40
40
|
|
41
41
|
onAddInForm: function(){
|
42
|
-
this.
|
42
|
+
this.netzkeLoadComponent("add_window", {callback: function(w){
|
43
43
|
w.show();
|
44
44
|
w.on('close', function(){
|
45
45
|
if (w.closeRes === "ok") {
|
@@ -113,6 +113,9 @@
|
|
113
113
|
},
|
114
114
|
|
115
115
|
onColumnMove: function(ct, cl, oldIndex, newIndex){
|
116
|
+
// when moving a column forwards, the new index appears to be 1 too high; a bug in Ext JS? Fixing.
|
117
|
+
if (newIndex > oldIndex) newIndex--;
|
118
|
+
|
116
119
|
this.moveColumn({
|
117
120
|
old_index: oldIndex,
|
118
121
|
new_index: newIndex
|
@@ -138,7 +141,7 @@
|
|
138
141
|
var ids = [];
|
139
142
|
// collect records ids
|
140
143
|
Ext.each(records, function(r){ids.push(r.id)});
|
141
|
-
// call
|
144
|
+
// call Grid's API
|
142
145
|
this.moveRows({ids: Ext.encode(ids), new_index: newIndex});
|
143
146
|
},
|
144
147
|
|
@@ -169,7 +172,7 @@
|
|
169
172
|
|
170
173
|
// Not a very clean approach to clean-up. The problem is that this way the advanced search functionality stops being really pluggable. With Ext JS 4 find the way to make it truely so.
|
171
174
|
onDestroy: function(){
|
172
|
-
|
175
|
+
this.callParent();
|
173
176
|
|
174
177
|
// Destroy the search window (here's the problem: we are not supposed to know it exists)
|
175
178
|
if (this.searchWindow) {
|
@@ -8,92 +8,28 @@
|
|
8
8
|
multiSelect: true,
|
9
9
|
|
10
10
|
initComponent: function(){
|
11
|
-
var metaColumn;
|
12
|
-
var fields = []; // field configs for the underlying data model
|
13
|
-
|
14
11
|
this.plugins = this.plugins || [];
|
15
12
|
this.features = this.features || [];
|
16
13
|
|
17
14
|
// Enable filters feature
|
18
|
-
this.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Ext.each(this.columns, function(c, i){
|
25
|
-
|
26
|
-
this.normalizeRenderer(c);
|
27
|
-
|
28
|
-
// Build the field configuration for this column
|
29
|
-
var fieldConfig = {name: c.name, defaultValue: c.defaultValue, useNull: true}; // useNull is needed to not convert nils to 0 in associations!
|
30
|
-
|
31
|
-
if (c.name !== 'meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
|
32
|
-
|
33
|
-
if (c.attrType == 'datetime') {
|
34
|
-
fieldConfig.dateFormat = 'Y-m-d H:i:s'; // set the format in which we receive datetime from the server (so that the model can parse it)
|
35
|
-
|
36
|
-
// While for 'date' columns the renderer is set up automatically (through using column's xtype), there's no appropriate xtype for our custom datetime column.
|
37
|
-
// Thus, we need to set the renderer manually.
|
38
|
-
// NOTE: for Ext there's no distinction b/w date and datetime; date fields can include time.
|
39
|
-
if (!c.renderer) {
|
40
|
-
// format in which the data will be rendered; if c.format is nil, Ext.Date.defaultFormat extended with time will be used
|
41
|
-
c.renderer = Ext.util.Format.dateRenderer(c.format || Ext.Date.defaultFormat + " H:i:s");
|
42
|
-
}
|
43
|
-
};
|
44
|
-
|
45
|
-
fields.push(fieldConfig);
|
46
|
-
|
47
|
-
// We will not use meta columns as actual columns (not even hidden) - only to create the records
|
48
|
-
if (c.meta) {
|
49
|
-
metaColumn = c;
|
50
|
-
return;
|
51
|
-
}
|
52
|
-
|
53
|
-
// if comboboxOptions are provided, we render a combobox instead of textfield
|
54
|
-
// if (c.comboboxOptions && c.editor.xtype === "textfield") {
|
55
|
-
// c.editor = {xtype: "combobox", options: c.comboboxOptions.split('\\n')}
|
56
|
-
// }
|
57
|
-
|
58
|
-
|
59
|
-
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
60
|
-
|
61
|
-
if (c.assoc) {
|
62
|
-
// Editor for association column
|
63
|
-
c.editor = Ext.apply({
|
64
|
-
parentId: this.id,
|
65
|
-
name: c.name
|
66
|
-
}, c.editor);
|
67
|
-
|
68
|
-
// Renderer for association column
|
69
|
-
this.normalizeAssociationRenderer(c);
|
70
|
-
}
|
71
|
-
|
72
|
-
if (c.editor) {
|
73
|
-
Ext.applyIf(c.editor, {selectOnFocus: true});
|
74
|
-
}
|
75
|
-
|
76
|
-
// Setting the default filter type
|
77
|
-
if (c.filterable && !c.filter) {
|
78
|
-
c.filter = {type: c.assoc ? 'string' : this.fieldTypeForAttrType(c.attrType)};
|
79
|
-
}
|
80
|
-
|
81
|
-
// setting dataIndex
|
82
|
-
c.dataIndex = c.name;
|
83
|
-
|
84
|
-
}, this);
|
15
|
+
if (this.enableColumnFilters) {
|
16
|
+
this.features.push({
|
17
|
+
encode: true,
|
18
|
+
ftype: 'filters'
|
19
|
+
});
|
20
|
+
}
|
85
21
|
|
86
|
-
|
22
|
+
// Normalize columns. Extract data fields and meta column.
|
23
|
+
this.processColumns();
|
87
24
|
|
88
25
|
// Define the model
|
89
26
|
Ext.define(this.id, {
|
90
27
|
extend: 'Ext.data.Model',
|
91
28
|
idProperty: this.pri, // Primary key
|
92
|
-
fields: fields
|
29
|
+
fields: this.fields
|
93
30
|
});
|
94
|
-
|
95
|
-
|
96
|
-
Ext.Array.remove(this.columns, metaColumn);
|
31
|
+
delete this.pri;
|
32
|
+
delete this.fields;
|
97
33
|
|
98
34
|
// Prepare column model config with columns in the correct order; columns out of order go to the end.
|
99
35
|
var colModelConfig = [];
|
@@ -117,49 +53,12 @@
|
|
117
53
|
// ... instead, define own column model
|
118
54
|
this.columns = colModelConfig;
|
119
55
|
|
120
|
-
|
121
|
-
|
122
|
-
// DirectProxy that uses our Ext.direct provider
|
123
|
-
var proxy = Ext.create('Ext.data.proxy.Direct', {
|
124
|
-
directFn: Netzke.providers[this.id].getData,
|
125
|
-
reader: reader,
|
126
|
-
listeners: {
|
127
|
-
exception: {
|
128
|
-
fn: this.loadExceptionHandler,
|
129
|
-
scope: this
|
130
|
-
},
|
131
|
-
load: { // Netzke-introduced event; this will also be fired when an exception occurs.
|
132
|
-
fn: function(proxy, response, operation) {
|
133
|
-
// besides getting data into the store, we may also get commands to execute
|
134
|
-
response = response.result;
|
135
|
-
if (response) { // or did we have an exception?
|
136
|
-
Ext.each(['data', 'total', 'success'], function(property){delete response[property];});
|
137
|
-
this.bulkExecute(response);
|
138
|
-
}
|
139
|
-
},
|
140
|
-
scope: this
|
141
|
-
}
|
142
|
-
}
|
143
|
-
});
|
144
|
-
|
145
|
-
this.store = Ext.create('Ext.data.Store', {
|
146
|
-
model: this.id,
|
147
|
-
proxy: proxy,
|
148
|
-
pruneModifiedRecords: true,
|
149
|
-
remoteSort: true,
|
150
|
-
pageSize: this.rowsPerPage
|
151
|
-
});
|
56
|
+
// data store
|
57
|
+
this.store = this.buildStore();
|
152
58
|
|
59
|
+
// load inline data if available
|
153
60
|
if (this.inlineData) this.store.loadRawData(this.inlineData);
|
154
61
|
|
155
|
-
// Drag'n'Drop
|
156
|
-
if (this.enableRowsReordering){
|
157
|
-
this.ddPlugin = new Ext.ux.dd.GridDragDropRowOrder({
|
158
|
-
scrollable: true // enable scrolling support (default is false)
|
159
|
-
});
|
160
|
-
this.plugins.push(this.ddPlugin);
|
161
|
-
}
|
162
|
-
|
163
62
|
// Cell editing
|
164
63
|
if (!this.prohibitUpdate) {
|
165
64
|
this.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {pluginId: 'celleditor'}));
|
@@ -172,7 +71,7 @@
|
|
172
71
|
xtype: 'pagingtoolbar',
|
173
72
|
dock: 'bottom',
|
174
73
|
store: this.store,
|
175
|
-
items: this.bbar && ["-"].concat(this.bbar) // append the
|
74
|
+
items: this.bbar && ["-"].concat(this.bbar) // append the passed bbar
|
176
75
|
});
|
177
76
|
} else if (this.bbar) {
|
178
77
|
this.dockedItems.push({
|
@@ -182,10 +81,8 @@
|
|
182
81
|
});
|
183
82
|
}
|
184
83
|
|
185
|
-
|
186
84
|
delete this.bbar;
|
187
85
|
|
188
|
-
// Now let Ext.grid.EditorGridPanel do the rest (original initComponent)
|
189
86
|
this.callParent();
|
190
87
|
|
191
88
|
// Context menu
|
@@ -215,21 +112,9 @@
|
|
215
112
|
if (this.actions.edit) this.actions.edit.setDisabled(selModel.getCount() != 1 || this.prohibitUpdate);
|
216
113
|
}, this);
|
217
114
|
|
218
|
-
// Drag n Drop event
|
219
|
-
if (this.enableRowsReordering){
|
220
|
-
this.ddPlugin.on('afterrowmove', this.onAfterRowMove, this);
|
221
|
-
}
|
222
|
-
|
223
115
|
// WIP: GridView
|
224
116
|
this.getView().getRowClass = this.defaultGetRowClass;
|
225
117
|
|
226
|
-
// this.on('edit', function(editor, e) {
|
227
|
-
// if (e.column.assoc && e.record.get('meta')) {
|
228
|
-
// console.log("editor:", editor);
|
229
|
-
// editor.setRawValue("");
|
230
|
-
// }
|
231
|
-
// });
|
232
|
-
|
233
118
|
// When starting editing as assocition column, pre-load the combobox store from the meta column, so that we don't see the real value of this cell (the id of the associated record), but rather the associated record by the configured method.
|
234
119
|
this.on('beforeedit', function(editor, e){
|
235
120
|
if (e.column.assoc && e.record.get('meta')) {
|
@@ -246,7 +131,7 @@
|
|
246
131
|
}
|
247
132
|
}, this);
|
248
133
|
|
249
|
-
this.on('
|
134
|
+
this.on('afterlayout', function() {
|
250
135
|
// Persistence-related events (afterrender to avoid blank event firing on render)
|
251
136
|
if (this.persistence) {
|
252
137
|
// Inform the server part about column operations
|
@@ -258,6 +143,109 @@
|
|
258
143
|
}, this);
|
259
144
|
},
|
260
145
|
|
146
|
+
processColumns: function() {
|
147
|
+
this.fields = [];
|
148
|
+
|
149
|
+
// Run through columns and set up different configuration for each
|
150
|
+
Ext.each(this.columns, function(c, i){
|
151
|
+
|
152
|
+
this.normalizeRenderer(c);
|
153
|
+
|
154
|
+
// Build the field configuration for this column
|
155
|
+
var fieldConfig = {name: c.name, defaultValue: c.defaultValue, useNull: true}; // useNull is needed to not convert nils to 0 in associations!
|
156
|
+
|
157
|
+
if (c.name !== 'meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
|
158
|
+
|
159
|
+
if (c.attrType == 'datetime') {
|
160
|
+
fieldConfig.dateFormat = 'Y-m-d H:i:s'; // set the format in which we receive datetime from the server (so that the model can parse it)
|
161
|
+
|
162
|
+
// While for 'date' columns the renderer is set up automatically (through using column's xtype), there's no appropriate xtype for our custom datetime column.
|
163
|
+
// Thus, we need to set the renderer manually.
|
164
|
+
// NOTE: for Ext there's no distinction b/w date and datetime; date fields can include time.
|
165
|
+
if (!c.renderer) {
|
166
|
+
// format in which the data will be rendered; if c.format is nil, Ext.Date.defaultFormat extended with time will be used
|
167
|
+
c.renderer = Ext.util.Format.dateRenderer(c.format || Ext.Date.defaultFormat + " H:i:s");
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
this.fields.push(fieldConfig);
|
172
|
+
|
173
|
+
// We will not use meta columns as actual columns (not even hidden) - only to create the records
|
174
|
+
if (c.meta) {
|
175
|
+
this.metaColumn = c;
|
176
|
+
return;
|
177
|
+
}
|
178
|
+
|
179
|
+
// Set rendeder for association columns (the one displaying associations by the specified method instead of id)
|
180
|
+
if (c.assoc) {
|
181
|
+
// Editor for association column
|
182
|
+
c.editor = Ext.apply({
|
183
|
+
name: c.name
|
184
|
+
}, c.editor);
|
185
|
+
|
186
|
+
// Renderer for association column
|
187
|
+
this.normalizeAssociationRenderer(c);
|
188
|
+
}
|
189
|
+
|
190
|
+
if (c.editor) {
|
191
|
+
Ext.applyIf(c.editor, {selectOnFocus: true, parentId: this.id});
|
192
|
+
}
|
193
|
+
|
194
|
+
// Setting the default filter type
|
195
|
+
if (c.filterable && !c.filter) {
|
196
|
+
c.filter = {type: c.assoc ? 'string' : this.fieldTypeForAttrType(c.attrType)};
|
197
|
+
}
|
198
|
+
|
199
|
+
// setting dataIndex
|
200
|
+
c.dataIndex = c.name;
|
201
|
+
|
202
|
+
}, this);
|
203
|
+
},
|
204
|
+
|
205
|
+
buildStore: function() {
|
206
|
+
var store = Ext.create('Ext.data.Store', Ext.apply({
|
207
|
+
model: this.id,
|
208
|
+
proxy: this.buildProxy(),
|
209
|
+
pruneModifiedRecords: true,
|
210
|
+
remoteSort: true,
|
211
|
+
pageSize: this.rowsPerPage,
|
212
|
+
autoLoad: !this.loadInlineData
|
213
|
+
}, this.dataStore));
|
214
|
+
|
215
|
+
delete this.dataStore;
|
216
|
+
|
217
|
+
return store;
|
218
|
+
},
|
219
|
+
|
220
|
+
buildProxy: function() {
|
221
|
+
// DirectProxy that uses our Ext.direct provider
|
222
|
+
return Ext.create('Ext.data.proxy.Direct', {
|
223
|
+
directFn: Netzke.providers[this.id].getData,
|
224
|
+
reader: this.buildReader(),
|
225
|
+
listeners: {
|
226
|
+
exception: {
|
227
|
+
fn: this.loadExceptionHandler,
|
228
|
+
scope: this
|
229
|
+
},
|
230
|
+
load: { // Netzke-introduced event; this will also be fired when an exception occurs.
|
231
|
+
fn: function(proxy, response, operation) {
|
232
|
+
// besides getting data into the store, we may also get commands to execute
|
233
|
+
response = response.result;
|
234
|
+
if (response) { // or did we have an exception?
|
235
|
+
Ext.each(['data', 'total', 'success'], function(property){delete response[property];});
|
236
|
+
this.netzkeBulkExecute(response);
|
237
|
+
}
|
238
|
+
},
|
239
|
+
scope: this
|
240
|
+
}
|
241
|
+
}
|
242
|
+
});
|
243
|
+
},
|
244
|
+
|
245
|
+
buildReader: function() {
|
246
|
+
return Ext.create('Ext.data.reader.Array', {root: 'data', totalProperty: 'total'});
|
247
|
+
},
|
248
|
+
|
261
249
|
fieldTypeForAttrType: function(attrType){
|
262
250
|
var map = {
|
263
251
|
integer : 'int',
|
@@ -279,7 +267,7 @@
|
|
279
267
|
var dataRecords = this.getStore().getProxy().getReader().read(data);
|
280
268
|
this.getStore().loadData(dataRecords.records);
|
281
269
|
Ext.each(['data', 'total', 'success'], function(property){delete data[property];}, this);
|
282
|
-
this.
|
270
|
+
this.netzkeBulkExecute(data);
|
283
271
|
},
|
284
272
|
|
285
273
|
// Tries editing the first editable (i.e. not hidden, not read-only) sell
|
File without changes
|
@@ -0,0 +1,216 @@
|
|
1
|
+
module Netzke
|
2
|
+
module Basepack
|
3
|
+
class Grid < Netzke::Base
|
4
|
+
module Services
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
endpoint :get_data do |params, this|
|
9
|
+
# not a usual Netzke endpoint, as it's being used by the Ext.data.DirectStore
|
10
|
+
this.merge! get_data(params)
|
11
|
+
end
|
12
|
+
|
13
|
+
endpoint :post_data do |params, this|
|
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
|
+
this.update_new_records mod_records[:create]
|
26
|
+
this.update_mod_records mod_records[:update] if mod_records[:update]
|
27
|
+
this.netzke_feedback @flash
|
28
|
+
end
|
29
|
+
|
30
|
+
endpoint :delete_data do |params, this|
|
31
|
+
if !config[:prohibit_delete]
|
32
|
+
record_ids = ActiveSupport::JSON.decode(params[:records])
|
33
|
+
data_adapter.destroy(record_ids)
|
34
|
+
on_data_changed
|
35
|
+
this.netzke_feedback I18n.t('netzke.basepack.grid.deleted_n_records', :n => record_ids.size)
|
36
|
+
this.load_store_data get_data
|
37
|
+
else
|
38
|
+
this.netzke_feedback I18n.t('netzke.basepack.grid.cannot_delete')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
endpoint :resize_column do |params, this|
|
43
|
+
raise "Called resize_column endpoint while not configured to do so" if !config[:persistence]
|
44
|
+
|
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
|
+
state[:columns_order] = current_columns_order
|
48
|
+
end
|
49
|
+
|
50
|
+
endpoint :move_column do |params, this|
|
51
|
+
raise "Called move_column endpoint while not configured to do so" if !config[:persistence]
|
52
|
+
|
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
|
+
state[:columns_order] = current_columns_order
|
62
|
+
end
|
63
|
+
|
64
|
+
endpoint :hide_column do |params, this|
|
65
|
+
raise "Called hide_column endpoint while not configured to do so" if !config[:persistence]
|
66
|
+
current_columns_order = state[:columns_order] || initial_columns_order
|
67
|
+
current_columns_order[normalize_index(params[:index].to_i)][:hidden] = params[:hidden]
|
68
|
+
state[:columns_order] = current_columns_order
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns options for a combobox
|
72
|
+
# params receive:
|
73
|
+
# +attr+ - column's name
|
74
|
+
# +query+ - what's typed-in in the combobox
|
75
|
+
# +id+ - selected record id
|
76
|
+
endpoint :get_combobox_options do |params, this|
|
77
|
+
column = final_columns.detect{ |c| c[:name] == params[:attr] }
|
78
|
+
this.data = data_adapter.combo_data(column, params[:query])
|
79
|
+
end
|
80
|
+
|
81
|
+
endpoint :move_rows do |params, this|
|
82
|
+
data_adapter.move_records(params)
|
83
|
+
end
|
84
|
+
|
85
|
+
# When providing the edit_form component, fill in the form with the requested record
|
86
|
+
endpoint :deliver_component do |params, this|
|
87
|
+
if params[:name] == 'edit_window'
|
88
|
+
components[:edit_window].form_config.record_id = params[:record_id].to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
super(params, this)
|
92
|
+
end
|
93
|
+
|
94
|
+
# TODO: functionality of the following 2 endpoints could probably be improved by subclassing Basepack::Form as a dedicated form for adding/editing records in a grid.
|
95
|
+
# Process the submit of multi-editing form ourselves
|
96
|
+
endpoint :multi_edit_window__multi_edit_form__netzke_submit do |params, this|
|
97
|
+
ids = ActiveSupport::JSON.decode(params.delete(:ids))
|
98
|
+
data = ids.collect{ |id| ActiveSupport::JSON.decode(params[:data]).merge("id" => id) }
|
99
|
+
|
100
|
+
data.map!{|el| el.delete_if{ |k,v| v.is_a?(String) && v.blank? }} # only interested in set values
|
101
|
+
|
102
|
+
mod_records_count = process_data(data, :update).count
|
103
|
+
|
104
|
+
# remove duplicated flash messages
|
105
|
+
@flash = @flash.inject([]){ |r,hsh| r.include?(hsh) ? r : r.push(hsh) }
|
106
|
+
|
107
|
+
if mod_records_count > 0
|
108
|
+
on_data_changed
|
109
|
+
this.netzke_set_result("ok")
|
110
|
+
this.on_submit_success
|
111
|
+
end
|
112
|
+
|
113
|
+
this.netzke_feedback(@flash)
|
114
|
+
end
|
115
|
+
|
116
|
+
# The following two look a bit hackish, but serve to invoke on_data_changed when a form gets successfully submitted
|
117
|
+
endpoint :add_window__add_form__netzke_submit do |params, this|
|
118
|
+
this.merge!(component_instance(:add_window__add_form).invoke_endpoint(:netzke_submit, params))
|
119
|
+
on_data_changed if this.set_form_values.present?
|
120
|
+
this.delete(:set_form_values)
|
121
|
+
end
|
122
|
+
|
123
|
+
endpoint :edit_window__edit_form__netzke_submit do |params, this|
|
124
|
+
this.merge!(component_instance(:edit_window__edit_form).invoke_endpoint(:netzke_submit, params))
|
125
|
+
on_data_changed if this.set_form_values.present?
|
126
|
+
this.delete(:set_form_values)
|
127
|
+
end
|
128
|
+
end # included
|
129
|
+
|
130
|
+
# Implementation for the "get_data" endpoint
|
131
|
+
def get_data(*args)
|
132
|
+
params = args.first || {} # params are optional!
|
133
|
+
if !config[:prohibit_read]
|
134
|
+
{}.tap do |res|
|
135
|
+
records = get_records(params)
|
136
|
+
res[:data] = records.map{|r| data_adapter.record_to_array(r, final_columns(:with_meta => true))}
|
137
|
+
res[:total] = count_records(params) if config[:enable_pagination]
|
138
|
+
end
|
139
|
+
else
|
140
|
+
flash :error => "You don't have permissions to read data"
|
141
|
+
{ :netzke_feedback => @flash }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
protected
|
146
|
+
|
147
|
+
# Returns an array of records.
|
148
|
+
def get_records(params)
|
149
|
+
params[:limit] = config[:rows_per_page] if config[:enable_pagination]
|
150
|
+
params[:scope] = config[:scope] # note, params[:scope] becomes ActiveSupport::HashWithIndifferentAccess
|
151
|
+
|
152
|
+
data_adapter.get_records(params, final_columns)
|
153
|
+
end
|
154
|
+
|
155
|
+
def count_records(params)
|
156
|
+
params[:scope] = config[:scope] # note, params[:scope] becomes ActiveSupport::HashWithIndifferentAccess
|
157
|
+
|
158
|
+
data_adapter.count_records(params, final_columns)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Override this method to react on each operation that caused changing of data
|
162
|
+
def on_data_changed
|
163
|
+
end
|
164
|
+
|
165
|
+
# Given an index of a column among enabled (non-excluded) columns, provides the index (position) in the table
|
166
|
+
def normalize_index(index)
|
167
|
+
norm_index = 0
|
168
|
+
index.times do
|
169
|
+
while true do
|
170
|
+
norm_index += 1
|
171
|
+
break unless final_columns[norm_index][:included] == false
|
172
|
+
end
|
173
|
+
end
|
174
|
+
norm_index
|
175
|
+
end
|
176
|
+
|
177
|
+
# Params:
|
178
|
+
# <tt>:operation</tt>: :update or :create
|
179
|
+
def process_data(data, operation)
|
180
|
+
success = true
|
181
|
+
mod_records = {}
|
182
|
+
if !config[:"prohibit_#{operation}"]
|
183
|
+
modified_records = 0
|
184
|
+
data.each do |record_hash|
|
185
|
+
id = record_hash.delete('id')
|
186
|
+
record = operation == :create ? data_adapter.new_record : data_adapter.find_record(id)
|
187
|
+
success = true
|
188
|
+
|
189
|
+
# merge with strong default attirbutes
|
190
|
+
record_hash.merge!(config[:strong_default_attrs]) if config[:strong_default_attrs]
|
191
|
+
|
192
|
+
record_hash.each_pair do |k,v|
|
193
|
+
data_adapter.set_record_value_for_attribute(record, final_columns_hash[k.to_sym].nil? ? {:name => k} : final_columns_hash[k.to_sym], v, config.role || :default)
|
194
|
+
end
|
195
|
+
|
196
|
+
# try to save
|
197
|
+
mod_records[id] = data_adapter.record_to_array(record, final_columns(:with_meta => true)) if success && record.save
|
198
|
+
|
199
|
+
# flash eventual errors
|
200
|
+
if !record.errors.empty?
|
201
|
+
success = false
|
202
|
+
record.errors.to_a.each do |msg|
|
203
|
+
flash :error => msg
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
else
|
208
|
+
success = false
|
209
|
+
flash :error => "You don't have permissions to #{operation} data"
|
210
|
+
end
|
211
|
+
mod_records
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|