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