redmine_extensions 0.0.39 → 0.1.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +30 -59
  3. data/app/controllers/easy_settings_controller.rb +1 -1
  4. data/app/helpers/redmine_extensions/application_helper.rb +108 -65
  5. data/app/helpers/redmine_extensions/rendering_helper.rb +5 -0
  6. data/app/presenters/easy_query_adapter_presenter.rb +50 -0
  7. data/app/views/common/_collapsible_module_layout.html.erb +13 -0
  8. data/app/views/easy_entity_assignments/_assignments_container.html.erb +10 -15
  9. data/app/views/easy_entity_assignments/_query_index.html.erb +2 -10
  10. data/app/views/easy_queries/_easy_query_tile.html.erb +7 -0
  11. data/app/views/easy_settings/edit.html.erb +1 -1
  12. data/config/routes.rb +3 -7
  13. data/lib/generators/redmine_extensions/entity/templates/_form.html.erb.erb +1 -1
  14. data/lib/generators/redmine_extensions/entity/templates/_sidebar.html.erb.erb +8 -8
  15. data/lib/generators/redmine_extensions/entity/templates/context_menu.html.erb.erb +7 -7
  16. data/lib/generators/redmine_extensions/entity/templates/custom_field.rb.erb +7 -7
  17. data/lib/generators/redmine_extensions/entity/templates/edit.html.erb.erb +16 -16
  18. data/lib/generators/redmine_extensions/entity/templates/index.api.rsb.erb +5 -5
  19. data/lib/generators/redmine_extensions/entity/templates/index.html.erb.erb +4 -4
  20. data/lib/generators/redmine_extensions/entity/templates/mail_added.html.erb.erb +1 -1
  21. data/lib/generators/redmine_extensions/entity/templates/mail_added.text.erb.erb +2 -2
  22. data/lib/generators/redmine_extensions/entity/templates/mail_updated.text.erb.erb +2 -2
  23. data/lib/generators/redmine_extensions/entity/templates/migration.rb.erb +9 -9
  24. data/lib/generators/redmine_extensions/entity/templates/new.html.erb.erb +16 -16
  25. data/lib/generators/redmine_extensions/entity/templates/query.rb.erb +1 -1
  26. data/lib/generators/redmine_extensions/entity/templates/routes.rb.erb +12 -12
  27. data/lib/generators/redmine_extensions/entity/templates/show.html.erb.erb +37 -37
  28. data/lib/redmine_extensions/easy_query_adapter.rb +107 -88
  29. data/lib/redmine_extensions/easy_query_helpers/outputs.rb +69 -0
  30. data/lib/redmine_extensions/engine.rb +11 -1
  31. data/lib/redmine_extensions/query_output.rb +41 -25
  32. data/lib/redmine_extensions/query_outputs/list_output.rb +14 -0
  33. data/lib/redmine_extensions/query_outputs/tile_output.rb +19 -0
  34. data/lib/redmine_extensions/redmine_patches/patches.rb +2 -3
  35. data/lib/redmine_extensions/version.rb +1 -1
  36. data/spec/redmine/bin/about +0 -0
  37. data/spec/redmine/bin/bundle +0 -0
  38. data/spec/redmine/bin/rails +0 -0
  39. data/spec/redmine/bin/rake +0 -0
  40. data/spec/redmine/extra/svn/reposman.rb +0 -0
  41. data/spec/redmine/public/dispatch.fcgi.example +0 -0
  42. data/spec/redmine/script/about +0 -0
  43. data/spec/redmine/script/rails +0 -0
  44. metadata +1978 -1972
  45. data/lib/redmine_extensions/query_outputs/table_output.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69aa53880c59eeba8d228b39825f6acd5f9f303a
4
- data.tar.gz: 9e7e9d2b63507cd4a9ee8f9145e2a412703e8650
3
+ metadata.gz: 03e7f631e32d5cbbce9cfd94ab32c76a0e3fb93a
4
+ data.tar.gz: 5454a96009a0928de22a9c918f487468154f154e
5
5
  SHA512:
