Sei sulla pagina 1di 28

BackOffice – NG Cockpit

The Backoffice is the Landscape where all Backend business tools would reside in the future.
The Backoffice Framework provides UI building components called Widgets which you can
wire together to build your own Cockpit.

Q: How to generate your own backoffice-based extension to add new cockpit functionality?

Ans: - ybackoffice template is used to generate your own back office extension

Explain “ybackoffice” using ant extgen

✓Step 1 = C:\develop\projects\Demo\hybris\bin\platform>ant extgen& Hit Enter

✓Step 2 = Choose Template for generation = ybackoffice (type ybackoffice) and hit enter.

✓Step 3 = Choose name of your extension = demobackoffice& hit enter

✓Step 4 = Choose package name of your extension = nz.govt.aucklandcouncil.demobackoffice &

other options as false

✓Step 5 = Add your extension “demobackoffice” to your... \config\localextensions.xml


Create a new BackofficeRole group

This means that you can design a Backoffice application that shows a different application mash-up
to different business users, depending on their business role.

Create Roles using Backoffice FWK:

1. Create a new Backoffice Role group:

a. Go to User Groups in User node.

b. Choose the Backoffice Role from the drop-down menu:

The wizard Create New Backoffice Role pops up and you can create the new role here:

c. After creating the role you need to edit it in the Administration tab. You can add relevant
authorities there.
2. Once you have done this, your new group is available in the Application Orchestrator. You can
choose the group you want to design your Backoffice application for.

Create Roles using Impex:

You can create a backoffice role using impex also. Sample impex scripts are provided below. You can
make use of it.

a) Create a new BackofficeRole group


INSERT_UPDATE BackofficeRole ; UID[unique=true]; locname[lang=en]; backOfficeLoginDisabled ;
authorities

;demouserrole; Demo User Role; FALSE; demouserrole;

b) Create a new UserGroup member of the new BackofficeRole group and employeegroup group
INSERT_UPDATE UserGroup ; uid[unique=true]; locname[lang=en]
; demogroup ; "Demo User Group"
INSERT_UPDATE PrincipalGroupRelation ; source(uid)[unique=true] ; target(uid)[unique=true]
; demogroup ; employeegroup ;
; demogroup ; demouserrole ;

c) Create users member of the new group


INSERT_UPDATE Employee ; UID[unique=true]; name; groups(uid); description
; password
; demouser@aucklandcouncil.govt.nz; Demo User; demogroup ; This user has access to
booking failitator.; 1234

d) Provide access rights to Item type


$START_USERRIGHTS
Type;UID;MemberOfGroups;Password;Target;read;change;create;remove;change_perm
UserGroup;demogroup;;;;;;
;;;;Product;+;+;+;-;-
$END_USERRIGHTS

Update your backoffice configuration, add a new perspective by configuring principal attribute of
contexts to your new backoffice role.

To configure new perspective in “demobackoffice-backoffice-config.xml” file.

Goto * C:\develop\projects\Demo\hybris\bin\custom\demobackoffice\resources\demobackoffice-
backoffice-config.xml file.

Insert the following complete code block in place of the comment section above (remove all the
existing code inside the <config> tags)
<config xmlns="http://www.hybris.com/cockpit/config">
<context component="perspective-chooser" principal="demouserrole">
<y:perspective-chooser xmlns:y="http://www.hybris.com
/cockpitng/config/perspectiveChooser">
<y:authority name="demouserrole">
<y:perspective id="demobackoffice-perspective"/>
</y:authority>
</y:perspective-chooser>
</context>
</config>

Goto * C:\develop\projects\Demo\hybris\bin\custom\demobackoffice\resources\demobackoffice-
backoffice-widgets.xml file.

Add Border Layout widget for your new perspective inside <widgets> tag.
<widget-extension widgetId="backofficeMainSlot">
<widget id="demobackoffice-perspective"
widgetDefinitionId="com.hybris.cockpitng.borderlayout" template="false"
slotId="perspectives" title="demo.perspective.name” access="demouserrole">
</widget>
</widget-extension>

To see new backoffice perspective, do above changes and call ant clean all and start hybris
server using hybrisserver.bat command for windows. Once server is up then update system
by selecting new backoffice(demobackoffice) extension.
Define Node Structure & Layout

To define the node structure & layout of screen in “demobackoffice-backoffice-config.xml” file. Add
the xml configuration (define the node and columns).
<context component="explorer-tree" merge-by="module">

