773c116224e34963c1ebc790cad2bc45e70e433e
[Packages/TYPO3.CMS.git] / typo3 / sysext / em / res / js / em_locallist.js
1 /***************************************************************
2 * Copyright notice
3 *
4 * (c) 2010 Steffen Kamper <info@sk-typo3.de>
5 * All rights reserved
6 *
7 * This script is part of the TYPO3 project. The TYPO3 project is
8 * free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The GNU General Public License can be found at
14 * http://www.gnu.org/copyleft/gpl.html.
15 *
16 * This script is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * This copyright notice MUST APPEAR in all copies of the script!
22 ***************************************************************/
23
24 /**
25 * ExtJS for the extension manager.
26 *
27 *
28 * @author Steffen Kamper <info@sk-typo3.de>
29 * @package TYPO3
30 * @subpackage extension manager
31 */
32 Ext.ns('TYPO3.EM', 'TYPO3.EM.GridColumns');
33
34 TYPO3.EM.LocalList = Ext.extend(Ext.grid.GridPanel, {
35 border: false,
36 plain: true,
37 stripeRows: true,
38 stateful: true,
39 stateId: 'LocalList',
40 stateEvents: ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
41 bodyStyle: 'padding: 10px;',
42
43 rowExpander: new Ext.ux.grid.RowPanelExpander({
44 hideable: false,
45 id: 'LocalListExpander',
46 createExpandingRowPanelItems: function(record, rowIndex) {
47 var panelItems = [
48 new Ext.TabPanel({
49 plain: true,
50 activeTab: 0,
51 tabPosition: 'top',
52 enableTabScroll: true,
53 autoWidth: true,
54 plugins: [new Ext.ux.plugins.FitWidthToParent()],
55 defaults: {
56 cls: 'gridrowpanel',
57 height: 250
58 },
59 record: record,
60 items:[
61 {
62 title: TYPO3.l10n.localize('msg_info'),
63 html: TYPO3.EM.Layouts.showExtInfo(record.data),
64 listeners: {
65 activate: function(panel) {
66 var updateScriptLink = Ext.fly('update-check-' + record.data.extkey);
67 if (updateScriptLink) {
68 updateScriptLink.on('click', function() {
69 panel.getEl().mask('loading');
70 TYPO3.EM.ExtDirect.getExtensionUpdateScript(record.data.extkey, function(response) {
71 panel.getEl().unmask();
72 if (response.success) {
73 var w = new Ext.Window({
74 maximized: true,
75 layout: 'fit',
76 title: TYPO3.l10n.localize('ext_details_updateScript') + ' (' + record.data.extkey + ')',
77 items: [
78 {
79 xtype: 'iframePanel',
80 id: 'updateScript-' + record.data.extkey
81 }
82 ]
83 }).show(true, function() {
84 Ext.getCmp('updateScript-' + record.data.extkey).setUrl('mod.php?M=tools_em&nodoc=1&CMD[showExt]=' + record.data.extkey + '&SET[singleDetails]=updateModule');
85 });
86 } else {
87 TYPO3.Flashmessage.display(TYPO3.Severity.information, TYPO3.l10n.localize('cmd_update'), TYPO3.l10n.localize('repository_update_not_needed'), 5);
88 }
89 });
90 }, this);
91 }
92
93 }
94 }
95 },
96 {
97 title: TYPO3.l10n.localize('msg_dbupdate'),
98 html: TYPO3.EM.App.loadingIndicor,
99 xtype: 'form',
100 disabled: record.data.installed === 0,
101 listeners: {
102 activate: function(panel) {
103 panel.update(TYPO3.EM.App.loadingIndicor);
104 TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
105 panel.update(response, true, this.readUpdateForm.createDelegate(this));
106 }, this);
107 }
108 },
109 scope: this,
110 readUpdateForm: function() {
111 var button = Ext.get('update-submit-' + record.data.extkey);
112 Ext.apply(this.form, {
113 api: {
114 submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
115 },
116 paramsAsHash: false
117 });
118 if (button) {
119 button.on('click', function() {
120 this.doUpdate(false);
121 }, this);
122 }
123 },
124 doUpdate: function(noSave) {
125 this.form.submit({
126 waitMsg : noSave ? ' ' : TYPO3.l10n.localize('action_updateDatabase'),
127 params: {
128 extkey: record.data.extkey,
129 exttype: record.data.typeShort,
130 noSave: noSave
131 },
132 success: function(form, action) {
133 this.ownerCt.activeTab.update(TYPO3.EM.App.loadingIndicor);
134 TYPO3.EM.ExtDirect.getExtensionUpdate(record.data.extkey, function(response) {
135 this.ownerCt.activeTab.update(response, true, this.readUpdateForm.createDelegate(this));
136 }, this);
137 },
138 failure: function(form, action) {
139 if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
140 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('msg_error'),
141 TYPO3.l10n.localize('msg_error') + ':' + action.response.status + ': ' +
142 action.response.statusText, 5);
143 }
144 if (action.failureType === Ext.form.Action.SERVER_INVALID) {
145 // server responded with success = false
146 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('invalid'), action.result.errormsg, 5);
147 }
148 },
149 scope: this
150 });
151 }
152 },
153 {
154 title: TYPO3.l10n.localize('msg_configuration'),
155 xtype: 'form',
156 disabled: record.data.installed === 0,
157 html: TYPO3.EM.App.loadingIndicor,
158 listeners: {
159 activate: function(panel) {
160 panel.update(TYPO3.EM.App.loadingIndicor);
161 TYPO3.EM.ExtDirect.getExtensionConfiguration(record.data.extkey, function(response) {
162 panel.update(response, true, this.readConfigForm.createDelegate(this));
163 }, this);
164 }
165 },
166 scope: this,
167 readConfigForm: function() {
168 var button = Ext.get('configuration-submit-' + record.data.extkey);
169 if (!button) {
170 var button = Ext.get('update-submit-' + record.data.extkey);
171 }
172 var select = Ext.select('.mod-menu-template-select');
173 Ext.apply(this.form, {
174 api: {
175 submit: TYPO3.EM.ExtDirect.saveExtensionConfiguration
176 },
177 paramsAsHash: false
178 });
179 if (select) {
180 var converted = new Ext.form.ComboBox({
181 transform: select.elements[0],
182 typeAhead: true,
183 listeners: {
184 beforequery: function(o) {
185 o.forceAll = true;
186 },
187 select: function() {
188 this.doSubmit(true);
189 },
190 scope: this
191 }
192 });
193 }
194 if (button) {
195 button.on('click', function() {
196 this.doSubmit(false);
197 }, this);
198 }
199 },
200 doSubmit: function(noSave) {
201 this.form.submit({
202 waitMsg : noSave ? ' ' : TYPO3.l10n.localize('action_saving_settings'),
203 params: {
204 extkey: record.data.extkey,
205 exttype: record.data.typeShort,
206 noSave: noSave
207 },
208 success: function(form, action) {
209 if (action.result.html) {
210 this.ownerCt.activeTab.update(action.result.html, true, this.readConfigForm.createDelegate(this));
211 } else {
212 TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.l10n.localize('msg_configuration'), TYPO3.l10n.localize('configurationSaved'), 5);
213 }
214 },
215 failure: function(form, action) {
216 if (action.failureType === Ext.form.Action.CONNECT_FAILURE) {
217 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('msg_error'),
218 TYPO3.l10n.localize('msg_error') + ':' + action.response.status + ': ' +
219 action.response.statusText, 5);
220 }
221 if (action.failureType === Ext.form.Action.SERVER_INVALID) {
222 // server responded with success = false
223 TYPO3.Flashmessage.display(TYPO3.Severity.error, TYPO3.l10n.localize('invalid'), action.result.errormsg, 5);
224 }
225 },
226 scope: this
227 });
228 }
229 },
230 {
231 title: TYPO3.l10n.localize('msg_files'),
232 xtype: 'extfilelist',
233 recordData: record.data,
234 cls: 'gridrowfilespanel'
235 },
236 {
237 xtype: 'terupload',
238 title: TYPO3.l10n.localize('cmd_terupload'),
239 recordData: record.data,
240 disabled: !TYPO3.settings.EM.hasCredentials
241 },
242 {
243 title: TYPO3.l10n.localize('msg_developerinformation'),
244 html: '<div class="loading-indicator">' + TYPO3.l10n.localize('action_loading') + '</div>',
245 listeners: {
246 activate: function(panel) {
247 TYPO3.EM.ExtDirect.getExtensionDevelopInfo(record.data.extkey, function(response) {
248 panel.update(response);
249 });
250 }
251 }
252 },
253 {
254 title: TYPO3.l10n.localize('details_maintenance'),
255 html: TYPO3.EM.App.loadingIndicor,
256 listeners: {
257 activate: function(panel) {
258 TYPO3.EM.ExtDirect.getExtensionBackupDelete(record.data.extkey, function(response) {
259 panel.update(response, true, this.readBackupDeleteLinks.createDelegate(this));
260 }, this);
261 }
262 },
263 scope: this,
264 readBackupDeleteLinks: function() {
265 var emconflink = Ext.select('a.emconfLink');
266 if (emconflink.elements.length) {
267 var link = emconflink.elements[0];
268 link.removeAttribute('onclick');
269 Ext.get(link).on('click', function() {
270 this.waitBox = Ext.Msg.wait(TYPO3.l10n.localize('ext_details_update_em_conf'), record.data.extkey);
271 TYPO3.EM.ExtDirect.cleanEmConf(record.data.extkey, function(response) {
272 this.waitBox.hide();
273 TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.l10n.localize('ext_details_update_em_conf'), response.result, 5);
274 }, this);
275 });
276 }
277 var deletelink = Ext.select('a.deleteLink');
278 if (deletelink.elements.length) {
279 var link = deletelink.elements[0];
280 link.removeAttribute('onclick');
281 Ext.get(link).on('click', function() {
282 this.waitBox = Ext.Msg.wait(TYPO3.l10n.localize('extDelete_from_server'), record.data.extkey);
283 TYPO3.EM.ExtDirect.deleteExtension(record.data.extkey, function(response) {
284 this.waitBox.hide();
285 if (response.success) {
286 TYPO3.Flashmessage.display(TYPO3.Severity.ok, TYPO3.l10n.localize('msg_extkexDeletedSuccess'), response.result, 5);
287 Ext.StoreMgr.get('localstore').remove(record);
288 } else {
289 TYPO3.Flashmessage.display(TYPO3.Severity.error, response.error, response.result, 5);
290 }
291 }, this);
292 });
293 }
294
295 }
296 }
297 ]
298 })
299 ];
300 return panelItems;
301 }
302 }),
303
304 initComponent:function() {
305 this.localstore = new Ext.data.GroupingStore({
306 storeId: 'localstore',
307 proxy: new Ext.data.DirectProxy({
308 directFn: TYPO3.EM.ExtDirect.getExtensionList
309 }),
310 autoLoad: false,
311 reader: new Ext.data.JsonReader({
312 idProperty: 'extkey',
313 root: 'data',
314 totalProperty: 'length',
315 fields:[
316 {name:'install'},
317 {name:'title'},
318 {name:'extkey'},
319 {name:'category'},
320 {name:'version'},
321 {name:'type'},
322 {name:'state'},
323 {name:'stateCls'},
324 {name:'icon'},
325 {name:'description'},
326 {name:'shy'},
327 {name:'installed'},
328 {name:'author'},
329 {name:'author_email'},
330 {name:'author_company'},
331 {name:'download'},
332 {name:'doc'},
333 {name:'typeShort'},
334 {name:'nodePath'},
335 {name:'reviewstate'},
336 {name:'required'},
337 {name:'doubleInstall'},
338 {name:'doubleInstallShort'},
339 {name:'updateModule'},
340 {name:'doNotLoadInFE'},
341 {name:'depends'},
342 {name:'conflicts'},
343 {name:'suggests'},
344 {name:'versionislower'},
345 {name:'maxversion'}
346 ]
347 }),
348
349 sortInfo:{
350 field: 'title',
351 direction: 'ASC'
352 },
353 remoteSort: false,
354 groupField: 'category',
355 showAction: false,
356 listeners: {
357 beforeload: function() {
358
359 },
360 datachanged: function(store) {
361 Ext.getCmp('displayExtensionLabel').setText(TYPO3.l10n.localize('extensions') + ' ' + store.data.length);
362 var hasFilters = store.hasStoreFilter();
363 TYPO3.EM.Filters.filters.each(function (filter) {
364 if (filter.active) {
365 hasFilters = true;
366 }
367 });
368 if (hasFilters) {
369 this.doClearFilters.show();
370 this.doClearFiltersSeperator.show();
371 } else {
372 this.doClearFilters.hide();
373 this.doClearFiltersSeperator.hide();
374 }
375 if (!TYPO3.settings.EM.hide_obsolete && !TYPO3.settings.EM.hide_shy && !TYPO3.settings.EM.display_installed && !TYPO3.settings.EM.display_updatable) {
376 this.filterMenuButton.removeClass('bold');
377 } else {
378 this.filterMenuButton.addClass('bold');
379 }
380 },
381 load: function(store) {
382 TYPO3.EM.App.refreshLocalList = false;
383 if (store.showAction) {
384 this.showExtension.defer(500, this);
385 }
386 },
387
388 scope: this
389 },
390 validateRecord: function(record) {
391 var control = Ext.getCmp('localSearchField');
392 if (control) {
393 var filtertext = control.getRawValue();
394 if (filtertext) {
395 //filter by search string
396 var re = new RegExp(Ext.escapeRe(filtertext), 'gi');
397 var isMatched = record.data.extkey.match(re) || record.data.title.match(re);
398 if (!isMatched) {
399 return false;
400 }
401 }
402 }
403 if (TYPO3.settings.EM.hide_obsolete == 1 && record.data.state === 'obsolete') {
404 return false;
405 }
406 if (TYPO3.settings.EM.hide_shy == 1 && record.data.shy == 1) {
407 return false;
408 }
409 if (TYPO3.settings.EM.display_installed == 1 && record.data.installed == 0) {
410 return false;
411 }
412 if (TYPO3.settings.EM.display_updatable == 1 && record.data.versionislower == 0) {
413 return false;
414 }
415
416 return true;
417 },
418
419 hasStoreFilter: function() {
420 return (TYPO3.settings.EM.hide_obsolete || TYPO3.settings.EM.hide_shy || TYPO3.settings.EM.display_installed || TYPO3.settings.EM.display_updatable);
421 },
422
423 clearStoreFilters: function(scope) {
424 Ext.each(scope.filterMenuButton.menu.items.items, function(item) {
425 item.setChecked(false, true);
426 });
427 TYPO3.settings.EM.hide_obsolete = TYPO3.settings.EM.hide_shy = TYPO3.settings.EM.display_installed = TYPO3.settings.EM.display_updatable = 0;
428 TYPO3.EM.ExtDirect.saveSetting('display_installed', 0);
429 TYPO3.EM.ExtDirect.saveSetting('display_updatable', 0);
430 TYPO3.EM.ExtDirect.saveSetting('hide_shy', 0);
431 TYPO3.EM.ExtDirect.saveSetting('hide_obsolete', 0);
432 scope.filterRecords();
433 },
434
435 highlightSearch: function(value) {
436 var control = Ext.getCmp('localSearchField');
437 if (control) {
438 var filtertext = control.getRawValue();
439 if (filtertext) {
440 var re = new RegExp(Ext.escapeRe(filtertext), 'gi');
441 var result = re.exec(value) || [];
442 if (result.length) {
443 return value.replace(result[0], '<span class="filteringList-highlight">' + result[0] + '</span>');
444 }
445 }
446 }
447 return value;
448 }
449 });
450
451 var searchField = new Ext.ux.form.SearchField({
452 store: this.localstore,
453 filterFunction: this.filterRecords,
454 id: 'localSearchField',
455 width: 200
456 });
457
458 var cols = [
459 TYPO3.settings.EM.inlineToWindow == 1 ? TYPO3.EM.GridColumns.DummyColumn : this.rowExpander,
460 TYPO3.EM.GridColumns.InstallExtension,
461 TYPO3.EM.GridColumns.ExtensionTitle,
462 TYPO3.EM.GridColumns.ExtensionKey,
463 TYPO3.EM.GridColumns.ExtensionCategory,
464 TYPO3.EM.GridColumns.ExtensionAuthor,
465 TYPO3.EM.GridColumns.ExtensionType,
466 TYPO3.EM.GridColumns.ExtensionState
467 ];
468
469 var cm = new Ext.grid.ColumnModel({
470 columns: cols,
471 defaults: {
472 sortable: true
473 }
474 });
475
476 var sm = Ext.emptyFn();
477 if (TYPO3.settings.EM.inlineToWindow == 1) {
478 sm = new Ext.grid.RowSelectionModel({
479 singleSelect: true
480 });
481 }
482
483 Ext.apply(this, {
484 itemId: 'em-localLocalExtensionlist',
485 title: TYPO3.l10n.localize('availableExtensions'),
486 loadMask: {msg: TYPO3.l10n.localize('action_loading_extlist')},
487 layout: 'fit',
488 store: this.localstore,
489 cm: cm,
490 sm: sm,
491 plugins: TYPO3.settings.EM.inlineToWindow == 1 ? [TYPO3.EM.Filters] : [this.rowExpander, TYPO3.EM.Filters],
492 view : new Ext.grid.GroupingView({
493 forceFit : true,
494 groupTextTpl : '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "' + TYPO3.l10n.localize('msg_items') + '" : "' + TYPO3.l10n.localize('msg_item') + '"]})',
495 enableRowBody: true,
496 showPreview: true,
497 getRowClass: this.applyRowClass,
498 iconCls: 'icon-grid',
499 hideGroupedColumn: true
500 }),
501
502 tbar: [
503 ' ',
504 {
505 text: TYPO3.l10n.localize('cmd_filter'),
506 tooltip: TYPO3.l10n.localize('help_localFilter'),
507 tooltipType : 'qtip',
508 scale: 'small',
509 ref: '../filterMenuButton',
510 iconAlign: 'right',
511 menu : {
512 items: [
513 {
514 checked: TYPO3.settings.EM.display_installed ? true : false,
515 text: TYPO3.l10n.localize('display_installedOnly'),
516 handler: function(item, event) {
517 TYPO3.settings.EM.display_installed = item.checked ? 0 : 1;
518 TYPO3.EM.ExtDirect.saveSetting('display_installed', TYPO3.settings.EM.display_installed);
519 this.filterRecords();
520 },
521 scope: this
522 },
523 {
524 checked: TYPO3.settings.EM.display_updatable ? true : false,
525 text: TYPO3.l10n.localize('display_updatesOnly'),
526 handler: function(item, event) {
527 TYPO3.settings.EM.display_updatable = item.checked ? 0 : 1;
528 TYPO3.EM.ExtDirect.saveSetting('display_updatable', TYPO3.settings.EM.display_updatable);
529 this.filterRecords();
530 },
531 scope: this
532 },
533 {
534 checked: TYPO3.settings.EM.hide_shy ? true : false,
535 text: TYPO3.l10n.localize('hide_shy'),
536 handler: function(item, event) {
537 TYPO3.settings.EM.hide_shy = item.checked ? 0 : 1;
538 TYPO3.EM.ExtDirect.saveSetting('hide_shy', TYPO3.settings.EM.hide_shy);
539 this.filterRecords();
540 },
541 scope: this
542 },
543 {
544 checked: TYPO3.settings.EM.hide_obsolete ? true : false,
545 text: TYPO3.l10n.localize('hide_obsolete'),
546 handler: function(item, event) {
547 TYPO3.settings.EM.hide_obsolete = item.checked ? 0 : 1;
548 TYPO3.EM.ExtDirect.saveSetting('hide_obsolete', TYPO3.settings.EM.hide_obsolete);
549 this.filterRecords();
550 } ,
551 scope: this
552 }
553 ]
554 }
555 },
556 searchField,
557 {
558 xtype: 'tbseparator',
559 ref: '../doClearFiltersSeperator',
560 hidden: true
561 }, {
562 text: TYPO3.l10n.localize('cmd_ClearAllFilters'),
563 ref: '../doClearFilters',
564 handler: function() {
565 this.localstore.clearStoreFilters(this);
566 TYPO3.EM.Filters.clearFilters();
567 },
568 scope: this,
569 hidden: true
570 },
571 '-',
572 {
573 iconCls: 't3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-upload',
574 tooltip: TYPO3.l10n.localize('upload_ext_directly'),
575 ref: '../uploadButton',
576 handler: function() {
577 TYPO3.EM.Tools.uploadExtension();
578 },
579 scope: this
580 },
581 '->',
582 {
583 xtype: 'tbtext',
584 text: TYPO3.l10n.localize('action_loading_extlist'),
585 id: 'displayExtensionLabel',
586 style: {fontWeight: 'bold'}
587 },
588 ' '
589 ]
590 });
591
592 TYPO3.EM.LocalList.superclass.initComponent.apply(this, arguments);
593 },
594
595
596 showExtension: function() {
597 var row = this.store.find('extkey', this.store.showAction);
598 if (row) {
599 if (TYPO3.settings.EM.inlineToWindow == 1) {
600
601 } else {
602 this.rowExpander.expandRow(row);
603 }
604 this.getSelectionModel().selectRow(row);
605 this.getView().focusRow(row);
606 }
607 this.store.showAction = false;
608 },
609
610 onRender: function() {
611 TYPO3.EM.LocalList.superclass.onRender.apply(this, arguments);
612 if (this.localstore.getCount() == 0) {
613 this.localstore.load({
614 params: {
615 repository: TYPO3.settings.EM.selectedRepository
616 }
617 });
618 }
619
620 this.on('rowdblclick', function(grid, rowIndex, event) {
621 if (TYPO3.settings.EM.inlineToWindow == 1) {
622 this.showExtInfoInWindow(rowIndex);
623 }
624 });
625
626 this.on('cellclick', function(grid, rowIndex, columnIndex, event) {
627 if (TYPO3.settings.EM.inlineToWindow == 1 && columnIndex == 2) {
628 this.showExtInfoInWindow(rowIndex);
629 }
630 });
631
632 },
633
634 afterRender: function() {
635 TYPO3.EM.LocalList.superclass.afterRender.apply(this, arguments);
636 },
637
638 showExtInfoInWindow: function(index) {
639 var record = this.store.getAt(index);
640 var id = 'window-extinfo-' + record.data.extkey;
641 var tabs = this.rowExpander.createExpandingRowPanelItems(record, index);
642
643 Ext.apply(tabs, {
644 height: 'auto'
645 });
646
647 if (Ext.WindowMgr.get(id)) {
648 Ext.WindowMgr.bringToFront(id);
649 } else {
650 new Ext.Window({
651 title: TYPO3.EM.Tools.renderExtensionTitle(record),
652 maximized: true,
653 layout: 'fit',
654 items : tabs,
655 id: id
656 }).show();
657 }
658 },
659
660 filterRecords: function() {
661 Ext.StoreMgr.get('localstore').filterBy(TYPO3.EM.Filters.getRecordFilter());
662 }
663
664 });
665
666 Ext.reg('TYPO3.EM.LocalList', TYPO3.EM.LocalList);