Modes, rights and behaviors

Modes

A same template can be used according to different modes to produce a view (screen part). These modes are :

  • READ = read only, simple display
  • EDIT = change, modify, input
  • CREATE = input for data creation

(This modes should cover current requirements but other modes could be invented.)

Rights

Generally, a user has a profile which gives him/her rights on pieces of functionnality (access to a screen part, several screen parts or special areas in a screen part).

Behaviors

A GUI component can adapt itself according to the current mode and user rights. The main behaviors are :

  • HIDDEN : the component is not visible
  • VISIBLE : the component is visible but is not active (read only)
  • ACTIVE : the component is active, which means that the information it displays is editable.

Most components are concerned : it is easy to imagine these principles on input fields, but thay can also be applied on a table column, a whole table, a form area... Note that a container behavior could also influence its children behavior.

Policies

A policy defines the different behaviors that a component can follow according to modes and user rights.

Default widget policy

By defaut, a component has these behaviors :

  • if READ mode : VISIBLE
  • if EDIT mode : ACTIVE
  • if CREATE mode : ACTIVE

These are the 'default default behaviors'. Default behaviors on a specific widget could be different (if expected) : there is a default policy for every widget (getDefaultBehaviorPolicy()).

Change of policy

Default behavior can be modified on any component. For instance, one may want a field on an identifier data to be editable in CREATE mode but not in EDIT mode. Another case would be to make some data invisible in READ mode. Thus we must be able to change the policy on any component, in other words to redefine the behavior for the different modes. To achieve this, we can use the following syntax : 'mode:behavior; mode:behavior; mode:behavior'

Example : widget.setBehaviorPolicy("read:visible; edit:visible; create:active");

As there is a default policy, it is not necessary to redefine the behavior on all the modes. In the example, only the behavior in EDIT mode differs from the default policy, then we can just use the following expression : "edit:visible"

The 'all' keyword enables to change the behavior on all modes. For example : all:visible will make the component visible (but inactive) in all modes.

Using user rights

It can be useful to make a component inactive or invisible depending of the user rights. Therefore, these rights can influence the component behavior. By default, the policy ignores user rights. It is necessary to redefine it and the syntax of policy expression accepts rights in this way : mode[right]:behavior

Of course, the identifier used for the right into brackets must be declared in the authorization system.

Example : edit[admin]:visible means that the component has default behavior except for users having the 'admin' right - for them, the component is only visible and not active in EDIT mode.

But it is more often useful to restrict the abilities of users that don't have a specific right. To achieve this, we can exclude a right using the '-' sign : edit[-manager]:hidden means that widget is hidden in EDIT mode for all users that don't have the 'manager' right.

In order to keep policy expression quite short, we can set several rights into brackets : edit[-manager,admin]:hidden (hidden for all except manager and admin)

Last example, a widget which is active in CREATE mode and only visible in EDIT and READ modes for users with manager or admin rights, and hidden in all modes for other users :

edit[manager,admin]:visible; all[-manager,admin]:hidden

Let's apply

The current mode is stored at the context level. The default mode is EDIT. Calling setMode() on context will make all components linked to this context adapt their behavior : each component will ask its policy to know which behavior to apply and then adapt their actual behavior (becoming invisible, inactive, etc)

As Monoi does not handle (yet) the way view parts are organized in a 'navigation' point of view, it is still developper's responsibility to set the context mode when appropriate. A quite standard way to manage this would be to develop some 'screen part' classes with :

  • a description of UI content with Monoi components
  • a context (linked to the root container)
  • a way to transmit a data set
  • a way to set the screen mode

Then, it would be easy to show a screen part in a certain mode, passing data to display or edit.