");
- } else
- {
+ } else {
$('html').find("#errorExplanation").html(error.html());
}
+
/* data updated, remove spin and add success icon for 2sec */
- setTimeout(function(){
+ setTimeout(function() {
$('.details .' + cssClass + ' i.fa-spin').removeClass('fa-refresh fa-spin').addClass('fa-times statusKo');
- setTimeout(function(){
+ setTimeout(function() {
$('.details .' + cssClass + ' i.fa-times.statusKo').remove();
}, 2000);
}, 500);
- jQuery.ajax({
- type: 'GET',
- url: LOCATION_HREF,
- data: { "authenticity_token" : token },
- crossDomain: true,
- async: false,
- beforeSend: function(xhr) {
- xhr.setRequestHeader("authenticity_token", token);
- },
- success: function(msg) {
- parsed = $.parseHTML(msg);
- }
- });
+ jQuery.ajax({
+ type: 'GET',
+ url: LOCATION_HREF,
+ data: { "authenticity_token" : token },
+ crossDomain: true,
+ async: false,
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader("authenticity_token", token);
+ },
+ success: function(msg) {
+ parsed = $.parseHTML(msg);
+ }
+ });
} else {
-
/* removing error div if exists */
$('html').find("#errorExplanation").remove();
-
}
-
- /* we update the details block */
- $('div.issue.details').html($(parsed).find('div.issue.details').html());
- $('body').find('.details .' + cssClass + ' .value').append(' ');
-
- /* we update form*/
- $('form#issue-form').html($(parsed).find('form#issue-form').html());
- /* we update issue properties edit block */
- $('#all_attributes').html($(parsed).find('#all_attributes').html());
+ /* we update the details block */
+ $('div.issue.details').html( $(parsed).find('div.issue.details').html() );
+ $('body').find('.details .' + cssClass + ' .value').append(' ');
- /* we init edit fields */
- initEditFields();
- initEditFieldListeners();
-
- if($(parsed).find('#required_field_array').length) {
- updateRequiredFields(JSON.parse($(parsed).find('#required_field_array').html()));
- }
-
- /* we update the history list */
- $('#history').append($(parsed).find('#history .journal.has-details:last-child'));
+ /* we update form*/
+ $('form#issue-form').html( $(parsed).find('form#issue-form').html() );
- /* data updated, remove spin and add success icon for 2sec */
+ /* we update issue properties edit block */
+ $('#all_attributes').html( $(parsed).find('#all_attributes').html() );
+
+ /* we init edit fields */
+ initEditFields();
+ initEditFieldListeners();
+
+ if ($(parsed).find('#required_field_array').length) {
+ updateRequiredFields(JSON.parse($(parsed).find('#required_field_array').html()));
+ }
+
+ /* we update the history list */
+ $('#history').append($(parsed).find('#history .journal.has-details:last-child'));
+
+ /* data updated, remove spin and add success icon for 2sec */
+ setTimeout(function(){
+ $('.details .' + cssClass + ' i.fa-spin').removeClass('fa-refresh fa-spin').addClass('fa-check statusOk');
setTimeout(function(){
- $('.details .' + cssClass + ' i.fa-spin').removeClass('fa-refresh fa-spin').addClass('fa-check statusOk');
- setTimeout(function(){
- $('.details .' + cssClass + ' i.fa-check.statusOk').remove();
- }, 2000);
- }, 500);
+ $('.details .' + cssClass + ' i.fa-check.statusOk').remove();
+ }, 2000);
+ }, 500);
- //set datepicker fallback for input type date
- if( $('body').find('input[type=date]').length
- && $('body').find('input[type=date]').datepickerFallback instanceof Function
- && typeof datepickerOptions !== 'undefined')
- {
- $('body').find('input[type=date]').datepickerFallback(datepickerOptions);
- }
-
+ //set datepicker fallback for input type date
+ if (
+ $('body').find('input[type=date]').length &&
+ $('body').find('input[type=date]').datepickerFallback instanceof Function &&
+ typeof datepickerOptions !== 'undefined'
+ ) {
+ $('body').find('input[type=date]').datepickerFallback(datepickerOptions);
+ }
},
- error: function(xhr, msg, error) {
+ error: function(xhr, msg, error) {
/* error and no update, info logged into console */
console.log('%c -------- Error while updating the issue attribute dynamically -------- ', 'background: #ff0000; color: white; font-weight:900');
console.log('%c xhr data: ', 'background: black; color: white;');
@@ -372,98 +408,99 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
console.log('%c error data: ', 'background: black; color: white;');;
console.log(error);
console.log('%c ---------------------------------------------------------- ', 'background: #ff0000; color: white; font-weight:900');
+
$('.details .' + cssClass + ' i.fa-spin').removeClass('fa-refresh fa-spin').addClass('fa-times').html(" " + _TXT_ERROR_AJAX_CALL);
- setTimeout(function(){
- $('.details .' + cssClass + ' i.fa-times').remove();
- }, 2000);
+ setTimeout(function(){
+ $('.details .' + cssClass + ' i.fa-times').remove();
+ }, 2000);
}
- });
+ });
};
/* Listeners foreach attribute */
-function initEditFieldListeners()
-{
- var domSelectStatus = $('body').find('#statusListDropdown select');
- domSelectStatus.on('change', function(e){
+function initEditFieldListeners() {
+ var domSelectStatus = $('body').find('#statusListDropdown select');
+ domSelectStatus.on('change', function(e) {
issueDynamicUpdate('status_id', domSelectStatus.val(), 'select', 'status');
/* update the classes status from */
$("#content > div.issue").removeClass(function (index, className) {
return (className.match (/(^|\s)status-\S+/g) || []).join(' ');
}).addClass('status-' + domSelectStatus.val());
- }); /* end on change domSelectStatus */
-
- var domSelectPriorities = $('body').find('#prioritiesListDropdown select');
- domSelectPriorities.on('change', function(e){
+ }); /* end on change domSelectStatus */
+
+ var domSelectPriorities = $('body').find('#prioritiesListDropdown select');
+ domSelectPriorities.on('change', function(e){
issueDynamicUpdate('priority_id', domSelectPriorities.val(), 'select', 'priority');
/* update the classes priority from */
$("#content > div.issue").removeClass(function (index, className) {
return (className.match (/(^|\s)priority-\S+/g) || []).join(' ');
}).addClass('priority-' + domSelectPriorities.val());
- }); /* end on change domSelectPriorities */
-
- var domSelectUsers = $('body').find('#usersListDropdown select');
- domSelectUsers.on('change', function(e){
+ }); /* end on change domSelectPriorities */
+
+ var domSelectUsers = $('body').find('#usersListDropdown select');
+ domSelectUsers.on('change', function(e){
issueDynamicUpdate('assigned_to_id', domSelectUsers.val(), 'select', 'assigned-to');
- }); /* end on change domSelectUsers */
-
- var domSelectRatio = $('body').find('#doneRatioListDropdown select');
- domSelectRatio.on('change', function(e){
+ }); /* end on change domSelectUsers */
+
+ var domSelectRatio = $('body').find('#doneRatioListDropdown select');
+ domSelectRatio.on('change', function(e){
issueDynamicUpdate('done_ratio', domSelectRatio.val(), 'progress', 'progress');
- }); /* end on change domSelectRatio */
-
- var domInputEstimatedTime = $('body').find('#EstimatedTimeInput input');
- $('#EstimatedTimeInput a.btn.validate').on('click', function(e)
- {
+ }); /* end on change domSelectRatio */
+
+ var domInputEstimatedTime = $('body').find('#EstimatedTimeInput input');
+ $('#EstimatedTimeInput a.btn.validate').on('click', function(e) {
e.preventDefault();
$('.estimated-hours .value .error').remove();
var estimatedTime = parseFloat(domInputEstimatedTime.val());
- if(estimatedTime >= 0)
- {
+
+ if (estimatedTime >= 0) {
issueDynamicUpdate('estimated_hours', estimatedTime, 'input', 'estimated-hours');
} else {
/* estimated time must be > 0 */
$('.estimated-hours .value').append(' ' + _TXT_ERROR_POSITIVE_NUMBER + '');
}
+
return false;
- });
-
- domInputEstimatedTime.on('keyup', function(e){
+ });
+
+ domInputEstimatedTime.on('keyup', function(e){
$('.details .attributes .estimated-hours.attribute .selectedValue span').html(
$('.details .attributes .estimated-hours.attribute .value input').val()
);
+
if (e.keyCode == 13) {
$('#EstimatedTimeInput a.btn.validate').click();
}
- });/* end EstimatedTime */
-
- var domInputStartDate = $('body').find('#StartDateInput input');
- $('#StartDateInput a.btn.validate').on('click', function(e)
- {
+ });/* end EstimatedTime */
+
+ var domInputStartDate = $('body').find('#StartDateInput input');
+ $('#StartDateInput a.btn.validate').on('click', function(e) {
e.preventDefault();
$('.start-date .value .error').remove();
- if(new Date(domInputStartDate.val()).getTime() <= new Date($('body').find('#DueDateInput input').val()).getTime() || $('body').find('#DueDateInput input').val() == "")
+ if (new Date(domInputStartDate.val()).getTime() <= new Date($('body').find('#DueDateInput input').val()).getTime() || $('body').find('#DueDateInput input').val() == "")
{
issueDynamicUpdate('start_date', domInputStartDate.val(), 'date', 'start-date');
} else {
/* start date must be < due date */
$('.start-date .value').append(' ' + _TXT_ERROR_START_DATE + '');
}
+
return false;
- });
-
- domInputStartDate.on('keyup', function(e){
+ });
+
+ domInputStartDate.on('keyup', function(e){
if (e.keyCode == 13) {
$('#StartDateInput a.btn.validate').click();
}
- });/* end StartDate */
-
- var domInputDueDate = $('body').find('#DueDateInput input');
- $('#DueDateInput a.btn.validate').on('click', function(e)
- {
+ });/* end StartDate */
+
+ var domInputDueDate = $('body').find('#DueDateInput input');
+ $('#DueDateInput a.btn.validate').on('click', function(e) {
e.preventDefault();
$('.due-date .value .error').remove();
+
if(new Date($('body').find('#StartDateInput input').val()).getTime() <= new Date(domInputDueDate.val()).getTime() || $('body').find('#StartDateInput input').val() == "" )
{
issueDynamicUpdate('due_date', domInputDueDate.val(), 'date', 'due-date');
@@ -472,129 +509,120 @@ function initEditFieldListeners()
$('.due-date .value').append(' ' + _TXT_ERROR_DUE_DATE + '');
}
return false;
- });
-
- domInputDueDate.on('keyup', function(e){
+ });
+
+ domInputDueDate.on('keyup', function(e){
if (e.keyCode == 13) {
$('#DueDateInput a.btn.validate').click();
}
- });/* end StartDate */
+ });/* end StartDate */
- var domInputTitle = $('body').find('#TitleInput input');
- $('#TitleInput a.btn.validate').on('click', function(e)
- {
+ var domInputTitle = $('body').find('#TitleInput input');
+ $('#TitleInput a.btn.validate').on('click', function(e) {
e.preventDefault();
issueDynamicUpdate('subject', domInputTitle.val(), 'input', 'subject');
-
+
return false;
- });
-
- domInputTitle.on('keyup', function(e){
+ });
+
+ domInputTitle.on('keyup', function(e){
if (e.keyCode == 13) {
$('#TitleInput a.btn.validate').click();
}
- });/* end Title */
+ });/* end Title */
- var domInputDescription = $('body').find('#DescriptionInput textarea');
+ var domInputDescription = $('body').find('#DescriptionInput textarea');
- if(domInputDescription.length)
- {
- $('#DescriptionInput a.btn.validate').on('click', function(e)
- {
+ if(domInputDescription.length) {
+ $('#DescriptionInput a.btn.validate').on('click', function(e) {
e.preventDefault();
var new_value = domInputDescription.val();
-
- if(typeof(CKEDITOR) === "object"
- && typeof(CKEDITOR.instances['description_textarea'].getData) === typeof(Function)){
+
+ if (
+ typeof(CKEDITOR) === "object" &&
+ typeof(CKEDITOR.instances['description_textarea'].getData) === typeof(Function)
+ ) {
new_value = CKEDITOR.instances['description_textarea'].getData();
}
-
+
issueDynamicUpdate('description', new_value, 'textarea', 'description');
return false;
- });
-
- if(typeof(jsToolBar) === typeof(Function))
- {
+ });
+
+ if (typeof(jsToolBar) === typeof(Function)) {
var wikiToolbar = new jsToolBar(document.getElementById('description_textarea')); wikiToolbar.draw();
- } else if(typeof(CKEDITOR) === "object" && typeof(CKEDITOR.replace) === typeof(Function)) {
+ } else if (typeof(CKEDITOR) === "object" && typeof(CKEDITOR.replace) === typeof(Function)) {
CKEDITOR.replace('description_textarea', { height: 100 });
}
- }
+ }
- var dynamic_edit_assigned_to_id = $('body').find('#dynamic_edit_assigned_to_id select');
+ var dynamic_edit_assigned_to_id = $('body').find('#dynamic_edit_assigned_to_id select');
- if(dynamic_edit_assigned_to_id.length)
- {
+ if (dynamic_edit_assigned_to_id.length) {
dynamic_edit_assigned_to_id.on('change', function(e){
issueDynamicUpdate('assigned_to_id', dynamic_edit_assigned_to_id.val(), 'select', 'assigned-to');
- });
- }
+ });
+ }
- var dynamic_edit_fixed_version = $('body').find('#dynamic_edit_fixed_version select');
+ var dynamic_edit_fixed_version = $('body').find('#dynamic_edit_fixed_version select');
- if(dynamic_edit_fixed_version.length)
- {
+ if (dynamic_edit_fixed_version.length) {
dynamic_edit_fixed_version.on('change', function(e){
issueDynamicUpdate('fixed_version_id', dynamic_edit_fixed_version.val(), 'select', 'fixed-version');
- });
- }
-
+ });
+ }
+
/* end Description */
/* Custom fields */
- for(var i = 0 ; i < CF_VALUE_JSON.length ; i++)
- {
- (function() {
- var info = CF_VALUE_JSON[i].custom_field;
- var value = CF_VALUE_JSON[i].value;
- if(info.visible && info.editable)
- {
- var inputType = "input";
- switch (info.field_format)
- {
- case "bool":
- case "user":
- case "list":
- case "enumeration":
- case "version":
- inputType = "select";
- break;
- case "text":
- inputType = "textarea";
- break;
-
- }
+ for (var i = 0 ; i < CF_VALUE_JSON.length ; i++) {
+ (
+ function() {
+ var info = CF_VALUE_JSON[i].custom_field;
+ var value = CF_VALUE_JSON[i].value;
- // Specific case : version field with checkboxes
- if(info.field_format == "version" && info.format_store.edit_tag_style == "check_box")
- {
- inputType = "version";
- $('body').find('#dynamic_edit_cf_' + info.id + ' input').on('click', function(e){
- $('label[for=issue_custom_field_values_' + info.id + ']').next().find('input[value=' + $(this).val() + ']').click();
- });
- }
-
- var domInputField = $('body').find('#dynamic_issue_custom_field_values_' + info.id);
- $('body').find('#dynamic_edit_cf_' + info.id + ' a.btn.validate').on('click', function(e)
- {
- var new_value = domInputField.val();
-
- issueDynamicUpdate('custom_field_values_' + info.id , new_value, inputType, 'cf_' + info.id);
-
- return false;
- });
-
- domInputField.on('keyup', function(e){
- if (e.keyCode == 13 && inputType != "textarea") {
- $('body').find('#dynamic_edit_cf_' + info.id + ' a.btn.validate').click();
+ if (info.visible && info.editable) {
+ var inputType = "input";
+ switch (info.field_format) {
+ case "bool":
+ case "user":
+ case "list":
+ case "enumeration":
+ case "version":
+ inputType = "select";
+ break;
+ case "text":
+ inputType = "textarea";
+ break;
}
- });
- }
- }()); // closure FTW
+ // Specific case : version field with checkboxes
+ if (info.field_format == "version" && info.format_store.edit_tag_style == "check_box") {
+ inputType = "version";
+ $('body').find('#dynamic_edit_cf_' + info.id + ' input').on('click', function(e) {
+ $('label[for=issue_custom_field_values_' + info.id + ']').next().find('input[value=' + $(this).val() + ']').click();
+ });
+ }
+
+ var domInputField = $('body').find('#dynamic_issue_custom_field_values_' + info.id);
+ $('body').find('#dynamic_edit_cf_' + info.id + ' a.btn.validate').on('click', function(e) {
+ var new_value = domInputField.val();
+
+ issueDynamicUpdate('custom_field_values_' + info.id , new_value, inputType, 'cf_' + info.id);
+
+ return false;
+ });
+
+ domInputField.on('keyup', function(e) {
+ if (e.keyCode == 13 && inputType != "textarea") {
+ $('body').find('#dynamic_edit_cf_' + info.id + ' a.btn.validate').click();
+ }
+ });
+ }
+ }()
+ ); // closure FTW
}
+}
-}
-
-initEditFieldListeners();
\ No newline at end of file
+initEditFieldListeners();
diff --git a/lib/details_issue_hooks.rb b/lib/details_issue_hooks.rb
index ea9cae9..888869b 100644
--- a/lib/details_issue_hooks.rb
+++ b/lib/details_issue_hooks.rb
@@ -1,205 +1,213 @@
class DetailsIssueHooks < Redmine::Hook::ViewListener
-
def protect_against_forgery?
false
- end
-
- def current_is_detail_page(context)
- # check if we see an issue but not creating a new one or on the specific edit page
- ret = context[:controller] && context[:controller].is_a?(IssuesController) && context[:request].original_url.rindex(/\/issues\/\S+/) && !context[:request].original_url.rindex(/\/issues\/new/) && !context[:request].original_url.rindex(/\/issues\/\d+\/edit/)
- end
-
- def view_layouts_base_html_head(context)
- if current_is_detail_page(context)
- stylesheet_link_tag('issue_dynamic_edit.css', :plugin => :redmine_issue_dynamic_edit)
- end
- end
-
- def view_layouts_base_body_bottom(context)
- if current_is_detail_page(context)
- javascript_include_tag('issue_dynamic_edit_configuration_file.js', 'issue_dynamic_edit.js', :plugin => :redmine_issue_dynamic_edit)
- end
end
- def view_issues_show_details_bottom(context = { })
+ def current_is_detail_page(context)
+ # check if we see an issue but not creating a new one or on the specific edit page
+ ret = context[:controller] && context[:controller].is_a?(IssuesController) && context[:request].original_url.rindex(/\/issues\/\S+/) && !context[:request].original_url.rindex(/\/issues\/new/) && !context[:request].original_url.rindex(/\/issues\/\d+\/edit/)
+ end
+
+ def view_layouts_base_html_head(context)
+ return unless current_is_detail_page(context)
+
+ stylesheet_link_tag('issue_dynamic_edit.css', :plugin => :redmine_issue_dynamic_edit)
+ end
+
+ def view_layouts_base_body_bottom(context)
+ return unless current_is_detail_page(context)
+
+ javascript_include_tag('issue_dynamic_edit_configuration_file.js', 'issue_dynamic_edit.js', :plugin => :redmine_issue_dynamic_edit)
+ end
+
+ def view_issues_show_details_bottom(context = {})
project = context[:project]
request = context[:request]
issue_id = request.path_parameters[:id]
- back = request.env['HTTP_REFERER']
+ back = request.env['HTTP_REFERER']
- o = ''
-
- if (issue_id)
+ o = ''
+
+ if issue_id
issue = Issue.find(issue_id)
- readOnlyAttributes = issue.read_only_attribute_names(User.current)
- requiredAttributes = issue.required_attribute_names(User.current)
-
- # o << requiredAttributes.to_json
-
- allRequiredFieldsFilled = true
- requiredAttributes.each do |attr|
- if(issue.read_attribute(attr).to_s.empty?)
- allRequiredFieldsFilled = false
- end
- end
-
- if (issue)
- if (User.current.allowed_to?(:edit_issues, project))
-
- # if there's a JS error, we hide the generated values
- o << '
'
-
- # Status dropdown
- statuses = issue.new_statuses_allowed_to(User.current)
- if (!statuses.empty? && !(readOnlyAttributes.include? 'status_id') && allRequiredFieldsFilled)
- o << ""
- o << " "
+ readOnlyAttributes = issue.read_only_attribute_names(User.current)
+ requiredAttributes = issue.required_attribute_names(User.current)
+
+ # o << requiredAttributes.to_json
+
+ allRequiredFieldsFilled = true
+ requiredAttributes.each do |attr|
+ if issue.read_attribute(attr).to_s.empty?
+ allRequiredFieldsFilled = false
+ end
+ end
+
+ if issue
+ if User.current.allowed_to?(:edit_issues, project)
+ # if there's a JS error, we hide the generated values
+ o << '
'
+
+ # Status dropdown
+ statuses = issue.new_statuses_allowed_to(User.current)
+ if (
+ !statuses.empty? &&
+ !readOnlyAttributes.include?('status_id') &&
+ allRequiredFieldsFilled
+ )
+ o << ""
+ o << " "
end
-
- # Users dropdown
- assignables = project.assignable_users
- if (!assignables.empty? && !(readOnlyAttributes.include? 'assigned_to_id'))
- o << ""
- o << " "
+
+ # Users dropdown
+ assignables = project.assignable_users
+ if (
+ !assignables.empty? &&
+ !readOnlyAttributes.include?('assigned_to_id')
+ )
+ o << ""
+ o << " "
end
-
- # Priorities dropdown
- priorities = IssuePriority.all
- if(!priorities.empty? && !(readOnlyAttributes.include? 'priority_id'))
- o << ""
- o << " "
- end
-
- # %done dropdown
- if(!(readOnlyAttributes.include? 'done_ratio'))
- percent = 0
- o << ""
- o << " "
- end
-
- # Estimated_time dropdown
- if(!(readOnlyAttributes.include? 'estimated_hours'))
- o << ""
- o << " "
- o << ""
- o << " "
- o << ""
- end
-
- # Start date
- if(!(readOnlyAttributes.include? 'start_date'))
- o << ""
- o << " "
- o << " "
- o << " "
- o << ""
- o << ""
- end
-
- # Due date
- if(!(readOnlyAttributes.include? 'due_date'))
- o << ""
- o << " "
- o << " "
- o << " "
- o << ""
- o << ""
- end
- # Title
- # Make quotings in subject! (PP)
- clonesubject = issue.subject.gsub('"','"')
- o << ""
- o << " "
- o << " "
- o << " "
- o << ""
+ # Priorities dropdown
+ priorities = IssuePriority.all
- # Description
- o << ""
- o << " "
- o << "
"
- o << "
"
- o << ""
-
- end
- end
-
- o << "\n"
-
-
-
- o << "
#{requiredAttributes.to_json}
\n"
-
+ o << " "
+ end
- # closing the display none div parent
- o << "
"
- return o
+ # %done dropdown
+ if ! readOnlyAttributes.include?('done_ratio')
+ percent = 0
+ o << ""
+ o << " "
+ end
+
+ # Estimated_time dropdown
+ if ! readOnlyAttributes.include?('estimated_hours')
+ o << ""
+ o << " "
+ o << ""
+ o << " "
+ o << ""
+ end
+
+ # Start date
+ if ! readOnlyAttributes.include?('start_date')
+ o << ""
+ o << " "
+ o << " "
+ o << " "
+ o << ""
+ o << ""
+ end
+
+ # Due date
+ if ! readOnlyAttributes.include?('due_date')
+ o << ""
+ o << " "
+ o << " "
+ o << " "
+ o << ""
+ o << ""
+ end
+
+ # Title
+ # Make quotings in subject! (PP)
+ clonesubject = issue.subject.gsub('"','"')
+ o << ""
+ o << " "
+ o << " "
+ o << " "
+ o << ""
+
+ # Description
+ o << ""
+ o << " "
+ o << "
"
+ o << "
"
+ o << ""
+ end
+ end
+
+ o << "\n"
+
+ o << "
#{requiredAttributes.to_json}
\n"
+
+ # closing the display none div parent
+ o << "