C4H365 EN Col24
C4H365 EN Col24
C4H365
Material Number: 50163526 SARA
Col24
Some Necessities
= Participant List
= Course Material
© SAP SE C4H365
Training Overview
Personal Introduction
Role Spring/JEE
Project Experience
Company
Previous SAP
Commerce Cloud
Hobbies Experience, incl.
Cockpit /
Backoffice
2 C4H365 © SAP SE
Training Content — Theory + Practice
= 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
= SAP Commerce Cloud Platforms & Basics — for those, please check out:
— Either SAP Commerce Cloud Developer Training, Part | and Part Il (C4H340 & C4H341)
— 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
© SAP SE C4H365
Training Environment Intro OES Sune SEE
x
© Recent = = a= =
vm Videos
= 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
4 C4H365 © SAP SE
What you will learn
= Connect widgets
= Define a context configuration for your widget and use the merge capability
9:00 4. Introduction
Lunch
4. Orchestrate A Cockpit
© SAP SE C4H365
Working Hours — Day 2
6. Widget Communication
12:30
Lunch
Lunch
6 C4H365 © SAP SE
Exercise 1 — Class Setup
© SAP SE C4H365 7
SAP Customer Experience
Thank you.
8 C4H365 © SAP SE
We will learn about:
Cockpits/Perspectives
Vv
Application Orchestrator
Vv
© SAP SE C4H365 9
Backoffice Fundamentals Refresher - Architecture
Backoffice Framework
3rd Party i
Widgets i Core Backoffice Framework
10 C4H365 © SAP SE
Backoffice Fundamentals Refresher - Technologies
Technologies used i)
spring LXML
dy « ©
# <I>
JAXB
« platformbackoffice extension
— Provides some of the editors and actions that enable you to manage SAP Commerce Cloud
© 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
ant all
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 - |
© SAP SE C4H365 13
Precedence of Application Configuration (*-widgets. xm1)
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
14 C4H365 © SAP SE
Precedence of UI Context Configuration (*-config.xm1)
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.
() & 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
© SAP SE C4H365 15
UI Context Configuration * ExplorerTree
Book
<context
component="bb-explorer-tree">
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
Image Description ©
® 300Wx300H/chicken-or-egg.png - Bookstore Product Catalog :... 20
© SAP SE C4H365 17
Widgets
= MVC-based
= Specific purpose
= Highly composable
= Highly connectable
22
Widgets
Backoffice Business Application
23
18 C4H365 © SAP SE
Actions & Editors
= Actions
— Used to trigger CRUD operations on objects or to trigger method calls in widget controllers
@&_ Permission settings: Manage type- and attribute-based permissions per Principal
= 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.
© SAP SE C4H365 19
Cockpits
Cockpit Concept
» What is a cockpit?
_= SAF
. A
acialaienen
ministration
—
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
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
‘Show cockpit-config.xml
AO Menu
pectives]
< ™ adminarea Kpit. ame tt »name >
cockpitWidgetChildrenInvisible Slot
Select Authority Group v Loy ‘symbolic widgets {_] Showslotids {—) Showconnections 2) Widget Clipboard i=
Editor Area o @x
as
Reference Advanced
Search Group a @ x
as
Image Cropper 2 @ x
as
22 C4H365 © SAP SE
Demo
= You can also visually configure Backoffice UI widgets using the Application Orchestrator
© SAP SE C4H365 23
Exercise 2
Administration Cockpit
Book Management
35
24 C4H365 © SAP SE
|. Create a New Extension
$ ant extgen
Flexible Layout
View Switcher
[views]
[untitled] _ collaboration.container
[perspectives]
admin.area Book or
Border Layout
leftSlot + centerSlot
© SAP SE C4H365 25
ll. Create a New Cockpit e 2
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
> Development Support (Breadboard Widget, Caching, Configuration Reset, Hot Deployment)
© SAP SE C4H365 27
Environment Set Up
Use an IDE
= Here, we are using Eclipse IDE for Enterprise Java __\ ec|| Se
and Web Developers =f
28 C4H365 © SAP SE
Set Up Ant
= (Optionally) In Eclipse, point the Ant class path to the one that comes with the platform
-${HYBRIS_BIN_DIR}/platform/apache-ant-*
wf ( wh
Development Support
© SAP SE C4H365 29
Development Support: Overview
Breadboard Widget
Breadboard
30 C4H365 © SAP SE
Demo — Breadboard Widget
2,987.26
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!
${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
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
32 C4H365 © SAP SE
Development Support - Resetting Backoffice Configuration (Auto-Triggered)
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
- After restarting the system, three new buttons appear in the Backoffice app
Reset Everything ——— p—— Reload Localization Labels
© SAP SE C4H365 33
Development Support - Using the Redeploy Backoffice Extentions Button
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)
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
@+.
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
© 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
‘|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
— Disabling Caching of Components and Controllers to quickly and conveniently see your changes to
component views
— 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
= Disable caching
Thank you.
38 C4H365 © SAP SE
SAP Customer Experience
Orchestrate a Cockpit
© SAP SE C4H365 39
Orchestration Overview
What is Orchestration?
= Integration approach that allows for decoupling applications and software components
= building out one or more business processes by adding and connecting widgets (through
Application Orchestrator or through widgets. xml)
40 C4H365 © SAP SE
Steps to Orchestrate a 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
< Categories
Choose widget x
[views] +
[untitled] _ collaboration.container
[perspectives] +
admin.area Book izati ive.narie [i
< > 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
Close
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>
</widget>
</widgets>
INTERNAL SAP and Partnors Only 10
© SAP SE C4H365 43
A Short Detour: Common Layout 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
44 C4H365 © SAP SE
Collapsible Container Widget
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
© SAP SE C4H365 45
Split Layout Widget
‘Split Layout
[children] +
‘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)
= Based on setting, can also render Chat Code Editor Example Title
contained widgets as: —
— portal Chat GR 2 x
— list
= Settings
— type
46 C4H365 © SAP SE
Complex Cockpit Layouts
bottom +
Rattam Cantian
bottom
© 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
IS
@ Home
{4 Inbox
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
" 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
» autoSortEnabled expandeditemsAfterFilterSoftLimit: 15 = x
. explorerTreeConfigCtx: explorer-tree ,*
Add Setting
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>
</widget>
</widgets>
© SAP SE C4H365 49
Step 3: Connect the Widget Instances
Communication in Backoffice
24
50 C4H365 © SAP SE
Step 3: Connect the Widgets
reset out
Type: java.util.Map
© 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
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 ...>
</widget>
Invisible Widgets
[cockpitWidgetChildrenInvisible]
© SAP SE C4H365 53
Application Orchestrator — Symbolic View
pa Collection Browser
31
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’ <
Title: "How to Make Friends and Infuriate People" - Bookstore Product Catalog : Staged ay
Go @ 7 v
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]
“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.
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 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
© SAP SE C4H365 57
Exercise 4 — Orchestrate a Cockpit
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
Anenpreparation, three Q RB
main widgets added:
¥ Book Management Tree sell @v fz &
‘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
40
58 C4H365 © SAP SE
Exercise 4 — The End Goal
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
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
> The communication among widget models, widget view files and widget controllers.
60 C4H365 © SAP SE
Creating a Widget
What is a Widget?
© SAP SE C4H365 61
Widget Definition and Widgets
parent Q..1
WidgetDefinition
-id : String
-name : String 1
-id : String
-controller : String
-slotId : String
-viewURI : String
-inputs : List<WidgetSocket>
-outputs : List<WidgetSocket>
Widget Communication
L Widget WidgetDefinition
1
1 1 1
source inputs outputs
* * *
WidgetConnection WidgetSocket
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
definition.xml Example
© 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
64 C4H365 © SAP SE
UI Framework
POWERED
© SAP SE C4H365 65
ZUL Schema
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}"/>
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
Note that no mutator (setter) method is necessary. The value gets set automatically by the
Backoffice Framework. 15
© SAP SE C4H365 67
ZUL Playground Widget
Reset
code
button
For more information on how to use this widget, refer to this page on the SAP Commerce Help:
68 C4H365 © SAP SE
Custom Widget Controller
= Extend DefaultWidgetController
MyChatController.java
widgetInstanceManager. getWidgetSettings().getBooleanC"online");
@SocketEventCsocketId = "incomingMsg")
public void receiveMsg(final String msg)
lastMsgLabel.setValue(msg);
}
© SAP SE C4H365 69
Accessing the Settings
<settings>
<setting key="mySetting” type="Java.
lang. String” default-value= "123"/>
</settings>
</widget-definition>
22
70 C4H365 © SAP SE
Changing Widget Model
Widget Model
24
© SAP SE C4H365 71
Widget Model, cont.
model.setValueC"product.code", “product_1234");
25
72 C4H365 © SAP SE
Backoffice Application Context
@WireVariable
protected BackofficeBookstoreService backofficeBookstoreService;
© 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
29
74 C4H365 © SAP SE
Exercise 5 — Create a New Widget
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
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")
sendOutputC"outgoingMsg", entry);
© SAP SE C4H365 77
Adding Input Sockets
Input Sockets
= Inthe definition. xml, define a sockets element with one or more child input elements
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
© SAP SE C4H365 79
Output Sockets
= Indefinition.xml, define a sockets element with one or more child output elements
definition.
xml
<widget-definition ...
<sockets>
</widget-definition>
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
80 C4H365 © SAP SE
Connecting Sockets
© SAP SE C4H365 81
Connecting Using Application Orchestrator, cont.
Connections (*-backoffice-widgets.xm1l)
widgets. xml
<widgets>
</widgets>
82 C4H365 © SAP SE
What if socket types don’t match?
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
4. Adjust the socketDataType_$T setting, if the source widget’s socket type is of the generic
type <T>
Adapter Widgets
© SAP SE C4H365 83
Adapter Widgets e Where should they go?
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
inputObject
Collection semen ne cememeecememeneeeee C) Editor Area
Browser
selecteditem
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
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
23
© SAP SE C4H365 87
Global Events — Annotation
= 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
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;
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
= Awidget can respond to actions on the Ul components in the widget controller via
» Wiring UI components
» Using @ViewEvent
© SAP SE C4H365 89
Exercise 6 — Connect Your Widgets
| Glick to zoom!
= Can handle updates and deletions, and in le: The Chicken or Egg Dilemma -
Cracked
90 C4H365 © SAP SE
1. Look at the Existing Socket Handler
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);
}
—Widget definition
© SAP SE C4H365 91
3. Connect Through an Adapter
92 C4H365 © SAP SE
SAP Customer Experience
Thank you.
© SAP SE C4H365 93
We will learn about:
> How to define a new configuration type based on XSD and JAXB
Backoffice Context
94 C4H365 © SAP SE
Flashback!
Aybris
All in One
Validity Period a Authors: Carsten Joch
ISBN13: 33355361520
Rentable?: false
Online from Online to
a 8 a
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
© SAP SE C4H365 95
Backoffice Context Configuration — Recap
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... &
96 C4H365 © SAP SE
Context Configuration Precedence
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
Commerce
Platform
= Widgets Search — = Widgets
Backoffice
Backoffice
Module + Module Module
Backoffice cockpit-config.xml
Application
© SAP SE C4H365 97
Context Configuration - Data Types
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
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
7
coe
Boing fs.
P huspewwnunyerie.cor/cocksitfe nase.xed
= 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>
= 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>
Generate XML
tree.xsd
LI
<xs:schema ...>
<xs:element name= "tree’>
2. Call getWidgetInstanceManager().loadConfiguration()
</context>
TreeController.java
rc
oo EXPLORER v
<widget ...>
<panel ...>
<caption ...> © Home
<div>
& Inbox
> system
22
> Catalog
—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)
shoestorebackoffice-backoffice-config.xml
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
= Useful and fast way to test your widget’s context Reset to Defaults
configuration
Show cockpit-config.xml
Reset to Defaults
Reset Everything
31
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
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
= 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
= 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
Take advantage of the power that context configuration gives you by:
It should specify the sequence of Book properties that you would like
the widget to display, but only when viewing a Book.
= 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.
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.
6 68 . + Refresh
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
Reuse Product type’s configuration in the Admin cockpit to improve the Book type’s editor view in the
Book Management cockpit.
G © Refresh
Essential n
Validity Period n
6 6
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
Introduction
"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
= Actions and Editors are not socket-aware, but they can be made socket-aware using STUBS (This will be
discussed later)
en | }
es_CO
pt
New Password
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
myWidget.zul
<widget ..>
</widget>
myWidget.zul
<widget ..>
</widget>
Editors in Widgets
= 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 " [>
= 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)
= 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>
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" >
myWidget.zul
<widget ..>
</widget>
myWidget.zul
<widget ..>
</widget> [ 7 |
myWidget.zul
<widget ..>
</widget>
MyWidgetController.java
public class MyWidgetController\extends DefaultWidgetController
Creating an Editor
= 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>
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);
= 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
= Create Action: + ()
¥ Product
Book
= Delete Action: w
26
Actions in Widgets
= 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 ..>
</widget>
MyWidgetController. java
WidgetModel model = getModel();
model.putC"product", product);
MyAction. java
public ReturnType everyActionMethod ( ActionContext<ProductModel> ctx ) {
ProductModel boundProduct = ctx.getData();
</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>
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 ..>
</widget>
MyWidgetController.java
public class MyWidgetControNer extends defaultWidgetController
<widget ...>
<actions id=' " sclass="yw-actionsSlot"
group= “common” i ig’ />
</widget>
MyWidgetController.java
public class MyWidgetControNer extends défaultWidgetController
= 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 ...>
33
Creating an Action
= Definition file:
bookstorecustombackoffice/backoffice/resources/actions/myAction/definition. xml
<iconUri>icons/hwicon. png</iconUri>
<iconHoverUri>icons/hwicon_hover.png</iconHoverUri>
<iconDisabledUri>icons/hwicon_disabled.png</iconDisabledUri>
</action-definition>
MyAction. java
public class MyAction implements CockpitAction<BookModel, String>
{
@0verride
public ActionResult<String> performCActionContext<BookModel> context)
{
}
}
= 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>
+)
‘sendQutput¢ "testOutput", context. getInitialValue());
<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
= Socket is supported in the development of editors & actions, but the actual socket
communication is class level rather than instance level.
AS
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
Overview
= Based on JUnit
* Supports mockite
= Framework-specific configurations using annotations provided by Backoffice
= Provides OOTB tests for widget definitions, boundaries, and some code compatibility checks (e.g.
existence of an editor’s no-arg constructor)
Unit-Testing Widgets
= 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.
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;
}
}
Annotations
= Annotations provide fixture declarations of specific Backoffice runtime elements (View, Socket, Global)
executeInputSocketEventCDemoWidgetController.
JN_SOCKET, “dot.separated.string");
assertSocketOutput(DemoWidgetController.
OU7_SOCKET,
Lists.newArrayListC"dot", “separated", "“string"));
assertValueSet(DemoWidgetController. /AS7_RESULT_SIZE, Integer.valueOf(3));
: 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.
= Write a unit test that checks for the correct behavior of the controller after
receiving a book as input
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
Good to Know
> Use CSS or SASS to define new or replace existing Backoffice styling
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
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
Building a Dashboard - 2
ZK Charts
myextension-backoffice-widgets.
xml
If you want to configure the layout of the grid, you have to provide a configuration
for the dashboard component:
myextension-backoffice-config. xml
Switching Perspectives
@ 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 >
Marketing >
= 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
__
:Explorer :Condition :Perspective
Tree Evaluator Container
2.A [node Home]: send Dashboard node
Authority Groups
Dynamic Forms - 1
Prices n
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.
cockpit-config.
xml
<context type= “Book” component= “edi torAreaDynamicForms" ...>
<df:dynamicForms ...>
<df:attribute id= “unigqueld"
triggeredOn= “*"
qualifier= “priceQuantity"
disabledlIf= "(minOrderQuantity > 5 //
maxOrderQuantity < 15)" />
</df:dynamicForms>
</context>
Localization
a Widgets myextension/backoffice/resources/widgets/mywidget/labels
Editors myextension/backoffice/resources/widgets/editors/myeditor/labels
Actions myextension/backoffice/resources/widgets/actions/myaction/labels
Localization Files
20
—Editor and Action controllers can use the getLabel() method of the EditorContext and
ActionContext classes, respectively
21
Styling Components
» Use CSS
= Based on ZK
= ZK Java API or inside .zul view files: sclass property
<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
= Fully CSS-compatible
local.properties
backoffice. cockpitng. resourceloader. resourcecache.enabled=false
= 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
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