diff --git a/_build/templates/default/sass/_trash.scss b/_build/templates/default/sass/_trash.scss new file mode 100644 index 00000000000..56c0190aecb --- /dev/null +++ b/_build/templates/default/sass/_trash.scss @@ -0,0 +1,3 @@ +.trashrow { + background-color: silver !important; +} \ No newline at end of file diff --git a/core/lexicon/en/trash.inc.php b/core/lexicon/en/trash.inc.php new file mode 100644 index 00000000000..b1157ba9161 --- /dev/null +++ b/core/lexicon/en/trash.inc.php @@ -0,0 +1,46 @@ + + Before you restore any resource, check the publishing state - you can unpublish resources here directly from the grid with a double-click on the published-cell of the resource.'; + +$_lang['trash.manage_recycle_bin_tooltip'] = "Go to the trash bin manager"; + +$_lang['trash.deletedon_title'] = 'Deleted on'; +$_lang['trash.deletedbyUser_title'] = 'Deleted by User'; + +$_lang['trash.context_title'] = 'Context'; + +$_lang['trash.purge_all'] = 'Purge all'; +$_lang['trash.restore_all'] = 'Restore all'; + +$_lang['trash.selected_purge'] = 'Purge selected resources'; +$_lang['trash.selected_restore'] = 'Restore selected resources'; + +$_lang['trash.purge'] = 'Purge resource'; +$_lang['trash.purge_confirm_title'] = 'Purge resource(s)?'; +$_lang['trash.purge_confirm_message'] = 'Do you really want to finally delete the following resource(s)? This cannot be undone.
' + _('trash.intro_msg') + '
' + , xtype: 'modx-description' + }, { + xtype: 'modx-grid-trash' + , id: 'modx-trash-resourcelist' + , cls: 'main-wrapper' + , preventRender: true + }] + }], { + stateful: true + , stateId: 'modx-trash-tabpanel' + , stateEvents: ['tabchange'] + , getState: function () { + return {activeTab: this.items.indexOf(this.getActiveTab())}; + } + })] + }); + MODx.panel.Trash.superclass.constructor.call(this, config); + this.addEvents('emptyTrash'); +}; +Ext.extend(MODx.panel.Trash, MODx.FormPanel); +Ext.reg('modx-panel-trash', MODx.panel.Trash); + +MODx.grid.Trash = function (config) { + config = config || {}; + + this.sm = new Ext.grid.CheckboxSelectionModel(); + Ext.applyIf(config, { + url: MODx.config.connector_url + ,baseParams: { + action: 'resource/trash/getlist' + } + ,fields: [ + 'id', + 'context_key', + 'parentPath', + 'pagetitle', + 'longtitle', + 'published', + 'deletedon', + 'cls', + 'deletedbyUser', + 'context_name'] + ,paging: true + + // when we change e.g. the publishing state of a deleted resource, we refresh the tree to reflect + // the changes done + ,autosave: true + ,save_action: 'resource/updatefromgrid' + ,save_callback: function() { + this.refreshEverything(); + } + + ,remoteSort: true + ,sm: this.sm + ,columns: [this.sm, { + header: _('id') + , dataIndex: 'id' + , width: 20 + , sortable: true + }, { + header: _('trash.context_title') + , dataIndex: 'context_name' + , width: 60 + , sortable: false + }, { + header: _('pagetitle') + , dataIndex: 'pagetitle' + , width: 80 + , sortable: true + , tooltip: "TODO: longtitle here" + }, { + header: _('long_title') + , dataIndex: 'longtitle' + , width: 120 + , sortable: false + }, { + header: _('published') + , dataIndex: 'published' + , width: 40 + , sortable: false + , editor: {xtype: 'combo-boolean', renderer: 'boolean'} + }, { + header: _('trash.deletedon_title') + , dataIndex: 'deletedon' + , width: 75 + , sortable: false + }, { + /* header: _('trash.deletedby_title') + , dataIndex: 'deletedby' + , width: 40 + , sortable: false + }, { + */ header: _('trash.deletedbyUser_title') + , dataIndex: 'deletedbyUser' + , width: 40 + , sortable: false + }] + , + tbar: [{ + text: _('bulk_actions') + , menu: [{ + text: _('trash.selected_purge') + , handler: this.purgeSelected + , scope: this + }, { + text: _('trash.selected_restore') + , handler: this.restoreSelected + , scope: this + }] + }, { + xtype: 'button' + , text: _('trash.purge_all') + , id: 'modx-purge-all' + , cls: 'x-form-purge-all red' + , listeners: { + 'click': {fn: this.purgeAll, scope: this} + } + }, { + xtype: 'button' + , text: _('trash.restore_all') + , id: 'modx-restore-all' + , cls: 'x-form-restore-all green' + , listeners: { + 'click': {fn: this.restoreAll, scope: this} + } + }, '->', { + xtype: 'textfield' + , name: 'search' + , id: 'modx-source-search' + , cls: 'x-form-filter' + , emptyText: _('search_ellipsis') + , listeners: { + 'change': {fn: this.search, scope: this} + , 'render': { + fn: function (cmp) { + new Ext.KeyMap(cmp.getEl(), { + key: Ext.EventObject.ENTER + , fn: this.blur + , scope: cmp + }); + }, scope: this + } + } + }, { + xtype: 'button' + , text: _('filter_clear') + , id: 'modx-filter-clear' + , cls: 'x-form-filter-clear' + , listeners: { + 'click': {fn: this.clearFilter, scope: this} + } + }] + }); + MODx.grid.Trash.superclass.constructor.call(this, config); +}; + +Ext.extend(MODx.grid.Trash, MODx.grid.Grid, { + getMenu: function () { + var r = this.getSelectionModel().getSelected(); + var p = r.data.cls; + + var m = []; + if (this.getSelectionModel().getCount() > 1) { + m.push({ + text: _('trash.selected_purge') + , handler: this.purgeSelected + , scope: this + }); + m.push({ + text: _('trash.selected_restore') + , handler: this.restoreSelected + , scope: this + }); + } else { + if (p.indexOf('purge') !== -1) { + m.push({ + text: _('trash.purge') + , handler: this.purgeResource + }); + } + if (p.indexOf('restore') !== -1) { + m.push({ + text: _('trash.restore') + , handler: this.restoreResource + }); + } + } + if (m.length > 0) { + this.addContextMenuItem(m); + } + } + , purgeResource: function () { + MODx.msg.confirm({ + title: _('trash.purge_confirm_title') + , text: _('trash.purge_confirm_message', { + 'list': this.listResources('