Skip to content

Commit 4c083dc

Browse files
committed
first commit
0 parents  commit 4c083dc

15 files changed

+308
-0
lines changed

MIT-LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2009 [name of plugin creator]
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
RemoteTicketSupport
2+
===================
3+
4+
Simple plugin that shows how to create tickets from remote domains using jsonp. Dependent on engines plugin. See 'sample/report.html' for client html code.
5+
6+
Simple drop this plugin into your redmine vendor/plugins dir, and copy content of sample/report.html to your client site. Please note to modify host domain, in my case its 192.168.1.34. The html is required prototype and calendar.js to run, its not really that hard to clear this dependencies.
7+
8+
Rails 2.0 and 2.3: There are bug with ActiveSupport, have to patch it https://rails.lighthouseapp.com/projects/8994/tickets/1956-json-validations-errors-for-activeresource
9+
10+
Copyright (c) 2009 RustamG, released under the MIT license

Rakefile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require 'rake'
2+
require 'rake/testtask'
3+
require 'rake/rdoctask'
4+
5+
desc 'Default: run unit tests.'
6+
task :default => :test
7+
8+
desc 'Test the remote_ticket_support plugin.'
9+
Rake::TestTask.new(:test) do |t|
10+
t.libs << 'lib'
11+
t.pattern = 'test/**/*_test.rb'
12+
t.verbose = true
13+
end
14+
15+
desc 'Generate documentation for the remote_ticket_support plugin.'
16+
Rake::RDocTask.new(:rdoc) do |rdoc|
17+
rdoc.rdoc_dir = 'rdoc'
18+
rdoc.title = 'RemoteTicketSupport'
19+
rdoc.options << '--line-numbers' << '--inline-source'
20+
rdoc.rdoc_files.include('README')
21+
rdoc.rdoc_files.include('lib/**/*.rb')
22+
end
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
class RemoteIssuesController < ActionController::Base
2+
3+
include ApplicationHelper
4+
helper ApplicationHelper
5+
6+
def create_remotely
7+
8+
@project = Project.find(params[:project_id])
9+
10+
if @project.nil?
11+
render :json => 'Project not found.'.to_json, :callback => params[:callback]
12+
return
13+
end
14+
15+
@issue = Issue.new
16+
@issue.copy_from(params[:copy_from]) if params[:copy_from]
17+
@issue.project = @project
18+
# Tracker must be set before custom field values
19+
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
20+
if @issue.tracker.nil?
21+
render :json => 'No tracker is associated to this project. Please check the Project settings.'.to_json, :callback => params[:callback]
22+
return
23+
end
24+
if params[:issue].is_a?(Hash)
25+
@issue.attributes = params[:issue]
26+
@issue.watcher_user_ids = params[:issue]['watcher_user_ids'] if User.current.allowed_to?(:add_issue_watchers, @project)
27+
end
28+
@issue.author = User.current
29+
30+
default_status = IssueStatus.default
31+
unless default_status
32+
render :json => 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'.to_json, :callback => params[:callback]
33+
return
34+
end
35+
@issue.status = default_status
36+
@allowed_statuses = ([default_status]).uniq
37+
38+
#if request.get? || request.xhr?
39+
if params[:callback].nil?
40+
@issue.start_date ||= Date.today
41+
else
42+
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
43+
# Check that the user is allowed to apply the requested status
44+
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
45+
if @issue.save
46+
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
47+
render :json => l(:notice_successful_create).to_json, :callback => params[:callback]
48+
return
49+
else
50+
render :json => @issue.errors.to_json, :callback => params[:callback]
51+
return
52+
end
53+
end
54+
@priorities = Enumeration::get_values('IPRI')
55+
end
56+
57+
end

