Skip to content

Commit

Permalink
Fix Element handling from within Categories tree (#16546)
Browse files Browse the repository at this point in the history
### What does it do?
Adds a new tree method to properly extract Element data from the working
tree Node. There are three patterns for a Node's id, but only one was
being accounted for in the code. Additionally, cleans up code formatting
in the affected methods.

### Why is it needed?
Within the Categories tree, these actions are currently inoperable:
- Element removal
- Plugin activation/deactivation

### How to test
1. Create a handful of Elements (at least one of each type), both within
a Category and within the root (no Category)
2. Verify the ability to remove each Element (from both the Categories
tree and from within the individual Element trees)
3. Verify the ability to activate/deactivate Plugins (from both the
Categories tree and from within the individual Element trees)

### Related issue(s)/PR(s)
Resolves #16487 for MODX
3.0.x
Related to 2.x solution #16488
Port of 3.x solution #16489

---------

Co-authored-by: Jim Graham <jim@pixelsandstrings.com>
  • Loading branch information
opengeek and smg6511 authored Mar 25, 2024
1 parent 1ebd52b commit e5055c4
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 53 deletions.
2 changes: 1 addition & 1 deletion manager/assets/modext/modx.jsgrps-min.js

Large diffs are not rendered by default.

161 changes: 109 additions & 52 deletions manager/assets/modext/widgets/element/modx.tree.element.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,62 +141,123 @@ Ext.extend(MODx.tree.Element,MODx.tree.Tree,{
});
}

,removeElement: function(itm,e) {
var id = this.cm.activeNode.id.substr(2);
var oar = id.split('_');
/**
* @property {Function} extractElementIdentifiersFromActiveNode Gets an Element's type, id, and category id from an active Node's id
*
* @param {Ext.tree.Node} activeNode The Node currently being acted upon
* @return {Object} An object containing relevant identifiers of the Element this Node represents
*/
,extractElementIdentifiersFromActiveNode: function(activeNode) {
let startIndex;
const extractedData = {};

switch (true) {
// When creating Elements in the root of their tree
case activeNode.id.indexOf('n_type_') === 0:
startIndex = 7;
break;
// When altering or removing an Element from within the Categories tree
case activeNode.id.indexOf('n_c_') === 0:
startIndex = 4;
break;
default:
startIndex = 2;
}
const identifiers = activeNode.id.substr(startIndex).split('_');

/*
Expected array items:
- When working in the Categories tree: [element type, node type ('element'), element id, element's category id]
- When working in any of the five Element trees: [element type, node type ('category'), element's category id]
- When creating and Element in the root of it's type's tree: [element type]
*/

[extractedData.type] = identifiers;

switch (identifiers.length) {
case 4:
return {
...extractedData,
elementId: parseInt(identifiers[2], 10),
categoryId: parseInt(identifiers[3], 10)
};
case 3:
return {
...extractedData,
categoryId: parseInt(identifiers[2], 10)
};
case 1:
return extractedData;
// no default
}
return false;
}

,removeElement: function(itm, e) {
const elementIdentifiers = this.extractElementIdentifiersFromActiveNode(this.cm.activeNode);
MODx.msg.confirm({
title: _('warning')
,text: _('remove_this_confirm',{
type: _(oar[0])
,name: this.cm.activeNode.attributes.name
})
,url: MODx.config.connector_url
,params: {
action: 'element/'+oar[0]+'/remove'
,id: oar[2]
}
,listeners: {
'success': {fn:function() {
this.cm.activeNode.remove();
/* if editing the element being removed */
if (MODx.request.a == 'element/'+oar[0]+'/update' && MODx.request.id == oar[2]) {
MODx.loadPage('welcome');
}
},scope:this}
title: _('warning'),
text: _('remove_this_confirm', {
type: _(elementIdentifiers.type),
name: this.cm.activeNode.attributes.name
}),
url: MODx.config.connector_url,
params: {
action: `element/${elementIdentifiers.type}/remove`,
id: elementIdentifiers.elementId
},
listeners: {
success: {
fn: function() {
this.cm.activeNode.remove();
/* if editing the element being removed */
if (
MODx.request.a === `element/${elementIdentifiers.type}/update`
&& parseInt(MODx.request.id, 10) === elementIdentifiers.elementId
) {
MODx.loadPage('welcome');
}
},
scope: this
}
}
});
}

,activatePlugin: function(itm,e) {
var id = this.cm.activeNode.id.substr(2);
var oar = id.split('_');
,activatePlugin: function(itm, e) {
const elementIdentifiers = this.extractElementIdentifiersFromActiveNode(this.cm.activeNode);
MODx.Ajax.request({
url: MODx.config.connector_url
,params: {
action: 'Element/Plugin/Activate'
,id: oar[2]
}
,listeners: {
'success': {fn:function() {
this.refreshParentNode();
},scope:this}
url: MODx.config.connector_url,
params: {
action: 'Element/Plugin/Activate',
id: elementIdentifiers.elementId
},
listeners: {
success: {
fn: function() {
this.refreshParentNode();
},
scope: this
}
}
});
}

,deactivatePlugin: function(itm,e) {
var id = this.cm.activeNode.id.substr(2);
var oar = id.split('_');
,deactivatePlugin: function(itm, e) {
const elementIdentifiers = this.extractElementIdentifiersFromActiveNode(this.cm.activeNode);
MODx.Ajax.request({
url: MODx.config.connector_url
,params: {
action: 'Element/Plugin/Deactivate'
,id: oar[2]
}
,listeners: {
'success': {fn:function() {
this.refreshParentNode();
},scope:this}
url: MODx.config.connector_url,
params: {
action: 'Element/Plugin/Deactivate',
id: elementIdentifiers.elementId
},
listeners: {
success: {
fn: function() {
this.refreshParentNode();
},
scope: this
}
}
});
}
Expand Down Expand Up @@ -256,13 +317,9 @@ Ext.extend(MODx.tree.Element,MODx.tree.Tree,{
});
}

,_createElement: function(itm,e,t) {
var id = this.cm.activeNode.id.substr(2);
var oar = id.split('_');
var type = oar[0] == 'type' ? oar[1] : oar[0];
var cat_id = oar[0] == 'type' ? 0 : (oar[1] == 'category' ? oar[2] : oar[3]);
var a = 'element/'+type+'/create';
this.redirect('?a='+a+'&category='+cat_id);
,_createElement: function(itm, e, t) {
const elementIdentifiers = this.extractElementIdentifiersFromActiveNode(this.cm.activeNode);
this.redirect(`?a=element/${elementIdentifiers.type}/create&category=${elementIdentifiers.categoryId}`)
this.cm.hide();
return false;
}
Expand Down

0 comments on commit e5055c4

Please sign in to comment.