Initial Redmine tooling and local plugin forks
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
<%= contact_tag(contact, :id => "customer_send_tag") %>
|
||||
(<%= contact_email %>)
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<% if !@issue.blank? && User.current.allowed_to?(:view_helpdesk_tickets, @project) %>
|
||||
<span id="cusomer_profile_and_issues">
|
||||
<div id="customer_profile">
|
||||
<div class="contextual">
|
||||
<%= link_to l(:button_update),
|
||||
{:controller => 'helpdesk_tickets',
|
||||
:action => 'edit',
|
||||
:issue_id => @issue},
|
||||
:remote => true if User.current.allowed_to?(:edit_helpdesk_tickets, @project) %>
|
||||
|
||||
</div>
|
||||
<h3><%= l(:label_helpdesk_contact) %></h3>
|
||||
<% unless !(@show_form == "true") %>
|
||||
<%= form_for @helpdesk_ticket, :url => {:controller => 'helpdesk_tickets',
|
||||
:action => 'update',
|
||||
:issue_id => @issue},
|
||||
:html => {:id => 'ticket_data_form',
|
||||
:method => :put} do |f| %>
|
||||
|
||||
<% unless @helpdesk_ticket.new_record? %>
|
||||
<div class="contextual">
|
||||
<%= link_to image_tag('link_break.png'),
|
||||
{:controller => 'helpdesk_tickets', :action => 'destroy', :id => @helpdesk_ticket},
|
||||
:method => :delete,
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:title => l(:label_relation_delete) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<p class="contact_auto_complete"><%= label_tag :helpdesk_ticket_contact_id, l(:label_helpdesk_contact)%><br>
|
||||
<%= select_contact_tag('helpdesk_ticket[contact_id]', @helpdesk_ticket.customer, :is_select => Contact.visible.by_project(ContactsSetting.cross_project_contacts? ? nil : @project).count < 50, :include_blank => false, :add_contact => true, :display_field => @helpdesk_ticket.customer.blank?) %>
|
||||
</p>
|
||||
|
||||
<p><%= label_tag :helpdesk_ticket_source, l(:label_helpdesk_ticket_source)%><br>
|
||||
<%= f.select :source, helpdesk_tickets_source_for_select %></p>
|
||||
|
||||
<p><%= f.text_field :ticket_date, :size => 12, :required => true, :value => @helpdesk_ticket.ticket_date.to_date, :label => l(:label_helpdesk_ticket_date) %> <%= f.text_field :ticket_time, :value => @helpdesk_ticket.ticket_date.to_s(:time), :size => 5 %><%= calendar_for('helpdesk_ticket_ticket_date') %> </p>
|
||||
|
||||
<p>
|
||||
<%= label_tag :helpdesk_ticket_cc_address, l(:label_helpdesk_cc_address) %><br>
|
||||
<% @cc_address = @helpdesk_ticket.cc_address.try(:split, ',') || [] %>
|
||||
<%= f.select :cc_address, options_for_select(@cc_address.map { |email|[email, email] }, @cc_address), {}, {:multiple => true } %>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
<%= submit_tag l(:button_update) %>
|
||||
<%= link_to l(:button_cancel), {}, :onclick => "$('#ticket_data_form').hide(); return false;" %>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
<span class="small-card">
|
||||
<%= render :partial => 'contacts/contact_card', :object => @issue.customer if @issue.customer %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<% if @issue.customer && (customer_issues = @issue.customer.all_tickets.preload(:status, :tracker, :helpdesk_ticket).visible.order_by_status.to_a).count - 1 > 0 %>
|
||||
<div id="customer_previous_issues">
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_helpdesk_all) + " (#{customer_issues.count})", {:controller => 'issues',
|
||||
:action => 'index',
|
||||
:set_filter => 1,
|
||||
:f => [:customer, :status_id],
|
||||
:v => {:customer => [@issue.customer.id]},
|
||||
:op => {:customer => '=', :status_id => '*'}} %>
|
||||
</div>
|
||||
|
||||
<h3><%= l(:label_helpdesk_contact_activity) %> </h3>
|
||||
|
||||
<ul>
|
||||
<% (customer_issues.first(5)).each do |issue| %>
|
||||
<li title="<%= "#{issue.tracker} (#{issue.status})" if issue.tracker && issue.status %>" >
|
||||
<span class="icon <%= helpdesk_ticket_source_icon(issue.helpdesk_ticket) %>"></span>
|
||||
<span class="ticket-title <%= 'selected' if @issue == issue %>">
|
||||
<%= link_to_issue(issue, :truncate => 60, :project => (@project != issue.project), :tracker => false) %>
|
||||
</span>
|
||||
<span class="ticket-meta">
|
||||
<%= format_time(issue.created_on) %>
|
||||
<%= "- #{issue.assigned_to.name}" if issue.assigned_to %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
</span>
|
||||
<% end %>
|
||||
@@ -0,0 +1,6 @@
|
||||
<% if @project && @project.module_enabled?(:contacts_helpdesk)%>
|
||||
<h3><%= l(:label_helpdesk_reports) %></h3>
|
||||
<%= link_to l(:label_helpdesk_first_response_time), project_helpdesk_reports_path(@project, :report => 'first_response_time') %>
|
||||
<br>
|
||||
<%= link_to l(:label_helpdesk_busiest_time_of_day), project_helpdesk_reports_path(@project, :report => 'busiest_time_of_day') %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,154 @@
|
||||
<% if authorize_for(:issues, :send_helpdesk_response) && @issue.customer && @issue.customer.primary_email %>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
function emailTagResult (opt) {
|
||||
if (opt.name){
|
||||
var formated_tag = $('<span>' + opt.avatar + ' ' + opt.text + '</span>');;
|
||||
} else {
|
||||
var formated_tag = opt.text;
|
||||
}
|
||||
return formated_tag
|
||||
};
|
||||
function emailTagSelection (opt) {
|
||||
if (opt.name){
|
||||
var formated_tag = opt.name + ' <' + opt.email + '>';
|
||||
} else {
|
||||
var formated_tag = opt.text;
|
||||
}
|
||||
return formated_tag
|
||||
};
|
||||
$(document).ready(function() {
|
||||
toggleSendMail($('#helpdesk_is_send_mail').get(0));
|
||||
var select2_fields = ['#helpdesk_to', '#helpdesk_cc', '#helpdesk_bcc'];
|
||||
$.each(select2_fields, function(index, field){
|
||||
$(field).select2({
|
||||
ajax: {
|
||||
url: '<%= auto_complete_contacts_path(:project_id => (ContactsSetting.cross_project_contacts? ? nil : @project), :is_company => nil) %>',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function (params) {
|
||||
return { q: params.term };
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
return { results: $.grep(data, function(elem){ elem.id = elem.email; return elem }) };
|
||||
},
|
||||
cache: true
|
||||
},
|
||||
tags: true,
|
||||
placeholder: ' ',
|
||||
minimumInputLength: 1,
|
||||
width: '60%',
|
||||
templateResult: emailTagResult,
|
||||
templateSelection: emailTagSelection,
|
||||
}).on('select2:open', function (e) {
|
||||
$(field).closest('.cc-list-edit').find('.select2-search__field').val(' ').trigger($.Event('input', { which: 13 })).val('');
|
||||
});
|
||||
});
|
||||
|
||||
$('#email_footer').insertAfter($('#helpdesk_is_send_mail').parents().eq(1).find('.jstEditor'));
|
||||
$('#email_header').insertBefore($('#helpdesk_is_send_mail').parents().eq(1).find('>legend'));
|
||||
$('#email_canned_responses').insertBefore($('#helpdesk_is_send_mail').parents().eq(1).find('>legend'));
|
||||
});
|
||||
|
||||
var issue_status = $('#issue_status_id').val();
|
||||
|
||||
function toggleSendMail(element) {
|
||||
if (element.checked) {
|
||||
$('.email-template').show();
|
||||
<% unless HelpdeskSettings["helpdesk_answered_status", @project].blank? %>
|
||||
issue_status = $('#issue_status_id').val();
|
||||
$('#issue_status_id').val("<%= HelpdeskSettings["helpdesk_answered_status", @project] %>");
|
||||
<% end %>
|
||||
<% if @issue.assigned_to.blank? %>
|
||||
$('#issue_assigned_to_id').val("<%= User.current.id %>");
|
||||
<% end %>
|
||||
|
||||
} else {
|
||||
$('.email-template').hide();
|
||||
$('#cc_list_edit').hide();
|
||||
$('#helpdesk_is_cc').val("");
|
||||
<% unless HelpdeskSettings["helpdesk_answered_status", @project].blank? %>
|
||||
$('#issue_status_id').val(issue_status);
|
||||
<% end %>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateCannedResposeFrom(url, value) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'post',
|
||||
data: {id: value}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<% canned_responses = CannedResponse.visible.in_project_or_public(@project) %>
|
||||
<% if canned_responses.any? %>
|
||||
<span id="email_canned_responses" style="display: none; float:right;" class="email-template">
|
||||
<%= select_tag 'helpdesk[canned_response]', options_for_select([[ "--- #{l(:label_helpdesk_canned_response_plural)} ---", '' ]] + canned_responses.order("#{CannedResponse.table_name}.name").map{|cr| [cr.name, cr.id]}), :onchange => "updateCannedResposeFrom('#{escape_javascript add_canned_responses_path(:project_id => @project, :issue_id => @issue, :format => 'js')}', $(this).val())" %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<% unless HelpdeskSettings["helpdesk_emails_header", @project].blank? %>
|
||||
<div id="email_header" style="display: none;" class="email-template">
|
||||
<%= textilizable(HelpdeskMailer.apply_macro(HelpdeskSettings["helpdesk_emails_header", @project], @issue.customer, @issue, User.current)).html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% unless HelpdeskSettings["helpdesk_emails_footer", @project].blank? %>
|
||||
<div id="email_footer" style="display: none;" class="email-template">
|
||||
<%= textilizable(HelpdeskMailer.apply_macro(HelpdeskSettings["helpdesk_emails_footer", @project], @issue.customer, @issue, User.current)).html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<p id="helpdesk_send_response">
|
||||
<%= check_box_tag 'helpdesk[is_send_mail]', 1, HelpdeskSettings["send_note_by_default", @project], :onclick => "toggleSendMail(this);" %>
|
||||
<%= label_tag :helpdesk_is_send_mail, l(:label_is_send_mail), :class => "icon icon-email-to", :style => "" %>
|
||||
|
||||
<span id="journal_contacts" style="display: none;" class="email-template">
|
||||
<span id="customer_to_email" class="email-template">
|
||||
<%= render :partial => "issues/customer_to_email", :locals => {:contact => Contact.where(:email => @issue.helpdesk_ticket.default_to_address).first || @issue.customer, :contact_email => @issue.helpdesk_ticket.default_to_address } %>
|
||||
</span>
|
||||
<a href="#" class="inline-edit email-template" onclick="$('#customer_to_email').hide(); $(this).hide(); $('#cc_list_edit').show(); return false;"><img alt="Edit" src="/images/edit.png" style="vertical-align:middle;" ></a>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div id="cc_list_edit" style="display:none;">
|
||||
<% contact_emails = ((@issue.helpdesk_ticket.cc_address.to_s.split(',') + @issue.helpdesk_ticket.response_addresses).uniq.map { |email| [email, email] } + (@issue.contacts + [@issue.customer]).uniq.map{ |contact| [contact.email_name, contact.primary_email] }).uniq(&:last) %>
|
||||
<%= hidden_field_tag 'helpdesk[is_cc]' %>
|
||||
<p class="cc-list-edit">
|
||||
<span class="is-cc">
|
||||
<%= label_tag l(:label_helpdesk_to) %>
|
||||
</span>
|
||||
<%= select_tag 'journal_message[to_address]', options_for_select(contact_emails, @issue.helpdesk_ticket.default_to_address), :id => "helpdesk_to", :multiple => true %>
|
||||
</p>
|
||||
<p class="cc-list-edit">
|
||||
<span class="is-cc">
|
||||
<%= label_tag l(:label_helpdesk_cc) %>
|
||||
</span>
|
||||
<%= select_tag 'journal_message[cc_address]', options_for_select(contact_emails, @issue.customer.primary_email != @issue.helpdesk_ticket.default_to_address ? @issue.customer.primary_email : @issue.helpdesk_ticket.cc_addresses), :id => "helpdesk_cc", :multiple => true %>
|
||||
</p>
|
||||
<div style="clear: both;"></div>
|
||||
<p class="cc-list-edit">
|
||||
<span class="is-cc">
|
||||
<%= label_tag l(:label_helpdesk_bcc) %>
|
||||
</span>
|
||||
<%= select_tag 'journal_message[bcc_address]', nil, :id => "helpdesk_bcc", :multiple => true %>
|
||||
</p>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag :redmine_helpdesk, :plugin => 'redmine_contacts_helpdesk' %>
|
||||
<%= stylesheet_link_tag :helpdesk, :plugin => 'redmine_contacts_helpdesk' %>
|
||||
<% end %>
|
||||
|
||||
<% if authorize_for(:issues, :send_helpdesk_response) && @issue.customer && @issue.customer.primary_email %>
|
||||
<%= javascript_tag do %>
|
||||
$('#content .contextual:first a:first').before('<%= helpdesk_reply_link %>')
|
||||
$('#content .contextual:last a:first').before('<%= helpdesk_reply_link %>')
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,56 @@
|
||||
<% if User.current.allowed_to?(:view_helpdesk_tickets, @project) && @issue.is_ticket? %>
|
||||
<div id="ticket_data">
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_helpdesk_public_link), public_ticket_path(@issue.helpdesk_ticket, :hash => @issue.helpdesk_ticket.token), :class => "icon icon-public-link" if RedmineHelpdesk.public_tickets? && !@issue.is_private %>
|
||||
<%# link_to l(:label_helpdesk_spam),
|
||||
{:controller => 'helpdesk',
|
||||
:action => 'delete_spam',
|
||||
:project_id => @project,
|
||||
:issue_id => @issue},
|
||||
:method => :delete,
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:class => "icon icon-email-spam" if @issue.helpdesk_ticket.source == HelpdeskTicket::HELPDESK_EMAIL_SOURCE && @issue.customer.primary_email && User.current.allowed_to?(:send_response, @project) && User.current.allowed_to?(:delete_issues, @project) && User.current.allowed_to?(:delete_contacts, @project) %>
|
||||
</div>
|
||||
<span class="icon <%= helpdesk_ticket_source_icon(@issue.helpdesk_ticket) %>", title="<%= l(:label_helpdesk_to_address) %>: <%= @issue.helpdesk_ticket.to_address %>">
|
||||
<%= @issue.helpdesk_ticket.is_incoming? ? l(:label_helpdesk_from) : l(:label_sent_to) %>
|
||||
</span>
|
||||
<span class="ticket_customer" style="white-space: nowrap;display: inline-block;">
|
||||
<%= contact_tag(@issue.customer, :type => "plain") %>
|
||||
(<%= @issue.helpdesk_ticket.from_address %>)
|
||||
</span>
|
||||
<% if attachment = @issue.helpdesk_ticket.message_file %>
|
||||
<span class="attachment" style="white-space: nowrap;display: inline-block;">
|
||||
<%= link_to_attachment attachment, :text => l(:label_helpdesk_original), :download => true, :class => 'icon icon-attachment' -%>
|
||||
<%= h(" - #{attachment.description}") unless attachment.description.blank? %>
|
||||
<span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
|
||||
<%= link_to_if_authorized image_tag('magnifier.png', :plugin => "redmine_contacts_helpdesk"),
|
||||
:controller => 'helpdesk', :action => 'show_original',
|
||||
:id => attachment, :project_id => @project %>
|
||||
</span>
|
||||
<% end %>
|
||||
<span class="helpdesk-message-date"><%= format_time(@issue.helpdesk_ticket.ticket_date) %></span>
|
||||
<br>
|
||||
<% unless @issue.helpdesk_ticket.cc_address.blank? %>
|
||||
<span class="helpdesk-message-date"><%= l(:label_helpdesk_cc) %>: <%= @issue.helpdesk_ticket.cc_address.split(',').join(', ') %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if Redmine::VERSION.to_s > '3.2' %>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$(".attributes").first().prepend($("#ticket_data"));
|
||||
$("#ticket_data").after("<hr>");
|
||||
});
|
||||
</script>
|
||||
<% else %>
|
||||
<hr />
|
||||
<% end %>
|
||||
|
||||
<%= issue_fields_rows do |rows|
|
||||
rows.left l(:label_helpdesk_ticket_reaction_time), distance_of_time_in_words(@issue.helpdesk_ticket.reaction_time, 0, :include_seconds => true) if @issue.helpdesk_ticket.reaction_time
|
||||
rows.left l(:label_helpdesk_ticket_resolve_time), distance_of_time_in_words(@issue.helpdesk_ticket.resolve_time, 0, :include_seconds => true) if @issue.helpdesk_ticket.resolve_time
|
||||
rows.right l(:label_helpdesk_contact_vote), show_customer_vote(@issue.helpdesk_ticket.vote, @issue.helpdesk_ticket.vote_comment) if @issue.helpdesk_ticket.vote && @issue.helpdesk_ticket.vote >= 0
|
||||
rows.right l(:label_helpdesk_ticket_first_response_time), distance_of_time_in_words(@issue.helpdesk_ticket.first_response_time, 0, :include_seconds => true) if @issue.helpdesk_ticket.first_response_time
|
||||
rows.right l(:label_helpdesk_ticket_last_response_time), distance_of_time_in_words(@issue.helpdesk_ticket.last_response_time, Time.now.utc) if @issue.helpdesk_ticket.last_response_time
|
||||
end %>
|
||||
|
||||
<% end %>
|
||||
@@ -0,0 +1,26 @@
|
||||
<% if @issue.new_record? && !@copy_from && User.current.allowed_to?(:edit_helpdesk_tickets, @project) && (@issue.tracker_id.to_s == HelpdeskSettings["helpdesk_tracker", @project.id] || HelpdeskSettings["helpdesk_tracker", @project.id] == 'all') %>
|
||||
<div class="email-template">
|
||||
<% @issue.build_helpdesk_ticket if @issue.helpdesk_ticket.blank? %>
|
||||
<%= form.fields_for :helpdesk_ticket do |f| %>
|
||||
<div class="splitcontentleft">
|
||||
<p><%= f.label_for_field("issue_helpdesk_ticket_attributes_contact_id_selected_contact", :label => l(:label_helpdesk_contact), :required => true) %>
|
||||
<%= select_contact_tag('issue[helpdesk_ticket_attributes][contact_id]', @issue.helpdesk_ticket.try(:customer), :is_select => Contact.visible.by_project(ContactsSetting.cross_project_contacts? ? nil : @project).count < 50, :include_blank => true, :add_contact => true, :display_field => @issue.helpdesk_ticket.try(:customer).blank?) %>
|
||||
</p>
|
||||
|
||||
<p class="required">
|
||||
<%= f.text_field :ticket_date, :label => l(:label_helpdesk_ticket_date), :size => 12, :value => @issue.helpdesk_ticket.ticket_date.to_date %>
|
||||
<%= f.text_field :ticket_time, :size => 5, :no_label => true, :value => @issue.helpdesk_ticket.ticket_date.to_s(:time) %><%= calendar_for('issue_helpdesk_ticket_attributes_ticket_date') %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="splitcontentright">
|
||||
<p><%= f.select :source, helpdesk_tickets_source_for_select, :label => l(:label_helpdesk_ticket_source) %></p>
|
||||
<p><%= label_tag :helpdesk_send_as, l(:label_helpdesk_send_as)%>
|
||||
<%= select_tag :helpdesk_send_as, options_for_select(helpdesk_send_as_for_select, params[:helpdesk_send_as]) %> </p>
|
||||
</div>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
Reference in New Issue
Block a user