redmine_extensions 0.4.4 → 0.5.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/README.md +47 -0
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +1 -0
- data/app/helpers/redmine_extensions/application_helper.rb +9 -6
- data/app/views/common/_collapsible_module_layout.html.erb +20 -2
- data/app/views/redmine_extensions/_jasmine.html.erb +3 -1
- data/lib/generators/redmine_extensions/entity/templates/_sidebar.html.erb.erb +1 -1
- data/lib/redmine_extensions/engine.rb +9 -19
- data/lib/redmine_extensions/patch_manager.rb +43 -43
- data/lib/redmine_extensions/version.rb +3 -1
- metadata +9 -24
- data/lib/redmine_extensions/html_formatting/formatter.rb +0 -86
- data/lib/redmine_extensions/html_formatting/helper.rb +0 -73
- data/lib/redmine_extensions/html_formatting/internals.rb +0 -23
- data/lib/redmine_extensions/html_formatting.rb +0 -3
- data/spec/features/autocomplete_spec.rb +0 -17
- data/spec/features/jasmine_spec.rb +0 -9
- data/spec/support/plugin_generator.rb +0 -111
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f546239fc57393520a159c44ce22ff11a15065869488f1e65aafb8890d3f0ac
|
4
|
+
data.tar.gz: 8b1c89f27696a4013e95d9f6f1bf6ba87035af404bc78b3d323b27c94e508c3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d74ef572956e79c8c1ebb38d5db34ee3f812b52879b351fa10fd8e7126f7bac4b71caaa2b44f19e0f8fdc3c47a24f8bbfd6e39e022d2b68aa631c51a96f55c14
|
7
|
+
data.tar.gz: 57e51045f7038976950067078965bfc1a5c0bef1a0c1391150af94c8ef4fd9388f895417e120b41248078331de5bf12a44e7c49a456a0dd293efb8185e8432e9
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Redmine Extensions
|
2
|
+
|
3
|
+
[](https://git.easy.cz/redmine/redmine_extensions_gem/-/commits/master)
|
4
|
+
|
5
|
+
[](https://git.easy.cz/redmine/redmine_extensions_gem/-/releases)
|
6
|
+
|
7
|
+
[](http://badge.fury.io/rb/redmine_extensions)
|
8
|
+
|
9
|
+
This gem provides an extended funcionality for a Redmine project
|
10
|
+
|
11
|
+
## Provided funcionalities
|
12
|
+
* EasySetting - per project settings
|
13
|
+
* Redmine Plugin Generator
|
14
|
+
* Redmine Entity Generator
|
15
|
+
|
16
|
+
## Redmine Plugin Generator
|
17
|
+
|
18
|
+
Description:
|
19
|
+
The plugin generator creates stubs for a new Redmine plugin.
|
20
|
+
Plugin is prepared for use in Redmine and Easy Redmine as well.
|
21
|
+
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.
|
22
|
+
|
23
|
+
Example:
|
24
|
+
rails g redmine_extensions:plugin NameOfNewPlugin
|
25
|
+
create plugins/name_of_new_plugin/app/controllers
|
26
|
+
...
|
27
|
+
|
28
|
+
Help:
|
29
|
+
rails g redmine_extensions:plugin --help
|
30
|
+
|
31
|
+
|
32
|
+
## Redmine Entity Generator
|
33
|
+
|
34
|
+
Description:
|
35
|
+
The entity generator creates new entity for Redmine plugin.
|
36
|
+
New entity is prepared for use in Redmine and Easy Redmine as well.
|
37
|
+
|
38
|
+
Example:
|
39
|
+
rails g redmine_extensions:entity NameOfNewPlugin Post
|
40
|
+
create plugins/name_of_new_plugin/app/controllers
|
41
|
+
...
|
42
|
+
|
43
|
+
Help:
|
44
|
+
rails g redmine_extensions:entity --help
|
45
|
+
|
46
|
+
## Licence
|
47
|
+
This is published under GPL-2 license.
|
@@ -31,8 +31,9 @@ module RedmineExtensions
|
|
31
31
|
|
32
32
|
# hide elements for issues and users
|
33
33
|
def detect_hide_elements(uniq_id, user = nil, default = true)
|
34
|
-
return
|
35
|
-
|
34
|
+
return if uniq_id.blank?
|
35
|
+
|
36
|
+
'style="display:none"'.html_safe if !toggle_button_expanded?(uniq_id, user, default)
|
36
37
|
end
|
37
38
|
|
38
39
|
def url_to_entity(entity, options={})
|
@@ -140,6 +141,8 @@ module RedmineExtensions
|
|
140
141
|
end
|
141
142
|
|
142
143
|
def get_jasmine_tags
|
144
|
+
ActiveSupport::Deprecation.warn "jasmine will be removed from redmine_extensions"
|
145
|
+
|
143
146
|
tags = params[:jasmine]
|
144
147
|
return [] if tags == 'true'
|
145
148
|
if tags.is_a?(String)
|
@@ -154,7 +157,7 @@ module RedmineExtensions
|
|
154
157
|
def easy_avatar_url(user = nil)
|
155
158
|
user ||= User.current
|
156
159
|
result = if Setting.gravatar_enabled?
|
157
|
-
options = {:
|
160
|
+
options = { ssl: (request&.ssl?), default: Setting.gravatar_default }
|
158
161
|
email = nil
|
159
162
|
if user.respond_to?(:mail)
|
160
163
|
email = user.mail
|
@@ -287,7 +290,7 @@ module RedmineExtensions
|
|
287
290
|
# * +rootElement+ - Has sence only if jsonpath is used for available values. It tells if the json response has values wrapped under root element.
|
288
291
|
# For response like <tt>{projects: [[<name>, <id>], [<name2>, <id2>]]}</tt> user option <tt>rootElement: 'projects'</tt>
|
289
292
|
def autocomplete_field_tag(name, jsonpath_or_array, selected_values, options = {})
|
290
|
-
options.reverse_merge!(
|
293
|
+
options.reverse_merge!(select_first_value: false, load_immediately: false, preload: true, multiple: true, combo: false)
|
291
294
|
options[:id] ||= sanitize_to_id(name)
|
292
295
|
|
293
296
|
selected_values ||= []
|
@@ -298,8 +301,8 @@ module RedmineExtensions
|
|
298
301
|
source = "'#{jsonpath_or_array}'"
|
299
302
|
end
|
300
303
|
|
301
|
-
content_tag(:span, :
|
302
|
-
search_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id])) +
|
304
|
+
content_tag(:span, class: 'easy-multiselect-tag-container', data: { cy: "container_old_autocomplete--#{name}" }) do
|
305
|
+
search_field_tag('', '', (options[:html_options] || {}).merge(id: options[:id], data: { cy: "search_old_autocomplete--#{name}" })) +
|
303
306
|
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} });")
|
304
307
|
end
|
305
308
|
end
|
@@ -1,8 +1,26 @@
|
|
1
1
|
<div class="module box <%= renderer.container_class %>"<%=raw renderer.saving_state_enabled? && %Q{ data-toggle="#{renderer.id}"} || nil %>>
|
2
2
|
<%= content_tag(:div, class: 'module-heading ' + renderer.heading_class, onclick: (renderer.collapsible? && 'EasyToggler.toggle(this.nextElementSibling, event)' || nil)) do %>
|
3
|
-
<%= content_tag(:span, ' ', class: 'expander module-toggler') if renderer.collapsible? %>
|
4
3
|
<%= content_tag(renderer.heading_tag, renderer.heading, class: renderer.icon) %>
|
5
|
-
|
4
|
+
<% if renderer.heading_links.presence %>
|
5
|
+
<div class="module-heading-links">
|
6
|
+
<a class="module-heading-links__control icon-more-horiz control--<%= renderer.id %>" title="<%= l(:button_heading_links) %>" aria-label="<%= l(:button_heading_links) %>" role="button"></a>
|
7
|
+
<ul class="module-heading-links__tooltip tooltip tooltip--<%= renderer.id %>">
|
8
|
+
<%= renderer.heading_links %>
|
9
|
+
<% if renderer.collapsible? -%>
|
10
|
+
<li><span href="#" class="icon-chevron-up module__expander" data-cy="expander__toggle--module" title="Expander" aria-label="Expander" role="button"> </span></li>
|
11
|
+
<% end -%>
|
12
|
+
</ul>
|
13
|
+
<script>
|
14
|
+
EASY.schedule.require(function(){
|
15
|
+
$('.control--<%= renderer.id %>').toggleable({
|
16
|
+
observer: EASY.defaultClickObserver,
|
17
|
+
content: $('.tooltip--<%= renderer.id %>')
|
18
|
+
})},function () {
|
19
|
+
return EASY.defaultClickObserver;
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</div>
|
23
|
+
<% end -%>
|
6
24
|
<% end if renderer.heading.present? %>
|
7
25
|
<div class="module-content" id="<%= renderer.id %>"<%=raw renderer.collapsed? && %q{ style="display:none"} || nil %>>
|
8
26
|
<%= content -%>
|
@@ -1,7 +1,9 @@
|
|
1
|
+
<% ActiveSupport::Deprecation.warn "Jasmine will be removed from redmine_extensions in next version" %>
|
2
|
+
|
1
3
|
<% if params[:jasmine] %>
|
2
4
|
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine.js"></script>
|
3
5
|
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine-html.js"></script>
|
4
6
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine.css">
|
5
7
|
<%= javascript_include_tag('redmine_extensions/jasmine_lib/jasmine_lib.js') %>
|
6
8
|
<%= stylesheet_link_tag('redmine_extensions/jasmine.css') %>
|
7
|
-
<% end %>
|
9
|
+
<% end %>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%% if @<%= model_name_underscored %> && !@<%= model_name_underscored %>.new_record? %>
|
3
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
4
|
<%% end %>
|
5
|
-
<%%
|
5
|
+
<%% if @<%= model_name_underscored %>.nil? %>
|
6
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
7
|
<%% end %>
|
8
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')) %>
|
@@ -8,10 +8,9 @@ require_relative './query_output'
|
|
8
8
|
|
9
9
|
module RedmineExtensions
|
10
10
|
class Engine < ::Rails::Engine
|
11
|
-
|
12
11
|
config.generators do |g|
|
13
|
-
g.test_framework :rspec, :
|
14
|
-
g.fixture_replacement :factory_girl, :
|
12
|
+
g.test_framework :rspec, fixture: false
|
13
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
15
14
|
g.assets false
|
16
15
|
g.helper false
|
17
16
|
end
|
@@ -30,7 +29,7 @@ module RedmineExtensions
|
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
|
-
#config.to_prepare goes after Reloader.to_prepare
|
32
|
+
# config.to_prepare goes after Reloader.to_prepare
|
34
33
|
RedmineExtensions::Reloader.to_prepare do
|
35
34
|
RedmineExtensions::QueryOutput.register_output RedmineExtensions::QueryOutputs::ListOutput
|
36
35
|
RedmineExtensions::QueryOutput.register_output RedmineExtensions::QueryOutputs::TilesOutput
|
@@ -39,7 +38,7 @@ module RedmineExtensions
|
|
39
38
|
ApplicationController.include RedmineExtensions::RenderingHelper
|
40
39
|
end
|
41
40
|
|
42
|
-
initializer 'redmine_extensions.initialize' do |
|
41
|
+
initializer 'redmine_extensions.initialize' do |_app|
|
43
42
|
ActionDispatch::Routing::RouteSet::Generator.prepend RedmineExtensions::RailsPatches::RouteSetGeneratorPatch
|
44
43
|
end
|
45
44
|
|
@@ -52,17 +51,15 @@ module RedmineExtensions
|
|
52
51
|
if true
|
53
52
|
js_dir = app.root.join('public', 'javascripts', 'redmine_extensions')
|
54
53
|
FileUtils.mkdir(js_dir) unless File.directory?(js_dir)
|
55
|
-
Dir.glob(
|
56
|
-
|
57
|
-
|
58
|
-
rescue
|
59
|
-
end
|
54
|
+
Dir.glob(root.join('app', 'assets', 'javascripts', 'redmine_extensions', '*.js')) do |js_file|
|
55
|
+
FileUtils.cp(js_file, app.root.join('public', 'javascripts', 'redmine_extensions'))
|
56
|
+
rescue StandardError
|
60
57
|
end
|
61
58
|
end
|
62
59
|
end
|
63
60
|
|
64
61
|
# include helpers
|
65
|
-
initializer 'redmine_extensions.rails_patching', before: :load_config_initializers do |
|
62
|
+
initializer 'redmine_extensions.rails_patching', before: :load_config_initializers do |_app|
|
66
63
|
ActiveSupport.on_load(Rails::VERSION::MAJOR >= 5 ? :action_controller_base : :action_controller) do
|
67
64
|
helper RedmineExtensions::ApplicationHelper
|
68
65
|
# helper RedmineExtensions::EasyQueryHelper
|
@@ -78,17 +75,10 @@ module RedmineExtensions
|
|
78
75
|
initializer 'redmine_extensions.initialize_easy_plugins', after: :load_config_initializers do
|
79
76
|
require_relative './hooks'
|
80
77
|
|
81
|
-
unless Redmine::Plugin.installed?(:easy_extensions)
|
82
|
-
ActiveSupport.run_load_hooks(:easyproject, self)
|
83
|
-
end
|
78
|
+
ActiveSupport.run_load_hooks(:easyproject, self) unless Redmine::Plugin.installed?(:easy_extensions)
|
84
79
|
|
85
80
|
require_relative './easy_entity_formatters/easy_entity_formatter'
|
86
81
|
end
|
87
82
|
|
88
|
-
# initializer :add_html_formatting do |app|
|
89
|
-
# require_relative "./html_formatting"
|
90
|
-
# Redmine::WikiFormatting.register(:HTML, RedmineExtensions::HTMLFormatting::Formatter, RedmineExtensions::HTMLFormatting::Helper)
|
91
|
-
# end
|
92
|
-
|
93
83
|
end
|
94
84
|
end
|
@@ -47,14 +47,14 @@ module RedmineExtensions
|
|
47
47
|
# => :after => 'Project'
|
48
48
|
# => :last
|
49
49
|
# => :if => Proc.new{ Object.const_defined?(:EasyBudgetSheetQuery) }
|
50
|
-
def self.register_patch(original_klasses_to_patch, patching_module, options={})
|
50
|
+
def self.register_patch(original_klasses_to_patch, patching_module, options = {})
|
51
51
|
return if @@reloading_code
|
52
52
|
|
53
53
|
options ||= {}
|
54
54
|
|
55
55
|
begin
|
56
56
|
const = patching_module.constantize
|
57
|
-
@@patches_locations[patching_module] = const.methods(false).map{|m| const.method(m) }.first.source_location.first
|
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
60
|
from_location = caller_locations(2..2).first
|
@@ -71,7 +71,7 @@ module RedmineExtensions
|
|
71
71
|
raise ArgumentError, 'EasyPatchManager->register_patch: The \'original_klass_to_patch\' have to be a string or array of strings!'
|
72
72
|
end
|
73
73
|
|
74
|
-
raise ArgumentError, "EasyPatchManager->register_patch: The \'patching_module\' (#{patching_module}) already exists!" if EasyPatch.all_patching_modules.include?(
|
74
|
+
raise ArgumentError, "EasyPatchManager->register_patch: The \'patching_module\' (#{patching_module}) already exists!" if EasyPatch.all_patching_modules.include?(patching_module)
|
75
75
|
|
76
76
|
if options[:section]
|
77
77
|
section = options.delete(:section).to_sym
|
@@ -81,47 +81,47 @@ module RedmineExtensions
|
|
81
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
|
-
pcollection = @@registered_patches[section].move_and_get_or_insert(
|
84
|
+
pcollection = @@registered_patches[section].move_and_get_or_insert(original_klass_to_patch, options)
|
85
85
|
pcollection << EasyPatch.new(original_klass_to_patch, patching_module, options)
|
86
86
|
end
|
87
87
|
end
|
88
|
-
private_class_method :register_patch
|
89
88
|
|
89
|
+
private_class_method :register_patch
|
90
90
|
|
91
|
-
def self.register_ruby_patch(original_klass_to_patch, patching_module, options={})
|
92
|
-
register_patch(original_klass_to_patch, patching_module, {:
|
91
|
+
def self.register_ruby_patch(original_klass_to_patch, patching_module, options = {})
|
92
|
+
register_patch(original_klass_to_patch, patching_module, { section: :ruby }.merge(options))
|
93
93
|
end
|
94
94
|
|
95
|
-
def self.register_rails_patch(original_klass_to_patch, patching_module, options={})
|
96
|
-
register_patch(original_klass_to_patch, patching_module, {:
|
95
|
+
def self.register_rails_patch(original_klass_to_patch, patching_module, options = {})
|
96
|
+
register_patch(original_klass_to_patch, patching_module, { section: :rails }.merge(options))
|
97
97
|
end
|
98
98
|
|
99
|
-
def self.register_redmine_plugin_patch(original_klass_to_patch, patching_module, options={})
|
100
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :redmine_plugins}.merge(options))
|
99
|
+
def self.register_redmine_plugin_patch(original_klass_to_patch, patching_module, options = {})
|
100
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :redmine_plugins }.merge(options))
|
101
101
|
end
|
102
102
|
|
103
|
-
def self.register_other_patch(original_klass_to_patch, patching_module, options={})
|
104
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :others}.merge(options))
|
103
|
+
def self.register_other_patch(original_klass_to_patch, patching_module, options = {})
|
104
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :others }.merge(options))
|
105
105
|
end
|
106
106
|
|
107
|
-
def self.register_concern_patch(original_klass_to_patch, patching_module, options={})
|
108
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :concerns}.merge(options))
|
107
|
+
def self.register_concern_patch(original_klass_to_patch, patching_module, options = {})
|
108
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :concerns }.merge(options))
|
109
109
|
end
|
110
110
|
|
111
|
-
def self.register_controller_patch(original_klass_to_patch, patching_module, options={})
|
112
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :controllers}.merge(options))
|
111
|
+
def self.register_controller_patch(original_klass_to_patch, patching_module, options = {})
|
112
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :controllers }.merge(options))
|
113
113
|
end
|
114
114
|
|
115
|
-
def self.register_helper_patch(original_klass_to_patch, patching_module, options={})
|
116
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :helpers}.merge(options))
|
115
|
+
def self.register_helper_patch(original_klass_to_patch, patching_module, options = {})
|
116
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :helpers }.merge(options))
|
117
117
|
end
|
118
118
|
|
119
|
-
def self.register_model_patch(original_klass_to_patch, patching_module, options={})
|
120
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :models}.merge(options))
|
119
|
+
def self.register_model_patch(original_klass_to_patch, patching_module, options = {})
|
120
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :models }.merge(options))
|
121
121
|
end
|
122
122
|
|
123
|
-
def self.register_patch_to_be_first(original_klass_to_patch, patching_module, options={})
|
124
|
-
register_patch(original_klass_to_patch, patching_module, {:section => :force_first}.merge(options))
|
123
|
+
def self.register_patch_to_be_first(original_klass_to_patch, patching_module, options = {})
|
124
|
+
register_patch(original_klass_to_patch, patching_module, { :section => :force_first }.merge(options))
|
125
125
|
end
|
126
126
|
|
127
127
|
def self.register_easy_page_helper(*helper_or_helpers_klass_name)
|
@@ -208,28 +208,28 @@ module RedmineExtensions
|
|
208
208
|
end
|
209
209
|
|
210
210
|
def [](name)
|
211
|
-
pcollection = @patches_collections.detect{|patch_col| patch_col.name == name }
|
211
|
+
pcollection = @patches_collections.detect { |patch_col| patch_col.name == name }
|
212
212
|
end
|
213
213
|
|
214
214
|
def include_patch?(name)
|
215
|
-
!!@patches_collections.detect{|patch_col| patch_col.name == name }
|
215
|
+
!!@patches_collections.detect { |patch_col| patch_col.name == name }
|
216
216
|
end
|
217
217
|
|
218
|
-
def move_and_get_or_insert(
|
219
|
-
pcollection = @patches_collections.detect{|patch_col| patch_col.name == name }
|
220
|
-
founded_order = find_order(
|
218
|
+
def move_and_get_or_insert(name, options)
|
219
|
+
pcollection = @patches_collections.detect { |patch_col| patch_col.name == name }
|
220
|
+
founded_order = find_order(options)
|
221
221
|
if pcollection
|
222
222
|
if founded_order
|
223
223
|
pcollection.order = founded_order
|
224
224
|
update_order_by(pcollection)
|
225
225
|
end
|
226
226
|
else
|
227
|
-
pcollection = insert(
|
227
|
+
pcollection = insert(name, founded_order)
|
228
228
|
end
|
229
229
|
pcollection
|
230
230
|
end
|
231
231
|
|
232
|
-
def find_order(
|
232
|
+
def find_order(options)
|
233
233
|
if options.delete(:first)
|
234
234
|
return 1
|
235
235
|
elsif before = options.delete(:before)
|
@@ -240,7 +240,7 @@ module RedmineExtensions
|
|
240
240
|
actual = nil
|
241
241
|
before_patch = self[before_class_name]
|
242
242
|
actual = before_patch.order if before_patch
|
243
|
-
if actual && (
|
243
|
+
if actual && (!min || actual < min)
|
244
244
|
min = actual
|
245
245
|
end
|
246
246
|
end
|
@@ -277,7 +277,7 @@ module RedmineExtensions
|
|
277
277
|
|
278
278
|
private
|
279
279
|
|
280
|
-
def push_back(
|
280
|
+
def push_back(collection)
|
281
281
|
# => ambitious, if it is private method...
|
282
282
|
# raise ArgumentError, "Section already contains a collection #{collection.name}" if @patches_collections.detect{ |coll| collection.name == coll.name }
|
283
283
|
@patches_collections << collection
|
@@ -287,16 +287,16 @@ module RedmineExtensions
|
|
287
287
|
@last_order += 1
|
288
288
|
end
|
289
289
|
|
290
|
-
def insert(
|
290
|
+
def insert(name, order = nil)
|
291
291
|
final_order = order || last_order
|
292
|
-
collection = EasyPatchesCollection.new(
|
293
|
-
push_back(
|
294
|
-
update_order_by(
|
292
|
+
collection = EasyPatchesCollection.new(name, final_order)
|
293
|
+
push_back(collection)
|
294
|
+
update_order_by(collection) if order
|
295
295
|
collection
|
296
296
|
end
|
297
297
|
|
298
|
-
def update_order_by(
|
299
|
-
@patches_collections.select {|patch_coll| (
|
298
|
+
def update_order_by(collection)
|
299
|
+
@patches_collections.select { |patch_coll| (patch_coll.name != collection.name) && (patch_coll.order >= collection.order) }.each do |col|
|
300
300
|
col.order = col.order + 1
|
301
301
|
end
|
302
302
|
@patches_collections.sort!
|
@@ -347,7 +347,6 @@ module RedmineExtensions
|
|
347
347
|
|
348
348
|
end
|
349
349
|
|
350
|
-
|
351
350
|
class EasyPatch
|
352
351
|
|
353
352
|
def self.all_patching_modules
|
@@ -374,9 +373,7 @@ module RedmineExtensions
|
|
374
373
|
end
|
375
374
|
|
376
375
|
def apply_patch
|
377
|
-
if (cond = @options[:if]) && cond.respond_to?(:call)
|
378
|
-
return unless cond.call
|
379
|
-
end
|
376
|
+
return if (cond = @options[:if]) && cond.respond_to?(:call) && !cond.call
|
380
377
|
|
381
378
|
pm_klass = easy_constantize(patching_module)
|
382
379
|
# pm_klass.class_eval { unloadable }
|
@@ -392,10 +389,13 @@ module RedmineExtensions
|
|
392
389
|
oktp_klass.include pm_klass
|
393
390
|
end
|
394
391
|
end
|
392
|
+
rescue NameError => e
|
393
|
+
patch_location = Module.const_source_location(patching_module)
|
394
|
+
raise NameError, "#{e.message} in #{patch_location}"
|
395
395
|
end
|
396
396
|
|
397
397
|
def easy_constantize(name)
|
398
|
-
|
398
|
+
name.constantize
|
399
399
|
rescue NameError
|
400
400
|
if RedmineExtensions::PatchManager.patches_locations.has_key?(name)
|
401
401
|
RedmineExtensions::PatchManager.with_reloading_code do
|
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.5.1
|
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: 2022-06-
|
11
|
+
date: 2022-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '6.2'
|
19
|
+
version: '6.1'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '6.2'
|
26
|
+
version: '6.1'
|
33
27
|
description: Redmine Extensions provide many extended functionalities for Redmine
|
34
28
|
project.
|
35
29
|
email:
|
@@ -39,6 +33,7 @@ extensions: []
|
|
39
33
|
extra_rdoc_files: []
|
40
34
|
files:
|
41
35
|
- LICENSE
|
36
|
+
- README.md
|
42
37
|
- Rakefile
|
43
38
|
- app/assets/javascripts/redmine_extensions/application.js
|
44
39
|
- app/assets/javascripts/redmine_extensions/blocking.js
|
@@ -166,10 +161,6 @@ files:
|
|
166
161
|
- lib/redmine_extensions/engine.rb
|
167
162
|
- lib/redmine_extensions/export/easy_other_formats_builder.rb
|
168
163
|
- lib/redmine_extensions/hooks.rb
|
169
|
-
- lib/redmine_extensions/html_formatting.rb
|
170
|
-
- lib/redmine_extensions/html_formatting/formatter.rb
|
171
|
-
- lib/redmine_extensions/html_formatting/helper.rb
|
172
|
-
- lib/redmine_extensions/html_formatting/internals.rb
|
173
164
|
- lib/redmine_extensions/migration.rb
|
174
165
|
- lib/redmine_extensions/patch_manager.rb
|
175
166
|
- lib/redmine_extensions/query_output.rb
|
@@ -185,13 +176,10 @@ files:
|
|
185
176
|
- lib/redmine_extensions/version.rb
|
186
177
|
- lib/tasks/redmine_extensions_tasks.rake
|
187
178
|
- spec/factories/easy_settings.rb
|
188
|
-
- spec/features/autocomplete_spec.rb
|
189
|
-
- spec/features/jasmine_spec.rb
|
190
179
|
- spec/init_rails.rb
|
191
180
|
- spec/models/easy_setting_spec.rb
|
192
181
|
- spec/presenters/easy_settings/params_wrapper_spec.rb
|
193
182
|
- spec/spec_helper.rb
|
194
|
-
- spec/support/plugin_generator.rb
|
195
183
|
homepage: https://www.easyredmine.com
|
196
184
|
licenses:
|
197
185
|
- GPL-2.0
|
@@ -204,24 +192,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
192
|
requirements:
|
205
193
|
- - ">="
|
206
194
|
- !ruby/object:Gem::Version
|
207
|
-
version: '2.
|
195
|
+
version: '2.7'
|
208
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
197
|
requirements:
|
210
198
|
- - ">="
|
211
199
|
- !ruby/object:Gem::Version
|
212
200
|
version: '0'
|
213
201
|
requirements: []
|
214
|
-
rubygems_version: 3.
|
202
|
+
rubygems_version: 3.2.33
|
215
203
|
signing_key:
|
216
204
|
specification_version: 4
|
217
|
-
summary: Redmine Extensions is set of
|
218
|
-
|
205
|
+
summary: Redmine Extensions is set of useful features for Redmine. Main focus is on
|
206
|
+
development helpers, but many users can find it helpfull
|
219
207
|
test_files:
|
220
208
|
- spec/factories/easy_settings.rb
|
221
|
-
- spec/features/autocomplete_spec.rb
|
222
|
-
- spec/features/jasmine_spec.rb
|
223
209
|
- spec/init_rails.rb
|
224
210
|
- spec/models/easy_setting_spec.rb
|
225
211
|
- spec/presenters/easy_settings/params_wrapper_spec.rb
|
226
212
|
- spec/spec_helper.rb
|
227
|
-
- spec/support/plugin_generator.rb
|
@@ -1,86 +0,0 @@
|
|
1
|
-
module RedmineExtensions
|
2
|
-
module HTMLFormatting
|
3
|
-
class Formatter < String
|
4
|
-
include ActionView::Helpers::TagHelper
|
5
|
-
|
6
|
-
RULES = [:tidy_html_from_editor, :rinku_auto_link, :inline_auto_link, :inline_auto_mailto]
|
7
|
-
|
8
|
-
def to_html(*rules, &block)
|
9
|
-
ret = self.dup
|
10
|
-
RULES.each do |rule_name|
|
11
|
-
ret = (method(rule_name).call(ret) || ret)
|
12
|
-
end
|
13
|
-
ret
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
AUTO_LINK_RE = %r{
|
19
|
-
( # leading text
|
20
|
-
#<\w+.*?>| # leading HTML tag, or
|
21
|
-
[^=<>!:'"/]| # leading punctuation, or
|
22
|
-
\{\{\w+\(| # inside a macro?
|
23
|
-
^ # beginning of line
|
24
|
-
)
|
25
|
-
(
|
26
|
-
(?:https?://)| # protocol spec, or
|
27
|
-
(?:s?ftps?://)|
|
28
|
-
(?:www\.)| # www.*
|
29
|
-
(?:smb://)|
|
30
|
-
(?:file://)
|
31
|
-
)
|
32
|
-
(
|
33
|
-
(\S+?) # url
|
34
|
-
(\/)? # slash
|
35
|
-
)
|
36
|
-
((?:>)?|[^\w\=\/;\(\)]*?) # post
|
37
|
-
(?=<|\s| |$)
|
38
|
-
}x unless const_defined?(:AUTO_LINK_RE)
|
39
|
-
|
40
|
-
def rinku_auto_link(text)
|
41
|
-
Rinku.auto_link(text) if defined?(Rinku)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Turns all urls into clickable links (code from Rails).
|
45
|
-
def inline_auto_link(text, regex_rules = AUTO_LINK_RE)
|
46
|
-
text.gsub!(regex_rules) do
|
47
|
-
all, leading, proto, url, post = $&, $1, $2, $3, $6
|
48
|
-
|
49
|
-
if leading =~ /<a\s/i || leading =~ /![<>=]?/ || leading =~ /\{\{\w+\(/
|
50
|
-
#don't replace URL's that are already linked
|
51
|
-
#and URL's prefixed with ! !> !< != (textile images)
|
52
|
-
all
|
53
|
-
else
|
54
|
-
#Idea below : an URL with unbalanced parethesis and
|
55
|
-
#ending by ')' is put into external parenthesis
|
56
|
-
if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) )
|
57
|
-
url=url[0..-2] # discard closing parenth from url
|
58
|
-
post = ")"+post # add closing parenth to post
|
59
|
-
end
|
60
|
-
|
61
|
-
tag = content_tag('a', proto + url, :href => "#{proto == 'www.' ? "http://#{proto}" : proto}#{url}", :class => 'external', :target => '_blank')
|
62
|
-
%(#{leading}#{tag}#{post})
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Turns all email addresses into clickable links (code from Rails).
|
68
|
-
def inline_auto_mailto(text)
|
69
|
-
text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
|
70
|
-
mail = $1
|
71
|
-
if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
|
72
|
-
mail
|
73
|
-
else
|
74
|
-
content_tag('a', mail, :href => "mailto:#{mail}", :class => "email")
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# Tidy html. Fix html tags for correct show pages.
|
80
|
-
def tidy_html_from_editor(text)
|
81
|
-
Nokogiri::HTML::DocumentFragment.parse(text).to_html
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module RedmineExtensions
|
2
|
-
module HTMLFormatting
|
3
|
-
module Helper
|
4
|
-
|
5
|
-
def wikitoolbar_for(field_id, options={})
|
6
|
-
heads_for_wiki_formatter
|
7
|
-
|
8
|
-
custom_settings = options.delete(:custom)
|
9
|
-
options[:toolbar] ||= EasySetting.value('ckeditor_toolbar_config') || 'Basic'
|
10
|
-
options[:lang] ||= User.current.language
|
11
|
-
options[:lang] = Setting.default_language if options[:lang].blank?
|
12
|
-
options[:language] = options[:lang] if options[:lang].present?
|
13
|
-
|
14
|
-
# Syntax higlight
|
15
|
-
if EasySetting.value('ckeditor_syntax_highlight_enabled')
|
16
|
-
options[:codeSnippet_theme] ||= EasyCKEditor.syntaxt_higlight_template
|
17
|
-
else
|
18
|
-
if options[:removePlugins]
|
19
|
-
options[:removePlugins] << ','
|
20
|
-
else
|
21
|
-
options[:removePlugins] = ''
|
22
|
-
end
|
23
|
-
|
24
|
-
options[:removePlugins] << 'codesnippet'
|
25
|
-
end
|
26
|
-
|
27
|
-
hook_settings = call_hook(:helper_ckeditor_wikitoolbar_for_add_option, {:field_id => field_id, :options => options})
|
28
|
-
|
29
|
-
ck_options = options.collect{|k,v| "#{k}:'#{v}'"}
|
30
|
-
ck_options << custom_settings unless custom_settings.blank?
|
31
|
-
ck_options << hook_settings unless hook_settings.to_s.blank?
|
32
|
-
|
33
|
-
reminder_confirm = options[:attachment_reminder_message] ? options[:attachment_reminder_message] : l(:text_easy_attachment_reminder_confirm)
|
34
|
-
reminderjs = options[:attachment_reminder] ? "$('##{field_id}').addClass('set_attachment_reminder').data('ck', true).data('reminder_words', \"#{j(Attachment.attachment_reminder_words)}\").data('reminder_confirm', '#{j(reminder_confirm)}'); " : ''
|
35
|
-
|
36
|
-
js = "var ta_editor = CKEDITOR.instances['#{field_id}']; if (ta_editor) {CKEDITOR.remove(ta_editor);} CKEDITOR.replace('#{field_id}',{#{ck_options.join(',')}});"
|
37
|
-
js << "window.enableWarnLeavingUnsaved = '#{User.current.pref.warn_on_leaving_unsaved}';"
|
38
|
-
|
39
|
-
javascript_tag(reminderjs + js)
|
40
|
-
end
|
41
|
-
|
42
|
-
def initial_page_content(page)
|
43
|
-
end
|
44
|
-
|
45
|
-
def heads_for_wiki_formatter
|
46
|
-
unless @heads_for_wiki_formatter_included
|
47
|
-
header = javascript_include_tag('redmine_extensions/ckeditor/ckeditor')
|
48
|
-
|
49
|
-
# Syntax higlight
|
50
|
-
if EasySetting.value('ckeditor_syntax_highlight_enabled')
|
51
|
-
header << stylesheet_link_tag(EasyCKEditor.syntaxt_higlight_css)
|
52
|
-
header << javascript_include_tag(EasyCKEditor.syntaxt_higlight_js)
|
53
|
-
|
54
|
-
# Pre block have custom css attributes
|
55
|
-
# .pre-hljs will set them to default
|
56
|
-
header << javascript_tag(%{
|
57
|
-
$(document).ready(function() {
|
58
|
-
$('pre code').each(function(i, block) {
|
59
|
-
hljs.highlightBlock(block);
|
60
|
-
$(block).parent().addClass('pre-default');
|
61
|
-
});
|
62
|
-
});
|
63
|
-
})
|
64
|
-
end
|
65
|
-
|
66
|
-
content_for(:header_tags, header)
|
67
|
-
@heads_for_wiki_formatter_included = true
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module EasyCKEditor
|
2
|
-
|
3
|
-
def self.syntaxt_higlight_default_template
|
4
|
-
@syntaxt_higlight_default_template ||= 'github'
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.syntaxt_higlight_templates
|
8
|
-
@syntaxt_higlight_templates ||= ['github', 'googlecode', 'idea', 'monokai', 'monokai_sublime', 'railscasts']
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.syntaxt_higlight_template
|
12
|
-
EasySetting.value('ckeditor_syntax_highlight_theme') || syntaxt_higlight_default_template
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.syntaxt_higlight_css
|
16
|
-
"/plugin_assets/ckeditor/javascripts/ckeditor/plugins/codesnippet/lib/highlight/styles/#{syntaxt_higlight_template}"
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.syntaxt_higlight_js
|
20
|
-
@syntaxt_higlight_js ||= "/plugin_assets/ckeditor/javascripts/ckeditor/plugins/codesnippet/lib/highlight/highlight.pack.js"
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
RSpec.describe 'autocomplete', type: :feature, js: true, logged: :admin do
|
2
|
-
|
3
|
-
describe 'render' do
|
4
|
-
it 'generate default autocomplete' do
|
5
|
-
visit '/dummy_autocompletes'
|
6
|
-
expect(page).to have_css('input#default[type="search"]')
|
7
|
-
expect(page).to have_css('input[type="hidden"][name="default"][value="value1"]', visible: false)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'generate autocomplete_field in form_for' do
|
11
|
-
visit '/dummy_autocompletes'
|
12
|
-
expect(page).to have_css('input#dummy_entities_autocomplete[type="search"]')
|
13
|
-
expect(page).to have_css('input[type="hidden"][name="dummy_entity[array_of_dummies][]"][value="value1"]', visible: false)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
RSpec.describe 'jasmine', type: :feature, js: true, logged: :admin do
|
2
|
-
|
3
|
-
it 'run tests' do
|
4
|
-
visit "/dummy_entities?jasmine=true"
|
5
|
-
expect(page).to have_css('.jasmine-bar')
|
6
|
-
expect(page.evaluate_script('window.jasmineHelper.parseResult();')).to eq('success')
|
7
|
-
end
|
8
|
-
|
9
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'rails/generators'
|
2
|
-
|
3
|
-
module PluginGenerator
|
4
|
-
def self.generate_test_plugin!
|
5
|
-
Rails::Generators.invoke 'redmine_extensions:plugin', ['DummyPlugin'], behavior: :revoke, destination_root: Rails.root
|
6
|
-
Rails::Generators.invoke 'redmine_extensions:plugin', ['DummyPlugin'], behavior: :invoke, destination_root: Rails.root
|
7
|
-
generate_autocomplete!
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.generate_autocomplete!
|
11
|
-
generate_dummy_entity!
|
12
|
-
generate_entities_view!
|
13
|
-
generate_autocomplete_controller!
|
14
|
-
generate_autocomplete_routes!
|
15
|
-
generate_autocomplete_view!
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.generate_dummy_entity!
|
19
|
-
File.open( Rails.root.join('plugins', 'dummy_plugin', 'db', 'migrate', '20162010160230_create_dummy_entities.rb'), 'w' ) do |file|
|
20
|
-
file.write( <<-END_RUBY )
|
21
|
-
class CreateDummyEntities < ActiveRecord::Migration[4.2]
|
22
|
-
def change
|
23
|
-
create_table :dummy_entities do |t|
|
24
|
-
t.string :name
|
25
|
-
t.integer :value
|
26
|
-
t.references :project, index: true
|
27
|
-
t.text :array_of_dummies
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
END_RUBY
|
32
|
-
end
|
33
|
-
|
34
|
-
File.open( Rails.root.join('plugins', 'dummy_plugin', 'app', 'models', 'dummy_entity.rb'), 'w' ) do |file|
|
35
|
-
file.write( <<-END_RUBY )
|
36
|
-
class DummyEntity < ActiveRecord::Base
|
37
|
-
include Redmine::SafeAttributes
|
38
|
-
safe_attributes 'name',
|
39
|
-
'value',
|
40
|
-
'project_id',
|
41
|
-
'array_of_dummies'
|
42
|
-
|
43
|
-
serialize :array_of_dummies, Array
|
44
|
-
end
|
45
|
-
END_RUBY
|
46
|
-
end
|
47
|
-
|
48
|
-
File.open(Rails.root.join('plugins', 'dummy_plugin', 'app', 'controllers', 'dummy_entities_controller.rb'), 'w') do |file|
|
49
|
-
file.write( <<-END_RUBY )
|
50
|
-
class DummyEntitiesController < ApplicationController
|
51
|
-
def index
|
52
|
-
end
|
53
|
-
|
54
|
-
def create
|
55
|
-
@entity = DummyEntity.new
|
56
|
-
@entity.safe_attributes = params[:dummy_entity]
|
57
|
-
@entity.save
|
58
|
-
end
|
59
|
-
end
|
60
|
-
END_RUBY
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.generate_autocomplete_controller!
|
65
|
-
File.open(Rails.root.join('plugins', 'dummy_plugin', 'app', 'controllers', 'dummy_autocompletes_controller.rb'), 'w') do |file|
|
66
|
-
file.write( <<-END_RUBY )
|
67
|
-
class DummyAutocompletesController < ApplicationController
|
68
|
-
def index
|
69
|
-
end
|
70
|
-
end
|
71
|
-
END_RUBY
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.generate_autocomplete_routes!
|
76
|
-
File.open(Rails.root.join('plugins', 'dummy_plugin', 'config', 'routes.rb'), 'w') do |file|
|
77
|
-
file.write( <<-END_ROUTES )
|
78
|
-
resources :dummy_autocompletes
|
79
|
-
resources :dummy_entities
|
80
|
-
END_ROUTES
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.generate_autocomplete_view!
|
85
|
-
dir = Rails.root.join('plugins', 'dummy_plugin', 'app', 'views', 'dummy_autocompletes')
|
86
|
-
Dir.mkdir dir
|
87
|
-
File.open(dir.join('index.html.erb'), 'w') do |file|
|
88
|
-
file.write( <<-END_ERB )
|
89
|
-
<%= form_tag('/dummy_autocompletes', id: 'autocompletes_form') do %>
|
90
|
-
<%= autocomplete_field_tag('default', ['value1', 'value2'], ['value1']) %>
|
91
|
-
<% end %>
|
92
|
-
|
93
|
-
<%= form_for(DummyEntity.new(array_of_dummies: ['value1'])) do |f| %>
|
94
|
-
<%= f.autocomplete_field(:array_of_dummies, ['value1', 'value2'], {}, id: 'dummy_entities_autocomplete') %>
|
95
|
-
<% end %>
|
96
|
-
END_ERB
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def self.generate_entities_view!
|
101
|
-
dir = Rails.root.join('plugins', 'dummy_plugin', 'app', 'views', 'dummy_entities')
|
102
|
-
Dir.mkdir dir
|
103
|
-
File.open(dir.join('index.html.erb'), 'w') do |file|
|
104
|
-
file.write( <<-END_ERB )
|
105
|
-
<% DummyEntity.all.each do |entity| %>
|
106
|
-
<%= entity.name %>: <%= entity.value %>
|
107
|
-
<% end %>
|
108
|
-
END_ERB
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|