<n:explorer-tree xmlns:n="http://www.hybris.com/cockpitng/config/explorertree">

<n:navigation-node id="demoProduct">

<n:type-node id="demoProduct" code="Product"/>

</n:navigation-node>

</n:explorer-tree>

</context>

Perform below steps: -

a) C:\develop\projects\Demo\hybris\bin\platform>setantenv.bat
b) C:\develop\projects\Demo\hybris\bin\platform>ant clean all
c) C:\develop\projects\Demo\hybris\bin\platform>hybrisserver.bat
d) Perform update - https://localhost:9002 -> platform -> update
e) Goto https://localhost:9002/backoffice and see the results

Note = (1) You can also create the configuration directly using the Application Orchestrator without
having to write it in the demobackoffice-backoffice-config.xml file. To do this, open the editor using
Show cockpit-config.xml and hit the Store button after changing the configuration. However, if you
hit Reset to Defaults again, your dynamic configuration will be lost. To persist it permanently, it is
recommended to create the configuration in your custom extension.
(2) To view these UI changes made in demobackoffice-backoffice-config.xml without having
to do a rebuild or restart follow the below steps.

a. Switch to the Application Orchestrator mode by pressing F4 (you'll need to be logged in as


an administrator).

b. Click the Hybris logo in the upper right corner of the screen and select the Reset to Defaults
option under Show cockpit-config.xml

c. After the page reloads, press F4 again to exit Application Orchestrator mode
Add a new field / new attribute in the back office to the existing node:

Scenario = Let’s add “Agreement Name” in User --> Agreements

To achieve this, we should specify:

<context component="explorer-tree" merge-by="module"> in our custom extension.

It means that, find configuration for context="explorer-tree" from another module, and merge with
it.

✓ Step 1 = Goto demobackoffice\resources\demobackoffice-backoffice-config.xml file and add
the new attribute in the xml config file and save the changes


✓ Step 2 = Goto https://localhost:9002/backoffice and follow these steps to see the new field

(a) Switch to the Application Orchestrator mode by pressing F4 (you'll need to be logged in as
an administrator).

(b) Click the Hybris logo in the upper right corner of the screen and select the Reset to
Defaults option under Show cockpit-config.xml
(c) After the page reloads, press F4 again to exit Application Orchestrator mode

✓ Step 3 = Define the attribute in /demobackoffice/resources/demobackoffice-items.xml file

✓ Step 4 = Change the label name using localization

Goto /demobackoffice/resources/localization/demobackoffice-locales_en.properties” file and add this


line & Save the file
✓ Step 5 = = Perform below steps: -
a) C:\develop\projects\Demo\hybris\bin\platform >setantenv.bat
b) C:\develop\projects\Demo\hybris\bin\platform >ant clean all
c) C:\develop\projects\Demo\hybris\bin\platform >hybrisserver.bat
d) Perform update - https://localhost:9002 -> platform -> update
e) Goto https://localhost:9002/backoffice and see the results

If we want to configure explorer tree specific to perspective. Each perspective can have different
explorer tree.

Consider one perspective is having 2 nodes in explorer tree and another perspective is having 3
nodes, when user changes perspective it should display corresponding explorer tree.

To achieve this, we have two possibilities:

 as described here you can use the explorerTreeConfigCtx to define another component to
look up

 you can declare additional context attribute called module which should be equal to
the id of the perspective (the root widget's id of the perpective); in this case you may
use the same component

Editors
Editors are special components provided by the Backoffice Framework that you can use inside
your widgets in order to edit and manipulate data.

The Backoffice Framework comes with list of standard editors. Here we will see how
Extendedmultireferenceeditor can be used to select multiple references of another type. For
that, we need to define the editor id for a qualifier you want to be displayed as the default extended

multi reference editor, and you need to define the parameter listConfigContext and its value to

specify the components to appear in the context lookup.


Example:

Changing the editor for qualifier “variants” in product item.

Then the list has to be defined as well.

InlineEditing - Allows for inline editing of the displayed values. Default value: false

As we have changed the list view context in above example, you need to set it in parameter
colConfigCtxCode for collection browser widget inside demobackoffice-backoffice-widgets.xml
Perform below steps: -
a) C:\develop\projects\Demo\hybris\bin\platform >setantenv.bat
b) C:\develop\projects\Demo\hybris\bin\platform >ant clean all
c) C:\develop\projects\Demo\hybris\bin\platform >hybrisserver.bat
d) Perform update - https://localhost:9002 -> platform -> update
e) Goto https://localhost:9002/backoffice and see the results

