20100805

Tagsüber

Weiter mit ReportConfig und Kolonnenfiltern.

DONE:

  • Nebenbei: fill.py heißt jetzt initdb.py.
  • Die Antwort auf ein GET mit fmt=json eines Reports hat jetzt neben rows, total und title ein neues Attribut gc_choices, das eine einfache Liste der Auswahlmöglichkeiten für diese Combobox ist.
  • Lino.GridPanel hat jetzt zwei neue config parameter ls_columns und ls_grid_config. In der site.js werden nun diese beiden Parameter statt colModel benutzt. ls_grid_config kann undefiniert sein: das bedeutet, dass keine GridConfig existiert.
  • ReportConfig habe ich nach GridConfig umbenannt (und ReportColumn nach GridColumn).
  • ViewReportRequest fragt einen neuen URI-Parameter gc ab, der den Namen der gewünschten GC enthält.
  • Pro Report kann es auch eine GC mit leerem name geben. Das ist die Standard-Konfiguration. Die ist in der site.js schon berücksichtigt. Also falls ViewReportRequest eine leere gc findet, macht er keine Datenbank-Abfrage.
  • Für die Tests musste ich GridConfigs manuell eingeben, dabei kamen noch einige Bugs beim Speichern raus. Er setzte für AutoField immer einen Wert 0 und deshalb konnte man übers UI höchstens einen Record erstellen. Und man konnte ein normales Textfeld nicht auf leer setzen.

TODO:

  • Wenn eine GridConfig erstellt wird, sollte er automatisch deren Kolonnen erstellen.
  • Wartbarkeit. Was passiert mit den GridConfigs, wenn deren Report verändert worden ist? Prinzipiell kann sich Lino.GridPanel darauf verlassen, dass ls_grid_config sauber ist, weil der Server das kontrollieren kann.
  • In der Lino.GridPanel.tbar kommen zwei neue Elemente: eine ComboBox, in der man die verschiedenen ReportConfigs auswählen kann, und ein Button “Save Config” zum Speichern. Eine andere (bestehende) ReportConfig lädt man, indem man sie in der Combobox auswählt. Neue ReportConfigs erstellt man, indem man in der Combobox einen neuen Namen tippt und dann auf “Save Config” klickt.

17.40 Uhr : Check-In wegen Feierabend.

Abends

19.20 Uhr : Wie gut, dass man manchmal gegen seinen Willen aus der Arbeit rausgerissen wird! Bei der Unterbrechung ist mir aufgefallen, dass es Quatsch ist, die Grid-Konfigurationen in der Datenbank zu speichern; die müssen in schlichten Textdateien auf dem Server liegen! Also system.GridConfig und system.GridColumn kommen wieder raus. Stattdessen wird Report.grid_configs in Report.do_setup() gefüllt, indem er nach einer Datei contacts.Persons.config.js sucht. Für den Anfang dürfte eine Datei pro Report reichen, die alle GC’s dieses Reports enthält. Die Datei wird vom Server generiert und könnte (z.B. für countries.Countries) ungefähr folgenden Inhalt haben:

[
  { name: '',
    columns:[
      [90, 'isocode','ASC',''],
      [150, 'name','',''],
      [90, 'short_code','','']
      ]
  },
  { name: 'by_name',
    columns:[
      [150, 'name','ASC',''],
      [90, 'isocode','',''],
      [90, 'short_code','','']
      ]
  },
  { name: 'only short_code',
    columns:[
      [90, 'short_code','ASC','isnull',false],
      [90, 'isocode','','',''],
      [150, 'name','','','']
      ]
  }

Also eine relativ kompakte Liste von Objekten (eines pro GC). Jede GC hat einen Namen und eine Liste von Kolonnen. Jede Kolonne ist ein Array mit folgenden Feldern:

Für filter_operator begnügen wir uns fürs erste mit Djangos field lookup operators:

exact
contains
gt
gte
lt
lte
startswith
endswith
year
month
day
week_day

in          Liste mit beliebig vielen Werten
range       Liste mit 2 Werten

isnull      true/false

Das UI muss also wissen, welche Operatoren mit welchen Datentypen erlaubt sind und was sie als filter_value brauchen.

Aber bevor ich auf der Serverseite weiter ins Detail gehe, sollte ich wohl besser Ext.ux.grid.GridFilters anschauen.

0.30 Uhr. Dieses Plugin ist super! Obwohl ich zuerst mal anderthalb Stunden lang einen Bug suchen musste. (Ich habe in meinen Kolonnen einfach nur filterable:true konfiguriert. Laut Doku und auch laut Source (GridFilters.addFilters() in examples/ux/gridfilters/GridFilters.js) müsste das klappen, er findet dann den Datentyp selber raus, indem er in den Store schaut. Aber er findet trotzdem für type statt eines Strings (z.B. 'auto') ein Objekt {type:'auto'}. Tilt: Der GridFilters-Plugin verträgt keine Ext.data.Types! Ende gut, alles gut, nachdem die Erklärung gefunden habe, musste ich das natürlich noch ins Forum mitteilen.

Aber jetzt ist erstmal Feierabend!