How to hide the action button in backoffice based on user roles? - sap-commerce-cloud

How can I remove a button action in backoffice according to the user? I was able to disable the button by adding a condition in the canPerform method like this
public boolean canPerform(final ActionContext<String> ctx)
{
final UserModel currentUser = userService.getCurrentUser();
final boolean isUserMemberOfGroup = this.userService.isMemberOfGroup(currentUser,"group_name");
return isUserMemberOfGroup;
}
But I want to hide the button instead of making it disable.

I hope you already have a custom backoffice extension, if not then follow this tutorial to create one.
Now, in yourcustombackoffice-backoffice-config.xml you can declare listviewactions component for your itemtype with those actions which you want to allow to the user/group. Then you need to assign that user's role/group to the principal attribute.
For example, there are two backoffice roles "mainRole" and "otherRole". "mainRole" role has assigned to X user and "otherRole" role to Y user. Now using below backoffice config, X user can only see the Create button and Y user can only see Delete button.
<contexttype="Media" component="listviewactions" principal="mainRole" module="hideActionB">
<y:actionsxmlns:y="http://www.hybris.com/cockpit/config/hybris"xmlns:advanced-search="http://www.hybris.com/cockpitng/config/advancedsearch"xmlns:df="http://www.hybris.com/cockpitng/component/dynamicForms"xmlns:editorArea="http://www.hybris.com/cockpitng/component/editorArea"xmlns:explorer-tree="http://www.hybris.com/cockpitng/config/explorertree"xmlns:list-view="http://www.hybris.com/cockpitng/component/listView"xmlns:simple-search="http://www.hybris.com/cockpitng/config/simplesearch"xmlns:wz="http://www.hybris.com/cockpitng/config/wizard-config"xmlns:ysl="http://www.hybris.com/cockpitng/config/simplelist">
<y:group qualifier="common">
<y:label>actiongroup.common</y:label>
<y:action action-id="com.hybris.cockpitng.action.create" property="pageable.typeCode"/>
</y:group>
</y:actions>
</context>
<contexttype="Media" component="listviewactions" principal="otherRole" module="hideActionB">
<y:actionsxmlns:y="http://www.hybris.com/cockpit/config/hybris"xmlns:advanced-search="http://www.hybris.com/cockpitng/config/advancedsearch"xmlns:df="http://www.hybris.com/cockpitng/component/dynamicForms"xmlns:editorArea="http://www.hybris.com/cockpitng/component/editorArea"xmlns:explorer-tree="http://www.hybris.com/cockpitng/config/explorertree"xmlns:list-view="http://www.hybris.com/cockpitng/component/listView"xmlns:simple-search="http://www.hybris.com/cockpitng/config/simplesearch"xmlns:wz="http://www.hybris.com/cockpitng/config/wizard-config"xmlns:ysl="http://www.hybris.com/cockpitng/config/simplelist">
<y:group qualifier="common">
<y:label>actiongroup.common</y:label>
<y:action action-id="com.hybris.cockpitng.action.delete" property="currentObject"/>
</y:group>
</y:actions>
</context>
</config>
Find more detailed steps here

Related

How do I pass a value from one mobile screen to another using Acumatica MDSL?

Here is the scenario:
I have a GI ListFolder, (DB-Appointments), which displays Tech Appoints and the RefNbr of those appointments on the mobile app.
I want to have the user tap on an SO number and then be able to send that SO number to customized mobile app (Service Orders) which will allow the user to edit and change the service order information.
HOWEVER, I am unable to determine how to pass the value of the RefNbr from the first mobile app screen to the other one using the "redirect" command inside of the "EditDetail" container action. (code below)
Does anyone know how to do this?
add container "Result" {
containerActionsToExpand = 2
add field "ServiceOrderTypeFSServiceOrderSrvOrdType"
add field "RefNbr"
add containerAction "Insert" {
icon = "system://Plus"
behavior = Create
redirect = True
}
add containerAction "EditDetail" {
behavior = Open
redirect = True
redirectToScreen = "GI993132"
redirectToContainer = "Filter_$List$ServiceOrderTypeFSServiceOrderRefNbr"
}
}
}
Since it has been a couple of weeks without an answer, I can offer an alternative approach.
I haven't done redirects to other fields in the GI, but I do something similar to what you are describing. If you are open to alternatives, you can use the GI to go to a screen for the record (i.e. the Appointment). Then create a screen in the mobile app for the Service Order. Then put an action on the Appointment graph to View Service Order. Finally, on the Appointment screen use a RecordAction to redirect via the View Service Order action.
add recordAction "ViewServiceOrder" {
redirect = True
}
In this way, the redirect is defined as an action within Acumatica, and you are simply executing that action.

