HL Monitoring Module: Mobile-Support 1.0

Das HL Monitoring Module ist eine schlanke und mächtige Überwachungslösung für komplexe IT-Infrastrukturen. Insbesondere die Überwachung von Datenbanken wie Oracle oder SQL Server liegt hier im Fokus. Ziel meines Projekts war es, eine mobile Version, optimiert für Smartphones und Tablets, zu erstellen.

Zu meiner Person und zum Projekt

Mein Name ist Marvin Nowotny und ich bin seit August 2012 Auszubildender Fachinformatiker für Anwendungsentwicklung bei der Herrmann & Lenz Services GmbH. Bevor ich zu dieser Ausbildung antrat, war ich in einer schulischen Ausbildung zum Informationstechnischen Assistenten. Dort hatte ich meine ersten Programmiererfahrungen in C++ gemacht, wodurch mein Interesse für das Entwickeln von Software geweckt wurde.
Nachdem ich ein Praktikum bei der H&L Services GmbH absolviert hatte, erhielt ich dort einen Ausbildungsplatz. Am Anfang der Ausbildung lernte ich Java anhand von Fachlektüren und gegebenen Aufgaben. Als ich die Sprache gut genug beherrschte, entwickelte ich ein Programm, um unser Monitoring Module auf Belastbarkeit zu testen. Dabei wurde von dem Programm eine große Anzahl an Fake-Daten generiert, die anschließend in unserem Monitoring als Performance-Daten erkannt wurden.
Daraufhin war mein nächstes Projekt eine Mobilversion des Monitorings zu entwickeln. Hier sollte ich das Framework Sencha Touch nutzen, da einige unserer Entwickler in der Vergangenheit bereits damit gearbeitet hatten. Für mich bedeutete das eine weitere Hochsprache zu lernen: JavaScript. Zwar hatte ich bereits mit Java in Eclipse gearbeitet, fühlte mich mit JavaScript dort trotzdem unwohl. Als Alternative nutzte ich während der gesamten Entwicklung Sublime Text 2. Ausgeschmückt mit einigen Packages für Code-Formatierung, JShint-Einbindung und SVN-Plug-In startete ich mein Projekt.

Sencha Touch – das Mobile-Framework

Um Heutzutage eine Mobilversion einer Webapplikation zu erstellen kann man sich mit einigen Frameworks behelfen. Die bekanntesten sind jQuery Mobile, Dojo-Mobile oder Sencha Touch. Alle bieten gewisse Vor- und Nachteile weswegen man sich vor der Entwicklung Zeit nehmen sollte, um das am besten geeignete Framework für das eigene Projekt zu finden. In unserem Falle ist Sencha Touch eine gute Wahl. Es ist für dynamische Inhalte optimiert und es können optional Tools erworben werden, welche die Entwicklung vereinfachen, oder sogar beschleunigen. Zusätzlich nutzt Sencha Touch das Model-View-Controller-Konzept welches der Strukturierung der Applikation dient. Es abstrahiert die Daten (Model), von ihrer Ansicht (View) und der Programmlogik (Controller). Durch dieses Konzept erhält man sowohl robusten, als auch guten wartbaren Code. Das macht ST auch für dynamisch wachsende Projekte einsetzbar.

Da es in JavaScript keine Klassen im Sinne von Java, C oder Python gibt, nutzt Sencha ein eigen entwickeltes Klassensystem. Dieses kombiniert den alten Klassenbasierten-Stil anderer Programmiersprachen mit der dynamischen Struktur von JavaScript. Das macht es dem Anwender viel einfacher den Quellcode zu verstehen. Die Dokumentation bietet neben der klassischen Ansicht über jede Komponente häufig ein visuelles Beispiel. Dies zeichnet sich dadurch aus, das ein virtuelles Smartphone angezeigt wird, dessen Code man jederzeit einsehen sowie ändern kann. Die Änderung kann man durch einen einzelnen Mausklick anzeigen lassen – sofern der Code keinen Fehler auslöst. Neben diesen Beispielen gibt es noch weitere umfangreichere Darstellungen wie beispielsweise die Kitchen Sink. Um endlich mit dem entwickeln beginnen zu können benötigt man neben dem Software Development Kit zusätzlich noch Sencha CMD. Für die Installation und Konfiguration gibt es in der Dokumentation einen ausführlichen Guide, mit dessen Hilfe man recht zügig seine ersten Schritte mit ST machen kann. Mittels der Konsolenanwendung Sencha CMD können spezielle JavaScript-Dateien erstellt werden. Wem hier eine grafische Oberfläche fehlt kann sich mit dem Sencha Architect behelfen.

