redmine_extensions 0.3.7 → 0.4.0.beta

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 (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