redmine_extensions 0.3.7 → 0.4.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +10 -33
  3. data/app/helpers/redmine_extensions/application_helper.rb +8 -10
  4. data/app/models/easy_setting.rb +1 -1
  5. data/app/presenters/redmine_extensions/easy_setting_presenter.rb +1 -1
  6. data/lib/generators/redmine_extensions/entity/entity_generator.rb +2 -2
  7. data/lib/generators/redmine_extensions/entity/templates/_form.html.erb.erb +27 -24
  8. data/lib/generators/redmine_extensions/entity/templates/_list.html.erb.erb +48 -47
  9. data/lib/generators/redmine_extensions/entity/templates/_sidebar.html.erb.erb +8 -8
  10. data/lib/generators/redmine_extensions/entity/templates/context_menu.html.erb.erb +10 -11
  11. data/lib/generators/redmine_extensions/entity/templates/edit.html.erb.erb +3 -3
  12. data/lib/generators/redmine_extensions/entity/templates/edit.js.erb.erb +4 -4
  13. data/lib/generators/redmine_extensions/entity/templates/index.api.rsb.erb +2 -2
  14. data/lib/generators/redmine_extensions/entity/templates/index.html.erb.erb +2 -2
  15. data/lib/generators/redmine_extensions/entity/templates/index.js.erb.erb +2 -2
  16. data/lib/generators/redmine_extensions/entity/templates/new.html.erb.erb +4 -4
  17. data/lib/generators/redmine_extensions/entity/templates/new.js.erb.erb +4 -4
  18. data/lib/generators/redmine_extensions/entity/templates/show.html.erb.erb +6 -6
  19. data/lib/generators/redmine_extensions/entity/templates/show.js.erb.erb +2 -2
  20. data/lib/redmine_extensions/easy_query_helpers/outputs.rb +2 -2
  21. data/lib/redmine_extensions/easy_settings/mapper.rb +1 -1
  22. data/lib/redmine_extensions/engine.rb +8 -6
  23. data/lib/redmine_extensions/migration.rb +1 -1
  24. data/lib/redmine_extensions/patch_manager.rb +5 -13
  25. data/lib/redmine_extensions/version.rb +1 -1
  26. data/spec/features/autocomplete_spec.rb +2 -2
  27. metadata +8 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a09c29deceeb65baa0a4b83ea1546cdf8a316535ac6813777889b7aa45d0661
4
- data.tar.gz: 2946755a797aea4a7b5d135d893cc67e6d1b352c565022553e35342c52f1f8a2
3
+ metadata.gz: 186ecf1e1604893d9fda643e2b589dbada90b4319c0da5d7a5c2c0f3c53eb176
4
+ data.tar.gz: f956c9668a5926ba5012902dfb2a1c88d2dd020f7ea06428310e3ef3963e9cff
5
5
  SHA512:
6
- metadata.gz: bbf4463f41a86b822392978939c9902c31071e05745f419abc50ca1f2d893cd5c1098c009ac4361d3b3078fa6aa2a27710d7d9a7023c823bf4dd9dc908fd9d35
7
- data.tar.gz: 354ce6a7fcd2d02b718e4642280083e4af5592be0542d92ce4a1142e4f53200c8ed53c22917c4e5d375a735396fb8358fe23315306699029b872c13583efdc4e
6
+ metadata.gz: ac84a447270e5d19538c99c5fc6d4dcd95ac936de8645c179ebd497d27d09ff65f2def4d24ee5f1b80aa9ac4d78289feca73edfe1242ac94d4a136e03dd50804
7
+ data.tar.gz: ca999dfd768ba7df0f23f45f5508136eeebd4b09fdef1a92383ec26d0c4d6e3d950252b420913e804eafde49498b00e55122773f490dfce1bb4b53a6de8ea7a4
@@ -88,9 +88,9 @@ EasyGem.schedule.require(function () {
88
88
  },
89
89
  activate_on_input_click: true,
90
90
  load_immediately: false,
91
- show_toggle_button: true,
92
91
  select_first_value: true,
93
- autocomplete_options: {}
92
+ autocomplete_options: {},
93
+ multiselectOnChange: null // onchange of multiselect input function
94
94
  },
95
95
 
