redmine_extensions 0.3.9 → 0.4.1
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/redmine_extensions/blocking_namespace.js +3 -1
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +10 -33
- data/app/helpers/redmine_extensions/application_helper.rb +23 -9
- data/app/models/easy_setting.rb +1 -1
- data/app/presenters/redmine_extensions/easy_setting_presenter.rb +1 -1
- data/lib/generators/redmine_extensions/entity/entity_generator.rb +2 -2
- data/lib/redmine_extensions/easy_query_helpers/outputs.rb +2 -2
- data/lib/redmine_extensions/easy_settings/key.rb +1 -1
- data/lib/redmine_extensions/easy_settings/mapper.rb +3 -3
- data/lib/redmine_extensions/engine.rb +1 -1
- data/lib/redmine_extensions/migration.rb +1 -1
- data/lib/redmine_extensions/patch_manager.rb +5 -13
- data/lib/redmine_extensions/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5473a3520201d93aaa40645dfdc8bd03536e93286e8d7a5bccc08cf0fbc8006
|
4
|
+
data.tar.gz: cd979b19e9ea1e35a274d45ba6f2fa09ade3f15cf1e31d2743ac210249e4a873
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aa3d665971ad245e8f415bab96c438341309d7c3cd4a14c1a0a81e52c13bd5b9581d66983b8efa9d7a071201ca2945611350d83a322eb80fb36fbe082ac800b
|
7
|
+
data.tar.gz: 970f4328576c02b5193d61fd661ffe6ad21a01c54f07a539e8fde5e762a25ee8e6d98e1843019dea18769672fe353051aa42699e53df17639960b8aced0b0251
|
@@ -1,3 +1,5 @@
|
|
1
1
|
window.EASY = window.EASY || {};
|
2
2
|
window.EasyGem = window.EasyGem || {};
|
3
|
-
window.EasyGem.test = window.EasyGem.test || {};
|
3
|
+
window.EasyGem.test = window.EasyGem.test || {};
|
4
|
+
window.EASY.asyncModules = window.EASY.asyncModules || {};
|
5
|
+
window.EASY.asyncModules.states = window.EASY.asyncModules.states || {};
|
@@ -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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
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.
|
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
|
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
|
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
|
@@ -123,6 +123,22 @@ module RedmineExtensions
|
|
123
123
|
content_tag(:script, javascript_cdata_section(content), html_options)
|
124
124
|
end
|
125
125
|
|
126
|
+
def require_javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
|
127
|
+
content =
|
128
|
+
if block_given?
|
129
|
+
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
130
|
+
capture(&block)
|
131
|
+
else
|
132
|
+
content_or_options_with_block
|
133
|
+
end
|
134
|
+
html_options.reverse_merge!(type: 'application/javascript')
|
135
|
+
html_options[:data] ||= { container: '' }
|
136
|
+
html_options[:data][:container].slice!("#module_inside_")
|
137
|
+
content = "EasyGem.schedule.require(function(){#{content}}, function(){ return EASY.asyncModules.states['#{html_options[:data][:container]}']});"
|
138
|
+
|
139
|
+
javascript_tag content.html_safe, html_options
|
140
|
+
end
|
141
|
+
|
126
142
|
def get_jasmine_tags
|
127
143
|
tags = params[:jasmine]
|
128
144
|
return [] if tags == 'true'
|
@@ -183,8 +199,8 @@ module RedmineExtensions
|
|
183
199
|
|
184
200
|
def container_class
|
185
201
|
s = (@container_class.presence || css_classes[:container]).to_s
|
186
|
-
s
|
187
|
-
s
|
202
|
+
s += ' collapsible' if collapsible?
|
203
|
+
s += ' collapsed' if collapsed?
|
188
204
|
|
189
205
|
s
|
190
206
|
end
|
@@ -264,7 +280,6 @@ module RedmineExtensions
|
|
264
280
|
# * +load_immediately+ - tells if values should be loaded immediatelly after page loaded, or wait for first use of the field.
|
265
281
|
# Warning! if this option is false, selected values passed in first format will be ignored till it is loaded.
|
266
282
|
# 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
283
|
# * +select_first_value+ - if selectd_values are empty, with this option first available value will be selected.
|
269
284
|
# Available only with <tt>preload: true</tt> option.
|
270
285
|
# 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 +287,7 @@ module RedmineExtensions
|
|
272
287
|
# * +rootElement+ - Has sence only if jsonpath is used for available values. It tells if the json response has values wrapped under root element.
|
273
288
|
# For response like <tt>{projects: [[<name>, <id>], [<name2>, <id2>]]}</tt> user option <tt>rootElement: 'projects'</tt>
|
274
289
|
def autocomplete_field_tag(name, jsonpath_or_array, selected_values, options = {})
|
275
|
-
options.reverse_merge!({select_first_value: false,
|
290
|
+
options.reverse_merge!({select_first_value: false, load_immediately: false, preload: true, multiple: true, combo: false})
|
276
291
|
options[:id] ||= sanitize_to_id(name)
|
277
292
|
|
278
293
|
selected_values ||= []
|
@@ -285,7 +300,7 @@ module RedmineExtensions
|
|
285
300
|
|
286
301
|
content_tag(:span, :class => 'easy-multiselect-tag-container') do
|
287
302
|
search_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},
|
303
|
+
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
304
|
end
|
290
305
|
end
|
291
306
|
|
@@ -297,13 +312,12 @@ module RedmineExtensions
|
|
297
312
|
# HTML options can be passed as a hash with +html_options+. These options will be passed to the input element.
|
298
313
|
#
|
299
314
|
# ==== Examples
|
300
|
-
# autocomplete_field(:issue, :tag_ids, Tag.all.pluck(:name, :id), multiple: true
|
315
|
+
# autocomplete_field(:issue, :tag_ids, Tag.all.pluck(:name, :id), multiple: true)
|
301
316
|
# # => <span class="easy-multiselect-tag-container"> \
|
302
317
|
# <input type="text" id="issue_tags" /> \
|
303
318
|
# <button type="button" tabindex="-1" class="..." role="button" ...>
|
304
319
|
# <span class="ui-button-icon-primary ui-icon ui-icon-triangle-1-s"></span><span class="ui-button-text"> </span>
|
305
320
|
# </button>
|
306
|
-
# <a class="icon icon-add clear-link"></a> # toggle button to the multiselect tag from show_toggle_button option
|
307
321
|
# ...(wraping service tags)
|
308
322
|
# <input type="hidden" name="issue[tag_ids][]" value="#{@issue.tag_ids.first}" />
|
309
323
|
# <input type="hidden" name="issue[tag_ids][]" value="#{@issue.tag_ids.second}" />
|
data/app/models/easy_setting.rb
CHANGED
@@ -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].
|
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.
|
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.
|
397
|
+
'description' if text_columns.key?('description')
|
398
398
|
text_columns.keys.first
|
399
399
|
end
|
400
400
|
|
@@ -69,12 +69,12 @@ module RedmineExtensions
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def render_edit
|
72
|
-
outputs.map{ |output| output.render_edit }.join
|
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
|
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,20 +10,20 @@ module EasySettings
|
|
10
10
|
def key(name, **options, &block)
|
11
11
|
name = name.to_s
|
12
12
|
|
13
|
-
if
|
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)
|
17
17
|
end
|
18
18
|
|
19
19
|
EasySetting.mapper_clear_caches
|
20
|
-
@all_keys[name] = EasySettings::Key.init(name, options)
|
20
|
+
@all_keys[name] = EasySettings::Key.init(name, **options)
|
21
21
|
end
|
22
22
|
alias_method :add_key, :key
|
23
23
|
|
24
24
|
def keys(*names, **options, &block)
|
25
25
|
names.each do |name|
|
26
|
-
key(name, options, &block)
|
26
|
+
key(name, **options, &block)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
alias_method :add_keys, :keys
|
@@ -63,7 +63,7 @@ module RedmineExtensions
|
|
63
63
|
|
64
64
|
# include helpers
|
65
65
|
initializer 'redmine_extensions.rails_patching', before: :load_config_initializers do |app|
|
66
|
-
ActiveSupport.on_load(Rails
|
66
|
+
ActiveSupport.on_load(Rails::VERSION::MAJOR >= 5 ? :action_controller_base : :action_controller) do
|
67
67
|
helper RedmineExtensions::ApplicationHelper
|
68
68
|
# helper RedmineExtensions::EasyQueryHelper
|
69
69
|
end
|
@@ -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
|
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.
|
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 =
|
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
|
-
|
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
|
-
|
339
|
-
block.call patch
|
340
|
-
else
|
341
|
-
yield patch
|
342
|
-
end
|
334
|
+
yield patch
|
343
335
|
end
|
344
336
|
|
345
337
|
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.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Easy Software Ltd
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-03 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:
|
@@ -196,7 +196,7 @@ homepage: https://www.easyredmine.com
|
|
196
196
|
licenses:
|
197
197
|
- GPL-2.0
|
198
198
|
metadata: {}
|
199
|
-
post_install_message:
|
199
|
+
post_install_message:
|
200
200
|
rdoc_options: []
|
201
201
|
require_paths:
|
202
202
|
- lib
|
@@ -204,15 +204,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
204
|
requirements:
|
205
205
|
- - ">="
|
206
206
|
- !ruby/object:Gem::Version
|
207
|
-
version: '2.
|
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
212
|
version: '0'
|
213
213
|
requirements: []
|
214
|
-
rubygems_version: 3.0.
|
215
|
-
signing_key:
|
214
|
+
rubygems_version: 3.0.8
|
215
|
+
signing_key:
|
216
216
|
specification_version: 4
|
217
217
|
summary: Redmine Extensions is set of usefull features for Redmine. Main focus is
|
218
218
|
on development helpers, but many users can find it helpfull
|