Oberfläche des Sencha Architect

Oberfläche des Sencha Architect

Das kostenpflichtige Tool (es gibt eine kostenlose Testversion) bietet eine Vielzahl an Einstellungsmöglichkeiten sowie das digitale Endgerät im Zentrum der Anwendung. Während der Entwicklung nutzte ich dieses Programm um die Oberfläche anzupassen, Komponenten zu verschachteln und Anpassungen an vorhandenen Darstellungen vorzunehmen. Natürlich kann man auch komplexe Logik einbinden und während der ganzen Entwicklung mit dem Architect arbeiten. Wenn man mit seinen Komponenten fertig ist, kann man sich im Tab Code den dazugehörigen Quelltext ansehen und nach Belieben übernehmen oder später verändern.
Weitere Tools/Plug-Ins:

Die Entwicklung:

Das Ziel war eine Mobilversion unseres Monitoring-Moduls. Dabei sollten die Daten möglichst kompakt auf einem mobilen Endgerät angezeigt werden können. Außerdem sollte der Nutzer nicht von Informationen erschlagen werden und möglichst einfach auf die Wichtigsten zugreifen können. Zu Beginn sammelte ich was für Views vonnöten waren, um die gewünschten Informationen anzeigen zu können. In meinem Falle sähe eine Liste von Anforderungen wie folgt aus:

  • – Loginscreen
  • – Hauptansicht
    • – Monitoring
      • – Mandantendaten
      • – Hostdaten
      • – Servicedaten
      • – Instanzdaten
    • – Userinformationen
    • – Systeminformationen

Die Struktur lässt bereits vermuten, wann und wo welche Daten anzutreffen sind. Der nächste Schritt ist, sich eine gewisse Vorstellung vom grundlegenden Design zu machen. Ich habe mich an der Desktopversion des Monitorings orientiert und wollte die Komponenten so gut wie möglich übernehmen um den Endnutzer nicht mit neuen Darstellungen zu verwirren. Um größtmöglichen Überblick zu bieten habe ich u. A. ein dynamisches Dashboard erstellt und mich dabei ans Original gehalten.

Dashboard aus dem Monitoring Modul

Portraitansicht HTC One X, Android 4.1.1

Das Problem war hier, das gesamte Dashboard auf dem Smartphone anzeigen zu können, ohne dass ein Element wortwörtlich den Rahmen sprengt. In diesem Fall konnte ich die Beschreibungen der Felder nicht anzeigen, ohne dass die Symmetrie verletzt werden würde. Solch ein Problem lässt sich mit CSS bzw. Sass lösen. Sencha Touch nutzt die Stylesheet-Sprache Sass mit dessen Hilfe, und der von Compass, sich einfach CSS-Dateien erstellen lassen. Der Vorteil von Sass ist, dass CSS-Klassen sehr einfach verschachtelt werden können und auch die Nutzung von Variablen unterstützt wird. Compass kompiliert die SCSS-Datei zu einer CSS-Datei und schlägt Alarm falls die Syntax verletzt wurde. Um nun den Fall abzufangen, das die einzelnen Felder des Dashboards wegen der Definition zu groß werden, kann man in einer Klasse in der SCSS-Datei eine Art Bedingung stellen:

.dashboard-definition {
  body.x-phone.x-portrait & {
    display: none;
  }
}
Wenn man nun einem Feld die Klasse dashboard-definition zuweist, wird dessen Inhalt nicht angezeigt solange das Smartphone vertikal ausgerichtet ist. Sobald aber das Smartphone horizontal ausgerichtet wird werden die Definitionen angezeigt:

Landscapeansicht HTC One X, Android 4.1.1

Mit derselben Technik, die man auch als Responsives Webdesign kennt, wird auf dem Smartphone im Landscapemodus die Tab-Bar am unteren Rand ausgeblendet, da sonst etwa die Hälfte des Displays von statischen Informationen verdeckt wäre.

Gepushte View nach dem Dashboard

Da die Navigation auf dem Smartphone eher schwierig zu realisieren war, nutzte ich das Dashboard um zu jeder Entität mit jedem vorhandenen Status zu gelangen. Jedes Element (auch die Header) der Tabelle sollte, wenn Daten vorhanden sind, zu einer neuen View führen. Dafür erstellte ich einen Listener mit einem individuellen Event das gefeuert wird, sobald ein Element angetippt wird. Die dazugehörige Funktion überprüft zuerst, ob es sich bei dem Element um ein leeres Feld handelt, oder ob wirklich Daten vorhanden sind. Falls ja, werden Status, Entität und ID des Mandanten an eine Funktion übergeben um die gewünschte View anzuzeigen.

