Skip to content

Commit

Permalink
Merge pull request akiko-pusu#352 from akiko-pusu/develop
Browse files Browse the repository at this point in the history
Update JavaScript code in preparation for jQuery update of Redmine.
  • Loading branch information
akiko-pusu authored Jun 21, 2020
2 parents dd5b554 + 0333527 commit f1bff1c
Show file tree
Hide file tree
Showing 19 changed files with 436 additions and 309 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:2.5
FROM ruby:2.6
LABEL maintainer="AKIKO TAKANO / (Twitter: @akiko_pusu)" \
description="Image to run Redmine simply with sqlite to try/review plugin."

Expand Down
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Plugin to generate and use issue templates for each project to assist issue
creation. The latest version 1.0.x **is not compatible with IE11**. (Related: #310)
Please use version 0.3.7 or **0.3-stable branch** (uing jQuery version) as a stable release for Redmine4.x.
Please use version 0.3.8 or **[0.3-stable](https://github.com/akiko-pusu/redmine_issue_templates/tree/0.3-stable) branch** (uing jQuery version) as a stable release for Redmine4.x.

## Repository

Expand Down Expand Up @@ -112,6 +112,15 @@ If you have any requests, bug reports, please use GitHub issues. <https://github

## Changelog

### 1.0.3

NOTE: Mainly, maintenance, bugfix and refactoring only. There is no additional feature.

* Refactor JavaScript to work properly under jQuery 3.x (for Redmine trunk).
* Add some feature specs to test Builtin-fields support.

RESTRICTION: This version **is still not compatible with IE11**. (Related: #310)

### 1.0.2

Release to implememted Global note templates feature.
Expand Down Expand Up @@ -143,7 +152,7 @@ Thank you for the valuable information and feedback, @AlUser71!
### 1.0.0

RESTRICTION: This version **is not compatible with IE11**. (Related: #310)
Please use version **0.3.7** or **0.3-stable branch** (uing jQuery version) if you need to support IE11.
Please use version **0.3.8** or **[0.3-stable](https://github.com/akiko-pusu/redmine_issue_templates/tree/0.3-stable) branch** (uing jQuery version) if you need to support IE11.

NOTE: **Migration is required**.
Since ``Support Built-In / Custom Fields`` is an experimental feature, please **be careful** if you hope to try it.
Expand All @@ -156,6 +165,17 @@ Since ``Support Built-In / Custom Fields`` is an experimental feature, please **
And some browsers may not work fine because Support Built-In / Custom Fields feature uses Vue.js for frontend.
So feedback, issue report, suggestion highly appreciate!

### 0.3.8

This is bugfix release.

* Bugfix: Fix that Issue Templates plugin changes the cursor icon for "Information" menu on Redmine's administration page (by vividtone, GitHub #316)
* Bugfix: Orphaned template list is not displayed (GitHub #337)
* Update Russian translation (GitHub #340)
* Update Bulgarian translation (GitHub #329)
* Update Korean translation (update Korean translation)
* Bugfix: enabled to create a new issue template setting. (GitHub #322)

### 0.3.7

This is bugfix release to prevent the conflict with other plugins.
Expand All @@ -165,7 +185,6 @@ This is bugfix release to prevent the conflict with other plugins.

Thank you for the valuable information and feedback, @ChrisUHZ!


### 0.3.6

This is bugfix release against v0.3.5.
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/issue_templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def add_templates_to_group(templates, option = {})
end

def issue_templates
if params[:issue_project_id]
@project = Project.find(params[:issue_project_id])
end
IssueTemplate.get_templates_for_project_tracker(@project.id, @tracker.id)
end

Expand Down
2 changes: 1 addition & 1 deletion app/views/common/_orphaned.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h3 class='template_tracker'><%= l(:orphaned_template) %></h3>
<table class='list template_list issues'>
<table class='list issues template_list'>
<thead>
<tr>
<th>#</th>
Expand Down
2 changes: 1 addition & 1 deletion app/views/global_issue_templates/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<div class='template_box'>
<h3 class='template_tracker'><%= tracker.name %></h3>

<table class='list template_list issues ui-sortable table-sortable'>
<table class='list issues template_list ui-sortable table-sortable'>
<thead>
<tr>
<th>#</th>
Expand Down
6 changes: 3 additions & 3 deletions app/views/issue_templates/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<div id="json_generator">
<p>
<label><%= l(:label_select_field, default: 'Select a field') %></label>
<select v-model='newItemTitle'>
<select v-model='newItemTitle' id='field_selector'>
<option v-for='(value, key) in customFields' v-bind:value='key'>
{{ value.name }}
</option>
Expand All @@ -73,7 +73,7 @@
</a>
</p>
<p>
<label><%= l(:field_value) %></label>
<label for='value_selector'><%= l(:field_value) %></label>
<textarea id='issue_template_json_setting_field' v-if='fieldFormat() == "text"' rows=6
placeholder='<%= l(:enter_value, default: 'Please enter a value') %>' v-model='newItemValue'>
</textarea>
Expand All @@ -93,7 +93,7 @@
</select>

<select v-model='newItemValue' :multiple='customFields[newItemTitle].multiple == true'
v-if='fieldFormat() == "list" || fieldFormat() == "bool"'>
v-if='fieldFormat() == "list" || fieldFormat() == "bool"' id='value_selector'>
<option v-for="value in possibleValues()">{{ value }}</option>
</select>
<span style='margin-left: 4px;' class='icon icon-add' v-on:click='addField(newItemTitle, newItemValue)'>
Expand Down
166 changes: 79 additions & 87 deletions app/views/issue_templates/_issue_select_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@
<h2><span id='issue_template_dialog_title'></span><a class="close" href="#">&times;</a></h2>
</div>
</div>
<label for='template_search_filter'>
<%=h l(:label_filter_template, default: 'Filter template:') %>
</label>
<input type='text' name='template_search_filter'
id='template_search_filter' class='autocomplete'>
<div class='template_search_filter_wrapper'>
<label for='template_search_filter'>
<%=h l(:label_filter_template, default: 'Filter template:') %>
</label>
<input type='text' name='template_search_filter' id='template_search_filter' class='autocomplete'>
</div>
<div id='filtered_templates_list'></div>
</div>
</div>
Expand Down Expand Up @@ -72,91 +73,82 @@
</div>
<script type='text/javascript'>
//<![CDATA[
let pulldown_url = '<%= pulldown_url %>'
let tracker = '<%= @issue.tracker.id %>'
let is_triggered_by = '<%= is_triggered_by %>'
let load_url = '<%= url_for(controller: 'issue_templates', action: 'load',
project_id: project_id, is_triggered_by: is_triggered_by) %>'
let should_replaced = '<%= setting.should_replaced %>'
let confirmToReplace = true
let confirmation = '<%=h l(:label_confirmation) %>'
let general_text_Yes = '<%=h l(:general_text_Yes) %>'
let general_text_No = '<%=h l(:general_text_No) %>'
let confirm_message = undefined
if (should_replaced) {
confirm_message = '<%=h l(:label_template_applied, default: "Issue template is applied. You can revert with click 'Revert' link.") %>'
}

let templateNS = new ISSUE_TEMPLATE(
pulldown_url, load_url, confirm_message, should_replaced, confirmToReplace,
confirmation, general_text_Yes, general_text_No, is_triggered_by
)

templateNS.set_pulldown(tracker)

document.getElementById('issue_template').addEventListener('change', (event) => {
templateNS.changeTemplatePlace()
templateNS.load_template()
})

// Show dialog
document.getElementById('link_template_dialog').addEventListener('click', (event) => {
let template_list_url = '<%= url_for(controller: 'issue_templates',
action:'list_templates', project_id: project_id, issue_tracker_id: @issue.tracker.id) %>'
let template_list_title = '<%= "#{l(:issue_template)}: #{@issue.tracker.name}".html_safe %>'

templateNS.openDialog(template_list_url, template_list_title)
})

// revert template
document.getElementById('revert_template').addEventListener('click', (event) => {
templateNS.revertAppliedTemplate()
})

document.getElementById('erase_template').addEventListener('click', (event) => {
templateNS.eraseSubjectAndDescription()
})

// keydown keyup
document.querySelector("input[name='template_search_filter']").addEventListener('keydown', (event) => {
templateNS.filterTemplate(event)
})

document.querySelector("input[name='template_search_filter']").addEventListener('keyup', (event) => {
templateNS.filterTemplate(event)
})

// NOTE: Workaround for GitHub issue: 193
// Start observing the target node for configured mutations
try {
if (CKEDITOR.instances) {
// Create an observer instance linked to the callback function
let observer = new MutationObserver(callback)

// Select the node that will be observed for mutations
let targetNode = document.querySelector('#issue_description_and_toolbar')

// Options for the observer (which mutations to observe)
let config = { attributes: true, childList: true, characterData: true, subtree: true }

// Callback function to execute when mutations are observed
let callback = function (mutationsList) {
for (let i = 0, len = mutationsList.length; i < len; ++i) {
let mutation = mutationsList[i]
if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.')
if (mutation.target.className == 'cke_contents cke_reset') {
// Wait for a while til CKE Editor's textarea is rendered, and after that
// apply template text.
setTimeout('templateNS.replaceCkeContent()', 200)
observer.disconnect()
}
var templateConfig = {
pulldownUrl: '<%= pulldown_url %>',
isTriggeredBy: '<%= is_triggered_by %>',
loadUrl: '<%= url_for(controller: 'issue_templates', action: 'load', project_id: project_id, is_triggered_by: is_triggered_by) %>',
shouldReplaced: '<%= setting.should_replaced %>',
generalTextYes: '<%=h l(:general_text_Yes) %>',
generalTextNo : '<%=h l(:general_text_No) %>',
confirmMessage: '<%=h l(:label_template_applied, default: "Issue template is applied. You can revert with click 'Revert' link.") %>'
}

var templateNS = templateNS || new ISSUE_TEMPLATE(templateConfig);
templateNS.setPulldown('<%= @issue.tracker.id %>')

document.getElementById('issue_template').addEventListener('change', (event) => {
templateNS.changeTemplatePlace()
templateNS.loadTemplate()
})

// Show dialog
document.getElementById('link_template_dialog').addEventListener('click', (event) => {
let templateListUrl = '<%= url_for(controller: 'issue_templates',
action:'list_templates', project_id: project_id, issue_tracker_id: @issue.tracker.id) %>'
let templateListTitle = '<%= "#{l(:issue_template)}: #{@issue.tracker.name}".html_safe %>'

templateNS.openDialog(templateListUrl, templateListTitle)
})

// revert template
document.getElementById('revert_template').addEventListener('click', (event) => {
templateNS.revertAppliedTemplate()
})

document.getElementById('erase_template').addEventListener('click', (event) => {
templateNS.eraseSubjectAndDescription()
})

// keydown keyup
document.querySelector("input[name='template_search_filter']").addEventListener('keydown', (event) => {
templateNS.filterTemplate(event)
})

document.querySelector("input[name='template_search_filter']").addEventListener('keyup', (event) => {
templateNS.filterTemplate(event)
})

// NOTE: Workaround for GitHub issue: 193
// Start observing the target node for configured mutations
try {
if (CKEDITOR.instances) {
// Create an observer instance linked to the callback function
let observer = new MutationObserver(callback)

// Select the node that will be observed for mutations
let targetNode = document.querySelector('#issue_description_and_toolbar')

// Options for the observer (which mutations to observe)
let config = { attributes: true, childList: true, characterData: true, subtree: true }

// Callback function to execute when mutations are observed
let callback = function (mutationsList) {
for (let i = 0, len = mutationsList.length; i < len; ++i) {
let mutation = mutationsList[i]
if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.')
if (mutation.target.className == 'cke_contents cke_reset') {
// Wait for a while til CKE Editor's textarea is rendered, and after that
// apply template text.
setTimeout('templateNS.replaceCkeContent()', 200)
observer.disconnect()
}
}
}
observer.observe(targetNode, config)
}
} catch (e) {
// do nothing.
observer.observe(targetNode, config)
}
} catch (e) {
// do nothing.
}
</script>
Loading

0 comments on commit f1bff1c

Please sign in to comment.