96
96
  _create: function () {
@@ -102,7 +102,7 @@ EasyGem.schedule.require(function () {
102
102
  if (Array.isArray(this.options.source)) {
103
103
  this.options.preload = true;
104
104
  this._initData(this.options.source);
105
- } else if (this.options.preload && this.options.load_immediately) {
105
+ } else if ( (this.options.preload || this.options.select_first_value) && this.options.load_immediately ) {
106
106
  this.load();
107
107
  } else if (this.selectedValues) {
108
108
  this.setValue(this.selectedValues);
@@ -119,9 +119,6 @@ EasyGem.schedule.require(function () {
119
119
  this.valueElement = $('<span></span>');
120
120
  this.tag.after(this.valueElement);
121
121
 
122
- if (this.options.show_toggle_button)
123
- this._createToggleButton();
124
-
125
122
  this.valueElement.entityArray({
126
123
  inputNames: this.inputName,
127
124
  afterRemove: function (entity) {
@@ -138,31 +135,11 @@ EasyGem.schedule.require(function () {
138
135
  this.element.css('margin-right', 0);
139
136
  }
140
137
  },
141
-
142
- _createToggleButton: function () {
143
- var that = this;
144
- this.link_ac_toggle = $('<a>').attr('class', 'icon icon-add clear-link');
145
- this.link_ac_toggle.click(function (evt) {
146
- var $elem = $(this);
147
- evt.preventDefault();
148
- that.load(function () {
149
- var select = $('<select>').prop('multiple', true).prop('size', 5).prop('name', that.inputName);
150
- var option;
151
- $.each(that.possibleValues, function (i, v) {
152
- option = $('<option>').prop('value', v.id).text(v.value);
153
- option.prop('selected', that.getValue().indexOf(v.id) > -1);
154
- select.append(option);
155
- });
156
- var $container = $elem.closest('.easy-multiselect-tag-container');
157
- $container.find(':input').prop('disabled', true);
158
- $container.children().hide();
159
- $container.append(select);
160
- that.valueElement = select;
161
- that.expanded = true;
162
- });
163
- });
164
- this.element.parent().addClass('input-append');
165
- this.element.after(this.link_ac_toggle);
138
+ setMultiselectOnChange: function (fn) {
139
+ this.options.multiselectOnChange = fn;
140
+ },
141
+ multiselectOnChange: function(select, fn) {
142
+ if (fn) select.on("change", fn);
166
143
  },
167
144
 
168
145
  _createAutocomplete: function () {
@@ -278,7 +255,7 @@ EasyGem.schedule.require(function () {
278
255
  this.valuesLoaded = true;
279
256
 
280
257
  this.selectedValues = this.selectedValues ? this.selectedValues : [];
281
- if (this.selectedValues.length === 0 && this.options.preload && this.options.select_first_value && this.possibleValues.length > 0) {
258
+ if (this.selectedValues.length === 0 && this.options.select_first_value && this.possibleValues.length > 0) {
282
259
  this.selectedValues.push(this.possibleValues[0]['id']);
283
260
  }
284
261
 
@@ -373,7 +350,7 @@ EasyGem.schedule.require(function () {
373
350
  for (var i = values.length - 1; i >= 0; i--) {
374
351
  if (values[i] instanceof Object && !Array.isArray(values[i]) && values[i] !== null) {
375
352
  selected.push(values[i]);
376
- } else if (this.options.preload) {
353
+ } else if (this.options.preload || this.options.select_first_value) {
377
354
  var that = this;
378
355
  if (!Array.isArray(that.possibleValues))
379
356
  return;
@@ -20,7 +20,7 @@ module RedmineExtensions
20
20
  else
21
21
  presenter = RedmineExtensions::BasePresenter.present(model, self, options)
22
22
  end
23
- if block_given?
23
+ if block
24
24
  yield presenter
25
25
  else
26
26
  presenter
@@ -110,7 +110,7 @@ module RedmineExtensions
110
110
 
111
111
  def late_javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
112
112
  content =
113
- if block_given?
113
+ if block
114
114
  html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
115
115
  capture(&block)
116
116
  else
@@ -183,8 +183,8 @@ module RedmineExtensions
183
183
 
184
184
  def container_class
185
185
  s = (@container_class.presence || css_classes[:container]).to_s
186
- s << ' collapsible' if collapsible?
187
- s << ' collapsed' if collapsed?
186
+ s += ' collapsible' if collapsible?
187
+ s += ' collapsed' if collapsed?
188
188
 
189
189
  s
190
190
  end
@@ -264,7 +264,6 @@ module RedmineExtensions
264
264
  # * +load_immediately+ - tells if values should be loaded immediatelly after page loaded, or wait for first use of the field.
265
265
  # Warning! if this option is false, selected values passed in first format will be ignored till it is loaded.
266
266
  # Please use second format for proper functionality.
267
- # * +show_toggle_button+ - only valid with <tt>multiple: true, preload: true</tt> options set. Shows toggle button to expand select to the multiselect tag.
268
267
  # * +select_first_value+ - if selectd_values are empty, with this option first available value will be selected.
269
268
  # Available only with <tt>preload: true</tt> option.
270
269
  # With <tt>load_immediately: false</tt> it will appear kinda weird for user because it will select the value after user starts to interact with input.
@@ -272,7 +271,7 @@ module RedmineExtensions
272
271
  # * +rootElement+ - Has sence only if jsonpath is used for available values. It tells if the json response has values wrapped under root element.
273
272
  # For response like <tt>{projects: [[<name>, <id>], [<name2>, <id2>]]}</tt> user option <tt>rootElement: 'projects'</tt>
274
273
  def autocomplete_field_tag(name, jsonpath_or_array, selected_values, options = {})
275
- options.reverse_merge!({select_first_value: false, show_toggle_button: false, load_immediately: false, preload: true, multiple: true, combo: false})
274
+ options.reverse_merge!({select_first_value: false, load_immediately: false, preload: true, multiple: true, combo: false})
276
275
  options[:id] ||= sanitize_to_id(name)
277
276
 
278
277
  selected_values ||= []
@@ -284,8 +283,8 @@ module RedmineExtensions
284
283
  end
285
284
 
286
285
  content_tag(:span, :class => 'easy-multiselect-tag-container') do
287
- text_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
288
- late_javascript_tag("$('##{options[:id]}').easymultiselect({multiple: #{options[:multiple]}, rootElement: #{options[:rootElement].to_json}, inputName: '#{name}', preload: #{options[:preload]}, combo: #{options[:combo]}, 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} });")
286
+ search_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
287
+ late_javascript_tag("$('##{options[:id]}').easymultiselect({multiple: #{options[:multiple]}, rootElement: #{options[:rootElement].to_json}, inputName: '#{name}', preload: #{options[:preload]}, combo: #{options[:combo]}, source: #{source}, selected: #{selected_values.to_json}, select_first_value: #{options[:select_first_value]}, load_immediately: #{options[:load_immediately]}, autocomplete_options: #{(options[:jquery_auto_complete_options]||{}).to_json} });")
289
288
  end
290
289
  end
291
290
 
@@ -297,13 +296,12 @@ module RedmineExtensions
297
296
  # HTML options can be passed as a hash with +html_options+. These options will be passed to the input element.
298
297
  #
299
298
  # ==== Examples
300
- # autocomplete_field(:issue, :tag_ids, Tag.all.pluck(:name, :id), multiple: true, show_toggle_button: true)
299
+ # autocomplete_field(:issue, :tag_ids, Tag.all.pluck(:name, :id), multiple: true)
301
300
  # # => <span class="easy-multiselect-tag-container"> \
302
301
  # <input type="text" id="issue_tags" /> \
303
302
  # <button type="button" tabindex="-1" class="..." role="button" ...>
304
303
  # <span class="ui-button-icon-primary ui-icon ui-icon-triangle-1-s"></span><span class="ui-button-text">&nbsp;</span>
305
304
  # </button>
306
- # <a class="icon icon-add clear-link"></a> # toggle button to the multiselect tag from show_toggle_button option
307
305
  # ...(wraping service tags)
308
306
  # <input type="hidden" name="issue[tag_ids][]" value="#{@issue.tag_ids.first}" />
309
307
  # <input type="hidden" name="issue[tag_ids][]" value="#{@issue.tag_ids.second}" />
@@ -78,7 +78,7 @@ class EasySetting < ActiveRecord::Base
78
78
  @@mapper = EasySettings::Mapper.new
79
79
 
80
80
  def self.map(&block)
81
- if block_given?
81
+ if block
82
82
  @@mapper.instance_eval(&block)
83
83
  else
84
84
  @@mapper
@@ -119,7 +119,7 @@ module RedmineExtensions
119
119
  end
120
120
 
121
121
  def method_missing(meth, *attrs)
122
- if @plugin && @plugin.settings[:easy_settings] && @plugin.settings[:easy_settings].keys.include?(meth.to_sym)
122
+ if @plugin && @plugin.settings[:easy_settings] && @plugin.settings[:easy_settings].key?(meth.to_sym)
123
123
  EasySetting.value(prefix+meth.to_s, project_id)
124
124
  else
125
125
  super
@@ -385,7 +385,7 @@ module RedmineExtensions
385
385
  end
386
386
 
387
387
  def name_column
388
- 'name' if string_columns.keys.include?('name')
388
+ 'name' if string_columns.key?('name')
389
389
  string_columns.keys.first
390
390
  end
391
391
 
@@ -394,7 +394,7 @@ module RedmineExtensions
394
394
  end
395
395
 
396
396
  def description_column
397
- 'description' if text_columns.keys.include?('description')
397
+ 'description' if text_columns.key?('description')
398
398
  text_columns.keys.first
399
399
  end
400
400
 
@@ -1,38 +1,38 @@
1
1
  <%%= fields_for :<%= model_name_underscored %>, <%= model_name_underscored %> do |f| %>
2
2
  <%- if project? -%>
3
3
  <%% if <%= model_name_underscored %>.safe_attribute?('project_id') && !@project %>
4
- <p>
5
- <%%= f.label :project_id, ::<%= model_name %>.human_attribute_name(:project_id) %>
6
- <%%= f.select :project_id, Project.allowed_to(:manage_<%= model_name_pluralize_underscored %>).collect{|x| [x.name, x.id]}, include_blank: true %>
7
- </p>
4
+ <p>
5
+ <%%= f.label :project_id, ::<%= model_name %>.human_attribute_name(:project_id) %>
6
+ <%%= f.select :project_id, Project.allowed_to(:manage_<%= model_name_pluralize_underscored %>).collect{|x| [x.name, x.id]}, include_blank: true %>
7
+ </p>
8
8
  <%% end %>
9
9
  <%- end -%>
10
10
  <%- safe_columns.each do |column_name, column_options| -%>
11
11
  <%% if <%= model_name_underscored %>.safe_attribute?('<%= column_name %>') %>
12
- <p>
13
- <%%= f.label :<%= column_name %>, ::<%= model_name %>.human_attribute_name(:<%= column_name %>) %>
14
- <%- if column_options[:query_type] == 'string' || column_options[:query_type] == 'integer' -%>
15
- <%%= f.text_field :<%= column_name %> %>
16
- <%- elsif column_options[:query_type] == 'list' || column_options[:query_type] == 'list_optional' -%>
17
- <%%= f.select :<%= column_name %>, <%= column_options[:class] %>.all.collect{|x| [x.<%= column_options[:list_class_name] %>, x.id]}.sort, include_blank: true %>
18
- <%- elsif column_options[:query_type] == 'text' -%>
19
- <%%= f.text_area :<%= column_name %>, :cols => 60, :rows => (<%= model_name_underscored %>.<%= column_name %>.blank? ? 10 : [[10, <%= model_name_underscored %>.<%= column_name %>.length / 50].max, 100].min), :accesskey => accesskey(:edit), :class => 'wiki-edit' %>
20
- <%%= wikitoolbar_for '<%= model_name_underscored %>_<%= column_name %>' %>
21
- <%- elsif column_options[:query_type] == 'boolean' -%>
22
- <%%= f.radio_button :<%= column_name %>, false %>
23
- <%- else -%>
24
- <%%= f.text_field :<%= column_name %> %>
25
- <%- end -%>
26
- </p>
12
+ <p>
13
+ <%%= f.label :<%= column_name %>, ::<%= model_name %>.human_attribute_name(:<%= column_name %>) %>
14
+ <%- if column_options[:query_type] == 'string' || column_options[:query_type] == 'integer' -%>
15
+ <%%= f.text_field :<%= column_name %> %>
16
+ <%- elsif column_options[:query_type] == 'list' || column_options[:query_type] == 'list_optional' -%>
17
+ <%%= f.select :<%= column_name %>, <%= column_options[:class] %>.all.collect{|x| [x.<%= column_options[:list_class_name] %>, x.id]}.sort, include_blank: true %>
18
+ <%- elsif column_options[:query_type] == 'text' -%>
19
+ <%%= f.text_area :<%= column_name %>, cols: 60, rows: (<%= model_name_underscored %>.<%= column_name %>.blank? ? 10 : [[10, <%= model_name_underscored %>.<%= column_name %>.length / 50].max, 100].min), accesskey: accesskey(:edit), class: 'wiki-edit' %>
20
+ <%%= wikitoolbar_for '<%= model_name_underscored %>_<%= column_name %>' %>
21
+ <%- elsif column_options[:query_type] == 'boolean' -%>
22
+ <%%= f.radio_button :<%= column_name %>, false %>
23
+ <%- else -%>
24
+ <%%= f.text_field :<%= column_name %> %>
25
+ <%- end -%>
26
+ </p>
27
27
  <%% end %>
28
28
  <%- end -%>
29
29
  <% associations.each do |assoc| %>
30
30
  <%- next if assoc[1][:type] == 'has_many' -%>
31
31
  <% association_name = assoc[0] %>
32
- <p>
33
- <%%= f.label l(:label_<%= association_name %>) %>
34
- <%%= f.select :<%= association_name %>_id, <%= association_name.camelcase %>.visible.sorted.map{ |<%= association_name %>| [<%= association_name %>.to_s, <%= association_name %>.id]} %>
35
- </p>
32
+ <p>
33
+ <%%= f.label l(:label_<%= association_name %>) %>
34
+ <%%= f.select :<%= association_name %>_id, <%= association_name.camelcase %>.visible.sorted.map{ |<%= association_name %>| [<%= association_name %>.to_s, <%= association_name %>.id]} %>
35
+ </p>
36
36
  <% end %>
37
37
  <%- if acts_as_customizable? -%>
38
38
  <%% custom_field_values = <%= model_name_underscored %>.visible_custom_field_values %>
@@ -43,6 +43,9 @@
43
43
  <%% end %>
44
44
  <%- end -%>
45
45
  <%- if acts_as_attachable? -%>
46
- <p id="attachments_form"><label><%%= l(:label_attachment_plural) %></label><%%= render :partial => 'attachments/form', :locals => {:container => <%= model_name_underscored %>} %></p>
46
+ <p id="attachments_form">
47
+ <label><%%= l(:label_attachment_plural) %></label>
48
+ <%%= render partial: 'attachments/form', locals: { container: <%= model_name_underscored %> } %>
49
+ </p>
47
50
  <%- end -%>
48
51
  <%% end %>
@@ -1,5 +1,5 @@
1
- <%%= form_tag({}, :data => {:cm_url => context_menu_<%= model_name_pluralize_underscored %>_path}) do -%>
2
- <%%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
1
+ <%%= form_tag({}, data: {cm_url: context_menu_<%= model_name_pluralize_underscored %>_path}) do %>
2
+ <%%= hidden_field_tag 'back_url', url_for(params: request.query_parameters), id: nil %>
3
3
  <div class="autoscroll">
4
4
  <table class="list odd-even entities">
5
5
  <thead>
@@ -15,55 +15,56 @@
15
15
  </tr>
16
16
  </thead>
17
17
  <tbody>
18
- <%% grouped_query_results(entities, @query) do |entity, group_name, group_count, group_totals| -%>
19
- <%% if group_name %>
20
- <%% reset_cycle %>
21
- <tr class="group open">
22
- <td colspan="<%%= @query.inline_columns.size + 2 %>">
23
- <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
24
- <span class="name"><%%= group_name %></span>
25
- <%% if group_count %>
26
- <span class="count"><%%= group_count %></span>
27
- <%% end %>
28
- <span class="totals"><%%= group_totals %></span>
29
- <%%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
30
- "toggleAllRowGroups(this)", class: 'toggle-all') %>
31
- </td>
32
- </tr>
33
- <%% end %>
34
- <tr id="entity_id_<%%= entity.id %>" class="entity <%%= cycle('odd', 'even') %> hascontextmenu">
35
- <td class="checkbox hide-when-print"><%%= check_box_tag("ids[]", entity.id, false, id: nil) %></td>
36
- <%% @query.inline_columns.each do |column| %>
37
- <%%= content_tag('td', column_content(column, entity), class: column.css_classes) %>
18
+ <%% grouped_query_results(entities, @query) do |entity, group_name, group_count, group_totals| %>
19
+ <%% if group_name %>
20
+ <%% reset_cycle %>
21
+ <tr class="group open">
22
+ <td colspan="<%%= @query.inline_columns.size + 2 %>">
23
+ <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
24
+ <span class="name"><%%= group_name %></span>
25
+ <%% if group_count %>
26
+ <span class="count"><%%= group_count %></span>
27
+ <%% end %>
28
+ <span class="totals"><%%= group_totals %></span>
29
+ <%%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
30
+ 'toggleAllRowGroups(this)', class: 'toggle-all') %>
31
+ </td>
32
+ </tr>
38
33
  <%% end %>
39
- <td class="buttons">
40
- <%% if entity.editable_by?(User.current) -%>
41
- <%%= link_to l(:button_edit), edit_<%= model_name_underscored %>_path(entity),
42
- title: l(:button_edit),
43
- class: 'icon-only icon-edit' %>
44
- <%%= link_to l(:button_delete), <%= model_name_underscored %>_path(entity),
45
- data: {confirm: l(:text_are_you_sure)},
46
- method: :delete,
47
- title: l(:button_delete),
48
- class: 'icon-only icon-del' %>
49
- <%% end -%>
50
- </td>
51
- </tr>
52
- <%% @query.block_columns.each do |column|
53
- if (text = column_content(column, entity)) && text.present? -%>
54
- <tr class="<%%= current_cycle %>">
55
- <td colspan="<%%= @query.inline_columns.size + 1 %>" class="<%%= column.css_classes %>">
56
- <%% if query.block_columns.count > 1 %>
57
- <span><%%= column.caption %></span>
34
+ <tr id="entity_id_<%%= entity.id %>" class="entity <%%= cycle('odd', 'even') %> hascontextmenu">
35
+ <td class="checkbox hide-when-print"><%%= check_box_tag('ids[]', entity.id, false, id: nil) %></td>
36
+ <%% @query.inline_columns.each do |column| %>
37
+ <%%= content_tag('td', column_content(column, entity), class: column.css_classes) %>
38
+ <%% end %>
39
+ <td class="buttons">
40
+ <%% if entity.editable_by?(User.current) %>
41
+ <%%= link_to l(:button_edit), edit_<%= model_name_underscored %>_path(entity),
42
+ title: l(:button_edit),
43
+ class: 'icon-only icon-edit' %>
44
+ <%%= link_to l(:button_delete), <%= model_name_underscored %>_path(entity),
45
+ data: {confirm: l(:text_are_you_sure)},
46
+ method: :delete,
47
+ title: l(:button_delete),
48
+ class: 'icon-only icon-del' %>
58
49
  <%% end %>
59
- <%%= text %>
60
50
  </td>
61
51
  </tr>
62
- <%% end -%>
63
- <%% end -%>
64
- <%% end -%>
52
+ <%% @query.block_columns.each do |column| %>
53
+ <%% if (text = column_content(column, entity)) && text.present? %>
54
+ <tr class="<%%= current_cycle %>">
55
+ <td colspan="<%%= @query.inline_columns.size + 1 %>" class="<%%= column.css_classes %>">
56
+ <%% if query.block_columns.count > 1 %>
57
+ <span><%%= column.caption %></span>
58
+ <%% end %>
59
+ <%%= text %>
60
+ </td>
61
+ </tr>
62
+ <%% end %>
63
+ <%% end %>
64
+ <%% end %>
65
65
  </tbody>
66
66
  </table>
67
67
  </div>
68
- <%% end -%>
69
- <%%= context_menu %>
68
+ <%% end %>
69
+
70
+ <%%= context_menu %>
@@ -1,9 +1,9 @@
1
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 button' %></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
- </ul>
2
+ <%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
3
+ <%%= content_tag(:li, link_to(l(:button_edit), edit_polymorphic_path([@project, @<%= model_name_underscored %>]), title: l(:button_edit), class: 'icon icon-edit button')) %>
4
+ <%% end %>
5
+ <%% if @<%= model_name_underscored %>.nil? %>
6
+ <%%= content_tag(: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'))
7
+ <%% end %>
8
+ <%%= content_tag(: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')) %>
9
+ </ul>
@@ -1,21 +1,20 @@
1
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
- <%% if @safe_attributes.include? 'status' -%>
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
+ <%% if @safe_attributes.include? 'status' %>
6
6
  <li class="folder">
7
- <a href="#" class="submenu icon icon-issue-status" onclick="return false;"><%%= l(:field_status) -%></a>
7
+ <a href="#" class="submenu icon icon-issue-status" onclick="return false;"><%%= l(:field_status) %></a>
8
8
  <ul>
9
- <%% <%= model_name %>.statuses.keys.each do |s| -%>
9
+ <%% <%= model_name %>.statuses.keys.each do |status| %>
10
10
  <li>
11
- <%%= context_menu_link l("<%= model_name_underscored %>.statuses.#{s}"), bulk_update_<%= model_name_underscored %>_path(id: @<%= model_name_underscored %>_ids, <%= model_name_underscored %>: {status: s}, back_url: @back), method: :put,
12
- selected: (@selected[:status] == s), disabled: !@can[:edit], confirm: l(:text_are_you_sure) %>
11
+ <%%= context_menu_link l("<%= model_name_underscored %>.statuses.#{status}"), bulk_update_<%= model_name_underscored %>_path(id: @<%= model_name_underscored %>_ids, <%= model_name_underscored %>: { status: status }, back_url: @back), method: :put, selected: (@selected[:status] == status), disabled: !@can[:edit], confirm: l(:text_are_you_sure) %>
13
12
  </li>
14
- <%% end -%>
13
+ <%% end %>
15
14
  </ul>
16
15
  </li>
17
16
  <%% end %>
18
- <li><%%= context_menu_link l(:button_delete), <%= model_name_underscored %>_path(id: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: {confirm: l(:text_are_you_sure)}, class: 'icon icon-del', disabled: !@can[:delete] %></li>
17
+ <li><%%= context_menu_link l(:button_delete), <%= model_name_underscored %>_path(id: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: { confirm: l(:text_are_you_sure) }, class: 'icon icon-del', disabled: !@can[:delete] %></li>
19
18
 
20
- <%%= 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}) %>
19
+ <%%= 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 }) %>
21
20
  </ul>
@@ -1,6 +1,6 @@
1
1
  <%%= title l(:heading_<%= model_name_underscored %>_edit) %>
2
2
 
3
- <%%= form_for([@project, @<%= model_name_underscored %>], html: {multipart: <%= acts_as_attachable? %>, id: '<%= model_name_underscored %>_form', class: 'tabular', remote: request.xhr?}) do |f| %>
3
+ <%%= form_for([@project, @<%= model_name_underscored %>], html: { multipart: <%= acts_as_attachable? %>, id: '<%= model_name_underscored %>_form', class: 'tabular', remote: request.xhr? }) do |f| %>
4
4
  <%%= error_messages_for @<%= model_name_underscored %> %>
5
5
 
6
6
  <div class="box">
@@ -15,5 +15,5 @@
15
15
  <%% end %>
16
16
  <%% ### PAGE CUSTOMS ########################################################## %>
17
17
  <%% content_for :sidebar do %>
18
- <%%= render :partial => '<%= model_name_pluralize_underscored %>/sidebar' %>
19
- <%% end %>
18
+ <%%= render partial: '<%= model_name_pluralize_underscored %>/sidebar' %>
19
+ <%% end %>
@@ -2,14 +2,14 @@ var modal = $("#ajax-modal");
2
2
  modal.html("<%%= j render(template: '<%= model_name_pluralize_underscored %>/edit', formats: [:html]) %>");
3
3
  showModal(modal.attr("id"));
4
4
  var submitButton = {
5
- text:"<%%=j l(:button_update) -%>",
6
- title:"<%%=j l(:button_update) -%>",
5
+ text:"<%%=j l(:button_update) %>",
6
+ title:"<%%=j l(:button_update) %>",
7
7
  click: function() {$(this).find('form').submit()},
8
8
  'class': 'button-positive'
9
9
  };
10
10
  var closeButton = {
11
- text: "<%%=j l(:button_close) -%>",
12
- title: "<%%=j l(:button_close) -%>",
11
+ text: "<%%=j l(:button_close) %>",
12
+ title: "<%%=j l(:button_close) %>",
13
13
  click: function() {$(this).dialog('close');},
14
14
  'class': 'button'
15
15
  };
@@ -1,3 +1,3 @@
1
1
  api.array :<%= model_name_pluralize_underscored %>, api_meta(total_count: @entity_count, offset: @offset, limit: @limit) do
2
- render(@entities, {api: api})
3
- end
2
+ render(@entities, { api: api })
3
+ end
@@ -4,7 +4,7 @@
4
4
  <%%= context_menu context_menu_<%= model_name_pluralize_underscored %>_path(project_id: @project) %>
5
5
  <%% content_for :sidebar do %>
6
6
  <%%= render partial: '<%= model_name_pluralize_underscored %>/sidebar' %>
7
- <%%= render partial: 'sidebar/saved_easyqueries_by_type', locals: {query_class: @query.class, project: @project} %>
7
+ <%%= render partial: 'sidebar/saved_easyqueries_by_type', locals: { query_class: @query.class, project: @project } %>
8
8
  <%% end %>
9
9
  <% else %>
10
10
  <div class="contextual">
@@ -27,4 +27,4 @@
27
27
  <span class="pagination"><%%= pagination_links_full @entity_pages, @entity_count %></span>
28
28
  <%% end %>
29
29
  <%% end %>
30
- <% end %>
30
+ <% end %>
@@ -2,8 +2,8 @@ var modal = $("#ajax-modal");
2
2
  modal.html("<%%= j render(template: '<%= model_name_pluralize_underscored %>/index', formats: [:html]) %>");
3
3
  showModal(modal.attr("id"));
4
4
  var closeButton = {
5
- text: "<%%=j l(:button_close) -%>",
6
- title: "<%%=j l(:button_close) -%>",
5
+ text: "<%%=j l(:button_close) %>",
6
+ title: "<%%=j l(:button_close) %>",
7
7
  click: function() {$(this).dialog('close');},
8
8
  'class': 'button'
9
9
  };
@@ -1,10 +1,10 @@
1
1
  <%%= title l(:heading_<%= model_name_underscored %>_new) %>
2
2
 
3
- <%%= form_for([@project, @<%= model_name_underscored %>], html: {multipart: <%= acts_as_attachable? %>, id: '<%= model_name_underscored %>_form', class: 'tabular', remote: request.xhr?}) do |f| %>
3
+ <%%= form_for([@project, @<%= model_name_underscored %>], html: { multipart: <%= acts_as_attachable? %>, id: '<%= model_name_underscored %>_form', class: 'tabular', remote: request.xhr? }) do |f| %>
4
4
  <%%= error_messages_for @<%= model_name_underscored %> %>
5
5
 
6
6
  <div class="box">
7
- <%%= render partial: 'form', locals: {<%= model_name_underscored %>: @<%= model_name_underscored %>} %>
7
+ <%%= render partial: 'form', locals: { <%= model_name_underscored %>: @<%= model_name_underscored %> } %>
8
8
  </div>
9
9
 
10
10
  <%% if !request.xhr? %>
@@ -15,5 +15,5 @@
15
15
  <%% end %>
16
16
  <%% ### PAGE CUSTOMS ########################################################## %>
17
17
  <%% content_for :sidebar do %>
18
- <%%= render :partial => '<%= model_name_pluralize_underscored %>/sidebar' %>
19
- <%% end %>
18
+ <%%= render partial: '<%= model_name_pluralize_underscored %>/sidebar' %>
19
+ <%% end %>
@@ -2,14 +2,14 @@ var modal = $("#ajax-modal");
2
2
  modal.html("<%%= j render(template: '<%= model_name_pluralize_underscored %>/new', formats: [:html]) %>");
3
3
  showModal(modal.attr("id"));
4
4
  var submitButton = {
5
- text:"<%%=j l(:button_create) -%>",
6
- title:"<%%=j l(:button_create) -%>",
5
+ text:"<%%=j l(:button_create) %>",
6
+ title:"<%%=j l(:button_create) %>",
7
7
  click: function() {$(this).find('form').submit()},
8
8
  'class': 'button-positive'
9
9
  };
10
10
  var closeButton = {
11
- text: "<%%=j l(:button_close) -%>",
12
- title: "<%%=j l(:button_close) -%>",
11
+ text: "<%%=j l(:button_close) %>",
12
+ title: "<%%=j l(:button_close) %>",
13
13
  click: function() {$(this).dialog('close');},
14
14
  'class': 'button'
15
15
  };
@@ -22,9 +22,9 @@
22
22
  <%% end %>
23
23
  <%- if acts_as_customizable? -%>
24
24
  <hr />
25
- <%%= render partial: 'redmine_extensions/custom_field_rows', :locals => { :custom_field_values => @<%= model_name_underscored %>.visible_custom_field_values } %>
25
+ <%%= render partial: 'redmine_extensions/custom_field_rows', locals: { custom_field_values: @<%= model_name_underscored %>.visible_custom_field_values } %>
26
26
  <%- end -%>
27
- <%%= call_hook(:view_<%= model_name_pluralize_underscored %>_show_details_bottom, :<%= model_name_underscored %> => @<%= model_name_underscored %>) %>
27
+ <%%= call_hook(:view_<%= model_name_pluralize_underscored %>_show_details_bottom, :<%= model_name_underscored%>: @<%= model_name_underscored %>) %>
28
28
  </table>
29
29
  <%- if description_column? -%>
30
30
  <%% if !@<%= model_name_underscored %>.<%= description_column %>.blank? %>
@@ -38,13 +38,13 @@
38
38
  <%% end %>
39
39
  <%- end -%>
40
40
  <%- if acts_as_attachable? -%>
41
- <%% if @<%= model_name_underscored %>.attachments.any? -%>
41
+ <%% if @<%= model_name_underscored %>.attachments.any? %>
42
42
  <hr />
43
- <%%= link_to_attachments @<%= model_name_underscored %>, :thumbnails => true %>
43
+ <%%= link_to_attachments @<%= model_name_underscored %>, thumbnails: true %>
44
44
  <%% end %>
45
45
  <%- end -%>
46
46
  </div>
47
47
  <%% ### PAGE CUSTOMS ########################################################## %>
48
48
  <%% content_for :sidebar do %>
49
- <%%= render :partial => '<%= model_name_pluralize_underscored %>/sidebar' %>
50
- <%% end %>
49
+ <%%= render partial: '<%= model_name_pluralize_underscored %>/sidebar' %>
50
+ <%% end %>
@@ -2,8 +2,8 @@ var modal = $("#ajax-modal");
2
2
  modal.html("<%%= j render(template: '<%= model_name_pluralize_underscored %>/show', formats: [:html]) %>");
3
3
  showModal(modal.attr("id"));
4
4
  var closeButton = {
5
- text: "<%%=j l(:button_close) -%>",
6
- title: "<%%=j l(:button_close) -%>",
5
+ text: "<%%=j l(:button_close) %>",
6
+ title: "<%%=j l(:button_close) %>",
7
7
  click: function() {$(this).dialog('close');},
8
8
  'class': 'button'
9
9
  };
@@ -69,12 +69,12 @@ module RedmineExtensions
69
69
  end
70
70
 
71
71
  def render_edit
72
- outputs.map{ |output| output.render_edit }.join('').html_safe
72
+ outputs.map{ |output| output.render_edit }.join.html_safe
73
73
  end
74
74
 
75
75
  def render_data
76
76
  if outputs.any?
77
- outputs.map{ |output| output.render_data }.join('').html_safe
77
+ outputs.map{ |output| output.render_data }.join.html_safe
78
78
  else
79
79
  view_context.l(:label_no_output)
80
80
  end
@@ -10,7 +10,7 @@ module EasySettings
10
10
  def key(name, **options, &block)
11
11
  name = name.to_s
12
12
 
13
- if block_given?
13
+ if block
14
14
  key_dsl = EasySettings::KeyDSL.new
15
15
  key_dsl.instance_eval(&block)
16
16
  options = options.merge(key_dsl.options)
@@ -20,11 +20,13 @@ module RedmineExtensions
20
20
  config.eager_load_paths << config.root.join('app', 'models', 'easy_queries')
21
21
 
22
22
  initializer 'redmine_extensions.assets' do
23
- config.assets.precompile << 'redmine_extensions/applications.js'
24
- config.assets.precompile << 'redmine_extensions/blocking.js'
25
- unless Rails.env.production?
26
- config.assets.precompile << 'redmine_extensions/jasmine_lib/jasmine_lib.js'
27
- config.assets.precompile << 'redmine_extensions/jasmine.css'
23
+ if config.respond_to?(:assets)
24
+ config.assets.precompile << 'redmine_extensions/applications.js'
25
+ config.assets.precompile << 'redmine_extensions/blocking.js'
26
+ unless Rails.env.production?
27
+ config.assets.precompile << 'redmine_extensions/jasmine_lib/jasmine_lib.js'
28
+ config.assets.precompile << 'redmine_extensions/jasmine.css'
29
+ end
28
30
  end
29
31
  end
30
32
 
@@ -61,7 +63,7 @@ module RedmineExtensions
61
63
 
62
64
  # include helpers
63
65
  initializer 'redmine_extensions.rails_patching', before: :load_config_initializers do |app|
64
- ActiveSupport.on_load(Rails.version.start_with?('5') ? :action_controller_base : :action_controller) do
66
+ ActiveSupport.on_load(Rails::VERSION::MAJOR >= 5 ? :action_controller_base : :action_controller) do
65
67
  helper RedmineExtensions::ApplicationHelper
66
68
  # helper RedmineExtensions::EasyQueryHelper
67
69
  end
@@ -1,5 +1,5 @@
1
1
  module RedmineExtensions
2
- if Rails.version.start_with?('5')
2
+ if Rails::VERSION::MAJOR >= 5
3
3
  class Migration < ActiveRecord::Migration[4.2]
4
4
  end
5
5
  else
@@ -57,7 +57,7 @@ module RedmineExtensions
57
57
  @@patches_locations[patching_module] = const.methods(false).map{|m| const.method(m) }.first.source_location.first
58
58
  rescue
59
59
  # [0] is register_*_patch
60
- from_location = caller_locations[1]
60
+ from_location = caller_locations(2..2).first
61
61
  @@patches_locations[patching_module] = from_location.absolute_path
62
62
  end
63
63
 
@@ -78,7 +78,7 @@ module RedmineExtensions
78
78
  end
79
79
  section ||= :others
80
80
 
81
- raise ArgumentError, "EasyPatchManager->register_patch: The section (#{section}) must be one of x#{@@registered_patches.keys.join(', ')}x " unless @@registered_patches.keys.include?(section)
81
+ raise ArgumentError, "EasyPatchManager->register_patch: The section (#{section}) must be one of x#{@@registered_patches.keys.join(', ')}x " unless @@registered_patches.key?(section)
82
82
 
83
83
  original_klasses_to_patch.each do |original_klass_to_patch|
84
84
  pcollection = @@registered_patches[section].move_and_get_or_insert( original_klass_to_patch, options )
@@ -191,17 +191,13 @@ module RedmineExtensions
191
191
  # raise ArgumentError, 'Section order has to be a integer!' unless order.is_a?(Numeric)
192
192
  # @name = name
193
193
  # @order = order
194
- @patches_collections = Array.new
194
+ @patches_collections = []
195
195
  @last_order = 0
196
196
  end
197
197
 
198
198
  def each(&block)
199
199
  @patches_collections.each do |patch_collection|
200
- if block_given?
201
- block.call patch_collection
202
- else
203
- yield patch_collection
204
- end
200
+ yield patch_collection
205
201
  end
206
202
  end
207
203
 
@@ -335,11 +331,7 @@ module RedmineExtensions
335
331
  def each(&block)
336
332
 
337
333
  @patches.each do |patch|
338
- if block_given?
339
- block.call patch
340
- else
341
- yield patch
342
- end
334
+ yield patch
343
335
  end
344
336
 
345
337
  end
@@ -1,3 +1,3 @@
1
1
  module RedmineExtensions
2
- VERSION = '0.3.7'
2
+ VERSION = '0.4.0.beta'
3
3
  end
@@ -3,13 +3,13 @@ RSpec.describe 'autocomplete', type: :feature, js: true, logged: :admin do
3
3
  describe 'render' do
4
4
  it 'generate default autocomplete' do
5
5
  visit '/dummy_autocompletes'
6
- expect(page).to have_css('input#default[type="text"]')
6
+ expect(page).to have_css('input#default[type="search"]')
7
7
  expect(page).to have_css('input[type="hidden"][name="default"][value="value1"]', visible: false)
8
8
  end
9
9
 
10
10
  it 'generate autocomplete_field in form_for' do
11
11
  visit '/dummy_autocompletes'
12
- expect(page).to have_css('input#dummy_entities_autocomplete[type="text"]')
12
+ expect(page).to have_css('input#dummy_entities_autocomplete[type="search"]')
13
13
  expect(page).to have_css('input[type="hidden"][name="dummy_entity[array_of_dummies][]"][value="value1"]', visible: false)
14
14
  end
15
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Easy Software Ltd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-28 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '4.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6'
22
+ version: '6.2'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '4.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6'
32
+ version: '6.2'
33
33
  description: Redmine Extensions provide many extended functionalities for Redmine
34
34
  project.
35
35
  email:
@@ -204,14 +204,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
204
  requirements:
205
205
  - - ">="
206
206
  - !ruby/object:Gem::Version
207
- version: '2.1'
207
+ version: '2.5'
208
208
  required_rubygems_version: !ruby/object:Gem::Requirement
209
209
  requirements:
210
- - - ">="
210
+ - - ">"
211
211
  - !ruby/object:Gem::Version
212
- version: '0'
212
+ version: 1.3.1
213
213
  requirements: []
214
- rubygems_version: 3.0.4
214
+ rubygems_version: 3.0.8
215
215
  signing_key:
216
216
  specification_version: 4
217
217
  summary: Redmine Extensions is set of usefull features for Redmine. Main focus is