redmine_extensions 0.4.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -0
- data/app/assets/javascripts/redmine_extensions/redmine_extensions.js +1 -0
- data/app/helpers/redmine_extensions/application_helper.rb +27 -36
- data/app/views/common/_collapsible_module_layout.html.erb +20 -2
- data/app/views/easy_front_end/_easy_front_end.html.erb +1 -19
- data/db/migrate/20150705172511_create_easy_settings.rb +1 -1
- data/db/migrate/20160519161300_create_entity_assignments.rb +1 -1
- data/db/migrate/20190206121100_remove_foreign_key_from_easy_settings.rb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/_sidebar.html.erb.erb +1 -1
- data/lib/generators/redmine_extensions/entity/templates/show.html.erb.erb +1 -1
- data/lib/redmine_extensions/engine.rb +9 -23
- data/lib/redmine_extensions/hooks.rb +1 -9
- data/lib/redmine_extensions/migration.rb +1 -1
- data/lib/redmine_extensions/patch_manager.rb +43 -43
- data/lib/redmine_extensions/version.rb +3 -1
- metadata +11 -35
- data/app/assets/javascripts/redmine_extensions/jasmine_lib/boot.js +0 -153
- data/app/assets/javascripts/redmine_extensions/jasmine_lib/jasmine_helper.js +0 -292
- data/app/assets/javascripts/redmine_extensions/jasmine_lib/jasmine_lib.js +0 -3
- data/app/assets/javascripts/redmine_extensions/jasmine_tests/extend.js +0 -32
- data/app/assets/javascripts/redmine_extensions/jasmine_tests/jasmine_tests.js +0 -1
- data/app/assets/javascripts/redmine_extensions/jasmine_tests/modules.js +0 -164
- data/app/assets/stylesheets/redmine_extensions/jasmine.css +0 -35
- data/app/views/redmine_extensions/_development_mode.html.erb +0 -33
- data/app/views/redmine_extensions/_jasmine.html.erb +0 -7
- 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
@@ -1,164 +0,0 @@
|
|
1
|
-
describe("Modules", function () {
|
2
|
-
var nameCounter = 0;
|
3
|
-
|
4
|
-
function getName() {
|
5
|
-
return "jasmine_test_" + (nameCounter++);
|
6
|
-
}
|
7
|
-
|
8
|
-
function defineOptionModule(moduleName, context) {
|
9
|
-
EasyGem.module.module(moduleName, function () {
|
10
|
-
return function () {
|
11
|
-
context.add.apply(context, arguments);
|
12
|
-
}
|
13
|
-
});
|
14
|
-
}
|
15
|
-
|
16
|
-
function defineCallbackModule(moduleName, context) {
|
17
|
-
EasyGem.module.module(moduleName, function () {
|
18
|
-
return {
|
19
|
-
add: function () {
|
20
|
-
context.add.apply(context, arguments);
|
21
|
-
}
|
22
|
-
};
|
23
|
-
});
|
24
|
-
}
|
25
|
-
|
26
|
-
function resolveModules() {
|
27
|
-
EasyGem.module.setUrl("", null);
|
28
|
-
}
|
29
|
-
|
30
|
-
beforeEach(function () {
|
31
|
-
this.counter = 1;
|
32
|
-
var self = this;
|
33
|
-
this.count = function () {
|
34
|
-
self.counter++;
|
35
|
-
};
|
36
|
-
this.add = function (add) {
|
37
|
-
for (var i = 0; i < arguments.length; i++) {
|
38
|
-
self.counter += arguments[i];
|
39
|
-
}
|
40
|
-
};
|
41
|
-
});
|
42
|
-
describe("simple", function () {
|
43
|
-
it("works with option", function () {
|
44
|
-
var moduleName = getName();
|
45
|
-
defineOptionModule(moduleName, this);
|
46
|
-
expect(this.counter).toEqual(1);
|
47
|
-
EasyGem.loadModule(moduleName, 5);
|
48
|
-
expect(this.counter).toEqual(6);
|
49
|
-
});
|
50
|
-
it("works with callback", function () {
|
51
|
-
var moduleName = getName();
|
52
|
-
defineCallbackModule(moduleName, this);
|
53
|
-
expect(this.counter).toEqual(1);
|
54
|
-
EasyGem.loadModule(moduleName, function (module) {
|
55
|
-
module.add(5);
|
56
|
-
});
|
57
|
-
expect(this.counter).toEqual(6);
|
58
|
-
});
|
59
|
-
it("works with multiple options", function () {
|
60
|
-
var moduleName = getName();
|
61
|
-
defineOptionModule(moduleName, this);
|
62
|
-
expect(this.counter).toEqual(1);
|
63
|
-
EasyGem.loadModule(moduleName, 5, 9);
|
64
|
-
expect(this.counter).toEqual(15);
|
65
|
-
});
|
66
|
-
it("works with multiple options - loadModules", function () {
|
67
|
-
var moduleName = getName();
|
68
|
-
defineOptionModule(moduleName, this);
|
69
|
-
expect(this.counter).toEqual(1);
|
70
|
-
EasyGem.loadModules([moduleName], 5, 9);
|
71
|
-
expect(this.counter).toEqual(15);
|
72
|
-
});
|
73
|
-
});
|
74
|
-
describe("complex", function () {
|
75
|
-
describe("handle define after request", function () {
|
76
|
-
it("option", function () {
|
77
|
-
var moduleName = getName();
|
78
|
-
expect(this.counter).toEqual(1);
|
79
|
-
EasyGem.loadModule(moduleName, 8);
|
80
|
-
expect(this.counter).toEqual(1);
|
81
|
-
defineOptionModule(moduleName, this);
|
82
|
-
resolveModules();
|
83
|
-
expect(this.counter).toEqual(9);
|
84
|
-
});
|
85
|
-
it("callback", function () {
|
86
|
-
var moduleName = getName();
|
87
|
-
expect(this.counter).toEqual(1);
|
88
|
-
EasyGem.loadModule(moduleName, function (module) {
|
89
|
-
module.add(3);
|
90
|
-
});
|
91
|
-
expect(this.counter).toEqual(1);
|
92
|
-
defineCallbackModule(moduleName, this);
|
93
|
-
resolveModules();
|
94
|
-
expect(this.counter).toEqual(4);
|
95
|
-
});
|
96
|
-
});
|
97
|
-
describe("parts", function () {
|
98
|
-
it("define first", function () {
|
99
|
-
var moduleName = getName();
|
100
|
-
var self = this;
|
101
|
-
EasyGem.module.part(moduleName, [], function () {
|
102
|
-
this.add = function (option) {
|
103
|
-
self.add(option);
|
104
|
-
}
|
105
|
-
});
|
106
|
-
EasyGem.module.part(moduleName, function () {
|
107
|
-
this.addDouble = function (option) {
|
108
|
-
self.add(option * 2);
|
109
|
-
}
|
110
|
-
});
|
111
|
-
expect(this.counter).toEqual(1);
|
112
|
-
EasyGem.loadModule(moduleName, function (module) {
|
113
|
-
module.add(3);
|
114
|
-
module.addDouble(2);
|
115
|
-
});
|
116
|
-
expect(this.counter).toEqual(8);
|
117
|
-
});
|
118
|
-
it("request first", function () {
|
119
|
-
var moduleName = getName();
|
120
|
-
var self = this;
|
121
|
-
EasyGem.loadModule(moduleName, function (module) {
|
122
|
-
module.add(3);
|
123
|
-
module.addDouble(2);
|
124
|
-
});
|
125
|
-
expect(this.counter).toEqual(1);
|
126
|
-
EasyGem.module.part(moduleName, [], function () {
|
127
|
-
this.add = function (option) {
|
128
|
-
self.add(option);
|
129
|
-
}
|
130
|
-
});
|
131
|
-
expect(this.counter).toEqual(1);
|
132
|
-
EasyGem.module.part(moduleName, function () {
|
133
|
-
this.addDouble = function (option) {
|
134
|
-
self.add(option * 2);
|
135
|
-
}
|
136
|
-
});
|
137
|
-
resolveModules();
|
138
|
-
expect(this.counter).toEqual(8);
|
139
|
-
});
|
140
|
-
});
|
141
|
-
it("handle complex tree", function () {
|
142
|
-
var moduleName = getName();
|
143
|
-
var subModuleName1 = getName();
|
144
|
-
var subModuleName2 = getName();
|
145
|
-
EasyGem.module.module(moduleName, [subModuleName1, subModuleName2], function (sub1, sub2) {
|
146
|
-
this.sub1 = sub1;
|
147
|
-
this.sub2 = sub2;
|
148
|
-
});
|
149
|
-
expect(this.counter).toEqual(1);
|
150
|
-
EasyGem.loadModule(moduleName, function (module) {
|
151
|
-
module.sub1(2);
|
152
|
-
module.sub2.add(3);
|
153
|
-
});
|
154
|
-
resolveModules();
|
155
|
-
expect(this.counter).toEqual(1);
|
156
|
-
defineOptionModule(subModuleName1, this);
|
157
|
-
resolveModules();
|
158
|
-
expect(this.counter).toEqual(1);
|
159
|
-
defineCallbackModule(subModuleName2, this);
|
160
|
-
resolveModules();
|
161
|
-
expect(this.counter).toEqual(6);
|
162
|
-
});
|
163
|
-
});
|
164
|
-
});
|
@@ -1,35 +0,0 @@
|
|
1
|
-
.jasmine-specs {
|
2
|
-
margin: 0;
|
3
|
-
}
|
4
|
-
|
5
|
-
.jasmine_html-reporter {
|
6
|
-
margin-left: 100px;
|
7
|
-
margin-right: 100px;
|
8
|
-
}
|
9
|
-
|
10
|
-
.logo-jasmine {
|
11
|
-
width: 60px;
|
12
|
-
font-size: 0;
|
13
|
-
text-align: center;
|
14
|
-
color: white;
|
15
|
-
background-color: #fe7d99;
|
16
|
-
font-weight: normal;
|
17
|
-
}
|
18
|
-
|
19
|
-
.logo-jasmine--pass {
|
20
|
-
background-color: #01c8a9;
|
21
|
-
}
|
22
|
-
|
23
|
-
.logo-jasmine:before {
|
24
|
-
content: '\2620';
|
25
|
-
font-size: 40px;
|
26
|
-
}
|
27
|
-
|
28
|
-
.logo-jasmine--pass:before {
|
29
|
-
content: '\2705';
|
30
|
-
}
|
31
|
-
|
32
|
-
.logo-jasmine * {
|
33
|
-
height: 0 !important;
|
34
|
-
background-image: none !important;
|
35
|
-
}
|
@@ -1,33 +0,0 @@
|
|
1
|
-
<% if RedmineExtensions::PatchManager.reloadable_patches_applied > 1 %>
|
2
|
-
<div class="patches-applied">
|
3
|
-
<i class="icon icon-reload"></i> Patches applied (<%= RedmineExtensions::PatchManager.reloadable_patches_applied %>x)
|
4
|
-
</div>
|
5
|
-
|
6
|
-
<style>
|
7
|
-
.patches-applied {
|
8
|
-
position: fixed;
|
9
|
-
bottom: 0;
|
10
|
-
left: 0;
|
11
|
-
padding: 2px 10px;
|
12
|
-
background: #f44336;
|
13
|
-
border-top: 1px solid #b71c1c;
|
14
|
-
border-right: 1px solid #b71c1c;
|
15
|
-
animation: patches-applied-pulse 2s 5;
|
16
|
-
color: #fff;
|
17
|
-
z-index: 9999999;
|
18
|
-
}
|
19
|
-
|
20
|
-
@keyframes patches-applied-pulse {
|
21
|
-
0% {
|
22
|
-
box-shadow: 0 0 0 0 rgba(229, 115, 115, 0.4);
|
23
|
-
}
|
24
|
-
70% {
|
25
|
-
box-shadow: 0 0 0 20px rgba(229, 115, 115, 0);
|
26
|
-
}
|
27
|
-
100% {
|
28
|
-
box-shadow: 0 0 0 0 rgba(229, 115, 115, 0);
|
29
|
-
}
|
30
|
-
}
|
31
|
-
</style>
|
32
|
-
<% end %>
|
33
|
-
|
@@ -1,7 +0,0 @@
|
|
1
|
-
<% if params[:jasmine] %>
|
2
|
-
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine.js"></script>
|
3
|
-
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine-html.js"></script>
|
4
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/3.1.0/jasmine.css">
|
5
|
-
<%= javascript_include_tag('redmine_extensions/jasmine_lib/jasmine_lib.js') %>
|
6
|
-
<%= stylesheet_link_tag('redmine_extensions/jasmine.css') %>
|
7
|
-
<% end %>
|
@@ -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
|