First Launch - cuba-platform/sample-workshop GitHub Wiki
Our application is done, of course, to a first approximation. Let’s compile and launch it!
-
Invoke the Run — Start application server action from the menu. Studio will deploy a local Tomcat instance in the project subdirectory, deploy the compiled application there and launch it
-
Open the application by clicking a link in the bottom part of the Studio
- CUBA application welcomes us with the login screen. It’s a part of the security module, integrated into the platform. Default login and password are already set on the screen, so just click Submit.
-
After successful login you can see the main window of your application, which can be customised from the Studio, similarly to any other screen.
-
Open Application - Orders from the menu. The standard browser screen appears. It contains a generic data filter on top, a table of records with buttons on top, performing standard CRUD actions. There are more standard actions available in the platform, for example, export to excel. Click Create.
-
This is the autogenerated editor screen for the Order entity. Let’s fill up the form. Click […] to select a client.
- There are no clients in the system yet, so the client browser is empty. Click Create to add a new client to the system and fill up client editor with the following values and click OK:
- Name: Alex
- Phone Number: 999-99-99
- Email: [email protected]
-
Double click the client record we have just created or simply click Select on the bottom part of the client browser
-
We have specified a client for our order and it is shown in the client field accordingly to the Instance name, we specified for the Client entity (Name Phone number)
-
Create set the Mechanic field in the same way
- User: admin
- Hourly Rate: 10
- Complete entering data for the order using the following values and click OK
- Description: Broken chain
- Status: New
Our CRUD application is ready, so we have successfully completed items 1-3 of the functional specification!
Now let’s examine how data filter works. The CUBA generic filter enables you to filter data by all the fields of the screen main entity, all the entities it refers to as well as their fields. It also gives you the ability to create custom filtering rules based on JPQL queries and to save them for repeated use.
Create one more order with the following parameters:
Client
- Name: Freeman
- Phone Number: 111-11-11
- Email: [email protected]
Mechanic
- User: admin
- Hourly Rate: 8
Order
- Description: Wheels problem
- Hours Spent: 2
- Status: In progress
Parts (add one part)
- Title: Wheel 29’’
- Description: Standard wheel
- Price: 50
Let’s create a simple filter to find all the orders of a particular client.
-
Go to the Order Browser screen (Application — Orders) and click the Add search condition link
-
Select the Client property
-
Click Select
- Your filter automatically shows you options that can be applied for the Client field. Select Alex and click Search.
-
Only one record left after filtering.
-
Click on the [=] button to see what comparison options CUBA filters offer for users
[=] - exact equality
[in] - the field is contained in a specified set of values
[not in] - the field is NOT contained in a specified set of values
[<>] - the field is not equal to the specified value
[is set] - the field is null/not null
In a similar way, you can filter by all types of attributes (string, numeric, boolean, etc).
Sometimes it is not possible to filter records without join operation. Let’s take the following example: we want to filter all the orders that contain some particular part in it.
-
Click the Add search condition link
-
Select the Create new… option
-
Set condition Name: Part Specified in Order
-
Our main entity in the screen is Order, which has Set parts field, containing all the used parts. Let’s join parts to the orders: type join {E}. and the system will show you suggestions. Select the parts suggestion or just type it manually and assign alias p to the joining table. You should get the following Join clause: join {E}.parts p
-
Input p.id = ? in the Where field. The question mark here means the parameter that we will send to the condition from the generic filter UI.
-
Select Param type: Entity
-
Set Entity/Enum: SparePart
-
Click OK
- Specify the Wheel 29’’ value in your custom filter and click Search to see the result list
Obviously, there are a number of filters, that end-users reuse frequently. For that purpose you can save filters you create. Let’s save the “part specified in order” filter we have just created.
-
Click the cogwheel button on the right-hand side of the filter component
-
Click Save
-
Input Filter name: Part specified in order
-
Now you can access your filter by clicking the down arrow button, placed next to the Search one. Apply the saved filter.
- Applying a saved filter you can edit, remove it or make selected filter as default one by clicking the cogwheel button. Default filters appear in the screen automatically after opening.
-
Open the saved filter
-
Click the cogwheel button — Edit
-
Selecting conditions users are able to edit them
-
Also there is an ability to additional conditions and group them using OR and AND logical operators. Let’s add one more condition. For example, we want to control our stock of spare parts, so, we would like to know how many parts of some particular type we need for the new or unstatused orders. The logical expression we are going to build is the following: Part Specified in Order = ? AND (Status = NEW OR Status is not set).
-
Click the Add OR button and check that the OR group item is selected in the conditions list
-
Click Add
-
Select the Status attribute
-
Set Default value: New
-
Select the OR group item in the conditions list and add one more condition for the Status attribute
-
Change Operation to [is set] one and specify No in the Default value field
-
Click OK
-
Now we can see our complex filter
- Editing filters allows you to share them between users, set them as default screen filter, hide some conditions or groups of conditions. More information on generic filter component can be found here.
The platform has built-in functionality to manage users and access rights. This functionality is available from the Administration menu. The CUBA platform security model is role-based and controls CRUD permissions for entities, attributes, menu items and screen components and supports custom access restrictions. All security settings can be configured at runtime. There is also an additional facility to control row level access.
We need a role for mechanics in our application. A Mechanic will be able to modify an order and specify the number of hours they spent, and add or remove spare parts. The Mechanic role will have limited administrative functions. Only admin will be allowed to create orders, clients and spare parts.
-
Open Administration — Roles from the menu
-
Click Create
-
Set Name: Mechanic
We want to restrict access to the Administration screens for all Mechanic users, so let’s forbid the Administration menu item. Also, mechanics don’t need access to the mechanics and clients browsers, let’s forbid the corresponding screens too.
-
Select the Administration row in the Screens table
-
Select deny
-
Similarly deny access for Clients and Mechanics
As it has already been mentioned we want a mechanic only allow read access to clients, mechanics and parts. Also a mechanic should not be able to create or delete an order in the system. Only update it’s status, hours spent and manipulate with parts in the order.
-
Open the Entities tab
-
Select the Client entity and forbid create, update and delete operations
-
Repeat the second step for the Mechanic and SparePart entities
-
Forbid only create and delete operations for the Order entity
On attribute level we don’t want to allow a mechanic to set values for the client, mechanic and description attributes; also we would like to hide the amount field from them.
-
Open the Attributes tab
-
Select the Order row
-
Tick read-only for client, mechanic and description; tick hide for the amount attribute
- Click OK to save the role
Let’s apply the mechanic role to a new user and take a look at the application from the mechanic’s point of view.
-
Open Administration — Users
-
Click Create
-
Set Login: jack
-
Set password and password confirmation: qwe
-
Set Name: Jack
-
Add the Mechanic role to user Roles
-
Click OK to save the user
-
Let’s exit the application by clicking the top-right door button of the screen
-
Login with the new user Login: jack, Password: qwe
-
The Administration menu item is hidden as well as Mechanics and Clients browsers;
The Spare Parts browser is available in read-only mode;
The Orders browser allows us only editing of existing records;
The Order editor allows only changing the Hours spent and Status fields, as well as adding parts to an order; the amount field is hidden from our user.
The CUBA Platform Security subsystem allows you to control and restrict access to the level of records using the access groups mechanism. For example, we want to restrict access to our mechanics to see only orders that were assigned to them.
-
Log out from the system and login under administrator (Login: admin; Password: admin)
-
Open Administration — Access Groups from the menu. The groups have the hierarchical structure, where each element defines a set of constraints, allowing controlling access to individual entity instances (at row level).
-
Click Create — New
-
Set Name: Mechanics
-
Click OK
-
Open the Constraints tab for the newly created group
-
Click Create in the Constraints tab
-
Set Entity Name: Order
-
We can define what operation type we want to assign restriction to. Keep Operation Type: Read
-
For some operation types it is not possible to perform check at the database level, e.g. delete and update operations. For this reason there are three Check Types implemented in the platform: Check in database (using JPQL), Check in memory (using Groovy script; the only option for Create, Update, Delete, All operation types) and Check in database and in memory (using both JPQL and Groovy). In our example, we will use the Check in database check type
-
For the Check in database check type you can specify a JPQL query in the same way as we did for custom conditions in the generic filter. Click the Constraint Wizard link
-
Expand the Mechanic field and select the child User attribute
-
Click Select
-
Click OK in the Define query window. The platform has generated the where clause as {E}.mechanic.user.id = 'NULL'. We will need to tune it a bit.
-
Click the question mark located in the top-right corner of the Where Clause filed to see what predefined constants can be used here
-
We need the ID of the current user to compare with the mechanic’s user id. So, change 'NULL' to :session$userId. Finally, you should have the following code:
{E}.mechanic.user.id = :session$userId
-
Click Test Constraint
-
If test shows that constraint is valid, then click OK
-
Select the Company group on the Access Groups screen
-
Select Jack in the Users tab
-
Click Move To Group
-
Select the Mechanics group and click Select
-
Let’s now assign one of our mechanics to the new user. Go to Application - Mechanics in the main menu
-
Select the mechanic with hourly rate of 10
-
Click Edit
-
Specify the Jack user for this record and click OK
-
Now our mechanic is associated with the jack user. Re-login into the application using Jack’s credentials: Login: jack; Password: qwe
-
Open the Orders browser (Application — Orders). Now we can only see the orders assigned to Jack
There is a requirement in our functional specification to track critical data changes. CUBA Platform has a built-in mechanism to track entity changes, which you can configure to track operations with critical system data.
Keeping track of our application, it happens when one day someone has accidentally erased the order description. It is not appropriate to call the client on the phone, apologise and ask them to repeat the what needs to be done. Let’s see how this can be avoided.
-
Re-login into the application as administrator (Login: admin; Password: admin)
-
Open Administration — Entity Log from the menu
-
Go to the Setup tab
-
Click Create
-
Set Name: Order Auto: true Attributes: all
-
Click Save
Now the system will track all CRUD changes of all the fields of the Order entity. Go to the order browser and change status or description of any record, then get back to the Entity Log screen and you will see who made what change. On the screenshot below we changed the description of one of the orders and see what we have in the entity log:
While spending short time exploring the CUBA Platform and its features we have already finished the following requirements from the functional specification:
-
Store customers with their name, mobile phone and email -
Record information about orders: price for repair and time spent by mechanic -
Keep track of spare parts in stock -
Automatically calculate price based on spare parts used and time elapsed
-
Control security permissions for screens, CRUD operations and records' attributes -
Perform Audit of critical data changes -
Provide API for a mobile client to place an order
Note that we didn’t even type any line of source code, everything has been provided by the platform or scaffolded by the Studio. Let’s move forward towards business logic.