Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
The votes module¶
doctest init:
>>> import lino
>>> lino.startup('lino_book.projects.noi1e.settings.demo')
>>> from lino.api.doctest import *
The lino_xl.lib.votes
module adds the concept of “votes” to an
application. This document describes how this looks in Lino Noi.
This plugin is currently not used anywhere.
Introduction¶
Votes are currently not installed in noi, in favor of lino_xl.lib.stars
and having tickets be assignable.
A vote is when a given user has an opinion or interest about a given ticket. A special case are vote invitations (votes having state “invited”) where the user did not yet express any opinion or interest but is asked to do so.
Votes are visible in the VotesByVotable panel of a ticket. Your votes become visible as invitations, candidatures or tasks in your Office menu or your dashboard.
Vote invitations¶
Lino automatically creates vote invitations when a user comments on a ticket, works on a ticket or participates in an activity with that ticket.
When you have pending vote invitations, Lino displays them in the “My vote invitations” table on your dashboard.
This table basically is a list of tickets asking you to choose, for each of them, one of four options:
Cancelled : not interested. You declare that you don’t want to be bothered with this ticket.
Watching : You are interested, you are neutral and did not yet declare your opinion. You want to be notified when something happens in this ticket.
Pro : optimistically watching. You declare that you want this ticket to get done. You support this ticket.
Con : skeptically watching. You declare that you want this ticket to get refused.
The pro and con states will be visible in the WishesByMilestone view and may be used for quick voting polls.
Voting polls¶
A voting poll is when one user asks other users to vote “yes”, “no” or “undecided” on a series of questions.
You can run a voting poll in Noi as follows:
formulate your questions as tickets
create an activity and add your tickets as wishes
add enrolments to your activity. The participants will automatically get a vote invitation. Note that you must click the Save button of the activity for Lino to create vote invitations.
Candidatures¶
When a ticket has been declared “Open” by its author, then any watching user may decide move from unengaged watching to engaged acting. This is done in two steps: first you declare yourself as a candidate. The author of the ticket can then see your candidature and possibly assign you to that ticket.
My tasks¶
This table thows your votes having states assigned and done. It is your general “To-Do list”.
Here are some examples for different users.
>>> rt.login('jean').show(votes.MyTasks)
...
========================================================================================== =============================================================
Description Actions
------------------------------------------------------------------------------------------ -------------------------------------------------------------
`#2 (☎ Bar is not always baz) <Detail>`__, assigned to `Jean <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done] [Rate]
`#108 (⚒ Ticket 108) <Detail>`__ by `Mathieu <Detail>`__, assigned to `Jean <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done] [Rate]
`#84 (⚒ Ticket 84) <Detail>`__ by `Mathieu <Detail>`__ [▶] [★] **Done** → [Rate]
========================================================================================== =============================================================
>>> rt.login('mathieu').show(votes.MyTasks)
...
======================================================================================= ======================================================
Description Actions
--------------------------------------------------------------------------------------- ------------------------------------------------------
`#58 (☎ Ticket 58) <Detail>`__ by `Luc <Detail>`__, assigned to `Mathieu <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done]
`#34 (☎ Ticket 34) <Detail>`__ by `Luc <Detail>`__ [▶] [★] **Done**
`#19 (☉ Ticket 19) <Detail>`__ by `Luc <Detail>`__, assigned to `Mathieu <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done]
======================================================================================= ======================================================
>>> rt.login('luc').show(votes.MyTasks)
...
==================================================================================== ======================================================
Description Actions
------------------------------------------------------------------------------------ ------------------------------------------------------
`#98 (☎ Ticket 98) <Detail>`__ by `Jean <Detail>`__ [▶] [★] **Done**
`#83 (☉ Ticket 83) <Detail>`__ by `Jean <Detail>`__, assigned to `Luc <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done]
`#59 (☉ Ticket 59) <Detail>`__ by `Jean <Detail>`__ [▶] [★] **Done**
`#44 (⚒ Ticket 44) <Detail>`__ by `Jean <Detail>`__, assigned to `Luc <Detail>`__ [▶] [★] **Assigned** → [Cancelled] [Watching] [Done]
`#20 (⚒ Ticket 20) <Detail>`__ by `Jean <Detail>`__ [▶] [★] **Done**
==================================================================================== ======================================================
>>> rt.login('luc').show(votes.MyOffers)
...
======================================================== ===========================================================
Description Actions
-------------------------------------------------------- -----------------------------------------------------------
`#1 (⚹ Föö fails to bar when baz) <Detail>`__ [▶] [★] **Candidate** → [Cancelled] [Watching] [Assigned]
`#107 (☉ Ticket 107) <Detail>`__ by `Jean <Detail>`__ [▶] [★] **Candidate** → [Cancelled] [Watching]
`#68 (⚒ Ticket 68) <Detail>`__ by `Jean <Detail>`__ [▶] [★] **Candidate** → [Cancelled] [Watching]
======================================================== ===========================================================
Note that Luc is not a triager, that’s why he does not have an [Assigned] action on other people’s tickets.
>>> from lino_xl.lib.tickets.roles import Triager
>>> rt.login('luc').user.user_type.has_required_roles([Triager])
...
False
The state of a vote¶
See lino_xl.lib.votes.choicelists.VoteStates
>>> rt.login().show(votes.VoteStates)
...
======= =========== ===========
value name text
------- ----------- -----------
00 author Author
05 invited Invited
10 watching Watching
20 candidate Candidate
30 assigned Assigned
40 done Done
50 rated Rated
60 cancelled Cancelled
======= =========== ===========
The Votable
mixin¶
A votable, in Lino Noi, is a ticket. But the module is designed to be reusable in other contexts.