hide pages in websphere portal without using set parameters

I am using WebSphere Portal 8.5 Enable. I have created a custom theme. But this theme requires to hide pages on navigation which has unique name with ".omit." value in it, so that I don't have to manually set each page's parameter.
I created the flyout or menu dropdown using this:
Flyout or Menu Dropdown in Portal 8 themes
Any suggestions and pointers are welcome. Thanks in advance.
Maybe you have already thought about this.
The solution you mentioned (Flyout or Menu Dropdown in Portal 8 themes) hides nodes based on the hidden flag. This method is used to calculate it. Now you could query the uniquename of the Node witin this method and check for your naming pattern and use this to determine if it is hidden. It would allow you to combine the two as well.
the method I think you need to modify.
public boolean isHiddenPage(NavigationNode node){
if (node instanceof com.ibm.portal.MetaDataProvider) {
com.ibm.portal.MetaData iMetaData=((com.ibm.portal.MetaDataProvider) node).getMetaData();
Object url=iMetaData.getValue("hide.from.menu");
return (url != null && url.toString().equals("true"));
}
return false;
}
You can hide any page using the role settings just create a user group which is never used and make that the only thing that can access the page. You should be able to do this is your PAA's PageAssignAccessControl.xml (could be slightly wrong about the name of this file) as well as in the portal Admin console, so you can do it automatically in your deployment code.

ADF Refresh page jsf with page fragments jsff after set session variable

I have a template which includes a button that let you select a profile, you push the button and appear the available profiles, choose one and push accept. After that I set a variable session successfully.
I have a "First" jsf page with two jsff page fragments from a View Link. The view link is composed by a headerView and detailView. The headerView had a bind variable. What I need is that parameter (bindVariableParameter) can be set by the session variable of the template.
This is what I get:
I am in a home page (separate Application Module), I push the template button before I load de "First" jsf page and after that I go to the "First" jsf page the information is loaded successfully. What I do in the Application Module is something like that:
protected void prepareSession(Session session) {
Map sessionScope = ADFContext.getCurrent().getSessionScope();
String company = (String)sessionScope.get("compId");
System.out.println("Default Comapny in BC is: " + company);
super.prepareSession(session);
this.getSession().getUserData().put("Company", company);
System.out.println("After setting value in userData map of BC");
}
And in the bind variable expression of the headerView I use:
adf.userSession.userData.Company
It works great!!!! But!!!!
When I press the button again and I choose another profile, the info is not updated. Neither in the headerView neither in the detailView.
Also, when I go to the "First" jsf page (without previously push the template button), I got no info, which is right, because I don't have any session variable. After that I push the template button and select the profile, but the page is not refreshed.
I tried several ways to to this but I'm lost.
Could you help me?
Regards.
You have two options for this:
Option one: tune your AM as follows:
jbo.doconnectionpooling=true
jbo.txn.disconnect_level = 1
This will ensure prepareSession() method is being called before each operation. This happens to be a best practice in ADF productions systems, increasing scalability (see here )
Option two: Better than using prepareSession(), you can pass the Http Session data to ADF BC through a custom DataControlFactory.
You can find an example here: http://andrejusb.blogspot.co.uk/2012/05/solution-for-sharing-global-user-data.html

