redmine_extensions 0.0.39 → 0.1.01
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +30 -59
- data/app/controllers/easy_settings_controller.rb +1 -1
- data/app/helpers/redmine_extensions/application_helper.rb +108 -65
- data/app/helpers/redmine_extensions/rendering_helper.rb +5 -0
- data/app/presenters/easy_query_adapter_presenter.rb +50 -0
- data/app/views/common/_collapsible_module_layout.html.erb +13 -0
- data/app/views/easy_entity_assignments/_assignments_container.html.erb +10 -15
- data/app/views/easy_entity_assignments/_query_index.html.erb +2 -10
- data/app/views/easy_queries/_easy_query_tile.html.erb +7 -0
- data/app/views/easy_settings/edit.html.erb +1 -1
- data/config/routes.rb +3 -7
- data/lib/generators/redmine_extensions/entity/templates/_form.html.erb.erb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/_sidebar.html.erb.erb +8 -8
- data/lib/generators/redmine_extensions/entity/templates/context_menu.html.erb.erb +7 -7
- data/lib/generators/redmine_extensions/entity/templates/custom_field.rb.erb +7 -7
- data/lib/generators/redmine_extensions/entity/templates/edit.html.erb.erb +16 -16
- data/lib/generators/redmine_extensions/entity/templates/index.api.rsb.erb +5 -5
- data/lib/generators/redmine_extensions/entity/templates/index.html.erb.erb +4 -4
- 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/migration.rb.erb +9 -9
- data/lib/generators/redmine_extensions/entity/templates/new.html.erb.erb +16 -16
- data/lib/generators/redmine_extensions/entity/templates/query.rb.erb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/routes.rb.erb +12 -12
- data/lib/generators/redmine_extensions/entity/templates/show.html.erb.erb +37 -37
- data/lib/redmine_extensions/easy_query_adapter.rb +107 -88
- data/lib/redmine_extensions/easy_query_helpers/outputs.rb +69 -0
- data/lib/redmine_extensions/engine.rb +11 -1
- data/lib/redmine_extensions/query_output.rb +41 -25
- data/lib/redmine_extensions/query_outputs/list_output.rb +14 -0
- data/lib/redmine_extensions/query_outputs/tile_output.rb +19 -0
- data/lib/redmine_extensions/redmine_patches/patches.rb +2 -3
- data/lib/redmine_extensions/version.rb +1 -1
- data/spec/redmine/bin/about +0 -0
- data/spec/redmine/bin/bundle +0 -0
- data/spec/redmine/bin/rails +0 -0
- data/spec/redmine/bin/rake +0 -0
- data/spec/redmine/extra/svn/reposman.rb +0 -0
- data/spec/redmine/public/dispatch.fcgi.example +0 -0
- data/spec/redmine/script/about +0 -0
- data/spec/redmine/script/rails +0 -0
- metadata +1978 -1972
- data/lib/redmine_extensions/query_outputs/table_output.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03e7f631e32d5cbbce9cfd94ab32c76a0e3fb93a
|
4
|
+
data.tar.gz: 5454a96009a0928de22a9c918f487468154f154e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9851babf744466f612e6ac074e5bfb27980e27c33dc8cae48c5d3c7c99793bfdd2f19a9f593b8f994f9518475aa3f4aff49138b1052f7c96a5471d081a7d3f60
|
7
|
+
data.tar.gz: 119f3556b21232044b91a4fb05bcc3f0f7b7d3b08df9c4fd61b18edde70ca13c760091818791066a63539218a5b942f250920d05136a5298713e530be21e460b
|
@@ -340,8 +340,6 @@ window.closeFlashMessage = (function($element){
|
|
340
340
|
this._initData(this.options.source);
|
341
341
|
} else if ( this.options.preload && this.options.load_immediately) {
|
342
342
|
this.load();
|
343
|
-
} else if ( this.selectedValues ) {
|
344
|
-
this.setValue( this.selectedValues );
|
345
343
|
}
|
346
344
|
},
|
347
345
|
|
@@ -389,7 +387,7 @@ window.closeFlashMessage = (function($element){
|
|
389
387
|
select.append(option);
|
390
388
|
});
|
391
389
|
$container = $elem.closest('.easy-multiselect-tag-container');
|
392
|
-
$container.
|
390
|
+
$container.children(':input').prop('disabled', true);
|
393
391
|
$container.children().hide();
|
394
392
|
$container.append(select);
|
395
393
|
that.valueElement = select;
|
@@ -409,7 +407,7 @@ window.closeFlashMessage = (function($element){
|
|
409
407
|
that.load(function(){
|
410
408
|
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
|
411
409
|
response($.grep(that.possibleValues, function(val, i) {
|
412
|
-
return ( !request.term || matcher.test(val.value)
|
410
|
+
return ( !that.options.multiple || !request.term || matcher.test(val.value));
|
413
411
|
}));
|
414
412
|
}, function(){
|
415
413
|
response();
|
@@ -482,16 +480,16 @@ window.closeFlashMessage = (function($element){
|
|
482
480
|
_formatData: function(data) {
|
483
481
|
return $.map(data, function(elem, i){
|
484
482
|
var id, value;
|
485
|
-
if (elem
|
486
|
-
|
487
|
-
|
488
|
-
} else if (elem instanceof Object) {
|
489
|
-
value = elem.value;
|
490
|
-
id = elem.id;
|
483
|
+
if( $.isArray(elem) ) {
|
484
|
+
value = elem[0];
|
485
|
+
id = elem[1];
|
491
486
|
} else {
|
492
|
-
|
493
|
-
|
494
|
-
|
487
|
+
id = value = elem;
|
488
|
+
}
|
489
|
+
if ( elem !== null && typeof elem === 'object' )
|
490
|
+
return elem;
|
491
|
+
else
|
492
|
+
return {value: value, id: id};
|
495
493
|
});
|
496
494
|
},
|
497
495
|
|
@@ -544,7 +542,6 @@ window.closeFlashMessage = (function($element){
|
|
544
542
|
name: value.value
|
545
543
|
});
|
546
544
|
this.element.trigger('change');
|
547
|
-
this.element.val('');
|
548
545
|
} else {
|
549
546
|
this.element.val(value.value);
|
550
547
|
this.valueElement.val(value.id);
|
@@ -554,7 +551,7 @@ window.closeFlashMessage = (function($element){
|
|
554
551
|
|
555
552
|
setValue: function(values) {
|
556
553
|
var that = this;
|
557
|
-
if( typeof values
|
554
|
+
if( typeof values == 'undefined' || !values )
|
558
555
|
return false;
|
559
556
|
|
560
557
|
if( this.options.preload ) {
|
@@ -562,63 +559,37 @@ window.closeFlashMessage = (function($element){
|
|
562
559
|
if( that.options.multiple ) {
|
563
560
|
that.valueElement.entityArray('clear');
|
564
561
|
}
|
565
|
-
that._setValues(values)
|
562
|
+
that._setValues(values)
|
566
563
|
});
|
567
564
|
} else {
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
that._setValues(values);
|
565
|
+
// TODO - where to get real text value?
|
566
|
+
this.element.val(values[0]);
|
567
|
+
this.valueElement.val(values[0]);
|
572
568
|
}
|
573
569
|
},
|
574
570
|
|
575
571
|
_setValues: function(values) {
|
576
|
-
var
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
if( values[i] instanceof Object && !Array.isArray(values[i]) && values[i] !== null ) {
|
585
|
-
selected.push( values[i] );
|
586
|
-
} else if( this.options.preload && Array.isArray(this.possibleValues) ) {
|
587
|
-
for(var j = this.possibleValues.length - 1; j >= 0; j-- ) {
|
588
|
-
if ( values[i] == this.possibleValues[j].id || values[i] == this.possibleValues[j].id.toString() ) {
|
589
|
-
selected.push(this.possibleValues[j]);
|
590
|
-
break;
|
591
|
-
}
|
572
|
+
var that = this;
|
573
|
+
$.each(that.possibleValues, function(i, val) {
|
574
|
+
if ( values.indexOf(val.id) > -1 || (values.indexOf(val.id.toString()) > -1)) {
|
575
|
+
if(that.options.multiple) {
|
576
|
+
that.valueElement.entityArray('add', { id: val.id, name: val.value });
|
577
|
+
} else {
|
578
|
+
that.element.val(val.value);
|
579
|
+
that.valueElement.val(val.id);
|
592
580
|
}
|
593
|
-
} else {
|
594
|
-
selected.push( {id: values[i], value: values[i]} );
|
595
|
-
}
|
596
|
-
}
|
597
|
-
for (var i = selected.length - 1; i >= 0; i--) {
|
598
|
-
if(this.options.multiple) {
|
599
|
-
this.valueElement.entityArray('add', { id: selected[i].id, name: selected[i].value });
|
600
|
-
} else {
|
601
|
-
this.element.val(selected[i].value);
|
602
|
-
this.valueElement.val(selected[i].id);
|
603
581
|
}
|
604
|
-
}
|
582
|
+
});
|
605
583
|
},
|
606
584
|
|
607
|
-
getValue: function(
|
608
|
-
|
609
|
-
|
610
|
-
result = this.valueElement.entityArray('getValue'); // entityArray
|
585
|
+
getValue: function() {
|
586
|
+
if( this.options.multiple && !this.expanded ) {
|
587
|
+
return this.valueElement.entityArray('getValue'); // entityArray
|
611
588
|
} else if ( this.options.multiple ) {
|
612
|
-
|
589
|
+
return this.valueElement.val(); //select multiple=true
|
613
590
|
} else {
|
614
|
-
|
615
|
-
}
|
616
|
-
if( with_label ) {
|
617
|
-
result = this.possibleValues.filter(function(el) {
|
618
|
-
return result.indexOf( el.id ) >= 0;
|
619
|
-
});
|
591
|
+
return [this.valueElement.val()]; // hidden field
|
620
592
|
}
|
621
|
-
return result;
|
622
593
|
}
|
623
594
|
|
624
595
|
});
|
@@ -25,7 +25,7 @@ class EasySettingsController < ApplicationController
|
|
25
25
|
Setting.send "plugin_#{@plugin.id}=", params[:settings] if params[:settings]
|
26
26
|
if @easy_settings.save
|
27
27
|
flash[:notice] = l(:notice_successful_update)
|
28
|
-
redirect_back_or_default edit_easy_setting_path(@easy_settings)
|
28
|
+
redirect_back_or_default redmine_extensions_engine.edit_easy_setting_path(@easy_settings)
|
29
29
|
else
|
30
30
|
render :edit
|
31
31
|
end
|
@@ -6,7 +6,7 @@ module RedmineExtensions
|
|
6
6
|
|
7
7
|
def plugin_settings_path(plugin, *attrs)
|
8
8
|
if plugin.is_a?(Redmine::Plugin) && (plugin.settings[:only_easy] || plugin.settings[:easy_settings])
|
9
|
-
edit_easy_setting_path(plugin, *attrs)
|
9
|
+
redmine_extensions_engine.edit_easy_setting_path(plugin, *attrs)
|
10
10
|
else
|
11
11
|
super
|
12
12
|
end
|
@@ -44,20 +44,21 @@ module RedmineExtensions
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
def query_for_entity(entity_class)
|
48
|
+
entity_class_name = entity_class.name
|
49
|
+
query_class = "Easy#{entity_class_name}Query".constantize rescue nil
|
50
|
+
return query_class if query_class && query_class < EasyQuery
|
51
|
+
query_class ||= "#{entity_class_name}Query".constantize rescue nil
|
52
|
+
end
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
def render_entity_assignments(entity, target_entity, options = {}, &block)
|
55
|
+
options ||= {}
|
56
|
+
collection_name = options.delete(:collection_name) || target_entity.name.pluralize.underscore
|
57
|
+
query_class = query_for_entity(target_entity)
|
56
58
|
|
57
|
-
|
58
|
-
end
|
59
|
+
return '' if !query_class || !entity.respond_to?(collection_name)
|
59
60
|
|
60
|
-
|
61
|
+
project = options.delete(:project)
|
61
62
|
|
62
63
|
query = query_class.new(:name => 'c_query')
|
63
64
|
query.project = project
|
@@ -68,9 +69,8 @@ module RedmineExtensions
|
|
68
69
|
|
69
70
|
entities_count = entities.size
|
70
71
|
options[:entities_count] = entities_count
|
71
|
-
|
72
72
|
options[:module_name] ||= "entity_#{entity.class.name.underscore}_#{entity.id}_#{collection_name}"
|
73
|
-
options[:heading] ||= l("label_#{
|
73
|
+
options[:heading] ||= l("label_#{query.entity}_plural", :default => 'Heading')
|
74
74
|
|
75
75
|
if options[:context_menus_path].nil?
|
76
76
|
options[:context_menus_path] = [
|
@@ -82,9 +82,11 @@ module RedmineExtensions
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
query.output = options[:display_style] || (entities_count > 3 ? 'list' : 'tile')
|
86
|
+
|
85
87
|
render(:partial => 'easy_entity_assignments/assignments_container', :locals => {
|
86
88
|
:entity => entity,
|
87
|
-
:query => query, :
|
89
|
+
:query => query, :project => project,
|
88
90
|
:entities => entities, :entities_count => entities_count, :options => options})
|
89
91
|
end
|
90
92
|
|
@@ -106,65 +108,106 @@ module RedmineExtensions
|
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
109
|
-
# options:
|
110
|
-
# => options[:heading] = text beside of plus button
|
111
|
-
# => options[:container_html] = a hash of html attributes
|
112
|
-
# => options[:default_button_state] = (true => expanded -), (false => collapsed +)
|
113
|
-
# => options[:ajax_call] = make ajax call for saving state (true => ajax call, false => no call, no save)
|
114
|
-
# => options[:wrapping_heading_element] = html element outside heading => h3, h4
|
115
|
-
def render_toggler(container_uniq_id, user = nil, options={}, &block)
|
116
|
-
user ||= User.current
|
117
|
-
options[:heading] ||= ''
|
118
|
-
options[:heading_links] ||= []
|
119
|
-
options[:heading_links] = [options[:heading_links]] if options[:heading_links] && !options[:heading_links].is_a?(Array)
|
120
|
-
options[:container_html] ||= {}
|
121
|
-
options[:default_button_state] = false #if is_mobile_device?
|
122
|
-
options[:default_button_state] = true if options[:default_button_state].nil?
|
123
|
-
options[:ajax_call] = true if options[:ajax_call].nil?
|
124
|
-
|
125
|
-
s = ''
|
126
|
-
if !options.key?(:no_heading_button)
|
127
|
-
options[:heading] << content_tag(:div, options[:heading_links].join(' ').html_safe, :class => 'module-heading-links') unless options[:heading_links].blank?
|
128
|
-
s << render_toggler_header(user, options[:heading].html_safe, container_uniq_id, options)
|
129
|
-
end
|
130
|
-
|
131
|
-
if options[:ajax_call] == false
|
132
|
-
expanded = options[:default_button_state]
|
133
|
-
else
|
134
|
-
expanded = true
|
135
|
-
end
|
136
111
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
112
|
+
# ==== Options
|
113
|
+
# * <tt>class: Hash or String</tt> - This option can be used to add custom CSS classes. It can be *String* or *Hash*.
|
114
|
+
# class: {heading: 'heading-additional-css', container: 'container-additional-css'}
|
115
|
+
# * <tt>heading_tag: name of HTML element of module heading</tt> - By default its its *h3*
|
116
|
+
# ** Aliases for this options are: wrapping_heading_element, header_tag
|
117
|
+
# * <tt>toggle: false</tt> - This disable toggle function (collapsible and remember)
|
118
|
+
# ** Aliases for this options are: collapsible, no_expander
|
119
|
+
# * <tt>remember: false</tt> - This disable remember function of toggle conatiner
|
120
|
+
# ** Aliases for this options are: ajax_call
|
121
|
+
#
|
122
|
+
def render_module_easy_box(id, heading, options = {}, &block) # with fallback to old
|
123
|
+
options[:toggle] = true unless options.key?(:toggle)
|
124
|
+
options[:remember] = options.delete(:ajax_call) if options.key?(:ajax_call)
|
125
|
+
options[:collapsible] = !options.delete(:no_expander) if options.key?(:no_expander)
|
126
|
+
|
127
|
+
renderer = EasyBoxRenderer.new(self, id, heading, options)
|
128
|
+
renderer.content = capture {yield renderer}
|
129
|
+
|
130
|
+
renderer.render
|
142
131
|
end
|
143
132
|
|
144
|
-
|
145
|
-
expander_options = options[:expander_options] || {}
|
146
|
-
wrapping_heading_element = options[:wrapping_heading_element] || 'h3'
|
147
|
-
wrapping_heading_element_classes = (options[:wrapping_heading_element_classes] || '') + ' module-heading'
|
148
|
-
wrapping_heading_element_styles = options[:wrapping_heading_element_styles]
|
149
|
-
ajax_call = options.delete(:ajax_call) ? 'true' : 'false'
|
133
|
+
EasyBoxRenderer = Struct.new(:view, :id, :heading, :options) do
|
150
134
|
|
151
|
-
|
135
|
+
attr_writer :container_class, :heading_class, :content_class
|
136
|
+
attr_writer :heading_links, :footer, :icon
|
137
|
+
attr_accessor :content
|
152
138
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
139
|
+
def container_class
|
140
|
+
s = (@container_class.presence || css_classes[:container]).to_s
|
141
|
+
s << ' collapsible' if collapsible?
|
142
|
+
s << ' collapsed' if collapsed?
|
143
|
+
|
144
|
+
s
|
145
|
+
end
|
146
|
+
|
147
|
+
def saving_state_enabled?
|
148
|
+
collapsible? && (options[:remember].nil? || !!options[:remember])
|
149
|
+
end
|
150
|
+
|
151
|
+
def heading_tag
|
152
|
+
(options[:wrapping_heading_element] || (options[:header_tag] || options[:heading_tag])).presence || 'h3'
|
153
|
+
end
|
154
|
+
|
155
|
+
def heading_class
|
156
|
+
(@heading_class || css_classes[:heading]).to_s
|
157
|
+
end
|
158
|
+
|
159
|
+
def icon
|
160
|
+
@icon ||= options[:icon] && " icon #{options[:icon]}"
|
161
|
+
end
|
162
|
+
|
163
|
+
def heading_links
|
164
|
+
if block_given?
|
165
|
+
@heading_links = view.capture { yield }
|
166
|
+
else
|
167
|
+
@heading_links.to_s.html_safe
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def collapsible?
|
172
|
+
return @collapsible unless @collapsible.nil?
|
173
|
+
@collapsible ||= !!options[:toggle] && (options[:collapsible].nil? || !!options[:collapsible])
|
174
|
+
end
|
175
|
+
|
176
|
+
def collapsed?
|
177
|
+
!!options[:default] || !!options[:collapsed] || !!options[:default_button_state]
|
178
|
+
end
|
179
|
+
|
180
|
+
def footer
|
181
|
+
if block_given?
|
182
|
+
@footer = view.capture { yield }
|
183
|
+
else
|
184
|
+
@footer.to_s.html_safe
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def render
|
189
|
+
view.render({partial: 'common/collapsible_module_layout', locals: {renderer: self, content: content}} )
|
190
|
+
end
|
191
|
+
private
|
192
|
+
|
193
|
+
def css_classes
|
194
|
+
return @css_classes if @css_classes
|
195
|
+
if (css_class = options.delete(:class)).is_a?(Hash)
|
196
|
+
@css_classes = css_class
|
197
|
+
else
|
198
|
+
@css_classes = {
|
199
|
+
container: css_class,
|
200
|
+
heading: css_class,
|
201
|
+
content: css_class
|
202
|
+
}
|
203
|
+
end
|
161
204
|
end
|
162
205
|
|
163
|
-
html.html_safe
|
164
206
|
end
|
165
207
|
|
208
|
+
|
166
209
|
def autocomplete_field_tag(name, jsonpath_or_array, selected_values, options = {})
|
167
|
-
options.reverse_merge!({select_first_value: false, show_toggle_button: false, load_immediately: false
|
210
|
+
options.reverse_merge!({select_first_value: false, show_toggle_button: false, load_immediately: false})
|
168
211
|
options[:id] ||= sanitize_to_id(name)
|
169
212
|
|
170
213
|
selected_values ||= []
|
@@ -177,7 +220,7 @@ module RedmineExtensions
|
|
177
220
|
|
178
221
|
content_tag(:span, :class => 'easy-multiselect-tag-container') do
|
179
222
|
text_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
|
180
|
-
javascript_tag("$('##{options[:id]}').easymultiselect({multiple:
|
223
|
+
javascript_tag("$('##{options[:id]}').easymultiselect({multiple: true, rootElement: #{options[:rootElement]}, inputName: '#{name}', preload: true, source: #{source}, selected: #{selected_values.to_json}, show_toggle_button: #{options[:show_toggle_button]}, select_first_value: #{options[:select_first_value]}, load_immediately: #{options[:load_immediately]}, autocomplete_options: #{(options[:jquery_auto_complete_options]||{}).to_json} });")
|
181
224
|
end
|
182
225
|
end
|
183
226
|
|
@@ -20,5 +20,10 @@ module RedmineExtensions
|
|
20
20
|
partial.prepend("#{prefixes.last}/")
|
21
21
|
render(*attrs)
|
22
22
|
end
|
23
|
+
|
24
|
+
def query_outputs(presenter_or_query, options={})
|
25
|
+
presenter = present(presenter_or_query, options) rescue RedmineExtensions::BasePresenter.new(presenter_or_query, self, options)
|
26
|
+
RedmineExtensions::EasyQueryHelpers::Outputs.new(presenter, self)
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class EasyQueryAdapterPresenter < RedmineExtensions::BasePresenter
|
2
|
+
|
3
|
+
# --- GETTERS ---
|
4
|
+
attr_accessor :page_module, :row_limit
|
5
|
+
|
6
|
+
# should be defined in parent in future
|
7
|
+
def initialize(query, view_context=nil, options={})
|
8
|
+
super(query, view_context, options)
|
9
|
+
@query = query
|
10
|
+
|
11
|
+
@page_module = options[:page_module]
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def entities(options={})
|
16
|
+
#can not fetch, cuz gantt is fetching enstead of nil
|
17
|
+
@entities ||= @options[:entities] || h.instance_variable_get(:@entities) #|| model.entities(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def entity_count(options={})
|
21
|
+
@entity_count ||= h.instance_variable_get(:@entity_count) || model.entity_count(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def entity_pages
|
25
|
+
@options[:entity_pages] || h.instance_variable_get(:@entity_pages)
|
26
|
+
end
|
27
|
+
|
28
|
+
def available_outputs
|
29
|
+
outputs.available_outputs
|
30
|
+
end
|
31
|
+
|
32
|
+
def outputs
|
33
|
+
@outputs ||= RedmineExtensions::EasyQueryHelpers::Outputs.new(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
# ----- RENDERING HELPERS ----
|
37
|
+
|
38
|
+
def default_name
|
39
|
+
h.l(self.class.name.underscore, :scope => [:easy_query, :name])
|
40
|
+
end
|
41
|
+
|
42
|
+
def name
|
43
|
+
@name ||= options[:easy_query_name] || (model.new_record? ? default_name : model.name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def filters_active?
|
47
|
+
model.filters.any?
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="module box <%= renderer.container_class %>"<%=raw renderer.collapsible? && %Q{ data-toggle="#{renderer.id}"} || nil %>>
|
2
|
+
<%= content_tag(:div, class: 'module-heading ' + renderer.heading_class, onclick: (renderer.saving_state_enabled? && 'EasyToggler.toggle(this.nextElementSibling, event)' || nil)) do %>
|
3
|
+
<span class="expander module-toggler"> </span>
|
4
|
+
<%= content_tag(renderer.heading_tag, renderer.heading, class: renderer.icon) %>
|
5
|
+
<%= content_tag(:span, renderer.heading_links, class: 'module-heading-links') if renderer.heading_links %>
|
6
|
+
<% end %>
|
7
|
+
<div class="module-content" id="<%= renderer.id %>"<%=raw renderer.collapsed? && %q{ style="display:none"} || nil %>>
|
8
|
+
<%= content -%>
|
9
|
+
<%= content_tag(:div, class: 'module-content-footer') do %>
|
10
|
+
<%= renderer.footer %>
|
11
|
+
<% end if renderer.footer.present? %>
|
12
|
+
</div>
|
13
|
+
</div>
|
@@ -1,24 +1,20 @@
|
|
1
1
|
<%
|
2
|
-
|
3
|
-
heading = "#{options[:heading]} (#{entities_count})"
|
2
|
+
heading = "#{options[:heading]} (#{entities_count})"
|
4
3
|
%>
|
5
4
|
<% if entities_count > 0 %>
|
6
|
-
<div id="<%= options[:module_name] %>_container" class="entity_references_container easy-dropper-target easy-drop-issue
|
7
|
-
<%= call_hook(:view_easy_entity_assignemnt_top, :entity => entity, :query => query, :entities => entities, :options => options
|
8
|
-
<div class="box">
|
5
|
+
<div id="<%= options[:module_name] %>_container" class="entity_references_container easy-dropper-target easy-drop-issue" data-drop-action="<%= entity.class.name.underscore %>" data-entity-id="<%= entity.id %>" data-issue-show="1">
|
6
|
+
<%= call_hook(:view_easy_entity_assignemnt_top, :entity => entity, :query => query, :entities => entities, :options => options) %>
|
9
7
|
<%# entity_cards_params = {:module_name => options[:module_name], :project_id => project, :source_entity_type => entity.class.name, :source_entity_id => entity, :referenced_entity_type => referenced_entity_type, :referenced_collection_name => options[:referenced_collection_name]}.merge!(query.to_params) %>
|
10
8
|
<% entity_cards_params = {} %>
|
11
|
-
<%=
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
<%= render_module_easy_box(options[:module_name], heading+':', {class: {heading: entity_css_icon(query.entity), container: 'module-inside'}, default: false}) do |m| %>
|
10
|
+
<% m.heading_links do %>
|
11
|
+
<%= link_to('', {}, :class => 'icon-slab', :remote => true, :data => {:display => 'slab'}, :title => l(:title_easy_card_display_changer_tile)) %>
|
12
|
+
<%= link_to('', {}, :class => 'icon-bullet-list', :remote => true, :data => {:display => 'list'}, :title => l(:title_easy_card_display_changer_list)) %>
|
13
|
+
<% end %>
|
18
14
|
<%= render(:partial => 'easy_entity_assignments/query_index', :locals => {
|
19
15
|
:entity => entity,
|
20
|
-
:query => query,
|
21
|
-
:project => project, :options => options, :
|
16
|
+
:query => query,
|
17
|
+
:project => project, :options => options, :referenced_entities => entities}) %>
|
22
18
|
|
23
19
|
|
24
20
|
<% if options[:context_menus_path] && respond_to?(options[:context_menus_path]) %>
|
@@ -26,5 +22,4 @@
|
|
26
22
|
<% end %>
|
27
23
|
<% end %>
|
28
24
|
</div>
|
29
|
-
</div>
|
30
25
|
<% end %>
|
@@ -1,11 +1,3 @@
|
|
1
|
-
<%
|
2
|
-
<%=
|
3
|
-
<% elsif display_style == :tile %>
|
4
|
-
<div class="easy-entity-cards-container">
|
5
|
-
<div class="splitcontent">
|
6
|
-
<% entities.each do |referenced_entity| %>
|
7
|
-
<%# render_easy_entity_card(referenced_entity, entity, options.merge(:referenced_entities => referenced_entities)) %>
|
8
|
-
<% end %>
|
9
|
-
</div>
|
10
|
-
</div>
|
1
|
+
<% query_outputs(query, entities: referenced_entities, options: { hascontextmenu: true, disable_sort: true }).each do |output| %>
|
2
|
+
<%= output.render_data %>
|
11
3
|
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= form_for(@easy_settings, html: { class: 'form-box easy-setting-plugin-form' }) do |f| %>
|
1
|
+
<%= form_for([redmine_extensions_engine, @easy_settings], html: { class: 'form-box easy-setting-plugin-form' }) do |f| %>
|
2
2
|
<%= hidden_field_tag :back_url, params[:back_url] %>
|
3
3
|
|
4
4
|
<%= render "easy_settings/#{@easy_settings.plugin.id}", easy_settings: @easy_settings, settings: @settings, form: f %>
|
data/config/routes.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
# Engine routes
|
2
1
|
RedmineExtensions::Engine.routes.draw do
|
3
|
-
resources :easy_settings, except: :destroy
|
4
|
-
end
|
5
|
-
|
6
|
-
# Redmine routes
|
7
|
-
Rails.application.routes.draw do
|
8
|
-
mount RedmineExtensions::Engine => '/redmine_extensions'
|
9
2
|
|
10
3
|
resources :easy_settings, except: :destroy
|
4
|
+
|
11
5
|
end
|
6
|
+
|
7
|
+
RedmineExtensions::Engine.automount!
|
@@ -1,9 +1,9 @@
|
|
1
|
-
<ul>
|
2
|
-
<%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
|
3
|
-
<li><%%= link_to l(:button_edit), edit_polymorphic_path([@project, @<%= model_name_underscored %>]), title: l(:button_edit), class: 'icon icon-edit' %></li>
|
4
|
-
<%% end %>
|
5
|
-
<%% if @<%= model_name_underscored %>.nil? %>
|
6
|
-
<li><%%= link_to l(:button_<%= model_name_underscored %>_new), new_polymorphic_path([@project, :<%= model_name_underscored %>]), title: l(:title_<%= model_name_underscored %>_new), class: 'icon icon-add button button-positive' %></li>
|
7
|
-
<%% end %>
|
8
|
-
<li><%%= link_to l(:label_<%= model_name_pluralize_underscored %>), polymorphic_path([@project, :<%= model_name_pluralize_underscored %>], set_filter: '1'), title: l(:label_<%= model_name_pluralize_underscored %>), class: 'icon icon-folder button' %></li>
|
1
|
+
<ul>
|
2
|
+
<%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
|
3
|
+
<li><%%= link_to l(:button_edit), edit_polymorphic_path([@project, @<%= model_name_underscored %>]), title: l(:button_edit), class: 'icon icon-edit' %></li>
|
4
|
+
<%% end %>
|
5
|
+
<%% if @<%= model_name_underscored %>.nil? %>
|
6
|
+
<li><%%= link_to l(:button_<%= model_name_underscored %>_new), new_polymorphic_path([@project, :<%= model_name_underscored %>]), title: l(:title_<%= model_name_underscored %>_new), class: 'icon icon-add button button-positive' %></li>
|
7
|
+
<%% end %>
|
8
|
+
<li><%%= link_to l(:label_<%= model_name_pluralize_underscored %>), polymorphic_path([@project, :<%= model_name_pluralize_underscored %>], set_filter: '1'), title: l(:label_<%= model_name_pluralize_underscored %>), class: 'icon icon-folder button' %></li>
|
9
9
|
</ul>
|
@@ -1,8 +1,8 @@
|
|
1
|
-
<ul>
|
2
|
-
<%% if @<%= model_name_underscored %> -%>
|
3
|
-
<li><%%= context_menu_link l(:button_edit), edit_<%= model_name_underscored %>_path(@<%= model_name_underscored %>), class: 'icon icon-edit', disabled: !@can[:edit] %></li>
|
4
|
-
<%% end %>
|
5
|
-
<li><%%= context_menu_link l(:button_delete), <%= model_name_pluralize_underscored %>_path(ids: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: {confirm: l(:text_are_you_sure)}, class: 'icon icon-del', disabled: !@can[:delete] %></li>
|
6
|
-
|
7
|
-
<%%= call_hook(:view_<%= model_name_pluralize_underscored %>_context_menu_end, {<%= model_name_underscored %>: @<%= model_name_underscored %>, <%= model_name_pluralize_underscored %>: @<%= model_name_pluralize_underscored %>, can: @can, back: @back, project: @project}) %>
|
1
|
+
<ul>
|
2
|
+
<%% if @<%= model_name_underscored %> -%>
|
3
|
+
<li><%%= context_menu_link l(:button_edit), edit_<%= model_name_underscored %>_path(@<%= model_name_underscored %>), class: 'icon icon-edit', disabled: !@can[:edit] %></li>
|
4
|
+
<%% end %>
|
5
|
+
<li><%%= context_menu_link l(:button_delete), <%= model_name_pluralize_underscored %>_path(ids: @<%= model_name_underscored %>_ids, back_url: @back), method: :delete, data: {confirm: l(:text_are_you_sure)}, class: 'icon icon-del', disabled: !@can[:delete] %></li>
|
6
|
+
|
7
|
+
<%%= call_hook(:view_<%= model_name_pluralize_underscored %>_context_menu_end, {<%= model_name_underscored %>: @<%= model_name_underscored %>, <%= model_name_pluralize_underscored %>: @<%= model_name_pluralize_underscored %>, can: @can, back: @back, project: @project}) %>
|
8
8
|
</ul>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
class <%= model_name %>CustomField < CustomField
|
2
|
-
|
3
|
-
def type_name
|
4
|
-
:label_<%= @model_name_pluralize_underscored %>
|
5
|
-
end
|
6
|
-
|
7
|
-
end
|
1
|
+
class <%= model_name %>CustomField < CustomField
|
2
|
+
|
3
|
+
def type_name
|
4
|
+
:label_<%= @model_name_pluralize_underscored %>
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|