app/views/remote_issues/_form.rhtml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
<h2><%=l(:label_issue_new)%></h2>
3+
4+
<% labelled_tabular_form_for :issue, @issue,
5+
:html => {:multipart => true, :id => 'issue-form', :onsubmit=>"sendJSONP('http://#{ request.env['HTTP_X_FORWARDED_SERVER'].blank? ? request.env['HTTP_HOST'] : request.env['HTTP_X_FORWARDED_SERVER'] }/projects/identifier/create_issue_remotely?id_of_html_block=#{ params[:id_of_html_block] }&'+Form.serialize('issue-form'), 'loadit'); return false"} do |f| %>
6+
<%= error_messages_for 'issue' %>
7+
<div class="box">
8+
9+
<% if issue.new_record? %>
10+
<p><%= f.select :tracker_id, project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
11+
<%= observe_field :issue_tracker_id, :url => { :action => :new },
12+
:update => :content,
13+
:with => "Form.serialize('issue-form')" %>
14+
<hr />
15+
<% end %>
16+
17+
<div id="issue_descr_fields" <%= 'style="display:none"' unless issue.new_record? || issue.errors.any? %>>
18+
<p><%= f.text_field :subject, :size => 80, :required => true %></p>
19+
<p><%= f.text_area :description,
20+
:cols => 60,
21+
:rows => (issue.description.blank? ? 10 : [[10, issue.description.length / 50].max, 100].min),
22+
:accesskey => accesskey(:edit),
23+
:class => 'wiki-edit' %></p>
24+
</div>
25+
26+
<div class="splitcontentleft">
27+
<% if issue.new_record? || allowed_statuses.any? %>
28+
<% unless allowed_statuses.nil? %>
29+
<p><%= f.select :status_id, (allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
30+
<% end %>
31+
<% else %>
32+
<p><label><%= l(:field_status) %></label> <%= issue.status.name %></p>
33+
<% end %>
34+
35+
<p><%= f.select :priority_id, (priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
36+
<p><%= f.select :assigned_to_id, (issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
37+
<% unless project.issue_categories.empty? %>
38+
<p><%= f.select :category_id, (project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
39+
<%= prompt_to_remote(l(:label_issue_category_new),
40+
l(:label_issue_category_new), 'category[name]',
41+
{:controller => 'projects', :action => 'add_issue_category', :id => project},
42+
:class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
43+
<% end %>
44+
<%= content_tag('p', f.select(:fixed_version_id,
45+
(project.versions.sort.collect {|v| [v.name, v.id]}),
46+
{ :include_blank => true })) unless project.versions.empty? %>
47+
</div>
48+
49+
<div class="splitcontentright">
50+
<p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
51+
<p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
52+
<p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
53+
<p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
54+
</div>
55+
56+
<div style="clear:both;"> </div>
57+
<%= render :partial => 'form_custom_fields', :locals => {:issue => issue} %>
58+
59+
60+
61+
<% if issue.new_record? -%>
62+
<p><label><%= l(:label_issue_watchers) %></label>
63+
<% issue.project.users.sort.each do |user| -%>
64+
<label class="floating"><%= check_box_tag 'issue[watcher_user_ids][]', user.id, issue.watcher_user_ids.include?(user.id) %> <%=h user %></label>
65+
<% end -%>
66+
</p>
67+
<% end %>
68+
69+
<%= call_hook(:view_issues_form_details_bottom, { :issue => issue, :form => f }) %>
70+
71+
72+
73+
74+
75+
</div>
76+
77+
<input name="commit" value="Create" type="submit" id="button_submitton">
78+
79+
80+
<%= javascript_tag "Form.Element.focus('issue_subject');" %>
81+
<% end %>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div class="splitcontentleft">
2+
<% i = 0 %>
3+
<% split_on = issue.custom_field_values.size / 2 %>
4+
<% issue.custom_field_values.each do |value| %>
5+
<p><%= custom_field_tag_with_label :issue, value %></p>
6+
<% if i == split_on -%>
7+
</div><div class="splitcontentright">
8+
<% end -%>
9+
<% i += 1 -%>
10+
<% end -%>
11+
</div>
12+
<div style="clear:both;"> </div>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
3+
// callback
4+
function loadit(data) {
5+
// работаем с данными
6+
if (!data) {
7+
return;
8+
}
9+
10+
var oTotal = document.getElementById("<%= params[:id_of_html_block] %>");
11+
oTotal.innerHTML = data;//.ResultSet.totalResultsAvailable;
12+
13+
}
14+
15+
// здесь будет ссылка на новый элемент script
16+
var oElem = null;
17+
18+
function sendJSONP(url, callback) {
19+
20+
if (!url || !callback)
21+
return;
22+
23+
url += '&callback='+callback;
24+
25+
// выполняем запрос JSONP
26+
if (oElem) {
27+
oElem.parentNode.removeChild(oElem);
28+
}
29+
30+
oElem = document.createElement('script');
31+
oElem.setAttribute('type','text/javascript');
32+
document.getElementsByTagName('head')[0].appendChild(oElem);
33+
oElem.setAttribute('src', url);
34+
}
35+
36+
function loadForm(){
37+
38+
<% update_page do |page| %>
39+
<%= page.replace_html params[:id_of_html_block], :partial => 'form', :object => @issue, :locals => {:issue => @issue, :project => @project, :allowed_statuses => @allowed_statuses, :priorities => @priorities} %>
40+
<% end %>
41+
return false;
42+
43+
}
44+
45+
window.onload = function(){
46+
47+
document.getElementById("reportBtn").onclick = function(){
48+
if (document.getElementById("<%= params[:id_of_html_block] %>").style.display == 'none')
49+
document.getElementById("<%= params[:id_of_html_block] %>").style.display = 'block';
50+
loadForm();
51+
}
52+
53+
loadForm();
54+
55+
}

init.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Include hook code here
2+
require 'remote_ticket_support'

install.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Install hook code here

lib/remote_ticket_support.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RemoteTicketSupport
2+
=begin
3+
%w{ controllers }.each do |dir|
4+
path = File.join(File.dirname(__FILE__), 'app', dir)
5+
$LOAD_PATH << path
6+
ActiveSupport::Dependencies.load_paths << path
7+
ActiveSupport::Dependencies.load_once_paths.delete(path)
8+
end
9+
=end
10+
# doesnt needed since redmine using engines plugin's route inclusion method
11+
#require "remote_ticket_support/routing"

lib/routing.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# this file isnt needed anymore
2+
module RemoteTicketSupport #:nodoc:
3+
module Routing #:nodoc:
4+
module MapperExtensions
5+
def create_remotely
6+
@set.add_route("/projects/:project_id/create_issue_remotely", {:controller => "issues_controller", :action => "create_remotely"})
7+
end
8+
9+
end
10+
11+
end
12+
13+
end
14+
ActionController::Routing::RouteSet::Mapper.send :include, RemoteTicketSupport::Routing::MapperExtensions

routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
connect '/projects/:project_id/create_issue_remotely', :controller => 'remote_issues', :action => "create_remotely"

sample/report.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<html>
2+
<head>
3+
<script src="http://www.prototypejs.org/javascripts/prototype.js" type="text/javascript"></script>
4+
<script src="http://192.168.1.34/javascripts/calendar/calendar.js?1248714700" type="text/javascript"></script><script src="http://192.168.1.34/javascripts/calendar/lang/calendar-en.js?1248714704" type="text/javascript"></script><script src="http://192.168.1.34/javascripts/calendar/calendar-setup.js?1248714700" type="text/javascript"></script><link href="http://192.168.1.34/stylesheets/calendar.css?1248714720" media="screen" rel="stylesheet" type="text/css" />
5+
6+
</head>
7+
<body>
8+
<p>This is example of remote issue creating. Put hits file onto other domain and press the button.</p>
9+
10+
<script type="text/javascript" src="http://192.168.1.34/projects/identifier/create_issue_remotely?id_of_html_block=some_div_id"></script>
11+
<div id="some_div_id" style="display:none;"></div>
12+
<Br/><br/>
13+
<form>
14+
<input type=button value="Report" id="reportBtn">
15+
</form>
16+
</body>
17+
</html>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# desc "Explaining what the task does"
2+
# task :remote_ticket_support do
3+
# # Task goes here
4+
# end

uninstall.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Uninstall hook code here

0 commit comments

Comments
 (0)