Tuesday, February 13, 2018

Dashboard items and table titles

My yesterday’s changes caused a failure in Lino Welfare:

File "welfare/docs/specs/main.rst", line 49, in main.rst
Failed example:
    for h in soup.find_all('h2'):
        print(h.text.strip())
Expected:
    Benutzer und ihre Klienten ⍐
    Wartende Besucher ⍐
    Meine Termine ⍐
    Meine überfälligen Termine ⍐
    Meine Benachrichtigungen ⍐
Got:
    Benutzer und ihre Klienten ⍐
    Wartende Besucher (Wartet) ⍐
    Meine Termine (Verwaltet durch Rolf Rompen, Daten von 22.05.2014 bis ...) ⍐
    Meine überfälligen Termine (Verwaltet durch Rolf Rompen, Daten von 01.04.2014 bis 22.05.2014) ⍐
    Meine Benachrichtigungen (Empfänger Rolf Rompen, Nein) ⍐

Yes, indeed: lino.core.dashboard.DashboardItem.render_request() should not show the full title (get_title) buy just the get_title_base.

En passant:

  • I changed the symbol used to show a dashboard item in own window from [⍐] (2350) to [⏏] (23CF)
  • I added a new specs page The lino_xl.lib.events plugin (because I was surprised that abovementioned test failure appeared only during welfare, not already in book. With this page it would have appeared earlier.

Lino Tera

I played with the names, labels, titles and references of courses, course lines, teams etc. I am fiddling around based on different (but fuzzy) input sources:

  • feedback from Daniel after looking at the site
  • the imported data I see on their production site
  • what I believe they need

A team in lino_xl.lib.teams is now Referrable (which might require a database migration also for other applications).

Some translations. Verbose names and position in detail of fields Course.user and Course.teacher.

I changed the MyCoursesGiven no longer uses setup_request() and a master_key but simply param_defaults() (like in lino.modlib.users.My). This was needed after the changes in dashboard this morning.

Django migrations in Lino

I started to think a bit more seriously about how Django migrations on a Lino application would look like. Because a restore.py at SPZ Eupen takes two hours. And because I saw how they work at ajapaik.

The fundamental challenge is that a Lino application can inject fields (i.e. one plugin causes a field to be created on a model in another plugin) and can have conditional fields (plugins whose database structure depends on some local setting). This challenge was easier than I feared, thanks to Django’s MIGRATION_MODULES setting: we define one common migrations module for all plugins of a given application. New site attribute lino.core.site.Site.migration_module. I tried this in lino_book.projects.min9. Seems to work as expected:

$ go min9
$ python manage.py makemigrations

It reveals two more challenges: choices and babel values. Django does not know how to serialize them. I must add a deconstruct() method for these. Seems feasible. To be tested.

Also the default value of ChoiceList fields causes a problem –at least in Python 2– because it uses an unbound method. In a first step I converted all default values in application code from the deprecated default=MyChoices.foo.as_callable form to default=MyChoices.as_callable(‘foo’). Just to discover that this is not enough because it also creates an unbound function. A possible solution could be to simply deserialize them to the choice’s value (which is a plain string) and to make a ChoiceListField interpret them correctly. If that works, we could define the default value of choicelist fields simply as default=’foo’. But will that work on choicelists that get repopulated in a custom_workflows module? We will see…