038ebfe14128a698af861ebd3b47e018c3eb36fb
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Resources / Public / JavaScript / Modules / UpgradeDocs.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Install/UpgradeDocs
16 */
17 define([
18 'jquery',
19 'TYPO3/CMS/Install/Router',
20 'TYPO3/CMS/Install/ProgressBar',
21 'TYPO3/CMS/Install/InfoBox',
22 'TYPO3/CMS/Install/Severity',
23 'TYPO3/CMS/Backend/Notification',
24 'bootstrap',
25 'chosen'
26 ], function($, Router, ProgressBar, InfoBox, Severity, Notification) {
27 'use strict';
28
29 return {
30 selectorModalBody: '.t3js-modal-body',
31 selectorContentContainer: '.t3js-upgradeDocs-content',
32 selectorMarkReadToken: '#t3js-upgradeDocs-markRead-token',
33 selectorUnmarkReadToken: '#t3js-upgradeDocs-unmarkRead-token',
34 selectorRestFileItem: '.upgrade_analysis_item_to_filter',
35 selectorFulltextSearch: '.t3js-upgradeDocs-fulltext-search',
36 selectorChosenField: '.t3js-upgradeDocs-chosen-select',
37
38 chosenField: null,
39 fulltextSearchField: null,
40
41 initialize: function(currentModal) {
42 var self = this;
43 this.currentModal = currentModal;
44 var isInIframe = (window.location != window.parent.location) ? true : false;
45 if (isInIframe) {
46 top.require(['TYPO3/CMS/Install/chosen.jquery.min'], function () {
47 self.getContent();
48 });
49 }
50 else {
51 self.getContent();
52 }
53
54 // Mark a file as read
55 currentModal.on('click', '.t3js-upgradeDocs-markRead', function(e) {
56 self.markRead(e.target);
57 });
58 currentModal.on('click', '.t3js-upgradeDocs-unmarkRead', function(e) {
59 self.unmarkRead(e.target);
60 });
61
62 // Make jquerys "contains" work case-insensitive
63 jQuery.expr[':'].contains = jQuery.expr.createPseudo(function(arg) {
64 return function(elem) {
65 return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
66 };
67 });
68 },
69
70 getContent: function() {
71 var self = this;
72 var modalContent = this.currentModal.find(self.selectorModalBody);
73 var outputContainer = $(this.selectorContentContainer);
74 var message = ProgressBar.render(Severity.loading, 'Loading...', '');
75 outputContainer.empty().html(message);
76 $.ajax({
77 url: Router.getUrl('upgradeDocsGetContent'),
78 cache: false,
79 success: function(data) {
80 if (data.success === true && data.html !== 'undefined' && data.html.length > 0) {
81 modalContent.empty().append(data.html);
82 modalContent.find('[data-toggle="tooltip"]').tooltip({container: 'body'});
83 self.chosenField = modalContent.find(self.selectorChosenField);
84 self.fulltextSearchField = modalContent.find(self.selectorFulltextSearch);
85 self.initializeChosenSelector();
86 self.chosenField.on('change', function() {
87 self.combinedFilterSearch();
88 });
89 self.fulltextSearchField.on('keyup', function() {
90 self.combinedFilterSearch();
91 });
92 self.renderTags();
93 } else {
94 Notification.error('Something went wrong');
95 }
96 },
97 error: function(xhr) {
98 Router.handleAjaxError(xhr);
99 }
100 });
101 },
102
103 initializeChosenSelector: function() {
104 var self = this;
105 var tagString = '';
106 $(self.currentModal.find(this.selectorRestFileItem)).each(function() {
107 tagString += $(this).data('item-tags') + ',';
108 });
109 var tagArray = this.trimExplodeAndUnique(',', tagString).sort(function(a, b) {
110 // Sort case-insensitive by name
111 return a.toLowerCase().localeCompare(b.toLowerCase());
112 });
113 $.each(tagArray, function(i, tag) {
114 self.chosenField.append('<option>' + tag + '</option>');
115 });
116 var config = {
117 '.chosen-select': {width: "100%", placeholder_text_multiple: "tags"},
118 '.chosen-select-deselect': {allow_single_deselect: true},
119 '.chosen-select-no-single': {disable_search_threshold: 10},
120 '.chosen-select-no-results': {no_results_text: 'Oops, nothing found!'},
121 '.chosen-select-width': {width: "100%"}
122 };
123 for (var selector in config) {
124 self.currentModal.find(selector).chosen(config[selector]);
125 }
126 this.chosenField.trigger('chosen:updated');
127 },
128
129 combinedFilterSearch: function() {
130 var self = this;
131 var modalContent = this.currentModal.find(self.selectorModalBody);
132 var $items = modalContent.find('div.item');
133 if (this.chosenField.val().length < 1 && this.fulltextSearchField.val().length < 1) {
134 $('.panel-version:not(:first) > .panel-collapse').collapse('hide');
135 $items.removeClass('hidden searchhit filterhit');
136 return false;
137 }
138 $items.addClass('hidden').removeClass('searchhit filterhit');
139
140 // apply tags
141 if (self.chosenField.val().length > 0) {
142 $items
143 .addClass('hidden')
144 .removeClass('filterhit');
145 var orTags = [];
146 var andTags = [];
147 $.each(self.chosenField.val(), function(index, item) {
148 var tagFilter = '[data-item-tags*="' + item + '"]';
149 if (item.indexOf(':') > 0) {
150 orTags.push(tagFilter);
151 } else {
152 andTags.push(tagFilter);
153 }
154 });
155 var andString = andTags.join('');
156 var tags = [];
157 if (orTags.length) {
158 for (var i = 0; i < orTags.length; i++) {
159 tags.push(andString + orTags[i]);
160 }
161 } else {
162 tags.push(andString);
163 }
164 var tagSelection = tags.join(',');
165 modalContent.find(tagSelection)
166 .removeClass('hidden')
167 .addClass('searchhit filterhit');
168 } else {
169 $items
170 .addClass('filterhit')
171 .removeClass('hidden');
172 }
173 // apply fulltext search
174 var typedQuery = self.fulltextSearchField.val();
175 modalContent.find('div.item.filterhit').each(function() {
176 var $item = $(this);
177 if ($(':contains(' + typedQuery + ')', $item).length > 0 || $('input[value*="' + typedQuery + '"]', $item).length > 0) {
178 $item.removeClass('hidden').addClass('searchhit');
179 } else {
180 $item.removeClass('searchhit').addClass('hidden');
181 }
182 });
183
184 modalContent.find('.searchhit').closest('.panel-collapse').collapse('show');
185
186 //check for empty panels
187 modalContent.find('.panel-version').each(function() {
188 if ($(this).find('.searchhit', '.filterhit').length < 1) {
189 $(this).find(' > .panel-collapse').collapse('hide');
190 }
191 });
192 },
193
194 renderTags: function() {
195 $.each($(this.currentModal.find(this.selectorRestFileItem)), function() {
196 var $me = $(this);
197 var tags = $me.data('item-tags').split(',');
198 var $tagContainer = $me.find('.t3js-tags');
199 tags.forEach(function(value) {
200 $tagContainer.append($('<span />', {'class': 'label'}).text(value));
201 });
202 });
203 },
204
205 markRead: function(element) {
206 var self = this;
207 var executeToken = self.currentModal.find(this.selectorMarkReadToken).text();
208 var $button = $(element).closest('a');
209 $button.toggleClass('t3js-upgradeDocs-unmarkRead t3js-upgradeDocs-markRead');
210 $button.find('i').toggleClass('fa-check fa-ban');
211 $button.closest('.panel').appendTo(self.currentModal.find('.panel-body-read'));
212 $.ajax({
213 method: 'POST',
214 url: Router.getUrl(),
215 data: {
216 'install': {
217 'ignoreFile': $button.data('filepath'),
218 'token': executeToken,
219 'action': 'upgradeDocsMarkRead'
220 }
221 },
222 error: function(xhr) {
223 Router.handleAjaxError(xhr);
224 }
225 });
226 },
227
228 unmarkRead: function(element) {
229 var self = this;
230 var executeToken = self.currentModal.find(this.selectorUnmarkReadToken).text();
231 var $button = $(element).closest('a');
232 var version = $button.closest('.panel').data('item-version');
233 $button.toggleClass('t3js-upgradeDocs-markRead t3js-upgradeDocs-unmarkRead');
234 $button.find('i').toggleClass('fa-check fa-ban');
235 $button.closest('.panel').appendTo(self.currentModal.find('*[data-group-version="' + version + '"] .panel-body'));
236 $.ajax({
237 method: 'POST',
238 url: Router.getUrl(),
239 data: {
240 'install': {
241 'ignoreFile': $button.data('filepath'),
242 'token': executeToken,
243 action: 'upgradeDocsUnmarkRead'
244 }
245 },
246 error: function(xhr) {
247 Router.handleAjaxError(xhr);
248 }
249 });
250 },
251
252 trimExplodeAndUnique: function(delimiter, string) {
253 var result = [];
254 var items = string.split(delimiter);
255 for (var i = 0; i < items.length; i++) {
256 var item = items[i].trim();
257 if (item.length > 0) {
258 if ($.inArray(item, result) === -1) {
259 result.push(item);
260 }
261 }
262 }
263 return result;
264 }
265 };
266 });