partially fixed Github issue #12 : Read only attributes can't be edited anymore. Dynamic refresh for read only attributes when status changes

This commit is contained in:
Ilogeek 2017-09-19 11:39:51 +02:00
parent 7f5d6e6858
commit f314d1a472
4 changed files with 221 additions and 225 deletions

View File

@ -18,6 +18,8 @@ This plugin uses [FontAwesome icons](http://fontawesome.io/)
### Changelog
* **v 0.4.3** : partially fixed Github issue #12 : Read only attributes can't be edited anymore. Dynamic refresh for read only attributes when status changes
* **v 0.4.2** : fixed Github issue #10 : History list updated after modification
* **v 0.4.1** : fixed Github issue #7 : update status list to follow Redmine workflow
* **v 0.4.0** : fixed Github issues #2, #4, #9. Edited dropdown display
* **v 0.3.0** : start date, due date, ratio and estimated time fields are now dynamically editable. Translation files added (en, fr). Log added in console when AJAX fails

View File

@ -19,6 +19,8 @@ $(document).on('click', function(e){
}
});
function initEditFields()
{
/* Put new dropdown lists in the detailed info block */
if($('#statusListDropdown').length > 0) {
var htmlCopy = $('#statusListDropdown').get(0).outerHTML;
@ -75,6 +77,10 @@ if($('#DueDateInput').length > 0) {
$('.details .attributes .due-date.attribute .value').html() + '</span> <i class="fa fa-pencil fa-fw" aria-hidden="true"></i>' +
htmlCopy);
}
}
initEditFields();
$('body.controller-issues.action-show').on('click', '.btn.close', function(e){
e.preventDefault();
@ -130,13 +136,11 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
/* get result page content (updated issue detail page with new status) */
var parsed = $.parseHTML(msg);
var statusListDropdown = $(parsed).find("#statusListDropdown select");
var prioritiesListDropdown = $(parsed).find('#prioritiesListDropdown select');
/* we update dropdown status with new one from updated page */
$('#statusListDropdown select').html(statusListDropdown.html());
$('#issue_status_id').html(statusListDropdown.html());
$('#prioritiesListDropdown select').html(prioritiesListDropdown.html());
$('#issue_priority_id').html(prioritiesListDropdown.html());
/* we update the details block */
$('div.issue.details').html($(parsed).find('div.issue.details').html());
/* we init edit fields */
initEditFields();
initEditFieldListeners();
/* we update issue properties edit block */
$('#all_attributes').html($(parsed).find('#all_attributes').html());
@ -152,34 +156,10 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
}, 2000);
}, 500);
if(type == "progress") { // specific case for progress bar, we need to update the progress bar view
var progressBar = "<tbody><tr>";
var percentTodo = 100 - parseInt(field_value);
if(field_value != 0) { progressBar += "<td style='width: " + field_value + "%;' class='closed' title='" + field_value + "%'></td>"; }
if(percentTodo != 0) { progressBar += "<td style='width: " + percentTodo + "%;' class='todo'></td>"; }
progressBar += "</tr></tbody>";
$('.details .attributes .' + cssClass + '.attribute table.progress').attr('class', 'progress progress-' + field_value).html(progressBar);
$('.details .attributes .' + cssClass + ' .percent').html(field_value + "%");
} else if( type == "date") { // specific case for start date and due date, we have to update min and max date allowed
if(field_name == "start_date")
{
$('body').find('#DueDateInput input').attr('min', field_value);
} else if (field_name == "due_date")
{
$('body').find('#StartDateInput input').attr('max', field_value);
}
}
// update other fields to avoid conflict
$('#issue_lock_version').val(parseInt($('#issue_lock_version').val()) + 1 );
$('#last_journal_id').val(parseInt($('#last_journal_id').val()) + 1 );
if(type == "select")
{
$('#issue_' + field_name + ' option').removeAttr('selected').filter('[value=' + field_value + ']').prop('selected', true);
} else if (type == "input" || type == "date")
{
$('#issue_' + field_name).val(field_value);
}
},
error: function(xhr, msg, error) {
/* error and no update, info logged into console */
@ -200,7 +180,8 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
};
/* Listeners foreach attribute */
function initEditFieldListeners()
{
var domSelectStatus = $('body').find('#statusListDropdown select');
domSelectStatus.on('change', function(e){
issueDynamicUpdate('status_id', domSelectStatus.val(), 'select', 'status');
@ -297,3 +278,6 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
$('#DueDateInput a.btn.validate').click();
}
});/* end StartDate */
}
initEditFieldListeners();

View File

