1 /***************************************************************
4 * (c) 2010 Steffen Kamper <info@sk-typo3.de>
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.
13 * The GNU General Public License can be found at
14 * http://www.gnu.org/copyleft/gpl.html.
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.
21 * This copyright notice MUST APPEAR in all copies of the script!
22 ***************************************************************/
25 * ExtJS for the extension manager.
28 * @author Steffen Kamper <info@sk-typo3.de>
30 * @subpackage extension manager
32 Ext
.ns('TYPO3.EM', 'TYPO3.EM.GridColumns');
34 TYPO3
.EM
.LocalList
= Ext
.extend(Ext
.grid
.GridPanel
, {
40 stateEvents
: ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
41 bodyStyle
: 'padding: 10px;',
43 rowExpander
: new Ext
.ux
.grid
.RowPanelExpander({
45 id
: 'LocalListExpander',
46 createExpandingRowPanelItems: function(record
, rowIndex
) {
52 enableTabScroll
: true,
54 plugins
: [new Ext
.ux
.plugins
.FitWidthToParent()],
62 title
: TYPO3
.l10n
.localize('msg_info'),
63 html
: TYPO3
.EM
.Layouts
.showExtInfo(record
.data
),
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({
76 title
: TYPO3
.l10n
.localize('ext_details_updateScript') + ' (' + record
.data
.extkey
+ ')',
80 id
: 'updateScript-' + record
.data
.extkey
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');
87 TYPO3
.Flashmessage
.display(TYPO3
.Severity
.information
, TYPO3
.l10n
.localize('cmd_update'), TYPO3
.l10n
.localize('repository_update_not_needed'), 5);
97 title
: TYPO3
.l10n
.localize('msg_dbupdate'),
98 html
: TYPO3
.EM
.App
.loadingIndicor
,
100 disabled
: record
.data
.installed
=== 0,
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));
110 readUpdateForm: function() {
111 var button
= Ext
.get('update-submit-' + record
.data
.extkey
);
112 Ext
.apply(this.form
, {
114 submit
: TYPO3
.EM
.ExtDirect
.saveExtensionConfiguration
119 button
.on('click', function() {
120 this.doUpdate(false);
124 doUpdate: function(noSave
) {
126 waitMsg
: noSave
? ' ' : TYPO3
.l10n
.localize('action_updateDatabase'),
128 extkey
: record
.data
.extkey
,
129 exttype
: record
.data
.typeShort
,
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));
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);
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);
154 title
: TYPO3
.l10n
.localize('msg_configuration'),
156 disabled
: record
.data
.installed
=== 0,
157 html
: TYPO3
.EM
.App
.loadingIndicor
,
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));
167 readConfigForm: function() {
168 var button
= Ext
.get('configuration-submit-' + record
.data
.extkey
);
170 var button
= Ext
.get('update-submit-' + record
.data
.extkey
);
172 var select
= Ext
.select('.mod-menu-template-select');
173 Ext
.apply(this.form
, {
175 submit
: TYPO3
.EM
.ExtDirect
.saveExtensionConfiguration
180 var converted
= new Ext
.form
.ComboBox({
181 transform
: select
.elements
[0],
184 beforequery: function(o
) {
195 button
.on('click', function() {
196 this.doSubmit(false);
200 doSubmit: function(noSave
) {
202 waitMsg
: noSave
? ' ' : TYPO3
.l10n
.localize('action_saving_settings'),
204 extkey
: record
.data
.extkey
,
205 exttype
: record
.data
.typeShort
,
208 success: function(form
, action
) {
209 if (action
.result
.html
) {
210 this.ownerCt
.activeTab
.update(action
.result
.html
, true, this.readConfigForm
.createDelegate(this));
212 TYPO3
.Flashmessage
.display(TYPO3
.Severity
.ok
, TYPO3
.l10n
.localize('msg_configuration'), TYPO3
.l10n
.localize('configurationSaved'), 5);
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);
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);
231 title
: TYPO3
.l10n
.localize('msg_files'),
232 xtype
: 'extfilelist',
233 recordData
: record
.data
,
234 cls
: 'gridrowfilespanel'
238 title
: TYPO3
.l10n
.localize('cmd_terupload'),
239 recordData
: record
.data
,
240 disabled
: !TYPO3
.settings
.EM
.hasCredentials
243 title
: TYPO3
.l10n
.localize('msg_developerinformation'),
244 html
: '<div class="loading-indicator">' + TYPO3
.l10n
.localize('action_loading') + '</div>',
246 activate: function(panel
) {
247 TYPO3
.EM
.ExtDirect
.getExtensionDevelopInfo(record
.data
.extkey
, function(response
) {
248 panel
.update(response
);
254 title
: TYPO3
.l10n
.localize('details_maintenance'),
255 html
: TYPO3
.EM
.App
.loadingIndicor
,
257 activate: function(panel
) {
258 TYPO3
.EM
.ExtDirect
.getExtensionBackupDelete(record
.data
.extkey
, function(response
) {
259 panel
.update(response
, true, this.readBackupDeleteLinks
.createDelegate(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
) {
273 TYPO3
.Flashmessage
.display(TYPO3
.Severity
.ok
, TYPO3
.l10n
.localize('ext_details_update_em_conf'), response
.result
, 5);
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
) {
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
);
289 TYPO3
.Flashmessage
.display(TYPO3
.Severity
.error
, response
.error
, response
.result
, 5);
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
311 reader
: new Ext
.data
.JsonReader({
312 idProperty
: 'extkey',
314 totalProperty
: 'length',
325 {name
:'description'},
329 {name
:'author_email'},
330 {name
:'author_company'},
335 {name
:'reviewstate'},
337 {name
:'doubleInstall'},
338 {name
:'doubleInstallShort'},
339 {name
:'updateModule'},
340 {name
:'doNotLoadInFE'},
352 groupField
: 'category',
355 beforeload: function() {
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
) {
367 this.doClearFilters
.show();
368 this.doClearFiltersSeperator
.show();
370 this.doClearFilters
.hide();
371 this.doClearFiltersSeperator
.hide();
373 if (!TYPO3
.settings
.EM
.hide_obsolete
&& !TYPO3
.settings
.EM
.hide_shy
&& !TYPO3
.settings
.EM
.display_installed
) {
374 this.filterMenuButton
.removeClass('bold');
376 this.filterMenuButton
.addClass('bold');
379 load: function(store
) {
380 TYPO3
.EM
.App
.refreshLocalList
= false;
381 if (store
.showAction
) {
382 this.showExtension
.defer(500, this);
388 validateRecord: function(record
) {
389 var control
= Ext
.getCmp('localSearchField');
391 var filtertext
= control
.getRawValue();
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
);
401 if (TYPO3
.settings
.EM
.hide_obsolete
== 1 && record
.data
.state
=== 'obsolete') {
404 if (TYPO3
.settings
.EM
.hide_shy
== 1 && record
.data
.shy
== 1) {
407 if (TYPO3
.settings
.EM
.display_installed
== 1 && record
.data
.installed
== 0) {
414 hasStoreFilter: function() {
415 return (TYPO3
.settings
.EM
.hide_obsolete
|| TYPO3
.settings
.EM
.hide_shy
|| TYPO3
.settings
.EM
.display_installed
);
418 clearStoreFilters: function(scope
) {
419 Ext
.each(scope
.filterMenuButton
.menu
.items
.items
, function(item
) {
420 item
.setChecked(false, true);
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();
429 highlightSearch: function(value
) {
430 var control
= Ext
.getCmp('localSearchField');
432 var filtertext
= control
.getRawValue();
434 var re
= new RegExp(Ext
.escapeRe(filtertext
), 'gi');
435 var result
= re
.exec(value
) || [];
437 return value
.replace(result
[0], '<span class="filteringList-highlight">' + result
[0] + '</span>');
445 var searchField
= new Ext
.ux
.form
.SearchField({
446 store
: this.localstore
,
447 filterFunction
: this.filterRecords
,
448 id
: 'localSearchField',
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
463 var cm
= new Ext
.grid
.ColumnModel({
470 var sm
= Ext
.emptyFn();
471 if (TYPO3
.settings
.EM
.inlineToWindow
== 1) {
472 sm
= new Ext
.grid
.RowSelectionModel({
478 itemId
: 'em-localLocalExtensionlist',
479 title
: TYPO3
.l10n
.localize('localExtensionList'),
480 loadMask
: {msg
: TYPO3
.l10n
.localize('action_loading_extlist')},
482 store
: this.localstore
,
485 plugins
: TYPO3
.settings
.EM
.inlineToWindow
== 1 ? [TYPO3
.EM
.Filters
] : [this.rowExpander
, TYPO3
.EM
.Filters
],
486 view
: new Ext
.grid
.GroupingView({
488 groupTextTpl
: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "' + TYPO3
.l10n
.localize('msg_items') + '" : "' + TYPO3
.l10n
.localize('msg_item') + '"]})',
491 getRowClass
: this.applyRowClass
,
492 iconCls
: 'icon-grid',
493 hideGroupedColumn
: true
499 text
: TYPO3
.l10n
.localize('cmd_filter'),
500 tooltip
: TYPO3
.l10n
.localize('help_localFilter'),
501 tooltipType
: 'qtip',
503 ref
: '../filterMenuButton',
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();
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();
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();
542 xtype
: 'tbseparator',
543 ref
: '../doClearFiltersSeperator',
546 text
: TYPO3
.l10n
.localize('cmd_ClearAllFilters'),
547 ref
: '../doClearFilters',
548 handler: function() {
549 this.localstore
.clearStoreFilters(this);
550 TYPO3
.EM
.Filters
.clearFilters();
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();
568 text
: TYPO3
.l10n
.localize('action_loading_extlist'),
569 id
: 'displayExtensionLabel',
570 style
: {fontWeight
: 'bold'}
576 TYPO3
.EM
.LocalList
.superclass
.initComponent
.apply(this, arguments
);
580 showExtension: function() {
581 var row
= this.store
.find('extkey', this.store
.showAction
);
583 if (TYPO3
.settings
.EM
.inlineToWindow
== 1) {
586 this.rowExpander
.expandRow(row
);
588 this.getSelectionModel().selectRow(row
);
589 this.getView().focusRow(row
);
591 this.store
.showAction
= false;
594 onRender: function() {
595 TYPO3
.EM
.LocalList
.superclass
.onRender
.apply(this, arguments
);
596 if (this.localstore
.getCount() == 0) {
597 this.localstore
.load();
600 this.on('rowdblclick', function(grid
, rowIndex
, event
) {
601 if (TYPO3
.settings
.EM
.inlineToWindow
== 1) {
602 this.showExtInfoInWindow(rowIndex
);
606 this.on('cellclick', function(grid
, rowIndex
, columnIndex
, event
) {
607 if (TYPO3
.settings
.EM
.inlineToWindow
== 1 && columnIndex
== 2) {
608 this.showExtInfoInWindow(rowIndex
);
614 afterRender: function() {
615 TYPO3
.EM
.LocalList
.superclass
.afterRender
.apply(this, arguments
);
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
);
627 if (Ext
.WindowMgr
.get(id
)) {
628 Ext
.WindowMgr
.bringToFront(id
);
631 title
: TYPO3
.EM
.Tools
.renderExtensionTitle(record
),
640 filterRecords: function() {
641 Ext
.StoreMgr
.get('localstore').filterBy(TYPO3
.EM
.Filters
.getRecordFilter());
646 Ext
.reg('TYPO3.EM.LocalList', TYPO3
.EM
.LocalList
);