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