@ -6,7 +6,7 @@ Redmine::Plugin.register :redmine_issue_dynamic_edit do
name 'Redmine Dynamic edit Issue plugin'
author 'Hugo Zilliox'
description 'Allows users to dynamically update issue attributes in detailed view'
version '0.4.2'
version '0.4.3'
url 'https://github.com/ilogeek/redmine_issue_dynamic_edit'
author_url 'https://hzilliox.fr'
end

View File

@ -22,6 +22,9 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
if (issue_id)
issue = Issue.find(issue_id)
readOnlyAttributes = issue.read_only_attribute_names(User.current)
# o << issue.required_attribute_names(User.current).to_json
if (issue)
if (User.current.allowed_to?(:edit_issues, project))
@ -30,7 +33,7 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
# Status dropdown
statuses = issue.new_statuses_allowed_to(User.current)
if (!statuses.empty?)
if (!statuses.empty? && !(readOnlyAttributes.include? 'status_id'))
o << "<span class='dynamicEdit' id='statusListDropdown'>"
o << "<select data-issue='#{issue_id}'><option disabled='disabled' selected> </option>"
statuses.each do |s|
@ -45,8 +48,7 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
# Users dropdown
assignables = project.assignable_users
o << assignables.to_json
if (!assignables.empty?)
if (!assignables.empty? && !(readOnlyAttributes.include? 'assigned_to_id'))
o << "<span class='dynamicEdit' id='usersListDropdown'>"
o << "<select data-issue='#{issue_id}'><option disabled='disabled' selected> </option>"
assignables.each do |u|
@ -61,7 +63,7 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
# Priorities dropdown
priorities = IssuePriority.all
if(!priorities.empty?)
if(!priorities.empty? && !(readOnlyAttributes.include? 'priority_id'))
o << "<span class='dynamicEdit' id='prioritiesListDropdown'>"
o << "<select data-issue='#{issue_id}'><option disabled='disabled' selected> </option>"
priorities.each do |p|
@ -75,6 +77,7 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
end
# %done dropdown
if(!(readOnlyAttributes.include? 'done_ratio'))
percent = 0
o << "<span class='dynamicEdit' id='doneRatioListDropdown'>"
o << "<select data-issue='#{issue_id}'><option disabled='disabled' selected> </option>"
@ -90,15 +93,19 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
end
end
o << "</select> <a href='#' class='btn btn-primary close' aria-label='" + l(:ide_txt_cancel_btn) + "'><i class='fa fa-times fa-fw' aria-hidden='true'></i></a></span>"
end
# Estimated_time dropdown
if(!(readOnlyAttributes.include? 'estimated_hours'))
o << "<span class='dynamicEdit' id='EstimatedTimeInput'>"
o << " <input type='text' value='#{issue.estimated_hours}' size='6'/>"
o << "<a href='#' class='btn btn-primary validate' aria-label='" + l(:ide_txt_validation_btn) + "'><i class='fa fa-check fa-fw' aria-hidden='true'></i></a>"
o << " <a href='#' class='btn btn-primary close' aria-label='" + l(:ide_txt_cancel_btn) + "'><i class='fa fa-times fa-fw' aria-hidden='true'></i></a>"
o << "</span>"
end
# Start date
if(!(readOnlyAttributes.include? 'start_date'))
o << "<span class='dynamicEdit' id='StartDateInput'>"
o << " <input size=\"10\" value=\"#{issue.start_date}\" type=\"date\" max=\"#{issue.due_date}\">"
o << " <a href='#' class='btn btn-primary validate' aria-label='" + l(:ide_txt_validation_btn) + "'><i class='fa fa-check fa-fw' aria-hidden='true'></i></a>"
@ -109,8 +116,10 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
o << " $(function() { $('#StartDateInput input').addClass('date').datepickerFallback(datepickerOptions); });\n"
o << "//]]>\n"
o << "</script>"
end
# Due date
if(!(readOnlyAttributes.include? 'due_date'))
o << "<span class='dynamicEdit' id='DueDateInput'>"
o << " <input size=\"10\" value=\"#{issue.due_date}\" type=\"date\" min=\"#{issue.start_date}\">"
o << " <a href='#' class='btn btn-primary validate' aria-label='" + l(:ide_txt_validation_btn) + "'><i class='fa fa-check fa-fw' aria-hidden='true'></i></a>"
@ -121,6 +130,7 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
o << " $(function() { $('#DueDateInput input').addClass('date').datepickerFallback(datepickerOptions); });\n"
o << "//]]>\n"
o << "</script>"
end
end
end