3392a36ed9f3dd5577bdcf4fe3631991104c4fa0
[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 ]
345 }),
346
347 sortInfo:{
348 field: 'title',
349 direction: 'ASC'
350 },
351 remoteSort: false,
352 groupField: 'category',
353 showAction: false,
354 listeners: {
355 beforeload: function() {
356
357 },
358 datachanged: function(store) {
359 Ext.getCmp('displayExtensionLabel').setText(TYPO3.l10n.localize('extensions') + ' ' + store.data.length);
360 var hasFilters = store.hasStoreFilter();
361 TYPO3.EM.Filters.filters.each(function (filter) {
362 if (filter.active) {
363 hasFilters = true;
364 }
365 });
366 if (hasFilters) {
367 this.doClearFilters.show();
368 this.doClearFiltersSeperator.show();
369 } else {
370 this.doClearFilters.hide();
371 this.doClearFiltersSeperator.hide();
372 }
373 if (!TYPO3.settings.EM.hide_obsolete && !TYPO3.settings.EM.hide_shy && !TYPO3.settings.EM.display_installed) {
374 this.filterMenuButton.removeClass('bold');
375 } else {
376 this.filterMenuButton.addClass('bold');
377 }
378 },
379 load: function(store) {
380 TYPO3.EM.App.refreshLocalList = false;
381 if (store.showAction) {
382 this.showExtension.defer(500, this);
383 }
384 },
385
386 scope: this
387 },
388 validateRecord: function(record) {
389 var control = Ext.getCmp('localSearchField');
390 if (control) {
391 var filtertext = control.getRawValue();
392 if (filtertext) {
393 //filter by search string
394 var re = new RegExp(Ext.escapeRe(filtertext), 'gi');
395 var isMatched = record.data.extkey.match(re) || record.data.title.match(re);
396 if (!isMatched) {
397 return false;
398 }
399 }
400 }
401 if (TYPO3.settings.EM.hide_obsolete == 1 && record.data.state === 'obsolete') {
402 return false;
403 }
404 if (TYPO3.settings.EM.hide_shy == 1 && record.data.shy == 1) {
405 return false;
406 }
407 if (TYPO3.settings.EM.display_installed == 1 && record.data.installed == 0) {
408 return false;
409 }
410
411 return true;
412 },
413
414 hasStoreFilter: function() {
415 return (TYPO3.settings.EM.hide_obsolete || TYPO3.settings.EM.hide_shy || TYPO3.settings.EM.display_installed);
416 },
417
418 clearStoreFilters: function(scope) {
419 Ext.each(scope.filterMenuButton.menu.items.items, function(item) {
420 item.setChecked(false, true);
421 });
422 TYPO3.settings.EM.hide_obsolete = TYPO3.settings.EM.hide_shy = TYPO3.settings.EM.display_installed = 0;
423 TYPO3.EM.ExtDirect.saveSetting('display_installed', 0);
424 TYPO3.EM.ExtDirect.saveSetting('hide_shy', 0);
425 TYPO3.EM.ExtDirect.saveSetting('hide_obsolete', 0);
426 scope.filterRecords();
427 },
428
429 highlightSearch: function(value) {
430 var control = Ext.getCmp('localSearchField');
431 if (control) {
432 var filtertext = control.getRawValue();
433 if (filtertext) {
434 var re = new RegExp(Ext.escapeRe(filtertext), 'gi');
435 var result = re.exec(value) || [];
436 if (result.length) {
437 return value.replace(result[0], '<span class="filteringList-highlight">' + result[0] + '</span>');
438 }
439 }
440 }
441 return value;
442 }
443 });
444
445 var searchField = new Ext.ux.form.SearchField({
446 store: this.localstore,
447 filterFunction: this.filterRecords,
448 id: 'localSearchField',
449 width: 200
450 });
451
452 var cols = [
453 TYPO3.settings.EM.inlineToWindow == 1 ? TYPO3.EM.GridColumns.DummyColumn : this.rowExpander,
454 TYPO3.EM.GridColumns.InstallExtension,
455 TYPO3.EM.GridColumns.ExtensionTitle,
456 TYPO3.EM.GridColumns.ExtensionKey,
457 TYPO3.EM.GridColumns.ExtensionCategory,
458 TYPO3.EM.GridColumns.ExtensionAuthor,
459 TYPO3.EM.GridColumns.ExtensionType,
460 TYPO3.EM.GridColumns.ExtensionState
461 ];
462
463 var cm = new Ext.grid.ColumnModel({
464 columns: cols,
465 defaults: {
466 sortable: true
467 }
468 });
469
470 var sm = Ext.emptyFn();
471 if (TYPO3.settings.EM.inlineToWindow == 1) {
472 sm = new Ext.grid.RowSelectionModel({
473 singleSelect: true
474 });
475 }
476
477 Ext.apply(this, {
478 itemId: 'em-localLocalExtensionlist',
479 title: TYPO3.l10n.localize('localExtensionList'),
480 loadMask: {msg: TYPO3.l10n.localize('action_loading_extlist')},
481 layout: 'fit',
482 store: this.localstore,
483 cm: cm,
484 sm: sm,
485 plugins: TYPO3.settings.EM.inlineToWindow == 1 ? [TYPO3.EM.Filters] : [this.rowExpander, TYPO3.EM.Filters],
486 view : new Ext.grid.GroupingView({
487 forceFit : true,
488 groupTextTpl : '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "' + TYPO3.l10n.localize('msg_items') + '" : "' + TYPO3.l10n.localize('msg_item') + '"]})',
489 enableRowBody: true,
490 showPreview: true,
491 getRowClass: this.applyRowClass,
492 iconCls: 'icon-grid',
493 hideGroupedColumn: true
494 }),
495
496 tbar: [
497 ' ',
498 {
499 text: TYPO3.l10n.localize('cmd_filter'),
500 tooltip: TYPO3.l10n.localize('help_localFilter'),
501 tooltipType : 'qtip',
502 scale: 'small',
503 ref: '../filterMenuButton',
504 iconAlign: 'right',
505 menu : {
506 items: [
507 {
508 checked: TYPO3.settings.EM.display_installed ? true : false,
509 text: TYPO3.l10n.localize('display_installedOnly'),
510 handler: function(item, event) {
511 TYPO3.settings.EM.display_installed = item.checked ? 0 : 1;
512 TYPO3.EM.ExtDirect.saveSetting('display_installed', TYPO3.settings.EM.display_installed);
513 this.filterRecords();
514 },
515 scope: this
516 },
517 {
518 checked: TYPO3.settings.EM.hide_shy ? true : false,
519 text: TYPO3.l10n.localize('hide_shy'),
520 handler: function(item, event) {
521 TYPO3.settings.EM.hide_shy = item.checked ? 0 : 1;
522 TYPO3.EM.ExtDirect.saveSetting('hide_shy', TYPO3.settings.EM.hide_shy);
523 this.filterRecords();
524 },
525 scope: this
526 },
527 {
528 checked: TYPO3.settings.EM.hide_obsolete ? true : false,
529 text: TYPO3.l10n.localize('hide_obsolete'),
530 handler: function(item, event) {
531 TYPO3.settings.EM.hide_obsolete = item.checked ? 0 : 1;
532 TYPO3.EM.ExtDirect.saveSetting('hide_obsolete', TYPO3.settings.EM.hide_obsolete);
533 this.filterRecords();
534 } ,
535 scope: this
536 }
537 ]
538 }
539 },
540 searchField,
541 {
542 xtype: 'tbseparator',
543 ref: '../doClearFiltersSeperator',
544 hidden: true
545 }, {
546 text: TYPO3.l10n.localize('cmd_ClearAllFilters'),
547 ref: '../doClearFilters',
548 handler: function() {
549 this.localstore.clearStoreFilters(this);
550 TYPO3.EM.Filters.clearFilters();
551 },
552 scope: this,
553 hidden: true
554 },
555 '-',
556 {
557 iconCls: 't3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-upload',
558 tooltip: TYPO3.l10n.localize('upload_ext_directly'),
559 ref: '../uploadButton',
560 handler: function() {
561 TYPO3.EM.Tools.uploadExtension();
562 },
563 scope: this
564 },
565 '->',
566 {
567 xtype: 'tbtext',
568 text: TYPO3.l10n.localize('action_loading_extlist'),
569 id: 'displayExtensionLabel',
570 style: {fontWeight: 'bold'}
571 },
572 ' '
573 ]
574 });
575
576 TYPO3.EM.LocalList.superclass.initComponent.apply(this, arguments);
577 },
578
579
580 showExtension: function() {
581 var row = this.store.find('extkey', this.store.showAction);
582 if (row) {
583 if (TYPO3.settings.EM.inlineToWindow == 1) {
584
585 } else {
586 this.rowExpander.expandRow(row);
587 }
588 this.getSelectionModel().selectRow(row);
589 this.getView().focusRow(row);
590 }
591 this.store.showAction = false;
592 },
593
594 onRender: function() {
595 TYPO3.EM.LocalList.superclass.onRender.apply(this, arguments);
596 if (this.localstore.getCount() == 0) {
597 this.localstore.load();
598 }
599
600 this.on('rowdblclick', function(grid, rowIndex, event) {
601 if (TYPO3.settings.EM.inlineToWindow == 1) {
602 this.showExtInfoInWindow(rowIndex);
603 }
604 });
605
606 this.on('cellclick', function(grid, rowIndex, columnIndex, event) {
607 if (TYPO3.settings.EM.inlineToWindow == 1 && columnIndex == 2) {
608 this.showExtInfoInWindow(rowIndex);
609 }
610 });
611
612 },
613
614 afterRender: function() {
615 TYPO3.EM.LocalList.superclass.afterRender.apply(this, arguments);
616 },
617
618 showExtInfoInWindow: function(index) {
619 var record = this.store.getAt(index);
620 var id = 'window-extinfo-' + record.data.extkey;
621 var tabs = this.rowExpander.createExpandingRowPanelItems(record, index);
622
623 Ext.apply(tabs, {
624 height: 'auto'
625 });
626
627 if (Ext.WindowMgr.get(id)) {
628 Ext.WindowMgr.bringToFront(id);
629 } else {
630 new Ext.Window({
631 title: TYPO3.EM.Tools.renderExtensionTitle(record),
632 maximized: true,
633 layout: 'fit',
634 items : tabs,
635 id: id
636 }).show();
637 }
638 },
639
640 filterRecords: function() {
641 Ext.StoreMgr.get('localstore').filterBy(TYPO3.EM.Filters.getRecordFilter());
642 }
643
644 });
645
646 Ext.reg('TYPO3.EM.LocalList', TYPO3.EM.LocalList);