netzke-basepack 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +3 -0
  4. data/TODO.rdoc +1 -4
  5. data/features/form_panel.feature +2 -1
  6. data/features/grid_panel.feature +134 -5
  7. data/features/nested_attributes.feature +4 -1
  8. data/features/paging_form_panel.feature +41 -0
  9. data/features/search_in_grid.feature +20 -7
  10. data/features/step_definitions/form_panel_steps.rb +35 -0
  11. data/features/step_definitions/generic_steps.rb +20 -1
  12. data/features/step_definitions/grid_panel_steps.rb +63 -0
  13. data/features/support/env.rb +4 -0
  14. data/features/validations_in_grid.feature +13 -0
  15. data/features/virtual_attributes.feature +5 -9
  16. data/javascripts/basepack.js +21 -650
  17. data/javascripts/datetimefield.js +24 -0
  18. data/lib/generators/netzke/basepack_generator.rb +10 -0
  19. data/{generators/netzke_basepack/templates/public_assets → lib/generators/netzke/templates/assets}/ts-checkbox.gif +0 -0
  20. data/{generators/netzke_basepack → lib/generators/netzke}/templates/create_netzke_field_lists.rb +0 -0
  21. data/lib/netzke-basepack.rb +3 -41
  22. data/lib/netzke/active_record/attributes.rb +17 -21
  23. data/lib/netzke/basepack.rb +6 -1
  24. data/lib/netzke/basepack/data_accessor.rb +166 -0
  25. data/lib/netzke/basepack/form_panel.rb +69 -20
  26. data/lib/netzke/basepack/form_panel/fields.rb +15 -17
  27. data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +7 -0
  28. data/lib/netzke/basepack/form_panel/javascripts/display_mode.js +6 -0
  29. data/lib/netzke/basepack/form_panel/javascripts/{main.js → form_panel.js} +42 -8
  30. data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +24 -7
  31. data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +52 -0
  32. data/lib/netzke/basepack/form_panel/services.rb +28 -2
  33. data/lib/netzke/basepack/form_panel/stylesheets/readonly_mode.css +14 -0
  34. data/lib/netzke/basepack/grid_panel.rb +151 -181
  35. data/lib/netzke/basepack/grid_panel/columns.rb +122 -84
  36. data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +22 -27
  37. data/lib/netzke/basepack/grid_panel/javascripts/{main.js → grid_panel.js} +182 -108
  38. data/lib/netzke/basepack/grid_panel/record_form_window.rb +7 -2
  39. data/lib/netzke/basepack/grid_panel/services.rb +58 -39
  40. data/lib/netzke/basepack/paging_form_panel.rb +86 -25
  41. data/lib/netzke/basepack/query_builder.rb +105 -0
  42. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +140 -0
  43. data/lib/netzke/basepack/search_panel.rb +61 -44
  44. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +153 -0
  45. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +64 -0
  46. data/lib/netzke/basepack/search_window.rb +64 -0
  47. data/lib/netzke/basepack/simple_app.rb +1 -1
  48. data/lib/netzke/basepack/simple_app/javascripts/{main.js → simple_app.js} +0 -0
  49. data/lib/netzke/basepack/tab_panel.rb +1 -2
  50. data/lib/netzke/basepack/tab_panel/javascripts/{main.js → tab_panel.js} +0 -0
  51. data/lib/netzke/basepack/version.rb +1 -1
  52. data/locales/en.yml +71 -4
  53. data/netzke-basepack.gemspec +47 -22
  54. data/spec/active_record/attributes_spec.rb +6 -6
  55. data/spec/components/form_panel_spec.rb +2 -13
  56. data/stylesheets/datetimefield.css +54 -0
  57. data/test/rails_app/Gemfile +3 -3
  58. data/test/rails_app/Gemfile.lock +67 -57
  59. data/test/rails_app/README +1 -256
  60. data/test/rails_app/app/components/book_form.rb +1 -3
  61. data/test/rails_app/app/components/book_form_with_custom_fields.rb +20 -0
  62. data/test/rails_app/app/components/book_form_with_nested_attributes.rb +18 -0
  63. data/test/rails_app/app/components/book_grid.rb +3 -1
  64. data/test/rails_app/app/components/book_grid_loader.rb +24 -0
  65. data/test/rails_app/app/components/book_grid_with_custom_columns.rb +28 -0
  66. data/test/rails_app/app/components/book_grid_with_default_values.rb +1 -1
  67. data/test/rails_app/app/components/book_grid_with_virtual_attributes.rb +0 -1
  68. data/test/rails_app/app/components/book_paging_form_panel.rb +3 -2
  69. data/test/rails_app/app/components/book_presentation.rb +3 -3
  70. data/test/rails_app/app/components/book_query_builder.rb +8 -0
  71. data/test/rails_app/app/components/book_search_panel.rb +5 -0
  72. data/test/rails_app/app/components/book_search_panel/javascripts/i18n_de.js +6 -0
  73. data/test/rails_app/app/components/double_book_grid.rb +18 -0
  74. data/test/rails_app/app/components/form_without_model.rb +1 -1
  75. data/test/rails_app/app/components/paging_form_with_search.rb +39 -0
  76. data/test/rails_app/app/components/user_grid.rb +1 -1
  77. data/test/rails_app/app/models/author.rb +1 -0
  78. data/test/rails_app/config/application.rb +6 -1
  79. data/test/rails_app/config/database.yml +7 -5
  80. data/test/rails_app/config/environments/test.rb +1 -1
  81. data/test/rails_app/config/locales/de.yml +35 -0
  82. data/test/rails_app/config/locales/es.yml +84 -8
  83. data/test/rails_app/db/migrate/20101026190021_create_books.rb +2 -2
  84. data/test/rails_app/db/migrate/20110213213050_create_netzke_component_states.rb +20 -0
  85. data/test/rails_app/db/schema.rb +2 -18
  86. data/test/rails_app/public/netzke/basepack/ts-checkbox.gif +0 -0
  87. data/test/unit/active_record_basepack_test.rb +1 -1
  88. metadata +46 -45
  89. data/generators/netzke_basepack/netzke_basepack_generator.rb +0 -13
  90. data/lib/netzke/basepack/grid_panel/search_window.rb +0 -56
  91. data/lib/netzke/data_accessor.rb +0 -113
  92. data/lib/netzke/ext.rb +0 -7
  93. data/lib/netzke/fields_configurator.rb +0 -170
  94. data/lib/netzke/json_array_editor.rb +0 -67
  95. data/lib/netzke/masquerade_selector.rb +0 -53
  96. data/test/rails_app/app/components/some_search_panel.rb +0 -34
  97. data/test/rails_app/db/development_structure.sql +0 -93
  98. data/test/rails_app/db/migrate/20100905214933_create_netzke_preferences.rb +0 -16