How to Refresh ADF jsf page components by pressing a button?

I have a fusion web application that contains an af:query panel (I created it query panel with table), and af:table and af:panelFormLayout that are related with each other. When I search an entry in the query panel results are shown both in table and in panelFormLayout. When I press reset button in the query panel, only the query panel is reset. I want to all the page to reset. How can I do that by using the easiness of ADF?
Basically you want to override the reset functionality of the af:query. In that case, you should:
1. Set the QueryListener property of the af:query to a managed bean method. You can refer to this example which describes all the steps required: Programmatically RESET query panel
Inside it, you'll see this call: AdfFacesContext.getCurrentInstance().addPartialTarget(t1);
It is responsible for the refresh of the table. Now, if you have all the content inside an af:panelGroupLayout for example (or any other payout type component), you can refresh it instead (so you need to bind it with a field on the bean and use it instead of t1 in this call. Otherwise, if you still wish the full page refresh, follow step 2.
2. Add the needed code to make the page refresh:
FacesContext context = FacesContext.getCurrentInstance();
String currentView = context.getViewRoot().getViewId();
ViewHandler vh = context.getApplication().getViewHandler();
UIViewRoot x = vh.createView(context, currentView);
x.setViewId(currentView);
context.setViewRoot(x);
Just put it inside the method described on the above link.

How to use custom logic to conditionally display a ribbon group in a grid view-like scenario in a supported fashion in CRM 2011?

I've modified the sitemap of a CRM 2011 solution to contain a new Area. That area contians a single Group and the Group contains a single SubArea.
The SubArea is defined with a URL attribute similar to this...
<SubArea Id="x" Url="/WebResources/new_/y.html"
<Titles>
<Title Title="z" LCID="1033" />
</Titles>
</SubArea>
When a user clicks on this subarea in the nav bar the y.html webresource loads in the content area of CRM as expected. It loads similar to how a grid view would load, but instead of the grid view, y.html is loaded.
In addition, a customized ribbon is loaded.
Currently this customized ribbon disables ribbon button groups based on the role of the current user. This is done using an EnableRule of the CommandDefinition in RibbonDiffXml. In the EnableRule a CustomRule is defined that references a javascript function that returns true or false based on some custom logic regarding the users role.
This is working well. However, I've been asked to remove the ribbon button groups instead of just hiding them.
My understanding is that this is more of a task for a DisplayRule than an enable rule. However, from what I gather DisplayRule does not have a CustomRule option as EnableRule does.
After gathering that DisplayRule isn't an option, I thought that I might be able to write some javascript in the Enable rule to remove the group (as well as return a value to enable it or not). However, after debugging the javascript, I see that although I have access to Xrm.Page, I do not have access to Xrm.Page.ui (similar to the expected result for a grid view). Therefore, I can't disable the tab here either (without resorting to unsupported javascript).
How can I use custom logic to conditionally display a ribbon group in a grid view-like scenario in a supported fashion (e.g. no jQuery/ect)?
Currently this customized ribbon disables ribbon button groups based on the role of the current user...
I assume then that you basically wish to toggle ribbon functionality, based on user's permissions.
DisplayRule does not have a CustomRule option as EnableRule does...
Correct
DisplayRule isn't an option
Not sure that this is necessarily true. While DisplayRule may not have a CustomRule option, it does have a MiscellaneousPrivilegeRule.
Depending on the configuration of your roles and your requirements, you may be able to bypass looking at the users "role" and instead set up a rule that effectively checks: if the user can read the invoice entity, show this button (group) (obviously this is just an example - you get the idea)...
If your roles are more complex you could create a pseudo-entity (e.g. called "CanViewMySpecialButtons"), remove it from anywhere in the UI and only grant read permissions to the roles that should view your buttons. You can then create a MiscellaneousPrivilegeRule that checks if the user can read your pseudo-entity - only those users in your role are able to see that entity therefore the button can be set hidden for all other users.

Resources