Image AddedTutorial detailsWe saw how to create tutorials for a group of users (by adding content for their Role). Now let's see how to create new tutorials and how to configure them. Previously, we saw that, in the tutorials.json file, you have to specify the list of available tutorials, by specifying each tutorial name and file. So now you have to create a JSON file for each tutorial, in the same folder where the tutorials.json is located. {tutorial_name}.json fileThis file must be located in /config/tutorials/{ROLE_NAME}/ General attributesName | Type | Required | Description | Example |
---|
steps | Array | true | This is the list of tutorial steps, step attributes are listed below | [{"intro":"Welcome to Abiquo's first tutorial"}] | - | - | - | - | - |
As you can see, for now the only attribute should be the steps one, in future releases we will probably add more attributes to improve this feature Step attributesName | Type | Required | Dependency* | Description | Example | Screenshot |
---|
intro | String | true | - | This is the only required element and it can be used alone. This is the text displayed to explain the current step. You can use HTML tags to improve user experience. If you don't specify the element attribute, the step will be added in the middle of the screen: this can be used for the first or final step, for example Info |
---|
Unique lineYou have to put the entire value on a single line. If you are using HTML tags, use <br> to add some space |
| "Welcome to <strong>Abiquo</strong><br>The objective of this tutorial is to help you deploy your first <strong>virtual machine</strong><br>You will see that it's very easy and quick :)<br><strong>Let's start!</strong>"
| Image Modified | translationCode | String | no | - | This is for multi-language support. By default, the text displayed for each description will be the intro value. You can use this attribute to specify a translation code, but be sure to add the translation code (and its translation) in all required language files, otherwise it will not work correctly. | "tutorial.step.1" |
| element | String | no | - | The javascript library is designed to highlight a specific UI element, and add a description of this element. This attribute is used to select an HTML element to highlight. Be careful of the following format restrictions: Start with '#', indicating that we are searching element by id Use '\\' to prevent '-' and '.', because most element IDs are composite names, and these two characters must be escaped
See #How to find the element id/name ------------------------------------------------------------------------------------------------------- IMPORTANT: element by name To identify an element by its name, use the following identifyElementBy attribute. Then specify the element attribute with its exact name (you don't need to use # or \\) ------------------------------------------------------------------------------------------------------- HTML element example: <a id="element.id" name="element_name">I'm a simple link</a> Search by id
element: "#element\\.id" Search by name element: "element_name", identifyElementBy: "name"
| "#virtualdatacenters\\.tab" | Image Modified | identifyElementBy | String | no | - | This attribute is used to specify that the element should be identified by something other than the id. At the moment, name is the only option. If you don't use this attribute (default behavior), the element will be identified by id. | name |
| subElement | Object | no | - | This attribute is used to specify another view element, different from the element to receive the user interaction (see actionType). The format should be as in the element format. Example element: a vapp element in Virtual Datacenter view subElement: the enter button, this button should receive the user click action
|
|
| subElement. element | String | required if | subElement | | "#vdc\\.vapp\\.enter\\-0" | Image Modified | subElement. getElementBy | String | required if | subElement | This attribute is used to specify that the sub-element should be identified by something other than the id. At the moment, name is the only option. If you don't use this attribute (default behavior), the sub-element will be identified by id. | name |
| actionType | String | required if | element | This attribute can control the user action before going to the next step. If you don't specify it, the Next button will always be active and the interaction with the user will be poor. The actionType can have three values: "onclick": this value specifies that the user needs to click the element (or subElement) in order to go to the next step. "ondblclick": this value specifies that the user needs to double click the element (or subElement) in order to go to the next step. "{event.name}": you can specify an event type to wait for, and automatically go to the next step. For example, when you are creating a virtual appliance, you want to wait for 'virtualAppliance.created' to continue. These events are dispatched in the clientUi, and displayed at the end of this document in the #List of clientUi events
| "onclick" |
| position | String | required if | element | This attribute is for positioning the description element related to the element. Values can be: | "bottom" (In the previous element screenshot, you can see that the description is placed at the bottom of selected element) |
| blockPrevious | Boolean | no | - | By default, in the description zone, you have three buttons: Exit, Previous and Next. All buttons are available for each step (except Previous in the first step and Next in the last step). With this attribute, you can block the Previous button in specific steps, which can be useful in some cases, for example, when you ask the user to click a button to change the a main view, and you don't want the user to go back to the previous view. You can also block the Next button, for details, please see the actionType attribute |
|
| delayBeforeNextItem | Number | no | - | This attribute can be used to add a timeout before going to the next step. When the library goes to the next step, the next element should exist in the view, otherwise the tutorial will fail. This attribute is very helpful when you are changing the current view and it's necessary to wait until the next element is retrieved from the database and loaded. The value is in milliseconds | 1000 |
| skipStep | Object | no | - | Some steps can be skipped, for example, if the user already did the tutorial, or if a step needs an element to be created, but the element already exists. | "skipStep":{ "existingElement":"vapp", "identifyElementBy":"name", "stepsToSkip":2 } |
| skipStep. existingElement | String | required if | skipStep | This attribute is to check if an element exists. You can specify the element name or id (check the identifyElementBy attribute) | "vapp" |
| skipStep. identifyElementBy | String | required if | skipStep | Use this attribute to specify if the existingElement should be located by name or by id | "name" |
| skipStep. stepsToSkip | Number | required if | skipStep | Specify the number of steps to skip if the existingElement is located (the minimum is 1, means to skip this step and go to the next one) | 2 |
| - | - | - | - | - | - |
|
SampleHere you can find a sample of a tutorial file Tutorial sample file Code Block |
---|
{
"steps" : [
{
"intro": "Welcome to <strong>Abiquo</strong><br>The objective of this tutorial is to help you deploy your first <strong>virtual machine</strong><br>You will see that it's very easy and quick :)<br><strong>Let's start!</strong>"
},
{
"element": "#virtualdatacenters\\.tab",
"intro": "In the <strong>Virtual Datacenter</strong> section, you will manage all you virtual infrastructure, let's begin by clicking this icon<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Click the <strong>'Virtual Datacenters'</strong> icon to continue</i>",
"position": "bottom",
"actionType": "onclick",
"blockPrevious": true
},
{
"element": "#virtual\\-datacenter\\-list\\-container",
"intro": "This is the list of available <strong>virtual datacenters</strong>, each of them contains some virtual appliances<br>",
"position": "right",
"translationCode":"tutorial.step.1"
},
{
"element": "#vdc\\-0",
"intro": "Select the 'vdc' virtual datacenter in order to continue with virtual appliance creation<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Select the <strong>'vdc'</strong> virtual datacenter</i>",
"position": "right",
"actionType": "onclick",
"delayBeforeNextItem": 1000
},
{
"element": "#create\\.vapp",
"intro": "You can now create a virtual appliance, which contains virtual machines you'll want to deploy<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Click the '+' button</i>",
"position": "left",
"actionType": "onclick",
"skipStep":{
"existingElement":"vapp",
"identifyElementBy":"name",
"stepsToSkip":2
}
},
{
"element": "#newVirtualApplianceForm",
"intro": "Fill all required fields and then click the 'Save' button to create the <strong>virtual appliance</strong><br>",
"position": "left",
"actionType":"virtualAppliance.created",
"blockPrevious": true
},
{
"element": "#vdc\\.vapp\\.list",
"intro": "The <strong>virtual appliance</strong> has been created and you can find it in this list<br>",
"position": "top",
"blockPrevious": true
},
{
"element": "#vdc\\.vapp\\-0",
"subElement": "#vdc\\.vapp\\.enter\\-0",
"intro": "The virtual appliance contains your virtual machines, you need to add at least one to deploy it<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Click the 'enter' button</i>",
"position": "top",
"actionType": "onclick",
"delayBeforeNextItem":300
},
{
"element": "#vapp\\.vmTemplate\\.list",
"intro": "A <strong>virtual machine</strong> is based on a </strong>virtual machine template, here you can find all the available template</strong><br>",
"position": "right",
"blockPrevious": true
},
{
"element": "#vapp\\.vmTemplate\\-0",
"intro": "Let's use this template, please double click on it to use it as a virtual machine (<strong>note:</strong> you can also drag&drop the template into the virtual machine list on the right)<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Double click the 'm0n0wall' virtual machine template</i>",
"position": "right",
"actionType": "ondblclick",
"skipStep":{
"existingElement":"#vapp\\.vm\\-0",
"identifyElementBy": "id"
}
},
{
"element": "#vapp\\.vm\\.list",
"intro": "The virtual machine has been created and now ready to be deployed<br>",
"position": "left"
},
{
"element": "#vapp\\.deploy",
"intro": "Now you just have to click the <strong>Deploy Virtual Appliance</strong> button in order to deploy all virtual machines<br><br><span style='color: orange'><strong>Action Needed:</strong></span><br><i>Click the 'Deploy Virtual Appliance' button to continue</i>",
"position": "left",
"actionType": "onclick",
"delayBeforeNextItem":1000
},
{
"element": "#vapp\\.vm\\-0",
"intro": "You can see that the virtual machine is being deployed, it will be deployed once the state is 'DEPLOYED'<br>",
"position": "right"
},
{
"intro": "You can see that the virtual machine is being deployed, you have successfully completed this tutorial<br><br><span style='color: green'><strong>Tutorial completed:</strong></span><br><i>You have deployed your first virtual machine</i>"
}
]
} |
List of clientUi eventsHere you can find some most useful clientUI events allocationRule.created allocationRule.edited allocationRule.deleted volume.created volume.edited volume.deleted category.created category.edited category.deleted templateDefinitions.created templateDefinitions.deleted virtualDatacenter.created virtualDatacenter.edited virtualDatacenter.deleted virtualAppliance.created virtualAppliance.edited virtualAppliance.deleted user.created user.edited user.deleted storagePools.created storagePools.edited storagePools.deleted storageDevices.created storageDevices.edited storageDevices.deleted physicalMachine.created physicalMachine.discovered physicalMachine.edited physicalMachine.deleted racks.created racks.edited racks.deleted virtualmachine.created virtualMachine.edited virtualMachine.deleted scope.created scope.edited scope.deleted role.created role.edited role.deleted remoteServices.created remoteServices.edited remoteServices.deleted networkServiceType.created networkServiceType.edited networkServiceType.deleted networks.created networks.edited networks.deleted publicip.created publicip.edited publicip.deleted enterprise.created enterprise.edited enterprise.deleted datacenter.created datacenter.edited datacenter.deleted license.created license.requested
How to find the element id/nameYou can find an element's id or name using your browser. The following sections explain how to do this on Chrome and Firefox, but you can use another browser, inline UI analyzer or whatever software you want. ChromeFirst, open the clientUI in your browser and then press CTRL + ALT + i to open the Developer tools. Image ModifiedThen click Elements tab, then the inspector icon and select the element that you want to find out the id/name of. Image ModifiedIn this example, you can see that the element has the id = vapp.vm-0 so you can use it as the element attribute. FirefoxFirst, open the clienUI in your browser and then press F12 to open the Developer tools. Image ModifiedThen click Inspector tab, then the inspector icon and select the element you want to know its id/name Image ModifiedIn this example, you can see that the element has the id = vapp.vm-0 so you can use it as the element attribute. |