Add a custom button in AEM DAM console and validate the asset Before Deleting
Add a custom button in AEM DAM Console (Touch UI)
Sling Merger is the best way to overlay and hide/add any buttons in components or even AEM consoles.
If you would like to do any custom action on the assets, for ex: Validate the asset before deleting, you can follow the below process.
Use Case Scenario:
When we select the asset and click on the delete, there is no way of holding that activity, we can catch the events by using Event Listeners and do any activity post deletion, but if you would like to make any check's before deletion and stop deleting the asset,There are a couple of options for this requirement
1. Create a workflow and assign the workflow to the asset to do the activity
2. Add a custom button and call a servlet to do required actions, if you are satisifed the conditions in the servlet, you can delete it directly or you can hold the deletion and send emails or any other actions.
You can even call a workflow from the servlet to do the activity if any user intervention is required
Creating a custom button
Navigate to the dam path in the crx/deIn the scenario, we are doing an activity on the selection of asset, so we will be overlaying the selection node.
Right click on the node (/libs/dam/gui/content/assets/jcr:content/actions/selection) and click on "Overlay Node"
Select the Match Node Types check box to create the overlay nodes with the same structure and node types.
This should create us the overlay structure under /apps folder as /apps/dam/gui/content/assets/jcr:content/actions/selection
Once we have the structure, we can add/hide any buttons.
In this scenario, I am hiding the delete button and create a new button
Create a new node under selection with name as "delete" and type as "nt:unstructured"
Add a property sling:hideResource with Boolean type and value as true.
After this you will not be able to see the delete button in the asset console.
you can copy the existing delete node from "/libs/dam/gui/content/assets/jcr:content/actions/selection/delete" and paste under "/apps/dam/gui/content/assets/jcr:content/actions/selection"
Update the properties as below:
Delete the property actionConfigName
granite-rel : cq-damadmin-admin-actions-request-delete-activator
text : Request for Delete
sling:resourceType : granite/ui/components/coral/foundation/button
Save the ChangesI did not clean up the unwanted properties for now
You should be able to see the new button while selecting any asset in the DAM console
Click Action for the custom button
- Create a new folder "request-for-deletion" under /apps folder.
- Create a cq:ClientLibraryFolder under the "request-for-deletion" folder
- Add the categories multi value property with "dam.gui.actions.coral" as the value --> Without this your clientlibs will not be called.
- Create below files under clientlibs folder
- request-for-deletion.js
- js.txt
- Add request-for-deletion.js in the js.txt
Add the below script in the request-for-deletion.js file
(function($, $document) {
$(document).on("foundation-contentloaded", function(e) {
/* This value of granite-rel in the custom button should be used here to identify the trigger event*/
var requestForDeletion = ".cq-damadmin-admin-actions-request-delete-activator";
$(document).off("click", requestForDeletion).on("click", requestForDeletion, function(e) {
var paths = [];
var selectedItems = $(".foundation-selections-item");
selectedItems.each(function() {
paths.push($(this).get(0).getAttribute('data-foundation-collection-item-id'));
});
$.ajax({
type: 'GET',
url: '/bin/flash/deleteassets',
data: 'assetPaths=' + paths,
success: function(msg) {
alert('Assets are requested for deletion');
}
});
});
});
})(jQuery, jQuery(document));
The above script will be executed when we select any assets and click on Request For Deletion button. This will make an ajax request to the servlet.
Sling Servlet
package com.flash.aem.core.servlets;
import java.io.IOException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowService;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.model.WorkflowModel;
/**
* The Class RequestForDeletionServlet.
*
* @author sudheerdvn
*/
@Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Request for Deletion Servlet",
ServletResolverConstants.SLING_SERVLET_METHODS + "=GET",
ServletResolverConstants.SLING_SERVLET_PATHS + "=/bin/flash/deleteassets" })
public class RequestForDeletionServlet extends SlingAllMethodsServlet {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 4675612505863065427L;
/** The log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
@Reference
private WorkflowService workflowService;
/*
* (non-Javadoc)
*
* @see
* org.apache.sling.api.servlets.SlingSafeMethodsServlet#doGet(org.apache.sling.
* api.SlingHttpServletRequest, org.apache.sling.api.SlingHttpServletResponse)
*/
@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
throws ServletException, IOException {
String assetPaths = request.getParameter("assetPaths");
if (null != assetPaths) {
log.debug("assetPaths are {}", assetPaths);
String[] assetPathsArray = assetPaths.split(",");
ResourceResolver resourceResolver = request.getResourceResolver();
Session session = resourceResolver.adaptTo(Session.class);
log.debug("session is {}", session);
for (String assetPath : assetPathsArray) {
log.debug("assetPath is {}", assetPath);
/*
* In this use case i have simply triggered another workflow for deletion
* process. We can validate the conditions and start the workflow or do all the
* validations inside the workflow directly.
*/
triggerWorkflow(session, assetPath);
}
// Do required action with the asset paths
}
}
/**
* Trigger workflow.
*
* @param session
* the session
* @param assetPath
* the asset path
*/
private void triggerWorkflow(Session session, String assetPath) {
log.debug("In Trigger workflow");
WorkflowSession workflowSession = workflowService.getWorkflowSession(session);
WorkflowModel workflowModel;
try {
workflowModel = workflowSession.getModel("/var/workflow/models/delete-asset");
if (null != workflowModel) {
log.debug("workflowModel is {}", workflowModel);
WorkflowData wfData = workflowSession.newWorkflowData("JCR_PATH", assetPath);
workflowSession.startWorkflow(workflowModel, wfData);
log.debug("Started workflow");
}
} catch (WorkflowException e) {
log.error("WorkflowException occurred while starting the workflow", e);
}
}
}
You can refer to the workflow model implementation here (Link to the post in the same blog)
Comments
Post a Comment