Result:

Inline Editing:
There are some other commonly used editors provided by backoffice framework.

Example:

Editor - Check Box Boolean Editor

ID - com.hybris.cockpitng.editor.boolean.checkbox

Description - Can be used to change the value of a Boolean property. If the box is checked, the
value is true, otherwise it is false.

Preview -

Editor - Default Date Editor

ID - com.hybris.cockpitng.editor.defaultdate

Description - Can be used to change the value of a Date property. To change the value a calendar
pop-up is opened.

Preview -
Editor - Default Enum Editor

ID - com.hybris.cockpitng.editor.defaultenum

Description - An editor that can handle enumeration values. It covers java.lang.Enum values as well
as any other class that has an EnumValueResolver implementation, for example values of
type HybrisEnumValue.

Preview -
Editor - WYSIWYG Editor

ID - com.hybris.cockpitng.editor.wysiwyg

Description - Rich text editor (What You See Is What You Get).

Preview -
Creating an Editor

It is possible to create your custom editor. Creating a custom editor is similar to creating a
custom widget. You need to create an editor definition and java class implementation. The renderer

class of the editor is responsible for creation of the actual view. It is also responsible for setting up the
communication of value changes back to the widget using the EditorListener.

Your XXXEditor class must implement the CockpitEditorRenderer interface.

Requirement:

Create Custom drop down, display all OPEN status orders placed by specific user till current time.

Pre-Condition:

BookingModel extends OrderModel

Steps:

Create the below folder structure in custom backoffice(demobackoffice) Extension.


1) In the directory
demobackoffice\backoffice\resources\widgets\editors\availableBookingsEditor create the
following definition file:

definition.xml

2) Create renderer class,

2.1) View of our custom editor is a ComboBox component. So, Create combobox and set it to parent.

3) Get List of Bookings which are open status as per requirement above, set that into Comboitem
and then append that Comboitem as child to ComboBox.

List<BookingModel> availableBookings = new ArrayList<BookingModel>();


/* write API logic to get list of open bookings here */

4) Add ZK listeners to the editor view (ComboBox) to catch the ON_CHANGE, which are triggered
when the value changes.
In the above example, the widget will be notified that the value has changed through EditorListener.

5) We need to define the editor id for a qualifier you want to be displayed as custom drop down
editor like below.

Note: We can define custom editors for different components like editor-area, create-wizard etc.,
Here I have used it in create-wizard component.

Result:

Creating an Editor Without a Renderer Class

It is possible to create an editor that uses a ZUL file to define the view, therefore does not require a
custom renderer class at all.

1) Add the definition:


definition.xml
2) Create the ZUL file:

boolEditor.zul

If you do not have a custom renderer class defined, then by default an implicit renderer of
type DefaultZulCockpitEditorRenderer is used.

Localizing Editors

1. Go to the directory myextension/backoffice/resources/widgets/editors/<nameOfEditor>


2. Create the labels folder.
3. Create the labels.properties and labels_<isocode>.properties files.
Create, for example, the labels_en.properties file, for each language you want a localized label
for.

These properties files are the place to specify your localized keys:

my.localized.key=My localized value

Using Editors in Widgets

To use an editor in a widget, you need to add it to the widget view. It should have some id and you
also need to define its type.

widgetid.zul

<!-- ... -->

<editor id="textEditor" type="java.lang.String"


defaultEditor="com.hybris.cockpitng.editor.defaulttext"
onValueChanged="mywidgetController.doThings()"/>

</widget>
Every time a user changes the value in the editor, meaning every time the event
called onValueChanged is triggered, the doThings() method, of the mywidgetController is invoked.

public class MyWidgetController extends DefaultWidgetController

private Editor textEditor;

@ViewEvent(componentID = "textEditor", eventName = "onValueChanged")

public void myCallback()

final String tmp = (String) textEditor.getValue();

// do something with the value

Widgets

We will see, how to open up a popup widget immediately after clicking the node in the explore tree
hierarchy. The behaviour should be similar to the '+' button that performs the create action in
backoffice. Do not want any editorarea/listview, just a simple create wizard pop up should be shown
on click.

To achieve above scenario, you need to follow below steps:

1) Add a type node:

