0% found this document useful (0 votes)
298 views159 pages

C4H365 EN Col24

The document outlines the SAP Commerce Cloud Backoffice Framework Developer Training (C4H365), detailing course content, prerequisites, and training structure. It includes an overview of the training environment, learning objectives, and specific exercises planned for each day of the course. Additionally, it highlights the technologies and configurations involved in creating custom Backoffice extensions and the importance of prior knowledge in Java and the ZK Framework.

Uploaded by

venkat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
298 views159 pages

C4H365 EN Col24

The document outlines the SAP Commerce Cloud Backoffice Framework Developer Training (C4H365), detailing course content, prerequisites, and training structure. It includes an overview of the training environment, learning objectives, and specific exercises planned for each day of the course. Additionally, it highlights the technologies and configurations involved in creating custom Backoffice extensions and the importance of prior knowledge in Java and the ZK Framework.

Uploaded by

venkat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 159

SAP Customer Experience

SAP Commerce Cloud Backoffice Framework


Developer Training

C4H365
Material Number: 50163526 SARA
Col24

INTERNAL —- SAP and Partners Only

Some Necessities

= Participant List

= Course Material

= Accessing Remote Training VMs

NAL SAP and Partners Only

© SAP SE C4H365
Training Overview

Personal Introduction

SAP Commerce Cloud


Personal Introduction
Trainer
Name

Role Spring/JEE
Project Experience

Company
Previous SAP
Commerce Cloud
Hobbies Experience, incl.
Cockpit /
Backoffice

2 C4H365 © SAP SE
Training Content — Theory + Practice

This course consists of two parts:

= In-class Lectures

— Illustrate the theory behind core functionality and main concepts of the SAP Commerce Cloud
Backoffice Framework
— Demonstrate the software
— Give an idea of what's available out-of-the-box and what has to be implemented
= Instructor-assisted Exercises (for most modules)
— Give you a chance to write a “Hello World” for each topic presented
— Answer your questions and assist you with the lab exercises

Training Content — What’s Not Included

= SAP Commerce Cloud Platforms & Basics — for those, please check out:

— Either SAP Commerce Cloud Developer Training, Part | and Part Il (C4H340 & C4H341)

— Or the dedicated free E-learnings:

® Beginner: Exploring the Technical Essentials of SAP Commerce Cloud

® Intermediate: Expanding Upon Technical Essentials of SAP Commerce Cloud

» Advanced: Mastering the Technical Essentials of SAP Commerce Cloud

=» SAP Commerce Cloud, composable storefront (aka. Spartacus}

— For that, we offer SAP Commerce Cloud Spartacus ILT Developer Training (C4H370)

= System Administration

— for that, we offer Live Session Series: SAP Commerce Cloud — System Administrator

= Customer-/Project-specific problems

INTERNAL SAP and Parners Only

© SAP SE C4H365
Training Environment Intro OES Sune SEE

x
© Recent = = a= =

® Starred Exercises Handouts eclipse- workspace


= Laptop or personal computer @ Home
bundle

=» Access to SAP VM i) “ane


(through SAP Training Landscape) Y Downloads
dd Music
© Pictures

vm Videos

The VM environment contains TH Wastebasket

» JDK 17 (SapMachine) Gl Floppy Disk


+ Other Locations
= Exercise PDFs (in Exercises)
= Slide PDFs (in Handouts)
= SAP Commerce Cloud (in workspace)
» An IDE
— we provide a pre-configured Eclipse instance (in eclipse-bundle)

INTERNAL SAP and Partnors Only 7

Before the training ...

= It's recommended that you have walked through the E-Learning course:

— SAP Commerce Backoffice Framework Fundamentals (the link only works if you are logged
into SAP learning hub first.)

— This important preparation will save you loads of time and confusion when doing the
exercises in this course

= Beginner-level ZK Framework knowledge (very helpful)

=" Good Java knowledge

INTERNAL SAP and Partnors Only 8

4 C4H365 © SAP SE
What you will learn

= Create a new cockpit/layout in the Backoffice application

= Use existing widgets

= Use the standard widgets library

= Create a new widget

= Connect widgets

= Define a context configuration for your widget and use the merge capability

= Create custom actions and editors

= Unit test your widget

INTERNAL SAP and Parners Only

Working Hours — Day 1

9:00 4. Introduction

Exercise 1 — Class Setup

Day 1 2. Backoffice Fundamentals Recap

12:30 Exercise 2 — Create A New Cockpit

Lunch

13:30 3. Development Environment

Exercise 3 — Set Up The Development Environment

4. Orchestrate A Cockpit

17:00 Exercise 4 — Orchestrate A Cockpit

INTERNAL SAP and Parners Only

© SAP SE C4H365
Working Hours — Day 2

9:00 5. Widget Fundamentals

Day 2 Exercise 5 — Create Your Own Widget

6. Widget Communication
12:30
Lunch

13:30 Exercise 6 — Connect Your Widgets

7. Widget Context Configuration

17:00 Exercise 7 — Configure The Context

INTERNAL SAP and Parners Only

Working Hours — Day 3

9:00 8. Actions and Editors (a)

Day 3 Exercise 8a — Custom Editor

12:30 8. Actions and Editors (b)

Lunch

13:30 Exercise 8b — Custom Action

9. Backoffice Testing Framework

Exercise 9 — Test Your Widget

17:00 10. Good To Know

INTERNAL SAP-ane Pato On 12

6 C4H365 © SAP SE
Exercise 1 — Class Setup

Exercise 1 — Class Setup

= Install and initialize SAP Commerce Cloud using a recipe.


= Start SAP Commerce Cloud, verify the environment and exercise data.

= EY Administration cockpit + & @ @


Filter tree (Alt+Down for options) Products Type to search Q ® y

@ Home tly e,.e@ @ (s)a #


inbox (Product... Artie Number 11 Identifier Jt ‘Status Catalog Version
D system >, Oo testBook001 testBo0k001 a90 ‘Bookstore
Product Catalog : Staged
© tomas . om.) 19439522259 ‘The Chicken or Egg Dilemma - Cracked avo ‘Bookstore Product Catalog : Staged
Og 18685677009 English-Serbian dictionary avo ‘Bookstore
Product Catalog : Staged
cantor: Og 18679478989 ‘A Polyglot in London avo ‘Bookstore Product Catalog : Staged
canteens O86 8423207600 History of Pizza & Wine avo Bookstore
Product Catalog: Staged
‘Categories Og 7313785739 History: India avo Bookstore
Product Catalog : Staged
Products OG a 6265644009 ‘The Trainer's Secret avs Bookstore
Product Catalog : Staged
proc vai Type Og 6493374189 ‘The Programmer avo Bookstore Product Catalog : Staged
nts Og 6824238759 ‘The eCommerce Murderess avo ‘Bookstore
Product Catalog : Staged
Og 15650539359 (OMS Expert in 24 Hours avo ‘Bookstore
Product Catalog : Staged
Komen Og 15536152009 Hybris All in One avo ‘Bookstore Product Catalog : Staged
met nated vos 4729720538 Hybrs for ummies BvD —_ Bookstore
Product Catalog: Staged
No queries FD nernennnn 7 7 7 Pars Perera nanuwts
tems selected a7 hems

© SAP SE C4H365 7
SAP Customer Experience

Thank you.

SAP Customer Experience

Backoffice Fundamentals Recap

INTERNAL — SAP and Partners Only

8 C4H365 © SAP SE
We will learn about:

> Backoffice Framework Fundamentals

> Backoffice Configuration

Widgets, Actions & Editors


Vv

Cockpits/Perspectives
Vv

Application Orchestrator
Vv

INTERNAL SAP and Partnors Only 2

Backoffice Framework Fundamentals

© SAP SE C4H365 9
Backoffice Fundamentals Refresher - Architecture

Backoffice Framework

Sanders ; UI Frontend Perspective


7 3rd Party
Frameworks
Library
Backoffice Engine
Backoffice
Felaalial
Widgets ZK Framework

3rd Party i
Widgets i Core Backoffice Framework

Backoffice Fundamentals Refresher - Architecture

= Backoffice Administrator Cockpit


Backoffice Business
E Application
* Single user interface for all SAP £
8
al
Commerce Cloud back-end business tools no)
=i
x) Backoffice Admin
¢ Provided out-of-the-box in SAP Oo a“ Widgets
ca)
Commerce Cloud 2
©
£ Backoffice Admin
¢« For administrators and business users E
ie) Core
Oo
o
zx
ep)
Backoffice Framework

10 C4H365 © SAP SE
Backoffice Fundamentals Refresher - Technologies

Technologies used i)
spring LXML

dy « ©
# <I>

JAXB

Major Backoffice Framework Extensions

" backoffice extension:


— Backoffice framework and Administration Cockpit with standard widgets
— Single web application which is a container for all Backoffice modules
— Contains the Application Orchestrator (F4) to design your custom mashup
— Accessible by default at https: //localhost:9002/backoffice

« platformbackoffice extension
— Provides some of the editors and actions that enable you to manage SAP Commerce Cloud

« ybackoffice extension template


— Template you can use to generate a custom extension where you can implement your own
Backoffice module, widgets, or UI configuration
— The Application Orchestrator can help you generate the configuration that adds your custom
components to Backoffice
— Each extension based on ybackoffice will contribute to the main Backoffice application

INTERNAL SAP and Partnors Only 7

© SAP SE C4H365 11
Custom Backoffice Extensions

= Acustom backoffice extension can contribute to the whole and unique Backoffice web app with
new modules (areas), widgets and/or UI configuration
= Create a new backoffice extension:
— Create the extension with ant
ant extgen

— Select the ybackoffice template


— Provide the name and default package for the new extension, can leave the other values to their defaults
(sample widget and style sheet)

— Add the new extension to config/localextensions.xml


— Perform complete build of the platform

ant all

— Import the extension project into the IDE

INTERNAL SAP and Parners Only

Backoffice Configuration

12 C4H365 © SAP SE
Custom Backoffice Extensions: Essential XML Files (in resources’ folder)
V8 trainingbackoffice
The following xml files are relevant inside the > BA JRE System Library [JRE [17.0.2]
> mi Referenced Libraries
resources folder of a custom Backoffice extension > @Bsre
> (@backoffice/srce
(e.g., the trainingbackoffice extension): > @testsre
> @gensre
> @backoffice
— trainingbackoffice/resources/ trainingbackoffice- > @classes
backoffice-widgets.xml: Configuration of custom widget lib
v_*= resources
components and their connections. (& backoffice
@ cockpitng
— trainingbackoffice/resources/trainingbackoffice- @ localization
@ trainingbackoffice
backoffice-config.xml: Configuration of custom context @ trainingbackoffice-backoffice-labels
components. [S| beans.xsd

— trainingbackoffice/resources/ trainingbackoffice-
backoffice-spring.xml: Contribution to the Widget
fice-backoffice-wit
Application Context. This is an additional Spring context | trainingbackoffice-beans.xm
with auto reload possibilities during runtime. It's shared ft) trainingbackoffice-items.xml
X) trainingbackoffice-spring.xml
among all the Backoffice extensions. B)build.xmi
&)buildcallbacks.xml
[X) extensioninfo.xml
[S| extensioninfo.xsd
=) platformhome.properties
INTERNAL SAP and Parners Only |=) project.properties

Backoffice Configuration - |

Two types of Configuration:


1) Application Structure
2) Ul Context

1. Application Structure: via *-backoffice-widgets.xml files


2 Declarations of ALL widget instances that make up the
Backoffice-Framework application — merged into widgets. xml
2 Each widget’s initial “widget settings” (e.g., visibility of its slots)
1 How each widget is nested within another widget’s “slot”
(i.e., the hierarchal composition of widget instances)
1 Wiring of widgets (i.e., interconnections via widget sockets)

© SAP SE C4H365 13
Precedence of Application Configuration (*-widgets. xm1)

= 2 sources of this configuration:

— widgets.xml: Merged configuration of the whole Backoffice application including any


extensions based on the ybackoffice template.

1 Not to be modified directly, it is generated automatically, e.g., when you add/remove widgets
and create widget connections using Application Orchestrator.

— trainingbackoffice/resources/trainingbackoffice-backoffice-widgets.xml: Default
configuration of components defined in the mybackoffice extension.

= Performing a reset of widgets. xml in the Application Orchestrator will result in a loss of the
dynamic configuration. Default configuration from all Backoffice module extensions will be re-
loaded.

Backoffice Configuration - Il

Two types of Configuration:


1) Application Structure
2) UI Context

2. Ul Context Config.-— via *-backoffice-config.xml files


"2 Context-sensitive component-specific configs:
— Each widget type has its own special XML configuration format (within <context>
bodies) to affect how each widget instance view is generated by the widget
controller
— Allows each instance of the same widget type (definition) to adapt what it displays
or how it functions to its contextual circumstances (e.g., type of data being
displayed; privileges of user / role logged in)

14 C4H365 © SAP SE
Precedence of UI Context Configuration (*-config.xm1)

= 3 different sources of UI configuration info:

cockpit-config. xml: Merged configuration of the whole Backoffice application including


any extensions based on the ybackoffice template

1 Can be modified at runtime via Application Orchestrator --> Show cockpit-config.xml.

trainingbackoffice/resources/trainingbackoffice-backoffice-config. xml:
Configuration of components defined in, e.g., the mybackoffice extension.

(optional): trainingbackoffice/backoffice/resources/widgets/mygwidget/cockpit-
config.xml:
Configuration supplied as part of the definition of a specific widget.
Think of it as the widget instance’s default configuration.

The merged configuration can be loaded at runtime by doing a reset on “config.xml” in


Application Orchestrator (similar to widgets.xml)

UI Context Config uration « Examples

= EY Aaminisraon cockpit ~ <context type="Book” & © 8


on Book component= > Qa a 4