6
- metadata.gz: d32c640609e40752ea5eca7e887d49c3ba54fe98ad6a8bb08a6eb118752bd0b8e0f9eb7c9e853714f947e9a7c22000f93667fa6aa8a4f1b30157ee4c88438497
7
- data.tar.gz: f96ccef09fa3848e4adfde7575e71a36a9d9f36bfc273856b9e587490e9ebfa589c28d54c4eb14914142766025cd0a74fa2a58a24a29a9abcba09c89c40b5c92
6
+ metadata.gz: 9851babf744466f612e6ac074e5bfb27980e27c33dc8cae48c5d3c7c99793bfdd2f19a9f593b8f994f9518475aa3f4aff49138b1052f7c96a5471d081a7d3f60
7
+ data.tar.gz: 119f3556b21232044b91a4fb05bcc3f0f7b7d3b08df9c4fd61b18edde70ca13c760091818791066a63539218a5b942f250920d05136a5298713e530be21e460b
@@ -340,8 +340,6 @@ window.closeFlashMessage = (function($element){
340
340
  this._initData(this.options.source);
341
341
  } else if ( this.options.preload && this.options.load_immediately) {
342
342
  this.load();
343
- } else if ( this.selectedValues ) {
344
- this.setValue( this.selectedValues );
345
343
  }
346
344
  },
347
345
 
@@ -389,7 +387,7 @@ window.closeFlashMessage = (function($element){
389
387
  select.append(option);
390
388
  });
391
389
  $container = $elem.closest('.easy-multiselect-tag-container');
392
- $container.find(':input').prop('disabled', true);
390
+ $container.children(':input').prop('disabled', true);
393
391
  $container.children().hide();
394
392
  $container.append(select);
395
393
  that.valueElement = select;