2) You need to add ConditionEvaluator widget to your configuration and configure expression for it.
The expression should be evaluated to true when your custom node is selected. For example, if your
node has id 'my_custom_node' then expression should look like: " #root.id EQ 'my_custom_node' ".

In above scenario, node id is ‘Customer’. You need to add conditionevaluator widget and configure
expression with the following script :
#root.id EQ ‘Customer’
3) Then propextractor widget would be helpful. The complete widget configuration looks like this.

4) The final step is connecting everything together:

 Explorer tree (nodeSelected) with ConditionEvaluator(input)


 ConditionEvaluator(true) with Propextractor(genericInput)
 Propextractor(genericOutput) with ConfigurableFlow(contextType)

Result:

Customer node, open popup when you click on that.


Actions and Widgets
Let us consider the requirement to send email to customer whose login is disabled. I am going to
achieve this by creating an action and this action is enabled only for login disabled customer. When
your action triggers, it will open a newly created popup widget associated with this action with
customer mail id pre-populated. In out widget, clicking send button will trigger the email event.

Creating the Action Definition

Create a definition.xml file in the following directory:

<NAME_OF_EXTENSION>/backoffice/resources/widgets/actions/<NAME_OF_ACTIO
N>.

Example:

<action-definition
id="com.hybris.cockpitng.action.disabledUserEmail"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.hybris.com/schema/cockpitng/action-
definition.xsd">

<name>Disabled User Email</name>


<description>Send Email to disabled user</description>
<version>1.0</version>
<author>Kannan</author>

<actionClassName>nz.govt.aucklandcouncil.demobackoffice.action.DisabledUserEmailAct
ion</actionClassName>

<iconUri>icons/mail_disabled.png</iconUri>
<iconHoverUri>icons/mail_active.png</iconHoverUri>
<iconDisabledUri>icons/mail_disabled.png</iconDisabledUri>

<inputType>de.hybris.platform.core.model.user.CustomerModel</inputType>
<outputType>java.lang.Object</outputType>
<sockets>
<output id="disabledUserContext"/>
</sockets>
</action-definition>

The above example is for an action named disabledUserEmail whose implementation class is
nz.govt.aucklandcouncil.demobackoffice.action.DisabledUserEmailAction. The images that are
defined must be stored in the following directory:
myextension/backoffice/resources/widgets/actions/myaction.
2) Creating the Action Implementation Class

In the following code example, the perform() method is the action callback method, invoked
when an action is executed. The canPerform() method determines the state in which the action will
be rendered.

public class DisabledUserEmailAction extends AbstractComponentWidgetAdapterAware


implements CockpitAction<CustomerModel, Object>
{
protected static final String SOCKET_OUT_CONTEXT = "disabledUserContext";

@Override
public boolean canPerform(final ActionContext<CustomerModel> ctx)
{
final CustomerModel customer = ctx.getData();
if (customer != null)
{
boolean canPerform = false;
if (customer.isLoginDisabled())
{
canPerform = true;
}
return canPerform;
}
return false;
}

@Override
public ActionResult<Object> perform(final ActionContext<CustomerModel> ctx)
{
final CustomerModel customer = ctx.getData();
this.sendOutput(SOCKET_OUT_CONTEXT, customer);
return new ActionResult(ActionResult.SUCCESS);
}

}
Configuring Action:

You need to configure your action id where it should be displayed. As per above requirement, this
action should be configured in customer editor area action section.

<context merge-by="module" type="Customer" component="editorareaactions">


<y:actions xmlns:y="http://www.hybris.com/cockpit/config/hybris">
<y:group qualifier="common">
<y:label>actiongroup.common</y:label>
<y:action action-id="com.hybris.cockpitng.action.disabledUserEmail"
property="currentObject"/>
</y:group>
</y:actions>
</context>

Action Result:

1) Login Enabled User – Action should be disabled.


2) Login Disabled User – Action should be Enabled.

Creating widget:

Create a definition.xml file and add information about disabled user email.

Definition.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>


<widget-definition id="com.hybris.cockpitng.widget.notifyDisabledUserWidget"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="http://www.hybris.com/schema/cockpitng/widget-
definition.xsd">

<name>Disabled User Widget</name>


<description>Widget to show disabled user email</description>
<defaultTitle>Notify Disabled User</defaultTitle>
<version>0.1</version>

