redmine_extensions 0.2.0 → 0.2.2
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/application.js +3 -1
- data/app/assets/javascripts/redmine_extensions/blocking.js +6 -0
- data/app/assets/javascripts/redmine_extensions/blocking_module.js +58 -0
- data/app/assets/javascripts/redmine_extensions/blocking_polyfill.js +59 -0
- data/app/assets/javascripts/redmine_extensions/blocking_schedule.js +125 -0
- data/app/assets/javascripts/redmine_extensions/easy_togglers.js +1 -1
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +1 -237
- data/app/controllers/easy_settings_controller.rb +5 -16
- data/app/helpers/redmine_extensions/application_helper.rb +16 -1
- data/app/models/easy_setting.rb +0 -1
- data/db/migrate/20150705172511_create_easy_settings.rb +1 -1
- data/db/migrate/20160519161300_create_entity_assignments.rb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/custom_field.rb.erb +7 -7
- data/lib/generators/redmine_extensions/entity/templates/index.api.rsb.erb +5 -5
- data/lib/generators/redmine_extensions/entity/templates/mail_added.html.erb.erb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/mail_added.text.erb.erb +2 -2
- data/lib/generators/redmine_extensions/entity/templates/mail_updated.text.erb.erb +2 -2
- data/lib/generators/redmine_extensions/entity/templates/routes.rb.erb +12 -12
- data/lib/generators/redmine_extensions/plugin/USAGE +1 -0
- data/lib/generators/redmine_extensions/plugin/plugin_generator.rb +3 -1
- data/lib/redmine_extensions.rb +2 -2
- data/lib/redmine_extensions/core_ext.rb +3 -3
- data/lib/redmine_extensions/easy_query_adapter.rb +4 -4
- data/lib/redmine_extensions/easy_settings.rb +5 -5
- data/lib/redmine_extensions/easy_settings/params_wrapper.rb +0 -1
- data/lib/redmine_extensions/engine.rb +13 -11
- data/lib/redmine_extensions/hooks.rb +19 -5
- data/lib/redmine_extensions/html_formatting.rb +3 -3
- data/lib/redmine_extensions/migration.rb +9 -0
- data/lib/redmine_extensions/patch_manager.rb +26 -4
- data/lib/redmine_extensions/rails_patches/route_set_generator_patch.rb +3 -13
- data/lib/redmine_extensions/redmine_patches/controllers/application_controller_patch.rb +7 -9
- data/lib/redmine_extensions/version.rb +1 -1
- metadata +30 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da8777314a9bae88694949647545b995d50c9309
|
4
|
+
data.tar.gz: 249040470908720afa5ea03f5b2abb6397ddc6d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ca1694b0b46c1227f68bd10ec343972463cbc10d28e7270deaf36c049fcae38d048d31956556308abb17c4afad23f1d2bd426c4c29104b31ffa55bf23531ca4
|
7
|
+
data.tar.gz: 68a7929556ee214804c81bbaa6d5ef94f8d9d088fd0ea0720cff306390363fc26f42c9366756424cd15f59a19aff245cc0ee99cdbc73f034ade563698e6a8172
|
@@ -0,0 +1,58 @@
|
|
1
|
+
(function () {
|
2
|
+
"use strict";
|
3
|
+
/**
|
4
|
+
* @type {Object.<String,Array.<Function>>}
|
5
|
+
*/
|
6
|
+
var waitingModules = {};
|
7
|
+
/**
|
8
|
+
* @type {Object<String,boolean>}
|
9
|
+
*/
|
10
|
+
var registeredModules = {};
|
11
|
+
|
12
|
+
|
13
|
+
window.EASY = window.EASY || {};
|
14
|
+
/**
|
15
|
+
* Module constructor. Execute [func] only if [moduleName] is registered
|
16
|
+
* Works also, if EASY.registerModule is called after module definition
|
17
|
+
* @param {String} moduleName
|
18
|
+
* @param {Function} func
|
19
|
+
* @param {...*} rest - parameters for [func]
|
20
|
+
*/
|
21
|
+
EASY.module = function easyModule(moduleName, func, rest) {
|
22
|
+
if (registeredModules[moduleName]) {
|
23
|
+
if (rest !== undefined) {
|
24
|
+
func.apply(window, Array.prototype.slice.call(arguments, 2));
|
25
|
+
} else {
|
26
|
+
func();
|
27
|
+
}
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
var modules = waitingModules[moduleName];
|
31
|
+
if (!modules) {
|
32
|
+
waitingModules[moduleName] = modules = [];
|
33
|
+
}
|
34
|
+
if (rest) {
|
35
|
+
var args = Array.prototype.slice.call(arguments, 2);
|
36
|
+
modules.push(function () {
|
37
|
+
func.apply(window, args);
|
38
|
+
})
|
39
|
+
} else {
|
40
|
+
modules.push(func);
|
41
|
+
}
|
42
|
+
};
|
43
|
+
/**
|
44
|
+
* Enables modules with [moduleName] name
|
45
|
+
* If any modules are in waitingModules, they are executed immediately.
|
46
|
+
* @param {String} moduleName
|
47
|
+
*/
|
48
|
+
EASY.registerModule = function registerModule(moduleName) {
|
49
|
+
registeredModules[moduleName] = true;
|
50
|
+
if (waitingModules[moduleName]) {
|
51
|
+
var modules = waitingModules[moduleName];
|
52
|
+
for (var i = 0; i < modules.length; i++) {
|
53
|
+
modules[i]();
|
54
|
+
}
|
55
|
+
delete waitingModules[moduleName];
|
56
|
+
}
|
57
|
+
};
|
58
|
+
})();
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
(function($, window, undefined) {
|
3
|
+
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
4
|
+
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
5
|
+
|
6
|
+
// requestAnimationFrame polyfill by Erik Moller
|
7
|
+
// fixes from Paul Irish and Tino Zijdel
|
8
|
+
|
9
|
+
var lastTime = 0,
|
10
|
+
running,
|
11
|
+
animate = function (elem) {
|
12
|
+
if (running) {
|
13
|
+
window.requestAnimationFrame(animate, elem);
|
14
|
+
jQuery.fx.tick();
|
15
|
+
}
|
16
|
+
},
|
17
|
+
vendors = ['ms', 'moz', 'webkit', 'o'];
|
18
|
+
|
19
|
+
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
20
|
+
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
|
21
|
+
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|
22
|
+
|| window[vendors[x]+'CancelRequestAnimationFrame'];
|
23
|
+
}
|
24
|
+
|
25
|
+
if (!window.requestAnimationFrame)
|
26
|
+
window.requestAnimationFrame = function(fn, element) {
|
27
|
+
var currTime = new Date().getTime(),
|
28
|
+
delta = currTime - lastTime,
|
29
|
+
timeToCall = Math.max(0, 16 - delta);
|
30
|
+
|
31
|
+
var id = window.setTimeout(function() {
|
32
|
+
fn(currTime + timeToCall);
|
33
|
+
},
|
34
|
+
timeToCall
|
35
|
+
);
|
36
|
+
|
37
|
+
lastTime = currTime + timeToCall;
|
38
|
+
|
39
|
+
return id;
|
40
|
+
};
|
41
|
+
|
42
|
+
if (!window.cancelAnimationFrame) {
|
43
|
+
window.cancelAnimationFrame = function(id) {
|
44
|
+
clearTimeout(id);
|
45
|
+
};
|
46
|
+
}
|
47
|
+
|
48
|
+
jQuery.fx.timer = function (timer) {
|
49
|
+
if (timer() && jQuery.timers.push(timer) && !running) {
|
50
|
+
running = true;
|
51
|
+
animate(timer.elem);
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
jQuery.fx.stop = function() {
|
56
|
+
running = false;
|
57
|
+
};
|
58
|
+
|
59
|
+
}(jQuery, this));
|
@@ -0,0 +1,125 @@
|
|
1
|
+
(function () {
|
2
|
+
"use strict";
|
3
|
+
/**
|
4
|
+
* @typedef {Function} SchedulePrerequisite
|
5
|
+
* @return {boolean}
|
6
|
+
*/
|
7
|
+
/**
|
8
|
+
* @typedef {{func:Function,[priority]:number,[pre]:SchedulePrerequisite}} ScheduleTask
|
9
|
+
*/
|
10
|
+
var lateMaxDelay = 3;
|
11
|
+
var lateDelay = lateMaxDelay;
|
12
|
+
/** @type {Array.<ScheduleTask>} */
|
13
|
+
var mainArray = [];
|
14
|
+
/** @type {Array.<ScheduleTask>} */
|
15
|
+
var lateArray = [];
|
16
|
+
/** @type {Array.<ScheduleTask|null>} */
|
17
|
+
var prerequisiteArray = [];
|
18
|
+
|
19
|
+
/** @param {ScheduleTask} a
|
20
|
+
* @param {ScheduleTask} b
|
21
|
+
*/
|
22
|
+
var sortFunction = function (a, b) {
|
23
|
+
return b.priority - a.priority;
|
24
|
+
};
|
25
|
+
|
26
|
+
var tick = function () {
|
27
|
+
var count1 = 0;
|
28
|
+
if (mainArray.length > 0) {
|
29
|
+
count1 = mainArray.length;
|
30
|
+
mainArray.sort(sortFunction);
|
31
|
+
for (var i = 0; i < mainArray.length; i++) {
|
32
|
+
mainArray[i].func();
|
33
|
+
}
|
34
|
+
mainArray = [];
|
35
|
+
lateDelay = lateMaxDelay;
|
36
|
+
}
|
37
|
+
var count2 = executePrerequisites();
|
38
|
+
var count3 = 0;
|
39
|
+
if (lateArray.length) {
|
40
|
+
if (lateDelay === 0) {
|
41
|
+
lateArray.sort(sortFunction);
|
42
|
+
// console.log(lateArray.map(function (p1) {
|
43
|
+
// return p1.priority
|
44
|
+
// }));
|
45
|
+
var limitPriority = lateArray[0].priority - 5;
|
46
|
+
for (i = 0; i < lateArray.length; i++) {
|
47
|
+
if (lateArray[i].priority <= limitPriority) break;
|
48
|
+
lateArray[i].func.call(window);
|
49
|
+
}
|
50
|
+
if (i === lateArray.length) {
|
51
|
+
count3 = lateArray.length;
|
52
|
+
lateArray = [];
|
53
|
+
lateDelay = lateMaxDelay;
|
54
|
+
} else {
|
55
|
+
lateArray = lateArray.slice(i);
|
56
|
+
count3 = i;
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
lateDelay--;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
if (EASY.schedule.out && (count1 || count2 || count3)) {
|
63
|
+
console.log("EE: " + count1 + " REQ: " + count2 + " LATE: " + count3);
|
64
|
+
}
|
65
|
+
};
|
66
|
+
var isNotNull = function (a) {
|
67
|
+
return a !== null;
|
68
|
+
};
|
69
|
+
/** @return {number} */
|
70
|
+
var executePrerequisites = function () {
|
71
|
+
if (prerequisiteArray.length === 0) return 0;
|
72
|
+
var count = 0;
|
73
|
+
for (var i = 0; i < prerequisiteArray.length; i++) {
|
74
|
+
if (prerequisiteArray[i].pre()) {
|
75
|
+
count++;
|
76
|
+
prerequisiteArray[i].func.call(window);
|
77
|
+
prerequisiteArray[i] = null;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
if (count) {
|
81
|
+
prerequisiteArray = prerequisiteArray.filter(isNotNull);
|
82
|
+
count += executePrerequisites();
|
83
|
+
}
|
84
|
+
return count;
|
85
|
+
};
|
86
|
+
|
87
|
+
var cycle = function scheduleCycle() {
|
88
|
+
tick();
|
89
|
+
window.requestAnimationFrame(cycle);
|
90
|
+
};
|
91
|
+
document.addEventListener("DOMContentLoaded", cycle);
|
92
|
+
window.EASY = window.EASY || {};
|
93
|
+
/**
|
94
|
+
*
|
95
|
+
* @type {{out: boolean, late: EASY.schedule.late, require: EASY.schedule.require, main: EASY.schedule.main}}
|
96
|
+
*/
|
97
|
+
EASY.schedule = {
|
98
|
+
out: false,
|
99
|
+
/**
|
100
|
+
* Functions, which should be executed right after "DOMContentLoaded" event
|
101
|
+
* @param {Function} func
|
102
|
+
* @param {number} [priority]
|
103
|
+
*/
|
104
|
+
main: function (func, priority) {
|
105
|
+
mainArray.push({func: func, priority: priority || 0})
|
106
|
+
},
|
107
|
+
/**
|
108
|
+
* Functions, which should wait for prerequisite fulfillment
|
109
|
+
* @param {Function} func
|
110
|
+
* @param {SchedulePrerequisite} prerequisite
|
111
|
+
*/
|
112
|
+
require: function (func, prerequisite) {
|
113
|
+
prerequisiteArray.push({func: func, pre: prerequisite})
|
114
|
+
},
|
115
|
+
/**
|
116
|
+
* Functions, which should be executed after several render loops after "DOMContentLoaded" event
|
117
|
+
* @param {Function} func
|
118
|
+
* @param {number} [priority]
|
119
|
+
*/
|
120
|
+
late: function (func, priority) {
|
121
|
+
lateArray.push({func: func, priority: priority || 0})
|
122
|
+
}
|
123
|
+
};
|
124
|
+
})();
|
125
|
+
|
@@ -31,242 +31,6 @@ REDMINE_EXTENSIONS = {
|
|
31
31
|
|
32
32
|
};
|
33
33
|
|
34
|
-
|
35
|
-
// TODO delete - it will be added to extensions
|
36
|
-
(function($, undefined) {
|
37
|
-
|
38
|
-
var plugin = 'easygrouploader';
|
39
|
-
if( $.fn[plugin] )
|
40
|
-
return;
|
41
|
-
var defaults = {
|
42
|
-
next_button_cols: 1,
|
43
|
-
load_opened: false,
|
44
|
-
load_limit: 25,
|
45
|
-
texts: {
|
46
|
-
'next': 'Next',
|
47
|
-
}
|
48
|
-
};
|
49
|
-
|
50
|
-
$.fn[plugin] = function(options, methodParams) {
|
51
|
-
$.each($(this), function(idx) {
|
52
|
-
var instance = $(this).data('plugin_' + plugin);
|
53
|
-
if (!instance) {
|
54
|
-
instance = new EasyGroupLoader(this, options);
|
55
|
-
$(this).data('plugin_' + plugin, instance);
|
56
|
-
} else if (typeof options === 'string') {
|
57
|
-
switch (options) {
|
58
|
-
case 'load_groups':
|
59
|
-
if (instance.options.load_opened)
|
60
|
-
instance.load_all_groups();
|
61
|
-
}
|
62
|
-
}
|
63
|
-
});
|
64
|
-
return $(this);
|
65
|
-
};
|
66
|
-
|
67
|
-
|
68
|
-
function EasyGroupLoader(elem, options) {
|
69
|
-
this.groupsContainer = $(elem);
|
70
|
-
this.options = $.extend({}, defaults, options);
|
71
|
-
this.loadUrl = options.loadUrl || elem.data('url');
|
72
|
-
this.callback = options.callback;
|
73
|
-
this.texts = this.options.texts;
|
74
|
-
|
75
|
-
this.init();
|
76
|
-
}
|
77
|
-
|
78
|
-
EasyGroupLoader.prototype.init = function()
|
79
|
-
{
|
80
|
-
var self = this;
|
81
|
-
this.groupsContainer.on('click', '.group .expander', function(evt) {
|
82
|
-
var $row = $(this).closest('tr.group');
|
83
|
-
var group = $row.data('group') || new Group(self, $row);
|
84
|
-
|
85
|
-
if (!group.loaded) {
|
86
|
-
if (!group.header.hasClass('group-loaded')) {
|
87
|
-
group.load();
|
88
|
-
group.toggle();
|
89
|
-
}
|
90
|
-
} else {
|
91
|
-
group.toggle();
|
92
|
-
if(typeof(self.callback) === 'function')
|
93
|
-
self.callback();
|
94
|
-
}
|
95
|
-
|
96
|
-
});
|
97
|
-
if (this.options.load_opened)
|
98
|
-
this.load_all_groups();
|
99
|
-
};
|
100
|
-
|
101
|
-
EasyGroupLoader.prototype.initInlineEdit = function()
|
102
|
-
{
|
103
|
-
$('.multieditable-container:not(.multieditable-initialized)', this.groupsContainer).each(function() {
|
104
|
-
initInlineEditForContainer(this);
|
105
|
-
});
|
106
|
-
initProjectEdit();
|
107
|
-
initEasyAutocomplete();
|
108
|
-
};
|
109
|
-
|
110
|
-
EasyGroupLoader.prototype.load_all_groups = function()
|
111
|
-
{
|
112
|
-
var group;
|
113
|
-
var self = this;
|
114
|
-
var groups_to_load = [];
|
115
|
-
var entity_count = 0;
|
116
|
-
$('.group', this.groupsContainer).not('.group-loaded').each(function() {
|
117
|
-
group = $(this).data('group') || new Group(self, $(this));
|
118
|
-
if (!group.loaded) {
|
119
|
-
groups_to_load.push(group);
|
120
|
-
entity_count += group.count;
|
121
|
-
}
|
122
|
-
if (entity_count >= self.options.load_limit) {
|
123
|
-
self.load_groups(groups_to_load);
|
124
|
-
entity_count = 0;
|
125
|
-
groups_to_load = [];
|
126
|
-
}
|
127
|
-
});
|
128
|
-
if (groups_to_load.length > 0) {
|
129
|
-
this.load_groups(groups_to_load);
|
130
|
-
}
|
131
|
-
};
|
132
|
-
|
133
|
-
EasyGroupLoader.prototype.load_groups = function(groups_to_load) {
|
134
|
-
var self = this;
|
135
|
-
var group_names = groups_to_load.map(function(group) {
|
136
|
-
return group.group_value;
|
137
|
-
});
|
138
|
-
// var url = EPExtensions.setAttrToUrl(, 'group_to_load', group_names);
|
139
|
-
$.ajax(this.loadUrl, {
|
140
|
-
method: 'GET',
|
141
|
-
data: { group_to_load: group_names },
|
142
|
-
success: function(data, textStatus, request) {
|
143
|
-
var parsed = (typeof data === 'object') ? data : $.parseJSON(data);
|
144
|
-
|
145
|
-
$.each(groups_to_load, function(idx, group) {
|
146
|
-
group.parseData(parsed[group.group_name]);
|
147
|
-
group.toggle();
|
148
|
-
});
|
149
|
-
self.initInlineEdit();
|
150
|
-
}
|
151
|
-
});
|
152
|
-
};
|
153
|
-
|
154
|
-
function Group(loader, header)
|
155
|
-
{
|
156
|
-
this.loader = loader;
|
157
|
-
this.header = header;
|
158
|
-
this.header.data('group', this);
|
159
|
-
this.group_name = this.header.data('group-name');
|
160
|
-
this.group_value = this.group_name;
|
161
|
-
if( $.isArray(this.group_name) ) {
|
162
|
-
// potencialne nebezpecne - TODO: vymyslet spravny oddelovac
|
163
|
-
this.group_name = '["' + this.group_name.join('", "') + '"]';
|
164
|
-
}
|
165
|
-
this.count = parseInt(this.header.data('entity-count'));
|
166
|
-
this.pages = this.header.data('pages') || 1;
|
167
|
-
this.loaded = this.header.hasClass('preloaded');
|
168
|
-
}
|
169
|
-
|
170
|
-
Group.prototype.toggle = function() {
|
171
|
-
EPExtensions.issuesToggleRowGroup(this.header);
|
172
|
-
};
|
173
|
-
|
174
|
-
Group.prototype.load = function() {
|
175
|
-
var $hrow = this.header;
|
176
|
-
var self = this;
|
177
|
-
|
178
|
-
if (!$hrow.hasClass('group-loaded')) {
|
179
|
-
$hrow.addClass('group-loaded');
|
180
|
-
$.ajax(this.loader.loadUrl, {
|
181
|
-
method: 'GET',
|
182
|
-
data: {
|
183
|
-
group_to_load: this.group_value
|
184
|
-
},
|
185
|
-
success: function(data, textStatus, request) {
|
186
|
-
self.parseData(data);
|
187
|
-
self.loader.initInlineEdit();
|
188
|
-
if(typeof(self.loader.callback) === 'function')
|
189
|
-
self.loader.callback();
|
190
|
-
}
|
191
|
-
});
|
192
|
-
}
|
193
|
-
};
|
194
|
-
|
195
|
-
Group.prototype.parseData = function(data) {
|
196
|
-
var $hrow = this.header;
|
197
|
-
|
198
|
-
this.rows = $(data);
|
199
|
-
$hrow.after(this.rows);
|
200
|
-
$hrow.data('group-page', 1);
|
201
|
-
this.loaded = true;
|
202
|
-
if (this.pages > 1) {
|
203
|
-
this.createNextButton();
|
204
|
-
// .find doesn't work on this set
|
205
|
-
this.rows.filter("tr:last").after(this.next_button);
|
206
|
-
}
|
207
|
-
};
|
208
|
-
|
209
|
-
Group.prototype.loadNext = function() {
|
210
|
-
var $hrow = this.header;
|
211
|
-
var page = $hrow.data('group-page') + 1;
|
212
|
-
var self = this;
|
213
|
-
|
214
|
-
if (page <= this.pages) {
|
215
|
-
$.ajax(this.loader.loadUrl, {
|
216
|
-
method: 'GET',
|
217
|
-
data: {
|
218
|
-
page: page,
|
219
|
-
group_to_load: this.group_value
|
220
|
-
},
|
221
|
-
success: function(data, textStatus, request) {
|
222
|
-
self.next_button.before(data);
|
223
|
-
|
224
|
-
self.loader.initInlineEdit();
|
225
|
-
$hrow.data('group-page', page);
|
226
|
-
if (self.pages === page) {
|
227
|
-
self.next_button.remove();
|
228
|
-
}
|
229
|
-
}
|
230
|
-
});
|
231
|
-
}
|
232
|
-
};
|
233
|
-
|
234
|
-
Group.prototype.createNextButton = function() {
|
235
|
-
//var next_link_url = EPExtensions.setAttrToUrl(this.loader.loadUrl, 'group_to_load', this.group_value);
|
236
|
-
var next_link_url = this.loader.loadUrl + ( this.loader.loadUrl.indexOf('?') >= 0 ? '&' : '?' ) + $.param({group_to_load: this.group_value});
|
237
|
-
this.next_link = $('<a>', {href: next_link_url, 'class': 'button'}).text(this.loader.texts['next']).append($("<i>", {"class": "icon-arrow"}));
|
238
|
-
this.next_button = $('<tr/>', {'class': 'easy-next-button'}).html($('<td>', {colspan: this.loader.options.next_button_cols, "class": "text-center"}).html(this.next_link));
|
239
|
-
|
240
|
-
var self = this;
|
241
|
-
|
242
|
-
this.next_link.click(function(evt) {
|
243
|
-
evt.preventDefault();
|
244
|
-
self.loadNext();
|
245
|
-
});
|
246
|
-
};
|
247
|
-
|
248
|
-
})(jQuery);
|
249
|
-
|
250
|
-
window.cancelAnimFrame = ( function() {
|
251
|
-
return window.cancelAnimationFrame ||
|
252
|
-
window.webkitCancelRequestAnimationFrame ||
|
253
|
-
window.mozCancelRequestAnimationFrame ||
|
254
|
-
window.oCancelRequestAnimationFrame ||
|
255
|
-
window.msCancelRequestAnimationFrame ||
|
256
|
-
clearTimeout;
|
257
|
-
} )();
|
258
|
-
|
259
|
-
window.requestAnimFrame = (function(){
|
260
|
-
return window.requestAnimationFrame ||
|
261
|
-
window.webkitRequestAnimationFrame ||
|
262
|
-
window.mozRequestAnimationFrame ||
|
263
|
-
window.oRequestAnimationFrame ||
|
264
|
-
window.msRequestAnimationFrame ||
|
265
|
-
function(callback){
|
266
|
-
return window.setTimeout(callback, 1000 / 60);
|
267
|
-
};
|
268
|
-
})();
|
269
|
-
|
270
34
|
window.showFlashMessage = (function(type, message, delay){
|
271
35
|
var $content = $("#content");
|
272
36
|
$content.find(".flash").remove();
|
@@ -291,7 +55,7 @@ window.showFlashMessage = (function(type, message, delay){
|
|
291
55
|
var $element = $(element);
|
292
56
|
if(delay){
|
293
57
|
setTimeout(function(){
|
294
|
-
|
58
|
+
window.requestAnimationFrame(function(){
|
295
59
|
closeFlashMessage($element);
|
296
60
|
});
|
297
61
|
}, delay);
|
@@ -3,20 +3,9 @@
|
|
3
3
|
#
|
4
4
|
class EasySettingsController < ApplicationController
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def new
|
11
|
-
end
|
12
|
-
|
13
|
-
def create
|
14
|
-
if @easy_settings.save
|
15
|
-
redirect_to :back
|
16
|
-
else
|
17
|
-
render :new
|
18
|
-
end
|
19
|
-
end
|
6
|
+
before_action :require_admin, only: [:edit, :update]
|
7
|
+
before_action :find_optional_project
|
8
|
+
before_action :find_plugin, only: [:edit, :update]
|
20
9
|
|
21
10
|
def edit
|
22
11
|
@settings = Setting.send("plugin_#{@plugin.id}")
|
@@ -25,11 +14,11 @@ class EasySettingsController < ApplicationController
|
|
25
14
|
|
26
15
|
def update
|
27
16
|
if params[:settings]
|
28
|
-
Setting.send("plugin_#{@plugin.id}=", params[:settings])
|
17
|
+
Setting.send("plugin_#{@plugin.id}=", params[:settings].permit!)
|
29
18
|
end
|
30
19
|
|
31
20
|
if params[:easy_setting]
|
32
|
-
@easy_settings = EasySettings::ParamsWrapper.from_params(params[:easy_setting]
|
21
|
+
@easy_settings = EasySettings::ParamsWrapper.from_params(params[:easy_setting].permit!, project: @project, prefix: @plugin.id)
|
33
22
|
|
34
23
|
if @easy_settings.save
|
35
24
|
# All good
|
@@ -108,6 +108,21 @@ module RedmineExtensions
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
+
def late_javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
|
112
|
+
content =
|
113
|
+
if block_given?
|
114
|
+
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
115
|
+
capture(&block)
|
116
|
+
else
|
117
|
+
content_or_options_with_block
|
118
|
+
end
|
119
|
+
html_options.reverse_merge!({type:'application/javascript'})
|
120
|
+
priority = html_options.delete(:priority) || 0
|
121
|
+
content = " EASY.schedule.late(function(){#{content} }, #{priority});"
|
122
|
+
|
123
|
+
content_tag(:script, javascript_cdata_section(content), html_options)
|
124
|
+
end
|
125
|
+
|
111
126
|
|
112
127
|
# ==== Options
|
113
128
|
# * <tt>class: Hash or String</tt> - This option can be used to add custom CSS classes. It can be *String* or *Hash*.
|
@@ -240,7 +255,7 @@ module RedmineExtensions
|
|
240
255
|
|
241
256
|
content_tag(:span, :class => 'easy-multiselect-tag-container') do
|
242
257
|
text_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
|
243
|
-
|
258
|
+
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} });")
|
244
259
|
end
|
245
260
|
end
|
246
261
|
|
data/app/models/easy_setting.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
class <%= model_name %>CustomField < CustomField
|
2
|
-
|
3
|
-
def type_name
|
4
|
-
:label_<%= @model_name_pluralize_underscored %>
|
5
|
-
end
|
6
|
-
|
7
|
-
end
|
1
|
+
class <%= model_name %>CustomField < CustomField
|
2
|
+
|
3
|
+
def type_name
|
4
|
+
:label_<%= @model_name_pluralize_underscored %>
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
api.array :<%= model_name_pluralize_underscored %>, api_meta(total_count: @entity_count, offset: @offset, limit: @limit) do
|
2
|
-
@entities.each do |<%= model_name_underscored %>|
|
3
|
-
render_api_<%= model_name_underscored %>(api, <%= model_name_underscored %>)
|
4
|
-
end
|
5
|
-
end
|
1
|
+
api.array :<%= model_name_pluralize_underscored %>, api_meta(total_count: @entity_count, offset: @offset, limit: @limit) do
|
2
|
+
@entities.each do |<%= model_name_underscored %>|
|
3
|
+
render_api_<%= model_name_underscored %>(api, <%= model_name_underscored %>)
|
4
|
+
end
|
5
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
<h1><%%= link_to(@<%= model_name_underscored %>.to_s, @<%= model_name_underscored %>_url) %></h1>
|
1
|
+
<h1><%%= link_to(@<%= model_name_underscored %>.to_s, @<%= model_name_underscored %>_url) %></h1>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<%%= @<%= model_name_underscored %>.to_s %>
|
2
|
-
<%%= @<%= model_name_underscored %>_url %>
|
1
|
+
<%%= @<%= model_name_underscored %>.to_s %>
|
2
|
+
<%%= @<%= model_name_underscored %>_url %>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<%%= @<%= model_name_underscored %>.to_s %>
|
2
|
-
<%%= @<%= model_name_underscored %>_url %>
|
1
|
+
<%%= @<%= model_name_underscored %>.to_s %>
|
2
|
+
<%%= @<%= model_name_underscored %>_url %>
|
@@ -1,13 +1,13 @@
|
|
1
|
-
<% if project? %>
|
2
|
-
resources :projects do
|
3
|
-
resources :<%= model_name_pluralize_underscored %>
|
4
|
-
end
|
5
|
-
<% end %>
|
6
|
-
resources :<%= model_name_pluralize_underscored %> do
|
7
|
-
collection do
|
8
|
-
get 'autocomplete'
|
9
|
-
get 'bulk_edit'
|
10
|
-
post 'bulk_update'
|
11
|
-
get 'context_menu'
|
12
|
-
end
|
1
|
+
<% if project? %>
|
2
|
+
resources :projects do
|
3
|
+
resources :<%= model_name_pluralize_underscored %>
|
4
|
+
end
|
5
|
+
<% end %>
|
6
|
+
resources :<%= model_name_pluralize_underscored %> do
|
7
|
+
collection do
|
8
|
+
get 'autocomplete'
|
9
|
+
get 'bulk_edit'
|
10
|
+
post 'bulk_update'
|
11
|
+
get 'context_menu'
|
12
|
+
end
|
13
13
|
end
|
@@ -2,6 +2,7 @@ Description:
|
|
2
2
|
The plugin generator creates stubs for new Redmine plugin.
|
3
3
|
Plugin is prepared for use in Redmine and Easy Redmine as well.
|
4
4
|
You can use --customer flag to generate a special plugin if you can make just a few changes to code. Backup this plugin before Redmine or Easy Redmine upgrade and move back for keep you changes.
|
5
|
+
You can use --path flag to specify parent directory.
|
5
6
|
|
6
7
|
Example:
|
7
8
|
rails g redmine_extensions:plugin NameOfNewPlugin
|
@@ -5,13 +5,15 @@ module RedmineExtensions
|
|
5
5
|
attr_reader :plugin_path, :plugin_name_underscored, :plugin_pretty_name, :plugin_title
|
6
6
|
|
7
7
|
class_option :customer, type: :boolean, default: false, banner: '', :desc => 'plugin will act as customer modification. It is useful for changing few things and be uptodate with the core.'
|
8
|
+
class_option :path, type: :string, default: nil, banner: '', :desc => 'relative path to parent directory for plugin.'
|
8
9
|
|
9
10
|
def initialize(*args)
|
10
11
|
super
|
11
12
|
|
12
13
|
@plugin_name_underscored = options[:customer] ? "modification_#{file_name.underscore}" : file_name.underscore
|
13
14
|
@plugin_pretty_name = plugin_name_underscored.titleize
|
14
|
-
|
15
|
+
|
16
|
+
@plugin_path = (options[:path] || "plugins") + "/#{plugin_name_underscored}"
|
15
17
|
@plugin_title = @plugin_name_underscored.camelize
|
16
18
|
end
|
17
19
|
|
data/lib/redmine_extensions.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative "./redmine_extensions/engine"
|
2
|
+
require_relative './redmine_extensions/core_ext'
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative './core_ext/object'
|
2
|
+
require_relative './core_ext/string'
|
3
|
+
require_relative './core_ext/date_range'
|
@@ -3,8 +3,8 @@ require 'query'
|
|
3
3
|
module RedmineExtensions
|
4
4
|
module QueryColumnAdapter
|
5
5
|
def self.included(base)
|
6
|
-
base.extend
|
7
|
-
base.
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.include InstanceMethods
|
8
8
|
|
9
9
|
base.class_eval do
|
10
10
|
attr_accessor :includes
|
@@ -168,8 +168,8 @@ end
|
|
168
168
|
if Redmine::Plugin.installed?(:easy_extensions)
|
169
169
|
# EasyQuery exist
|
170
170
|
else
|
171
|
-
QueryColumn.
|
171
|
+
QueryColumn.include RedmineExtensions::QueryColumnAdapter
|
172
172
|
RedmineExtensions::PatchManager.register_model_patch('Query', 'RedmineExtensions::QueryAdapter')
|
173
173
|
EasyQuery = EasyQueryAdapter
|
174
|
-
EasyQuery.
|
174
|
+
EasyQuery.prepend RedmineExtensions::QueryAdapterDefaults
|
175
175
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module EasySettings
|
2
2
|
end
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
require_relative './easy_settings/key'
|
5
|
+
require_relative './easy_settings/key_dsl'
|
6
|
+
require_relative './easy_settings/mapper'
|
7
|
+
require_relative './easy_settings/form_model'
|
8
|
+
require_relative './easy_settings/params_wrapper'
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'active_support/dependencies'
|
2
|
-
|
3
|
-
|
2
|
+
require_relative './patch_manager'
|
3
|
+
require_relative './redmine_patches/patches'
|
4
4
|
|
5
|
-
|
5
|
+
require_relative './query_output'
|
6
6
|
|
7
7
|
module RedmineExtensions
|
8
8
|
class Engine < ::Rails::Engine
|
@@ -16,18 +16,20 @@ module RedmineExtensions
|
|
16
16
|
|
17
17
|
config.autoload_paths << config.root.join('lib')
|
18
18
|
config.eager_load_paths << config.root.join('app', 'models', 'easy_queries')
|
19
|
+
config.assets.precompile << 'redmine_extensions/applications.js'
|
20
|
+
config.assets.precompile << 'redmine_extensions/blocking.js'
|
19
21
|
|
20
22
|
#config.to_prepare goes after Reloader.to_prepare
|
21
|
-
|
23
|
+
RedmineExtensions::Reloader.to_prepare do
|
22
24
|
RedmineExtensions::QueryOutput.register_output RedmineExtensions::QueryOutputs::ListOutput
|
23
25
|
RedmineExtensions::QueryOutput.register_output RedmineExtensions::QueryOutputs::TilesOutput
|
24
26
|
# RedmineExtensions::BasePresenter.register 'RedmineExtensions::EasyQueryPresenter', 'EasyQuery'
|
25
27
|
# ApplicationController.send :include, RedmineExtensions::RailsPatches::ControllerQueryHelpers
|
26
|
-
ApplicationController.
|
28
|
+
ApplicationController.include RedmineExtensions::RenderingHelper
|
27
29
|
end
|
28
30
|
|
29
31
|
initializer 'redmine_extensions.initialize' do |app|
|
30
|
-
ActionDispatch::Routing::RouteSet::Generator.
|
32
|
+
ActionDispatch::Routing::RouteSet::Generator.prepend RedmineExtensions::RailsPatches::RouteSetGeneratorPatch
|
31
33
|
end
|
32
34
|
|
33
35
|
initializer 'redmine_extensions.append_migrations' do |app|
|
@@ -58,23 +60,23 @@ module RedmineExtensions
|
|
58
60
|
include RedmineExtensions::RailsPatches::ActiveRecord
|
59
61
|
end
|
60
62
|
ActiveSupport.on_load(:action_view) do
|
61
|
-
default_form_builder.
|
63
|
+
default_form_builder.include RedmineExtensions::RailsPatches::FormBuilderPatch
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
67
|
initializer 'redmine_extensions.initialize_easy_plugins', after: :load_config_initializers do
|
66
|
-
|
68
|
+
require_relative './hooks'
|
67
69
|
|
68
70
|
unless Redmine::Plugin.installed?(:easy_extensions)
|
69
71
|
ActiveSupport.run_load_hooks(:easyproject, self)
|
70
72
|
end
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
+
require_relative './easy_query_adapter'
|
75
|
+
require_relative './easy_entity_formatters/easy_entity_formatter'
|
74
76
|
end
|
75
77
|
|
76
78
|
# initializer :add_html_formatting do |app|
|
77
|
-
#
|
79
|
+
# require_relative "./html_formatting"
|
78
80
|
# Redmine::WikiFormatting.register(:HTML, RedmineExtensions::HTMLFormatting::Formatter, RedmineExtensions::HTMLFormatting::Helper)
|
79
81
|
# end
|
80
82
|
|
@@ -1,16 +1,30 @@
|
|
1
1
|
module RedmineExtensions
|
2
2
|
class Hooks < Redmine::Hook::ViewListener
|
3
|
+
@visited = false
|
4
|
+
def easy_extensions_blocking_javascripts_hook(context={})
|
5
|
+
if defined?(EasyExtensions)
|
6
|
+
@visited = true
|
7
|
+
context[:template].require_asset('redmine_extensions/blocking')
|
8
|
+
end
|
9
|
+
end
|
3
10
|
|
4
|
-
def
|
11
|
+
def easy_extensions_javascripts_hook(context={})
|
5
12
|
if defined?(EasyExtensions)
|
6
|
-
context[:
|
7
|
-
|
13
|
+
context[:template].require_asset('redmine_extensions/blocking') unless @visited
|
14
|
+
context[:template].require_asset('redmine_extensions/application')
|
15
|
+
# context[:hook_caller].javascript_include_tag('redmine_extensions/application')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_layouts_base_html_head(context={})
|
20
|
+
unless defined?(EasyExtensions)
|
21
|
+
javascript_include_tag('redmine_extensions/blocking_polyfill') +
|
22
|
+
javascript_include_tag('redmine_extensions/blocking_schedule') +
|
23
|
+
javascript_include_tag('redmine_extensions/blocking_module') +
|
8
24
|
javascript_include_tag('redmine_extensions/jquery.entityarray') +
|
9
25
|
javascript_include_tag('redmine_extensions/redmine_extensions') +
|
10
26
|
javascript_include_tag('redmine_extensions/easy_togglers')
|
11
27
|
end
|
12
|
-
|
13
28
|
end
|
14
|
-
|
15
29
|
end
|
16
30
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative './html_formatting/internals'
|
2
|
+
require_relative './html_formatting/formatter'
|
3
|
+
require_relative './html_formatting/helper'
|
@@ -116,8 +116,8 @@ module RedmineExtensions
|
|
116
116
|
controller_klass = controller_klass_name.constantize
|
117
117
|
|
118
118
|
@registered_easy_page_helpers.each do |helper_klass_name|
|
119
|
-
if
|
120
|
-
helper_klass_symbol =
|
119
|
+
if helper_klass_name.end_with?('Helper')
|
120
|
+
helper_klass_symbol = helper_klass_name[0, helper_klass_name.index('Helper')]
|
121
121
|
end
|
122
122
|
|
123
123
|
controller_klass.class_eval "helper :#{helper_klass_symbol.underscore}" if helper_klass_symbol
|
@@ -352,18 +352,40 @@ module RedmineExtensions
|
|
352
352
|
pm_klass = patching_module.constantize
|
353
353
|
oktp_klass = original_klass_to_patch.constantize
|
354
354
|
|
355
|
-
|
355
|
+
if @options[:prepend]
|
356
|
+
oktp_klass.prepend pm_klass # unless oktp_klass.include?(pm_klass)
|
357
|
+
else
|
358
|
+
oktp_klass.include pm_klass # unless oktp_klass.include?(pm_klass)
|
359
|
+
end
|
356
360
|
end
|
357
361
|
|
358
362
|
end
|
359
363
|
|
360
364
|
end
|
365
|
+
|
366
|
+
module Reloader
|
367
|
+
def self.to_prepare(*args, &block)
|
368
|
+
if defined? ActiveSupport::Reloader
|
369
|
+
ActiveSupport::Reloader.to_prepare(*args, &block)
|
370
|
+
else
|
371
|
+
ActionDispatch::Reloader.to_prepare(*args, &block)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def self.to_cleanup(*args, &block)
|
376
|
+
if defined? ActiveSupport::Reloader
|
377
|
+
ActiveSupport::Reloader.to_complete(*args, &block)
|
378
|
+
else
|
379
|
+
ActionDispatch::Reloader.to_cleanup(*args, &block)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
361
383
|
end
|
362
384
|
|
363
385
|
ActiveSupport.on_load(:easyproject, yield: true) do
|
364
386
|
RedmineExtensions::PatchManager.apply_persisting_patches
|
365
387
|
end
|
366
388
|
|
367
|
-
|
389
|
+
RedmineExtensions::Reloader.to_prepare do
|
368
390
|
RedmineExtensions::PatchManager.apply_reloadable_patches
|
369
391
|
end
|
@@ -1,20 +1,10 @@
|
|
1
1
|
module RedmineExtensions
|
2
2
|
module RailsPatches
|
3
3
|
module RouteSetGeneratorPatch
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
base.class_eval do
|
8
|
-
def use_relative_controller_with_redmine_extensions!
|
9
|
-
return if current_controller && current_controller.start_with?('redmine_extensions')
|
10
|
-
use_relative_controller_without_redmine_extensions!
|
11
|
-
end
|
12
|
-
|
13
|
-
alias_method_chain :use_relative_controller!, :redmine_extensions
|
14
|
-
end
|
15
|
-
|
4
|
+
def use_relative_controller!
|
5
|
+
return if current_controller && current_controller.start_with?('redmine_extensions')
|
6
|
+
super
|
16
7
|
end
|
17
|
-
|
18
8
|
end
|
19
9
|
end
|
20
10
|
end
|
@@ -2,8 +2,8 @@ module RedmineExtensions
|
|
2
2
|
module ApplicationControllerPatch
|
3
3
|
|
4
4
|
def self.included(base)
|
5
|
-
base.extend
|
6
|
-
base.
|
5
|
+
base.extend ClassMethods
|
6
|
+
base.include InstanceMethods
|
7
7
|
|
8
8
|
base.class_eval do
|
9
9
|
helper_method :easy_extensions?
|
@@ -29,13 +29,11 @@ module RedmineExtensions
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
32
|
+
def save_easy_settings(project = nil)
|
33
|
+
wrapper = EasySettings::ParamsWrapper.from_params(params.require(:easy_setting).permit!, project: project)
|
34
|
+
wrapper.save
|
35
|
+
wrapper
|
36
|
+
end
|
39
37
|
|
40
38
|
end
|
41
39
|
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redmine_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
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: 2017-
|
11
|
+
date: 2017-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '4.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: actionpack
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '4.2'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '6'
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
39
48
|
- !ruby/object:Gem::Version
|
40
49
|
version: '4.2'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '6'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: sqlite3
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +145,10 @@ files:
|
|
133
145
|
- LICENSE
|
134
146
|
- Rakefile
|
135
147
|
- app/assets/javascripts/redmine_extensions/application.js
|
148
|
+
- app/assets/javascripts/redmine_extensions/blocking.js
|
149
|
+
- app/assets/javascripts/redmine_extensions/blocking_module.js
|
150
|
+
- app/assets/javascripts/redmine_extensions/blocking_polyfill.js
|
151
|
+
- app/assets/javascripts/redmine_extensions/blocking_schedule.js
|
136
152
|
- app/assets/javascripts/redmine_extensions/easy_togglers.js
|
137
153
|
- app/assets/javascripts/redmine_extensions/jquery.entityarray.js
|
138
154
|
- app/assets/javascripts/redmine_extensions/redmine_extensions.js
|
@@ -231,6 +247,7 @@ files:
|
|
231
247
|
- lib/redmine_extensions/html_formatting/formatter.rb
|
232
248
|
- lib/redmine_extensions/html_formatting/helper.rb
|
233
249
|
- lib/redmine_extensions/html_formatting/internals.rb
|
250
|
+
- lib/redmine_extensions/migration.rb
|
234
251
|
- lib/redmine_extensions/patch_manager.rb
|
235
252
|
- lib/redmine_extensions/query_output.rb
|
236
253
|
- lib/redmine_extensions/query_outputs/list_output.rb
|
@@ -276,22 +293,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
293
|
version: '0'
|
277
294
|
requirements: []
|
278
295
|
rubyforge_project:
|
279
|
-
rubygems_version: 2.
|
296
|
+
rubygems_version: 2.6.7
|
280
297
|
signing_key:
|
281
298
|
specification_version: 4
|
282
299
|
summary: Redmine Extensions is set of usefull features for Redmine. Main focus is
|
283
300
|
on development helpers, but many users can find it helpfull
|
284
301
|
test_files:
|
285
|
-
- spec/
|
286
|
-
- spec/factories/time_entries.rb
|
302
|
+
- spec/factories/easy_queries.rb
|
287
303
|
- spec/factories/easy_settings.rb
|
288
304
|
- spec/factories/issues.rb
|
289
305
|
- spec/factories/projects.rb
|
306
|
+
- spec/factories/time_entries.rb
|
290
307
|
- spec/factories/trackers.rb
|
291
|
-
- spec/factories/easy_queries.rb
|
292
308
|
- spec/factories/users.rb
|
309
|
+
- spec/features/autocomplete_spec.rb
|
310
|
+
- spec/models/easy_setting_spec.rb
|
293
311
|
- spec/presenters/redmine_extensions/easy_setting_presenter_spec.rb
|
294
|
-
- spec/
|
312
|
+
- spec/rails_helper.rb
|
295
313
|
- spec/spec_helper.rb
|
296
|
-
- spec/
|
297
|
-
- spec/features/autocomplete_spec.rb
|
314
|
+
- spec/support/plugin_generator.rb
|