Initial Redmine tooling and local plugin forks
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<%= avatar(@user, :size => 54, :id => 'avatar') %>
|
||||
@@ -0,0 +1,226 @@
|
||||
function getXmlHttp(){
|
||||
var xmlhttp;
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch (e) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch (E) {
|
||||
xmlhttp = false;
|
||||
}
|
||||
}
|
||||
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
}
|
||||
return xmlhttp;
|
||||
}
|
||||
|
||||
function serialize(form){
|
||||
var boundary = String(Math.random()).slice(2);
|
||||
var boundaryMiddle = '--' + boundary + '\r\n';
|
||||
var boundaryLast = '--' + boundary + '--\r\n'
|
||||
var cont_start = 'Content-Disposition: form-data; name="';
|
||||
var cont_middle = '"\r\n\r\n';
|
||||
var cont_end = '\r\n';
|
||||
var field = '';
|
||||
var body = ['\r\n'];
|
||||
if (typeof form == 'object' && form.nodeName == "FORM") {
|
||||
for (index = form.elements.length - 1; index >= 0; index--) {
|
||||
field = form.elements[index];
|
||||
if (field.type == 'select-multiple') {
|
||||
for (option = form.elements[index].options.length - 1; option >= 0; option--) {
|
||||
if (field.options[option].selected) { body.push(cont_start + field.name + cont_middle + field.options[option].value + cont_end); }
|
||||
}
|
||||
} else {
|
||||
if (field.type != 'submit' && field.type != 'file' && field.type != 'button') {
|
||||
if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
|
||||
body.push(cont_start + field.name + cont_middle + field.value + cont_end);
|
||||
}
|
||||
} else {
|
||||
if (field.type == 'file'){
|
||||
if (field.files.length > 0) {
|
||||
body.push(cont_start + field.name + cont_middle + field.attributes['data-value'] + cont_end);
|
||||
body.push(cont_start + field.name + '_name' + cont_middle + field.files[0].name + cont_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [boundary, body.join(boundaryMiddle) + boundaryLast];
|
||||
}
|
||||
|
||||
function translation(field){
|
||||
return RedmineHelpdeskIframe.configuration['translation'] ? RedmineHelpdeskIframe.configuration['translation'][field] : null;
|
||||
}
|
||||
|
||||
function ticketCreated(){
|
||||
success_div = document.createElement('div');
|
||||
success_div.id = 'submit_button';
|
||||
success_div.className = 'success-message';
|
||||
success_div.style.textAlign = 'center';
|
||||
success_div.style.margin = '15%';
|
||||
success_div.style.font = '20px Arial';
|
||||
success_div.innerHTML = translation('createSuccessLabel') || '<%= t(:label_helpdesk_widget_ticket_created) %>';
|
||||
|
||||
success_desc_div = document.createElement('div');
|
||||
success_desc_div.style.textAlign = 'center';
|
||||
success_desc_div.style.margin = '5%';
|
||||
success_desc_div.style.font = '14px Arial';
|
||||
success_desc_div.innerHTML = translation('createSuccessDescription');
|
||||
|
||||
document.getElementById('widget_form').innerHTML = '';
|
||||
document.getElementById('widget_form').appendChild(success_div);
|
||||
document.getElementById('widget_form').appendChild(success_desc_div);
|
||||
}
|
||||
|
||||
function ticketErrors(errors){
|
||||
errors_div = document.createElement('div');
|
||||
errors_div.id = 'ticket-error-details';
|
||||
errors_div.className = 'ticket-error-details';
|
||||
|
||||
error_p = document.createElement('div');
|
||||
error_p.innerHTML = translation('createErrorLabel') || '<%= t(:label_helpdesk_widget_ticket_errors) %>';
|
||||
errors_div.appendChild(error_p);
|
||||
|
||||
errors_link = document.createElement('a');
|
||||
errors_link.id = 'ticket-errors-link';
|
||||
errors_link.href = 'javascript:void(0)';
|
||||
errors_link.style.paddingLeft = '10px';
|
||||
errors_link.addEventListener('click', function(){ toggleErrorsList() });
|
||||
errors_link.innerHTML = '<%= t(:label_helpdesk_widget_ticket_error_details) %>';
|
||||
error_p.appendChild(errors_link);
|
||||
|
||||
ul = document.createElement('ul');
|
||||
ul.id = 'ticket-errors';
|
||||
ul.className = 'ticket-errors';
|
||||
ul.style.display = 'none';
|
||||
errors_div.appendChild(ul);
|
||||
|
||||
for (var key in errors) {
|
||||
if (key != 'base') {
|
||||
processErrorForField(ul, key, errors[key])
|
||||
} else {
|
||||
errors[key].forEach(function(error_text) {
|
||||
processErrorForCustomField(ul, key, error_text);
|
||||
});
|
||||
}
|
||||
}
|
||||
document.getElementById('flash').appendChild(errors_div);
|
||||
}
|
||||
|
||||
function createErrorLi(target, text){
|
||||
li = document.createElement('li');
|
||||
li.id = 'ticket-error';
|
||||
li.className = 'ticket-error';
|
||||
li.innerHTML = text;
|
||||
target.appendChild(li);
|
||||
}
|
||||
|
||||
function markFieldAsError(element){
|
||||
element.style.border = '';
|
||||
element.classList.add('error_field');
|
||||
element.addEventListener('keyup', checkFieldContent);
|
||||
}
|
||||
|
||||
function markRequireFieldsAsError(){
|
||||
fields = document.querySelectorAll("[data-require='true'] > input, [data-require='true'] > select, [data-require='true'] > textarea, .required-field");
|
||||
required_fields = Array.from(fields);
|
||||
var respose = false;
|
||||
required_fields.forEach(function(field) {
|
||||
if (field.value.length == 0) {
|
||||
markFieldAsError(field);
|
||||
respose = true;
|
||||
}
|
||||
});
|
||||
return respose;
|
||||
}
|
||||
|
||||
function unmarkFieldsAsError(){
|
||||
error_fields = Array.from(document.getElementsByClassName('error_field'));
|
||||
error_fields.forEach(function(field) {
|
||||
field.classList.remove('error_field');
|
||||
field.removeEventListener('keyup', checkFieldContent);
|
||||
});
|
||||
}
|
||||
|
||||
function checkFieldContent(){
|
||||
if (this.value.length > 0) {
|
||||
this.style.border = '1px solid #d9d9d9';
|
||||
} else {
|
||||
this.style.border = '1px solid red';
|
||||
}
|
||||
}
|
||||
|
||||
function processErrorForField(ul, key, error_text) {
|
||||
createErrorLi(ul, error_text);
|
||||
field = document.getElementById(key);
|
||||
if (field != null) { markFieldAsError(field); }
|
||||
}
|
||||
|
||||
function processErrorForCustomField(ul, key, error_text) {
|
||||
checkCustomFieldsOnError(error_text);
|
||||
createErrorLi(ul, error_text);
|
||||
}
|
||||
|
||||
function checkCustomFieldsOnError(error_text){
|
||||
custom_fields = Array.from(document.getElementsByClassName('custom_field'));
|
||||
custom_fields.forEach(function(cfield) {
|
||||
cfield_regex = new RegExp(cfield.attributes['data-error-key'].value);
|
||||
if (cfield_regex.test(error_text)){
|
||||
markFieldAsError(cfield.getElementsByTagName('input')[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleErrorsList(){
|
||||
errors_list = document.getElementById('ticket-errors');
|
||||
if (errors_list == null) { return true }
|
||||
if (errors_list && errors_list.style.display == 'block') {
|
||||
errors_list.style.display = 'none';
|
||||
} else {
|
||||
errors_list.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function processResponse(response){
|
||||
if (response['result']) {
|
||||
ticketCreated();
|
||||
parent.postMessage(JSON.stringify({ reload: true }), "*");
|
||||
} else {
|
||||
ticketErrors(response['errors']);
|
||||
}
|
||||
var formSubmitBtn = document.getElementById('form-submit-btn');
|
||||
if (formSubmitBtn){
|
||||
formSubmitBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function needReloadProjectData(){
|
||||
parent.postMessage(JSON.stringify({ project_reload: true }), "*");
|
||||
}
|
||||
|
||||
function submitTicketForm(){
|
||||
document.getElementById('flash').innerHTML = '';
|
||||
unmarkFieldsAsError();
|
||||
if (markRequireFieldsAsError()){ return false; }
|
||||
|
||||
var base_url = '<%= Setting.protocol %>://<%= Setting.host_name %>'
|
||||
var xmlhttp = getXmlHttp();
|
||||
var serialize_result = serialize(document.getElementById('widget_form'));
|
||||
var boundary = serialize_result[0];
|
||||
var form_params = serialize_result[1];
|
||||
document.getElementById('form-submit-btn').disabled = true;
|
||||
xmlhttp.open('POST', base_url + '/helpdesk_widget/create_ticket.js', true);
|
||||
xmlhttp.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == 4) {
|
||||
if (xmlhttp.status == 200 || xmlhttp.status == 304) {
|
||||
processResponse(JSON.parse(xmlhttp.responseText));
|
||||
} else {
|
||||
processResponse({result: false, errors: []});
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlhttp.send(form_params);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<% @issue.editable_custom_field_values.each do |value| %>
|
||||
<% if @enabled_cf && @enabled_cf.include?(value.custom_field_id.to_s) %>
|
||||
<% required = value.custom_field.is_required? %>
|
||||
<p class="custom_field" data-error-key="<%= value.custom_field.name %>" data-require="<%= required %>"><%= custom_field_tag_with_label :issue, value, :required => required %></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,135 @@
|
||||
#widget_form {
|
||||
padding: 10px;
|
||||
font-family: helvetica, arial, sans-serif;
|
||||
}
|
||||
|
||||
#widget_form .form-control,
|
||||
#widget_form .custom_fields input,
|
||||
#widget_form .custom_fields select,
|
||||
#widget_form .custom_fields textarea {
|
||||
background: 0 0;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: #333;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
height: 36px;
|
||||
line-height: 16px;
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 12px;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
#widget_form select.form-control,
|
||||
#widget_form .custom_fields select {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAAAXNSR0IArs4c6QAAATNJREFUKBW1kc1KxDAUhW/CxM2M4EO4m7UwrzDDDBUXRRDxPbpw4cL3EHFhYcTSEh/BhevufAhhOptJabwnmhIjI+JPIDS5P1/OPSX64yW01o/GmNMkSZ5/wy6KYl8pdS0F0UQNBk8Mnv4UiF4wwJLW2qUQYo+srTiRMZTj316YMEMvGI4FgK6qjIS44KDk5N1qvT5L07T5Cpvn+Wh3OLziviMGddx3PpvPL3s1D2U5s1LeOLVE9caYw22+wq8dpe75wTHDXkTXnUwXCw0B0qtAwLTtAd9r3mN4gkd83n8RQw41vGv0eBhqeiAuULRqmgnGdp5IWQa+Or94itJNAWu4Np6iHxnAYH3y1eUivzhmg563kjgQ3iNfWfhHv8Jaf96m0Ofp/QfcgrZp2+N4xL7wvw6vkGme5fEw/bwAAAAASUVORK5CYII=) 97% 14px no-repeat;
|
||||
background-size: 12px 9px;
|
||||
}
|
||||
|
||||
#widget_form .custom_fields textarea,
|
||||
#widget_form textarea.form-control {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
|
||||
#widget_form .custom_fields select[multiple] {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
#widget_form .title {
|
||||
color: #333;
|
||||
padding-bottom: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#widget_form .custom_fields label > span {
|
||||
color: #333;
|
||||
padding-bottom: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#widget_form #flash {
|
||||
color: red;
|
||||
padding-bottom: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#widget_form input.error_field,
|
||||
#widget_form select.error_field,
|
||||
#widget_form textarea.error_field,
|
||||
#widget_form .custom_fields input.error_field,
|
||||
#widget_form .custom_fields select.error_field,
|
||||
#widget_form .custom_fields textarea.error_field {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
#widget_form .submit_button{
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#widget_form .attach_div{
|
||||
position: relative;
|
||||
float: right;
|
||||
margin: 10px;
|
||||
min-width: 80px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#widget_form .attach_link{
|
||||
position: relative;
|
||||
font: 14px Arial;
|
||||
color: #3699ca;
|
||||
}
|
||||
|
||||
#widget_form .attach_field{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -80px;
|
||||
width: 160px;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#widget_form .btn {
|
||||
float: right;
|
||||
background: #3699ca;
|
||||
color: #fff;
|
||||
height: 36px;
|
||||
padding: 0 14px;
|
||||
line-height: 30px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
border: 0px;
|
||||
font-size: 14px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
-ms-appearance: none;
|
||||
-o-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
#widget_from .attach {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
margin: 10px 16px 0 0;
|
||||
max-width: 210px;
|
||||
text-decoration: underline;
|
||||
color: #2996cc;
|
||||
}
|
||||
|
||||
#helpdesk_widget.open {
|
||||
border-radius: 0 100% 100% !important;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
}
|
||||
@@ -0,0 +1,556 @@
|
||||
function getXmlHttp(){
|
||||
var xmlhttp;
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
|
||||
} catch (e) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch (E) {
|
||||
xmlhttp = false;
|
||||
}
|
||||
}
|
||||
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
}
|
||||
return xmlhttp;
|
||||
}
|
||||
|
||||
var RedmineHelpdeskWidget = {
|
||||
widget: document.getElementById('helpdesk_widget'),
|
||||
widget_button: null,
|
||||
width: 400,
|
||||
height: 500,
|
||||
margin: 20,
|
||||
iframe: null,
|
||||
form: null,
|
||||
schema: null,
|
||||
reload: false,
|
||||
configuration: {},
|
||||
attachment: null,
|
||||
base_url: '<%= Setting.protocol %>://<%= Setting.host_name %>',
|
||||
config: function(configuration){
|
||||
this.configuration = configuration;
|
||||
this.apply_config();
|
||||
},
|
||||
apply_config: function(){
|
||||
if (this.configuration['color']) {
|
||||
this.widget_button.style.backgroundColor = this.configuration['color'];
|
||||
}
|
||||
switch (this.configuration['position']) {
|
||||
case 'topLeft':
|
||||
this.widget.style.top = '20px';
|
||||
this.widget.style.left = '20px';
|
||||
break;
|
||||
case 'topRight':
|
||||
this.widget.style.top = '20px';
|
||||
this.widget.style.right = '20px';
|
||||
break;
|
||||
case 'bottomLeft':
|
||||
this.widget.style.bottom = '20px';
|
||||
this.widget.style.left = '20px';
|
||||
break;
|
||||
case 'bottomRight':
|
||||
this.widget.style.bottom = '20px';
|
||||
this.widget.style.right = '20px';
|
||||
break;
|
||||
default:
|
||||
widget.style.bottom = '20px';
|
||||
widget.style.right = '20px';
|
||||
}
|
||||
},
|
||||
translation: function(field){
|
||||
return this.configuration['translation'] && this.configuration['translation'][field] ? this.configuration['translation'][field] : null;
|
||||
},
|
||||
identify: function(field){
|
||||
return this.configuration['identify'] && this.configuration['identify'][field] ? this.configuration['identify'][field] : null
|
||||
},
|
||||
load: function() {
|
||||
this.widget.addEventListener('click', function(){ RedmineHelpdeskWidget.toggle() });
|
||||
this.create_widget_button();
|
||||
this.decorate_widget_button();
|
||||
this.create_iframe();
|
||||
this.decorate_iframe();
|
||||
this.load_schema();
|
||||
this.created = true;
|
||||
},
|
||||
load_schema: function() {
|
||||
var xmlhttp = getXmlHttp();
|
||||
xmlhttp.open('GET', this.base_url + '/helpdesk_widget/load_form.json', true);
|
||||
xmlhttp.responseType = 'json';
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == 4) {
|
||||
if (xmlhttp.status == 200 || xmlhttp.status == 304) {
|
||||
RedmineHelpdeskWidget.schema = xmlhttp.response;
|
||||
RedmineHelpdeskWidget.fill_form();
|
||||
} else {
|
||||
RedmineHelpdeskWidget.schema = {};
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlhttp.send(null);
|
||||
},
|
||||
create_widget_button: function(){
|
||||
button = document.createElement('div');
|
||||
button.id = 'widget_button';
|
||||
button.className = 'widget_button';
|
||||
button.innerHTML = this.configuration['icon'] || '?';
|
||||
button.setAttribute('name', 'helpdesk_widget_button');
|
||||
button.style.backgroundColor = '#7E8387';
|
||||
button.style.backgroundSize = '15px 15px';
|
||||
button.style.cursor = 'pointer';
|
||||
button.style.color = 'white';
|
||||
button.style.textAlign = 'center';
|
||||
button.style.fontSize = '32px';
|
||||
button.style.verticalAlign = 'middle';
|
||||
button.style.lineHeight = '54px';
|
||||
button.style.borderRadius = '30px';
|
||||
button.style.boxShadow = 'rgba(0, 0, 0, 0.258824) 0px 2px 5px 0px';
|
||||
button.style.display = 'none';
|
||||
button.style.webkitTransition = "transform 0.2s ease";
|
||||
this.widget_button = button;
|
||||
this.widget.appendChild(button);
|
||||
},
|
||||
decorate_widget_button: function(){
|
||||
widget = this.widget;
|
||||
widget.style.position = 'fixed';
|
||||
widget.style.bottom = '20px';
|
||||
widget.style.right = '20px';
|
||||
widget.style.width = '54px';
|
||||
widget.style.height = '54px';
|
||||
widget.style.zIndex = 9999;
|
||||
},
|
||||
create_iframe: function(){
|
||||
this.iframe = document.createElement('iframe');
|
||||
this.widget.appendChild(this.iframe);
|
||||
},
|
||||
decorate_iframe: function(){
|
||||
iframe = this.iframe;
|
||||
iframe.setAttribute('id', 'helpdesk_ticket_container');
|
||||
iframe.setAttribute('width', this.width);
|
||||
iframe.setAttribute('height', 0);
|
||||
iframe.setAttribute('frameborder', 0);
|
||||
iframe.style.visibility = 'hidden';
|
||||
iframe.style.position = 'absolute';
|
||||
iframe.style.opacity = '0';
|
||||
iframe.style.width = this.width;
|
||||
iframe.style.backgroundColor = 'white';
|
||||
iframe.style.webkitTransition = "opacity 0.2s ease";
|
||||
iframe.style.boxShadow = 'rgba(0, 0, 0, 0.258824) 0px 1px 4px 0px';
|
||||
iframe.setAttribute('name', 'helpdesk_widget_iframe');
|
||||
},
|
||||
fill_form: function(){
|
||||
if (Object.keys(this.schema.projects).length > 0) {
|
||||
this.apply_avatar();
|
||||
this.create_form();
|
||||
this.create_form_title();
|
||||
this.create_error_flash();
|
||||
|
||||
if (this.identify('redmineUserID')) {
|
||||
this.create_form_hidden(this.form, 'redmine_user', 'redmine_user', 'form-control', this.identify('redmineUserID'));
|
||||
}
|
||||
if (this.identify('nameValue')) {
|
||||
this.create_form_hidden(this.form, 'username', 'username', 'form-control', this.identify('nameValue'));
|
||||
} else {
|
||||
this.create_form_text(this.form, 'username', 'username', this.translation('nameLabel') || '<%= t(:label_helpdesk_widget_name) %>', 'form-control', this.identify('nameValue'), true);
|
||||
}
|
||||
if (this.identify('emailValue')) {
|
||||
this.create_form_hidden(this.form, 'email', 'email', 'form-control', this.identify('emailValue'));
|
||||
} else {
|
||||
this.create_form_text(this.form, 'email', 'email' , this.translation('emailLabel') || '<%= t(:label_helpdesk_widget_email) %>', 'form-control', this.identify('emailValue'), true);
|
||||
}
|
||||
if (this.identify('subjectValue')) {
|
||||
this.create_form_hidden(this.form, 'subject', 'issue[subject]', 'form-control', this.identify('subjectValue'));
|
||||
} else {
|
||||
this.create_form_text(this.form, 'subject', 'issue[subject]' , this.translation('subjectLabel') || '<%= t(:label_helpdesk_widget_subject) %>', 'form-control', this.identify('subjectValue'), true);
|
||||
}
|
||||
this.create_projects_selector();
|
||||
this.create_form_area(this.form, 'description', 'issue[description]' , this.translation('descriptionLabel') || '<%= t(:label_helpdesk_widget_description) %>', 'form-control', true);
|
||||
|
||||
var project_id = null;
|
||||
var tracker_id = null;
|
||||
if (RedmineHelpdeskWidget.configuration['identify']){
|
||||
project_id = RedmineHelpdeskWidget.schema.projects[RedmineHelpdeskWidget.configuration['identify']['projectValue']];
|
||||
if (project_id) {
|
||||
tracker_id = RedmineHelpdeskWidget.schema.projects_data[project_id].trackers[RedmineHelpdeskWidget.configuration['identify']['trackerValue']];
|
||||
}
|
||||
}
|
||||
|
||||
this.load_project_data(project_id || this.schema.projects[Object.keys(this.schema.projects)[0]], tracker_id);
|
||||
this.iframe.contentWindow.document.body.appendChild(this.form);
|
||||
this.append_stylesheets();
|
||||
this.append_scripts();
|
||||
this.create_message_listener();
|
||||
} else {
|
||||
this.widget.style.display = 'none';
|
||||
}
|
||||
},
|
||||
apply_avatar: function(){
|
||||
button = document.getElementById('widget_button');
|
||||
avatar = RedmineHelpdeskWidget.configuration['user_avatar'];
|
||||
if (avatar && avatar.length > 0) {
|
||||
var xmlhttp = getXmlHttp();
|
||||
xmlhttp.open('GET', RedmineHelpdeskWidget.base_url + '/helpdesk_widget/avatar/' + avatar, true);
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == 4) {
|
||||
if (xmlhttp.status == 200 || xmlhttp.status == 304) {
|
||||
button.style.backgroundSize = 'cover';
|
||||
button.style.backgroundImage = 'url(' + RedmineHelpdeskWidget.base_url + '/helpdesk_widget/avatar/' + avatar + ')' ;
|
||||
button.style.border = '2px solid';
|
||||
button.innerHTML = ' ';
|
||||
} else {
|
||||
button.style.backgroundSize = '15px 15px';
|
||||
button.innerHTML = '?';
|
||||
}
|
||||
button.style.display = 'block';
|
||||
button.style.lineHeight = '50px';
|
||||
}
|
||||
};
|
||||
xmlhttp.send(null);
|
||||
} else {
|
||||
button.style.lineHeight = '54px';
|
||||
button.style.backgroundSize = '15px 15px';
|
||||
button.innerHTML = '?';
|
||||
button.style.display = 'block';
|
||||
}
|
||||
},
|
||||
append_stylesheets: function(){
|
||||
|
||||
if (this.configuration['styles']) {
|
||||
styles_css = document.createElement('style');
|
||||
styles_css.innerHTML = this.configuration['styles'];
|
||||
styles_css.type = "text/css";
|
||||
}
|
||||
widget_css = document.createElement('link');
|
||||
widget_css.href = this.base_url + '/helpdesk_widget/widget.css';
|
||||
widget_css.rel = "stylesheet";
|
||||
widget_css.type = "text/css";
|
||||
this.iframe.contentWindow.document.head.appendChild(widget_css);
|
||||
if (this.configuration['styles']) {
|
||||
this.iframe.contentWindow.document.head.appendChild(styles_css);
|
||||
}
|
||||
},
|
||||
append_scripts: function(){
|
||||
script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = this.base_url + '/helpdesk_widget/iframe.js';
|
||||
this.iframe.contentWindow.document.head.appendChild(script);
|
||||
|
||||
config_script = document.createElement('script');
|
||||
config_script.innerHTML = "var RedmineHelpdeskIframe = {configuration: "+ JSON.stringify(this.configuration) +"}";
|
||||
this.iframe.contentWindow.document.head.appendChild(config_script);
|
||||
},
|
||||
create_form: function(){
|
||||
this.form = document.createElement('form');
|
||||
this.form.action = this.base_url + '/helpdesk_widget/create_ticket';
|
||||
this.form.acceptCharset = 'UTF-8';
|
||||
this.form.method = 'post';
|
||||
this.form.id = 'widget_form';
|
||||
this.form.setAttribute('onSubmit', 'submitTicketForm(); return false;');
|
||||
this.form.style.marginBottom = 0;
|
||||
},
|
||||
create_form_title: function(){
|
||||
if (this.configuration['title']) {
|
||||
title_div = document.createElement('div');
|
||||
title_div.id = 'title';
|
||||
title_div.className = 'title';
|
||||
title_div.innerHTML = this.configuration['title'];
|
||||
this.form.appendChild(title_div);
|
||||
}
|
||||
},
|
||||
create_error_flash: function(){
|
||||
flash_div = document.createElement('div');
|
||||
flash_div.id = 'flash';
|
||||
flash_div.className = 'flash';
|
||||
this.form.appendChild(flash_div);
|
||||
},
|
||||
create_projects_selector: function(){
|
||||
var project_id = null;
|
||||
if (RedmineHelpdeskWidget.configuration['identify']){
|
||||
project_id = RedmineHelpdeskWidget.schema.projects[RedmineHelpdeskWidget.configuration['identify']['projectValue']];
|
||||
}
|
||||
if (project_id) {
|
||||
this.create_form_hidden(this.form, 'project_id', 'project_id', 'form-control projects', project_id);
|
||||
} else {
|
||||
this.create_form_select(this.form, 'project_id', 'project_id', RedmineHelpdeskWidget.schema.projects, project_id, 'form-control projects');
|
||||
}
|
||||
},
|
||||
load_project_data: function(project_id, tracker_id){
|
||||
container_div = this.form.getElementsByClassName('container')[0]
|
||||
if (container_div) { container_div.remove() };
|
||||
|
||||
container_div = document.createElement('div');
|
||||
container_div.id = 'container';
|
||||
container_div.className = 'container';
|
||||
|
||||
custom_div = document.createElement('div');
|
||||
custom_div.id = 'custom_fields';
|
||||
custom_div.className = 'custom_fields';
|
||||
|
||||
submit_div = document.createElement('div');
|
||||
submit_div.id = 'submit_button';
|
||||
submit_div.className = 'submit_button';
|
||||
|
||||
container_div.appendChild(custom_div);
|
||||
container_div.appendChild(submit_div);
|
||||
|
||||
if (RedmineHelpdeskWidget.configuration['identify'] && RedmineHelpdeskWidget.schema.projects_data[project_id].trackers[RedmineHelpdeskWidget.configuration['identify']['trackerValue']]){
|
||||
tracker_id = RedmineHelpdeskWidget.schema.projects_data[project_id].trackers[RedmineHelpdeskWidget.configuration['identify']['trackerValue']]
|
||||
this.create_form_hidden(custom_div, 'tracker_id', 'tracker_id', 'form-control trackers', tracker_id);
|
||||
} else {
|
||||
this.create_form_select(custom_div, 'tracker_id', 'tracker_id', this.schema.projects_data[project_id].trackers, tracker_id, 'form-control trackers');
|
||||
tracker_id = custom_div.getElementsByClassName('trackers')[0].value;
|
||||
}
|
||||
this.load_custom_fields(custom_div, project_id, tracker_id);
|
||||
|
||||
this.create_form_submit(submit_div, this.translation('createButtonLabel') || '<%= l(:label_helpdesk_widget_create_ticket) %>');
|
||||
this.create_attch_link(submit_div);
|
||||
|
||||
this.form.appendChild(container_div);
|
||||
},
|
||||
reload_project_data: function(){
|
||||
project_id = this.form.getElementsByClassName('projects')[0].value;
|
||||
tracker_id = container_div.getElementsByClassName('trackers')[0].value;
|
||||
|
||||
this.load_project_data(project_id, tracker_id);
|
||||
this.positionate_iframe();
|
||||
},
|
||||
create_form_select: function(target, field_id, field_name, values, selected, field_class){
|
||||
|
||||
if (Object.keys(values).length == 1) {
|
||||
field = document.createElement('input');
|
||||
field.type = 'hidden';
|
||||
field.id = field_id;
|
||||
field.name = field_name;
|
||||
field.className = field_class;
|
||||
field.value = values[Object.keys(values)[0]];
|
||||
} else {
|
||||
field = document.createElement('select');
|
||||
field.id = field_id;
|
||||
field.name = field_name;
|
||||
field.className = field_class;
|
||||
for (var project in values) {
|
||||
option = document.createElement('option');
|
||||
option.value = values[project]
|
||||
if(values[project] == selected) { option.selected = 'selected'; }
|
||||
option.innerHTML = project;
|
||||
field.appendChild(option);
|
||||
}
|
||||
}
|
||||
field.setAttribute('onChange', 'needReloadProjectData();');
|
||||
target.appendChild(field);
|
||||
},
|
||||
create_form_hidden: function(target, field_id, field_name, field_class, value){
|
||||
field = document.createElement('input');
|
||||
field.type = 'hidden';
|
||||
field.id = field_id;
|
||||
field.name = field_name;
|
||||
field.value = value;
|
||||
field.className = field_class;
|
||||
target.appendChild(field);
|
||||
},
|
||||
create_form_text: function(target, field_id, field_name, field_placeholder, field_class, value, required){
|
||||
field = document.createElement('input');
|
||||
field.type = 'text';
|
||||
field.id = field_id;
|
||||
field.name = field_name;
|
||||
field.value = value;
|
||||
field.placeholder = field_placeholder;
|
||||
field.className = required ? field_class + ' required-field' : field_class;
|
||||
target.appendChild(field);
|
||||
},
|
||||
create_form_area: function(target, field_id, field_name, field_placeholder, field_class, required){
|
||||
field = document.createElement('textarea');
|
||||
field.cols = 55;
|
||||
field.rows = 10;
|
||||
field.id = field_id;
|
||||
field.name = field_name;
|
||||
field.placeholder = field_placeholder;
|
||||
field.className = required ? field_class + ' required-field' : field_class;
|
||||
target.appendChild(field);
|
||||
},
|
||||
create_form_submit: function(target, label){
|
||||
field = document.createElement('input');
|
||||
field.id = 'form-submit-btn';
|
||||
field.type = 'submit';
|
||||
field.name = 'submit';
|
||||
field.className = 'btn';
|
||||
field.value = label;
|
||||
field.title = this.translation('buttomLabel') || '';
|
||||
if (RedmineHelpdeskWidget.configuration['color']) {
|
||||
field.style.background = RedmineHelpdeskWidget.configuration['color'];
|
||||
}
|
||||
target.appendChild(field);
|
||||
},
|
||||
create_attch_link: function(target){
|
||||
if (this.configuration['attachment'] != false ) {
|
||||
attach_div = document.createElement('div');
|
||||
attach_div.className = 'attach_div';
|
||||
|
||||
attach_link = document.createElement('a');
|
||||
attach_link.className = 'attach_link';
|
||||
attach_link.href = 'javascript:void(0)';
|
||||
attach_link.innerHTML = this.translation('attachmentLinkLabel') || 'Attach a file';
|
||||
attach_div.appendChild(attach_link);
|
||||
|
||||
attach_field = document.createElement('input');
|
||||
attach_field.type = 'file';
|
||||
attach_field.id = 'attachment';
|
||||
attach_field.className = 'attach_field';
|
||||
attach_field.name = 'attachment';
|
||||
attach_field.attributes['data-max-size'] = <%= Setting[:attachment_max_size].to_i * 1024 %>;
|
||||
attach_field.addEventListener('change', function(){ RedmineHelpdeskWidget.upload_file() });
|
||||
attach_div.appendChild(attach_field);
|
||||
this.attachment = attach_field;
|
||||
|
||||
target.appendChild(attach_div);
|
||||
}
|
||||
},
|
||||
upload_file: function(){
|
||||
if (this.attachment.attributes['data-max-size'] > this.attachment.files[0].size) {
|
||||
this.read_file(this.attachment.files[0], function(e){
|
||||
attach_field = RedmineHelpdeskWidget.form.getElementsByClassName('attach_field')[0]
|
||||
attach_field.attributes['data-value'] = e.target.result;
|
||||
displayed_name = (attach_field.files[0].name.length <= 20) ? attach_field.files[0].name : attach_field.files[0].name.substring(0, 20) + '...';
|
||||
RedmineHelpdeskWidget.form.getElementsByClassName('attach_link')[0].innerHTML = displayed_name;
|
||||
});
|
||||
} else {
|
||||
this.attachment.attributes['data-value'] = '';
|
||||
RedmineHelpdeskWidget.form.getElementsByClassName('attach_link')[0].innerHTML = '<%= t(:label_helpdesk_widget_file_large) %>';
|
||||
}
|
||||
},
|
||||
read_file: function(file, callback){
|
||||
var reader = new FileReader();
|
||||
reader.onload = callback
|
||||
reader.readAsDataURL(file);
|
||||
},
|
||||
load_custom_fields: function(target, project_id, tracker_id){
|
||||
var xmlhttp = getXmlHttp();
|
||||
var params = 'project_id=' + encodeURIComponent(project_id) + '&tracker_id=' + encodeURIComponent(tracker_id);
|
||||
custom_div = document.createElement('div');
|
||||
xmlhttp.open('GET', this.base_url + '/helpdesk_widget/load_custom_fields?' + params, true);
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (xmlhttp.readyState == 4) {
|
||||
if (xmlhttp.status == 200 || xmlhttp.status == 304) {
|
||||
custom_div.innerHTML = xmlhttp.responseText;
|
||||
target.appendChild(custom_div);
|
||||
RedmineHelpdeskWidget.set_custom_values();
|
||||
RedmineHelpdeskWidget.positionate_iframe();
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlhttp.send(null);
|
||||
},
|
||||
set_custom_values: function(){
|
||||
if (this.configuration['identify'] && this.configuration['identify']['customFieldValues']){
|
||||
for(var cf in this.configuration['identify']['customFieldValues']) {
|
||||
custom_field = this.form.querySelector('#issue_custom_field_values_' + this.schema.custom_fields[cf])
|
||||
if (custom_field){
|
||||
switch (custom_field.tagName){
|
||||
case 'INPUT':
|
||||
custom_field.type = 'hidden';
|
||||
custom_field.value = this.configuration['identify']['customFieldValues'][cf];
|
||||
this.form.querySelector("[data-error-key='" + cf + "']").style.display = 'none';
|
||||
break;
|
||||
case 'SELECT':
|
||||
options = custom_field.options;
|
||||
for(var option, index = 0; option = options[index]; index++) {
|
||||
if(option.value == this.configuration['identify']['customFieldValues'][cf]) {
|
||||
this.create_form_hidden(custom_field.parentElement, custom_field.id, custom_field.name, custom_field.classList.toString(), this.configuration['identify']['customFieldValues'][cf]);
|
||||
custom_field.remove();
|
||||
this.form.querySelector("[data-error-key='" + cf + "']").style.display = 'none';
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
positionate_iframe: function(){
|
||||
widget_height = this.form.offsetHeight > this.height ? this.height : this.form.offsetHeight;
|
||||
this.iframe.setAttribute('height', this.margin + widget_height);
|
||||
switch (this.configuration['position']) {
|
||||
case 'topLeft':
|
||||
this.iframe.style.top = (this.margin + this.widget_button.offsetWidth) + 'px';
|
||||
iframe.style.left = (this.margin - this.widget_button.offsetWidth / 2) + 'px';
|
||||
break;
|
||||
case 'topRight':
|
||||
this.iframe.style.top = (this.margin + this.widget_button.offsetWidth) + 'px';
|
||||
iframe.style.left = (this.margin + this.widget_button.offsetWidth - this.width - 20) + 'px';
|
||||
break;
|
||||
case 'bottomLeft':
|
||||
this.iframe.style.top = (- this.margin * 2 - widget_height) + 'px';
|
||||
iframe.style.left = (this.margin - this.widget_button.offsetWidth / 2) + 'px';
|
||||
break;
|
||||
case 'bottomRight':
|
||||
this.iframe.style.top = (- this.margin * 2 - widget_height) + 'px';
|
||||
iframe.style.left = (this.margin + this.widget_button.offsetWidth - this.width - 20) + 'px';
|
||||
break;
|
||||
default:
|
||||
this.iframe.style.top = (- this.margin * 2 - widget_height) + 'px';
|
||||
iframe.style.left = (this.margin + this.widget_button.offsetWidth - this.width - 20) + 'px';
|
||||
}
|
||||
},
|
||||
create_message_listener: function(){
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
var eventer = window[eventMethod];
|
||||
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
|
||||
|
||||
eventer(messageEvent,function(e) {
|
||||
data = JSON.parse(e.data);
|
||||
if (data['reload'] == true) {
|
||||
RedmineHelpdeskWidget.reload = true;
|
||||
}
|
||||
if (data['project_reload'] == true) {
|
||||
RedmineHelpdeskWidget.reload_project_data();
|
||||
}
|
||||
},false);
|
||||
},
|
||||
reload_form: function(){
|
||||
this.iframe.remove();
|
||||
this.create_iframe();
|
||||
this.fill_form();
|
||||
this.decorate_iframe();
|
||||
this.reload = false;
|
||||
},
|
||||
show: function() {
|
||||
this.iframe.style.visibility = 'visible';
|
||||
this.iframe.style.opacity = '1';
|
||||
this.positionate_iframe();
|
||||
switch (this.configuration['position']) {
|
||||
case 'topLeft':
|
||||
case 'topRight':
|
||||
this.widget_button.style.borderRadius = '50% 50% 0%';
|
||||
break;
|
||||
case 'bottomLeft':
|
||||
case 'bottomRight':
|
||||
this.widget_button.style.borderRadius = '0 100% 100%';
|
||||
break;
|
||||
default:
|
||||
this.widget_button.style.borderRadius = '0 100% 100%';
|
||||
}
|
||||
this.widget_button.style.webkitTransform = 'rotate(45deg)';
|
||||
this.widget_button.style.mozTransform = 'rotate(45deg)';
|
||||
this.widget_button.style.msTransform = 'rotate(45deg)';
|
||||
this.widget_button.style.oTransform = 'rotate(45deg)';
|
||||
},
|
||||
hide: function() {
|
||||
if (this.reload == true) {
|
||||
this.reload_form();
|
||||
}
|
||||
body = this.iframe.contentWindow.document.body;
|
||||
this.iframe.style.visibility = 'hidden';
|
||||
this.iframe.style.opacity = '0';
|
||||
this.widget_button.style.borderRadius = '30px';
|
||||
this.widget_button.style.webkitTransform = '';
|
||||
this.widget_button.style.mozTransform = '';
|
||||
this.widget_button.style.msTransform = '';
|
||||
this.widget_button.style.oTransform = '';
|
||||
},
|
||||
toggle: function() {
|
||||
(this.iframe.style.visibility == 'visible') ? this.hide() : this.show();
|
||||
}
|
||||
}
|
||||
|
||||
RedmineHelpdeskWidget.load();
|
||||
Reference in New Issue
Block a user