@@ -9,8 +9,13 @@ module Netzke
9
9
  :auto_height => true,
10
10
  :fbar => [:ok.action, :cancel.action]
11
11
 
12
- action :ok, :text => 'OK'
13
- action :cancel
12
+ action :ok do
13
+ { :text => I18n.t('netzke.basepack.grid_panel.record_form_window.actions.ok')}
14
+ end
15
+
16
+ action :cancel do
17
+ { :text => I18n.t('netzke.basepack.grid_panel.record_form_window.actions.cancel')}
18
+ end
14
19
 
15
20
  js_method :init_component, <<-JS
16
21
  function(params){
@@ -45,30 +45,33 @@ module Netzke
45
45
  end
46
46
 
47
47
  endpoint :resize_column do |params|
48
- raise "Called api_resize_column while not configured to do so" if config[:enable_column_resize] == false
49
- columns[normalize_index(params[:index].to_i)][:width] = params[:size].to_i
50
- save_columns!
48
+ raise "Called api_resize_column while not configured to do so" if !config[:persistence]
49
+ current_columns_order = state[:columns_order] || initial_columns_order
50
+ current_columns_order[normalize_index(params[:index].to_i)][:width] = params[:size].to_i
51
+ update_state(:columns_order, current_columns_order)
51
52
  {}
52
53
  end
53
54
 
54
55
  endpoint :move_column do |params|
55
- raise "Called api_move_column while not configured to do so" if config[:enable_column_move] == false
56
+ raise "Called api_move_column while not configured to do so" if !config[:persistence]
56
57
  remove_from = normalize_index(params[:old_index].to_i)
57
58
  insert_to = normalize_index(params[:new_index].to_i)
58
- column_to_move = columns.delete_at(remove_from)
59
- columns.insert(insert_to, column_to_move)
60
- save_columns!
61
59
 
62
- # reorder the columns on the client side (still not sure if it's not an overkill)
63
- # {:reorder_columns => columns.map(&:name)} # Well, I think it IS an overkill - commented out
64
- # until proven to be necessary
60
+ current_columns_order = state[:columns_order] || initial_columns_order
61
+
62
+ column_to_move = current_columns_order.delete_at(remove_from)
63
+ current_columns_order.insert(insert_to, column_to_move)
64
+
65
+ update_state(:columns_order, current_columns_order)
66
+
65
67
  {}
66
68
  end
67
69
 
68
70
  endpoint :hide_column do |params|
69
- raise "Called api_hide_column while not configured to do so" if config[:enable_column_hide] == false
70
- columns[normalize_index(params[:index].to_i)][:hidden] = params[:hidden].to_b
71
- save_columns!
71
+ raise "Called api_hide_column while not configured to do so" if !config[:persistence]
72
+ current_columns_order = state[:columns_order] || initial_columns_order
73
+ current_columns_order[normalize_index(params[:index].to_i)][:hidden] = params[:hidden].to_b
74
+ update_state(:columns_order, current_columns_order)
72
75
  {}
73
76
  end
74
77
 
@@ -77,7 +80,7 @@ module Netzke
77
80
  query = params[:query]
78
81
 
79
82
  column = columns.detect{ |c| c[:name] == params[:column] }
80
- scope = column.to_options[:scope] || column.to_options[:editor].try(:fetch, :scope)
83
+ scope = column.to_options[:scope] || column.to_options[:editor].try(:fetch, :scope, nil)
81
84
  query = params[:query]
82
85
 
83
86
  {:data => combobox_options_for_column(column, :query => query, :scope => scope, :record_id => params[:id])}
@@ -155,16 +158,36 @@ module Netzke
155
158
  def get_data(*args)
156
159
  params = args.first || {} # params are optional!
157
160
  if !config[:prohibit_read]
158
- records = get_records(params)
159
- {:data => records.map{|r| r.to_array(columns)}, :total => config[:enable_pagination] && records.total_entries}
161
+ {}.tap do |res|
162
+ records = get_records(params)
163
+ res[:data] = records.map{|r| r.to_array(columns(:with_meta => true))}
164
+ res[:total] = records.total_entries if config[:enable_pagination]
165
+
166
+ # provide association values for all records at once
167
+ # assoc_values = get_association_values(records, columns)
168
+ # res[:set_association_values] = assoc_values.literalize_keys if assoc_values.present?
169
+ end
160
170
  else
161
171
  flash :error => "You don't have permissions to read data"
162
- {:feedback => @flash}
172
+ { :feedback => @flash }
163
173
  end
164
174
  end
165
175
 
166
176
  protected
167
177
 
178
+ # Returns all values for association columns, per column, per associated record id, e.g.:
179
+ # {
180
+ # :author__first_name => {1 => "Vladimir", 2 => "Herman"},
181
+ # :author__last_name => {1 => "Nabokov", 2 => "Hesse"}
182
+ # }
183
+ # This is used to display the association by the specified method instead by the foreign key
184
+ # def get_association_values(records, columns)
185
+ # columns.select{ |c| c[:name].index("__") }.each.inject({}) do |r,c|
186
+ # column_values = {}
187
+ # records.each{ |r| column_values[r.value_for_attribute(c)] = r.value_for_attribute(c, true) }
188
+ # r.merge(c[:name] => column_values)
189
+ # end
190
+ # end
168
191
  def get_records(params)
169
192
 
170
193
  # Restore params from component_session if requested
@@ -213,23 +236,6 @@ module Netzke
213
236
  end
214
237
  end
215
238
 
216
- # An ActiveRecord::Relation instance encapsulating all the necessary conditions
217
- def get_relation(params)
218
- # make params coming from Ext grid filters understandable by meta_where
219
- conditions = params[:filter] && convert_filters(params[:filter]) || {}
220
-
221
- relation = data_class.where(conditions)
222
-
223
- if params[:extra_conditions]
224
- extra_conditions = normalize_extra_conditions(ActiveSupport::JSON.decode(params[:extra_conditions]))
225
- relation = relation.extend_with_netzke_conditions(extra_conditions) if params[:extra_conditions]
226
- end
227
-
228
- relation = relation.extend_with(config[:scope]) if config[:scope]
229
-
230
- relation
231
- end
232
-
233
239
  # Override this method to react on each operation that caused changing of data
234
240
  def on_data_changed; end
235
241
 
@@ -277,7 +283,7 @@ module Netzke
277
283
 
278
284
  # try to save
279
285
  # modified_records += 1 if success && record.save
280
- mod_records[id] = record.to_array(columns) if success && record.save
286
+ mod_records[id] = record.to_array(columns(:with_meta => true)) if success && record.save
281
287
  # mod_record_ids << id if success && record.save
282
288
 
283
289
  # flash eventual errors
@@ -316,8 +322,10 @@ module Netzke
316
322
  #
317
323
  # metawhere: :id.gt => 100, :food_name.matches => '%pizza%'
318
324
  def convert_filters(column_filter)
325
+ # these are still JSON-encoded due to the migration to Ext.direct
326
+ column_filter=JSON.parse(column_filter)
319
327
  res = {}
320
- column_filter.each_pair do |k,v|
328
+ column_filter.each do |v|
321
329
  assoc, method = v["field"].split('__')
322
330
  if method
323
331
  assoc = data_class.reflect_on_association(assoc.to_sym)
@@ -326,13 +334,14 @@ module Netzke
326
334
  field = assoc.to_sym
327
335
  end
328
336
 
329
- value = v["data"]["value"]
330
- case v["data"]["type"]
337
+ value = v["value"]
338
+
339
+ case v["type"]
331
340
  when "string"
332
341
  field = field.send :matches
333
342
  value = "%#{value}%"
334
343
  when "numeric", "date"
335
- field = field.send :"#{v['data']['comparison']}"
344
+ field = field.send :"#{v['comparison']}"
336
345
  end
337
346
  res.merge!({field => value})
338
347
  end
@@ -345,6 +354,16 @@ module Netzke
345
354
  end
346
355
  end
347
356
 
357
+ def initial_columns_order
358
+ columns.map do |c|
359
+ {
360
+ :name => c[:name],
361
+ :width => c[:width],
362
+ :hidden => c[:hidden]
363
+ }
364
+ end
365
+ end
366
+
348
367
  # def check_for_positive_result(res)
349
368
  # if res[:set_form_values]
350
369
  # # successful creation
@@ -15,6 +15,9 @@ module Netzke
15
15
  # When it's a Proc, it's passed the model class, and is expected to return an ActiveRecord::Relation, e.g.:
16
16
  #
17
17
  # :scope => { |rel| rel.where(:id.gt => 100).order(:created_at) }
18
+ #
19
+ # == ToDo
20
+ # * Update the number of records after form submit
18
21
  class PagingFormPanel < FormPanel
19
22
 
20
23
  # override
@@ -25,17 +28,75 @@ module Netzke
25
28
  # Pass total records amount and the first record to the JS constructor
26
29
  def js_config
27
30
  super.merge({
28
- :total_records => total_records,
29
- :record => record.to_hash(fields)
31
+ :total_records => total_records
30
32
  })
31
33
  end
32
34
 
33
35
  endpoint :get_data do |params|
34
- record = get_relation.offset(params[:start].to_i).limit(1).first
35
- record_hash = record && record.to_hash(fields).each_pair.inject({}){ |r,(k,v)| r.merge(k.l => v) }
36
- {:records => record_hash && [record_hash] || [], :total => total_records}
36
+ @record = get_relation(params).offset(params[:start].to_i).limit(1).first
37
+ record_hash = @record && js_record_data
38
+ {:records => record_hash && [record_hash] || [], :total => total_records(params)}
39
+ end
40
+
41
+ action :search do
42
+ {
43
+ :text => I18n.t('netzke.basepack.paging_form_panel.actions.search'),
44
+ :tooltip => I18n.t('netzke.basepack.paging_form_panel.actions.search_tooltip'),
45
+ :icon => :find,
46
+ :select => true
47
+ }
37
48
  end
38
49
 
50
+ def configure_bbar(c)
51
+ super
52
+ c[:bbar] << :search.action
53
+ end
54
+
55
+ js_method :on_search, <<-JS
56
+ function(el){
57
+ if (this.searchWindow) {
58
+ this.searchWindow.show();
59
+ } else {
60
+ this.loadComponent({name: 'search_form', callback: function(win){
61
+ this.searchWindow = win;
62
+ var currentConditionsString = this.getStore().baseParams.extra_conditions;
63
+ if (currentConditionsString) {
64
+ win.items.first().getForm().setValues(Ext.decode(currentConditionsString));
65
+ }
66
+
67
+ win.items.first().on('apply', function(){
68
+ win.onSearch();
69
+ return false; // do not propagate the 'apply' event
70
+ }, this);
71
+
72
+ win.on('hide', function(){
73
+ var query = win.getQuery();
74
+ if (win.closeRes == 'search'){
75
+ this.getStore().baseParams.query = Ext.encode(query);
76
+ this.getStore().load();
77
+ }
78
+ el.toggle(query.length > 0); // toggle based on the state
79
+ }, this);
80
+ }, scope: this});
81
+ }
82
+ }
83
+ JS
84
+
85
+ js_method :get_store, <<-JS
86
+ function(){
87
+ return this.store;
88
+ }
89
+ JS
90
+
91
+ js_method :after_render, <<-JS
92
+ function(){
93
+ Netzke.classes.Basepack.PagingFormPanel.superclass.afterRender.call(this);
94
+
95
+ new Ext.LoadMask(this.bwrap, Ext.apply(this.applyMask, {store: this.store}));
96
+ }
97
+ JS
98
+
99
+
39
100
  js_method :init_component, <<-JS
40
101
  function(){
41
102
 
@@ -44,23 +105,20 @@ module Netzke
44
105
  // Otherwise, the things would be simpler, because this.getForm().items would already has all the fields in one place for us
45
106
  this.fieldNames = [];
46
107
  this.extractFields(this.items);
47
- var fieldNames = this.fieldNames;
48
108
 
49
- var store = new Ext.data.JsonStore({
50
- url: this.endpointUrl('get_data'),
109
+ var store = new Ext.data.DirectStore({
110
+ directFn: Netzke.providers[this.id].getData,
51
111
  root: 'records',
52
- fields: fieldNames,
112
+ fields: this.fieldNames.concat('_meta'),
53
113
  data: {records: [this.record], total: this.totalRecords}
54
114
  });
55
115
 
56
- store.on('beforeload', function(){
57
- if (!this.loadMaskCmp) this.loadMaskCmp = new Ext.LoadMask(this.bwrap, this.applyMask);
58
- this.loadMaskCmp.show();
59
- }, this);
60
-
61
116
  store.on('load', function(st, r){
62
- this.setFormValues(r[0].data);
63
- if (this.loadMaskCmp) this.loadMaskCmp.hide();
117
+ if (r.length == 0) {
118
+ this.getForm().reset();
119
+ } else {
120
+ this.setFormValues(r[0].data);
121
+ }
64
122
  }, this);
65
123
 
66
124
  this.bbar = new Ext.PagingToolbar({
@@ -70,21 +128,24 @@ module Netzke
70
128
  items: ["-"].concat(this.bbar || [])
71
129
  });
72
130
 
131
+ this.store = store;
132
+
73
133
  Netzke.classes.Basepack.PagingFormPanel.superclass.initComponent.call(this);
74
134
  }
75
135
  JS
76
136
 
77
- protected
137
+ component :search_form do
138
+ {
139
+ :lazy_loading => true,
140
+ :class_name => "Netzke::Basepack::SearchWindow",
141
+ :model => config[:model]
142
+ }
143
+ end
78
144
 
79
- # Returns ActiveRecord::Relation for the data
80
- def get_relation
81
- relation = data_class.scoped
82
- relation = relation.extend_with(config[:scope]) if config[:scope]
83
- relation
84
- end
145
+ protected
85
146
 
86
- def total_records
87
- @total_records ||= get_relation.count
147
+ def total_records(params = {})
148
+ @total_records ||= get_relation(params).count
88
149
  end
89
150
 
90
151
  end
@@ -0,0 +1,105 @@
1
+ module Netzke
2
+ module Basepack
3
+ class QueryBuilder < Netzke::Base
4
+ js_base_class "Ext.TabPanel"
5
+
6
+ js_property :active_tab, 0
7
+
8
+ js_translate :overwrite_confirm, :overwrite_confirm_title, :delete_confirm, :delete_confirm_title
9
+
10
+ js_mixin :query_builder
11
+
12
+ component :search_panel do
13
+ {
14
+ :class_name => "Netzke::Basepack::SearchPanel",
15
+ :model => config[:model],
16
+ :query => config[:query],
17
+ :auto_scroll => config[:auto_scroll]
18
+ }
19
+ end
20
+
21
+ action :clear_all do
22
+ {
23
+ :text => I18n.t('netzke.basepack.query_builder.actions.clear_all'),
24
+ :tooltip => I18n.t('netzke.basepack.query_builder.actions.clear_all_tooltip'),
25
+ :icon => :cross
26
+ }
27
+ end
28
+
29
+ action :reset do
30
+ {
31
+ :text => I18n.t('netzke.basepack.query_builder.actions.reset'),
32
+ :tooltip => I18n.t('netzke.basepack.query_builder.actions.reset_tooltip'),
33
+ :icon => :application_form
34
+ }
35
+ end
36
+
37
+ action :save_preset do
38
+ {
39
+ :text => I18n.t('netzke.basepack.query_builder.actions.save_preset'),
40
+ :tooltip => I18n.t('netzke.basepack.query_builder.actions.save_preset_tooltip'),
41
+ :icon => :disk
42
+ }
43
+ end
44
+
45
+ action :delete_preset do
46
+ {
47
+ :text => I18n.t('netzke.basepack.query_builder.actions.delete_preset'),
48
+ :tooltip => I18n.t('netzke.basepack.query_builder.actions.delete_preset_tooltip'),
49
+ :icon => :cross
50
+ }
51
+ end
52
+
53
+ action :apply do
54
+ {
55
+ :text => I18n.t('netzke.basepack.query_builder.actions.apply'),
56
+ :tooltip => I18n.t('netzke.basepack.query_builder.actions.apply_tooltip'),
57
+ :icon => :accept
58
+ }
59
+ end
60
+
61
+ def js_config
62
+ super.tap do |s|
63
+ s[:bbar] = (config[:bbar] || []) + [:clear_all.action, :reset.action, "->",
64
+ I18n.t('netzke.basepack.query_builder.presets'),
65
+ {
66
+ :xtype => "combo",
67
+ :triggerAction => "all",
68
+ :value => super[:load_last_preset] && last_preset.try(:fetch, "name"),
69
+ :store => state[:presets].blank? ? [[[], ""]] : state[:presets].map{ |s| [s["query"], s["name"]] },
70
+ :ref => "../presetsCombo",
71
+ :listeners => {:before_select => {
72
+ :fn => "function(combo, record){
73
+ var form = Ext.getCmp('#{global_id}');
74
+ form.buildFormFromQuery(record.data.field1);
75
+ }".l
76
+ }}
77
+ }, :save_preset.action, :delete_preset.action
78
+ ]
79
+ end
80
+ end
81
+
82
+ endpoint :save_preset do |params|
83
+ saved_searches = state[:presets] || []
84
+ existing = saved_searches.detect{ |s| s["name"] == params[:name] }
85
+ query = ActiveSupport::JSON.decode(params[:query])
86
+ if existing
87
+ existing["query"].replace(query)
88
+ else
89
+ saved_searches << {"name" => params[:name], "query" => query}
90
+ end
91
+ update_state(:presets, saved_searches)
92
+ {:feedback => I18n.t('netzke.basepack.query_builder.preset_saved')}
93
+ end
94
+
95
+ endpoint :delete_preset do |params|
96
+ saved_searches = state[:presets]
97
+ saved_searches.delete_if{ |s| s["name"] == params[:name] }
98
+ update_state(:presets, saved_searches)
99
+ {:feedback => I18n.t('netzke.basepack.query_builder.preset_deleted')}
100
+ end
101
+
102
+
103
+ end
104
+ end
105
+ end