redmine_extensions 0.0.39 → 0.1.01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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