20110206

lino.js 1 MB kleiner

Samstag Nacht. Kurz vorm Einschlafen bekam ich die Idee, dass der folgende Punkt doch eigentlich recht einfach machbar sein müsste:

  1. Der JS-Code, der ein Detail-Fenster definiert, wird in der lino.js für jeden Report zweimal generiert (detail und insert). Ein einziges Mal für alle Reports würde reichen.

Also aufstehen und mal nachschauen. In der lino.js sieht es momentan so aus:

Lino.contacts.Persons.detail = function(caller,params) {
  var ww = new Lino.DetailWrapper(caller,{
      fk_name: null,
      url_data: "/api/contacts/Persons",
      content_type: 22, name: "detail"
    },params);
  var last_name1712 = new Ext.form.TextField(...);
  ...
  var main_panel1905 = new Ext.Panel(...);
  var form_panel1906 = new Lino.FormPanel(ww,{
      ls_url: "/contacts/Persons",
      ls_bbar_actions: [ ... ],
      has_navigator: true,
      items: new Ext.TabPanel({ items: [ main_panel1905 ...  ], ... }),
      listeners: { ... },
      before_row_edit: function(record){...},
      ls_detail_handler: Lino.contacts.Persons.detail,
      layout: "fit",
      method: "PUT",
      ls_insert_handler: Lino.contacts.Persons.insert
  });
  ww.main_item = form_panel1906;
  ww.show();
}

Das müsste stattdessen so aussehen:

Lino.contacts.Persons.FormPanel = Ext.extend(Lino.FormPanel,{
  constructor : function(ww,config) {
      var last_name1712 = new Ext.form.TextField(...);
      ...
      var main_panel1905 = new Ext.Panel(...);
      Lino.contacts.Persons.FormPanel.superclass.constructor.call(this, ww,config);
  }
})
Lino.contacts.Persons.detail = function(caller,params) {
  var ww = new Lino.DetailWrapper(caller,{
      fk_name: null,
      url_data: "/api/contacts/Persons",
      content_type: 22, name: "detail"
    },params);
  ww.main_item = new Lino.contacts.Persons.FormPanel(ww,{
      ls_url: "/contacts/Persons",
      ls_bbar_actions: [ ... ],
      has_navigator: true,
      items: new Ext.TabPanel({ items: [ main_panel1905 ...  ], ... }),
      listeners: { ... },
      before_row_edit: function(record){...},
      ls_detail_handler: Lino.contacts.Persons.detail,
      layout: "fit",
      method: "PUT",
      ls_insert_handler: Lino.contacts.Persons.insert
  });
  ww.show();

Gedacht, getan: nach knapp anderthalb Stunden ist die lino.js von 2.791.466 auf 1.754.633 Bytes geschrumpft. Mit genau der gleichen Funktionalität. Also ein Megabyte unnützer Code wurde da generiert und bei jedem neuen Seitenaufruf verschickt!

Refresh nach Einfügen

Und da ich scheinbar so gut in Form bin, schau ich mir auch noch folgenden Bug mal an:

  1. Wenn man in Personen-Suchlisten, Personen (und an einigen anderen Stellen) das Fenster “Einfügen” bestätigt, dann funktioniert das Refresh nicht. Eigentlich müsste er die neu erstellte Suche im Detail anzeigen. Stattdessen zeigt er sie nicht einmal in der Grid an. Da kommt ein TypeError im JS. (Ein einfacher Klick auf Refresh reicht dann)

Tatsächlich, die zwei Tage Zwangspause haben gut getan, auch dieser Punkt war schnell erledigt. Das war, weil ich in Lino.ComboBox die initComponent() falsch definiert hatte. Da wurde die Originalversion überhaupt nicht mehr aufgerufen. Und später versuchte dann einen Store zu entbinden, der noch nicht in einen ArrayStore konvertiert worden war.

Clickable ForeignKeys

Jetzt kommt dieser Punkt dran:

  1. Wenn man auf einen ForeignKey klickt, sollte er kein neues Browserfenster öffnen, sondern lediglich ein neues Fenster.

Ratespiel: wer findet den Fehler im folgenden Code? Ich habe mindestens eine Viertelstunde gebraucht…

Lino.fk_renderer = function(fkname,handler) {
  return function(value, metaData, record, rowIndex, colIndex, store) {
    if (record.phantom) return '';
    if (value)
        var s = '<a href="#" onclick="' ;
        s += handler + '(undefined,{record_id:' + Ext.encode(record.data[fkname]) + '})">';
        s += value + '</a>';
        return s
    return '';
  }
}

Jedenfalls hat Lino jetzt ein irritierendes Verhalten weniger: Wenn man in einer Grid auf einen ForeignKey klickt, um das referenzierte Objekt im Detail zu sehen, öffnet er jetzt nicht mehr ein neues Browserfenster, sondern ein Ext.Window. (Das onclick-Event dieses href ruft den detail-Handler auf dem referenzierten Element.)

Idem für die klickbaren Links in den Erinnerungen im Anfangsbildschirm.

href=javascript: statt onclick=

Gerade sehe ich zufällig, dass ich statt

<a href="#" onclick="foo()">

auch sagen kann:

<a href="javascript:foo()">

Das mach ich, denn dann kriegt der Bentuzer den JS-Code in der Statuszeile angezeigt, wenn er mit der Maus über den Link fährt.

Saving Grid Configs

Der folgende Punkt ist jetzt wahrscheinlich behoben:

  1. Gridkonfigurationen speichern funktioniert nicht. Oder –besser gesagt– wird erst aktiv nach dem nächsten Server-Restart.

Ich logge jetzt außerdem in der system.log, wenn eine Konfiguration gespeichert wird.

Remove obsolete database fields

Hier schon mal eine Liste der Datenfelder, die mit dem kommenden Release rausfliegen:

no_shift
no_weekend
has_family
has_own_car
can_car
can_truck
can_clark
can_bus
it_knowledge
physical_handicap
mental_handicap
psycho_handicap
health_problems
juristic_problems
dependency_problems
social_competence
motivation_lack
fulltime_only
parttime_only
young_children
is_illiterate

lino.repotrs.Report.validate_grid_config() ignoriert jetzt Kolonnennamen, die nicht existieren, und konvertiert die .rpt-Datei automatisch.

New format for grid configurations

Abends habe ich mich dann noch an folgenden Punkt gemacht:

  1. Grid configs
  1. sollten in den config dirs stehen und nicht im DATA_DIR
  2. sollten vielleicht besser YAML statt .py sein.

Das bisherige Format mit allen GCs in einer einzigen .rpt-Datei war nicht gut. Stattdessen mach ichs jetzt wie mit den .dtl-Dateien: pro GC eine Datei. Dateinamen werden wie .dtl-Dateien alphabetischer Reihenfolge eingelesen. Dieser Code ist für beide gleich und sitzt jetzt ebenfalls in lino.modlib.config. GCs haben keinen Namen mehr (an manchen Stellen heißt die betreffende Variable noch “name”, obschon es ein integer ist), und die Standard-GC ist nicht mehr ‘default’ sondern 0 (und hat als Label “Standard”, was aber erst zum Zuge kommt wenn man mehr als eine Ansicht hat)

Release 1.1.2

/releases/2011/0205 ist jetzt bereit und eingecheckt, aber noch nicht in Eupen installiert.