Erreichbare Views aus der Hostliste

Ein weiteres Navigationsproblem bestand darin, die Services per Host anzeigen zu lassen. Um von einer Komponente aus mehrere Views anzeigen zu lassen definiert man einfach mehrere Events. In der Liste der Hosts nutze ich den Disclosure-Button (im Screenshot das blaue Pfeil-Icon), der bei Betätigung Informationen über den jeweiligen Host anzeigt. Beim antippen des Listeneintrags selbst, werden alle Services angezeigt, die zu diesem Host gehören. Jedoch gibt es seit der Frameworkversion 2.2 hier ein Problem. Wenn der Nutzer auf den Disclose-Button drückt, werden 2 Events gefeuert: disclose und tap. Dadurch erscheint sowohl ein Overlay mit Informationen zum Host X sowie darunter eine neue Liste mit Services. Als Lösung bietet sich an, über das Event-Objekt auf dessen Target zuzugreifen und damit den Fall abzufangen (natürlich nur in der Funktion des tap-events), das der Nutzer den Disclose-Button gedrückt hat.

       if (e.getTarget('div.x-list-disclosure')) {
			return null;
		}
Dies verhindert zwar nicht das 2 Events gefeuert werden, jedoch wird nur eine Funktion vollständig ausgeführt.   Ein anderes, versionsübergreifendes Problem war das PullRefresh-Plug-In. In der Version 2.0 wurden weder Sortierparameter bei der Aktualisierung übernommen, noch war das Datumsformat frei wählbar. In der Version 2.1 war nur das Datumsproblem behoben, den Sortierparameter musste man per Override selber einbinden. Auch in der aktuellen Version gibt es wieder ein Problem das sich per Override lösen lässt. Das Problem ist, das das Plug-In nicht mehr den Store lädt. Dadurch wird das Event refresh nicht mehr gefeuert wodurch die View nicht weiß, dass es neue (aktualisierte) Daten zum anzeigen gibt. In der neuen Funktion fetchLatest() in PullRefresh.js werden lediglich 3 Objekte erstellt: Danach wird operation mit den Parametern aus dem Store befüllt und schließlich mit Hilfe der read()-Funktion des proxy-Objekts gelesen. Dadurch erscheinen zwar aktuelle Records im Store aber es wird einfach nichts aktualisiert. In der danach aufgerufenen Funktion, onLatestFetched, lässt sich beweisen, dass der Store nach Ausführung neue Records besitzt. In vorherigen Versionen des Frameworks hätte man einfach die refreshFn innerhalb der Plug-In-Konfiguration definiert. Wenn sie nicht explizit angegeben wurde, führte das Plug-In einfach store.load() aus. Seit 2.2.0 aber, muss das Plugin erweitert werden um diese zu ändern. Die Lösung die ich gewählt habe war eine Hilfsklasse zu erstellen, welche das Plug-In erweitert: Alternativ lässt sich auch von hier eine externe Klasse erwerben die die Konfiguration der refreshFn innerhalb des Plug-Ins wieder zulässt.   Nachdem ich mit der Version für das Smartphone fertig war, fehlte noch die passende Oberfläche für Tabletnutzer. Hier bietet das Framework eine simple Lösung: Profile. Ein Profil wirkt immer nur auf der angegebenen Plattform und zeigt somit nur die Dateien an, die in diesem angegeben wurden. Um die Views voneinander zu abstrahieren erstellte ich also 2 Profile – Phone und Tablet. Da ich zuvor keine Profile genutzt hatte musste ich nun aufteilen in Smartphone-spezifisch, Tablet-spezifisch und Universell. Universell sind normalerweise alle Models und Stores da es bei Profilen meist nur um die Oberfläche geht. Aber auch Listen oder beispielsweise das Dashboard können als View für beide Plattformen genutzt werden. Wichtiger hingegen sind die Controller dessen Funktionen je nach View angepasst oder sogar komplett geändert werden müssen. Um eine profilspezifische Datei einzubinden geht man ähnlich vor wie in der App.js: Die angegebenen Dateien finden sich dann, je nach Plattform, in app/controller/phone oder app/controller/tablet. Diese Struktur wird für alle eingebundenen Dateien beibehalten.

Schreibe einen Kommentar