doc/book/en/development/datamodel/define-workflows.rst
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 22 Sep 2009 18:59:00 +0200
branchstable
changeset 3372 26b89dfe4170
parent 3322 a522f86ab617
child 3560 7d76775f965d
permissions -rw-r--r--
typo
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
.. -*- coding: utf-8 -*-
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
2539
0f26a76b0348 [doc] some more rewriting
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2476
diff changeset
     3
Define a Workflow
0f26a76b0348 [doc] some more rewriting
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2476
diff changeset
     4
=================
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     6
General
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     7
-------
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
     8
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
     9
A workflow describes how certain entities have to evolve between
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    10
different states. Hence we have a set of states, and a "transition graph",
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
i.e. a list of possible transitions from one state to another state.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    12
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    13
We will define a simple workflow for a blog, with only the following
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    14
two states: `submitted` and `published`. So first, we create a simple
2175
16d3c37c5d28 [doc] improvements
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2172
diff changeset
    15
*CubicWeb* in ten minutes (see :ref:`BlogFiveMinutes`).
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    16
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    17
Set-up a workflow
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    18
-----------------
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    19
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    20
We want to create a workflow to control the quality of the BlogEntry
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2307
diff changeset
    21
submitted on your instance. When a BlogEntry is created by a user
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
its state should be `submitted`. To be visible to all, it has to
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    23
be in the state `published`. To move it from `submitted` to `published`,
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
we need a transition that we can call `approve_blogentry`.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    25
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
A BlogEntry state should not be modifiable by every user.
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    27
So we have to define a group of users, `moderators`, and
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    28
this group will have appropriate permissions to publish a BlogEntry.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
There are two ways to create a workflow: from the user interface,
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    31
or by defining it in ``migration/postcreate.py``.
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    32
This script is executed each time a new ``cubicweb-ctl db-init`` is done.
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    33
We strongly recommend to create the workflow in ``migration/postcreate.py``
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
and we will now show you how. Read `Under the hood`_ to understand why.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    36
The state of a entity is managed by the `in_state` attribute which can be added to you entity schema by two ways:
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    37
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    38
* direct inheritance by subclassing your class from `cubicweb.schema.WorkflowableEntityType`
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    39
* by delegation using `cubicweb.schema.make_worflowable` (usable as a decorator)
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    40
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    41
About our example of BlogEntry, we must have:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    42
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    43
.. sourcecode:: python
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    44
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    45
  from cubicweb.schema import WorkflowableEntityType
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    47
  class BlogEntry(EntityType, WorkflowableEntityType):
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    48
      ...
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    49
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    50
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    51
Create states, transitions and group permissions
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    53
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    54
The ``postcreate.py`` script is executed in a special environment, adding
2175
16d3c37c5d28 [doc] improvements
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2172
diff changeset
    55
several *CubicWeb* primitives that can be used.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    56
They are all defined in the ``class ServerMigrationHelper``.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    57
We will only discuss the methods we use to create a workflow in this example.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    58
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
To define our workflow for BlogDemo, please add the following lines
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    60
to ``migration/postcreate.py``:
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    61
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    62
.. sourcecode:: python
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    63
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
  _ = unicode
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
  moderators = add_entity('CWGroup', name=u"moderators")
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    68
This adds the `moderators` user group.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    70
.. sourcecode:: python
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    71
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    72
  wf = add_workflow(u'your workflow description', 'BlogEntry')
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    73
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    74
At first, instanciate a new workflow object with a gentle description and the concerned entity types (this one can be a tuple for multiple value).
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    75
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    76
.. sourcecode:: python
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    77
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    78
  submitted = wf.add_state(_('submitted'), initial=True)
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    79
  published = wf.add_state(_('published'))
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    81
``add_state`` expects as first argument the name of the state you want to create and an optional argument to say if it is supposed to be the initial state of the entity type.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    82
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    83
.. sourcecode:: python
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    84
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    85
  wf.add_transition(_('approve_blogentry'), (submitted,), published, ('moderators', 'managers'),)
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    86
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    87
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    88
``add_transition`` expects
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    89
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    90
  * as the first argument the name of the transition
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    91
  * then the list of states on which the transition can be triggered,
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
    92
  * the target state of the transition,
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    93
  * and the permissions
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    94
    (e.g. a list of user groups who can apply the transition; the user
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    95
    has to belong to at least one of the listed group to perform the action).
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    96
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
    97
.. sourcecode:: python
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    98
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
    99
  checkpoint()
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   100
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   101
.. note::
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   102
  Do not forget to add the `_()` in front of all states and transitions names while creating
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   103
  a workflow so that they will be identified by the i18n catalog scripts.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   104
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   105
In addition to the user group conditions which the user needs to belong to one of those, we could have added a RQL condition.
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   106
In this case, the user can only perform the action if the two conditions are satisfied.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   107
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   108
If we use a RQL condition on a transition, we can use the following variables:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   109
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   110
* `%(eid)s`, object's eid
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   111
* `%(ueid)s`, user executing the query eid
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   112
* `%(seid)s`, the object's current state eid
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   113
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   114
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   115
.. image:: ../../images/03-transitions-view.en.png
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   116
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   117
You can notice that in the action box of a BlogEntry, the state
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   118
is now listed as well as the possible transitions for the current state defined by the workflow.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   119
The transitions will only be displayed for users having the right permissions.
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
   120
In our example, the transition `approve_blogentry` will only be displayed
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   121
for the users belonging to the group `moderators` or `managers`.
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   122
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   123
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   124
Under the hood
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   125
~~~~~~~~~~~~~~
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   126
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   127
A workflow is a collection of entities of type ``State`` and of type ``Transition``
2175
16d3c37c5d28 [doc] improvements
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2172
diff changeset
   128
which are standard *CubicWeb* entity types.
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   129
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   130
For instance, the preceding lines:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   131
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   132
.. sourcecode:: python
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   133
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   134
  submitted = wf.add_state(_('submitted'), initial=True)
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   135
  published = wf.add_state(_('published'))
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   136
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   137
will create two entities of type ``State``, one with name 'submitted', and the other
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   138
with name 'published'. Whereas:
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   139
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   140
.. sourcecode:: python
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   141
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   142
  wf.add_transition(_('approve_blogentry'), (submitted,), published, ('moderators', 'managers'),)
2172
cf8f9180e63e delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1714
diff changeset
   143
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   144
will create an entity of type ``Transition`` with name `approve_blogentry` which will
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   145
be linked to the ``State`` entities created before.
3322
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   146
As a consequence, we could use the administration interface to do these operations. But it is not recommended because it will be uselessly complicated and will be only local to your instance.
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   147
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   148
Indeed, if you create the states and transitions through the user interface, next time you initialize the database you will have to re-create all the entities.
a522f86ab617 [D] book: define a workflow
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2539
diff changeset
   149
The user interface should only be a reference for you to view the states and transitions, but is not the appropriate interface to define your application workflow.
1714
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   150
a721966779be new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff changeset
   151