BISO 3 ist das Projekt zur Erneuerung des Sencha ExtJS 4.x-UIs. Wir lösen es mit der neuesten Sencha-Version (aktuell: 7.3) ab. Im gleichen Zug können wir gleich ein paar Anpassungen in der Architektur vornehmen.
Die bisherige Struktur sieht so aus:
. # --> Docker-Volume auf /var/www/html
├── ....
└── webroot # --> Apache-Webroot
├── app.js # Sencha App-Start
├── app # Sencha App
├── config.php # BISO-Projekt-Config (gaia config)
├── backend # BISO-Backend (PHP-Klassen)
├── components # Vendor-Libs
├── data # Userdaten
├── db_migrations
├── packages # Ext-Packages (Thema)
│ └── poseidon
├── reporting # Backend-Reporting-Scripte
└── templates # Kunden-spezifische Backend-Templates
Problematisch an dieser Struktur ist, dass alle Dateien im Webroot liegen, und somit auch vom Webroot aus zugänglich sind.
Das soll mit einer neuen Struktur verhindert werden:
. # --> Docker-Volume auf /var/www/html
├── ....
└── webroot # webroot selber wird vom Webserver aus nicht ausgeliefert
├── public # --> Apache-Webroot
│ ├── app # Sencha App
│ ├── app.js # Sencha App-Start
│ ├── backend # Webroot-Pfad "/backend"
│ │ ├── .htaccess # redirect alle Requests auf index.php
│ │ └── index.php # Bootstrap: gaia-Include ausserhalb public/
│ ├── index.html # Frontend-Startseite (ExtJS start)
│ ├── packages # Ext-Packages (Thema)
│ │ └── poseidon
│ └── components # Vendor-Libs JavaScript (Ext etc.)
├── config.php # BISO-Projekt-Config (gaia config)
├── backend # BISO-Backend (PHP-Klassen)
├── vendor # Vendor-Libs composer (php-only)
├── data # Userdaten
├── db_migrations
├── reporting # Backend-Reporting-Scripte
└── templates # Kunden-spezifische Backend-Templates
Das Webroot, welches der Webserver "sieht", wird also eine Stufe nach unten/innen geschoben. So können alle weiteren Daten, welche nicht vom Web zugänglich sein müssen, ausserhalb des Webroots platziert werden, es werden keine Daten exponiert.
Wie oben aufgezeigt ändert sich für den Entwicklungs-Container folgendes:
/var/www/html wird weiterhin das git-root gemountet.apache-config) umkonfiguriert: das Webroot von Apache zeigt neu auf /var/www/html/webroot/public.Als Konsequenz muss dies dann auch auf den produktiven Systemen so umgebaut werden.
Neu wird die Ordnerstruktur der Ext-Applikation anhand der Datenmodelle, nicht mehr anhand der Funktion organisiert:
Anstatt wie bisher:
app/store/Benutzer.js,
app/model/Benutzer.js,
app/proxy/Benutzer.js,
app/view/benutzer/List.js
wird neu
app/benutzer/Store.js,
app/benutzer/Model.js,
app/benutzer/Proxy.js,
app/benutzer/ListView.js
verwendet.
dev-v3webroot/legacy_app/done-Ordner), wenn wir die Funktion im neuen Code
abgedeckt haben: So stellen wir sicher, dass am Schluss nichts vergessen geht.Neu werden globale Events alle von KP.GlobalEventsController abgehandelt.
Dieser stellt auch die Event-Namen als Statics zur Verfügung, welche
anstelle reiner Strings verwendet werden soll.
Ein globaler Event wird folgendermassen ausgelöst:
Ext.globalEvents.fireEvent(KP.GlobalEventsController.getShowBeratungsfall(), rec.getId());
Alle globalen Events werden direkt von diesem Controller abgehandelt, NICHT mehr von einzelnen View-Controllern!
Anstelle:
let situationStore = Ext.StoreManager.lookup('Situation.Fall');
if (!situationStore) {
situationStore = Ext.create('KP.situation.Store', {
autoLoad: false,
remoteFilter: true,
remoteSort: true,
pageSize: -1,
storeId: 'Situation.Fall'
});
situationStore.getProxy().extraParams.onlyActive = true;
situationStore.load();
}
soll nun das KP.tools.StoreManagerHelperMixin verwendet werden: Diese Helper-
Funktion erstellt den Store anhand der Config, und registriert ihn im StoreManager.
Bei der 2. Verwendung kommt er dann direkt aus dem StoreManager.
// mixins: ['KP.tools.StoreManagerMixin']
{
xtype: 'combobox',
// Mixin definiet this.storeFromManager
store: this.storeFromManager({
type: 'Situation', // store-alias, must
storeId: 'Situation.Fall', // must
// optionale Store-config:
autoLoad: false,
remoteFilter: true,
remoteSort: true,
// auch Extra-Params für den Proxy sind möglich:
proxy: { extraParams: { onlyActive: true } }
}),
},
Neu in ExtJS 7 kann in Ext.data.Store.filter() keine Callback für den load-Event mehr
angegeben werden. Damit wir bei Remote-Stores trotzdem auf den load()-Event nach einem filter() erhalten, haben wir die Methode remoteFilterPromise() auf dem KP.base.Store entwickelt:
store.remoteFilterPromise({
property: 'id',
'value': 4
}).then(() => {
// ... do something
});
// oder:
await store.remoteFilterPromise({
property: 'id',
'value': 4
});
// do something
Im Beratungsfall-Form öffnen wir Unter-Forms (z.B. BF-Termin) nicht mehr in Windows, sondern als weiteres Panel im übergeordneten Card-Layout. Dies ist vom UI her intuitiver und tablet-tauglicher.
Um aus dem Beratungsfall-Form heraus ein Unter-Panel zu öffnen, muss das Beratungsfallpanel
( KP.beratungsfall.BaseForm oder Kindklasse) ein event opencarditem gefeuert werden,
mit der zu öffnenden Komponente als Parameter:
Beispiel:
let fallpanel = this.getFallPanel(); // KP.beratungsfall.BaseForm
let form = Ext.create('KP.bf_notiz.Form');
fallpanel.fireEvent('opencarditem', form);
Bei Listen in der Sublist-Tab-Panel-Komponente wird dies schon selbständig gemacht:
Alle list-Komponenten in beratungsfallform [itemId=sublists] relayen den opencarditem event automatisch: Dort kann also folgendes direkt auf der Grid-Komponente gemacht werden:
let form = Ext.create('KP.bf_notiz.Form');
let verlaufgrid = getVerlaufGridIrgendwie().fireEvent('opencarditem', form);