@@ -409,7 +407,7 @@ window.closeFlashMessage = (function($element){
409
407
  that.load(function(){
410
408
  var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
411
409
  response($.grep(that.possibleValues, function(val, i) {
412
- return ( !request.term || matcher.test(val.value) );
410
+ return ( !that.options.multiple || !request.term || matcher.test(val.value));
413
411
  }));
414
412
  }, function(){
415
413
  response();
@@ -482,16 +480,16 @@ window.closeFlashMessage = (function($element){
482
480
  _formatData: function(data) {
483
481
  return $.map(data, function(elem, i){
484
482
  var id, value;
485
- if (elem instanceof Array) {
486
- value = elem[0];
487
- id = elem[1];
488
- } else if (elem instanceof Object) {
489
- value = elem.value;
490
- id = elem.id;
483
+ if( $.isArray(elem) ) {
484
+ value = elem[0];
485
+ id = elem[1];
491
486
  } else {
492
- id = value = elem;
493
- }
494
- return {value: value, id: id};
487
+ id = value = elem;
488
+ }
489
+ if ( elem !== null && typeof elem === 'object' )
490
+ return elem;
491
+ else
492
+ return {value: value, id: id};
495
493
  });
496
494
  },
497
495
 
@@ -544,7 +542,6 @@ window.closeFlashMessage = (function($element){
544
542
  name: value.value
545
543
  });
546
544
  this.element.trigger('change');
547
- this.element.val('');
548
545
  } else {
549
546
  this.element.val(value.value);
550
547
  this.valueElement.val(value.id);
@@ -554,7 +551,7 @@ window.closeFlashMessage = (function($element){
554
551
 
555
552
  setValue: function(values) {
556
553
  var that = this;
557
- if( typeof values === 'undefined' || !values )
554
+ if( typeof values == 'undefined' || !values )
558
555
  return false;
559
556
 
560
557
  if( this.options.preload ) {
@@ -562,63 +559,37 @@ window.closeFlashMessage = (function($element){
562
559
  if( that.options.multiple ) {
563
560
  that.valueElement.entityArray('clear');
564
561
  }
565
- that._setValues(values);
562
+ that._setValues(values)
566
563
  });
567
564
  } else {
568
- if( that.options.multiple ) {
569
- that.valueElement.entityArray('clear');
570
- }
571
- that._setValues(values);
565
+ // TODO - where to get real text value?
566
+ this.element.val(values[0]);
567
+ this.valueElement.val(values[0]);
572
568
  }
573
569
  },
574
570
 
575
571
  _setValues: function(values) {
576
- var selected = [];
577
-
578
- if( values.length == 0 )
579
- return false;
580
-
581
- // allows the combination of only id values and values with label
582
- for (var i = values.length - 1; i >= 0; i--) {
583
- var identifier, label;
584
- if( values[i] instanceof Object && !Array.isArray(values[i]) && values[i] !== null ) {
585
- selected.push( values[i] );
586
- } else if( this.options.preload && Array.isArray(this.possibleValues) ) {
587
- for(var j = this.possibleValues.length - 1; j >= 0; j-- ) {
588
- if ( values[i] == this.possibleValues[j].id || values[i] == this.possibleValues[j].id.toString() ) {
589
- selected.push(this.possibleValues[j]);
590
- break;
591
- }
572
+ var that = this;
573
+ $.each(that.possibleValues, function(i, val) {
574
+ if ( values.indexOf(val.id) > -1 || (values.indexOf(val.id.toString()) > -1)) {
575
+ if(that.options.multiple) {
576
+ that.valueElement.entityArray('add', { id: val.id, name: val.value });
577
+ } else {
578
+ that.element.val(val.value);
579
+ that.valueElement.val(val.id);
592
580
  }
593
- } else {
594
- selected.push( {id: values[i], value: values[i]} );
595
- }
596
- }
597
- for (var i = selected.length - 1; i >= 0; i--) {
598
- if(this.options.multiple) {
599
- this.valueElement.entityArray('add', { id: selected[i].id, name: selected[i].value });
600
- } else {
601
- this.element.val(selected[i].value);
602
- this.valueElement.val(selected[i].id);
603
581
  }
604
- }
582
+ });
605
583
  },
606
584
 
607
- getValue: function(with_label) {
608
- var result;
609
- if ( this.options.multiple && !this.expanded ) {
610
- result = this.valueElement.entityArray('getValue'); // entityArray
585
+ getValue: function() {
586
+ if( this.options.multiple && !this.expanded ) {
587
+ return this.valueElement.entityArray('getValue'); // entityArray
611
588
  } else if ( this.options.multiple ) {
612
- result = this.valueElement.val(); // select multiple=true
589
+ return this.valueElement.val(); //select multiple=true
613
590
  } else {
614
- result = [this.valueElement.val()]; // hidden field
615
- }
616
- if( with_label ) {
617
- result = this.possibleValues.filter(function(el) {
618
- return result.indexOf( el.id ) >= 0;
619
- });
591
+ return [this.valueElement.val()]; // hidden field
620
592
  }
621
- return result;
622
593
  }
623
594
 
624
595
  });
@@ -25,7 +25,7 @@ class EasySettingsController < ApplicationController
25
25
  Setting.send "plugin_#{@plugin.id}=", params[:settings] if params[:settings]
26
26
  if @easy_settings.save
27
27
  flash[:notice] = l(:notice_successful_update)
28
- redirect_back_or_default edit_easy_setting_path(@easy_settings)
28
+ redirect_back_or_default redmine_extensions_engine.edit_easy_setting_path(@easy_settings)
29
29
  else
30
30
  render :edit
31
31
  end
@@ -6,7 +6,7 @@ module RedmineExtensions
6
6
 
7
7
  def plugin_settings_path(plugin, *attrs)
8
8
  if plugin.is_a?(Redmine::Plugin) && (plugin.settings[:only_easy] || plugin.settings[:easy_settings])
9
- edit_easy_setting_path(plugin, *attrs)
9
+ redmine_extensions_engine.edit_easy_setting_path(plugin, *attrs)
10
10
  else
11
11
  super
12
12
  end
@@ -44,20 +44,21 @@ module RedmineExtensions
44
44
  end
45
45
  end
46
46
 
47
- def render_entity_assignments(entity, target_class, options = {}, &block)
48
- options ||= {}
49
- collection_name = options.delete(:collection_name) || target_class.name.pluralize.underscore
50
-
51
- project = options.delete(:project)
52
- query_class = options.delete(:query_class)
47
+ def query_for_entity(entity_class)
48
+ entity_class_name = entity_class.name
49
+ query_class = "Easy#{entity_class_name}Query".constantize rescue nil
50
+ return query_class if query_class && query_class < EasyQuery
51
+ query_class ||= "#{entity_class_name}Query".constantize rescue nil
52
+ end
53
53
 
54
- if query_class.nil?
55
- query_class_name = target_class.name + 'Query'
54
+ def render_entity_assignments(entity, target_entity, options = {}, &block)
55
+ options ||= {}
56
+ collection_name = options.delete(:collection_name) || target_entity.name.pluralize.underscore
57
+ query_class = query_for_entity(target_entity)
56
58
 
57
- query_class = query_class_name.constantize #if Object.const_defined?(query_class_name)
58
- end
59
+ return '' if !query_class || !entity.respond_to?(collection_name)
59
60
 
60
- return '' if !query_class || !(query_class < EasyQuery) || !entity.respond_to?(collection_name)
61
+ project = options.delete(:project)
61
62
 
62
63
  query = query_class.new(:name => 'c_query')
63
64
  query.project = project
@@ -68,9 +69,8 @@ module RedmineExtensions
68
69
 
69
70
  entities_count = entities.size
70
71
  options[:entities_count] = entities_count
71
-
72
72
  options[:module_name] ||= "entity_#{entity.class.name.underscore}_#{entity.id}_#{collection_name}"
73
- options[:heading] ||= l("label_#{target_class.name.underscore}_plural", :default => 'Heading')
73
+ options[:heading] ||= l("label_#{query.entity}_plural", :default => 'Heading')
74
74
 
75
75
  if options[:context_menus_path].nil?
76
76
  options[:context_menus_path] = [
@@ -82,9 +82,11 @@ module RedmineExtensions
82
82
  end
83
83
  end
84
84
 
85
+ query.output = options[:display_style] || (entities_count > 3 ? 'list' : 'tile')
86
+
85
87
  render(:partial => 'easy_entity_assignments/assignments_container', :locals => {
86
88
  :entity => entity,
87
- :query => query, :target_class => target_class, :project => project,
89
+ :query => query, :project => project,
88
90
  :entities => entities, :entities_count => entities_count, :options => options})
89
91
  end
90
92
 
@@ -106,65 +108,106 @@ module RedmineExtensions
106
108
  end
107
109
  end
108
110
 
109
- # options:
110
- # => options[:heading] = text beside of plus button
111
- # => options[:container_html] = a hash of html attributes
112
- # => options[:default_button_state] = (true => expanded -), (false => collapsed +)
113
- # => options[:ajax_call] = make ajax call for saving state (true => ajax call, false => no call, no save)
114
- # => options[:wrapping_heading_element] = html element outside heading => h3, h4
115
- def render_toggler(container_uniq_id, user = nil, options={}, &block)
116
- user ||= User.current
117
- options[:heading] ||= ''
118
- options[:heading_links] ||= []
119
- options[:heading_links] = [options[:heading_links]] if options[:heading_links] && !options[:heading_links].is_a?(Array)
120
- options[:container_html] ||= {}
121
- options[:default_button_state] = false #if is_mobile_device?
122
- options[:default_button_state] = true if options[:default_button_state].nil?
123
- options[:ajax_call] = true if options[:ajax_call].nil?
124
-
125
- s = ''
126
- if !options.key?(:no_heading_button)
127
- options[:heading] << content_tag(:div, options[:heading_links].join(' ').html_safe, :class => 'module-heading-links') unless options[:heading_links].blank?
128
- s << render_toggler_header(user, options[:heading].html_safe, container_uniq_id, options)
129
- end
130
-
131
- if options[:ajax_call] == false
132
- expanded = options[:default_button_state]
133
- else
134
- expanded = true
135
- end
136
111
 
137
- s << (content_tag(:div, {
138
- :id => container_uniq_id,
139
- :style => (expanded ? '' : 'display:none')
140
- }.merge(options[:container_html]) { |k, o, n| "#{o}; #{n}" }, &block))
141
- s.html_safe
112
+ # ==== Options
113
+ # * <tt>class: Hash or String</tt> - This option can be used to add custom CSS classes. It can be *String* or *Hash*.
114
+ # class: {heading: 'heading-additional-css', container: 'container-additional-css'}
115
+ # * <tt>heading_tag: name of HTML element of module heading</tt> - By default its its *h3*
116
+ # ** Aliases for this options are: wrapping_heading_element, header_tag
117
+ # * <tt>toggle: false</tt> - This disable toggle function (collapsible and remember)
118
+ # ** Aliases for this options are: collapsible, no_expander
119
+ # * <tt>remember: false</tt> - This disable remember function of toggle conatiner
120
+ # ** Aliases for this options are: ajax_call
121
+ #
122
+ def render_module_easy_box(id, heading, options = {}, &block) # with fallback to old
123
+ options[:toggle] = true unless options.key?(:toggle)
124
+ options[:remember] = options.delete(:ajax_call) if options.key?(:ajax_call)
125
+ options[:collapsible] = !options.delete(:no_expander) if options.key?(:no_expander)
126
+
127
+ renderer = EasyBoxRenderer.new(self, id, heading, options)
128
+ renderer.content = capture {yield renderer}
129
+
130
+ renderer.render
142
131
  end
143
132
 
144
- def render_toggler_header(user, content, modul_uniq_id, options={})
145
- expander_options = options[:expander_options] || {}
146
- wrapping_heading_element = options[:wrapping_heading_element] || 'h3'
147
- wrapping_heading_element_classes = (options[:wrapping_heading_element_classes] || '') + ' module-heading'
148
- wrapping_heading_element_styles = options[:wrapping_heading_element_styles]
149
- ajax_call = options.delete(:ajax_call) ? 'true' : 'false'
133
+ EasyBoxRenderer = Struct.new(:view, :id, :heading, :options) do
150
134
 
151
- html = ''
135
+ attr_writer :container_class, :heading_class, :content_class
136
+ attr_writer :heading_links, :footer, :icon
137
+ attr_accessor :content
152
138
 
153
- if options[:no_expander]
154
- html << content_tag(wrapping_heading_element, content, :class => wrapping_heading_element_classes, :style => wrapping_heading_element_styles)
155
- else
156
- html << '<div class="module-toggle-button">'
157
- html << "<div class='group open' >"
158
- html << content_tag(wrapping_heading_element, content, :class => wrapping_heading_element_classes, :style => wrapping_heading_element_styles, :onclick => "var event = arguments[0] || window.event; if( !$(event.target).hasClass('do_not_toggle') && !$(event.target).parent().hasClass('module-heading-links') ) toggleMyPageModule(this,'#{modul_uniq_id}','#{user.id}', #{ajax_call})")
159
- html << "<span class='expander #{expander_options[:class]}' onclick=\"toggleMyPageModule($(this),'#{modul_uniq_id}','#{user.id}', #{ajax_call}); return false;\" id=\"expander_#{modul_uniq_id}\">&nbsp;</span>"
160
- html << '</div></div>'
139
+ def container_class
140
+ s = (@container_class.presence || css_classes[:container]).to_s
141
+ s << ' collapsible' if collapsible?
142
+ s << ' collapsed' if collapsed?
143
+
144
+ s
145
+ end
146
+
147
+ def saving_state_enabled?
148
+ collapsible? && (options[:remember].nil? || !!options[:remember])
149
+ end
150
+
151
+ def heading_tag
152
+ (options[:wrapping_heading_element] || (options[:header_tag] || options[:heading_tag])).presence || 'h3'
153
+ end
154
+
155
+ def heading_class
156
+ (@heading_class || css_classes[:heading]).to_s
157
+ end
158
+
159
+ def icon
160
+ @icon ||= options[:icon] && " icon #{options[:icon]}"
161
+ end
162
+
163
+ def heading_links
164
+ if block_given?
165
+ @heading_links = view.capture { yield }
166
+ else
167
+ @heading_links.to_s.html_safe
168
+ end
169
+ end
170
+
171
+ def collapsible?
172
+ return @collapsible unless @collapsible.nil?
173
+ @collapsible ||= !!options[:toggle] && (options[:collapsible].nil? || !!options[:collapsible])
174
+ end
175
+
176
+ def collapsed?
177
+ !!options[:default] || !!options[:collapsed] || !!options[:default_button_state]
178
+ end
179
+
180
+ def footer
181
+ if block_given?
182
+ @footer = view.capture { yield }
183
+ else
184
+ @footer.to_s.html_safe
185
+ end
186
+ end
187
+
188
+ def render
189
+ view.render({partial: 'common/collapsible_module_layout', locals: {renderer: self, content: content}} )
190
+ end
191
+ private
192
+
193
+ def css_classes
194
+ return @css_classes if @css_classes
195
+ if (css_class = options.delete(:class)).is_a?(Hash)
196
+ @css_classes = css_class
197
+ else
198
+ @css_classes = {
199
+ container: css_class,
200
+ heading: css_class,
201
+ content: css_class
202
+ }
203
+ end
161
204
  end
162
205
 
163
- html.html_safe
164
206
  end
165
207
 
208
+
166
209
  def autocomplete_field_tag(name, jsonpath_or_array, selected_values, options = {})
167
- options.reverse_merge!({select_first_value: false, show_toggle_button: false, load_immediately: false, preload: true, multiple: true})
210
+ options.reverse_merge!({select_first_value: false, show_toggle_button: false, load_immediately: false})
168
211
  options[:id] ||= sanitize_to_id(name)
169
212
 
170
213
  selected_values ||= []
@@ -177,7 +220,7 @@ module RedmineExtensions
177
220
 
178
221
  content_tag(:span, :class => 'easy-multiselect-tag-container') do
179
222
  text_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
180
- javascript_tag("$('##{options[:id]}').easymultiselect({multiple: #{options[:multiple]}, rootElement: #{options[:rootElement].to_json}, inputName: '#{name}', preload: #{options[:preload]}, source: #{source}, selected: #{selected_values.to_json}, show_toggle_button: #{options[:show_toggle_button]}, select_first_value: #{options[:select_first_value]}, load_immediately: #{options[:load_immediately]}, autocomplete_options: #{(options[:jquery_auto_complete_options]||{}).to_json} });")
223
+ javascript_tag("$('##{options[:id]}').easymultiselect({multiple: true, rootElement: #{options[:rootElement]}, inputName: '#{name}', preload: true, source: #{source}, selected: #{selected_values.to_json}, show_toggle_button: #{options[:show_toggle_button]}, select_first_value: #{options[:select_first_value]}, load_immediately: #{options[:load_immediately]}, autocomplete_options: #{(options[:jquery_auto_complete_options]||{}).to_json} });")
181
224
  end
182
225
  end
183
226
 
@@ -20,5 +20,10 @@ module RedmineExtensions
20
20
  partial.prepend("#{prefixes.last}/")
21
21
  render(*attrs)
22
22
  end
23
+
24
+ def query_outputs(presenter_or_query, options={})
25
+ presenter = present(presenter_or_query, options) rescue RedmineExtensions::BasePresenter.new(presenter_or_query, self, options)
26
+ RedmineExtensions::EasyQueryHelpers::Outputs.new(presenter, self)
27
+ end
23
28
  end
24
29
  end
@@ -0,0 +1,50 @@
1
+ class EasyQueryAdapterPresenter < RedmineExtensions::BasePresenter
2
+
3
+ # --- GETTERS ---
4
+ attr_accessor :page_module, :row_limit
5
+
6
+ # should be defined in parent in future
7
+ def initialize(query, view_context=nil, options={})
8
+ super(query, view_context, options)
9
+ @query = query
10
+
11
+ @page_module = options[:page_module]
12
+
13
+ end
14
+
15
+ def entities(options={})
16
+ #can not fetch, cuz gantt is fetching enstead of nil
17
+ @entities ||= @options[:entities] || h.instance_variable_get(:@entities) #|| model.entities(options)
18
+ end
19
+
20
+ def entity_count(options={})
21
+ @entity_count ||= h.instance_variable_get(:@entity_count) || model.entity_count(options)
22
+ end
23
+
24
+ def entity_pages
25
+ @options[:entity_pages] || h.instance_variable_get(:@entity_pages)
26
+ end
27
+
28
+ def available_outputs
29
+ outputs.available_outputs
30
+ end
31
+
32
+ def outputs
33
+ @outputs ||= RedmineExtensions::EasyQueryHelpers::Outputs.new(self)
34
+ end
35
+
36
+ # ----- RENDERING HELPERS ----
37
+
38
+ def default_name
39
+ h.l(self.class.name.underscore, :scope => [:easy_query, :name])
40
+ end
41
+
42
+ def name
43
+ @name ||= options[:easy_query_name] || (model.new_record? ? default_name : model.name)
44
+ end
45
+
46
+ def filters_active?
47
+ model.filters.any?
48
+ end
49
+
50
+ end
@@ -0,0 +1,13 @@
1
+ <div class="module box <%= renderer.container_class %>"<%=raw renderer.collapsible? && %Q{ data-toggle="#{renderer.id}"} || nil %>>
2
+ <%= content_tag(:div, class: 'module-heading ' + renderer.heading_class, onclick: (renderer.saving_state_enabled? && 'EasyToggler.toggle(this.nextElementSibling, event)' || nil)) do %>
3
+ <span class="expander module-toggler">&nbsp;</span>
4
+ <%= content_tag(renderer.heading_tag, renderer.heading, class: renderer.icon) %>
5
+ <%= content_tag(:span, renderer.heading_links, class: 'module-heading-links') if renderer.heading_links %>
6
+ <% end %>
7
+ <div class="module-content" id="<%= renderer.id %>"<%=raw renderer.collapsed? && %q{ style="display:none"} || nil %>>
8
+ <%= content -%>
9
+ <%= content_tag(:div, class: 'module-content-footer') do %>
10
+ <%= renderer.footer %>
11
+ <% end if renderer.footer.present? %>
12
+ </div>
13
+ </div>
@@ -1,24 +1,20 @@
1
1
  <%
2
- display_style = options[:display_style] || (entities_count > 3 ? :list : :tile)
3
- heading = "#{options[:heading]} (#{entities_count})"
2
+ heading = "#{options[:heading]} (#{entities_count})"
4
3
  %>
5
4
  <% if entities_count > 0 %>
6
- <div id="<%= options[:module_name] %>_container" class="entity_references_container easy-dropper-target easy-drop-issue <%= display_style.to_s %>" data-drop-action="<%= entity.class.name.underscore %>" data-entity-id="<%= entity.id %>" data-issue-show="1">
7
- <%= call_hook(:view_easy_entity_assignemnt_top, :entity => entity, :query => query, :entities => entities, :options => options, :target_class => target_class) %>
8
- <div class="box">
5
+ <div id="<%= options[:module_name] %>_container" class="entity_references_container easy-dropper-target easy-drop-issue" data-drop-action="<%= entity.class.name.underscore %>" data-entity-id="<%= entity.id %>" data-issue-show="1">
6
+ <%= call_hook(:view_easy_entity_assignemnt_top, :entity => entity, :query => query, :entities => entities, :options => options) %>
9
7
  <%# entity_cards_params = {:module_name => options[:module_name], :project_id => project, :source_entity_type => entity.class.name, :source_entity_id => entity, :referenced_entity_type => referenced_entity_type, :referenced_collection_name => options[:referenced_collection_name]}.merge!(query.to_params) %>
10
8
  <% entity_cards_params = {} %>
11
- <%= render_toggler(options[:module_name], User.current, {:heading => heading + ':', :wrapping_heading_element_classes => entity_css_icon(target_class),
12
- :container_html => {:class => 'module-inside'}, :default_button_state => false, :heading_links => [
13
- link_to('', {}, :class => 'icon-slab', :remote => true, :data => {:display => 'slab'}, :title => l(:title_easy_card_display_changer_tile)),
14
- link_to('', {}, :class => 'icon-bullet-list', :remote => true, :data => {:display => 'list'}, :title => l(:title_easy_card_display_changer_list))
15
- ]}) do %>
16
-
17
-
9
+ <%= render_module_easy_box(options[:module_name], heading+':', {class: {heading: entity_css_icon(query.entity), container: 'module-inside'}, default: false}) do |m| %>
10
+ <% m.heading_links do %>
11
+ <%= link_to('', {}, :class => 'icon-slab', :remote => true, :data => {:display => 'slab'}, :title => l(:title_easy_card_display_changer_tile)) %>
12
+ <%= link_to('', {}, :class => 'icon-bullet-list', :remote => true, :data => {:display => 'list'}, :title => l(:title_easy_card_display_changer_list)) %>
13
+ <% end %>
18
14
  <%= render(:partial => 'easy_entity_assignments/query_index', :locals => {
19
15
  :entity => entity,
20
- :query => query, :target_class => target_class,
21
- :project => project, :options => options, :entities => entities, :display_style => display_style}) %>
16
+ :query => query,
17
+ :project => project, :options => options, :referenced_entities => entities}) %>
22
18
 
23
19
 
24
20
  <% if options[:context_menus_path] && respond_to?(options[:context_menus_path]) %>
@@ -26,5 +22,4 @@
26
22
  <% end %>
27
23
  <% end %>
28
24
  </div>
29
- </div>
30
25
  <% end %>
@@ -1,11 +1,3 @@
1
- <% if display_style == :list %>
2
- <%= render :partial => 'easy_queries/easy_query_entities_list', :locals => {:query => query, :entities => entities, :options => {:hascontextmenu => true, :disable_sort => true} } -%>
3
- <% elsif display_style == :tile %>
4
- <div class="easy-entity-cards-container">
5
- <div class="splitcontent">
6
- <% entities.each do |referenced_entity| %>
7
- <%# render_easy_entity_card(referenced_entity, entity, options.merge(:referenced_entities => referenced_entities)) %>
8
- <% end %>
9
- </div>
10
- </div>
1
+ <% query_outputs(query, entities: referenced_entities, options: { hascontextmenu: true, disable_sort: true }).each do |output| %>
2
+ <%= output.render_data %>
11
3
  <% end %>
@@ -0,0 +1,7 @@
1
+ <div class="easy-entity-cards-container">
2
+ <div class="splitcontent">
3
+ <% query.entities.each do |referenced_entity| %>
4
+ <%= output.render_entity_tile(referenced_entity) %>
5
+ <% end %>
6
+ </div>
7
+ </div>
@@ -1,4 +1,4 @@
1
- <%= form_for(@easy_settings, html: { class: 'form-box easy-setting-plugin-form' }) do |f| %>
1
+ <%= form_for([redmine_extensions_engine, @easy_settings], html: { class: 'form-box easy-setting-plugin-form' }) do |f| %>
2
2
  <%= hidden_field_tag :back_url, params[:back_url] %>
3
3
 
4
4
  <%= render "easy_settings/#{@easy_settings.plugin.id}", easy_settings: @easy_settings, settings: @settings, form: f %>
data/config/routes.rb CHANGED
@@ -1,11 +1,7 @@
1
- # Engine routes
2
1
  RedmineExtensions::Engine.routes.draw do
3
- resources :easy_settings, except: :destroy
4
- end
5
-
6
- # Redmine routes
7
- Rails.application.routes.draw do
8
- mount RedmineExtensions::Engine => '/redmine_extensions'
9
2
 
10
3
  resources :easy_settings, except: :destroy
4
+
11
5
  end
6
+
7
+ RedmineExtensions::Engine.automount!
@@ -33,4 +33,4 @@
33
33
  <%- if acts_as_attachable? -%>
34
34
  <p id="attachments_form"><label><%%= l(:label_attachment_plural) %></label><%%= render :partial => 'attachments/form', :locals => {:container => <%= model_name_underscored %>} %></p>
35
35
  <%- end -%>
36
- <%% end %>
36
+ <%% end %>
@@ -1,9 +1,9 @@
1
- <ul>
2
- <%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
3
- <li><%%= link_to l(:button_edit), edit_polymorphic_path([@project, @<%= model_name_underscored %>]), title: l(:button_edit), class: 'icon icon-edit' %></li>
4
- <%% end %>
5
- <%% if @<%= model_name_underscored %>.nil? %>
6
- <li><%%= link_to l(:button_<%= model_name_underscored %>_new), new_polymorphic_path([@project, :<%= model_name_underscored %>]), title: l(:title_<%= model_name_underscored %>_new), class: 'icon icon-add button button-positive' %></li>
7
- <%% end %>
8
- <li><%%= link_to l(:label_<%= model_name_pluralize_underscored %>), polymorphic_path([@project, :<%= model_name_pluralize_underscored %>], set_filter: '1'), title: l(:label_<%= model_name_pluralize_underscored %>), class: 'icon icon-folder button' %></li>
1
+ <ul>
2
+ <%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
3
+ <li><%%= link_to l(:button_edit), edit_polymorphic_path([@project, @<%= model_name_underscored %>]), title: l(:button_edit), class: 'icon icon-edit' %></li>
4
+ <%% end %>
5
+ <%% if @<%= model_name_underscored %>.nil? %>
6
+ <li><%%= link_to l(:button_<%= model_name_underscored %>_new), new_polymorphic_path([@project, :<%= model_name_underscored %>]), title: l(:title_<%= model_name_underscored %>_new), class: 'icon icon-add button button-positive' %></li>
7
+ <%% end %>
8
+ <li><%%= link_to l(:label_<%= model_name_pluralize_underscored %>), polymorphic_path([@project, :<%= model_name_pluralize_underscored %>], set_filter: '1'), title: l(:label_<%= model_name_pluralize_underscored %>), class: 'icon icon-folder button' %></li>
9
9
  </ul>
@@ -1,8 +1,8 @@
1
- <ul>
2
- <%% if @<%= model_name_underscored %> -%>
3
- <li><%%= context_menu_link l(:button_edit), edit_<%= model_name_underscored %>_path(@<%= model_name_underscored %>), class: 'icon icon-edit', disabled: !@can[:edit] %></li>
4
- <%% end %>
5
- <li><%%= context_menu_link l(:button_delete), <%= model_name_pluralize_underscored %>_path(ids: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: {confirm: l(:text_are_you_sure)}, class: 'icon icon-del', disabled: !@can[:delete] %></li>
6
-
7
- <%%= call_hook(:view_<%= model_name_pluralize_underscored %>_context_menu_end, {<%= model_name_underscored %>: @<%= model_name_underscored %>, <%= model_name_pluralize_underscored %>: @<%= model_name_pluralize_underscored %>, can: @can, back: @back, project: @project}) %>
1
+ <ul>
2
+ <%% if @<%= model_name_underscored %> -%>
3
+ <li><%%= context_menu_link l(:button_edit), edit_<%= model_name_underscored %>_path(@<%= model_name_underscored %>), class: 'icon icon-edit', disabled: !@can[:edit] %></li>
4
+ <%% end %>
5
+ <li><%%= context_menu_link l(:button_delete), <%= model_name_pluralize_underscored %>_path(ids: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: {confirm: l(:text_are_you_sure)}, class: 'icon icon-del', disabled: !@can[:delete] %></li>
6
+
7
+ <%%= call_hook(:view_<%= model_name_pluralize_underscored %>_context_menu_end, {<%= model_name_underscored %>: @<%= model_name_underscored %>, <%= model_name_pluralize_underscored %>: @<%= model_name_pluralize_underscored %>, can: @can, back: @back, project: @project}) %>
8
8
  </ul>
@@ -1,7 +1,7 @@
1
- class <%= model_name %>CustomField < CustomField
2
-
3
- def type_name
4
- :label_<%= @model_name_pluralize_underscored %>
5
- end
6
-
7
- end
1
+ class <%= model_name %>CustomField < CustomField
2
+
3
+ def type_name
4
+ :label_<%= @model_name_pluralize_underscored %>
5
+ end
6
+
7
+ end