<sockets>
<input type="de.hybris.platform.core.model.user.CustomerModel" id="inputObject"/>
<output type="java.lang.String" id="send"/>
<output id="cancel" type="java.lang.String"/>
</sockets>
<controller
class="nz.govt.aucklandcouncil.demobackoffice.controllers.NotifyDisabledUserWidgetControl
ler"/>
</widget-definition>

Creating widget view

The view of this widget is defined in a ZK ZUL file, named after the last part of the widget ID as
specified in the definition.xml(in this case notifyDisabledUserWidget.zul ). Add the
text box and button components, providing an ID for each, along with a button label.

<widget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.zkoss.org/2005/zul">
<style src="${wr}/default.css"/>
<div>
<hlayout>
<label zclass="label-email" value="${labels.demobackoffice.
notifyDisablesUserWidget.emailInput}" width="100%"/>
<textbox id="emailInput" zclass="emailInput"/>
</hlayout>
<button id="sendBtn" sclass="y-btn-primary sendBtn" label="Send"/>
<button id="cancelBtn" sclass="y-btn-primary cancelBtn" label="Cancel"/>
</div>
</widget>

Creating a Controller

The newly created widget requires widget controller.

 Create a controller. It should extend DefaultWidgetController.


 Add the implementation for the following actions:
 When widget is poped up, disabled user email should be prepopulated in the text box.
 When the Send button is pressed, event to send email should be executed.

 Add a controller class in definition.xml of the widget.

NotifyDisabledUserWidgetController.java

package nz.govt.aucklandcouncil.demobackoffice.controllers;

import de.hybris.platform.core.model.user.CustomerModel;

import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;

import com.hybris.cockpitng.annotations.SocketEvent;
import com.hybris.cockpitng.annotations.ViewEvent;
import com.hybris.cockpitng.util.DefaultWidgetController;
public class NotifyDisabledUserWidgetController extends DefaultWidgetController
{
private Textbox emailInput;

@SocketEvent(socketId = "inputObject")
public void initEmailInput(final CustomerModel customer)
{
if (null != customer)
{
this.emailInput.setValue(customer.getUid());
}
}

@ViewEvent(componentID = "sendBtn", eventName = Events.ON_CLICK)


public void doSendMail() throws InterruptedException
{
/*
* add event logic to trigger mail
*
*/
Messagebox.show("Email sent successfully!!!!!");
}
}

Finally folder structure of your widget looks like here.

Connecting Action with Widget:


Now, we have our action and widget created. We need to connect our action with widget to display
widget popup when action triggers. To do that, we should add the below configuration into our
demobackoffice-backoffice-widgets.xml

Add this below code, inside your perspective widget.

<widget id="disabledUserPopup"
widgetDefinitionId="com.hybris.cockpitng.widget.notifyDisabledUserWidget"
slotId="cockpitWidgetChildrenInvisible"
title="disabledUser.sendMail.widget.title" template="true">
<instance-settings socketEventRoutingMode="LAST_USED">
<create onInit="false" reuseExisting="true">
<all-incoming-events/>
</create>
<close>
<all-outgoing-events/>
</close>
<select onInit="false">
<all-incoming-events/>
</select>
</instance-settings>
<setting key="widgetStyleClass" type="String"></setting>
<setting key="widgetStyleAttribute" type="String"></setting>
<setting key="_width" type="String">400px</setting>
<setting key="_height" type="String">250px</setting>
<virtual-sockets />
</widget>

Then make a connection between your action and widgets in same file below.

<widget-connection sourceWidgetId="STUB_com.hybris.cockpitng.action.disabledUserEmail"
outputId="disabledUserContext" targetWidgetId="disabledUserPopup" inputId="inputObject"/>

By using @SocketEvent, widgets communicates each other. So, we can pass data between widgets.

Result:

1) When triggering mail action, shows popup widget


2) clicking send button, triggers mail

Note:

You can change behavior of the framework, to make it easier to prototype a widget:
To make changes in ZUL files visible after page refresh, including changes to custom CSS files:
 Change the following properties, then restart the server:
local.properties

backoffice.cockpitng.additionalResourceLoader.enabled=true

backoffice.cockpitng.uifactory.cache.enabled=false

backoffice.cockpitng.widgetclassloader.resourcecache.enabled=false

backoffice.cockpitng.resourceloader.resourcecache.enabled=false

 Updates to labels.properties files are not affected and require the extension to be rebuilt.

Potrebbero piacerti anche