Custom fields support added (Github request #19)

This commit is contained in:
Hugo 2018-01-22 22:36:44 +01:00
parent bab8cf362c
commit 5174466a05
5 changed files with 100 additions and 7 deletions

View File

@ -1,8 +1,9 @@
# redmine_issue_dynamic_edit
Add new elements on detailed issue page to dynamically update issue's title, status, assignee, priority, start and due dates, ratio and estimated time fields, directly in the details block of the issue without any page refresh (JIRA style).
Add new elements on detailed issue page to **dynamically update issue's attributes and custom fields**, directly in the details block of the issue **without any page refresh** (*JIRA style*).
### 🔴 What info should you provide when opening an issue
### 🔴 What info you should provide when opening an issue
>This plugin use JS a lot. Could you then please check your JS console from your web browser ( [HowTo](https://webmasters.stackexchange.com/a/77337) ) and try again your issue. You'll see some information about what goes wrong.
>
>Could you copy / paste it in your issue and expand all possible object (error data for example) so we can look if there's a problem with the ajax call the plugin performs to update the issue or if there's any JS error.
@ -24,6 +25,7 @@ This plugin uses [FontAwesome icons](http://fontawesome.io/)
### Changelog
* **v 0.6.0** : NOW WITH CUSTOM FIELDS SUPPORT ! (Github #19)
* **v 0.5.0** : fixed Github issue #18 : textarea fixed (jstoolbar or ckeditor)
* **v 0.4.9** : fixed Github issue #17 : Datepicker fallback added for date fields
* **v 0.4.8** : fixed Github issues #15 and #16

View File

@ -91,6 +91,37 @@ function initEditFields()
$('div.description .wiki').html(' <i class="fa fa-pencil fa-fw" aria-hidden="true" style="float:right;"></i><span class="showValue">' + $('div.description .wiki').html() + '</span>' +
htmlCopy).addClass('value');
}
for(var i = 0 ; i < CF_VALUE_JSON.length ; i++)
{
var info = CF_VALUE_JSON[i].custom_field;
var value = CF_VALUE_JSON[i].value;
if(info.visible && info.editable)
{
if($('.details .attributes .cf_' + info.id + '.attribute .value').length)
{
var htmlCopy = $('#issue_custom_field_values_' + info.id).get(0).outerHTML;
// 2 technics with simple or double quote (safety first)
htmlCopy = htmlCopy.replace('id="', 'id="dynamic_').replace("id='", "id='dynamic_");
htmlCopy = htmlCopy.replace('class="', 'class="cf_' + info.id + ' ').replace("class='", "class='cf_" + info.id + " ");
var editHTML = "<span class='dynamicEdit' id='dynamic_edit_cf_" + info.id + "'>";
editHTML += htmlCopy;
editHTML += " <a href='#' class='btn btn-primary validate' aria-label='" + _TXT_VALIDATION_BTN + "'><i class='fa fa-check fa-fw' aria-hidden='true'></i></a>";
editHTML += " <a href='#' class='btn btn-primary close' aria-label='" + _TXT_CANCEL_BTN + "'><i class='fa fa-times fa-fw' aria-hidden='true'></i></a>";
editHTML += "</span>";
$('.details .attributes .cf_' + info.id + '.attribute .value').html('<span class="showValue">' +
$('.details .attributes .cf_' + info.id + '.attribute .value').html() + '</span> <i class="fa fa-pencil fa-fw" aria-hidden="true"></i>' +
editHTML);
if(info.field_format == "date")
{
$('body').find('#dynamic_issue_custom_field_values_' + info.id).datepickerFallback(datepickerOptions);
}
}
}
}
}
initEditFields();
@ -152,7 +183,6 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
url: _BASE_REDMINE_PATH + '/issues/bulk_update?back_url=' + prepareReturnUrl + '&amp;ids%5B%5D=' + _ISSUE_ID + '&amp;issue%5B' + field_name + '%5D=' + field_value,
data: { "authenticity_token" : token },
crossDomain: true,
async: false,
beforeSend: function(xhr) {
xhr.setRequestHeader("authenticity_token", token);
},
@ -205,14 +235,14 @@ function issueDynamicUpdate(field_name, field_value, type, cssClass){
$('div.issue.details').html($(parsed).find('div.issue.details').html());
$('body').find('.details .' + cssClass + ' .value').append(' <i class="fa fa-refresh fa-spin fa-fw"></i>');
/* we update issue properties edit block */
$('#all_attributes').html($(parsed).find('#all_attributes').html());
/* we init edit fields */
initEditFields();
initEditFieldListeners();
updateRequiredFields(JSON.parse($(parsed).find('#required_field_array').html()));
/* we update issue properties edit block */
$('#all_attributes').html($(parsed).find('#all_attributes').html());
/* we update the history list */
$('#history').append($(parsed).find('#history .journal.has-details:last-child'));
@ -387,6 +417,59 @@ function initEditFieldListeners()
}
/* 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;
}
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)
{
issueDynamicUpdate('custom_field_values%5D%5B' + info.id , domInputField.val(), 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(inputType == "textarea")
{
if(typeof(jsToolBar) === typeof(Function))
{
var wikiToolbar = new jsToolBar(domInputField); wikiToolbar.setHelpLink('/help/fr/wiki_syntax_textile.html'); wikiToolbar.draw();
} else if(typeof(CKEDITOR) === "object" && typeof(CKEDITOR.replace) === typeof(Function)) {
CKEDITOR.replace('dynamic_issue_custom_field_values_' + info.id, { height: 100 });
}
}
}
}()); // closure FTW
}
}
initEditFieldListeners();

View File

@ -101,4 +101,8 @@ body.controller-issues.action-show div.issue.details .splitcontent {
div.issue div.subject h3 {
position:relative;
display: inline-block;
}
body.controller-issues.action-show .dynamicEdit input[type="text"] {
width: auto !important;
}

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 without refreshing the page (JIRA style)'
version '0.5.0'
version '0.6.0'
url 'https://github.com/ilogeek/redmine_issue_dynamic_edit'
author_url 'https://hzilliox.fr'
end

View File

@ -159,12 +159,16 @@ class DetailsIssueHooks < Redmine::Hook::ViewListener
end
o << "<script>"
o << " var CF_VALUE_JSON = " + issue.editable_custom_field_values(User.current).to_json + ";\n"
o << " var _ISSUE_ID = \"#{issue_id}\";\n"
o << " var _USER_API_KEY = \"#{User.current.api_key}\";\n"
o << " var _BASE_REDMINE_PATH = \"#{Redmine::Utils.relative_url_root}\";\n"
# Translations text
o << " var _TXT_VALIDATION_BTN = \"" + l(:ide_txt_validation_btn) + "\";\n"
o << " var _TXT_CANCEL_BTN = \"" + l(:ide_txt_cancel_btn) + "\";\n"
o << " var _TXT_ERROR_POSITIVE_NUMBER = \"" + l(:ide_txt_error_positive_number) + "\";\n"
o << " var _TXT_ERROR_START_DATE = \"" + l(:ide_txt_error_start_date) + "\";\n"
o << " var _TXT_ERROR_DUE_DATE = \"" + l(:ide_txt_error_due_date) + "\";\n"