Book Management Tree ¥ mae ee. € @ (| a

| Book O Identifier 17 Book. Authors Deser... i


| ()__ ® The Chicken or Egg Dilemma - Cracked Ken Jian [Ken Jian] |

Be engist-serian aicionary Mare Markovich [Mare Markovich


(Bla Patyetatin London Phil Lacd [Phil Ladd] <context type= "Book"

() & wine
History ot Pizza Safin LifSafin ti] component=
asitems
" "
Title: "The Chicken or Egg Dilemma - Cracked" - Bookstore Product Catalog: Staged | <COntext type="Book
component="b >
8 ©
Properties Attributes Category System Prices Multimedia Verlants Extended Attributes Reviews Stock Administration

a [books.essential] a

<context sensier © cerdog version cape


component= brer-tree"> The Chicken or Egg Dilemma - Cracked Bookstore Product Catalog : Staged approved :
Image Desciption ® "Book"
® 300Wx300H/chicken-cr-exg.pri - Book... <context type= Boo
component= >

© SAP SE C4H365 15
UI Context Configuration * ExplorerTree

<context component= "bb-explorer-tree” perspective="bookstorebackoffice-


perspective”>
<n:expLorer-tree
xmLns:n= "“Attp://www. hybris. com/cockpitng/config/explorertree ">
<n:navigation-node id= "Book Management Tree’> = SARA Book Management ~
<n:type-node id= "Books" code="Book” />
</n:navigation-node>
book
</n:expLlorer-tree>
</context>
vy _ Book Management Tree

Book

<context
component="bb-explorer-tree">

UI Context Configuration « List View


<context type= "Book" component="bb-listview">
<List: list-view
xmLns: Llist=“Attp://www. hybris. com/cockpitng/component/1istView”>
<List:column qualifier="”" spring-bean="previewListCellRenderer” width="Z6px"
/>
<List:column qualifier= "name "/>
<List:column qualifier= "authors" />
<list:column quatifier="descriptién"/* * ae
</list:list-view> O | Identifier 11 Book.Authors Deser... It |
</ context> | {_) © The Chicken or Egg Dilemma - Cracked Ken Jian [Ken Jian]

O 8 English-Serbian dictionary Marc Markovich [Marc Markovich]

O | A Polyglot in London Phil Ladd [Phil Ladd]

Oo <}) History of Pizza & Wine Safin Li [Safin Li]

CB history: india Greg Matus [Greg Matus]


O The Trainer's Secret Shana Blair [Shana Blair]

(Bi the Programmer Nevena Antesevic [Nevena Antesevic]


<context type= "Book ” rce Murderess Pierre Billon [Pierre Billon]

component="bb-Listview"> 18

16 C4H365 © SAP SE
UI Context Configuration « Editor Area
<context type="Book" component="editor-area">
<editorArea:editorArea
xmLns:editorArea= "Attp://www. hybris. com/cockpi tng/component/edi torArea”">
<editorArea:essentials>
<editorArea:essentialSection name= “books. essential ">
<editorArea:attribute qualifier= "code"/>
<editorArea:attribute qualifier= "name "/>
<editorArea:attribute qualifier="catalogVersion"/>
<editorArea:attribute qualifier= "approvalStatus"/>
<editorArea:attribute qualifier= "picture"/>
<editorArea: attribute QU Title: "The Chicken or Egg Dilemma - Cracked"
- Bookstore Product Catalog : Sta... v
</editorArea:essentialSec « « 1 + (foe
</editorArea:essentials> Properties Attributes Category System Prices Multimedia Variants Extended Attributes. Reviews Stock Administration
</editorArea: editorArea>
</context> [books.essential *
Anticle Number* Identifier ©
< context type= "Book " 9439522259 ‘The Chicken or Egg Dilemma - Cracked

component="“editor-area"> Catalog version® Approval


Bookstore Product Catalog : Staged approved

Image Description ©
® 300Wx300H/chicken-or-egg.png - Bookstore Product Catalog :... 20

Widgets, Actions & Editors

© SAP SE C4H365 17
Widgets

= §tand-alone, deployable components

= MVC-based

= Clearly defined interface

= Specific purpose

= Highly composable

= Highly connectable

22

Widgets
Backoffice Business Application

= Widgets talk to each other via messages (i.e., Backoffice


objects) with the help of the Backoffice Framework

= The widgets are organized in a tree structure. The Backoffice &


tree structure of widgets ensures the hierarchical
Communication
structure. Owing to the hierarchical structure, a widget
can be a child of another widget.

= You can add, remove, and exchange widgets without


breaking the application

= List of Available Widgets on SAP Commerce Cloud Help

23

18 C4H365 © SAP SE
Actions & Editors

= Actions
— Used to trigger CRUD operations on objects or to trigger method calls in widget controllers

— Some default actions available in the framework are:

+ | Create action: Create an object of a Type

@&_ Permission settings: Manage type- and attribute-based permissions per Principal

‘1 Delete action: Delete an object of a Type

= List of Available Actions on SAP Commerce Cloud Help

Actions & Editors

= Editors
— Used to properly display and capture input for different types of data for editing. For example,
special editors might be required for editing dates and ranges.

— Some available editors:

° Default Boolean editor: ruc False @ wa

° Localized simple editor: | en + Localized value

= List of Available Editors on SAP Commerce Cloud Help

© SAP SE C4H365 19
Cockpits

Cockpit Concept

» What is a cockpit?
_= SAF
. A
acialaienen
ministration

Cockpit

— Adistinct sub-application within Backoffice Filter tree (Alt+


| AROS HT ime
— Only one cockpit can be viewed at a time | Book Management

— Represents the functionality of a standalone | @ _ Home : Task @


business application sii Qu
4
— Permissions at the cockpit level allow only specific 3 '"»™
sers/groups to access the cockpit =
u group pl System >

= When to create a new cockpit?

— When you have a need for a new standalone back office application
— When enabling a new business user role

27

20 C4H365 © SAP SE
Example Backoffice Cockpits
SV MiaeeP oduct Cockpit
a Assortment
= SARA Administration Cockpit

Srl nN All catalogs * +ly


gAdministration Products | 2
celieliesaualasggtions)
= EY Adaptive search ~
Home
‘>

Navigation Context Search profile context:

Inbox Index Configuration Ad a p


9223868

Electronics Solr Index -

System Index Type Qa Starter Kit [23194] - Electronics


Product Catalog : Staged
electronicsProductType v Bog

Catalog Catalog Version 1 79 > 179 result(s) found 499


Electronics Product Catalog: On v

Catalogs Seaich Frome DC Car Battery Adapter a)


100) £408? OC Car Battery Adapter
$179.93
Catalog Versions
>) Camcordertape Dv 6omin (2)
MiniDV Premium Tape - 60 min. Blister of 2. Bri
Categories y a) value for money, MiniDV Premium is an ideal
Categories
$8.00
Y Global
Flagship tripod with remote
PROFESSIONAL BW400CN Film control and pan handle [23355] -
| Products > Open Catalogue PROFESSIONAL BW400CN Film Electronics Product Catalog :...
> Brands $12.50
ava
> Color AC-VQ900AM
im AMR ‘AC Adaptor charger
$168.52

Application Orchestrator

© SAP SE C4H365 21
Perspective
Authority Group Selector Chooser
Application Orchestrator — Layout View
Outset level
ee Select Authority Group »- v ® os Symbolic widgets ff) Widget Clipboard

Tool ba r Backoffice Main Layout Setesh x


‘Show widgets.xml

Flexible Layout Reset to Defaults

‘Show cockpit-config.xml

View Switcher Reset to Defaults

Simulate config resolution

Slots Mev] Reset Everything


[untitled] collaboration.container Widget Toolbar Color P

Backoffice Perspective Container C®UGRAe*x

AO Menu
pectives]
< ™ adminarea Kpit. ame tt »name >

Widgets Border Layout A®GeMAxX


a
[cockpitwidgetChildreninvisible] searen +
a 2 C&P X | Adaptive Search Main Layout 9 CT BB X — Adapter
Configuration AT Rex
sontainer
Navigation Context a
Navigation Context Z Q @ X Search Result Browser REX Editor Area G@REX
Index Configuration z No items selected

Categories y Search Context e2@ROX staticSectionSlot a

cockpitWidgetChildrenInvisible Slot

Application Orchestrator — Symbolic Widgets View

Select Authority Group v Loy ‘symbolic widgets {_] Showslotids {—) Showconnections 2) Widget Clipboard i=

» Backoffice Main Layout CCG ax Generic Bookmark Handler @ @xXx

Deep Link Widget o @x

Editor Area o @x

as

Reference Advanced
Search Group a @ x
as

Image Cropper 2 @ x
as

22 C4H365 © SAP SE
Demo

= Backoffice is the next-generation administration framework, which is composed of a list of sub-


applications called cockpit

= Backoffice contains a Ready-to-Use library of Ul components, called widgets

= You can extend Backoffice by creating ybackoffice based extensions

= There are two kinds of important configuration files:

— Application structure configuration via *-backoffice-widgets.xml in each backoffice extension,


which will be merged to widgets.xml

— Ulcontext configuration defined in *-backoffice-config.xml in each backoffice extension, which


will be merged to cockpit-config.xml

= You can also visually configure Backoffice UI widgets using the Application Orchestrator

INTERNAL SAP and Partnors Only 33

© SAP SE C4H365 23
Exercise 2

Exercise 2 — Create a New Cockpit

Book Management Cockpit


A simple cockpit now, but you will build on top of it in the next exercises.

= SARA Book Management v

Administration Cockpit

Book Management

35

24 C4H365 © SAP SE
|. Create a New Extension

Create a new Backoffice extension

$ ant extgen

ll. Create a New Cockpit e 1

Create a new cockpit


using the Application Orchestrator

Backoffice Main Layout

Flexible Layout

View Switcher

[views]
[untitled] _ collaboration.container

Backoffice Perspective Container

[perspectives]
admin.area Book or

Border Layout

leftSlot + centerSlot

© SAP SE C4H365 25
ll. Create a New Cockpit e 2

Create a new cockpit


using the *-widgets. xml

By editing bookstorecustombackoffice-backoffice-widgets. xml

SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

26 C4H365 © SAP SE
SAP Customer Experience

Development Environment

INTERNAL — SAP and Partners Only

We will learn about:

> Environment Set Up

> Development Support (Breadboard Widget, Caching, Configuration Reset, Hot Deployment)

> Training Labs Tool

INTERNAL SAP and Parners Only

© SAP SE C4H365 27
Environment Set Up

Use an IDE

We recommend using an IDE a

= Here, we are using Eclipse IDE for Enterprise Java __\ ec|| Se
and Web Developers =f

Import all the required extensions to your workspace


(here are the minimal examples):
—config
—Platform
—alluicommons
—auditreportservices
IntelliJ IDEA
—backoffice
—Your new, custom Backoffice extension

28 C4H365 © SAP SE
Set Up Ant

= As usual: execute setantenv.sh (setantenv.bat under Windows) before building in your


console/terminal.

= (Optionally) In Eclipse, point the Ant class path to the one that comes with the platform
-${HYBRIS_BIN_DIR}/platform/apache-ant-*

wf ( wh

The platform's build targets are in Mdidigcr


HE RNT>

${HYBRIS_ BIN _DIR}/platform/build.xml

Development Support

© SAP SE C4H365 29
Development Support: Overview

Backoffice Framework provides several supports for your development:

Breadboard Widget

Disabling Caching of Components and Controllers

Resetting Backoffice Configuration

Hot Deployment Dev Toolbar

Development Support - Breadboard Widget

Breadboard

Awidget that’s installed on the Backoffice application Teste


Took tS
Simulates sending input data to the widget

Provides the output data as well

To access it, first login to Backoffice, then go to URL:


° https://ocalhost:9002/backoffice/?mode=breadboard

Note: Backoffice Framework development mode must be enabled


viathe property;
° backoffice.cockpitng.development.mode=true |

Exit via URL https://lLocalhost:9002/backoffice

30 C4H365 © SAP SE
Demo — Breadboard Widget

2,987.26

Development Support - Breadboard in Action!

Breadboard Sse"
= ‘Choose
2 widget: Border Layout B "cane Borderorder LayurLavou conto
controller; Iris cocking gets control
_com.hybris.cockpitng.widgets.controller; get Seting
(MUCeaescutec}
‘Cockpit Development& Testing Toot Code: ‘com.hybris.cockpitng.borderlayout ViewURI: ‘Icockpitng/widgets/borderlayout/border|

Filter™

Ey oe: |

Console
Sinput[(closeWest]:> true
| Closes the panel on the west (left) |

© SAP SE C4H365 31
Development Support - Disabling Caching of Components and Controllers

You can disable caching to force reloading of components at every page refresh

Quite handy during development — quickly and conveniently see your changes to
component views!

Set the following properties inside local. properties

${HYBRIS_CONFIG_DIR}/1local.properties
backoffice. cockpitng.additionalResourceLoader.enabl ed=true
backoffice. cockpitng.uifactory.cache.enabled=false
backoffice. cockpitng.widgetclassloader.resourcecache.enabled=false
backoffice. cockpitng. resourceloader. resourcecache.enabled=false

Development Support - Resetting Backoffice Configuration

Via the Application Orchestrator


Via the Administration Console (HAC)

Initialize: Update: ‘oe Symbolic widgets Widget Clipboard


IN

Refresh

Show widgets.xml
a

Reset to Defaults
create btg load testing data create btg load testing data
Show cockpit-config.xml

Reset to Defaul!
¥ backoffice ¥ backoffice
Simulate config resolution

eh TR
Reset Everything

Widget Toolbar Color >

32 C4H365 © SAP SE
Development Support - Resetting Backoffice Configuration (Auto-Triggered)

¢ Auto-triggering of resets can be convenient and can save time

backoffice.cockpitng.reset.triggers list of triggers that should induce a reset login, start

backof fice. cockpitng.reset.scope list of what should be reset, for both triggers widgets ,cockpitConfig

${HYBRIS_CONFIG_DIR}/local. properties
Examples:
backoffice. cockpitng.reset.triggers=login
backoffice. cockpitng.reset.scope=widgets, cockpitConfig

Development Support — Backoffice Development Toolbar

- Backoffice provides a development toolbar, i.e., a group of buttons to enable:


* Reset Everything — rest the “widgets.xml and “config.xml
* Reload Localization Labels — reload the localization key/value pairs from the labels files.
* Hot Deployment - is the ability to deploy executables to a running system without any need for
stopping or restarting the system (details cf. next).

» You need to enable the Backoffice Development Toolbar in local. properties:


- backoffice.cockpitng.development.mode=true

- After restarting the system, three new buttons appear in the Backoffice app
Reset Everything ——— p—— Reload Localization Labels

— SARA Administration Cockpit y Ts] [c] [5] 2a a

Redeploy Backoffice Extensions

© SAP SE C4H365 33
Development Support - Using the Redeploy Backoffice Extentions Button

(1. Perform an ant build at the command line

2. Press the Redeploy Backoffice Extensions button


= This reloads the JAR files with all Backoffice extensions (including yours) and recreates the
spring context
= The context reload can_be observed on the console:
INFO: Performing hot deploy
INFO [hybrisHTTP4] [BackoffiqeModulesManager] [auditreportservices] Registering backoffice configuration-only module
ort sdeModulesManager] [bookstorecustombackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [bookstorecustombackoffice] Copying bookstorecustombackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [customerreview] Registering backoffice configuration-only module
INFO [hybrisHTTP4] [BackofficeModulesManager] [platformbackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [platformbackoffice] Copying platformbackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [apiregistrybackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [apiregistrybackoffice] Copying apiregistrybackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [basecommercebackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [ba rcebackoffice] Copying r #fice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [searchbackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [searchbackoffice] Copying searchbackoffice_bof.jar from extension
| INFO. ChybrisHTTP4] [BackofficeModulesManager] [solrfacetsearchbackoffice] Registering and fetching full backoffice module
3. Refresh the page! INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [solrfacetsearchbackoffice] Copying solrfacetsearchbackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [voucherbackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [voucherbackoffice] Copying voucherbackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [promotionsbackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [promotionsbackoffice] Copying promotionsbackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BackofficeModulesManager] [commerceservicesbackoffice] Registering and fetching full backoffice module
INFO [hybrisHTTP4] [BackofficeLibraryFetcher] [commerceservicesbackoffice] Copying commerceservicesbackoffice_bof.jar from extension
INFO [hybrisHTTP4] [BeansDefinitionImportParser] Importing additional bean definitions: file: /Users/d@67131/Documents/work/hy2211_8/h'
ombackoffice/resources/bookstorecustombackoffice-backoffice-spring. xml
7

Development Support - Tools for Hot Deployment

The Redeploy button


Reloads the JAR files from all Backoffice extensions (including yours) and recreates their spring
contexts

Dynamic Code Evolution VM (DCEVM)


A modification of the Java HotSpot(TM) VM that allows unlimited class redefinition at runtime.
http://ssw.jku.at/dcevm/

JRebel
JRebel with SAP Commerce

34 C4H365 © SAP SE
Development Support - Comparison of the Tools
Java JVM Hot Swap Backoffice Hot DCEVM (Enhanced JRebel
{HotSpot VM) Deployment Debug Mode)

Changes to method bodies

BB
Adding/removing Methods
DN

OX

Bs

Bc

B-
Adding/removing constructors
WY

KK
Adding/removing fields
FB

Bis

B-
Bs
Adding/removing classes
oo

OR

Adding/removing annotations
OD

m+.
B+
KOK

Bs
Changing static field value
on

Adding/removing enum values

@+.
Es
Modifying interfaces
Bs
oO

KR

Replacing superclass
RM
oO
=

=
-

Adding/removing implemented
adding / / removing x
wR

—-.
=
a

interfaces
12 Initializes new instance fields Vv
=k

2 -

™-
13 Adding/Modifying/Removing bean X (but planned)
x

Training Labs Tool

© SAP SE C4H365 35
TrainingLabsTool

rf fy: EI:
= Aspecial project we made for the training [® Project Explorer X BESY
> 2 alluicommons
= Automates the exercise setup > EPauditreportservices
> 2 backoffice
. . . . . J 7
= Preinstalled in your build environment with Ant ; —<_
: . config
scripts and file resources for pre-exercise Biolsiiocm
preparation (and, if desired, the solution) v ie > TrainingLabsTool [C4H365New ilt23update]
> Bi\ JRE System Library [JavaSE-1.8]
= Before each exercise (after exercise 4): > Bi\ Referenced Libraries
> Gylibs
= Run ExerciseX-*-prepare ant target > Egresources
ms ri F
Eg > exercises.properties

= For (almost) each exercise there is an ‘lab_exercises_preparation_BFDev.xm|


# lab_exercises_solution_BFDev.xml
xy tltbfdevutil.sh
=" ExerciseX-*-prepare ant target | velocity.log
[5 version.txt
=" ExerciseX-*-solution ant target

Training Labs Tool


[$ Package Explorer 53 Shes Vv = ¢ IMPORTANT Be VERY careful:
> ©! platform Do not make any changes to ANY file in TrainingLabsTool!!
v e TrainingLabsTool
> mA JRE System Library (JavaSE-1.8)
> mi Referenced Libraries
> Bilibs Contains every file the Ant targets (a.k.a. scripts) copy to
v your custom extensions to help you with the exercises
>» @exercise10
>» @exercise2
>» @exercise3
Contains the files needed by a specific ExercisexXxX-*-prepare
v Bexercises
¥ [preparation] ant target to prepare your project(s) for an exercise
@ book.png
xX) bookstorecustombackoffice-backoffice-config.xml
xX) bookstorecustombackoffice-backoffice-widgets.xml Contains the files needed by the solution scripts
v solution
to provide a solution to an exercise (plus, you
X) bookstorecustombackoffice-backoffice-widgets.xml
>» Bexercised can compare your solution with them)
> @exercise6
> @exercise7
> Gexercise8.1 Contains properties/values to adapt TrainingLabsTool to your
carey environment (like where your platform project/folder is located)
exercise’

‘|exercises.properties
lab_exercises_preparation_BFDev.xml
lob exercises. solution BFDevxml <— Contains definitions of all TrainingLabsTool Ant targets |
Ho

(CU ttbtdevutiish
) velocity.log

36 C4H365 © SAP SE
Oren
= Choose a suitable IDE and import related extensions for Backoffice development

= Backoffice Framework provides several supports for your development:

— Breadboard Widget for testing input and output of other widgets

— Disabling Caching of Components and Controllers to quickly and conveniently see your changes to
component views

— Resetting Backoffice Configuration as user login or system startup

— Enable the Backoffice Development Toolbar to reload Backoffice related codes and resources without
restarting the system.

25

Exercise 3

© SAP SE C4H365 37
Exercise 3 — Set Up the Development Environment

= Prepare your IDE

= Disable caching

= Enable automatic configuration reset

= Enable the “Redeploy” button

SAP Customer Experience

Thank you.

38 C4H365 © SAP SE
SAP Customer Experience

Orchestrate a Cockpit

INTERNAL — SAP and Partners Only

We will learn about:

> Orchestration Overview for the 3 general steps

> Step 1: Create a New Cockpit

> Step 2: Add Widget Instances

> Step 3: Connect the Widget Instances

>» Orchestration Essentials to support the 3 steps

INTERNAL SAP and Parners Only

© SAP SE C4H365 39
Orchestration Overview

What is Orchestration?

Orchestration — run-time process of combining two or more software components to automate a


business process or synchronize data

= Integration approach that allows for decoupling applications and software components

= Provides message routing, security, data transformation, and reliability

= Allows for the central management and monitoring of your integrations

Orchestrating a Backoffice cockpit is:

= building out one or more business processes by adding and connecting widgets (through
Application Orchestrator or through widgets. xml)

INTERNAL SAP and Partnors Only 4

40 C4H365 © SAP SE
Steps to Orchestrate a Cockpit

Create a Add Connect


New Widget the Widget
Cockpit Instances Instances

Step 1: Create a New Cockpit

© SAP SE C4H365 41
Step 1: Create a new Cockpit — e.g. Choose a Layout
Choose widget x
Outset level
‘Select Authority Group - v @ cn C symbotic widgets (2) Widget Clipboard
< Layout
Backoffice Main Layout CCG RA
Border Layout
Flexible Layout CGRP ‘com.hybris.cockpitng.borderlayout
ee CueRex Description:
Border layout widget with north, south, west, east and center layout regions
[views] + one
[untitled] collaboration.container closeNorth (java.lang.Object)
— ‘openNorth (java.lang.Object)
closeWest (java.lang.Object)
Backoffice Perspective Container openWest (java.lang.Object)
closeEast (java.lang.Object)
openeast (java.lang.Object)
closeSouth (java.lang.Object)
‘openSouth (java.lang.Object)
setWestSize (java.lang.String)
Duitrnites

Choose widget x Add & conné& = Add & close

< Categories
Choose widget x

Selector er Upload) Retesh trary


Backoffice Main Layout

Backoffice Perspective Container


Layout (12)
Border Layout
Border layout widget with north, south, west, east ¢
Type the layout widget name
Collapsible Container
directly, or filter by keyword,
layout Dashboard
7

Step 1: Create a new Cockpit — Cockpit Configuration


Outset level >
Select Authority Group - vi ® 7 (J) symbolic widgets Widget Clipboard

Backoffice Main Layout FCG RAaAX

Flexible Layout PC Rex

View Switcher CG Rex

[views] +

[untitled] _ collaboration.container

Backoffice Perspective Container

[perspectives] +
admin.area Book izati ive.narie [i

Border Layout ps @asx

leftslot + centerSlot + rightSlot +

< > 8

42 C4H365 © SAP SE
Step 1: Create a new Cockpit - Settings

Configure settings for your new cockpit Settings for [com.hybris.cockpitng.borderlayout] custom-boarderlayout-cockpit x

such as L izati Virtual Access Restrictions About

= Title (tab display name) Title: My Cockpit

= Widget ID (for widget instance) wget: mycustonn coir


. autoCloseWest: false 9 x
— Needs to be unique
border: Wee x

~ Replace autogenerated value to broadcastHorizontalResize: true wy x


make it meaningful
centerBorder: Wea x

Available settings will be determined by een none 7


the specific widget
Add Setting

Close

INTERNAL SAP and Partnors Only 9

Step 1: Create a new Cockpit - Generated XML

As you work in Application Orchestrator, you can display the merged widgets.xml file to view the XML
that gets generated

= Search for your cockpit’s XML code by its unique Widget ID (for example mycustom-cockpit)

= Cockpits can be identified in the XML by the sLotId= "perspectives" attribute on a <widget ..> tag
= All widget instances added to a cockpit can be found inside the cockpit’s <widget ..> </widget> tags
custombackoffice-backoffice-widgets.xml

<widgets>

<widget id= "“mycustom-cockpit" widgetDefinitionld= "com. hybris. cockpitng. borderlayout"


slotId= "perspectives" title="My Cockpit" template="false">
<widget id="collapsible” ...

</widget>
</widget>

</widgets>
INTERNAL SAP and Partnors Only 10

© SAP SE C4H365 43
A Short Detour: Common Layout Widgets

Before we move on to Step 2 : How to Orchestrate a Cockpit,

let’s take a look at some of the most common layout widgets


that you can choose for your custom cockpit

Border Layout Widget


With poh and aataoan 2Raax
south slots
Most common layout used disabled | *S* + contersiot + ightstot +
= Contains 5 slots: north(top),
south(bottom), center, west (left),
and east(right) for placing other
widgets

= Lots of available widget settings With aff slots See tye 2208
— enable/disable specific slots enabled nnn 2 *
leftSlot + centerSlot + rightSlot bd
— set slot widths
— allow/disallow slots to be
collapsible
— apply a border

= This is the layout used for the


Administrator Cockpit

44 C4H365 © SAP SE
Collapsible Container Widget

= 2or3 slots that can be


collapsed/expanded Collapsible Container
. :
as)=> +
Q x

Top Caption
= Settings
top +
enable/disable 3rd slot
— title of each slot Geqtencaption

»>
— height (of top & center slots) in % eerter +
— allow locking
Bottom Caption

«
—_ initial slot view state — bottom +
collapsed/expanded
initial lock state of each slot —
locked/unlocked

Step 1: Create a New Cockpit

Portal Layout Widget

= No set layout! 1 large slot Portal Layout ars) Q x


" Add multiple widgetinstances to the {chitdren] =f
slot

= Allows for dynamic layout by end


user via drag and drop

= All widgets placed in the slot are


automatically draggable

Step 1: Create a New Cockpit

© SAP SE C4H365 45
Split Layout Widget
‘Split Layout

[children] +

Chat @Raax Example MVC


Code
conversation Editor @ Siaximize
= 1 slot for all widget instances

= All contained widget instances are separated


by splitters

= nd user can resize widget instances with


splitter

7 Settings = ELD” solittayoutpemo~

— orient (v_split or h_split)


test bel: some label myL

‘action example:
editors example:
‘actions example:
Global event queue scope examples: Global event 1 (desktop scope) Global event 2 (session scope)
Global event 3 (application scope)

Tab Layout Widget

= 1 slot for all widget instances


Tab Layout FPR ®& Q xX
= By default, renders contained widget
instances as tabs [children] +

= Based on setting, can also render Chat Code Editor Example Title
contained widgets as: —

— portal Chat GR 2 x

— list

— h_split / v_split conversation

= Settings

— type

Step 1: Create a New Cockpit

46 C4H365 © SAP SE
Complex Cockpit Layouts

You can create complex cockpit layouts by nesting layout widgets

Border Layout APG RMA x


s Border s
Collapsible Container PB WW X Tab Layout FRAX | inour F FRA *X
Tan Cantinn

top + [children] + Collapsible Container ZB


Tan Cantinn
Canter Cantinn a
top
center +
Cantar Cantinn

Rattam Cantian v center

bottom +
Rattam Cantian

bottom

Step 2: Add Widget Instances

© SAP SE C4H365 47
Step 2a: Add Widget Instances Choose widget x

< Categories
Border Layout
Explorer Tree
leftStot +
) Shows a hierarchical structure.

iS Choose widget x

< Navigation

Choose widget x Explorer Tree


com.hybris.cockpitng.widgets.common.explorertree

Sac Shows a hierarchical structure.


lavigation (1)
Inputs:
(com.hybris it jigation.Treeh +)
setTreeContext (java.util.Collection)
selectionContext (java.util.Map)
clear (java.lang.Object)
focusOnFilterTextbox (java.lang.Object)
clearSelectedNode (java.lang.Object)
refreshBySelectedNode (java.lang.Object)
Outputs:
(com.hybri navigation. NavigationNode)
dataGalartad fiava lana Ahiart) .

Add &connect Add & close

IS

Step 2b: Add Widget Instances - continued

@ Home

{4 Inbox

Now you should see an instance of the widget you System


v

chose replacing the empty slot


Catalog
v

Multimedia
v

User
v

Order
v

Price Settings
v

Internationalization
v

Marketing
v

Base Commerce
v

Deeplink Urls
v

20

48 C4H365 © SAP SE
Step 2c: Add Widget Instances - Settings

All widget instances have two attributes.


(please give them meaningful values): Settings for [com.hybris.cockpitng.widgets.common.explorertree] 851faOcf-b567-4808- 7
bd49-749698ea1f78

" Title (tab display name) General Localization Virtual sockets Access Restrictions About
= Widget ID (needs to be unique) Tite: My Custom Explorer
Widget ID: my-custom-explorer
With other widget specific settings.
For example, Explorer Tree widget has: setonscomponen
. tionsComponent: x

2 al low Fi Ite ri ng E ntri es allowFilteringEntries: true v x

. expl ore rTree Config Ctx autoSearchEnabled: ‘true v x

. autoSearchEnabled autoSortEnabled: false v x

» autoSortEnabled expandeditemsAfterFilterSoftLimit: 15 = x

. explorerTreeConfigCtx: explorer-tree ,*

Add Setting

These setting names (and a few default Close


values) come from the widget definition,
(which we will learn about later), and are
meaningful to the controller.

Step 2d: Add Widget Instances - Generated XML

You can display the merged, application-wide widgets.xml file to view the XML that got generated by the
Application Orchestrator for the new widget instance
= Find the widget’s XML elements via its unique Widget ID (my-custom-explorer)
= Widget elements added to a cockpit will be within that cockpit’s <widget ...> </widget> tags
= To preserve the changes, copy them to your custombackoffice-backoffice-widgets.xml
(Note the widget instance’s id, title, and settings)
custombackoffice-backoffice-widgets
.xml
<widgets>

<widget id= "mycustom-cockpit” widgetDefinitionld= "com. hybris. cockpitng. borderlayout”


slotId= perspectives” title= "Custom Layout Cockpit” template= "false’>
<widget id="my-custom-explorer”
widgetDefinitionld= "com. hybris.cockpitng. widgets. common. explorertree”
slotId="JeftSlot” title="My Custom Explorer” template="false’>
<setting key="7itle” type="String” value=""/>
<setting key="Widget ID” type="Boolean” value="false” />

</widget>
</widget>

</widgets>

© SAP SE C4H365 49
Step 3: Connect the Widget Instances

Communication in Backoffice

Backoffice Business Application

Widgets use input/output sockets to communicate


Backoffice ¢
Widget
To establish a connection, you should connect
| Outgoing message : |Receives messages
one widget’s output socket to another’s input
socket : : Backoffice
: Communication i
For a connection to be feasible, the data types of mapping

the input/output sockets on both ends must match


or be compatible

24

50 C4H365 © SAP SE
Step 3: Connect the Widgets

Advanced Search Xx rightSlot +


oo . we Drag to another widgets connect button to manage connections with drop widget.
[cockpitWidgetChildrenInvisible] Left click - manage connections. Right click - show/delete existing connections.

Advanced Search Engine x

Attribute Comparator Value

Step 3: Connect the Widgets — (continued)

Choose sockets to connect x

Source: com.hybris.cockpitng.advancedsearch Target: com.hybris.cockpitng.widgets.common.advancedsearche

autosuggestionQuery out searchData in


Type: com.hybris.cockpitng.search.data.AutosuggestionQueryDat Type: com.hybris.backoffice.widgets.advancedsearch.impL.Advan:

searchData out updateSearchData in


Type: com.hybris.backoffice.widgets.advancedsearch.impl.Advan Type: com.hybris.backoffice.widgets.advancedsearch.impl.Advan:

reset out
Type: java.util.Map

Source Out Socket Target In Socket

© SAP SE C4H365 51
Step 3: Connect the Widgets — Generated XML

In Backoffice orchestrator mode, you can display the merged widgets.xml file to view the XML that gets
generated for the new connection
= Search for either source or target widget’s XML code by the unique Widget IDs (custombackoffice-
advancedsearch or custombackoffice-advancedsearchengine)
= All widget connections are put inside <widget-connection ...> </widget-connection> tags
= To preserve the changes, copy them to your custombackoffice-backoffice-widgets.xml

Custombackoffice-backoffice-widgets. xml

<widget-connection sourceWidgetId="custombackoffice-advancedSearch" outputId="searchData"


targetWidgetId="custombackoffice-advancedSearchEngine” inputId="searchData"/>

27

Orchestration Essentials

52 C4H365 © SAP SE
Widget Slots

= Components defined in the view (.zul file) of a widget to which other widgets can be assigned
= Enable a widget to have child widgets
= Used to create composed widgets
= Used by the layouts to have different slots in different parts of the screen

some-widget.zul
<widget ...>

<widgetslot slotId="additionalArea" width="100%" height="100%" />

</widget>

Invisible Widgets

= Many widgets have a single invisible slot called cockpitWidgetChildrenInvisible


= Any widget placed on this slot will NOT be displayed
= Only accessible through its sockets
= Used for holding widgets that do only data manipulation
= (thus, they have no need for a view)

Advanced Search FC Bax

[cockpitWidgetChildrenInvisible]

Advanced sta gine GR Q x

© SAP SE C4H365 53
Application Orchestrator — Symbolic View

Symbolic view is a good place to see connections and dependencies

Advanced Search Backoffice Title

Advanced Search Engine

pa Collection Browser

31

Remember These Widget Types from the Recap?


Advanced Search

= SARA Book Management ~

Q RB 4
Explorer Tree 8 8
L_ +lv 3 = ie &
> Book Tree a Collection Browser
Identifier tt Book.Authors
Book
| | How to Make Friends and Infuriate People ‘Thomas Hardly [Thomas Hardly} Bookstore Product Catal
8 Two Gentlemen of Pamplona William Rattlespear [William Rattlespear] Bookstore Product Catalo

| Far from the Madding Shroud ‘Thomas Hardly [Thomas Hardly] Bookstore Product Catalo

8 Object-Oriented Methodology for Labrador Breeders Mavis Jones [Mavis Jones], Shirley McSpane [Shirley McSpane] Bookstore Product Catalo
8 UML Changed My Life Shirley McSpane [Shirley McSpane] Bookstore Product Catalo
an | Design Patterns for the Elderly Cynthia Jesperson [Cynthia Jesperson] Bookstore Product Catal’ <

Editor Area 46 items

Title: "How to Make Friends and Infuriate People" - Bookstore Product Catalog : Staged ay

Go @ 7 v

Essential Book Attributes

Article Number* Identifier © Catalog version* Approval*

2121888594 How to Make Friends and Infuriate Pr Bookstore Product Catalog : St... approved o

32

54 C4H365 © SAP SE
Advanced Search Engine Widget

= Ahelper widget that executes the search on behalf of the Advanced Search widget
= Used together with the Advanced Search widget
= Putin the invisible slot: cockpitWidgetChildrenInvisible

Advanced Search
aC @ x

[cockpitWidgetChildreninvisible]

Advanced Search Engine C2REex

Backoffice Space Management

“The Backoffice Space Management widget enables you to automatically expand or collapse areas in the
default Backoffice Application layout.”

End-user actions such as selecting a node in the navigation tree, triggering a search query, and selecting
an item in the list have an impact on the visibility of the following widgets:
= Advanced Search Widget
= Collection Browser Widget
= Editor Area Widget

© SAP SE C4H365 55
Previous/Next Item Selector

The Previous/Next Item Selector widget enables you to get the previous/next item's attributes in the
Editor Area displayed.

Title: “Two Gentlemen of Pamplona” - Bookstore Product Catalog : Staged fay

& 6 Refresh save |

Essential Book Attributes a


“a

Article Number* Identifier © Catalog version* Approval*

1109070349 Two Gentlemen of Pamplona Bookstore Product Catalog : St... approved v

Image Description 7)

3 300wx300H/generic-cover;...

35

Demo

56 C4H365 © SAP SE
Oren
: Acockpit is typically a layout widget added to the slot “perspectives” in the perspective container
widget.

= You can add a list of widget instances into a cockpit to construct your custom cockpit UI.

= Awidget can use widget slots to hold child widgets.


= cockpitWidgetChildreninvisible slot is a special slot which is not displayed, but can contain widgets for
backend data processing.

= Awidget can have input sockets accepting message from other widgets and output sockets
sending message to other widgets.

= Two widget instances can communicate by connecting one widget’s output socket to another
widget’s input socket.

= Any changes done via the Application Orchestrator are only saved temporarily. If you want to
persist the changes, you need to save them into your custom *-backoffice-widgets.xml.
INTERNAL SAP and Partnors Only 37

Exercise 4 — Orchestrate a Cockpit

© SAP SE C4H365 57
Exercise 4 — Orchestrate a Cockpit

Start making the Book Management cockpit your own!

The goal is to have a cockpit where the user can select the Book type node to view all
Books in the system. The user can then click on a book to bring up its editor.

39

What you will do?

= ISARA Book Management ~ 2 ¢ 6B & © 8

Anenpreparation, three Q RB
main widgets added:
¥ Book Management Tree sell @v fz &

= Explorer Tree Identifier 11 Book.Authors Catalog Version


Book
= Advanced Search ‘The Strange Case of the Disappearing SAP Commerce Website Bookstore Product Catalo
Withering Heights Charlotte T. Bron [Charlotte T. Bron], Dale Camaby [Dale Carnaby} Bookstore Product Catalo
= Collection Browser How to Make Friends and Infuriate People ‘Thomas Hardly [Thomas Hardly] Bookstore Product Catala
= No Editor Area yet ‘Two Gentlemen of Pamplona William Rattlespear [William Rattlespear] Bookstore Product Catalo
Far from the Madding Shroud ‘Thomas Hardly [Thomas Hardly] Bookstore Product Catalo
ee

‘Object-Oriented Methodology for Labrador Breeders Mavis Jones [Mavis Jones], Shirley McSpane [Shirley McSpane] Bookstore Product Catalo
You will: UML Changed My Life Shirley McSpane [Shirley McSpane] Bookstore Product Catalo.

= add anew Editor Area Design Patterns for the Elderly Cynthia Jesperson [Cynthia Jesperson] Bookstore Product Catalo

for the books Syntactic Structures Noam Chumski [Noam Chumski] Bookstore Product Catalo
‘Aspects of the Theory of Sin Tax Noam Chumski [Noam Chumski] Bookstore Product Catala
= [OPTIONAL] add
Project Management for Dummies and Vice Versa Gustav T. Winkelmann [Gustav T. Winkelmann] Bookstore Product Catalo
navigation buttons to it
CW

‘The Joy of Accounting - Part 5.3.2.c P.J. Smith [P.J. Smith] Bookstore Product Catalo
= persist your changes in Undaret ing the Eaminine Henny Thidar fhlenny Tide Ronketara Broduict Catala
*-widgets.xml 46 items

No items selected a &

40

58 C4H365 © SAP SE
Exercise 4 — The End Goal

ISAPA Book Management ~ ® C B & ® 8

Y Book Management Tree +ly @ E: (z)a


identifier it Book.Authors Catalog Version
Book
8 ‘How to Make Friends and Infuriate People Thomas Hardly [Thomas Hardly] Bookstore Product Catal

8 Two Gentlemen of Pamplona William Rattlespear (William Rattlespear] Bookstore Product Catalo

8 Far from the Madding Shroud Thomas Hardly [Thomas Hardly] Bookstore Product Catala

8 Object-Oriented Methodology for Labrador Breeders Mavis Jones [Mavis Jones], Shirley McSpane [Shirley McSpane] Bookstore Product Catalo

8 UML Changed My Life Shirley MeSpane [Shirley McSpane] Bookstore Product Catalo

8 Design Patterns for the Elderly Cynthia Jesperson [Cynthia Jesperson] Bookstore Product Catal’ <

46 items

Title: "How to Make Friends and Infuriate People” - Bookstore Product Catalog : Staged

G & t v Refresh

Essential Book Attributes

Article Number* Identifier © Catalog version" Approval*


2121888594 How to Make Friends and Infuriate Pt Bookstore Product Catalog : St... approved
a

SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

© SAP SE C4H365 59
SAP Customer Experience

Widget Fundamentals

INTERNAL — SAP and Partners Only

We will learn about:

> The basic components for creating a custom widget type.

> How to create a widget view file.

> How to implement a widget controller.

> The communication among widget models, widget view files and widget controllers.

> Backoffice Application Context.

INTERNAL SAP and Partnors Only 2

60 C4H365 © SAP SE
Creating a Widget

What is a Widget?

= Standalone, deployable component bob


= Has a clearly-defined interface
= Has one specific purpose
= Primary component of the Backoffice framework
» Uniquely identified by an ID attribute

ERNAL SAP and Partnors Only 4

© SAP SE C4H365 61
Widget Definition and Widgets

A Widget Definition is the blueprint for all instances of specific widgets


A widget instance is created based on a Widget Definition
* a widget instance can live in the slot of another widget instance

parent Q..1
WidgetDefinition
-id : String
-name : String 1
-id : String
-controller : String
-slotId : String
-viewURI : String
-inputs : List<WidgetSocket>
-outputs : List<WidgetSocket>

INTERNAL SAP and Parners Only

Widget Communication

= To have a meaningful application, widget instances have to communicate with each


other
= Awidget can have inputs and outputs (“sockets”), each of which has its own ID
(within the widget) and defined type
— This helps with compatibility checking when connecting two widget instances
= Each connection references both source and target widget instances and the
appropriate IDs of their input and output sockets
parent
®..1

L Widget WidgetDefinition
1
1 1 1
source inputs outputs
* * *

WidgetConnection WidgetSocket

INTERNAL SAP and Parners Only

62 C4H365 © SAP SE
Components of a Widget Definition

° <extensionName>/backoffice/resources/widgets/<folder_of_a_widget>
— definition.xml (required file)
— view file (optional) —A .zul1 file (only if widget has a user interface and wants to
start with a static view template)
— static resources (optional) — E.g., image, icon, .css files
— localization property files (optional) — E.g., for localized Ul labels

* <extensionName>/backoffice/src/
— Controller class (optional) — A Java class, if widget is non-static

INTERNAL SAP and Partnors Only 7

definition.xml Example

<?xml version="7.@" encoding= "U7F-8”" standalone= “yes "?>


<widget-definition xmlns:xsi= "http://www. w3. org/Z001/XML Schema-instance”
xsi:noNamespaceSchemaLocations "http://www. hybris. com/schema/cockpi tng/wi dget-definition.xsd”
id= "con. hybris.cockpitng.defaulttabwidget">
<name>Tab Layout</name>
<description>All rendered child components are displayed as tabs.</description>
<defaultTitle>Tab Layout</defaultTitle>
<author>hybris</author>
<version>@.1</version>
<controller class= "com. hybris.cockpitng.widgets. controller. TabWidgetController"/>
<view src= "defaultTabWidget.zul"/>
<sockets>
<input id= "closeAli” type="java. lang. Boolean" /> <!-- Java types used here -->
</sockets>
<keywords>
<keyword>Layout</keyword>
</keywords>
<settings>
<setting key="type” default-value= “tab” type= “String” /> <!-- Java types NOT used here -->
</settings>
</widget-definition>

INTERNAL SAP and Partnors Only 8

© SAP SE C4H365 63
Widget File Structure
v_ Ebookstorecustombackoffice
> @® gensre
> @testsre
> BA JRE System Library [Java SE 17.0.3.1 [17.0.3.1]]
> BA Referenced Libraries
> @Bsre
It's where your Backoffice-related code should be
==» (®backoffice/sre
implemented, for example widget controller > my fice.actions
implementation. .. > Bry, fice.config.details.jaxb
. s, > # im ry. editors
s > my. fice.services
S> Bmy. fice.wi
‘Sy my fice.wi
“4> {3 BookDetailsController.java
> G®backoffice/testsrce
v @backoffice
> @sclasses
v_ resources
> @actions
> Beng
It's where your widget definition resources should __ > Beditors
> @sschemas
be defined, every widget definition has its own “wt (widgets
folder, which contains its definition.xml, view file “== 3 bookDetails
and other static resources. |) bookDetails.zul
default.css
{X) definition.xml
> (&BookstorecustombackofficeWidget
> @classes
INTERNAL SAP and Parners Only

Create the View

64 C4H365 © SAP SE
UI Framework

Backoffice uses the ZK framework for creating the views

View files have . ZUL extension =

POWERED

In a view file, you'll find a combination of ZK XML syntax


+ SAP Commerce Cloud tags

Example view file — backofficeMainLayout.zul


backofficeMainLayout.zul
<?xml version= "2.0" encoding= "U7TF-8'>
<?taglib uri="http: //www.zkoss.org/dsp/web/core" prefix="c"?>

<widget width= "100%" height= "100%"


xmLns= “Attp://ww. zkoss. org/Z005/zul"
xmLns:xsi= “http://www. ws. org/Z001/SMLS chema-instance"
xmLns:h= “Attp://“www. w4. org/1999/xhtml ">

<vlayout id= "“mainContainer" width= "100%" height="100%” spacing="quto ">


<widgetslot slotID= "headerAreq” />
<widgetslot slotID= "“mainArea" vflex="1" />
</vlayout>

<div id="roleSelectorContainer" sclass= "yw-roleselector-container'>


<widgetslot slotID="roleSelectorSlot"/>
</div>
</widget>

© SAP SE C4H365 65
ZUL Schema

ZK XML syntax + SAP Commerce Cloud tags


myWidget.zul
<widget xmlns= "“Attp://www. zkoss.org/Z005/zul"
xmLns:xsi="Attp://ww.w3. org/ZO01/SMLS chema-instance"
xsi: schemaLocations= “Attp://www. zkoss. org/Z005/zul
http://www. hybris. com/schema/cockpi tng/schemas/zul.xsd'>

ZK ti iti‘*@d' SAP Commerce Cloud


<div> <widget>
<hlayout> <action>
<vlayout> <widgetchildren>
<button> <widgetslot>
<listbox>

Access to Controller and Model

Access methods of the widget instance’s controller and data of the widget model
from a .ZUL file using SpEL syntax with the widgetController and widgetModel
objects

myWidget.zul
<label value= "${widgetModel .MODEL_KEY}"/>

<label value= "${widgetControl ler. getRandomNumber()} "/>

66 C4H365 © SAP SE
Wiring between Controller and View

Each element in the zul file is wired to a property in the controller through
convention: by matching type and ID
MyChat. zul

View element’s id must be identical to the controller’s


member variable name
MyChatController.
java
public class MyChatController extends DefaultWidgetController {
protected Label lastMsgLabel;
‘protected Textbox msgInput; — :

Note that no mutator (setter) method is necessary. The value gets set automatically by the
Backoffice Framework. 15

Wiring Between Widget Definition, Controller, & View


definition. xml

MyWidgetController.java view. zul

© SAP SE C4H365 67
ZUL Playground Widget

= For testing ZUL file content on the fly History button

Reset
code
button

= Should be used in combination with Configuration


container
— InputTestWidget widget
— Cast widget

For more information on how to use this widget, refer to this page on the SAP Commerce Help:

ZUL Playground widget on Help

Create the Controller

68 C4H365 © SAP SE
Custom Widget Controller

= Extend DefaultWidgetController

= Automatically wire view elements


— By convention, the view element's id is identical to the controller's member variable name

= Use the Widget InstanceManager to access context params


— model data, instance settings, current user role, etc.

MyChatController.java
widgetInstanceManager. getWidgetSettings().getBooleanC"online");

The Widget Controller Java Class

public class MyChatController extends DefaultWidgetController


{
private Label lLastMsgLabel;
private Textbox msgInput;

@ViewEventCcomponentID = “sendBtn", eventName = Events. ON_CLICK)


public void sendMsg()
{
sendOutputC"outgoingMsg", msgInput.getText());

@SocketEventCsocketId = "incomingMsg")
public void receiveMsg(final String msg)

lastMsgLabel.setValue(msg);
}

© SAP SE C4H365 69
Accessing the Settings

Accessing Widget Settings


definition.
xml
<widget-definition ...>

<settings>
<setting key="mySetting” type="Java.
lang. String” default-value= "123"/>
</settings>

</widget-definition>

= Then inside your Controller code:


MyWidgetController.
java
getWidgetSettings().getStringC"mySetting");

= Or inside your View code:


myWidgetView.
zul
<label id= "alabel" value= "${widgetSettings.mySetting}" />

22

70 C4H365 © SAP SE
Changing Widget Model

Widget Model

= Widget model is used to represents the state of the widget


— Not to be confused with SAP Commerce Cloud platform’s Model
— Model is created when widget is created
— Stored in session
— Destroyed when session is closed or widget is removed

« Adding data to Model


WidgetModel model = widgetInstanceManager.getModel();
model.putC"product", product);

= Retrieving data from Model


ProductModel product = model.getValueC"product", ProductModel.class);

24

© SAP SE C4H365 71
Widget Model, cont.

= Accessing values of an Object in the Model

ProductModel product = model.getValueC"product", ProductModel.class);


String productCode = model.getValueC"product.code", String.class);
String categoryCode = model.getValueC"product.category.code",
String.class);

= Modifying data in Model

model.setValueC"product.code", “product_1234");

25

Backoffice Application Context

72 C4H365 © SAP SE
Backoffice Application Context

= Backoffice adds a 4" Spring context to SAP Commerce Cloud.


= This new Spring context is called the Backoffice Application Context.
= |t allows context to be shared between all Backoffice extensions (backoffice
extension + all extensions based on the ybackoffice template)
=|t enables runtime auto-reload capabilities (hot deployment).

= Backoffice Application Context beans must be defined in <extensionName>-


backoffice-spring.xml
= The definition/declaration is the same as the normal spring beans in
<extensionName>-spring.xml.

= However, it’s different to access/wire Backoffice Application Context beans...


(cf. next)

Access Backoffice Web Context Beans

"@WireVariable (instead of @Resource/@Autowired) is used to access a


Backoffice Web Context bean inside a widget controller
— Only used in controllers that extend DefaultWidgetController,
SelectorWidgetController, or BindWidgetController, though

@WireVariable
protected BackofficeBookstoreService backofficeBookstoreService;

= For all other wirings use the service locator - BackofficeSpringUtil


BackofficeBookstoreService backofficeBookstoreService =
BackofficeSpringUtil.getBeanc
“backofficeBookstoreService", BackofficeBookstoreService.class);

© SAP SE C4H365 73
Oren
= To develop a custom widget type, we need to prepare
» definition.xml(mandatory): provides the basic widget metadata and reference of other widget components
» View file(optional): represented by .zul file
» Controller class(optional): provide concrete business logic
» Other static files(optional): such as images, .css files, etc.

= Inthe view, we can access controller methods, settings, and widget model by using
widgetController, widgetSettings and widgetModel based on SpEL

« A Widget Controller can wire view element, access widget’s setting and access widget
model

= Backoffice Application Context beans can be accessed via @WireVariable or


BackofficeSpringUtil.getBean()

29

Exercise 5 — Create a New Widget

74 C4H365 © SAP SE
Exercise 5 — Create a New Widget

Create a widget for = 7 sort aragenent - > cB AO 8


previewing a selected book! “"“*"* ______4
© Book Management Tree Title: "Two Gentlemen of Pamplona" - Bookstore Product Catalog : Staged 8
= Complete the view’s ook 8 a + 4 Refesh
definition Essential Book Attributes a
|
= Complete the controller’s sce Nurbar iret Qergrs cam?
i m pl emen t ati ion u 1109070349 ‘Two Gentlemen of Par Bookstore Produ... approved .

Image Description © Book Details

= Add the new widget to the 23 scowso0W..


cockpit
Misc. Attributes (unassigned to a section or tab) aN Title: Two Gentlemen of Pamplona
Authors: William Rattlespear
Discount Class Price Class Tax Class Book.ISBN10 FSBN10:/1100070340
ISBN13: 3331109070349
v . ’ 1109070349 Description: -

Book.|SBN13 Documents speciticfeatures © — Bookauthors

SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

© SAP SE C4H365 75
SAP Customer Experience

Widget Communication

INTERNAL — SAP and Partners Only

We will learn about:

>» What are input and output sockets in widgets.

>» How to implement and use the input/output sockets.

>» How to connect sockets to enable widget communication.

>» How to handle view component events.

>» How to handle global cockpit events.

INTERNAL SAP and Parners Only

76 C4H365 © SAP SE
Socket IO

Socket IO

= Widgets talk to each other via message objects with the help of the Backoffice Framework

= Input: listens for a ‘data receive’ event on a given input socket descriptor
— Fires method inside widget’s controller annotated with @SocketEvent:

@SocketEventCsocketId = "incomingMsg")

= Output: writes data to a given output socket descriptor


— Calls utility method inside widget’s controller:

sendOutputC"outgoingMsg", entry);

INTERNAL SAP and Partnors Only 4

© SAP SE C4H365 77
Adding Input Sockets

Input Sockets

= Inthe definition. xml, define a sockets element with one or more child input elements

= Specify the socket id and type for each input element

definition.xml

<widget-definition ...>

<sockets>
<input id= “rncomingMsg” type="Java. lang. String" />

</sockets>

</widget-definition>

78 C4H365 © SAP SE
Input Socket Events

= Create a public method inside the widget’s controller and annotate it using @SocketEvent

= The socketId and method input parameter type should match their definition in widget’s
definition.
xml

MyChatController. java

@SocketEvent(socketId = "incomingMsg")
public void receiveMsg(final String msg){
//do something with the msg

Adding Output Socket

© SAP SE C4H365 79
Output Sockets

= Indefinition.xml, define a sockets element with one or more child output elements

= Specify the socket id and type for each output element

definition.
xml

<widget-definition ...

<sockets>

<output id= "outgoingMsg” type= "Java. lang. String” />


</sockets>

</widget-definition>

Sending Data Over Output Sockets

In the widget’s controller, call sendoutput using the name of the socketId and the data content
type that matches the type given to that output socket in the widget’s definition. xml.

MyChatController.
java

public void sencMsg(){


//create some msg
sendOutputC"outgoingMsg", msg);

80 C4H365 © SAP SE
Connecting Sockets

Connecting Using Application Orchestrator

Login as admin and press F4 to switch into Application Orchestrator


Can make connections in layout or symbolic widget view

Cece CAUSTIC: We Satcher

Socket connection exists

© SAP SE C4H365 81
Connecting Using Application Orchestrator, cont.

= Connect source widget and


target widget sockets by Book Management organization.perspective.name {untitled}

dragging and dropping chain


link icon from source to target

Choose sockets to connect


= Select source socket — ‘Source: com.hybris.cockpitng.chatwidget Target: com. hybris.cockpitng.chatWidget

Application Orchestrator will outMessage


‘Type: javatang String,
inMessage
Type: java.lang.String
suggest target sockets

= Socket types must match! Out Socket Ta Socket

Connections (*-backoffice-widgets.xm1l)

= Define source and target widgets

= Define input and output socket IDs

widgets. xml

<widgets>

<widget-connection sourceWidgetId= "“myChatOne”


outputId= “outgoingMsg”
targetWidgetId= "myChatTwo"
inputId="incomingMsg" />

</widgets>

82 C4H365 © SAP SE
What if socket types don’t match?

Several options when faced mismatched socket types:

1. Create a new widget definition having desired, matching socket type, plus a new controller
class to go with it.

2. Change the definitions of the existing widgets to get socket types to match

3. Use an adapter widget in between

4. Adjust the socketDataType_$T setting, if the source widget’s socket type is of the generic
type <T>

Adapter Widgets

= Main purpose for having adapters:


- If you need two widgets to communicate but socket types on the two ends don’t match.

= Existing adapter widgets:


- Logical NOT Gate Widget: to perform the logical NOT operation on a socket’s value
- Cast Widget: to cast the type of a socket to any other type, given that it’s a justified cast
- Condition Evaluator Widget: to set a condition (as a SpEL expression) to be evaluated
- Property Extractor Widget: applies an expression on the input object and sends the result
to the output
- Event Producer Widget: emits events with the input data
- Event Acceptor Widget: receives events of corresponding typed data

: Adapter widgets are typically not visible


- Why? cf. next slide...

© SAP SE C4H365 83
Adapter Widgets e Where should they go?

Remember cockpitWidgetChildrenInvisible slots?

= Every widget has a single invisible slot called cockpitWidgetChildrenInvisible

= It doesn’t matter in which widget’s


invisible slot you put the adapter

~ Only the socket connections [Bqirertee


RP |
ofine acapier mater

source adapter target


widget widget widget

Adapter widget instance can be put in the cokcpitWidgetChildrenInvisible


slots either in source widget or in target widget 17

socketDataType_$T Widget Setting

Sometimes a socket’s type is <widget id="bookstorecustombackoffice-preview-adapter” ...>

in terms of the generic type <T> <setting key="socketDataType_$T" type="String” value="my. bookstore.core.model.BookModel" />
</widget>
Collection Browser
com.hybris.cockpitng.collectio
You can specify what the generic type
Description:
is supposed to be in a widget instance,
Displays obj by adding/modifying a setting named
socketDataType_$T
list (<T>:LIST)
pageable (com.hybris.cockpitng.search.data.pageable.Page
previousltemSelectorInvocation (<T>)
nexitemselectorinvocation (<T>) (Similarly, if the socket were of the generic
reset java.util.Map . ;
Outputs: type <K>, then the setting’s name would
selecteditem (<T>) be socketDataType_$K )
selecteditems (<T>:LIST)
sortData (com.hybris.cockpitng.search.data.SortData)
previousltemSelectorContext (com.hybris.cockpitng.widgets.navigation.NavigationltemSelectorContext)
nextltemSelectorContext (com.hybris.cockpitng.widgets.navigation.NavigationltemSelectorContext)

84 C4H365 © SAP SE
socketDataType_$T Widget Setting e Example

<T> selectedItem = java.lang.Object inputObject

inputObject
Collection semen ne cememeecememeneeeee C) Editor Area
Browser
selecteditem

Auto adjust type x

The socket data types are not compatible but there is a generic
type variable. Do you want to set the type variable 'T' to . . .
‘java.lang.Object’? Answering “Yes” will result in the
socketDataType_$T setting being
No | xcs created automatically.

Demo

© SAP SE C4H365 85
Mapping View Events

How To Map View Events (E.g., handling button clicks)

You can access view events in a controller, using


1. the ID of the component
2. the type of the event

MyChat. zul
<?xml version= "2.0" encoding="UTF-8" standalone="yes”" 7>
<widget xmlns:xsi= “http://www. w3. org/2ZO01/XML Schema-instance”
xsi: noNamespaces chemalocation="http: //www. zkoss.org/2005/zul ">
<div>
<textbox id=”
<button
</div>
<div>
<label id="lastMsglabel” value="No message. "></label>
</div>
</widget>

22

86 C4H365 © SAP SE
Mapping View Events

MyChatController.
java
public class MyChatController extends DefaultWidgetController
{
private Label lLastMsgLabel;
private Textbox msgl

@ViewEventCcomponentID = “sendBtn", eventName = Events. ON_CLICK)


public void sendMsg(){
String msg = msgInput.getTextQ);
sendOutputC"outgoingMsg", msg);

23

Trapping Global Events

© SAP SE C4H365 87
Global Events — Annotation

= Based on the Spring Event System

= Denote the listener method by using the @GlobalCockpitEvent annotation and specify which
CRUD event you're trapping

The ObjectCRUDHandler interface has constants for all standard model-based event names that can be
trapped (notice: OBJECT_CREATED_EVENT is singular, unlike the others):

- ObjectCRUDHandler. OBJECT_CREATED_EVENT
- ObjectCRUDHandler. OBJECTS_UPDATED_EVENT
- ObjectCRUDHandler. OBJECTS_DELETED_EVENT

Widget Controller class

@GlobalCockpitEventCeventName = ".." <, scope>)


public void handleEvent(final CockpitEvent event) { ... }

Global Events — Publishing

The controller class of your Widget, Editor, or Action can also publish a CRUD Global Cockpit Event
to moger refresh on all listening components: MyXyzController.
java
.

fe dcstian EE ;
} private CockpitGlobaLEventPublisher cockpitGlobalEventPubLisher; 1

@Resource
private ModelService modelService;

public ReturnType controllerMethod(final SomeContext<ProductModel> ctx) {


final ProductModel currentProd = ctx.getDatad);

currentProd.setSomeAttribute( newValue );
try {
modelService. saveCcurrentProd);
| cockpitGlobalEventPublisher.publish€ //only on success
'i_.~ ObjectCRUDHandler OBJECTS \TED_EVENT,
ObjectCRUDHandler.OBJECTS_UPDATED_EVENT, currentBoo
currentBook, null 13!
} catch Cfinal ModelSavingException “ex) {. ss

88 C4H365 © SAP SE
Global Events — Scope

Scope is optional!

Available scopes:
—CockpitEvent. DESKTOP (default, if unspecified)
—CockpitEvent. SESSTON
—CockpitEvent.
Y/SER
—CockpitEvent.APPLICATION

= Communication can be setup between two widget instances


» Setup socket connection in *-backoffice-widgets.xml or using orchestrator
» Make sure the type between output socket and input socket should match, otherwise use adapter
widgets in-between
» Use @SocketEvent to respond to socket related events in a widget controller

= Awidget can respond to actions on the Ul components in the widget controller via
» Wiring UI components
» Using @ViewEvent

= Awidget can handle global cockpit events via @GlobalCockpitEvent

© SAP SE C4H365 89
Exercise 6 — Connect Your Widgets

Exercise 6 — Connect Your Widgets

"Create a smarter widget that

= Creates a popup preview ONLY if there is


an existing image

| Glick to zoom!

= Can handle updates and deletions, and in le: The Chicken or Egg Dilemma -
Cracked

turn update the view uthors: Ken Jian


ISBN13: 3339439522259
Rentable?: true

ERNAL SAP ard Partners Only 30

90 C4H365 © SAP SE
1. Look at the Existing Socket Handler

Have a look at handleSelectedBook (BookMode1)

BookDetailsController.java

@SocketEventCsocketId = SOCKET_SELECTED_BOOK)
public void handleSelectedBook(final BookModel book)
{
LOG.infoC"Socket event is caught with Book: " + Cbook != null ? book.getName() :
"no book available"));
setSelectedBook(Cbook);
renderQ);
}

INTERNAL SAP and Parners Only 3

2. Add a New Input Socket

= Create a java. lang.Boolean input to enable/disable previewing an image.

—Widget definition

—Widget controller (handleAllowPreview(Boolean))

INTERNAL SAP and Parners Only 32

© SAP SE C4H365 91
3. Connect Through an Adapter

= Set the input using an adapter.


The adapter checks if there’s
animage forthe selected book. = = “™ ~oeeee*

"Ifanimage exists, the adapter ia 7) = IE


outputs true (ifnot false) to _ .
Book Details.

INTERNAL SAP and Partnors Only 33.

4. Trap Global Events

Create methods for handling updates and deletions.

—Trap update event (handleObjectsUpdatedEvent (CockpitEvent ))

—Trap delete event (handleObjectsDeletedEvent (CockpitEvent ))

ERNAL SAP and Partnors Only Rad

92 C4H365 © SAP SE
SAP Customer Experience

Thank you.

SAP Customer Experience

Widget Context Configuration

INTERNAL — SAP and Partners Only

© SAP SE C4H365 93
We will learn about:

> How context configuration affects the final widget view

> How to define a new configuration type based on XSD and JAXB

> How to access and use context configuration in a widget controller

> How inheritance/merging works in context configuration

> How to use application orchestrator to change context configuration at runtime

INTERNAL SAP and Partnors Only 2

Backoffice Context

94 C4H365 © SAP SE
Flashback!

In the Book Management Type to search Q ma 2 A


cockpit, you might wonder what | Title: "HybrisAll in One" - Bookstore Product Catalog
: Staged | a
determines:
. ie tT v Refresh
the label on top of the editor
< Properties Attributes Category System Prices media Variants il Reviews Stc >
area
®The tabs in the editor area Escentiall s
widget . Article Number* Identifier © Catalog version* Approval*

MWhat the preview of a book < ssssiszoe ts Ain one —— - |...


should look like Image Book.publisher Book.rentable —

BB 300Wx300H/hybri... Hybris Press International (_) True (@) False


Chars: 26 Limit: 40 Chars lef () N/A

Aybris
All in One
Validity Period a Authors: Carsten Joch
ISBN13: 33355361520
Rentable?: false
Online from Online to

a 8 a

INTERNAL SAP and Partnors Only 4

Examples of Backoffice Context Configuration

Widget views can benefit greatly from Context-Sensitive configurations.

Examples:

Q: What part of the the explorer tree should be accessible to users in a certain role?

= A: Only system administrators should see the System node and its subtree

Q: Which fields should be visible for each item type when displayed?

= A: Show thumbnails only for the item types that have an image associated with them

INTERNAL SAP and Partnors Only 7

© SAP SE C4H365 95
Backoffice Context Configuration — Recap

= XML attributes of the <context> elements used in *config.xml


= Allows “filtering” of which context elements to merge
component - It specifies which component this configuration should apply in. When the widget
loads the configuration, it specifies the component name.
merge-by — Together with the parent attribute, it declares by which properties the configuration
should be merged
principal — It specifies a Backoffice Role of users that this configuration applies for.
type — If the widget can handle objects of many types, you can specify the configuration for
each type.
parent — It specifies a parent configuration which is supposed to be merged
custom attributes can be added, with some development work

INTERNAL SAP and Partnors Only 8

An Example of “Base” Configuration

Similar in principle to
Java's toString):
an item type’s “most en Q #8 4 a
basic” way to render
| Title: "Hybris All in One" - Bookstore Product Catalog : Staged | a

wo 6 A L Refresh

P , | bookstorecustombackoffice-backoffice-config.xml
<context merge-by="type” parent="Product" type="Book" component="base">
<y:base xmlns:y= "Attp://ww. hybris. com/cockpit/config/hybris">
<y: Labels>
<y:label>'Title: "" + Cname?:code) + '" - '
@LabelService. getObjectLabel CcatalogVersion)</y: label>
</y: lLabels> pk Det... &

<y:preview urlQualifier= "thumbnail?: picture” />


</y:base>
</context>

INTERNAL SAP and Partnors Only 9

96 C4H365 © SAP SE
Context Configuration Precedence

= 3 different versions of the UI configuration:

Loading
mybackoffice/backoffice/resources/widgets/mywidget/cockpit-config.xml
(optional) Configuration of a specific widget. Think of it as the widget’s default configuration Order

mybackoffice/resources/mybackoffice-backoffice-config. xml
Configuration of components defined in the mybackoffice extension. It can also be loaded at
runtime by doing a reset in Application Orchestrator or click reset everything button if dev
toolbar is enabled

cockpit-config.xml
Merged configuration of the whole Backoffice application. You can modify it at
runtime from Application Orchestrator - - > Show cockpit-config.xml. This file is stored
as an SAP Commerce Cloud Media item

INTERNAL SAP and Parners Only

Context Configuration Precedence - Example

Tree Collection Advanced Tree Collection Advanced


Explorer Browser Search Explorer Browser Search

Commerce
Platform
= Widgets Search — = Widgets
Backoffice
Backoffice
Module + Module Module

Backoffice cockpit-config.xml
Application

INTERNAL SAP and Parners Only

© SAP SE C4H365 97
Context Configuration - Data Types

Refreshing XML Concepts and Technologies

= XML: eXtensible Markup Language that defines a set of


rules for encoding documents in a format which is both >} JaxB
human-readable and machine-readable. Schema bind
4 classes

= XSD: XML Schema Definition specifies how to formally


describe the elements in an XML document.
follows instances of

= JAXB: Java Architecture for XML Binding (JAXB) unmarshal


allows Java developers to map Java classes to XML (validate) >
representations (and vice-versa). Marshal Java Objects Document ob
into XML and unmarshal XML into Java Objects. me < joes
marshal
(validate)

98 C4H365 © SAP SE
Context Configuration - Data Types

: Acontext configuration - data type, or configuration type, for short, is a composed type in
XML and can be used for holding context configuration data

= Each configuration type is defined inside an XML Schema Definition (XSD) file

: JAXB is used to auto-generate Java classes (JAXB-annotated POJOs) that correspond to XML
data conforming to your XSD types

: Atruntime, we use JAXB to convert from XML data to instances of their corresponding Java JAXB
classes

Configuration Types — Example: “Base” Configuration


Base. java
base.xsd
«<xs:schema xmlns:xs= "http: “www. w3. org/Z0@1/XML Schema” @XmlAccessorType(XmlAccessType. FIELD)
xmnins="http: //www. hybris. com/cockpit/config/hybris” @XmlTypeCname = “base”, propOrder = {} )
targetNamespace= "http://www. hybris. com/cockpit/config/hybris” @XmlRootElementCname = “base")
elementFormDefault= “qualified” > public class Base {

<xs:element name="base" type="base"/> protected Labels labels;


protected Preview preview;
<xs:complexType name="base">
public Labels getLabels() {
<xs:all>
return labels;

ech
<xs:element name="Jabels" type="labels" minOccurs="@"/>
<xs:element name= "preview" type="preview" minOccurs="0"/>
</xs:all>
</xs:complexType> public void setLabels(Labels value) {
this.labels = value;
<xs:complexType name= "labels "> }
<xs:all>
<xs:element name= "label" types="xs:string” minOccurs="0"/> public Preview getPreviewQ) {
<xs:element name="description” type="xs: string” minOccurss" O"/> return preview;
<xs:element name="iconPath" type="xs:string” minOccurs="0"/> }
</xs:all>
public void setPreview(Preview value) {
<xs:attribute name="beanId" type="xs:string"/>
this.preview = value;
</xs:complexType>
<xs:complexType name="preview">
<xs:attribute type="xs:boolean” default="false" name="fallbackToIcon” f>
<xs:attribute type="xs:string” name="urlQualifier" />
</xs:complexType>
</xs: schema>

© SAP SE C4H365 99
Creating New Configuration Types

= The three initial steps:


1. Create your own XSD file that defines the widget configuration
2. Use JAXB (via your IDE) to generate the Java classes based on the XSD file using JAXB
3. Use JAXB (via your IDE) to generate an XML file based on the XSD and fill the configuration
values
New JAXB Classes from schema
eve Neve XML File

7
coe
Boing fs.

P huspewwnunyerie.cor/cocksitfe nase.xed

Instantiating Configuration Types

= Place the generated configuration data (filled-in XML data structures) inside your custom Backoffice
extension *-backoffice-config.xml file within a context element.

= Define the component attribute value (i.e., provide a name for your configuration context entry)

= Optionally, define any context such as type and principal attribute values

bookstorecustombackoffice-backoffice-config.xml
<context merge-by="type” parent= "Product" type= "Book" component= "base ">
<y:base xmLns:y= "Attp://ww. hybris. com/cockpit/config/hybris">
<y: Labels>
<y:label>"Title: "" + Cname?:code) + '" - '
@LabelService. get0bjectLabel CcatalogVersion)</y: label>
</y: labels>
<y:preview urlQualifier= "thumbnatl?:picture"” />
</y:base>
</context>

100 C4H365 © SAP SE


Instantiating Configuration Types — Alternate Style

= Instead of specifying all attributes in a single element (as in the first example below), <context>
elements can also be nested (as in the second example). This can sometimes improve readability:

bookstorecustombackoffice-backoffice-config.xml

<context component= "base" merge-by= "type" type= "Book" parent= "Product" >
<y:base xmLns:y= "Attp://www. hybris. com/cockpit/contig/hybris'>...</y:base>
</context>
<context component= "base" merge-by= "type" type= "ReadingLight" parent= "Product" >
<y:base xmLns:y= "Attp://www. hybris. com/cockpit/contig/hybris'>...</y:base>
</context>
bookstorecustombackoffice-backoffice-config. xml

<context component= "base" merge-by= "type" >


<context type= "Book" parent= "Product" >
<y:base xmLns:y= "Attp://www. hybris. com/cockpit/contig/hybris'>...</y:base>
</context>
<context type="Readinglight" parent= "Product" >
<y:base xmLns:y= "Attp://www. hybris. com/cockpit/contig/hybris'>...</y:base>
</context>
</context>

Relation between XSD and Context Configuration


Generated XML Configuration
cockpit -config. xml <?xml version= "2.0" encoding= "U7F-8'?>
<context component= tree” ...> Create widget’s default context <tns:tree title=”” xmlns:tns=..>
<tree:tree xmlns:tree=”..” configuration from generated XML <tns:nav-node ..>
<tree:nav-node id=”.

</context>
Generate XML
tree.xsd
LI
<xs:schema ...>
<xs:element name= "tree’>

<extension> -backoffice-config. xml <xs:element name= “nav-node’>

<context component= tree” ..>


a Generate XB Class
</context> Tree.java -> Tree.class
<context component="tree” principle="aanin” .>
@xXmlAccessorType(...)
</context> @Xm1lRootElement(name ="tree")
public class Tree {

© SAP SE C4H365 101


Reading the Widget Configuration

=In the widget’s controller (examples to follow):

1. Instantiate and initialize a DefaultConfigContext object via its constructor:

* Specify the configuration component jd to request


* Optionally, specify type and/or principal (either via constructor or setter methods) to enable
filtering when Backoffice merges configuration components

2. Call getWidgetInstanceManager().loadConfiguration()

* Pass-in a reference to the initialized DefaultConfigContext instance


* Pass-in the JAXB type (i.e., Java. Lang. CLass<Type>) representing the JAXB class to return (and,
thus, the <context> body’s XSD type to expect)

Reading the Widget Configuration, cont.

To obtain a configuration from Backoffice: BookDetailsController. java

final DefaultConfigContext configContext = new


DefaultConfigContext(getWidgetSettings().getStringC WIDGET_SETTING_CONFIG_CONTEXT));

baseCfg = Optional. ofWu1 lable(getWi dgetInstanceManager(). loadConfigurationCconfigContext, Base.class));

It’s also possible to store a configuration:


BookDetailsController.java
getWidgetInstanceManager().storeConfigurationCconfigContext, Base.class)

102 C4H365 © SAP SE


Reading-in the Widget Configuration — Diagram
definition.xml
Merged cockpit-config.xml
* unique ID .
+ view Tree.java -> Tree.class .
* — controller <context component=“tree” ...>
* sockets @xmlAccessorTypet...) .
+ — settings @Xm1RootE lement(name= "tree ”) </context>
+ config id public class Tree { <context ... principle= “admin”
~} —

</context>
TreeController.java
rc

Tree treeConfig = WidgetInstanceManager Marshalling /Unmarshalling


. loadConfiguration{ConfigContext, config type)

<render view based on


Tree context config> ¢“_ JAXB instance

view.zul —™) Widget Instance

oo EXPLORER v
<widget ...>

<panel ...>
<caption ...> © Home
<div>
& Inbox
> system
22
> Catalog

Context Reuse and Merging

© SAP SE C4H365 103


Reusing and Merging Widget Configurations

"Use merge-by and parent <context> element XML attributes:

—merge-by: <context> attribute specifying the kind of merge, thus the kind of
parent the merge should be using
« Possible values: type | principal | component

—parent: <context> attribute specifying the next context item in the hierarchy of
config components to be merged

(examples follow)

Example 1 of Merging Widget Configurations

<context component= "abc" merge-by="type”


type= "Book" parent= "Product" >

If your widget controller's Defaul tConfigurationContext instance was


{component: abc; type: Book}
1. Backoffice would find the matching <context> element
2. Merge-in (inherit) the context info for this element's parent config element “in
the hierarchy, {component: abc; type: Product}
3. Merge-in (inherit) the context info for (presumably) the next parent config
element, {component: abc; type: Genericltem}, i.e., the item type that this
context element specified (presumably) as its parent in the type hierarchy,
and so on.

104 C4H365 © SAP SE


Example 2 of Merging Widget Configurations

<context component= "xyz" merge-by= "principal"


principal="admin"” parent="admingroup” >

If your widget controller's Defaul tConfigurationContext instance was


{component: xyz; principal: admin}
1. Backoffice would find your <context> entry where both values match
2. Merge-in (inherit) the context info for this element’s parent config element,
{component: xyz; principal: admingroup}
3. Merge-in (inherit) the context info for (presumably) the next parent element in
the hierarchy, {component: xyz; principal: backofficeadmingroup},
i.e., the User Group or Role that this context element specified as its parent
in the principal hierarchy (i.e., the User Group or Role of which
admingroup is a member), and so on.
27

An Illustrated Example Merging Widget Configurations

shoestorebackoffice-backoffice-config.xml

<property name= "size" />


<property namem "brand" />
</context>

<context |component= "ShoeDetai ls “Imerge-by= "principal al parents="productManagers" [principals “stockManagers’> |


<property name= "width" />
</context>

property name='size', {
property name="brand" component="ShoeDetails"|
principal="stockManagers"|
type=""
Merged view-configuration data a
property name='size", }
particular widget’s controller receives.
property name="brand",
DefaultConfigContext instance
(this widget wants to know, “in this Property name="width" used for loading configuration
contextual situation, what properties
should I display, and in what order?” )
28

© SAP SE C4H365 105


Orchestrate the Context

Changing Widget Configuration On The Fly


widgets Widget Clipboard
= Using Application Orchestrator mode, you can modify
widget context configuration and see the changes at Refresh
runtime (without restarting the server) \x
}
Show widgets.xml

= Useful and fast way to test your widget’s context Reset to Defaults
configuration
Show cockpit-config.xml

Reset to Defaults

Simulate config resolution

Reset Everything

Widget Toolbar Color >

31

106 C4H365 © SAP SE


Apply Cockpit-config Filters and Change at Runtime
You can filter the configuration file by providing the relevant values for the available attributes!

HH 1
1
HH __Somponent wet. Princpat source tary Mode Perspective
Ll --- pi bee x] T sox xt Search principal Search source Search authority Search module Search perspective
H1 | : : é = OS
HH ‘orgemployeerole *dynamicForms auditreponservices
HH advancedSearch( 0-910)" basecommercet backottice
HH Find parent for x Find parent for x Find parent for x Find parent for x
''
HH
H you can ‘Add new context tag or tag, 10 full context mode.

jectLabel| y:Label>
idee" thumbnail? :picture" />

a a
7
Unlike widgets. xml, you can modify, validate, and store :
your changes to cockpit- config. xml inside Application
Orchestrator.

XSD Validation

= Context configuration can be validated against the XSD of the configuration types

= Done by default when editing in Application Orchestrator

2 Can be controlled through this property:

backoffice. cockpitng. validate. cockpitConfig.orchestrator

2 true by default
Confirmation needed x

= If the configuration is not valid you ©® Are you sure that the configuration should be persisted?

50
get a warning when trying to store it

© SAP SE C4H365 107


Configuration Validation Everywhere

= Validation is not done by default if you change the configuration files directly rather
than through Application Orchestrator
1 Can be controlled through this property:

backoffice.cockpitng.validate. cockpitConfig.onstartup

1 false by default

= You'll get a warning in the system console:


$ ./hybrisserver.sh
WARN [hybrisHTTP1] [SchemaConfigValidator] Warnings occurred while processing configuration file:
SCHEMA VIOLATION: org.xml.sax.SAXParseException;...

= Context configuration is used to decide how and what to be shown on widgets under specific
circumstances
= We are using configuration types and the related java classes generated by JAXB to handle
context configuration.
= We can access context configuration in a widget controller class.
= Different widget instances with the same type can share the same context configuration or
have their own context configuration via *backoffice-config.xml.
= Context configuration can be merged based on type, component or principal

108 C4H365 © SAP SE


Exercise 7 — Configure the Context

Exercise 7 — Configure the Context

Take advantage of the power that context configuration gives you by:

= Defining new configuration types

= Reusing (merging-in) existing configuration

ERNAL SAP and Partnors Only 37

© SAP SE C4H365 109


1. Create a New Configuration Type

Create a new configuration type for the Book Details widget.

It should specify the sequence of Book properties that you would like
the widget to display, but only when viewing a Book.

You'll need to:


= Use a schema (provided for you) for the new configuration type
= Use JAXB to convert the schema into JAVA classes

INTERNAL SAP and Parners Only 338

2. Define New Configuration

= The Book Details widget already uses configuration data of type Base.
= This existing configuration is used to configure the image and label of a book.

bookstorecustombackoffice-backoffice-config.
xml
<context merge-by= “type” parent="Product" type="Book"” component="base">
<y:base xmlns:y=“Attp: //www. hybris. com/cockpit/config/hybris ">
<y: Labels>
<y:label>'Title: "' + Cname?:code}) + '" - ' + @labelService.getObjectLabel CcatalogVersion)</y:label>
</y: label s>
<y:preview urlQualifier= “thumbnail?:picture” />
</y:base>
</context>

= The other properties that are shown by your widget are currently hard-coded into the controller's render)
method.
= Define (and use) a new XML configuration-data type to allow you to configure which properties should be
shown by the Book Details widget.

INTERNAL SAP and Parners Only 39

110 C4H365 © SAP SE


3. Compare Configuration for Different Types

See how the editor for type Product looks in the Admin cockpit
= Compare it with how the editor for type Book looks in the Book Management cockpit.

Title: "UML Changed My Life" - Bookstore Product Catalog : Staged

6 68 . + Refresh

7 (Notice: no tabs and


—_ . no proper section headers)

es Ut creedUt
i xoerenneconne- a, (Bockvessertiad &
‘Anticle Number* Identifier © catalog version* Approval”
a Ut cares SSS a 3
Validity Period ae
Image Description ©
Tm coe £2 soomazipnaicomrpg-
Boe
6

[books.unbound] = A

2 5 2 seer
Book ISBN13 Documents Specific features © Book authors
ree [oe 5 [ome ete cats a ae
oe
INTERNAL SAP and Parners Only 40

4. Reuse Existing Configuration

Reuse Product type’s configuration in the Admin cockpit to improve the Book type’s editor view in the
Book Management cockpit.

Title: "The eCommerce Murderess" - Bookstore Product Catalog : Staged

G © Refresh

Properties Attributes Category System Prices Multimedia Variants Attributes i Stock

Essential n

Article Number* Identifier © Catalog version* Approval*


6824238759 The eCommerce Murderess Bookstore Product Catalog : ... approved v

Validity Period n

Online from Online to

6 6

INTERNAL SAP and Parners Only 4

© SAP SE C4H365 111


SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

SAP Customer Experience

Actions and Editors

INTERNAL — SAP and Partners Only

112 C4H365 © SAP SE


We will learn about:

>» The basic concepts of editors and actions

>» Using existing editors and actions in a widget

Developing custom editors and actions


Vv

Making editors and actions socket-aware


Vv

INTERNAL SAP and Partnors Only 2

Introduction

© SAP SE C4H365 113


Editors and Actions

"Actions and Editors are components that can be used INSIDE widgets

= Editors manage the input, display, and handling of a single value of a given type
* Key Concept: Display and Handle Data within a Widget’s view
* E.g. Boolean data types can use an editor that displays on/off radio buttons
to the user
* E.g. Date data types can have an input with format and validation or a custom date picker
= Actions are responsible for the invocation of custom code within Backoffice
* Key Concept: Do Something in Java, triggered by clicking on an icon
* E.g. creating a new type-based Item (e.g. a Product, Order, or Customer)
* E.g. changing the state of a Product's availability from ‘available’ to ‘unavailable’
* Often invoked using a button control or menu option

INTERNAL SAP and Partnors Only 4

Editors and Actions

= The Backoffice Framework provides standard Editors and Actions OOTB

= Process of defining custom Editors and Actions is similar to defining a Widget


(...but Editors and Actions are NOT specialized kinds of Widgets)

= Actions and Editors can also have context-based UI configurations

= Actions and Editors are not socket-aware, but they can be made socket-aware using STUBS (This will be
discussed later)

INTERNAL SAP and Partnors Only 5

114 C4H365 © SAP SE


Available Editors Gallery

Available Editors Gallery

= Default Boolean: O True © False O N/A

= Check Box Boolean:


0
= Localized Simple Editor:
Name

en | }
es_CO

pt

= Default Big Decimal Editor:


1011202.43460000

© SAP SE C4H365 115


Available Editors Gallery

= Default Password Editor: Change Password

New Password

Confirm New Password

= Default Date Editor: Time modified

Aug 14, 2023 3:09:39 PM

< Aug 2023

s M
30 31
6 7 10
13 14 15 16 7 18
20 2 22 23 24 25
27 28 29 30 31

03:09:39 PM

Editors in Widgets

116 C4H365 © SAP SE


Using a Default (Type-Mapped) Editor In a Widget

= Editor instances can be added to a widget via myWidget. zul


— Assign an ID to the view element
— Imply which editor definition to use by specifying the data type for the field
Each data type is mapped to its default editor in standard-editors- spring. xml
— Backoffice uses the default editor definition mapped to this type

myWidget.zul
<widget ..>

<label value= "First Name:" />


<editor id="firstNameFieldEditor” type= "java. lang. String" />

<label value= "Last Name:" />


<editor id= "lastNameFieldEditor" type= "java. lang. String" />

</widget>

Using a Specific Editor In a Widget

= An editor definition id may be explicitly specified, instead of implicitly via type:


* Assign an ID to the instance
* Specify the editor definition to use for the instance
Use the defaultEditor attribute
Specify the editor definition id
In this case, Backoffice’s WYSIWYG editor is used for this field instead of the default

myWidget.zul
<widget ..>

<label value= "Username: " />


<editor id= "“uvserNameFieldEditor”
defaultEditor= "com. hybris. cockpitng. editor. wysiwyg" />

</widget>

Editors in Widgets

© SAP SE C4H365 117


Binding the Editor to a Widget Model Property (via ZUL)

= Bind the editor to a property in the widget model using the property attribute
= Two-way binding:
— The property value will be displayed in the editor upon rendering
— When a user changes the value in the editor, the model property is automatically updated

MyWidgetController. java
WidgetModel model = getModel();
model.putC"product", product);

myWidget.zul
<label value= "Product code:" />
<editor type= "java. lang. String "| property= “product.\code " [>

<label value= "Category: " />


<editor type= "java. lang. String"|property= “product.\category. name" />

Specifying Attribute Editors via Configuration (1)

= Often, in practice, widget types require that you indirectly configure what
fields to display and how to display them (i.e., editors, sections, tabs, etc.)
— Configured via <context. .> XML entries in *-config.
xml
(as opposed to explicitly specifying the composition of ZUL components)
— The XML syntax for each <context. .> element body depends on the JAXB configuration type the
widget controller expects

= Based on this configuration, the widget controller dynamically generates ZUL display components (and binds
editors to the display components)

118 C4H365 © SAP SE


Specifying Attribute Editors via Configuration (2)

= For example:
Advanced Search widget instances expect a JAXB construct containing element
<field name= "attrib” editor= "editor. definition.id” >

mycustombackoffice-backoffice-config.xml
<context type= "Shoe" component= “advanced-search" >
<advanced-search: advanced-search
|xmLns:advanced-search] = “http://www. hybris. com/cockpi tng/config/advancedsearch" >
<advanced-search: field-List>

<advanced-search:|field| | name= "waterproof'| selected= "false"


editor= "com. hybris. cockpitng. editor. boolean. checkbox "|/>
</advanced-search: field-Llist>
</advanced-search: advanced-search>
</context>

Specifying Attribute Editors via Configuration (3)

Whereas:
Editor Area widget instances expect a JAXB construct containing element
<attribute qualifier= “attrib” editor="editor.definition.id” >
mycustombackoffice-backoffice-config.xml
<context merge-by="type” parent= "Product" type= "Shoe" component=
"edi tor-area” >
<editorArea:editorArea
|xmLns:editorArea| = “http://www. hybris. com/cockpi tng/component/edi torArea" >

<editorArea;jattribute| |qualifier= “szze"|


|editor= ‘my. shoestore. backoffice. editor. customSizeEdi tor"|/>
<editorArea:attribute qualifiers "color" />
</editorArea: editorArea>
</context>

Recall: Details of each widget type’s configuration data structure at


https://help.sap.com/docs/SAP_COMMERCE CLOUD PUBLIC CLOUD/9b5366ff6eb34
df5be29881ff55f97d2/8b5a00a2866910149de6d450109c80d1.htm

© SAP SE C4H365 119


Specifying an Initial Value via ZUL

= Specify an initial value by adding a valLue attribute

myWidget.zul
<widget ..>

<editor id="firstNameFieldEditor” type= "Java. lang. String"


property= "customer. FirstName" value="Some text" />

</widget>

Specifying Value-Change Handler via ZUL

= Handling a changed value (returned by an Editor) without binding to a property:


— Option 1 - define binding (handler) from the widget’s view

myWidget.zul
<widget ..>

<editor id= "userNameFieldEditor" type= "Java. lang. String”


onValueChanged= "“widgetController.doSomeThing(.)" />

</widget> [ 7 |

120 C4H365 © SAP SE


Specifying Value-Change Handler via Java Annotation

= Handling a changed value (returned by an Editor) without binding to a property


— Option 2 - Define onValueChanged event handling method in the widget’s controller with @ ViewEvent

myWidget.zul
<widget ..>

<editor id="userNameTextField” type= "Java. lang. String” />

</widget>

MyWidgetController.java
public class MyWidgetController\extends DefaultWidgetController

private Editor userNameTextFiekdEdi tor;

@V i ewEventCcomponentID= “uvserNameTextField”, eventName= “onValueChanged” )


public void doSomethingQ
{
final String tmp = CString) userNameTextFieldEditor.getValue();
// do something
Joos
t

Creating an Editor

© SAP SE C4H365 121


Creating an Editor 1 — Definition File

= Definition file:

bookstorecustombackoffice/backoffice/resources/editors/mySimpleTextEditor/definition.xml
<editor-definition id= "com. corp. cockpitng. editor.mysimpletexteditor” >
<name>My Simple Text Editor</name>
<description>Simple text editor</description>
<!--The type of the value this editor is capable of handling. Used for type-mapping -->
<type>java. lang. String</type>
<editorClassName>org.myextension.
editor. simplLetext.MySimpleTextEditor</editorCLlassName>
</editor-definition>

Creating an Editor 2 — Rendering via Custom Class


= Editor class can implement the CockpitEditorRenderer interface or extend its subclasses, such as
AbstractTextBasedEditorRenderer, the main responsibilities are two fold:
» Provide editor UI, which must be attached to parent component
» Register event listener to notify about value changed in this editor
MySimpleTextEditor. java

iattners {
a Textbox editorView = new Text BoxC5?
editorView.setValueCcontext.getInitialValueQ));

editorView.addEventListenerCEvents.ON_CHANGE,
new EventListener<Event>() { context object given to a
public void onEvent(final Event e) throws Exception cockpit editor during the
{. . .} rendering process.
}
ds
editorView.setParent(parent);

ween the listener to notify about value


changes or other events.

122 C4H365 © SAP SE


Creating an Editor 3 — Rendering via .zul File

= An editor can be rendered using a . zu] file instead of a custom Java class:
bookstorecustombackoffice/backoffice/resources/editors/mySimpleBoolEditor/definition.xml
<editor-definition id= "com. corp. cockpitng. editor.mysimplebooleditor” >
<name>My Simple Boolean Editor</name>
<description>Simple boolean editor</description>
<type>java. lang. Boolean</type>
<view src= "boolfditorView.zul” />
</editor-definition>
boolEditorView.
zul
<hlayout id= "boolfditor”>
<radiogroup id="rgr” />
<radio label="7rue” radiogroup="rgr” forward= ‘onCheck=boolfdi
tor. onEditorValueChanged(${true})'
checked= "$farg. initialValue == true}” />
<radio label="false” radiogroup="rgr” forward= ‘onCheck=bool£di
tor. onEdi torValueChanged(${false})'
checked="$farg. initialValue == false}” />
<radio label="n/a” radiogroup="rgr” forward= ‘onCheck=bool£di tor. onEdi torValueChanged(${nul1})'
checked= "$farg. initialValue == null}” />
</hlayout>

= Here, view events are “forwarded” to the event handlers bound to the root element by
OOTB DefaultZulCockpitEditorRenderer ee

Available Actions Gallery

© SAP SE C4H365 123


Available Actions Gallery

= Create Action: + ()

¥ Product

Book

> Variant Product

= Delete Action: w

= Launch Permission Management: LOW

26

Actions in Widgets

124 C4H365 © SAP SE


Using Actions in Widgets — ADD to Widget - via ZUL

= Add the Action to the widget view (any number of <action> elements allowed)
= Bind each action to an ‘attribute’ of the widget model via XML property attribute
— Auto-adds an observer to the widget model for handling changes
— Bound attributes are copied/synced into the Action’s ActionContext
myWidget.zul
<widget ..>

<action actionld="org.myextension.action.myAction” property="product"/>

</widget>
MyWidgetController. java
WidgetModel model = getModel();
model.putC"product", product);
MyAction. java
public ReturnType everyActionMethod ( ActionContext<ProductModel> ctx ) {
ProductModel boundProduct = ctx.getData();

Using Actions in Widgets — ADD to Widget — via Config

= Amore advanced/preferred way to add action(s) to a widget in the view


— Enables grouping of your actions to control visibility in a context-sensitive way
= Same as basic option, except Action is added indirectly to the widget view
= With the context configuration based on types or user roles, a widget can be loaded with different
actions at runtime.
myWidget.zul
<widget .>

<actions config= myActionsSlotConfig” group="common” sclass="yw-actionsSlot” />

</widget>

myExtension/resources/myExtenstion-backoffice-config.xml
<context component="myActionsSlotConfig" type="Product" >
<y:actions xmlns:y="http://www.hybris.com/cockpit/config/hybris">
<y:group qualifiér="common"> 1
| <¥: Label >actiongroup.common</y:
Label> 1
SyTACTTON UCL Ot d=" OG MVORCRIIST OT. CET OM MYA CET Orr -— — 7
property="currentBook" />
</y: group>
</y:actions>
</context>

© SAP SE C4H365 125


Using Actions in Widgets — onActionPerformed — Opt. A

OPTIONAL: You can specify the handler (for an Action’s successful perform() )
from widget's controller via @ViewEvent annotation using onActionPerformed
event name and id of <action> ZUL component
myWidget.zul
<widget ..>

<action id="myActionInstance” property= "product"


actionld= "org. myextension.action.myAction"” />

</widget>

MyWidgetController.java
public class MyWidgetControNer extends defaultWidgetController

@ViewEventCcomponentID="myActionInstance", eventName= “onActionPerformed” )


public void doSomething()
{

Using Actions in Widgets — onActionPerformed — Opt. B


OPTIONAL: You can specify the handler (for an Action’s successful perform() ) from widget’s
controller via @ViewEvent annotation, onActionPerformed event name and id of <actions>
ZUL component
myWidget.zul

<widget ...>
<actions id=' " sclass="yw-actionsSlot"
group= “common” i ig’ />
</widget>
MyWidgetController.java
public class MyWidgetControNer extends défaultWidgetController

@ViewEventCcomponentID=" ", eventName= “ondctionPerformed" )


public void doSomething®) { .. }
myExtension/resources/myExtenstion-backoffice-config. xml
<context component= "myActionsSlotConfig” type= "Product" >
<y:actions>
<y:group qualifier="common">
<y:action action-id= "org. myextension.action.myAction” property="currentBook" />
</y: group>
</y:actions>

126 C4H365 © SAP SE


Using Actions in Widgets — onActionPerformed — Opt. C

= OPTIONAL: You can specify a handler (for a successful Action perform() ) from within widget’s .ZUL file via
the onActionPer formed tag attribute myWidget.zul
<widget ...>

<action actionld= "org. myextenston. action.myAction” property= "product"


onActionPerformed=;"widgetControl
ler. saveProduct()" />
<!-- OR, to bind one handler w for ALC succesful Actions in an <actions> group -->
<actions id= "“myActionsin. aince” _ group= “common” config= "“myActionsSlotConfig"
onActionPerfovmeda “widget Con IsaveProduct()" />
Bees special variable to reference the actual
bound Widget Controller instance
MyWidgetController. java
package my.extensionbackoffice.widgets;

public class MyWidgetController extends DefaultWidgetController {


public void saveProduct() {

33

Creating an Action

© SAP SE C4H365 127


Creating an Action 1 — Definition File

= Definition file:

bookstorecustombackoffice/backoffice/resources/actions/myAction/definition. xml

<action-definition id="org.myextension.action.myaction” ... >


<name>MyAction</name>
<description>mMyAction</description>
<actionCLassName>org .myextension.actions.MyAction</actionCLassName>

<inputT ype>my. bookstore.model .BookModel</inputl ype>


<outputl ype>java. lang. String</outputl
ype>

<iconUri>icons/hwicon. png</iconUri>
<iconHoverUri>icons/hwicon_hover.png</iconHoverUri>
<iconDisabledUri>icons/hwicon_disabled.png</iconDisabledUri>

</action-definition>

Creating an Action 2 — Implementation Class

Action class implements CockpitAction<I, O>


= I specifies the Input type (of data attached to ActionContext)
= O specifies the Output type (of data that will be attached to ActionResuLt)
Seu ciislelemclelar-lWUlkoMmA CLLONRESULt<O> pertorm(ActionContext<I> ctx)

MyAction. java
public class MyAction implements CockpitAction<BookModel, String>
{
@0verride
public ActionResult<String> performCActionContext<BookModel> context)
{
}
}

128 C4H365 © SAP SE


Creating an Action 3 — Obtaining Data

= Action’s attached data can be obtained from its context:

@0verride MyAction. java


public ActionResult<String> perform(final ActionContext|<BookModel> context| )
{
ActionResult<String> result = null;
final| BookModel ctxBook| =| context. getDataQ);
final String bookSummary = generateSummary(ctxBook);
if CbookSummary != null) {
result = new ActionResult<String>(ActionResult.
SUCCESS, bookSummary );
t
else {
result = new ActionResult<String>(ActionResult.
ERROR);
t
Messagebox. show(result.getDataC) + " (" + result.getResultCodeQ) + ")" );
return result;

perform() returns anew ActionResult instance:


- first constructor arg: ActionResult. SUCCESS or ActionResult.£RROR
- second constructor arg: returned (payload) data
37

Editors and Actions Communication

© SAP SE C4H365 129


Socket-Aware Editors & Actions 1 — Definition

= Editor
or Action socket configuration
inside definition.xml1
file
— The XML syntax is the same as that for a widget
— The actual socket-awareness is added in the implementation class

definition.xml
<editor-definition .>
<name>Example Text Editor</name>
<editorClassName>com.my.corp.backoffice.
editors. ExampleEditor</editorClassName>

<sockets>
<input id= "testinput"/>
<output id= "“testOutput "/>
</sockets>
</editor-definition>

Socket-Aware Editors & Actions 2 —- Custom Class

= Backing class must extend AbstractComponentWidgetAdapterAware:

public class ExampleEditor


extends AbstractComponentWidgetAdapterAware
implements CockpitEditorRenderer<Object>

public void render(final Component parent,


final EditorContext<Object> context, final EditorListener<Object> listener)

addSocketInputEventListener("testInput", new EventListener<SocketEvent>()


{
public void onEvent(final SocketEvent event)

label.setValueC"Got " + event.getDataQ) + " from widget " + event. getSourceWidgetIDQ);

+)
‘sendQutput¢ "testOutput", context. getInitialValue());

130 C4H365 © SAP SE


Socket-Aware Editors & Actions 3 — Socket Methods

In the example on the previous slide:

Use addSocketInputEventListener("testInput", new


EventListener<SocketEvent>() {..}) to receive data through input socket

Use sendOutput("testOutput", context. getInitialValue()) to send data through


output socket

Socket-Aware Editors & Actions 4 — Connections

= An action/editor is NOT a widget (it's a component within a widget):


— It has no widget instance ID necessary for a <widget-connection>
— Instead, a “STUB widget ID” is used, formed by prepending the action/editor definition ID with
“STUB_”

<widget-connection
sourceWidgetId= "S7TUB_com. corp. cockpitng. editor.mycustomeredi tor”
outputId= “objectToEdit”
targetWidgetId= "borrowerEditorArea”
inputId= "imputObject" />

— Because this stub ID is based on the action/editor definition ID, an action/editor connection
applies to ALL INSTANCES of the action/editor definition
— Conversely, all widgets that use an instance of this action/editor will get the same
communications behavior from this Action/Editor

© SAP SE C4H365 131


Socket-Aware Editors & Actions 5 - Component Holder

The Application Orchestrator’s eon _ Ladle


Component Holder: ------------------------- > (0) [inet 7X) [omtontmatias 7 @ OX
(click on it to reveal contents) ~ .
= Holds all actions/editors that are lesen 2aex
“socket-aware” +
| — 7
;
|__| lmase Cropper oa @x
z
User Profile Setting
Widget 7G @ ex

Socket-Aware Editors & Actions 5 - Component Holder

= The Application Orchestrator’s cn $B cn eine tas


Man Layout
Badkotice FX Geete Boomaknnaer 9 PX
Component Holder: lalate elaiaiataheeine coronene == Pry" «os
Excel Export Action roo

(expanded — click to close) 3 oe :


« There is only one visual — ° | +
representation of a socket-aware ; ae sow 8 x
action/editor for all instances, due to veovaanen 8 .
the “STUB widget ID” ~aeee eee
=NOTE: An action/editor is ONLY 7 CT
able to connect -
to a widget instance :

132 C4H365 © SAP SE


Oren
= Editors and actions are special components in widgets

= There are a number of OOTB editors and actions

= Acustom editor contains


» definition.xml with meta information
» either a renderer class implementation or a zul file as the view.

= When developing a custom action, we need to


» provide definition.xml with meta information
» Implement the action class to perform logic with the underlying services

= Socket is supported in the development of editors & actions, but the actual socket
communication is class level rather than instance level.

AS

Exercise 8 — Create Custom Editors and


Actions

© SAP SE C4H365 133


Exercise 8 — Create Custom Editors and Actions

{. Create a custom editor for the publisher attribute


— Validates the input text
— Saves only if the input is validated
— Gives a warning if numeric values are typed in the field

2. Create an action to toggle the rentability of a book


— Books are by default not rentable
— Create a button in the Book Details widget that switches the rentability status

INTERNAL SAP and Parners Only 47

SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

134 C4H365 © SAP SE


SAP Customer Experience

Backoffice Testing Framework

INTERNAL — SAP and Partners Only

We will learn about:

> How to write unit tests for widget

> How to write unit tests for actions & editors

INTERNAL SAP and Partnors Only 2

© SAP SE C4H365 135


Introduction

Overview

= Supports testing of your custom widgets, editors, and actions

= Supports unit testing

= Based on JUnit

* Supports mockite
= Framework-specific configurations using annotations provided by Backoffice

= Supports integration and black-box testing (using the Breadboard Widget)

= Provides OOTB tests for widget definitions, boundaries, and some code compatibility checks (e.g.
existence of an editor’s no-arg constructor)

INTERNAL SAP and Partnors Only 4

136 C4H365 © SAP SE


Unit Testing Widgets

Unit-Testing Widgets

= Unit test should extend AbstractWidgetUnitTest, which helps to write black


box tests of two flavors:

— Test interactions with input and output sockets

— Test interactions with UI elements

= Intended for TDD - Write the tests and then test the widget

= When the declaration in the test becomes inconsistent with the widget definition,
the test will fail

= Encourages good practices such as using global constants for socket names.

© SAP SE C4H365 137


AbstractWidgetUnitTest

"AbstractWidgetUnitTest provides tests checking consistency between the test


declaration and the implementation of the following elements
—Sockets
—Commands
—View events
— Global events
—Null-safe check
° Executed against all declared inputs of the widget
° Checks for input parameters with null or default values
° For primitives, it checks some default values, like @ for int
° For non-primitives, the default value is the instance created by the no-arg constructor, if one exists
—Extensible fields check
° Checks if all the fields/attributes in a widget would be accessible by its inheriting children
° For all fields either declared protected or with a getter method associated with them

Unit-Testing Widgets

Extend AbstractWidgetUnitTest<WidgetController>

DemoWidgetTest. java
public class DemoWidgetTest extends
AbstractWidgetUnitTest<DemoWidgetController>
{
private final DemoWidgetController controller = new DemoWidgetControllerQ);

@0verride
protected DemoWidgetController getWidgetController()
{
return controller;
}
}

138 C4H365 © SAP SE


Annotations

Annotations

= Annotations provide fixture declarations of specific Backoffice runtime elements (View, Socket, Global)

= @DeclaredInput, @DeclaredViewEvent, @DeclaredGlobalCockpitEvent, @NullSafeWidget

@DeclaredInputCvalue = DemoWidgetController.IN_SOCKET, socketType = String.class)


= When having more than one: @DeclaredInputs, @DeclaredViewEvents,
@DeclaredGlobalCockpitEvents

@DeclaredInputs(value = {@DeclaredInput(value = ..), @DeclaredInputCvalue = ...)})


= When using Mockito, typically you @Mock your Service and View elements and @InjectMocks your
Controller

© SAP SE C4H365 139


Summary of Major Annotations

@DeclaredInput Describes a single input socket of the tested widget.


For example: @Declaredinput(value = "socketld", socketType = String.class)
@DeclaredInputs Aggregating annotation for @Declaredinput
@DeclaredViewEvent Describes a single view event of the tested widget.
For example: @DeclaredViewEvent(componentID = "componentid", eventName
= Events.ON_CLICK)
@DeclaredViewEvents Aggregating annotation for @DeclaredViewEvent.
@DeclaredGlobalCockpit Describes a global event handled by the tested widget.
Event For example: @DeclaredGlobalCockpitEvent(eventName="eventName",
scope="scope")
@NullSafeWidget Describes whether or not input socket support null parameters
For example: @NullSafeWidget(true)

Widget Behavior Testing

140 C4H365 © SAP SE


Widget Behavior Testing

= Simulate interactions with the widget


— execute widget methods
-— assertSocketOutput() G The most popular simulated interactions include:
— assertValueSet() * executeViewEvent
— assertValueNotNull() * executelnputSocketEvent
. Example: * executeGlobalEvent

— Simulate a click on the Last Size Button

— Test that the expected output on the Size output socket is 0

Widget Behavior Testing - Examples

—Send String "dot .separated.string" as an input on widget’s input socket

executeInputSocketEventCDemoWidgetController. IN_SOCKET, “dot.separated.string");

—Expected socket output as array of 3 strings — "dot", "separated", "string"


assertSocketOutput(DemoWidgetController. OU7T_SOCKET,
Lists. newArrayListC"dot", "separated", “string"));

—Expected model variable, lastResultSize, has value of 3


assertValueSet(DemoWidgetController. LAST_RESULT_SIZE, Integer. valueOf(3));

© SAP SE C4H365 141


Widget Behavior Testing - Examples
@Test
public void testSocketAndViewEvent()
{
executeViewEvent(DemoWidgetController. /AS7_SIZE_BUTTON_ID, Events. ON_CLICK);
assertSocketOutput(DemoWidgetController. SIZE_SOCKET, Integer. valueOf(@));

executeInputSocketEventCDemoWidgetController.
JN_SOCKET, “dot.separated.string");
assertSocketOutput(DemoWidgetController.
OU7_SOCKET,
Lists.newArrayListC"dot", “separated", "“string"));
assertValueSet(DemoWidgetController. /AS7_RESULT_SIZE, Integer.valueOf(3));

executeViewEvent(DemoWidgetController. /AS7_SIZE_BUTTON_ID, Events. ON_CLICK);


assertSocketOutput(DemoWidgetController.
SIZE_SOCKET, Integer.valueOf(3));

Action and Editor Testing

142 C4H365 © SAP SE


Action and Editor Testing

Extend AbstractActionUnitTest to test Actions

Extend AbstractCockpitEditorRendererUnitTest to test Editors

OOTB both of these provide:


= no-arg constructor checks
= null safety test

: Backoffice testing is based on JUnit and Mockito

: Widget test class should extend AbstractWidgetUnitTest, which provides basic testing facilities,
such as checking the consistency between test declaration and widget implementation, simulating
interaction with widget, etc.

= Action/Editor testing should extend AbstractActionUnitTest and


AbstractCockpitEditorRendererUnitTest, which also provide basic testing functions.

© SAP SE C4H365 143


Exercise 9 — Test Your Widget

Exercise 9 — Test Your Widget

= Complete the basic implementation of a widget controller’s test class that


extends AbstractWidgetUnitTest<>

= Write a unit test that checks for the correct behavior of the controller after
receiving a book as input

ERNAL SAP and Partnors Only 2t

144 C4H365 © SAP SE


SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

SAP Customer Experience

Good to Know

INTERNAL — SAP and Partners Only

© SAP SE C4H365 145


We will learn about:

> Some special widgets in Backoffice, such as


> saved queries list widget
>» home dashboard & ZK charts
> perspective container widget

>» What are authority groups

> How to use dynamic forms

>» The localization support in Backoffice

> Use CSS or SASS to define new or replace existing Backoffice styling

INTERNAL SAP and Parners Only

Saved Queries

146 C4H365 © SAP SE


Saved Queries

= The Saved Queries List Widget lets you save Saved queries Queries Filter
advanced queries.
Craftsman

List of Saved
— Its Query Filter facilitates filtering of the listed jeans
Advanced Search
queries
Queries
Clothing online
— You can also share saved queries with other
users or user groups
— Pressing the Save button in the Advanced
Search Widget generates a Saved queries
BackofficeSavedQuery instance, which is
passed to the List widget. J Filter Box

Shared Show Shared Queries


Tick Box
Jeans Filtered List

INTERNAL SAP and Parners Only

Home Dashboard & ZK Charts

© SAP SE C4H365 147


Building a Dashboard - 1

Run garbage collection action ] Edit mode: allows moving the widgets
Dashboard Home Simple Chart Widgets Refresh ———]
Finer
ee (tn fr options) Home c ep (&)

[@ =~ Memory verew
o .
Don “
@ caviog

wan When the default Home node


“ in the Explorer Tree is
Grate selected in the OOTB
oe configuration, you see the
A Marieng
Dashboard.
Pending Tasks Overview

It, too, is a widget and, in turn,


contains a set of Chart
Widgets.
Tiesame

INTERNAL SAP and Partnors Only 6

Building a Dashboard - 2

ZK Charts
myextension-backoffice-widgets.
xml

<widget id= “my_dashboard" widgetDefinitionld= "com. hybris. cockpitng. dashboard"


slotid="“some_slot” template="false’>
<widget id= "childWidget1" widgetDefinitionld= “sample.widgets.id”
slotIid= “dashboardWidgets" template= "false">
<!-- widget's setting -->
</widget>
<widget id= "childWidget2" widgetDefinitionld= “sample.widgets.id"”
slotIid= “dashboardWidgets" template= "false">
<!-- widget's setting -->
</widget>
<!-- and so on -->
</widget>

INTERNAL SAP and Partnors Only 7

148 C4H365 © SAP SE


Building a Dashboard - 3

If you want to configure the layout of the grid, you have to provide a configuration
for the dashboard component:
myextension-backoffice-config. xml

<context component= “dashboard'>


<dsb:dashboard defaultGridId="regular">
<dsb: grid minScreenWidth="0" maxScreenWidth="700" id="smaLL" rowHeight="250">
<dsb:placement widgetId="“childwidgeti" height="1" width="1" x="9" y="0"/>
<dsb: placement widgetId="childwWidgetN" height="1" width="1" x="9" y="1"/>
</dsb:grid>
<dsb:grid minScreenWidth="701" id="regular” unassigned="“append”>
"
<dsb: placement widgetId="“childwidgetN" height="1" width="2" x="9@" y="9"/>
<dsb: placement widgetId="“childwWidget2" height="1" width="1" x="9" y="1"/>
<dsb: placement widgetId="“childwWidgeti" height="1" width="1" x="1" y="1"/>
</dsb: grid>
</dsb:dashboard>
</context>
INTERNAL SAP and Parners Only

Switching Perspectives

© SAP SE C4H365 149


Switching Perspectives

= ISAPA Administration Cockpit ~


= The Perspective Container widget can contain multiple Home
(perspectives) widgets
@_ Home
Task Queue Overview
= The nodes in the Explorer Tree widget can be (4 inbox

associated with different perspectives system >

@ Catalog >
= Like in the Administration cockpit:
(Q_ Muttimedia >

Number
— Clicking on the “Home” node displays the dashboard

°
& User >
— Clicking on any other node, displays the Collapsible
Container that contains Advanced Search, etc. (3 order >

Price Settings >


18:00 20:00
© _intemationatization >

Marketing >

FS Base Commerce >

INTERNAL SAP and Parners Only

Perspective Switching Mechanism

= Acommunication channel must be set up in between the Explorer Tree and the Perspective
Container widgets
= The Perspective Container widget has an input socket called selectPerspectiveBylId
= Through this socket, other widgets can switch the perspective
= Two adapter widgets are used to decide which perspective should be displayed

interaction Backoffice Cockpit y


ae 2
oe . “Bo.
oe : Property 2 sen °
oo ot
vos Extractor Naps Bey
ot — Con...
apy
ae’ Ssip
1: send node

__
:Explorer :Condition :Perspective
Tree Evaluator Container
2.A [node Home]: send Dashboard node

INTERNAL SAP and Parners Only

150 C4H365 © SAP SE


Authority Groups

Authority Groups

So CC B & te) = Users are assigned different Backoffice Roles,


e.g. Product Manager, Translator
Backoffice Administrator Role
—————— r — Such roles can be combined into
Authority Groups

= You can restrict visibility of a specific instance of a


‘<<primitives>] 1 currentUser
User widget for certain users, user groups, or roles
<eprimitives> ] 0..* access
Autho: — ABackoffice cockpit will then show a different
application mash-up to different business users
— <widget ... access="role_B, role_C" />
‘| activeAuthGroup

= You can apply context-based widget configuration


based on a single user, user group, or role
[Cockpitwidgetengine
ters the widget tree by — <context ... principal="role_B" />
matching authorities
defined at a widget
fagainst authorities from
jactive authority group. = There can only be one active authority group at a
time in a given Backoffice application.
14

© SAP SE C4H365 151


Dynamic Forms

Dynamic Forms - 1

Dynamic Forms enable an element of responsiveness within form segments

They work with Editor Area and Wizard widgets

Prices n

Prices@ Min order quantity Max order quantity


+ Create Price Row oe ld 15

Price quantity Price Class @

1 v

Here, the Price quantity field is disabled if the value of Min order quantity is greater than 5 or
if the value of Max order quantity is less than 15.

152 C4H365 © SAP SE


Dynamic Forms - How are they configured?

cockpit-config.
xml
<context type= “Book” component= “edi torAreaDynamicForms" ...>
<df:dynamicForms ...>
<df:attribute id= “unigqueld"
triggeredOn= “*"
qualifier= “priceQuantity"
disabledlIf= "(minOrderQuantity &gt; 5 //
maxOrderQuantity &lt; 15)" />
</df:dynamicForms>
</context>

Localization

© SAP SE C4H365 153


Application and Component Localization

Application String Localization


= Backoffice framework decorates the ZK Labels utility

= com.hybris.cockpitng.util.1labels.WebappLabelLocator implements ZK’s LabelLocator


= LabelService interface’s getObjectLabel(...) method retrieves the appropriate label

= Localization files are stored by convention:

a Widgets myextension/backoffice/resources/widgets/mywidget/labels

Editors myextension/backoffice/resources/widgets/editors/myeditor/labels

Actions myextension/backoffice/resources/widgets/actions/myaction/labels

= Custom localization files locations can be defined by a


com.hybris.cockpitng.util.labels.ResourcesLabelLocator bean

Localization Files

Widget String Localization via Standard Java Resource Bundles

= Location and naming of file group (a.k.a. resource bundle)


— myextension/backoffice/resources/widgets/myWidget/labels
— Default labels and catch-all (also, the base name): labels.properties
— Language-specific overrides: labels_xx.properties
(where xx is the language ISO code)
QO) Ex: labels_es.properties for Espafol (i.e., Spanish)
O) Ex: labels_de.properties for Deutsch (i.e., German)
— WidgetInstanceManager interface can utilize getLabel(String key)
OU Delegates to LabelService

20

154 C4H365 © SAP SE


Localization Usage

= From within ZUL file:


<button id="sendBtn" label="$flabels. button}" />

= From within Widget controller:


—Via WidgetInstanceManager

String widgetName = getWidgetInstanceManager().getLabelCWIDGET_NAME_LABEL);


* ...0r via widget's convenience method):

String widgetName = getLabelCWIDGET_NAME_LABEL);

—Editor and Action controllers can use the getLabel() method of the EditorContext and
ActionContext classes, respectively

21

Styling Components

© SAP SE C4H365 155


Styling Components

» Use CSS
= Based on ZK
= ZK Java API or inside .zul view files: sclass property

= Actions: change icons inside definition file

<action-definition ...>

<iconUri>images/icon. png</iconUri>
<iconHoverUri>images/icon_hover.png</iconHoverUri>
<iconDisabledUri>images/icon_disabled.png</iconDisabledUri>
</action-definition>

Styling Components

ZK Java API
BookDetailsController.
java

final Div div = new DivQ);


div.setHeightC"100%");
div.setSclassCCSS_CLASS_IMAGE_DIV_LEFT);

Inside .zul view files


bookDetails.zul
<style src="$fwr}/styles.css"/>
<div id="bookDetailContainer" sclass=" yw-bookdetail-container"/>

156 C4H365 © SAP SE


An Alternative to CSS - Sass

= Backoffice provides support for Syntactically Awesome Style Sheets (Sass)


scripting language, a CSS preprocessor that gives better experience in styling
your application.

= Fully CSS-compatible

= Language extensions such as variables, nesting, and mixins

= Many useful functions for manipulating colors and other values

= Advanced features like control directives for libraries

= Well-formatted, customizable output

Enabling Sass Support

= Add the npmancillary extension to your SAP Commerce Cloud platform


—Add it to localextensions. xml
—Contains NodeJS and all necessary Grunt libraries for Sass support
= Set backoffice.sass.enabled to true in the Commerce platform’s
local.properties
local. properties
backoffice.sass.enabled=true

= Restart the Commerce server


—The resources are cached by the server by default
—You can disable caching by adding the following line to your local.properties

local.properties
backoffice. cockpitng. resourceloader. resourcecache.enabled=false

© SAP SE C4H365 157


Registering a Sass Extension

|. When creating an extension using ant extgen, and ybackoffice as the


template...
-— You're asked "Register as a SASS extension?"
— You should type in true

2. Or, if you haven’t registered it as a Sass extension,


— Add the following block to the extension’s buildcallback.
xml
custombackoffice/buildcallback.
xml
<macrodef name= “custombackoffice_before_but
ld'>
<sequential>
<register_sass_extension extensionname= “custombackoffice"/>
<register_sass_extension extensionname= “custombackoffice”
resources= “resources” destination=""/>
</sequential>
</macrodef>

Override Default Styles of Backoffice Application

= It is possible to replace the standard look and feel of the Backoffice Application.
— Create a custom Backoffice extension
— Use Sass and SCSS or CSS to style Backoffice application
— Add related properties to the project.properties file of your custom extension

custombackoffice/project. properties

backoffice. cockpitng.matnpage.css=/cng/css/mainpage_whiteLlabel.css
backoffice. cockpitng. Loginpage. css=/cng/css/Loginpage_whiteLabel.css
backoffice. cockpitng.overridewidgetsandeditors.css=/cng/css/mywidgetseditors.css

158 C4H365 © SAP SE


= Saved Queries List Widget enables easy access to custom search queries for items.
= Home Dashboard widget is a generic container for widgets to show ZK charts with statistics of the
running system.
= Perspective Container widget can contain multiple perspectives, which can be associated with
explorer tree nodes
— By clicking explorer tree, different perspectives can be switched
= By using authority groups, we can restrict visibility of widgets for specific user role
= Dynamic forms provide form-based flexibility in Backoffice.
= Localization support can adapt Backoffice UI to multiple languages.
= CSS and SASS enable easy and flexible customization of the stylings of Backoffice

SAP Customer Experience

Thank you.

©2023 SAP SE or an SAP affiliate company. All rights reserved. Soe Legal Notice on wa". sap comilegal-notice for use terms, disclaimers, disclosures, of restrictions relate’ to SAP Materials for genoral audiences

© SAP SE C4H365 159

You might also like