redmine_extensions 0.4.4 → 0.6.0
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 +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
|