The APS UI navigation tree is declared in Metadata Descriptor (APP-META.xml) as illustrated here.
In this document:
The attributes described in this section are applicable to all navigation elements.
IDs used in navigation elements must comply with the following regex patterns.
General requirement:
[a-zA-Z_\-][a-zA-Z_0-9\-]*
For a Single Page Application used in UX1:
[a-z][a-z0-9\-]*
Optionally, a navigation element can declare a privilege that users must obtain to have access to this element.
This privilege is declared by the shown-by-privilege
attribute as in the followings example, where
the top-level element (<navigation>) does not have an explicit declaration of an access privilege, and its child elements
require different access privileges:
<navigation id="navigation-without-privilege" label="Navigation wo privilege">
<plugs-to id="http://www.parallels.com/ccp/2"/>
<item id="item-wo-privilege">
<view id="view-wo-privilege" src="ui/view11.js"/>
<view id="view-with-privilege-1"
src="ui/view12.js" shown-by-privilege="privilege-1"/>
</item>
<item id="item-with-privilege-1" shown-by-privilege="privilege-1">
<view id="view-under-item-with-privilege-1" src="ui/view21.js"/>
<view id="view-with-privilege-2-under-item-with-privilege-1" src="ui/view22.js"
shown-by-privilege="privilege-2"/>
</item>
</navigation>
In accordance with the above declaration, the views are protected as follows:
The platform’s built-in UX1 Navigation Element Implicit Access
privilege grants access to view11.js
because neither this view nor its parents have an explicit declaration of
an access privilege.
The users granted both UX1 Navigation Element Implicit Access and privilege-1 privileges additionally have
access to view12.js
(this view requires privilege-1) and view21.js
(this view does not require an explicit
privilege, but its direct parent requires privilege-1).
The users granted UX1 Navigation Element Implicit Access, privilege-1, and privilege-2 privileges
additionally have access to view22.js
(this view requires privilege-2, and its direct parent requires
privilege-1).
For more details, see the Navigation Element Access Management document.
A platform user panel must have at least one placeholder for embedding APS UI navigation trees. The following placeholders are predefined in CP:
http://www.aps-standard.org/ui/application
is used to expose an APS navigation tree to the provider.
In OSS, it allows embedding a navigation tree
into the top level navigation menu of the application instance screen in the PCP.
http://www.aps-standard.org/ui/service
is used to expose navigation in the CCP.
In the platform, it allows embedding an APS UI tree into the top level navigation menu of the customer CP.
http://www.aps-standard.org/ui/user
is used to expose navigation to an end-user.
In the platform, it allows embedding the navigation tree into the top level navigation menu of the MyCP.
In UX1 environment, navigation trees can plug into:
http://www.aps-standard.org/rcp/2
- navigation placeholder in UX1 used by reseller administrators.
http://www.parallels.com/ccp/2
- navigation placeholder in UX1 used by customer administrators.
http://www.aps-standard.org/ui/user/2
- navigation placeholder in UX1 used by customer service users.
The <navigation> root element declares the navigation tree ID and its label. It can also contain the <plugs-to> and <var> elements. The tree is started from this root element embedding other navigation elements.
<navigation id="main" label="VPS Management">
<plugs-to id="http://www.aps-standard.org/ui/service"/>
<var name="vspmanagement" type-id="http://aps-standard.org/samples/basic/management" />
...
</navigation>
The <plugs-to> element specifies a placeholder (socket) for embedding the navigation tree. One of predefined placeholders or another platform specific placeholder is used depending on implementation.
The <var> element inside <navigation> defines a variable that will be available in any view of the tree, since every element inherits this declaration from the upper levels. Refer to the Navigation Variables document for more details.
An <item> element defines a navigation item that can embed other items, creating the skeleton of the navigation tree. Normally, it contains views and a variable definition. Optionally, you can use it as a placeholder to embed other navigation trees or tree branches.
This is an example of a multilayer branch:
<item id="network" label="Network">
<item id="network-ip" label="IP Addresses">
<view id="ip-addresses" label="IP Addresses">
...
</view>
</item>
<item id="network-firewall" label="Firewall">
<view id="firewall" label="Firewall" />
</item>
</item>
An application can define an icon for the second level navigation item, for example:
<item icon="fa-cogs" id="subscription-management" label="Subscriptions">
A <view> element defines an HTML or JS file and other attributes needed to visualize a screen. When a user navigates to an item, the view placed in that item will be active. The view can have other child views (to be called dynamically) as illustrated in the following example:
<view id="servers" src="ui/servers-main.html">
<view id="server-selected" label="Server Configuration" src="ui/servers.html"
description="This is the landpage to configure a virtual server">
<var name="server" type-id="http://aps-standard.org/samples/vpsdemo/vps/1.0" required="true" />
<view id="server-config" maximized="true">
<view id="server-config-details" maximized="true"/>
</view>
<view id="server-network" />
<view id="app-templates-network" />
</view>
</view>
The id
attribute must uniquely identify the view throughout the metadata XML file.
The label
attribute defines a string to print out on top of the screen.
The src
attribute defines the HTML or JS file implementing the view. All such files must be placed into
the ui/
folder, so the path must always start with “ui/”. If the src
attribute is missed, the implicit
definition is the concatenation of the id
value and the html
extension. In the example above,
if src
were missed in the <view id=”servers”> definition, the implicit name of the file would be servers.html
.
Note
In the CP environment, the src
attribute allows
using an HTML file as the source for several views in the same or in different navigation trees.
In UX1, the relationship must be one-to-one.
The description
attribute is used to display a text on top of the screen, just below the view label.
<view id="server-edit" label="Edit VPS" src="ui/server-edit.js"
description="You can edit the VPS properties here.
Note, if you change the OS, all data will be lost
and the upper limits on the properties will change">
...
</view>
Note
The description
attribute is valid in UX1 only, for all view types.
The maximized
attribute hides tabs behind the view, when the latter is opened.
This protects users from data loss in the view (data editor) that happens when a user occasionally clicks on a tab.
When working in UX1, you can find more types of view in addition to the regular view described here.
To embed navigation controls managed by the user panel into a view, you must first place a <controls> element inside the <view> element.
The following buttons can be used: cancel
, prev
, next
, and submit
.
These controls are declared in metadata and should be handled by methods defined in those views
where the controls are used.
CONTRLOL |
HANDLER |
DESCRIPTION |
---|---|---|
|
|
Cancels the view. The handler should navigate users to another view. |
|
|
Used in wizards to navigate to the previous view in a chain. If it is necessary to process some data before navigating to the previous view, you can do so in the respective button handler. |
|
|
Used in wizards to navigate to the next view in a chain. You can redefine the button handler, if it is necessary to process some data before navigating and to pass data to the next view. |
|
|
Used in a view to commit data processing. The handler must define data processing and navigation to another view. |
In the following example, two navigation buttons will appear in the offer-edit view.
<view id="offer-edit" label="Offer {offer.offername}">
<var name="offer" type-id="http://aps-standard.org/samples/vpsclouds/offers/1.0"/>
<controls>
<cancel label="Back to Offers list"/>
<submit label="Save Changes"/>
</controls>
</view>
The platform user panel must send an event to the view, when a navigation control is activated.
The following example illustrates how a click on the Cancel button can be processed inside
the offer-edit
view plugged into PCP:
aps.app.onCancel = function() {
aps.apsc.gotoView("offers");
};
In UX1, the best way is to define the handlers as methods of a view object
based on the aps/View
module, for example:
onCancel: function() {
aps.apsc.gotoView("servers");
}
Follow the limitations described below as the best practice recommendations for your application design.
In this section:
The depth of the navigation tree skeleton built by embedded items is limited:
In PCP and CCP, an application may have up to 2 levels of custom tabs that is up to 2 levels of items.
In UX1, an application may have 1 level of items.
In the sample package
,
the application declares a navigation tree consisting of 3 levels:
The meta declaration of the tree looks as follows:
<navigation>
<plugs-to id="http://www.aps-standard.org/ui/application"/>
<item id="1stlevel-item1" label="1st Level Item-1">
<view id="1stlevel-view1" label="1st Level View 1" src="ui/showviewid.html"
visible="true"/>
<item id="2ndlevel-item11" label="2nd Level Item-11">
<view id="2ndlevel-view11" label="2nd Level View 11" src="ui/showviewid.html"
visible="true"/>
<item id="3rdlevel-item111" label="3rd Level Item-111">
<view id="3rdlevel-view111" label="3rd Level View 111" src="ui/showviewid.html"/>
</item>
<item id="3rdlevel-item112" label="3rd Level Item-112">
<view id="3rdlevel-view112" label="3rd Level View 112" src="ui/showviewid.html"/>
</item>
</item>
<item id="2ndlevel-item12" label="2nd Level Item-12">
<view id="2ndlevel-view12" label="2nd Level View 12" src="ui/showviewid.html"
visible="false"/>
<item id="3rdlevel-item121" label="3rd Level Item-121">
<view id="3rdlevel-view121" label="3rd Level View 121" src="ui/showviewid.html"/>
</item>
<item id="3rdlevel-item122" label="3rd Level Item-122">
<view id="3rdlevel-view122" label="3rd Level View 122" src="ui/showviewid.html"/>
</item>
</item>
</item>
<item id="1stlevel-item2" label="1st Level Item-2">
<view id="1stlevel-view2" label="1st Level View 2" src="ui/showviewid.html"
visible="true"/>
</item>
<item id="1stlevel-item3" label="1st Level Item-3">
<item id="2ndlevel-item1" label="2nd Level Item-31">
<item id="3rdlevel-item1" label="3rd Level Item-311">
<view id="3rdlevel-view1" label="3rd Level View 311" src="ui/showviewid.html"
visible="true"/>
</item>
</item>
</item>
</navigation>
Once the application packages is imported and its APS application instance is installed, you will find the following navigation structure in the application instance view on PCP:
UX1 renders 2 levels of tabs and presents the 3rd level as links to the respective items. Once you click on a link, the child view of the selected item will show up.
The attributes considered in this section allow value assignment from a statement that includes evaluation of navigation variables. Such a dynamic assignment is rarely used since the computation of variable properties affects the overall performance of the UI, but nevertheless might be needed in exclusive cases.
Note
When building a package, the APS tools can miss some errors in RQL statements
that use navigation variables since a variable cannot be evaluated outside of the APS controller. For example,
it is not possible to validate whether a property used in a statement exists and not null. For example, the existence of
the vpsmanagement.showNetworkTab
property of the vpsmanagement
variable is not validated when the APS tools
parse the package. In case of such an error, diagnose it during test runtime on the platform using
its /var/log/pa/pui/pui.log
log file.
Refer to Using RQL for more details about statements used in attributes.
label
¶Dynamic assignment for a label is used more often than for other attributes. A typical example is to display the name of a resource being configured in an editor view:
<view id="offer-edit" label="Edit Offer {offer.name}">
<var name="offer" type-id="http://aps-standard.org/samples/offer-mgmt/offer/1.0"/>
<controls>
<cancel/>
<submit/>
</controls>
</view>
In the example above, label="{offer.name}"
means the label will get the value of the name
property of
the JSON object identified by the offer
variable.
visible
¶The visible
attribute makes an item visible on a condition. The expression can be
a Resource Query Language statement returning true or false. In the following example,
the navigation engine must evaluate the showNetworkTab
property of the object specified by the vpsmanagement
variable.
<item id="network" label="Network" visible="vpsmanagement.showNetworkTab=eq=true()">
Note
From the performance standpoint, instead of using the visible
attribute it would be better to
declare a required variable, which will have the same effect, for example:
<item id="network" label="Network">
<var name=network required="true" />
description
¶The description
attribute is used to display a text on top of the screen, just below the view label.
To display variable data, the text can contain a reference to a variable property, for example:
<view id="server-edit" label="Edit VPS" src="ui/server-edit.js"
description="You can edit the {vps.name} properties here.
Note, if you change the OS, all data will be lost
and the upper limits on the properties will change">
<var name="vps" type-id="http://aps-standard.org/samples/offer1p/vps/1.0"/>
...
</view>
The <placeholder> element inside a <navigation>, <item>, or <group> element declares a socket for embedding other navigation trees or tree branches. Those trees or branches must have the <plugs-to> element with the same ID as specified by the considered <placeholder> element. The following example illustrates how to declare a placeholder in an <item>:
<item id="network" label="Network">
...
<placeholder id="http://aps-standard.org/samples/basic/management#network" />
</item>
Warning
Although any APS application can declare its own placeholders, you should use this capability very carefully taking into account that incorrect plugging can convert a tree into a cyclic graph that destroys the navigation. For example, avoid the cases when one application, app-1, plugs its branch into another application, app-2, and the latter plugs its branch into the former, thus making a loop in the navigation structure.