Merkle Info-Screens
Datum: März 2022
Lesedauer: 80 Minuten
21.03.2023
Individuelle praktische Arbeit
Merkle Info-Screens - Frontend Webapplikation
Abbildung 1: Merkle Info-Screen
Quelle: Selbst erstellt in Figma
Kurzfassung
Ausgangssituation
Am St. Galler Standort der Merkle Switzerland AG hingen an verschiedenen Wänden
ungenutzte Bildschirme. Das Ziel dieser Arbeit war es, ansprechende Inhalte auf diesen
darzustellen. Dazu musste eine neue Webseite von Grund auf erstellt werden.
Diese Applikation ist dazu da, interessante, auflockernde und auch lustige Texte auf vier
verschiedenen Screens, welche von einer Interactive Media Designerin gestaltet wurden,
darzustellen. In einem animierten Ablauf werden die Screens elegant nacheinander gezeigt.
Die Anwendung musste in Nitro, einem Frontend-Setup-Framework, implementiert werden.
Umsetzung
Umgesetzt wurde das Projekt mithilfe der Projektmanagementmethode IPERKA.
Gearbeitet wurde mit Visual Studio Code als Entwicklungsumgebung und GitLab zur
Datensicherung und Protokollierung. Der Einsatz von Jira sorgte für eine gute Übersicht über
die Aufgaben.
Bei der Implementierung dieser Frontend-Webapplikation lag der Fokus auf dem
Nutzererlebnis und der Implementierung der gewünschten Animationen.
Wie vorgegeben, wurde die Lösung mit HTML, CSS und JS in einer Node-Umgebung erstellt.
Gebaut wurden die folgenden vier Screens:
- Welcome: Auf dem ersten Screen wird ein Mitarbeiter oder Besucher begrüsst. Die Nachricht ist abhängig vom Wochentag und der Uhrzeit.
- WeatherLocations: Der zweite Screen stellt Erinnerungen und Regeln dar. Auch diese unterscheiden sich je nach Zeitpunkt.
- Input: Damit wird der Betrachter über das aktuelle Wetter von drei Merkle- Standorten informiert. Um dieses zu ermitteln, kommuniziert dieser Screen auch mit einem externen System.
- Joke: Ein zweiteiliger Flachwitz soll für etwas Auflockerung sorgen.
Ergebnis
Das Ergebnis ist eine attraktive Webapplikation, welche über ein Notebook an den
Bildschirmen angeschlossen werden kann. Sie zeigt einen animierten, flüssigen Ablauf,
welcher mit zeit- und tagesabhängigem Inhalt versehen ist.
Das Projekt hat ein sauberes Setup und entspricht den Merkle-Konventionen. Bevor Änderungen
auf das GitLab-Repository gestellt werden können, werden diese automatisch auf die
Regelkonformität überprüft. Zudem ist es erweiterbar aufgebaut. In Zukunft kann der Durchlauf leicht mit
neuen Screens ergänzt werden.
Projektaufbauorganisation
An diesem Qualifikationsverfahren sind mehrere Personen beteiligt.
Rolle | Abkürzung | Beschreibung |
---|---|---|
Chefexperte | CEX | Aufsicht über die IPA. |
Hauptexperte | HEX | Hauptansprechpartner für KAND und VF. Begleitet VF und KAND durch IPA. |
Nebenexperte | NEX | Stellvertretender Ansprechpartner für KAND und VF während der IPA. Begleitet VF und KAND durch die IPA. |
Berufsbildner | BB | Verantwortlich für die betriebliche Ausbildung des KAND. |
Vorgesetzte Fachkraft | VF | Person, welche dem KAND während der IPA als Ansprechperson zur Verfügung steht. Ansprechperson für die Experten für die jeweilige IPA. |
Kandidat | KAND | Der Lernende, welcher die IPA durchführt. |
Mehr zum Qualifikationsverfahren steht in der Bildungsverordnung (opens in a new tab) geschrieben.
Zeitplan
Diese Excel-Mappe wurde als Anhang abgegeben. Für eine bessere Lesbarkeit empfehle ich die Zeiten dort zu betrachten.
Legende
Die Farben der zwei Gantt-Diagramme sind wie folgt zu interpretieren:
Abbildung 2: Legende
Quelle: Selbst erstellt in Excel
Soll-Zeit
Abbildung 3: Soll-Zeit
Quelle: Selbst erstellt in Excel
Ist-Zeit
Abbildung 4: Ist-Zeit
Quelle: Selbst erstellt in Excel
Arbeitsjournal
Das Arbeitsjournal, welches die Tätigkeiten während der zehn Tage beschreibt, wurde zur Verbesserung der Übersichtlichkeit aus diese Dokumentation entfernt.
Projektdokumentation
Nachfolgend wird das Projekt von der Aufgabenstellung bis zur Auswertung beschrieben.
Projektmanagementmethode
Eine passende Projektmanagementmethode ist die Voraussetzung einer effizienten Entwicklung. Ich untersuchte die gängigsten Varianten und entschied mich anschliessend für die geeignetste.
Vorgehensmodelle können in iterative und sequenzielle Arten unterteilt werden. Iterative
Modelle, wie beispielsweise Scrum, werden in der Softwareentwicklung meist bevorzugt. Sie
ermöglichen die schrittweise Entwicklung und Auslieferung von kleinen Teilen der Software
in kurzen Zyklen.
Hat man aber zu Beginn bereits ein vollständiges Ziel, arbeitet allein oder will den Fokus auf
die Dokumentation richten, ist dies wohl nicht der ideale Ansatz.
In solchen Fällen wählt man besser eines der sequenziellen Vorgehensmodelle, bei welchen
Wert auf klare aufeinanderfolgende Phasen gelegt wird. Dabei wird die nächste Tätigkeit
erst gestartet, wenn der vorherige Schritt vollständig abgeschlossen ist. Im Fokus steht eine
intensive Planungsphase, welche Unklarheiten und Veränderungen während der Umsetzung
minimieren soll. Auch eine strenge Kontrolle und hochwertige Dokumentation wird bei den
meisten dieser Modelle ermöglicht.
Die Entscheidung fiel auf das sequenzielle IPERKA-Modell. Wenn sauber nach IPERKA gearbeitet wird, können alle Punkte aus der Vorgabe abgedeckt werden. Bei diesem Modell wird ein Projekt in sechs Phasen unterteilt:
- Informieren: In einem ersten Schritt analysiert man den Auftrag, sodass man diesen genaustens versteht.
- Planen: Daraufhin beginnt man sich Gedanken über Lösungsvarianten zu machen.
- Entscheiden: Danach fällt man Entscheidungen.
- Realisieren: Im vierten Schritt kann man sich an die Umsetzung machen.
- Kontrollieren: Später wird überprüft, ob der Auftrag korrekt umgesetzt wurde.
- Auswerten: Als Letztes wird reflektiert, wie die Arbeit verlief.
Einen Nachteil hat IPERKA. Fehler werden normalerweise erst nach der kompletten Umsetzung
erkannt. So ist es schwierig, auf diese zu reagieren.
Deshalb werde ich schon während der Realisierung die einzelnen Komponenten testen,
bevor ich sie als fertig ansehe. In der Kontrollphase werde ich dann die Applikation
ganzheitlich auf alle Kriterien überprüfen.
IPERKA ist nicht die einzige sequenzielle Projektmanagementmethode. Auch die Festlegung
auf das Wasserfall- oder V-Modell wäre nicht verkehrt gewesen. Ich bin aber mit IPERKA
vertraut, da ich in der Berufsschulzeit bereits Erfahrungen damit sammeln konnte.
(Bexio, 2020) (Shiklo, 2019) (Augat, 2022)
1 Informationsbeschaffung
Als Erstes musste verstanden werden, warum es nötig ist, diesen Auftrag zu erfüllen. Dies ermöglicht es, die Sicht des Auftraggebers besser nachzuvollziehen.
Die Applikation soll das Büro etwas auflockern, indem sie Informationen darstellt. Beim Entwerfen der Screens wurde bewusst nicht auf das Corporate Design geachtet. So laufen abwechslungsreiche Inputs auf dem Bildschirm durch. Das Ergebnis soll zu einem noch interessanteren Arbeitsalltag beitragen. Der gezeigte Ablauf von Screens besteht aus diesen fünf Teilen:
- Begrüssung (Welcome)
- Reminders & Regeln (Input)
- Wetter Standorte (WeatherLocations)
- Flachwitz (Joke)
- Reminder & Regeln (Input)
Im Figma habe ich diesen Ablauf noch visualisiert:
Abbildung 5: Ablauf Screen-Loop
Quelle: Selbst erstellt in Figma
1.1 Erweiterbarkeit
Die Lösung soll modular sein. Denn die Abfolge der Screens muss leicht konfigurierbar sein. Es muss später auch möglich sein, zusätzliche Screens zu integrieren.
1.2 Ziel
Schlussendlich soll die Applikation auf einem Full HD (1920 x 1080 Pixel) Bildschirm dargestellt werden. Dazu muss die Applikation exportiert, auf einen bereitgestellten Laptop geladen und über HDMI am TV angehängt werden.
1.3 Unklarheiten
Nach der gründlichen Analyse blieb noch eine Frage ungeklärt. Leitfrage 4, Kriterium 6: "Es wird dieselbe Animation für die Übergänge zwischen den Screens verwendet. Die Zeitdauer eines Übergangs kann einfach konfiguriert werden."
Zur Sicherheit wurde bei der VF nachgefragt, ob wirklich die Dauer des Übergangs oder doch
eher die Zeitdauer eines Screens gemeint ist.
Das Kriterium ist aber korrekt formuliert. Es soll die Zeit des Übergangs konfigurierbar sein.
Mit Übergang ist gemeint: Letzte Ebene raus, neuer Hintergrund rein.
Die Screen-Dauer wird dann von den Screens selbst geregelt.
1.4 Projektumfeld
Nachdem ich mir ein Grundverständnis verschaffen konnte, war es an der Zeit, die Aufgabe etwas zu verfeinern. Dafür machte ich mir Gedanken über das Projektumfeld.
1.4.1 Abgrenzungen
Mir gelang es Themen zu identifizieren, welche nicht Teil des Auftrags sind.
Design
Das Design wurde von einer Interactive Media Designerin entwickelt. Als Frontend-
Entwickler darf ich davon abweichen, sofern ich dies begründe. Jedoch liegt es in diesem
Projekt nicht in meinem Aufgabenbereich, Änderungen an den Mockups vorzunehmen.
Assets
Alle benötigten Assets sind bereits organisiert. Die Schriften sind gekauft und die Icons gezeichnet.
Zu meinem Auftrag gehört es, diese korrekt zu exportieren.
Rechner und Bildschirm
Zu meiner Aufgabe gehört es nicht, den Laptop oder TV einzurichten. Diese funktionieren
bereits. Auch ein HDMI-Kabel liegt bereit.
Der Rechner wurde aufgesetzt und hat einen Node-Version-Switcher installiert, um leicht zur benötigten Node-Version zu wechseln.
Jira Erstellung
In diesem Projekt wird Jira eingesetzt, um den Fortschritt verfolgen zu können. Darüber
hinaus fungiert die Software als Dokumentation für zukünftige Entwickler.
Als Vorarbeit wurde bereits ein Jira-Projekt erstellt.
1.4.2 Umsysteme
Von den vier Screens benötigen drei keinen Zugang zu anderen Systemen. Diese greifen auf
lokal gespeicherte, strukturierte JSON-Dateien zu. Der WeatherLocations Screen ist eine
Ausnahme. Auf diesem wird das Wetter dreier zufälliger Standorte angezeigt. Diese Daten
können aber nicht fix in der Applikation festgehalten werden. Denn sie sind zum jetzigen
Zeitpunkt noch nicht bekannt.
Ich muss jetzt aber auch keine eigene Wetterstation bauen. Da der Rechner eine
Internetverbindung hat, ist es möglich, eine API anzusprechen.
Eine API ist eine Schnittstelle. Diese kann von meiner Applikation genutzt werden. Dazu
sende ich eine Anfrage an einen sogenannten Endpoint und warte auf eine Antwort. Was
genau hinter dieser API geschieht, ist für die eigene Applikation nicht entscheidend.
Der Auftrag gibt eine API namens "OpenWeather" vor.
Die Firma hinter dieser API sammelt Daten aus Wettermodellen, Satelliten, Radaren und
Wetterstationen.
Über einen API-Call erhält man Zugriff auf das aktuelle Wetter von über 200'000 Städten.
Damit können bestimmt auch alle neun vorgegebenen Standorte abgedeckt werden.
(OpenWeather, 2023)
Die Wetterdaten dieser Standorte sollten dann von der Applikation für eine Stunde gespeichert werden. Erst danach muss erneut abgefragt werden.
1.4.3 Assets
In diesem Projekt besteht auch eine Abhängigkeit von den Schriften und Icons. Vor der
Implementierung muss sichergestellt werden, dass diese Assets funktionieren. Deshalb
wurde bei den zwei Schriftarten getestet, ob diese auch Umlaute kodiert haben. Bei beiden
Schriften ist dies der Fall.
Auch die Icons mussten zuvor untersucht werden. Dazu wurden diese aus dem Figma
exportiert und im Browser geöffnet. Beim ersten Mal hatten die Rahmen unschöne,
transparente Striche drin. Unsere Designerin konnte dieses Problem aber beheben.
Ich habe also die Sicherheit, dass die Icons keine Probleme verursachen können.
1.4.4 Visual Studio Code
Visual Studio Code wurde als IDE vorgegeben.
Ich werde mit der Version 1.76 vom Februar 2023 arbeiten.
Um die Entwicklung noch etwas effizienter zu gestalten, installierte ich bereits während meiner Ausbildung ein paar Extensions. Von diesen werde ich in diesem Projekt auch Gebrauch machen:
- Svg Preview: Damit können SVGs direkt in VSC betrachtet werden.
- Auto Rename Tag: Diese Extension erkennt das Umbenennen eines Tags und passt den Opening- oder Closing-Tag automatisch an.
- EditorConfig for VS Code: So wird die vorhandene
.editorconfig
Datei erkannt und dessen Einstellungen angewandt.
1.4.5
Mir wurde vorgegeben, das Nitro-Framework zu verwenden.
Nitro ist ein Frontend-Setup-Framework, welches einem Projekt die grundlegenden
Funktionalitäten zur Verfügung stellt.
Mithilfe des Generators wird die kleine, flexible Node.js-Applikation installiert:
https://www.npmjs.com/package/generator-nitro (opens in a new tab)
1.4.6 Conventions
Im Auftrag wurde beschrieben, dass die Merkle-Conventions eingehalten werden müssen. Die genauen Vorgaben sind im Dokument "Merkle Frontend Conventions IPA" festgehalten. Das Wichtigste habe ich hier nochmals zusammengefasst.
Readme
ede Komponente wird durch ein Readme beschrieben.
Atomic Design
Eine Applikation wird modular mit Patterns aufgebaut. Patterns sind wiederverwendbare
Komponenten. Diese müssen sinnvoll benannt und Typen wie Atomen, Molekülen oder
Organismen zugewiesen werden.
Klassennamen müssen dann so gewählt werden, dass die Art der Komponente am Prefix
erkennbar ist. Eine Klasse heisst also beispielsweise a-button
.
Mehr über Atomic Design steht in der Dokumentation geschrieben:
https://bradfrost.com/blog/post/atomic-web-design/ (opens in a new tab)
Namics BEM
Bei der Namensgebung einer Klasse muss auch die Namics-BEM-Regel berücksichtigt
werden. BEM ist eine Naming Convention. Diese sorgt für einen modularen und
verständlichen Code.
Werden Elemente direkt über die Tags selektiert, so kann das Styling in CSS schnell
unübersichtlich werden. Dieses Vorgehen führt mit ziemlicher Sicherheit dazu, dass das
Aussehen irgendwelcher Elemente unabsichtlich angepasst wird.
Die BEM-Regeln verschaffen Klarheit. Diese besagen, dass den Elementen block
,
element
und modifier
Klassen vergeben werden müssen.
Block:
Eine Einheit, die allein dastehen kann
Element:
Ein Teil des Blockes
Modifier:
Eine Variante eines Blocks oder Elements
(BEM, 2023)
Das "Convetions-IPA" PDF weist zudem auf die Verwendung zweier Prefixe hin.
js:
Ein js
vor der Klasse signalisiert, dass diese nur in JS genutzt wird.
state:
Solche Klassen haben immer einen Modifier. Sie werden in JS und CSS genutzt.
Struktur
Das Projekt muss eine bestimmte Struktur einhalten. Das CSS und JS einer Komponente
werden beispielsweise immer in den entsprechenden Ordnern abgelegt.
pattern:
css/pattern.scss
js/pattern.js
pattern.html
readme.md
Conventional Commits
Bei der Benennung der Commits und Branches, werde ich mich an die Conventional Commits
halten. Die Regeln findet man hier:
https://www.conventionalcommits.org/en/v1.0.0/ (opens in a new tab)
Die Commits sollten also immer so aufgebaut sein:
<type>(<scope>): <ticket-nr.> <description>
Type:
Mit einer der zur Verfügung stehenden Arten wird gezeigt, um was es sich handelt.
Scope:
Zeigen, was davon betroffen ist.
Ticket-Nr.:
Nummer des Tickets angeben, damit dies später nachverfolgbar ist.
Description:
Eine aussagekräftige Beschreibung im Präsens.
Hier ein Beispiel:
feat(button): JIRBRD-123 add button
Branches
Der Haupt-Branch heisst master
. Davon wird der develop
abgezweigt. Ab diesem werden
dann die weiteren Branches kreiert. Der Workflow sieht also so aus:
Abbildung 6: Git Workflow
Quelle: Selbst erstellt in Pages
Branches werden folgendermassen benennt:
<type>/<ticket-nr.>-<ticket-title>
MR
Merge Requests werden so betitelt:
<ticket-nr.>: <ticket-name>
1.5 Besprechung
Um sicherzustellen, dass ich alles korrekt verstanden habe, besprach ich diese Interpretation des Auftrags mit der VF. Der Auftrag wurde korrekt verstanden. Zum Schluss erhielt ich noch ein paar Tipps:
- Ich soll so viel als möglich auslagern und generalisieren.
- Die Applikation muss nur im Format 16:9 gut aussehen.
- Wenn etwas nicht funktioniert, soll ich das dokumentieren.
2 Planung
2.1 Zeitplan
Nach der Informationsbeschaffung und einer genauen Analyse konnte der Zeitplan erstellt werden. Das Gantt Diagramm ist im Teil 1 unter "Zeitplan" ersichtlich.
2.1.1 Rundung
Vor der Erstellung wurde definiert, wie detailliert die Aufgaben geplant werden sollen. Da ich viele, und darunter auch kleine Aufgaben habe, entschied ich mich dafür, die Arbeitspakete auf eine Stunde genau zu schätzen.
2.1.2 Interpretation
Für die Aufgaben während der Realisierung wurde Zeit für die Dokumentation inkludiert.
Wenn also für einen Screen sieben Stunden eingeplant wurden, darf ein Teil dieser Zeit auch
zur Dokumentierung des Vorgehens genutzt werden.
Hinweis: Am Tag 4 wurde nachträglich eine Zeile "Ungeplante Aufgaben" eingeführt. Auf
dieser können Arbeiten festgehalten werden, welche nicht geplant wurden. Dies betrifft
beispielsweise die Umsetzung von Feedback aus dem Expertengespräch.
2.1.3 Blocker
Für die Informationsbeschaffung und Erstellung des Zeitplans wurde keine genaue Zeit
geschätzt. Dies liegt an IPERKA. Schliesslich konnte erst bei der Planungsphase geplant
werden.
Zu Beginn wurden aber sechs Stunden für diese Phasen blockiert. Dieser Blocker ist an der
gelben Farbe erkennbar.
2.1.4 Ist-Zeit
Während den zehn Tagen werde ich jeden Abend die Zeiten eintragen und einen Soll-Ist-
Vergleich vornehmen. Dieser wird dann im Arbeitsjournal festgehalten. Im Arbeitsjournal
werde ich auch meine Tätigkeiten, auf 15 Minuten gerundet, notieren.
Hinweis: Nach dem Expertenbesuch wurde festgelegt, dass Arbeiten von mindestens 30-
minütiger Dauer aufgelistet werden müssen.
2.1.5 Meilensteine
Der Zeitplan ist gross. Zur Übersicht legte ich deshalb Meilensteine an.
Meilenstein | Tag der Erreichung geplant | Tag der Erreichung |
---|---|---|
Setup (Gitlab, Nitro, Linting, Prettier und CI) | 3 | |
Welcome Screen | 4 | |
Input Screen | 5 | |
WeatherLocations Screen | 6 | |
Joke Screen | 7 | |
Loop mit Animation | 7 | |
Tests erfolgreich | 8 | |
Auswertung erledigt | 9 | |
Abgegeben | 10 |
2.2 Testkonzept
Bevor man mit der Umsetzung beginnt, müssen die Tests definiert werden.
2.2.1 Testmethoden
Da sehr vieles dieser Applikation nur visuell überprüft werden kann, wird die Applikation
nicht mit irgendwelchen Unit-Tests, sondern manuell getestet.
Das Ziel dieser Tests ist es, die Funktionalität, Performance und das Aussehen zu
untersuchen.
In einem Nitro-Projekt gibt es bereits zwei Arten von Tests, die leicht implementiert werden
können.
Cypress
Mit Cypress können automatisierte, funktionale Tests geschrieben werden. Dabei geht es
darum, die Funktionen einer Komponente zu überprüfen. Es wird ein Test implementiert,
der immer bestanden werden muss. Nach Änderungen an einer Komponente ist dann
schnell zu erkennen, ob diese noch die Erwartungen erfüllt.
Mehr über Cypress erfährt man auf der Webseite: https://www.cypress.io/ (opens in a new tab)
Diese Applikation hat aber nicht viele Funktionalitäten, welche gut automatisiert getestet werden könnten. Das meiste kann nur überprüft werden, indem eine Person die visuellen Resultate betrachtet.
Backstop
Im Projekt sind auch visuelle Tests vorzufinden.
Mit visuellen Tests kann sichergestellt werden, dass sich das Aussehen einer Komponente
oder Seite nicht verändert hat. Dazu gleicht Backstop Referenz-Bilder mit neu erstellten
Screenshots ab. Gibt es Veränderungen, so werden diese dargestellt.
Dies ist Backstops Webseite: https://github.com/garris/BackstopJS (opens in a new tab)
In diesem Projekt wäre es aufwändig, Backstop einzusetzen. Denn die Screens sind sehr animiert. Da ist es schwierig, die Screenshots zum richtigen Zeitpunkt zu erstellen.
Schlussfolgerung
Aus den genannten Gründen wird bewusst auf automatisierte Tests verzichtet. Die Applikation soll auf zwei verschiedene Weisen getestet werden:
- Technisch: Manche Tests verlangen es, etwas aus technischer Sicht zu betrachten. Also eine Art Black-Box-Testing. Dies gilt beispielsweise für die Überprüfung des URL-Query- Parameters, die Suche nach Memory Leaks, die Untersuchung der Browserkonsole und beim Linting.
- TV: Auf dem Bildschirm wird getestet, ob das Verhalten und Design den Anforderungen entsprechen.
Bei jedem Testfall ist in der Spalte "Art" jeweils einer dieser zwei Begriffe angegeben. Dadurch ist nachvollziehbar, in welcher Umgebung die Tests durchgeführt wurden. Hinweis: Dinge zum Vorgehen werden nicht getestet. Dazu gehört beispielsweise die Einhaltung der Commit Conventions. Dies wird später unter "Auswertung" überprüft.
2.2.2 Testdaten
Es werden Wetterdaten zu Testzwecken zur Verfügung gestellt. Ansonsten muss nichts beachtet werden.
2.2.3 Testumfeld
Durch die zwei Arten von Tests gibt es auch mehrere Testumfelder.
Technisch
Die technischen Untersuchungen werden direkt auf einem Laptop durchgeführt.
TV Die Applikation wird mit den folgenden Schritten auf dem TV getestet:
- Applikation exportieren:
npm run nitro:server
dist
Ordner per USB-Stick auf den Rechner kopieren- Mit der Kommandozeile in den
dist
Ordner navigieren - Mit
nvs use
zur korrekten Node-Version wechseln - Pakete per
npm i
installieren - Software starten:
npm start
- Port aus der Konsole lesen und die Anwendung im Chrome-Browser per Localhost öffnen
- Stockwerksbildschirm einschalten und Laptop mit HDMI-Kabel verbinden
- Displayeinstellungen des Rechners anpassen, sodass "Only Extended Display"
F11
klicken, um den Browser im Fullscreen anzuzeigen- Laptop zuklappen
2.2.4 Testmittel
Technisch
Für die technischen Tests wird ein MacBook Pro aus dem Jahr 2019, ein Chrome Browser
und die Visual Studio Code Entwicklungsumgebung benötigt.
TV
Die folgenden Testmittel sind bei der Überprüfung auf dem Bildschirm im Einsatz:
- Bildschirm (Full HD, 1920 x 1080 Pixel)
Die Auflösung des Bildschirms ist ein entscheidender Punkt. Die Webapplikation ist nämlich nicht responsive, sondern genau auf diese Masse zugeschnitten.
Will man auf einem anderen Gerät testen, so muss man die Dimensionen im Browser dementsprechend anpassen. Trotzdem gebe ich keine Garantie, dass es auf anderen Endgeräten funktioniert. - Laptop
- Verbunden mit dem "Innovating" WLAN (benötigt für die Kommunikation mit der API)
- Chrome-Browser
- Windows-Betriebssystem
- NPM (zum Starten der Applikation)
- NVS zur Installation der Node-Version
- HDMI-Anschluss
- HDMI-Kabel zur Verbindung der Geräte
2.3 Testfälle
Nachfolgend sind alle Testfälle definiert. Diese decken alle relevanten Kriterien des Auftrages ab.
Basisarbeiten
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
1.0 | Technisch | Erstellung Git-Repository | Auf git.namics.com gehen und nachschauen, ob das Projekt vom Nutzer "Kay Wild" erstellt wurde. | Repository ist unter den persönlichen Projekten auffindbar. |
1.1 | Technisch | Generierung Nitro-Projekt | Es wird überprüft, ob ein Nitro-Projekt existiert. In der .node-version Datei wird die Version überprüft | Ein Nitro-Projekt wurde mit einer möglichst aktuellen Node-Version erstellt. |
1.2 | Technisch | Lauffähigkeit Projektexport | Das Projekt wird wie im README.md beschrieben exportiert und gestartet. | Die Applikation ist lauffähig. |
1.3 | TV | Darstellung Screens in Loop | Die Applikation wird im Browser geöffnet und während fünf Minuten beobachtet. | Die Screens werden durchgehend im folgenden Ablauf angezeigt: Welcome -> Input -> WeatherLocations -> Joke -> Input |
1.4 | TV | Zufälligkeit der Inhalte und Farbvarianten | Die Applikation wird im Browser geöffnet und während fünf Minuten beobachtet. | Es werden zufällige Farben und Inhalte dargestellt. Keine Muster sind erkennbar. |
Standards und Conventions
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
2.0 | Technisch | Qualität README.md | Im Root des Projektes wird nach dem File gesucht. Dieses wird sorgfältig durchgelesen. | Die Datei ist aussagekräftig und enthält Informationen zum Projektsetup. |
2.1 | Technisch | Run-Scripts | package.json wird untersucht und die Scripts werden ausprobiert. | Alle vorhandenen Scripts können ausgeführt werden. Es sind keine unrelevanten Aufgaben enthalten. |
2.2 | Technisch | Sensible Daten im Repository | Das Ergebnis eines Security Analyzers wird angeschaut. | Die Analyse zeigt, dass das Repository sauber ist. |
Linting und Testing
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
3.0 | Technisch | Konfigurationen für Linting und Testing | README.md wird gelesen. | Es ist verständlich, wie das Linting und Testing ausgeführt werden kann. |
3.1 | Technisch | Githook | Ein Commit wird getätigt. | Alle im package.json unter lint-staged aufgeführten Scripts werden ausgeführt. |
3.2 | Technisch | Prettier und Linter | Die folgenden zwei Befehle werden in der Konsole ausgeführt: npm run lint npm run prettier | Es werden keine Probleme in der Konsole gemeldet. |
3.3 | Technisch | CI-Pipeline | Auf git.namics.com wird überprüft, ob bei den Pushes jeweils gelintet wurde. | Es ist ersichtlich, dass bei jedem Push das linting Script ausgeführt wurde. |
Verwendbarkeit der Applikation auf einem Screen im Merkle Office St. Gallen
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
4.0 | TV | Darstellung Stockwerkscreen | Projekt wird wie beschrieben exportiert und auf dem Bildschirm gestartet. | Die Applikation wird sauber dargestellt. |
4.1 | TV und technisch | Stabilität | Die Applikation wird während einer Stunde auf dem TV laufen gelassen. Danach wird die Seite im Inspect- Modus untersucht. | Nach einer Stunde sind weder Memory Leaks noch Fehler in der Browserkonsole erkennbar. |
4.2 | TV | Animationen | Gestartete Applikation wird im Browser beobachtet. | Die Animationen werden ohne Ruckeln dargestellt. |
4.3 | TV | Datums- und Zeitsteuerung | URL-Query-Parameter wird getestet. Dabei werden drei verschiedene Tage und Zeitpunkte ausprobiert. Beispiel: ?date=2023-02-20&time=09-30 | Die Screens müssen Daten anzeigen, welche zum Wochentag und der Uhrzeit passen. |
4.4 | TV | Übergänge | Die Übergänge des Screens werden genaustens angeschaut. | Die Animationen zwischen den Screens sind fliessend und ohne Wartepausen. |
4.5 | TV und technisch | Auslagerung Animationsdauer | In einem ersten Schritt wird überprüft, ob dieselben Übergänge zwischen den Screens angezeigt werden. Danach wird der Code untersucht. Dort soll die Dauer leicht umgestellt werden können. | Es werden dieselben Übergänge zwischen den Screens verwendet. Die Dauer der Übergänge soll an einem Ort für alle Screens konfigurierbar sein. |
Screen Welcome und Input
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
5.0 | Technisch | Speicherung Inhalte und Regeln | Es wird im Projekt nachgeschaut, ob die Daten sinnvoll angelegt wurden. | Es sollte ein sinnvoll strukturiertes JSON-File vorhanden sein. |
5.1 | TV | Animationen | Applikation wird gestartet und die Animationen angeschaut. | Die Elemente erscheinen und verschwinden gemäss der Designvorgabe. |
5.2 | Technisch | Einhaltung Regeln | Es wird mit den Regeln verglichen, ob auch die korrekten Inhalte dargestellt werden. | Die Auswahl der Inhalte sollte genau eingehalten werden. |
5.3 | TV | Schrift | Es wird überprüft, wie die Schrift aussieht. | Es wurden die vorgegebenen Webfonts (Plage Bold und Proxima Nova) angezeigt. Die Texte sind zentriert. |
5.4 | TV | Darstellung Text Welcome Screen | Der Welcome Screen wird angeschaut. | Der Begrüssungstext und der optionale Sekundärtext werden beide jeweils in einer Zeile dargestellt. |
5.5 | TV | Darstellung Text Input Screen | Die Daten des Screens werden so manipuliert, dass ein langer Text angezeigt wird. Daraufhin wird der Input Screen angeschaut. | Der Text läuft trotz des langen Textes nicht über mehr als drei Linien. Wenn der Text sehr lange ist, wird er auslaufend mit drei Punkten abgeschnitten. |
Screen Joke
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
6.0 | Technisch | Speicherung Inhalte | Es wird im Projekt nachgeschaut, ob die Daten sinnvoll angelegt wurden. | Es sollte ein sinnvoll strukturiertes JSON-File vorhanden sein. |
6.1 | TV | Darstellung Text | Der Screen wird mit verschieden langen Witzen angeschaut. | Der Text wird in einer fixen Grösse ausgegeben. Falls dieser aber zu lang ist, wird die Schriftgrösse verkleinert. |
6.2 | TV | Animation | Es wird angeschaut, wie der Flachwitz aufgelöst wird. | Die Texte werden, wie in der Designvorgabe beschrieben, ein- und ausgeblendet. |
6.3 | TV | Pulsieren | Beim Anschauen des Screens wird auf das Pulsieren geachtet. | Der erste Text pulsiert zweimal und wird ca. acht Sekunden gezeigt. Der zweite Teil pulsiert nur einmal. |
6.4 | TV | Hintergrundfarbe | Der Screen wird über mehrere Durchläufe hinweg betrachtet. | Die Hintergrundfarbe wird in jedem Durchlauf zufällig ausgewählt. Es sind keine Regelmässigkeiten erkennbar. |
6.5 | Technisch | Konfigurierbarkeit | Im Code wird nach einem Ort gesucht, an welchem die Dauer des Ablaufs konfiguriert werden kann. | Die Parameter für die Anzeigezeiten des Ablaufs sind auffindbar und konfigurierbar. |
Screen WeatherLocations
Nr. | Art | Was wird getestet? | Wie wird getestet? | Erwartetes Ergebnis |
---|---|---|---|---|
7.0 | TV | Animation | Es wird beobachtet, wie sich der Screen auf- und abbaut. | Der Screen wird gemäss der Vorgabe animiert. |
7.1 | TV | Auswahl Standorte | Die Standorte des Screens werden über mehrere Durchläufe hinweg beobachtet. | Es werden immer drei zufällige Standorte dargestellt. Keinerlei Regelmässigkeiten sind erkennbar. |
7.2 | TV | Darstellung Wetterdaten | Das angezeigte Wetter auf dem Screen wird betrachtet. Die Temperaturen werden durch eine Recherche überprüft. | Die Temperaturen sind korrekt und sinnvoll gerundet. Die Icons entsprechen auch den korrekten Werten. |
7.3 | TV | Zwischenspeicherung Daten | Die Liste der Standorte wird auf drei reduziert. Nach einem Durchlauf sollten alle Standorte zwischengespeichert sein. Der Rechner wird dann vom Internet getrennt. So ist erkennbar, ob versucht wurde, die API anzufragen. | Obwohl der Client kein Internet mehr hat, werden noch Wetterdaten angezeigt. |
7.4 | TV | Farblicher Fokus | Die Animation des Screens wird beobachtet. | Die einzelnen Standorte werden nacheinander farblich fokussiert. Auch die Outlines werden korrekt eingesetzt. |
7.5 | TV | Umgang mit Fehlern | Der Rechner wird vom Internet getrennt. Nach ein paar Minuten wird die Internetverbindung wiederhergestellt. | Der Screen wird schnell beendet und bei zukünftigen Durchläufen ausgelassen. Nachdem der Rechner wieder mit dem Internet verbunden ist, wird auch der Screen wieder angezeigt. |
3.4 Jira Tickets
Mithilfe von Jira-Tickets kann der Zwischenstand laufend verfolgt werden. Die Tickets werden wie folgt aufgebaut:
Inhalt | Beschreibung |
---|---|
Name | Ein aussagekräftiger Name soll das Ticket beschreiben. |
Definition of Ready | Im ersten Abschnitt werden die DoR-Kriterien beschrieben. Da wird aufgeführt, was erledigt sein muss, damit mit dem Ticket gestartet werden darf. |
Todo | Unter Todo wird aufgezeigt, was die Aufgabe ist. Dieser Abschnitt darf auch mit Hinweisen versehen werden. |
Definition of Done | Im letzten Teil werden die Akzeptanzkriterien notiert. Ein Ticket ist erst fertig, wenn diese erfüllt sind. |
Platziert wurden die Tickets dann auf einem Kanban Board. Dieses verfügt über die vier
Spalten BACKLOG
, SELECTED FOR DEVELOPMENT
, IN PROGRESS
und DONE
.
Alle bisherigen Ticktes sind Pflicht für die Erfüllung dieses Auftrags und deshalb unter
SELECTED FOR DEPLOYMENT
platziert.
Falls während der Entwicklung noch Ideen für Verbesserungen oder Erweiterungen
entstehen, können Tasks im Backlog erstellt werden.
Abbildung 7: Jira Kanban Board
Quelle: Screenshot Jira
Die Priorisierung wurde auch direkt bei der Erstellung vorgenommen. Je weiter oben sich
eine Aufgabe befindet, desto relevanter ist diese.
Die Reihenfolge wurde vom Zeitplan übernommen.
2.5 Datensicherung und Versionierung
Es ist wichtig, dass Daten vor Verlust geschützt sind. Zudem ist auch eine Wiederherstellung
älterer Versionen von Nutzen.
Der Sourcecode wird dementsprechend auf GitLab abgespeichert und ist so versioniert und
protokolliert. Lokale Änderungen werden dazu zu sinnvollen Zeitpunkten gepushed.
Die Dokumentation und der Zeitplan werden auf dem firmeninternen SharePoint abgelegt
und der VF freigegeben. Jeden Tag wird eine neue Hauptversion erstellt.
Zudem sichere ich die Dokumente täglich auf einen USB-Stick.
2.6 Wetter API
Um die Kommunikation zwischen den Komponenten zu visualisieren, wurde ein Flussdiagramm erstellt.
Abbildung 8: Flussdiagramm Kommunikation
Quelle: Selbst erstellt in lucid.app
2.6.1 AJAX
AJAX steht für "Asynchronous JavaScript and XML". AJAX ist keine Programmiersprache,
sondern eine Technik, um von einer Webseite aus einen Webserver zu erreichen.
Über die Jahre hinweg kamen einige Technologien auf, die diese Methode nutzen. Fetch ist
aktuell die modernste und leistungsfähigste Variante. Sie erschien 2015 und hat seine
Ähnlichkeiten mit dem älteren HTMLHttpRequest, bietet aber bessere und flexiblere
Features.
Nahezu alle Entwickler, einschliesslich jener von Plattformen wie Amazon und YouTube, bevorzugen diese Methode aufgrund der folgenden Vorteile:
- Moderne und einfache Syntax
- Viele Features (GET und POST, JSON, Headers)
- Lightweight
- Einfache Fehlerbehandlung
- Unterstützung durch moderne Browser
- Asynchrones Verhalten
2.6.2 Fehlerbehandlung
Eine API ist auch eine Abhängigkeit. Deswegen muss man damit umgehen können, wenn diese nicht erreichbar ist. Dies ist unter zwei Umständen der Fall:
- Bei einem Ausfall der API. Laut der Webseite hat die Schnittstelle eine Uptime von 95 Prozent. Ausfälle können also vorkommen. (OpenWeather, 2023)
- Falls die Internetverbindung des Rechners ausfällt. In solchen Fällen muss der Screen möglichst schnell beendet werden. Daraufhin soll er selbständig prüfen, ob die API wieder erreichbar ist.
2.6.3 Mock Daten
Laut den Angaben der API sind 60 Aufrufe pro Minute und eine Million im Monat kostenlos. Um zu testen, sollen trotzdem Mock Daten erstellt werden. Mock Daten sind vorgefertigte Werte, welche genutzt werden können, um ein Verhalten zu simulieren. (OpenWeather, 2023)
2.7 Daten
Nicht nur der Wetterscreen, sondern auch alle anderen benötigen Daten. Hierbei stellt sich die Frage, wo diese abgelegt werden.
2.7.1 Data Ordner
Eine Komponente in Nitro hat oft einen _data
Ordner. Darin werden leicht pflegbare
Daten, wie beispielsweise Titel, Texte oder URLs gespeichert. Diese Daten werden dann
direkt in der View dargestellt.
In diesem Projekt müssen die Daten in JS verwendet werden können. Um dies zu erreichen,
müsste man mit dieser Variante zuerst die View befüllen und dann in JS die Werte auslesen.
Dies ist also nicht die beste Variante.
2.7.2 Public Ordner
Im public
Ordner legt man Dateien ab, die dann im Projekt genutzt werden können. Unter
anderem befinden sich die Assets dort.
2.7.3 Routes
In Nitro kann man eigene Routes definieren. Eine Route ist ein API, welche mit JS geschrieben wird. Es ist möglich, die Daten bei der Route zu speichern und dann diese anzufragen. Der Vorteil dabei ist, dass der Service schon einen Teil der Logik übernehmen kann. Z. B. kann man diesen so schreiben, dass bei der Anfrage nur drei zufällige Standorte zurückgegeben werden. So muss man nicht zwingend alle Standorte abfragen und dann in der Komponente selbst entscheiden.
2.8 Architektur
Auch wenn es in diesem Frontend-Projekt nicht leicht ist, will ich
mich so gut als möglich an die 3-Layer-Architektur halten. Dazu
wird die Software in die drei Schichten "Präsentation",
"Anwendung" und "Datenhaltung" unterteilt.
Jede Schicht ist für eine Aufgabe zuständig und kommuniziert mit
der direkt darüber- oder darunterliegenden.
Dadurch werden die Verantwortlichkeiten klar getrennt, weshalb
ganze Schichten auch leicht ausgetauscht werden können.
In meinem Fall gehören die Views zur Präsentationsschicht. Diese
beinhalten keine Logik, sondern zeigen lediglich die Daten an. Im JS
ist die Logik der Anwendung.
Die Daten werden an einem der zuvor beschriebenen Orte
abgelegt.
Neben den Screens wird es einen Controller geben. Dieser ist aber kein typischer MVC-Controller, sondern ein Helper, welcher die Screens steuert.
Abbildung 9: 3-Layer- Architektur
Quelle: Selbst erstellt in lucid.app
2.9 Node Version
Wichtig bei der Installation ist, dass man eine passende Node-Version verwendet. Laut den
momentanen Anforderungen sind die 16.x und 14.x LTS-Versionen erlaubt.
Mit meinem installierten Node Version Switcher werde ich die bestmögliche Version
ausfindig machen und installieren.
(NodeJS, 2023) (Merkle, 2023)
2.10 Screen Klasse
Alle vier Screens haben Gemeinsamkeiten. Demnach erachte ich es als sinnvoll, eine Screen
Klasse anzulegen. Diese könnte dann Redundanzen vermeiden, indem sie Funktionen enthalten,
welche für alle Screens von Nutzen sind.
So könnte diese Klasse aussehen:
Abbildung 10: UML Klassendiagramm Screen
Quelle: Selbst erstellt in lucid.app
Dies ist aber erst eine Idee. Bei der Umsetzung könnten sich die Attribute und Methoden noch ändern.
2.11 Schriften
In diesem Projekt werden zwei Schriften verwendet:
- Plage Bold Text
- Proxima Nova
3 Entscheidung
In der dritten IPERKA-Phase können Entscheidungen getroffen werden.
3.1 Nitro Setup
Wie man ein Nitro-Projekt generieren kann, steht in dieser Anleitung beschrieben:
https://github.com/merkle-open/generator-nitro/tree/develop/packages/generator-nitro (opens in a new tab)
Bei der Installation muss ich dann auswählen, wie das Projekt aufgesetzt werden soll. Ich entschied mich für das folgende Setup:
Abfrage | Erklärung | Möglichkeiten | Meine Wahl | Begründung |
---|---|---|---|---|
Desired name | Name des Projektes | Freie Wahl | merkle-info-screens | Aussagekräftig |
Desired js compiler | JS- oder TS-Projekt erstellen | js / ts | js | Ich bin erfahrener in JS. |
Desired template engine | Ob man Handlebars oder Twig als Template Engine verwenden will. | hbs / twig | hbs | Ich kenne hbs besser. |
Including example code | Ob das Projekt mit Beispielcode erstellt werden soll. | y / n | n | Ich will von der grünen Wiese starten. |
Static exporting functionalities | Ob der Exporter, welcher die Files zusammenstellen und exportieren kann, hinzugefügt werden soll. | y / n | n | Das Projekt muss nicht statisch exportiert werden können. Der Export soll dynamisch sein. |
Using client side templates | Ob man dynamische Daten beim Client rendern will. | y / n | n | Benötige ich nicht. |
Using theming features | Ob man Theming einsetzen will. | y / n | n | Ich muss kein Theming einbauen. |
3.2 Packages
Als Programmierer muss man nicht alles von Grund auf selbst entwickeln. Es gibt Pakete, welche einem etwas Arbeit abnehmen können.
3.2.1 Darstellung Schrift
Mit Vanilla-JS und CSS kann ein Text nicht leicht dem Elternelement angepasst werden.
Deshalb werde ich ein Paket installieren, welches mir diese Aufgabe abnimmt.
Ich habe drei passende gefunden und diese miteinander verglichen:
Paket | Link | Snyk Health Score |
---|---|---|
fitty | https://www.npmjs.com/package/fitty (opens in a new tab) | 59 |
textfit | https://www.npmjs.com/package/textfit (opens in a new tab) | 51 |
use-fit-text | https://www.npmjs.com/package/use-fit-text (opens in a new tab) | 50 |
Die Health Score wurde von Snyk berechnet und gibt mit einem Wert zwischen 0 und 100
Auskunft über die Gesundheit eines Pakets. Bei der Berechnung dieses Wertes wird die
Sicherheit, Popularität, Pflege und Community untersucht.
Dies ist die Snyk-Webseite: https://snyk.io/advisor (opens in a new tab)
Neben dem Health Score achtete ich bei der Suche vor allem darauf, wie gut die Libraries mit den Anforderungen übereinstimmen. Dazu half es, ein Augenmerk auf die Dokumentation zu richten. Auch die Kosten und Grösse mussten beachtet werden.
Meine Entscheidung fiel aus mehreren Gründen auf Fitty. Denn es ist...
- ... sehr beliebt.
- ... nicht zu gross.
- ... mir bereits bekannt.
- ... sicher.
Es ist aber wichtig im Hinterkopf zu behalten, dass Fitty nicht mehr unterhalten wird.
Nach dieser Entscheidung stehen alle Packages fest:
Name | Beschreibung | Link | Snyk Health Score |
---|---|---|---|
@gondel/core | Damit kann in Nitro eine Verknüpfung zwischen den Komponenten und dem JS hergestellt werden. | https://www.npmjs.com/package/jquery (opens in a new tab) | 49 |
jquery | jQuery ist eine JS-Library. Damit kann vereinfachter JS-Code geschrieben werden. | https://www.npmjs.com/package/jquery (opens in a new tab) | 93 |
fitty | Passt die Grösse des Textes automatisch dem Parent Container an. | https://www.npmjs.com/package/fitty (opens in a new tab) | 59 |
3.3 Daten
In der Planung wurden Methoden zur Speicherung von Daten aufgeführt.
Hier entscheide ich mich für die Implementierung einer Route.
Ich werde also unter api/service/route
eine JS-Datei anlegen, welche die JSON-Daten
liefern kann.
Es stellt sich aber noch die Frage, ob alle Daten auf einmal geholt und dann in den
Komponenten verarbeitet werden oder der Service die Logik bei sich hält und nur bestimmte
Daten zurückliefert.
Damit nicht unnötige Daten versendet werden, entscheide ich mich für letzteres.
3.4 Screen WeatherLocations
3.4.1 API
OpenWeather stellt die Daten in den Formaten JSON, XML und HTML zur Verfügung. Ich werde JSON-Daten verlangen, da dieses Format in Kombination mit JS sehr geeignet ist. Die JSON-Daten sind einfach zu lesen und zu schreiben und können einfach in ein JS-Objekt konvertiert werden.
3.4.2 Speicherung
Die geholten Daten könnte ich für eine Stunde in Cookies oder im LocalStorage speichern. Jedoch würde diese Implementierung Zeit kosten. Aus diesem Grund werde ich die Wetter in einer lokalen Variable abspeichern und mit einem Zeitstempel versehen. Vor einer Abfrage soll dann überprüft werden, ob noch eine aktuelle Temperatur vorhanden ist.
3.5 Keyframes oder Transitions
In CSS können Animationen mit Keyframes und Transitions erstellt werden. Ich werde hauptsächlich Transitions einsetzen. Denn diese sind ideal, um zwischen zwei Status zu animieren. Zudem sind Transitions auch performanter und können in JS manipuliert werden. Ich beschränke mich aber nicht nur auf Transitions. Denn in ein paar Fällen, wie beispielsweise bei den Bubbles im Welcome Screen, eignen sich Keyframes besser. Denn dort müssen Elemente mehr als nur zwei Status haben.
3.6 Schriftformat
Von den Schriftarten stehen mir mehrere Dateiformate zur Verfügung:
Abkürzung | Schriftart | Beschreibung |
---|---|---|
EOT | Embedded Open Type | Dies ist ein veraltetes Format, welches speziell für den Internet Explorer entwickelt wurde. |
OTF | Open Type Format | Bei diesem Format wurde darauf geachtet, dass es viele Zeichen beinhaltet und von Plattformen unterstützt werden kann. |
WOFF | Web Open Font Format | Die Entwickler von WOFF nahmen sich zum Ziel, eine herausragende Schrift für den Browser zu erstellen. Dies gelang ihnen. Da die Schrift komprimiert wird, kann sie sehr schnell geladen werden. WOFF2 ist die neuere Version. Mit dieser können Schriften sogar noch stärker komprimiert werden. |
Aufgrund der genannten Vorteile, entschied ich mich für WOFF
.
(Pandey, 2023)
3.7 Sonstige Conventions
Natürlich gibt es noch weitere Conventions, an die man sich halten könnte. Wie
beispielsweise die Kennzeichnung einer privaten JS-Methode mit einem Bodenstrich vor
dem Funktionsnamen.
Ich werde mich auf die vorgegebenen Konventionen beschränken.
4 Realisierung
Nachdem die Entscheidungen getroffen wurden, konnte mit der Realisierung begonnen werden.
4.1 Erstellung GitLab Repsitory
Unter git.namics.com konnte ein leeres GitLab Repository erstellt werden.
In der Eingabemaske wurde dann ein Name und die Sichtbarkeit festgelegt. Wichtig dabei
war, dieses Projekt ohne Readme zu initialisieren. Denn nach der Erstellung soll ein neues
Setup gepushed werden.
Abbildung 11: Erstellung Repository
Quelle: Screenshot GitLab
Nachdem das Projekt erstellt wurde, habe ich als erstes den VF mit einer Developer
Rolle
hinzugefügt.
Danach konnte das Repository im Terminal mit dem folgenden Befehl geklont werden:
git clone git@git.namics.com:kwild/merkle-info-screens.git
Daraufhin erstellte ich einen Master Branch:
git switch -c master
4.2 Nitro Setup
Das Setup führte ich wie geplant durch. Dazu waren vier Schritte notwendig.
4.2.1 Node Version auswählen
Zuerst wurde nvs als Node Version Switcher genutzt, um die neuste Major 16 Version zu installieren. Dazu wurde dieser Befehl in der Konsole eingegeben:
nvs
In einem Menü konnte dann "Download another version" ausgewählt werden. Daraufhin
wurde diese Liste mit allen möglichen Versionen angezeigt. Ich wählte die Version 16.19.1
indem ich diese mit den Pfeiltasten auswählte und mit Enter bestätigte.
.-------------------------------------------.
| Select a node version |
+--/\---------------------------------------+
| *) node/17.4.0 |
| *) node/17.3.1 |
| *) node/17.3.0 |
| *) node/17.2.0 |
| *) node/17.1.0 |
| *) node/17.0.1 |
| *) node/17.0.0 |
| [*] node/16.19.1 (Gallium) |
| *) node/16.19.0 (Gallium) |
| *) node/16.18.1 (Gallium) |
| *) node/16.18.0 (Gallium) |
| *) node/16.17.1 (Gallium) |
| *) node/16.17.0 (Gallium) |
| *) node/16.16.0 (Gallium) |
| *) node/16.15.1 (Gallium) |
'--\/---------------------------------------'
Type a hotkey or use Down/Up arrows then Enter to choose an item.
4.2.2 Projekt generieren
Mit dieser Version konnte dann das Projekt generiert werden. Dazu musste der folgende Befehl eingegeben werden:
npx -p yo -p generator-nitro@latest - yo nitro
Damit wurde der Setup-Assistent gestartet. So konnten die Fragen mit den zuvor getroffenen Entscheidungen beantwortet werden.
_-----_ ╭──────────────────────────╮
| | │ Welcome to the │
|--(o)--| │ awe-inspiring Nitro │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What's the name of your app? merkle-info-screens
? What's your desired template engine? hbs
? What's your desired javascript js compiler? js
? Would you like to include theming support? No
? Would you like to include client side templates? No
? Would you like to include the example code? No
? Would you like to include static exporting functionalities? No
Scaffolding your app
4.2.3 Pakete installieren
Nach der Installation wurde eine Node-Version 16.19.0
in die .node-version
Datei
eingetragen. Zum damaligen Zeitpunkt war dies die höchstmögliche mit Nitro kompatible
Version. Um diese dann zu verwenden, wurde nvs use
ausgeführt.
Daraufhin konnte das Projekt mit npm install
installiert werden.
Wie im Kapitel "Entscheidung" beschrieben wird, werden noch weitere NPM-Pakete im Projekt benötigt. Diese zwei Befehle installierten Gondel und jQuery:
npm i @gondel/core
npm i jquery
4.2.4 Aufräumen
Zum Schluss musste das Projekt noch etwas aufgeräumt werden. Schliesslich will man keine unrelevanten Dateien und Konfigurationen im Repository.
Docker
In diesem Nitro-Projekt wird Docker nicht benötigt. Demzufolge entfernte ich alle Docker-
Dateien und Scripts im package.json
.
Testing
Wie im Testkonzept beschrieben steht, kann auf die Backstop- und Cypress-Tests verzichtet
werden. Aus diesem Grund wurde der Testordner und alle Test-Scripts aus dem
package.json
entfernt. Auch die Zeile src/patterns/**/tests/*test.js
im .eslintignore
durfte entfernt werden, da sich dort nun keine Tests befinden.
Browserslist
Mit Browserslist kann angegeben werden, auf welchen
Browsern die Applikation schlussendlich funktionieren
soll. Je nach Konfiguration werden die benötigten CSS-
Vendor-Prefixes hinzugefügt.
Ich passte die Konfiguration so an, dass nur die letzten
drei Chrome-Versionen unterstützt werden.
{
"browserslist": ["last 3 chrome versions", "note dead"]
}
Experimental Decorators
Damit in JS-Klassen ohne Fehlermeldungen definiert werden können, musste die im Bild
ersichtliche Einstellung angewählt werden.
Abbildung 12: Experimental Decorators
Quelle: Screenshot VSC
Proto
Proto ist der Entwicklungscode. Dieser besteht aus Hilfen für Programmierer, welche dann
aber auf der produktiven Seite nicht angezeigt werden.
In diesem Projekt wird kein Entwicklungscode benötigt. Deshalb entfernte ich den proto
Ordner und die Importe im head.hbs
. Zudem leerte ich die proto.js
Datei.
head.hbs
In der Head Datei befinden sich die Meta-Tags und JS- und CSS-Verlinkungen.
Beim Entfernen der Importe passte ich auch gleich den Titel und die Beschreibung der
Webapplikation an. Ich änderte diese auf "Merkle Info-Screens".
4.3 Linting und Testing
Das Ziel ist, einen gleichmässigen Code zu schreiben. Dafür müssen Regeln definiert werden, nach denen sich die Entwickler richten müssen. Dies ist die Voraussetzung für einen sauberen Code. Beim Linting wird dann überprüft, ob diese Regeln eingehalten wurden.
Um sicherzustellen, dass das Linting funktioniert, führte ich npm run lint
aus. Wie im
Screenshot erkennbar, ist das Linting bereits gut konfiguriert.
Abbildung 13: Linter
Quelle: Screenshot Terminal
Gelintet wird mit den folgenden Tools.
Script | Beschreibung |
---|---|
lint:css | Das CSS wird mit Stylelint überprüft https://stylelint.io/ (opens in a new tab) |
lint:data | Der Nitro-Environment-Linter überprüft, ob die Patterns valide sind. |
lint:html | Um das HTML zu überprüfen, wird html-validate eingesetzt. https://gitlab.com/html-validate/html-validate (opens in a new tab) |
lint:js | eslint ist der JS Linter. https://eslint.org/ (opens in a new tab) |
lint:license | Die Lizenzen aller verwendeten Produktiven Pakete werden vom NPM License Checker überprüft. https://www.npmjs.com/package/license-checker (opens in a new tab) |
Prettier ist dazu da, den Code nach Vorgaben zu formatieren. Mehr über das Tool erfährt
man auf dessen Webseite: https://prettier.io/ (opens in a new tab)
Das Script nimmt direkt Änderungen am Code vor.
Getestet habe ich den Prettier mit npm run prettier
. Wie im Bild zu erkennen ist, hat auch
dies schon von Beginn an funktioniert.
Abbildung 14: Prettier
Quelle: Screenshot Terminal
Sowohl beim Linting-Script als auch beim Prettier-Script nahm ich dann aber noch eine Verbesserung vor. Denn wie im Bildschirmfoto zu erkennen ist, wurden auch Dateitypen überprüft, welche in diesem Projekt nicht vorhanden sind. Deshalb entfernte ich diese aus den Scripts.
Abbildung 15: Linting und Testing Scripts
Quelle: Screenshot package.json
Nachträglich wurde dann auch noch TS aus dieser Liste entfernt.
4.4 Githook
Ein Githook ist ein Shell-Script, welches bei einer bestimmten Aktion getriggert wird. Damit
die Hooks ausgeführt werden können, muss Husky funktionsfähig sein. Dazu muss chmod +x .husky/pre-commit
auf der Konsole ausgeführt werden.
Der Ablauf sieht dann wie folgt aus:
-
Bei einem Commit erkennt dies Husky und führt das
pre-commit
File aus. -
In dieser Datei wird dann
lint-staged
ausgeführt:#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # if husky config is not in git root # cd ./... || return npx lint-staged
-
lint-staged
ist impackage.json
konfiguriert. Wird es ausgeführt, so werden alle Befehle durchlaufen, die dort angegeben sind. Darunter auch die Linter- und Prettier-Scripts. Erkennbar ist dies im folgenden Bild.package.json{ "lint-staged": { "src/**/*.{css,scss}": ["stylelint —-allow-empty-input"], "**/*.json": ["prettier —write", "npm run lint: data"], "src/**/*.js": ["prettier -write", "eslint"], "**/*.md": ["prettier -write"], "**/*.yml": ["prettier -write"], "package.json": [ "env-linter --saveExact --dependenciesExactVersion" ] } }
4.5 CI/CD
Continuous Integration / Continuous Deployment ist ein Prozess, bei welchem Code
regelmässig und automatisch getestet, gebuildet und auf ein Repository oder sogar eine
Produktionsumgebung gestellt wird.
Durch die Automatisierung wird sichergestellt, dass der Code jederzeit fehlerfrei ist.
Laut dem Auftrag muss in diesem Projekt bei jedem Push automatisch gelintet werden.
4.5.1 .gitlab-ci.yml
Das .gitlab-ci.yml
File ist die CI/CD Konfiguration eines Projektes. Die Datei wird im Root
eines Projektes abgelegt und definiert die Pipelines, Jobs und Umgebungen.
Als erstes fügte ich also diese Datei hinzu:
include:
- template: Jobs/Secret-Detection.gitlab-ci.yml
stages:
- lint
- test
lint-job:
stage: lint
image: node:16.19.0
script:
- echo "Installing project..."
- npm ci
- echo "Lint project..."
- npm run test
4.5.2 Stages und Jobs
Ein Job ist eine einzelne Aufgabe. Es ist nichts Weiteres als ein Script, welches unter
bestimmten Bedingungen und in einer definierten Umgebung ausgeführt wird. Eine Stage ist
ein Abschnitt, der gruppierte Aufgaben/Jobs hält. Die Stages definieren, in welcher
Reihenfolge welche Arten von Jobs durchgeführt werden.
In diesem Fall wird also zuerst der Lint-, gefolgt vom Test-Job ausgeführt.
4.5.3 Runners
Wird jetzt ein Push durchgeführt, so werden die Scripts abgebrochen.
Abbildung 16: GitLab Pipeline
Quelle: Screenshot GitLab
Um das vorhin beschriebene .gitlab-ci.yml
‡ File verwenden zu können, benötigt man einen Runner.
Ein Runner ist eine externe Maschine, die den Code ausführen kann.
Bei der Erstellung eines Runners kann gewählt werden, welche Infrastruktur darauf sein soll.
Die gängige Variante ist aber die Verwendung von shared Runners.
Shared Runners sind Runners, welche über die gesamte GitLab Instanz geteilt werden.
Um das YAML-File dann auszuführen, wird ein geeigneter Runner des Pools genutzt.
Ich aktivierte also die shared Runners in GitLab.
Abbildung 17: Shared Runners
Quelle: Screenshot GitLab
4.5.3 Docker
Die Scripts aus dem Yaml File werden in der Regel nicht direkt auf den Runnern ausgeführt.
Meistens wird, mithilfe eines Docker Images, eine passende Umgebung definiert.
Ein Docker ist ein Tool zur Verwendung von virtuellen Maschine, derer Konfigurationen (Systeme
und Versionen) definiert werden können. Dadurch wird garantiert, dass der Code in einer
konsistenten Umgebung ausgeführt wird. Insbesondere bei Testprozessen ist diese
einheitliche Umgebung von Vorteil. Und wenn nicht alle Mitglieder eines Entwicklungsteams
dasselbe Betriebssystem verwenden, kann Docker ebenfalls die Lösung sein.
Ein Docker-Image ist eine Definition, welche als Anleitung zum Bau eines Docker Containers
verwendet wird. Sie gibt vor, was der Container für Spezifikationen haben muss.
In der Konfiguration wählte ich ein Docker-Image, auf welchem Node 16.19.0
installiert
ist.
4.5.5 Ergebnis
Um zu überprüfen, ob die CI-Pipeline funktioniert, pushte ich einen Test-Commit. Das Ergebnis ist zufriedenstellend:
Abbildung 18: CI/CD Pipelines
Quelle: Screenshot GitLab
4.6 Branches
Wie geplant erstellte ich nun den Develop- und auch gleich den ersten Feature-Branch:
Abbildung 19: Erstellung Branches
Quelle: Screenshot Terminal
4.7 Screen Welcome
Als ersten Screen wählte ich den Welcome Screen. Wie ich diesen implementiert habe, steht in den nachfolgenden Zeilen beschrieben.
4.7.1 Schrift einbinden
Der Screen benötigte zwei verschiedene Schriften.
Als erstes erstellte ich darum eine angemessene Ordnerstruktur im shared
Ordner.
In diesem Ordner werden Assets und Codeschnipsel platziert, welche dann an verschiedenen Orten verwendet
werden. Dies ist also genau der richtige Ort für die Schriften.
Abbildung 20: Struktur Fonts in shared
Quelle: Screenshot VSC
Im fonts
Ordner habe ich dann die WOFF
-Dateien abgelegt. Unter css
konnte ich dann
sogenannte font faces
definieren. Mit diesen können eigene Schriften beschrieben
werden. In der Abbildung ist zu erkennen, wie die Definition der Plage-Bold-Text-Schrift
aufgebaut wurde.
@font-face {
font-family: 'Plage Bold Text';
font-display: fallback;
font-weight: 400;
src: local('Plage Bold Text'), local ('Plage-Bold-Text'), url('../fonts/plage-bold-text.woff2')
format('woff2'), url('../fonts/plage-bold-text.woff') format('woff');
}
Danach standen mir zwei Optionen zur Verfügung. Ich hätte ein Typo-File erstellen können.
Darin wäre dann definiert worden, wie sich die einzelnen Schriften auf den verschiedenen
Viewports verhalten.
Um das Projekt simple zu halten, entschied ich mich dafür, diese zwei SCSS-Dateien direkt im
ui.js
, dem Entrypoint der Applikation, zu importieren. So können die Schriften in allen anderen Stylesheets ohne
zusätzlichen Import genutzt werden.
import './shared/base/webfonts/css/webfont-plageboldtext.scss';
import './shared/base/webfonts/css/webfont-proximanova.scss';
import './shared/base/document/css/document.scss';
Im document.scss
definierte ich dann die neue Schrift als den Standard. Dank dem font-face
muss dazu nur noch der Name angegeben werden.
* {
font-family: 'Plage Bold Text', serif;
}
Wichtig ist auch, dass immer eine Schrift als Fallback definiert wird. Diese würde dann
angezeigt werden, wenn die Schrift nicht geladen werden kann.
Danach konnte die Schrift genutzt werden.
Abbildung 21: Plage Bold Text auf Webseite
Quelle: Screenshot Browser
4.7.2 Endpoint
Unter project/routes/data
wurde die API definiert. Diese besteht aus den Daten und einer JS-Datei.
routes:
data/messages.json
helpers
readme.md
welcome.js
In der JSON-Datei wurden die Daten strukturiert. Es gibt zwei Arrays. Unter greetings
sind
die Begrüssungen festgehalten, welche dann mit der grossen Schrift dargestellt werden.
secondaryTexts
speichert die Nachrichten, die darunter angezeigt werden.
In der Abbildung ist der Aufbau der Datei zu erkennen. Natürlich speichert diese Datei in
Wirklichkeit noch mehr Daten.
{
"greetings": [
{
"text": "Guten Morgen",
"startTime": "00:00",
"endTime": "10:00"
}
],
"secondaryTexts": [
{
"text": "Bald Wochenende",
"day": "Freitag"
},
{
"text": "Schön, dass du da bist",
"startTime": "00:00",
"endTime": "11:00"
}
]
}
Im welcome.js
ist der Endpoint definiert. Dieser stellt die /api/welcome/
URL zur
Verfügung. Darüber kann dann die Screen-Komponente nach den Daten fragen. Bei der
Anfrage wird immer ein Datum und eine Uhrzeit mitgegeben.
Die Abbildung veranschaulicht den Request.
Abbildung 22: Endpoint
Quelle: Screenshot Browser
Die Route wandelt dann diese Strings in ein Datumsobjekt um. Aus diesem kann dann der
Wochentag mit date.getDay()
ausgelesen werden. Diese Methode gibt eine Zahl zurück. Mit
dieser kann dann der entsprechende Wochentag identifiziert werden.
const weekdays = [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
];
const day = weekdays[date.getDay()];
Danach werden die Nachrichten aus dem messages.json
über das Dateisystem eingelesen
und in eine Variable umgewandelt. Ist dies getan, so wird nach der Zeit und dem soeben
gefundenen Wochentag gefiltert.
Dieses Filtern war nicht sehr leicht. Denn man musste sich auch Gedanken zu
Überschneidungen machen. Laut den vorgegebenen Daten kommt es nämlich vor, dass eine
Nachricht bis 11:30 Uhr angezeigt werden muss und eine andere um dieselbe Zeit startet. Ich
hätte den Code so schreiben können, dass das Enddatum entscheidend ist. Dadurch hätte
sich dann der Start um eine Minute verzögert. Dies wäre aber für einen Ersteller dieser
Nachrichten nicht ersichtlich gewesen, was zu Verwirrungen hätte führen können. Deshalb
entschied ich mich dazu, dass es bei den Definitionen der Zeiten keine Überschneidungen
geben darf. Falls ein Text ab 11:30 Uhr angezeigt werden soll, dann darf der vorherige
höchstens bis 11:29 Uhr dargestellt werden.
Nach diesem Filtern sind zwei mit Nachrichten gefüllte Arrays verfügbar. Diese Arrays
können mehrere Nachrichten oder auch keine beinhalten. Hier ein Beispiel:
Am Freitagabend trifft sowohl "Bald Wochenende" als auch "Bald ist Feierabend" zu.
Die Lösung setzte ich so um, dass immer der Wert, welcher als erster gefunden wurde,
zurückgegeben wird. So kann man dies beim Strukturieren der JSON-Datei beachten.
Im genannten Beispiel wird "Bald Wochenende" angezeigt, da sich dies weiter oben in der
Liste befindet.
Schlussendlich werden dann zwei Strings als JSON-Objekt zurückgegeben.
Falls es keinen passenden sekundären Text gibt, wird einfach ein leerer String gesendet.
4.7.3 Screen Klasse
Wie geplant wurde eine Screen-Klasse angelegt. Diese lagert Funktionalitäten aus, welche
für alle Screens von Nutzen sind.
Bisher implementierte ich die nachfolgenden zwei Methoden.
Zufällige Farbe
Die Screens benötigen immer zufällige Farben. Deshalb wurde eine getShuffledColor()
Funktion angelegt. Diese gibt ein durchmischtes Array mit den drei Farben (rot, grün und
gelb) zurück.
Datum und Zeit
Mehrere Screens sind auch datums- und zeitabhängig.
Deshalb implementierte ich eine getDateTime()
Methode.
Diese liest zuerst aus, ob Query-Parameter in der URL mitgegeben wurden.
Die Abbildung zeigt, wie dies umgesetzt wurde.
Ist dies der Fall, so werden diese Informationen zurückgegeben.
Falls nichts in der URL definiert wird, so wird das aktuelle Datum und die Zeit verwendet.
getQueryParameters() {
const search = window.location.search;
return new URLSearchParams(search);
}
// Returns the dateTime defined in url through query parameter. If nothing is set, the current dateTime is used.
getDateTime() {
const now = new Date();
let date = now.toISOString().slice(0, 10); // slices the date so only the year, month and day are used
let time = now
.toLocaleTimeString('de-CH', { hour12: false, hour: '2-digit', minute: '2-digit' })
.replace(':', '-');
const queryParameters = this.getQueryParameters();
const queryDate = queryParameters.get('date');
const queryTime = queryParameters.get('time');
if (queryDate !== null) {
date = queryDate;
}
if (queryTime !== null) {
time = queryTime;
}
return { date, time };
}
4.7.4 Komponente erstellen
Daraufhin wurde die Komponente erstellt.
Mit npm run nitro:pattern
wurde ein Script ausgeführt, welches einem bei der Erstellung
hilft. Wie in der Abbildung zu erkennen, konnte der Name, Typ und weitere
Konfigurationsmöglichkeiten ausgewählt werden.
Abbildung 23: Pattern Generator
Quelle: Screenshot Terminal
Request
Der Welcome Screen kann nun die getDateTime()
Funktion aufrufen, um an ein Datum und
eine Zeit zu gelangen. Danach wird ein Fetch-Request abgesetzt. Dieser sendet das Datum
und die Zeit in einem Get-Request an die URL, an welcher sich der Endpoint befindet.
Zurück erhält der Screen dann eine Response, welche eine Nachricht und optional einen
Sekundärtext enthält.
Die Methode, welche diese Abfrage durchführt, sieht wie folgt aus:
async getWelcomeData() {
// Returns either the url query parameter or current dateTime.
const dateTime = this.getDateTime();
return fetch(new Request(`/api/welcome/?date=${dateTime.date}&time=${dateTime.time}`))
.then((response) => {
if (response.status === 200) {
return response.json();
}
throw new Error('Something went wrong. Check if the route is ok.');
})
.then((response) => {
return response;
})
.catch(async (error) => {
// eslint-disable-next-line no-console
console.error(error);
});
}
Bubbles
Im Screen müssen auch animierte Kreise angezeigt werden. Diese fügte ich dem Markup mit
Divs hinzu. Vier der Bubbles färbte ich dann in JS mit der zweiten Farbe des Color-Arrays. Die
restlichen vier erhielten die dritte und letzte Farbe.
Damit die Kreise unterschiedlich gross sind, setzte ich die Höhe und Breite zufällig mit JS.
Man hätte diese auch mit CSS-Fix angeben können. Die jetzige Lösung passt aber besser zum
Konzept. Denn so sieht der Screen bei jedem Laden anders aus.
Auch zur Positionierung nutze ich wieder JS. Es wurde aber darauf geachtet, dass die Farben
gruppiert bleiben.
Die eine Vierergruppe von Kreisen wird zwischen 40 und 80 Prozent von links und 0 und 50 Prozent von oben platziert.
Die andere befindet sich unten links. Dazu werden Werte zwischen 50 und 100 Prozent von links und 0 und 40 Prozent von oben verwendet.
Die Elemente bleiben aber nicht fix positioniert, sondern werden leicht bewegt. Auch dies wurde
wieder mit JS gelöst. In einer moveBubbles()
Funktion werden die Kreise zufällig um ein paar
wenige Prozent verschoben. Diese Methode wird mit einem Intervall alle drei Sekunden
aufgerufen.
Text
Damit der Text möglichst gross und immer auf einer Linie dargestellt wird, installierte ich
Fitty mit npm i fitty
. Daraufhin konnte ich die Library auf die geholten Text-DOM-Elemente
anwenden. Diese Abbildung zeigt, wie simpel das ist.
// Apply library - https://github.com/rikschennink/fitty
fitty(greeting);
fitty(secondaryText);
Um der Schrift dann noch den speziellen Look zu verpassen, musste ich ihr mit text-shadow
noch den Rahmen zeichnen und einen Schatten geben. Den Schatten konnte ich
direkt aus dem Figma kopieren. Beim Rahmen musste ich selbst herausfinden, wie man
diesen definieren kann.
body {
text-shadow: -10px 15px rgba(0, 0, 0, 0.95), -4px -4px #000, 4px -4px #000, -4px
4px #000, 4px 4px #000;
}
Hier ist zu erkennen, dass der Text einen schwarzen Rand und Schatten hat und sich auch trotz der Länge noch anzeigen lässt:
Abbildung 24: Anzeige langer Welcome Text
Quelle: Screenshot Browser
Entry Animation
Animiert wird in der folgenden Reihenfolge:
- Die Bubbles erscheinen von oben und unten
- Die Bubbles bewegen sich bis zum Ende des Screens
- Die Hauptnachricht wird eingeblendet
- Der Sekundärtext wird eingeblendet
- Der Sekundärtext pulsiert drei Mal
4.7.5 Resultat
Der aufgebaute Screen sieht so aus:
Abbildung 25: Welcome Screen
Quelle: Screenshot Browser
4.7.6 Verbesserungspotenzial
Natürlich gibt es auch immer Verbesserungspotenzial:
- Für die Kreise werden momentan acht Divs im Markup platziert. Die Auslagerung in ein Bubble-Pattern wäre sinnvoll.
- Der Endpoint wird bei jedem Durchlauf angesprochen. Jedoch können sich die Nachrichten nur alle 30 Minuten ändern. Man könnte Daten also eine Weile zwischenspeichern.
Diese Punkte wurden in einem neuen Ticket aufgenommen. Dieses ist im Backlog platziert.
4.8 Abschluss Ticket
Nachdem die Aufgaben eines Tickets erledigt wurden, ging ich die folgenden Schritte durch:
-
Refactoring: Gesamthaft wird der Code erst zum Schluss überarbeitet. Trotzdem versuchte ich die Dateien ein wenig aufzuräumen.
-
Überprüfung der Akzeptanzkriterien: Um die Erfüllung des Auftrags sicherzustellen, wurde die Komponente auf die Akzeptanzkriterien überprüft.
-
Erstellung MR: Danach wurde ein Merge Request erstellt. So kann der Code auf den Develop Branch geschoben werden.
Im MR wird nochmals über den Code geschaut und überprüft, ob die Pipelines erfolgreich durchlaufen wurden.
In der Abbildung ist der MR des ersten Screens sichtbar.Abbildung 26: MR Screen Welcome
Quelle: Screenshot GitLab -
Merge: Aktion in GitLab ausführen.
-
Ticket aktualisieren: Der MR wurde noch im Jira verlinkt und das Ticket als abgeschlossen markiert.
-
Stand holen: Zum Schluss muss lokal nur noch auf den Develop Banch gewechselt werden, um dort den Stand mit
git pull
zu holen.
4.9 Screen Input
Der Input Screen zeigt zufällige Erinnerungen und Regeln an. Wie er umgesetzt wurde, steht in den nachfolgenden Zeilen beschrieben.
4.9.1 Daten
Beim Input Screen war die sinvolle Strukturierung der Daten die Schwierigkeit.
Zwei Strukturierungsmöglichkeiten standen zur Wahl:
- Kategorien wie "always" und "monday" erstellen und die Texte diesen zuordnen
- Jeden Text nur einmal auflisten und ihn mit einem Array versehen. In diesem wird dann angegeben, zu welchen Zeitpunkten er angezeigt werden soll.
Ich entschied mich für letzteres, da es zu einem übersichtlicheren Resultat führte. So muss ein Text nur an einem Ort angepasst werden.
{
"text": "Dream. Do. Deliver.",
"shown": ["always"]
},
{
"text": "Definiere 3 Ziele für diese Woche!",
"timeslots": ["monday", "tuesday"]
},
{
"text": "Timesheet bereit zum Absenden?",
"shown": ["friday"]
}
Wie beim Screen Welcome wurde auch hier eine API gebaut. Diese liest die Inputs aus und
sammelt diejenigen mit einem passenden Tagesabschnitt oder Tag. Die Texte, welche immer
angezeigt werden können, werden auch immer selektiert.
In der Abbildung wird gezeigt, wie alle passenden Inputs in ein Array gespeichert werden.
// Get inputs that either match the part of the day or the weekday
const filteredInputs = inputsArray.filter(
(input =
input.shown.includes(dayPart) ||
input.shown.includes(day) ||
input.shown.includes('Immer'))
);
Bei einem Request auf die Schnittstelle wird dann ein zufälliger Eintrag dieses Arrays zurückgegeben.
4.9.2 Text
Der Text muss zentriert und über höchstens drei Linien dargestellt werden. Um dies zu
bewerkstelligen, wurde das -webkit-box
Layout genutzt. Im Bild ist zu sehen, mit welchen
fünf Zeilen der Text entsprechend dargestellt werden kann.
.s-input__text {
display: -webkit-box; // enables an older layout mode
-webkit-line-clamp: 3; // allows three lines
-webkit-box-orient: vertical; // orientation of the box - content from top to bottom
hyphens: auto; // adds hyphen to long words
text-align: center;
}
Hier ist gut zu erkennen, dass die Styles wirkungsvoll sind.
Abbildung 27: Darstellung langer Text Input
Quelle: Screenshot Browser
4.9.3 Pulse Util
Auch dieser Text muss zweimal pulsieren. Damit keine Redundanzen im Sourcecode entstehen, lagerte ich das zuvor erstellte Keyframe in ein Util aus. So kann die pulsierende Animation in allen Screens genutzt werden.
4.10 Screen WeatherLocations
Dieser Screen informiert den Betrachter über das Wetter verschiedener Merkle-Standorte.
4.10.1 API
Zu Beginn las ich mich in die Dokumentation von OpenWeather ein.
Nachdem ich verstanden hatte, wie die API angesprochen werden kann, setzte ich einen Request für den Standort St. Gallen ab.
Die API lieferte mir dann sehr viele Informationen über das Wetter.
Von all diesen Daten benötigt der Screen die Temperatur (main
-> temp
) und das aktuelle Wetter (weather
-> main
)
Abbildung 28: Response Wetter API
Quelle: Screenshot Browser
Diese API muss aber nicht einmal, sondern gleich dreimal angefragt werden. Wie man am
besten mehrere Requests gleichzeitig absetzt, wusste ich zuvor noch nicht. Beim
Recherchieren stiess ich auf Promise.all()
. Damit kann auf das Resultat von mehreren
Fetches gewartet werden.
(Elias, 2023)
Bei der Arbeit mit der API kam dann ein Problem auf. Anscheinend gab mir die API das
Wetter von falschen Standorten zurück. Anstelle der Daten von "Vila Real" kamen Daten aus
einer Stadt aus Italien zurück.
Eine Überprüfung offenbarte, dass dies der falschen Definierung der Koordinaten geschuldet
war. Es gibt nämlich drei Formate in welchen Koordinaten gespeichert werden können.
(Google, 2023)
Zuvor verwendete ich das erste Suchergebnis von Google. Die API erwartet aber eine andere
Form. Um diese herauszufinden, nutze ich dann eine spezialisierte Webseite:
https://www.latlong.net/ (opens in a new tab)
Daraufhin kam ein neues Problem auf. Bei den Städten Hamburg und Lissabon wird im
Namen nicht der Stadt, sondern eines Stadtteils (Neustadt und Chiado) zurückgesendet.
Denn die Koordinaten treffen da anscheinend genau diese Bezirke.
Um dieses Problem zu lösen, werden die beiden Namen in JS überschrieben. Festgehalten ist
dies im Readme der Komponente, sodass zukünftige Entwickler davon wissen und eventuell
einen besseren Weg finden.
4.10.2 Mock Daten
Als die Antwort der API bekannt war, konnten Mock Daten implementiert werden. Dazu
wurde eine weitere Route implementiert. Diese gibt unter /api/weather
ein Wetter zur
angefragten Ortschaft zurück.
Bei der Erstellung der Mock Daten wurde darauf geachtet, dass diese von der Struktur her
identisch mit der richtigen API sind. So kann einfach zwischen den beiden Schnittstellen
gewechselt werden.
Zudem wurde dafür gesorgt, dass die Daten unterschiedlich sind und möglichst viele
Zustände abdecken.
Um auf die Mock Daten zu wechseln, muss nur die Variable useMockData
auf true
gesetzt
werden.
4.10.3 Zufällige Standorte
Um an die drei zufälligen Standorte zu gelangen, wurde ebenfalls eine Route gebaut. Sie ist
unter /api/locations
ansprechbar und antwortet immer mit drei zufälligen und
verschiedenen Standorten.
Um dies zu bewerkstelligen, holt sie einen zufälligen Eintrag aus der Liste und überprüft, ob
dieser bereits im selectedLocations
Array gesammelt wurde. Hinzugefügt wird dann der
Standort nur, wenn er sich nicht bereits in dieser Sammlung befindet.
4.10.4 Befüllen der Screens
Die Screens werden mit JS befüllt. Die Texte können dazu ins HTML geladen werden. Bei der
Temperatur galt es zu beachten, dass das Grad-Zeichen richtig angezeigt wird. Dafür sorgte
dieser Text: °C
Zudem wird die Angabe auf eine Ganzzahl gerundet.
Um das Wetter noch visuell zu zeigen, sollen Icons dargestellt werden. Diese mussten zuerst
aus dem Figma als SVGs exportiert werden.
Beim Export konnten mehrere Dateitypen ausgewählt werden. Ich entschied mich für SVG,
da die Grafik so in jeder Grösse scharf bleibt.
Die Icons wurden dann im img
Ordner unter assets
abgelegt. Wichtig dabei zu wissen
ist, dass alle Bilder von dort minifiziert und in den public/assets/img
Ordner kopiert
werden.
Zuerst musste dann herausgefunden werden, welche
Arten von Wetter überhaupt zurückgegeben werden
können. Darüber gab die folgende Seite Auskunft:
https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2 (opens in a new tab)
Damit alle Arten auch in irgendeiner Form abgebildet
werden können, erstellte ich eine Liste.
Diese weist jede Art von Wetter einem der
verfügbaren Icons zu.
Returned main value | Icon used |
---|---|
drizzle | rainy.svg |
rain | rain.svg |
snoW | snow.svg |
mist | foggy.svg |
haze | foggy.svg |
dust | foggy.svg |
fog | fog.svg |
sand | unkown.svg |
ash | fog.svg |
squall | wind.svg |
tornado | storm.svg |
clear | sun.svg |
clouds | clouds.svg |
Das unknown.svg
ist ein Geschenkpaket.
Verwendet wird es, damit auch bei speziellen und
unbekannten Wettern ein Icon angezeigt wird.
Für die Icons fand ich keine Verwendung:
- Schneeregen wird nie zurückgegeben
- Das Bewölktsymbol wird nicht benötigt, da bei wolkigem Wetter bereits die Wolke allein verwendet werden kann
4.10.5 Zwischenspeichern
Um unnötige API-Requests zu vermeiden, soll das Wetter wie geplant zwischengespeichert
werden.
Nachdem die initiale Anfrage an OpenWeather gesendet wurde, können die Daten
gespeichert werden. In der Abbildung ist die Methode erkennbar, welche die Daten in einem
Array ablegt. Dabei werden die Wetter mit einem expiry
versehen. Das "Ablaufdatum"
befindet sich eine Stunde in der Zukunft.
storeWeathers(weatherArray) {
const now = new Date();
weatherArray.forEach((weather) => {
const weatherToStore = {
expiry: now.getTime() + 3600000, // 1h
weather,
};
this.storedWeathers.push(weatherToStore);
});
}
Beim nächsten Mal wird dann das Array zuerst auf gültige Daten überprüft. Nur wenn keine
gültigen Informationen über den gewünschten Standort vorhanden sind, werden diese
abgefragt.
So kann es sein, dass bei einem Durchlauf drei oder auch kein Wetter geholt werden muss.
4.10.6 Styling
Um den Screen zu gestalten, wurde Flexbox eingesetzt. Damit konnten die drei Boxen und auch deren Inhalt passend gemäss dieser Abbildung platziert werden.
Abbildung 29: Screen WeatherLocations
Quelle: Screenshot Browser
Um zu animieren, wird ein margin-top
Wert verändert. Dadurch werden die drei Container
von oben oder unten in den Screen hineingeschoben.
Der Fokus Style, mit Rändern und grünem Hintergrund, wird dann per JS mit einer state-m-weather__container--active
Klasse unter den drei Boxen weitergegeben. Dabei wird die
Dauer des Screens zwischen den einzelnen Fokussen aufgeteilt.
Laut der Vorgabe müssen die einzelnen Container auch eine Outline haben. Da musste entschieden werden, ob diese nur als Trennlinie zwischen den drei Boxen oder auch rundum angezeigt werden soll. Die Entscheidung fiel auf Ersteres. Denn der TV rahmt die Webseite schon mit seinem schwarzen Rand ein. Eine zusätzliche Linie würde nur Platz vom Inhalt wegnehmen.
4.10.7 Verbesserungspotenzial
Man könnte das Wetter noch genauer auswerten und abbilden. Zudem sieht der Rand um die Zahlen nicht optimal aus. Tickets dafür sind erstellt, werden aber nicht im Rahmen dieser Arbeit erledigt.
4.11 Screen Joke
Auch der Aufbau dieses Screens ist den bisherigen nachempfunden.
Die Witze werden in einem JSON gespeichert und jeweils ein Witz kann über die Route /api/joke
abgefragt werden.
Ein Witz besteht jeweils aus einer Frage und einer sogenannten "Punchline".
Die Frage, in der Abbildung dargestellt, wird zuerst angezeigt und mithilfe des zuvor beschriebenen Pulse Util zweimal pulsiert. Danach wird der Text mit einem Übergang ausgeblendet. Daraufhin folgt die Auflösung. Diese wird langsam eingeblendet und pulsiert einmal.
Abbildung 30: Joke Screen
Quelle: Screenshot Browser
Der Text wird standardmässig in einer fixen Grösse ausgegeben. Ist nicht genügend Platz
vorhanden, so wird die Schriftgrösse verkleinert.
Fitty ist in diesem Projekt bereits installiert. Deshalb versuchte ich zuerst eine Lösung mit
dem NPM-Paket zu finden. Leider fand ich keine passende. Denn will man mit Fitty Texte
über mehrere Zeilen erlauben, so muss man diesen eine Mindestgrösse verpassen. Die
Textgrössen sind dann aber bei jedem Inhalt unterschiedlich und unterschreiten lediglich
diese Mindestgrösse nicht.
In diesem Projekt waren aber Texte gefordert, welche immer gleich gross sind und sich nur
verkleinern, wenn nicht genügend Platz da ist.
Um dies zu erreichen, wurde schlussendlich eine eigene Funktion implementiert. In JS wird
überprüft, ob die Höhe oder Breite des Texthalters grösser ist als die des Screens. Trifft dies
zu, so bedeutet das, dass der Text nicht mehr komplett sichtbar ist. In einem solchen Fall
wird die Schriftgrösse dann um zehn Pixel verkleinert. Daraufhin wird erneut überprüft.
Um den Screen so anpassungsfähig wie möglich zu gestalten, stellt dieser die zwei Variablen
questionTime
und punchlineTime
zur Verfügung. Diese bestimmen, wie lange die Frage und
Auflösung angezeigt werden. Die Länge ist so frei konfigurierbar.
Zu beachten gilt, dass bei einer sehr kurzen Dauer (unter drei Sekunden) die Animationen
nicht vollständig angezeigt werden können.
Im Readme ist aber genaustens beschrieben, welche Werte nicht unterschritten werden
sollten.
4.12 Controller
Damit die Screens auch in einem schönen Ablauf gezeigt werden können, musste ein Controller implementiert werden. Dieser kennt die Screens und kann diese zum richtigen Zeitpunkt starten.
4.12.1 Ablauf
Der Ablauf lässt sich wie folgt beschreiben:
- Der Controller nimmt einen Screen aus dem Loop und startet diesen.
- Der gestartete Screen animiert sich selbst, stellt die nötigen Inhalte dar und baut sich auch wieder selbst ab.
- Nachdem der Screen fertig ist, meldet er dies dem Controller.
- Der Controller startet daraufhin den nächsten Screen.
Diese vier Schritte wiederholen sich dann.
Dieses Vorgehen unterscheidet sich minimal von dem geplanten Prozessablauf unter
"Wetter API" in der Planungsphase. Denn bei der Konzeption wurde noch davon
ausgegangen, dass der Controller die Screens auch stoppt.
In der nachfolgenden Grafik ist der Ablauf am Beispiel des Input Screens nochmals
dargestellt.
Abbildung 31: Ablauf Input Screen
Quelle: Selbst erstellt in lucid.app
Damit sich der Controller mit den Screens verständigen kann, wurde Gondel eingesetzt. So können sich die Komponenten mithilfe von Event Listenern verständigen.
4.12.2 Erweiterbarkeit
Die Abfolge ist erweiterbar. Um einen neuen Screen zu
erstellen, reicht es, eine neue Komponente anzulegen, diese in
index.hbs
zu platzieren und dem Loop hinzuzufügen.
Gezeigt ist die Schleife in der Abbildung rechts.
Zu beachten gilt es nur, dass ein Screen nicht direkt zweimal
nacheinander angezeigt werden kann. Ein Ticket zur
Implementierung dieses Features befindet sich aber im
Backlog.
this.loop = [
{ name: 'input' },
{ name: 'welcome' },
{ name: 'input' },
{ name: 'weather' },
{ name: 'joke' },
];
Auch die Logik muss bei zukünftigen Screens nicht neu entwickelt werden. Die Screen-Klasse deckt mit ihren Funktionen bereits alle wichtigen Funktionalitäten ab.
4.12.3 Konfiguration
Um die Zeitdauer des Übergangs zu verstellen, kann die transition
Variable der Screen Klasse
verändert werden. Standardmässig ist diese auf zwei Sekunden eingestellt.
Dieser Wert gilt dann für sämtliche Screens.
4.12.4 Umgang mit Fehlern
Damit der Wetterscreen nur nach einem erfolgreichen Request angezeigt wird, muss auf
Fehler bei der Anfrage reagiert werden. Dazu wurde vom catch
Gebrauch gemacht. Dieser
Abschnitt des Fetches wird ausgeführt, falls beispielsweise keine Internetverbindung
besteht.
Kommt es nun dazu, dass der Code zu diesem Bereich gelangt, so wird eine abortScreen
Funktion ausgeführt. Diese beendet den Screen dann ohne Animation und startet direkt den
nächsten. Dies in einer so kurzen Zeitspanne, dass der Nutzer dies nicht einmal mitbekommt.
Für ihn sieht es so aus, als ob das Wetter ausgelassen wurde.
4.12.4 Animation
Für die Animationen wurden der Screen-Klasse drei Methoden hinzugefügt.
moveIn
: Damit wird ein Screen mit einem Übergang von rechts nach links geschoben.moveOut
: So kann der alte Screen nach rechts hinausgeschoben werden.resetPosition
: Positioniert den Screen wieder an der Ursprungsposition.
4.12.6 Schwarzer Rand
Falls zwei aufeinanderfolgende Screens dieselbe
Hintergrundgrundfarbe haben, kommt dadurch die
Animation nicht zur Geltung. Folglich musste ein
schwarzer Rand zwischen den Screens gezeichnet
werden.
Der unkomplizierteste Weg wäre das Setzen einer
border
oder outline
. Diese Lösung sagte mir aber
nicht zu, da die Linie dann durchgehend sichtbar
gewesen wäre.
Demzufolge wurde entschieden, den Rand nur zum
Zeitpunkt der Animation zu vergeben. Dazu musste
der bereits bestehenden moveOut
Methode in der
Screen-Klasse nur eine Zeile hinzugefügt werden.
Abbildung 32: Rand zwischen Screens
Quelle: Screenshot Browser
4.13 Favicon
Nachdem alle notwendigen Tickets erledigt wurden, konnte
bereits eines aus dem Backlog implementiert werden.
Auf https://favicon.io/ (opens in a new tab) wurde ein Favicon generiert und in die Applikation eingebaut.
Dieses ist zwar nicht sichtbar auf dem TV, hilft aber einem
Programmierer, den Tab beim Entwickeln schneller ausfindig zu machen.
4.14 Export
In Nitro kann ein Projekt statisch oder dynamisch exportiert werden. Wie bereits
entschieden wurde, muss ein Export mit Server erstellt werden können. Denn nur so hat die
Applikation Zugriff auf die Routes.
Beim Projektsetup wurden die zwei Ordner locales
und server
entfernt. Dies sorgte
zuerst für Probleme beim Exportieren. In der Abbildung ist ersichtlich, dass versucht wurde,
Dateien von dort in den Zielordner zu kopieren.
Abbildung 33: Export Problem
Quelle: Screenshot Terminal
Die VF wies auf zwei Lösungswege hin:
- Die zwei Ordner wieder hinzufügen
- Die zwei Pfade der Nitro-Konfiguration in
config/defaults.js
entfernen
Ich entschied mich für die erste Variante, da diese schneller umzusetzen war und legte die zwei Ordner mit jeweils einem Readme an.
4.15 Readme
Im Readme wurde beschrieben, was das Projekt ist, für welchen Browser und Bildschirm es
gemacht wurde, wie ein Entwickler es aufsetzen kann und worauf bei der Entwicklung und
beim Testen geachtet werden muss.
Als Inspiration wurde diese Vorlage genutzt:
https://github.com/merkle-open/frontend-defaults/blob/master/doc/README.md (opens in a new tab)
4.16 Routes
Hier noch eine Übersicht über alle erstellten Routes.
Name | URL | Request | Response |
---|---|---|---|
Input | api/input | Zeitpunkt | Zufälliger Input |
Joke | api/joke | - | Zufälliger Joke |
Locations | api/locations | - | Drei zufällige Standorte |
Weather | api/weather | Standort | Wetter des Standorts |
Welcome | api/input | Zeitpunkt | Zufällige Begrüssung mit optionalem Sekundärtext |
5 Kontrolle
Die fünfte Phase ist der Kontrolle gewidmet.
5.1 Refactoring
Als alle notwendigen Tickets abgeschlossen waren, konnten Verbesserungen durchgeführt werden. Überprüft wurde unter anderem, ob...
- ... die Code-Conventions, Formatierung und Naming den aktuellen Merkle Conventions entsprechen
- ... die Projekt-Struktur den Merkle-Conventions entspricht
- ... die "Run scripts" im
package.json
sinnvoll gruppiert sind und keine unrelevanten Aufgaben enthalten - ... auf der Konsole keine unrelevanten Ausgaben vorhanden sind
- ... alle Readmes der Patterns sauber geschrieben sind
Nachfolgend sind die Hauptveränderungen aufgeführt.
5.1.1 Private Methoden
In der Entscheidungsphase wurde beschlossen, dass private JS-Methoden nicht mit einem
Bodenstrich gekennzeichnet werden müssen.
Arbeitet man mit den Gondel Event Listenern, so ist es Pflicht, die zugehörigen Methoden
privat zu kennzeichnen. Demzufolge wurde neu entschieden, dass alle privaten Funktionen
mit dem Bodenstrich versehen werden sollen. Dies führte zu einem einheitlicheren
Quellcode.
5.1.2 Routes Linten
Der Linter war bisher so konfiguriert, dass dem Code unter
src
Beachtung geschenkt wurde. Damit die Routes auch
kontrolliert werden, wurde im package.json
eine zusätzliche
Regel definiert. In der Abbildung ist zu sehen, dass nun auch die
JS-Dateien unter routes
gelintet und getestet werden.
{
"project/routes/*.js": ["prettier --write", "eslint"]
}
5.1.3 jQuery
Zu Beginn des Projektes wurde beschlossen, dass jQuery eingebunden werden soll. Dies
wurde beim Setup auch getan. Jedoch gab es schlussendlich keine sinnvollen
Verwendungszwecke für die Library. Jegliche Logik konnte mit Vanilla-JS umgesetzt werden.
Damit kein unnötiger Code vorhanden ist, wurde das Paket entfernt.
5.1.4 Pattern Konfiguration
Da weder Atome noch Organismen eingesetzt wurden, konnten diese Typen aus dem
pattern.js
entfernt werden.
5.1.5 Ausgaben auf der Konsole
Damit keine Ausgaben auf der Konsole erschienen, wurden alle console.log()
Befehle
entfernt.
Nur im Falle eines Problems mit einer der Routes wird eine Meldung angezeigt, um den
Entwickler mit einer Fehlerbeschreibung zu unterstützen. Zu solchen Fehlern kommt es aber
in der Regel nicht.
5.2 Testdurchführung
Datum: 17.03.2023
Person: Kay Wild
Bei der Einrichtung der Testumgebung wurde schnell klar, dass es ein paar Probleme geben
wird. Denn während der Entwicklung wurden die Komponenten für einen Full-HD
(1920x1080 Pixel) Bildschirm entwickelt.
Als dann der Laptop am Bildschirm angehängt wurde, war direkt eine Inhaltsverschiebung
ersichtlich.
Dies trat nur beim Erweitern des Bildschirms auf - beim Spiegeln nicht. Da das Notebook
aber zugeklappt hinter dem TV verstaut werden soll, muss die Lösung auch mit dem
zugeklappten Gerät funktionieren.
Infolgedessen wurde die Auflösung des TVs überprüft. Erstaunlicherweise hat dieser, sowie auch alle anderen Bildschirme im Gebäude, nur eine 1280x720 Pixel Auflösung. Dies wurde dann schnellstmöglich der VF mitgeteilt. Diese wies darauf hin, dass auch dies ein 16.9- Verhältnis ist. Wenn also die Pixelangaben anders gemacht werden, so kann der Inhalt auch da schön angezeigt werden.
5.2.1 Basisarbeiten
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
1.0 | 13:30 | Erstellung Git-Repository | GitLab Repository wurde im privaten Bereich angelegt. ![]() |
1.1 | 13:30 | Generierung Nitro-Projekt | Ein Nitro Projekt ist vorhanden. In der .node-version Datei ist die Version 16.19.0 notiert. ![]() |
1.2 | 13:30 | Lauffähigkeit Projektexport | Ein Export kann mit npm run nitro:server erstellt und wie in der Abbildung gestartet werden. Beschrieben ist dies im Readme. ![]() |
1.3 | 13:30 | Darstellung Screens in Loop | Die Reihenfolge der Screens stimmt auch noch nach fünf Minuten. |
1.4 | 13:30 | Zufälligkeit der Inhalte und Farbvarianten | Nach fünf Minuten Beobachtungszeit konnten keine Muster erkannt werden. Die Farben und Inhalte sind zufällig. |
5.2.2 Standards und Conventions
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
2.0 | 14:00 | Qualität README.md | Das Readme enthält Informationen vom Setup über die Entwicklung und das Testing bishin zum Export. Eine Einleitung erklärt zudem das Projekt. Diese ist im Bild zu sehen. ![]() |
2.1 | 14:00 | Run-Scripts | Die Scripts wurden mit npm run getestet und funktionieren. |
2.2 | 14:00 | Sensible Daten im Repository | In der Abbildung ist erkennbar, dass das Projekt laut dem Security-Job beim Master-Merge keine sensiblen Daten enthält. ![]() |
5.2.3 Linting und Testing
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
3.0 | 14:30 | Konfigurationen für Linting und Testing | ❌ Das Readme enthält keine Informationen über die Verwendung des Linters und Prettiers. |
3.1 | 14:30 | Githook | Alle Scripts laufen durch. ![]() |
3.2 | 14:30 | Prettier und Linter | Der Linter läuft ohne Fehler oder Warnungen durch. ![]() ![]() |
3.3 | 14:30 | CI-Pipeline | Auf GitLab ist ersichtlich, dass die Pipeline schon seit Anbeginn des Projekts korrekt konfiguriert ist. ![]() |
5.2.4 Verwendbarkeit der Applikation auf einem Screen im Merkle Office St. Gallen
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
4.0 | 15:00 | Darstellung Stockwerkscreen | ❌ Die Inhalte des Input- und Wetterscreens werden nicht richtig platziert. ![]() |
4.1 | 15:00 | Stabilität | Um die Stabilität zu überprüfen, wurden zwei Dinge unternommen. Beobachtung nach einer Stunde: Nach mehr als einer Stunde wurden die Inhalte immer noch ansprechend und korrekt dargestellt. Die Applikation hatte auch keine Pausen oder mühsames Stocken. Profiling über fünf Minuten: Im Inspect-Modus wurde die Performance der Applikation über fünf Minuten hinweg aufgezeichnet. Das Ergebnis ist wie folgt zu interpretieren: - Blau wird die JS-Heap angezeigt. Je höher diese Linie steigt, desto mehr Memory benötigt JS. Da die Grafik nicht unendlich steigt, sondern sich auch immer wieder abbaut, muss man sich keine Sorgen über das Memory machen. Denn JS gibt die Ressourcen schnell wieder frei. - Grün sind die DOM-Nodes dargestellt. Auch diese Werte sind zufriedenstellend. ![]() |
4.2 | 15:30 | Animationen | Die Animationen werden flüssig dargestellt. |
4.3 | 15:30 | Datums- und Zeitsteuerung | Um die Zeitsteuerung zu überprüfen, wurden drei verschiedene Daten mitgegeben.; 1. ?date=2023-02-20&time=09-30 ![]() ?date=2003-02-12&time=22-14 ![]() ?date=2023-02-10&time=12-14 ![]() |
4.4 | 15:30 | Übergänge | Die Übergänge sehen ansprechend aus. |
4.5 | 15:30 | Auslagerung Animationsdauer | Es konnte festgestellt werden, dass alle Animationen identisch sind. Im Code wurde auch schnell der Ort entdeckt, an welchem die Dauer der Übergänge verändert werden kann. Es zeigte sich, dass diese Zeile eine Auswirkung auf alle Screens hat. ![]() |
5.2.5 Screen Welcome und Input
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
5.0 | 16:00 | Speicherung Inhalte und Regeln | Alle Daten befinden sich an einem zentralen Ort und sind auch sinnvoll strukturiert. ![]() |
5.1 | 16:00 | Animationen | ⚠️ Alle Designvorgaben wurden umgesetzt. Die Bubbles könnten noch verbessert werden. Diese werden nämlich nach längerer Zeit über den kompletten Screen verteilt. |
5.2 | 16:00 | Einhaltung Regeln | Da am Nachmittag getestet wurde, stimmte der angezeigte Input. ![]() |
5.3 | 16:00 | Schrift | ❌ Die Schriften haben die vorgegeben Schriftarten und sind zentriert. Der Rand sieht jedoch in seltenen Fällen nicht perfekt aus. |
5.4 | 16:00 | Darstellung Text Welcome Screen | Egal wie lang der Text oder klein das Fenster ist, er bleibt lesbar. ![]() |
5.5 | 16:00 | Darstellung Text Input Screen | ❌ Bei manchen äusserst langen Texten sieht das Resultat noch nicht zufriedenstellend aus. ![]() |
5.2.6 Screen Joke
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
6.0 | 16:00 | Speicherung Inhalte | Die Daten sind ansprechend strukturiert in einer JSON-Datei abgelegt. |
6.1 | 16:00 | Darstellung Text | Auch lange Witze können vollständig angezeigt werden. ![]() |
6.2 | 16:30 | Animation | Die Frage pulsiert zweimal und wird danach ausgeblendet. Daraufhin erscheint eine Punchline, welche einmal pulsiert. |
6.3 | 16:30 | Pulsieren | Die Frage pulsiert zweimal und wird danach ausgeblendet. Daraufhin erscheint eine Punchline, welche einmal pulsiert. |
6.4 | 16:30 | Dieser Test wurde gestrichen, da der Test 1.4 dies bereits überprüft hat. | |
6.5 | 16:30 | Konfigurierbarkeit | Es stehen zwei Variablen zur Anpassung der zwei Längen zur Verfügung. ![]() ![]() |
5.2.6 Screen WeatherLocations
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
7.0 | 16:30 | Animation | Wie in der Vorgabe geschrieben steht, wird der Screen korrekt auf- und abgebaut. |
7.1 | 16:30 | Auswahl Standorte | Bei der Betrachtung schien es danach, als wären die Standorte komplett zufällig. Auch beim Aufruf der Location Route unter /api/locations wurden keine Regelmässigkeiten in den Antworten entdeckt. ![]() |
7.2 | 16:30 | Darstellung Wetterdaten | Die Temperaturen sind korrekt und werden immer auf ganze Zahlen gerundet. |
7.3 | 16:30 | Zwischenspeicherung Daten | Nachdem jeder Standort bereits angezeigt wurde, wurde das WLAN deaktiviert. Danach konnten immer noch Daten angezeigt werden. Die Zwischenspeicherung funktioniert also. |
7.4 | 16:30 | Farblicher Fokus | ⚠️ Die Outlines von drei Pixeln werden angezeigt und der Fokus wird gemäss der Vorgabe verschoben. Die Animation könnte mit einem Übergang beim Bildwechsel noch schöner gestaltet werden. |
7.5 | 16:30 | Umgang mit Fehlern | Als schon von Beginn weg kein Internet verfügbar war, wurde der Screen überhaupt nicht erst sichtbar. Nach der Aktivierung des WLANs wurde das Wetter wieder angzeigt. |
5.3 Testauswertung
Von den 35 Testergebnissen entsprachen 29 den
Erwartungen. Vier Tests scheiterten. Bei weiteren zwei gibt es
noch Verbesserungspotenzial.
Damit die Applikation den Anforderungen entspricht, sollten
die vier Probleme mit höchster Priorität noch behoben
werden. Bleibt danach noch Zeit für die Verbesserungen, so
wäre es schön, wenn diese auch noch getätigt werden
könnten.
Abbildung 57: Testauswertung
Quelle: Selbst erstellt in Excel
Insgesamt bin ich zufrieden mit dem Ergebnis. Jedoch überrascht es mich trotzdem ein wenig, dass sechs Dinge noch nicht optimal sind.
5.4 Verbesserungen
Nachfolgend steht beschreiben, wie die Probleme behoben wurden.
5.4.1 Konfigurationen für Linting und Testing - 3.0
Konfiguriert waren die Linting und Testing Scripts. Jedoch stand nirgends geschrieben, wie man diese verwendet. Im Readme musste also noch ein kurzer Text hinzugefügt werden.
5.4.2 Darstellung Stockwerksscreen - 4.0
Vorerst musste die Frage geklärt werden, ob die Zeit für diese Verbesserung reicht und wie
wichtig diese für die Applikation ist.
Der einfachste Weg wäre, den Laptop einfach nie zuzuklappen, was aber das Ziel dieser
Arbeit verfehlen würden. Deshalb wurde entschieden, dass dieses Problem angegangen
werden muss.
Aufgrund der Standard-HD Auflösung der Stockwerksscreens stimmte die Darstellung des Wetterscreens nicht. Dies wurde von langen Standortbeschriftungen verursacht. Denn diese vergrösserten die Boxen. Um das Problem zu beheben, wurden drei Dinge unternommen.
- Der Overflow des Containers, in welchem das Wetter dargestellt wird, wurde auf
hidden
gesetzt. - Der Text erhielt eine maximale Breite von 90 Prozent.
white-space
des Textes wurde aufnowrap
gesetzt, damit der Text immer auf einer Zeile bleibt.
Daraufhin wurden zur Sicherheit fast alle absoluten Pixelangaben durch relative
Masseinheiten wie em
, %
, vw
oder vh
ersetzt.
Aus diesem Fehler lernte ich, dass man im Frontend immer so viele Fälle wie möglich abdecken soll.
5.4.3 Animationen - 5.1
Die Bubbles im Welcome-Screen werden in einer Funktion, die einmal pro Sekunde
aufgerufen wird, auf dem Screen verschoben. Auch nachdem der Screen beendet ist, werden
die Bubbles immer noch animiert. Dies ist nicht optimal für die Performance.
Aus diesem Grund wird eine Codezeile eingebaut, die das Intervall beendet:
clearInterval(this.moveBubblesInterval);
5.4.4 Schrift - 5.3
Der Schriftschatten wurde verbessert, indem er mit em
zum Verhältnis zur Schriftgrösse und
nicht absolut mit Pixeln gesetzt wird. So muss dieser auch nur einmal definiert werden und
kann dann von allen Schriften, unabhängig deren Grössen, genutzt werden.
5.4.5 Darstellung Text Input Screen - 5.5
Um keine Vendor Prefixes zu benötigen, wurde display: -webkit-box;
im Input-Screen beim
Refactoring durch flex
ersetzt. Die Tests zeigten aber, dass dies nicht funktioniert.
Infolgedessen wurde dieser Wert wieder auf -webkit-box
geändert.
Damit der Linter dies nicht bemängelt, wurde Stylelint für diese Zeile wie folgt deaktiviert:
// stylelint-disable-next-line value-no-vendor-prefix
5.4.6 Farblicher Fokus - 7.4
Aus Zeitgründen wurde der Entscheid gefällt, dass der Bildwechsel nicht animiert wird. Dies wären aber drei mögliche Lösungswege:
- Das Icon als Hintergrundbild eines Divs einbinden. Dadurch kann eine Transition auf der Source definiert werden.
- Es werden beide Icons dem HTML hinzugefügt. Das farblose wird dann mit einem Übergang unsichtbar. Das aktive Icon wird langsam angezeigt.
- Nur das farbige Bild wird eingebunden. Die Farbe wird dann mit einem CSS-Filter entfernt und später wieder langsam angezeigt.
Ein Ticket für diese Verbesserung wurde erstellt.
5.5 Testdurchführung 2
Nachdem die Verbesserungen getätigt wurden, musste die Funktionalität dieser sichergestellt werden.
Datum: 20.03.2023
Person: Kay Wild
Nr. | Zeitpunkt | Was wird getestet? | Ergebnis |
---|---|---|---|
3.0 | 8:30 | Konfiguration für Linting und Testing | Im Readme ist nun vermerkt, wie der Linter und Prettier ausgeführt werden können. ![]() |
4.0 | 8:30 | Darstellung Stockwerksscreen | Alle Screens werden korrekt dargestellt. ![]() |
5.1 | 8:30 | Animationen | Um sicherzustellen, dass sich die Kreise nach dem Stopp nicht mehr bewegen, wurden zwei Konsolenausgaben eingebaut. Der Text "In moveBubbles function" wird bei jedem Aufruf der Funktion, welche die Bubbles verschiebt, ausgegeben. In der Browserkonsole ist erkennbar, dass die Funktion nach zwölf Aufrufen nicht mehr genutzt wird. ![]() |
5.3 | 8:30 | Schrift | Der Textschatten ist nun nicht mehr mit Pixeln, sondern im Verhältnis zur Schriftgrösse gesetzt. Die Schrift sieht auf allen Screens ansprechend aus. ![]() |
5.5 | 8:30 | Darstellung Text Input Screen | Der Text läuft über höchstens drei Linien und wird mit drei Punkten abgeschnitten, falls er zu lange ist. ![]() |
- | Diese Verbesserung wurde noch nicht vorgenommen und deshalb auch nicht getestet. |
Bei der zweiten Testdurchführung bestanden alle Fälle. Es muss nichts mehr an der Applikation verändert werden.
5.6 Überprüfung Design
Um sicherzustellen, dass die Designerin des Projektes zufrieden mit der Implementierung
der Mockups ist, wurde Feedback bei ihr eingeholt.
Sie war sehr zufrieden mit dem Ergebnis. Jedoch fielen ihr noch zwei Dinge auf:
- Die Rahmen um die Kreise im Welcome-Screen dürften etwas dicker sein.
- Der Zeilenabstand beim Witz und den Inputs könnte etwas kleiner sein.
Daraufhin wurde der Rahmen der Bubble in der entsprechenden Klasse von einem auf vier
Pixel gestellt. Die Verkleinerung des Zeilenabstands wurde in einem Ticket festgehalten.
Würde man diesen anpassen, so könnte das eventuell Auswirkungen auf das Verhalten der
Texte haben. Demzufolge müsste man auch erneut testen.
6 Auswertung
In der letzten IPERKA-Phase wird überprüft, wie die Arbeit ausgeführt wurde.
6.1 Vorgehen
6.1.1 Mittel
Wie geplant, wurden sinnvolle Hilfsmittel eingesetzt. Eines davon ist Jira. Das darin
enthaltene Kanban Board bildete während der Entwicklung den aktuellen Stand ab.
Im Bildschirmfoto ist das Entwicklungsstadium des vierten Tages erkennbar.
Abbildung 63: Nutzung Jira
Quelle: Screenshot Jira
Auch GitLab wurde, wie beabsichtigt, fleissig genutzt. Vom Tag zwei bis zehn wurden insgesamt 148 Commits getätigt. Die Grafik stellt dar, an welchen Tagen diese ausgeführt wurden. Sie zeigt, dass die Arbeit gut auf die Tage verteilt wurde.
Abbildung 64: GitLab Commits
Quelle: Screenshot GitLab
Auch die Nachrichten dieser Commits entsprechen den definierten Vorgaben.
Abbildung 65: Commit Messages
Quelle: Screenshot GitLab
Um die Dokumente zu sichern, wurde OneDrive genutzt. Da wurde der tägliche Stand versioniert. Das gesamte Verzeichnis mit den Dokumentationen und auch den Zeitplänen war der VF durchgehend freigegeben.
Abbildung 66: OneDrive
Quelle: Screenshot OneDrive
6.1.2 Methoden
Im Code ist schnell erkennbar, dass die Conventions eingehalten wurden. Konzepte wie BEM und Atomic Design widerspiegeln sich im Code. Die Logik ist in Komponenten unterteilt, jegliche Teile des Projekts werden durch ein Readme beschrieben und der Linter läuft ohne Warnungen durch.
6.2 Probleme
Ein Projekt verläuft in den allerseltensten Fällen ohne Unannehmlichkeiten. Auch in diesem traten ein paar Probleme auf.
6.2.1 OneDrive
Die Dokumentation und der Zeitplan waren mit dem OneDrive
synchronisiert. Am Tag sieben wurde dann die Meldung
angezeigt, dass die automatische Speicherung nicht mehr
funktioniert. Beim Versuch, sich erneut anzumelden, kam der im
Bild ersichtliche Fehler.
Das Problem war aber nicht verheerend. Es gab nämlich zwei
sinnvolle Wege, dies zu umgehen.
- Mit der online Version arbeiten
- Lokal arbeiten und das Dokument am Abend hochladen
Ich entschied mich für die letztere Variante, da bei dieser nicht die Gefahr bestand, dass das Dokument speziell formatiert wird.
Abbildung 67: OneDrive 403
Quelle: Screenshot Okta Fehler
Das Problem wurde dann auch dem IT-Support gemeldet. Dieser riet, die Office-Programme
zu schliessen, den Laptop neu zu starten und daraufhin das Outlook-Konto zu löschen.
Um keine Zeit zu verlieren, wurde aber vorerst darauf verzichtet.
6.2.2 GitLab
Am achten Tag funktionierte kurzzeitig der GitLab-Login aller Mitarbeiter nicht. Dies war aber nicht weiter schlimm. Denn während dieser Zeit konnten lokale Commits erstellt werden. Bald funktionierte der Zugang von selbst wieder, woraufhin die Änderungen auf das Repository gepushed werden konnten.
6.2.3 IPERKA
IPERKA war eine grosse Hilfe. Die Projektmanagementmethode brachte eine Struktur in das
Projekt, hatte jedoch einen grossen Nachteil. Durch das Testen in der Endphase
kann sehr schlecht auf Fehler reagiert werden.
In diesem Projekt scheiterten nur vier Testfälle, da die Komponenten gut aufgeteilt und auch
bereits separat überprüft wurden. Wären die Tests aber schlechter ausgefallen, so wäre dies
fatal gewesen. Denn die Zeit hätte wohl kaum für grosse Verbesserungen gereicht.
6.3 Zeitmanagement
Die Zeitschätzung war äusserst akkurat. Erstaunlicherweise gab es trotz der genauen
Planung keine Abweichungen von mehr als zwei Stunden. Dies zeigt auch das nachfolgende
Diagramm, welches die Zeiten der Realisierungs- und Kontrollphase darstellt.
Vorteilhaft war auch, dass bei den Schätzungen der Komponenten auch Zeit für die
Dokumentation inbegriffen war. So konnte die Entwicklung fortlaufend festgehalten werden.
Nächstes Mal sollte aber noch Zeit für Verbesserungen reserviert werden. Denn wären mehr
Tests gescheitert, hätte dies eine sehr stressige Endphase bedeutet.
Abbildung 68: Soll- und Ist-Zeit
Quelle: Selbst erstellt in Excel
Da genau 80 Stunden gearbeitet wurden, führte dies zu einem Saldo von 0.
Neben der Planung wurden zu Beginn auch Meilensteine definiert. Bis auf "Tests erfolgreich", konnten diese pünktlich erreicht werden.
Meilenstein | Tag der Erreichung geplant | Tag der Erreichung |
---|---|---|
Setup Gitlab, Nitro, Linting, Prettier und CI | 3 | 3 |
Welcome Screen | 4 | 4 |
Input Screen | 5 | 5 |
WeatherLocations Screen | 6 | 6 |
Joke Screen | 7 | 7 |
Loop mit Animation | 7 | 7 |
Tests erfolgreich | 8 | ⚠️ 9 |
Auswertung erledigt | 9 | 9 |
Abgegeben | 10 | 10 |
Insgesamt war die Zeitschätzung also sehr zufriedenstellend.
6.4 Resultat
Das Endprodukt kann nun auf den Bildschirmen des Betriebs dargestellt werden. Dies ist
sehr erfreulich. In den Abbildungen ist zu sehen, wie der Info-Screen im sechsten Stockwerk
durchläuft.
Das Resultat entspricht über alle Bereiche hinweg den Anforderungen. Nicht nur der Code,
sondern auch das Vorgehen und die Dokumentation erfüllen meine persönlichen
Erwartungen. Dies liegt daran, dass viel Wert auf diese Themen gelegt wurde.
Abbildung 69: Info-Screen sechster Stock - Wetter
Quelle: Selbst erstellt
Abbildung 70: Info-Screen sechster Stock - Welcome
Quelle: Selbst erstellt
6.5 Zukunft
In Zukunft könnte man diese Webseite auf allen Bildschirmen darstellen.
Dazu benötigt man dann weitere Notebooks, auf denen man die
Applikation startet.
Durch den modularen Aufbau der Applikation kann diese auch leicht mit
neuen Screens erweitert werden. Eine Terminübersicht, Empfehlung für
das Mittagessen, Bild des Tages, Eventcountdown oder ein Mitmach-
Screen zur Förderung der Interaktivität, die Ideen sind vorhanden. Es ist
also sehr wahrscheinlich, dass noch Screens hinzukommen.
Selbstverständlich gibt es auch immer noch
Verbesserungsmöglichkeiten, wie die Optimierung des JS-Codes. Obwohl
mehrere Stunden in die Verbesserung dieser Zeilen investiert wurde,
gibt es noch Teile, welche schöner geschrieben werden können.
In der Abbildung ist das Jira-Backlog zu sehen. Dort sind alle weiteren
Optimierungsmöglichkeiten festgehalten.
Abbildung 71: Jira Backlog
Quelle: Screenshot Jira
Schlusswort
Mein persönliches Ziel, alle Vorgaben zu erfüllen, konnte ich erreichen. Zum Schluss blieb sogar noch etwas Zeit, um einen kleinen Teil der im Backlog festgehaltenen Verbesserungen zu implementieren.
Mit der Betreuung der VF bin ich sehr zufrieden. Ob im Bürogebäude oder über Teams die VF war immer schnell zu erreichen.
Trotzdem konnte ich diese zehn Tage sehr selbständig Arbeiten und so mein eigenes Können
unter Beweis stellen. Ich fragte nur nach bei Unklarheiten zum Auftrag oder wenn ich nicht mehr
weiterkam.
Während der Arbeit entstand selbstverständlich, aufgrund deren Wichtigkeit, etwas Druck.
Dieser hat mich aber mehr angespornt als gestresst. Ich war zehn Tage lang motiviert, um
sowohl ein hervorragendes Projekt abzuliefern als auch eine gute Note zu erzielen.
Aus den Arbeitsjournalen ist zu entnehmen, dass ich zu Beginn etwas unsicher war, ob die
Software in der vorgegebenen Zeit implementiert werden kann. Mitte der Woche war ich
dann auch knapp hinter dem Zeitplan. Ich liess mich davon aber nicht beirren, sondern
arbeitete konzentriert und exakt weiter. Schlussendlich konnte ich das Projekt komplett
fertigstellen.
Rückblickend konnte ich so einiges von diesem Projekt lernen.
- Wie bereits beschrieben birgt die Arbeit mit IPERKA die Gefahr, dass Probleme erst am Schluss erkannt werden. In meinem Fall offenbarten die Tests keine riesigen Komplikationen. Ich werde aber zukünftig darauf achten, früh und sauber zu testen.
- Im Frontend sollte man eine Applikation immer, auch wenn weitere Endgeräte
vorerst noch nicht geplant sind, mit responsiven Gedanken im Hinterkopf
implementieren. Es soll später nicht schwierig sein, zusätzliche Viewports
einzubauen.
Ich setzte ein paar Grössen mit Pixelwerten. Als sich dann aber herausstellte, dass der Bildschirm eine andere Auflösung hat, schadete dies der Darstellung.
In Zukunft werde ich möglichst viele Werte mit relativen Einheiten setzen. - Es ist nicht verkehrt, etwas mehr Wert auf die Dokumentation zu legen. In der Praxis bedeutet dies vielleicht nicht, die Umsetzung auf hunderten von Seiten festzuhalten. Ich werde mir aber Zeit nehmen, um die Readmes sauber zu verfassen.
- Ich ging fest davon aus, dass das Dokumentieren mich an der Umsetzung hindert. Das Beschreiben der Umsetzung kostete zwar Zeit, half mir aber mein Vorgehen und alternative Lösungen zu überdenken. In Zukunft werde ich bei Problemen schneller zu Stift und Papier greifen.
- Das Projekt lief aufgrund des klaren Verständnisses der Aufgabenstellung und der exakten Planung des Vorgehens so gut. Zukünftig werde ich Aufträge noch genauer analysieren und noch vor der Implementierung überlegen, was für Lösungsmöglichkeiten mir zur Verfügung stehen. Es ist nicht verkehrt, auch Dinge, die man für selbstverständlich hält (wie die Auflösung des Bildschirmes), nochmals zu überprüfen.
- Mir wurde in diesem Projekt erneut bewusst, wie gerne ich im Frontend-Bereich arbeite. Während der ersten eineinhalb Tage freute ich mich auf die Umsetzung der Webseite.
Insgesamt hat mir das Projekt Spass bereitet. Es gefiel mir auch, dass es sich nicht um eine typische Aufgabe handelte. Ich mochte die Herausforderungen und setzte die Aufgabe sehr gerne um. Ich wünsche mir auch von der Applikation, dass diese irgendwann weiterentwickelt wird. Vielleicht von mir oder sogar von einem zukünftigen Lehrling.
Nun hoffe ich, dass sich auch die Mitarbeiter und Besucher an den bespielten Bildschirmen erfreuen und ab und zu mal jemand stehen bleibt.
Glossar
Begriff | Definition |
---|---|
API | Eine Schnittstelle, die es Anwendungen ermöglicht, untereinander zu kommunizieren und Daten auszutauschen. |
Assets | Dateien wie Bilder oder Videos, die in eine Website oder Anwendung eingebunden werden. |
Black-Box-Testing | Ein Testverfahren, bei dem die interne Funktionsweise einer Anwendung nicht bekannt ist und nur das Ergebnis getestet wird. |
Commit | Eine Aktion, bei welcher Änderungen an einem Code-Repository gespeichert werden. |
Conventions | Übliche Standards und Regeln, die in der Softwareentwicklung befolgt werden, um eine konsistente und leicht verständliche Codebasis zu gewährleisten. |
Container | Ein Docker-Container ist eine ausführbare Umgebung, die alle erforderlichen Abhängigkeiten und Konfigurationen enthält, um eine Anwendung unabhängig von der zugrunde liegenden Infrastruktur auszuführen. |
Cookies | Kleine Textdateien, die auf dem Computer eines Nutzers gespeichert werden und Informationen über den Besuch einer Website enthalten. |
CSS | Cascading Style Sheets ist da zur Gestaltung von Webseiten. |
CSS-Vendor-Prefixes | Wird von verschiedenen Browsern hinzugefügt, um neue CSS-Features zu implementieren, bevor sie offiziell standardisiert sind. |
Docker | Ein Open-Source-Tool zur Erstellung, Bereitstellung und Verwaltung von Containern. |
DOM-Nodes | Elemente, welche im Dokument einer Webseite enthalten sind. |
Div | Ein HTML-Element zur Kennzeichnung oder Gestaltung eines Abschnitts. |
Endpoint | Eine spezifische URL, über die eine API aufgerufen werden kann, um Daten abzurufen oder zu ändern. |
Event Listener | Damit kann eine Aktion beim Eintritt eines Ereignisses ausgeführt werden. |
Experimental Decorators | Ist eine experimentelle JS-Funktion, welche es ermöglicht, Dekoratoren in Klassen und Methoden zu verwenden, um das Verhalten von Objekten zu ändern oder zu erweitern. |
Extensions | Zusätzliche Software-Module, zur Erweiterung der IDE-Funktionalität. |
Fallback | Eine alternative Option, welche zum Tragen kommt, wenn das ursprüngliche Element oder die Funktion nicht verfügbar ist. |
Fetch | Eine Funktion in JS, um asynchron Daten von einer API abzurufen. |
Figma | Eine Design-Software. |
Flexbox | Ein CSS-Layout. |
Font-face | Eine CSS-Regel zur Definition von Schriftarten. |
Gantt | Eine grafische Darstellung von Projektphasen und Aufgaben. Gantt wird in der Projektmanagement-Planung verwendet. |
Handlebars | Eine Templating-Engine, um dynamisch HTML-Code zu generieren. |
Headers | Informationen, welche in einer HTTP-Anfrage oder -Antwort enthalten sind, um Details über die Übertragung von Daten zwischen Client und Server zu geben. |
Helper | Eine Funktion, um wiederkehrende Aufgaben zu automatisieren und vereinfachen. |
XMLHttpRequest | Ein Objekt in JS zur asynchronen Abfrage von API-Daten. |
IDE | Eine Entwicklungsumgebung, die speziell für die Softwareentwicklung entwickelt wurde. |
Image | Ein Docker-Image ist eine Vorlage, die alle notwendigen Bestandteile enthält, um einen Docker-Container zu erstellen. |
Jira | Ein Tool zur Projektmanagement-Planung und -verfolgung. |
JS | JavaScript ist eine Skriptsprache, welche für Webbrowser entwickelt wurde. |
JSON | Ein Datenformat zur Speicherung strukturierter Daten. |
Library | Ein Satz von wiederverwendbaren Code-Modulen, welche zur Vereinfachung von Entwicklungsprozessen verwendet werden. |
Lightweight | Eine Anwendung oder ein Framework, das auf Einfachheit und geringen Ressourcenbedarf ausgelegt ist. |
Localhost | Der Hostname, welcher auf die eigene lokale Maschine verweist. |
LTS | Eine langfristig unterstützte Version einer Software oder eines Betriebssystems. |
Memory | Bezieht sich auf den Bereich des Speichers, in dem Daten temporär abgelegt werden, während ein Programm ausgeführt wird. |
Merge Request | Eine Anfrage an ein Git-Repository, um Änderungen von einem Branch in einen anderen zu überführen. |
Mock Daten | Künstlich erstellte Testdaten, welche oft zu Testzwecken erstellt werden. |
Mockup | Das Design der Webseite. In diesem Fall wurde es mit Figma erstellt. |
Node Version Switcher | Ein Tool, das verwendet wird, um zwischen verschiedenen Versionen von Node.js zu wechseln. |
NPM | NPM ist ein Werkzeug zum Installieren und Verwalten von Bibliotheken und Tools für Node.js-Anwendungen. |
Opening- und Closing-Tag | Die öffnenden und schliessenden HTML-Tags, die den Anfang und das Ende eines HTML-Elements markieren. |
Package | Eine Sammlung von Code-Modulen und Abhängigkeiten. Packages können installiert und verwaltet werden. |
package.json | Eine Datei in einem Node.js-Projekt, welche Informationen über das Projekt und seine Abhängigkeiten enthält. |
Pattern | Ein wiederkehrendes Design- oder Codierungselement, das zur Vereinfachung und Standardisierung von Entwicklungsprozessen verwendet wird. |
Prefix | Eine vorangestellte Zeichenfolge. |
Profiling | Die Sammlung und Analyse von Informationen über die Leistung und das Verhalten einer Webseite. |
Push | Eine Aktion, bei welcher Änderungen auf das Repository gesendet werden. |
Readme | Eine Datei, die Informationen und Anweisungen zur Verwendung des Codes enthält. |
Refactoring | Die Überarbeitung des Quellcodes, um diesen effizienter und wartbarer zu gestalten. |
Root | Der oberste Verzeichnisordner in einer Verzeichnisstruktur. |
Routes | In Nitro geschriebene APIs, die Funktionen unter einer URL bereitstellen. |
SVG | Ein Vektor-basiertes Grafikformat. |
Terminal | Ein Programm zur Nutzung einer Shell. |
Theming | Die Anpassung des Erscheinungsbilds einer Webseite. |
TS | TypeScript ist JS mit einer starken Typisierung. |
Twig | Eine PHP-Templating-Engine zur Generierung von dynamischem HTML-Code. |
Unit Tests | Tests, welche einzelne Teile einer Anwendung auf ihre Funktionalität überprüfen. |
Vanilla-JS | Ist reines JS, ohne die Verwendung von Frameworks. |
Viewports | Der sichtbare Bereich einer Webseite auf verschiedenen Geräten, wie Desktops, Tablets und Smartphones. |
VSC | Visual Studio Code ist eine integrierte Entwicklungsumgebung von Microsoft. |
White-Box-Testing | Ein Testverfahren, bei dem der interne Code einer Anwendung bekannt ist und gezielt getestet wird. |
Literaturverzeichnis
Augat, L. (28. März 2022). TimeTrack. Die beliebtesten Vorgehensmodelle im Projektmanagement.
Abgerufen von: https://www.timetrackapp.com/blog/vorgehensmodell-projektmanagement/ (opens in a new tab)
BEM. (10. März 2023). BEM. Introduction.
Abgerufen von: https://getbem.com/introduction/ (opens in a new tab)
Bexio. (27. Oktober 2020). Bexio. Mit der IPERKA-Methode bessere Entscheidungen für Ihr KMU treffen.
Abgerufen von: www.bexio.com/de-CH/blog/view/iperka-methode
ChatGPT. (13. März 2023). ChatGPT.
Abgerufen von: https://chat.openai.com (opens in a new tab)
Elias. (13. März 2023). Stack Overflow. Fetch multiple URLs at the same time?
Abgerufen von: https://stackoverflow.com/questions/59037553/fetch-multiple-urls-at-the-same-time (opens in a new tab)
Google. (14. März 2023). Google Maps Help. Discover coordinates or search by latitude & longitude.
Abgerufen von: https://support.google.com/maps/answer/18539?hl=en&co=GENIE.Platform%3DDesktop (opens in a new tab)
Merkle. (7. März 2023). Github. generator-nitro.
Abgerufen von: https://github.com/merkle-open/generator-nitro/tree/develop/packages/generator-nitro (opens in a new tab)
NodeJS. (7. März 2023). NodeJS. Releases.
Abgerufen von: https://nodejs.dev/en/about/releases/ (opens in a new tab)
OpenWeather. (6. März 2023). OpenWeather. Weather API.
Abgerufen von: https://openweathermap.org/api (opens in a new tab)
OpenWeather. (7. März 2023). OpenWeather. Pricing.
Abgerufen von: https://openweathermap.org/price (opens in a new tab)
Pandey, A. (7. März 2023). Meidum. Understanding of Font Formats: TTF, OTF, WOFF, EOT & SVG.
Abgerufen von: https://medium.com/@aitareydesign/understanding-of-font-formats-ttf-otf-woff-eot-svg-e55e00a1ef2 (opens in a new tab)
Shiklo, B. (6. Oktober 2019). ScienceSoft. 8 Vorgehensmodelle der Softwareentwicklung: mit Grafiken erklärt.
Abgerufen von: https://scnsoft.de/blog/vorgehensmodelle-der-softwareentwicklung (opens in a new tab)
Wild, K. (7. März 2023). The Dach Hub. Patterns in Nitro.
Abgerufen von: https://thedachhub.merkleinc.com/display/EDU/Patterns+in+Nitro (opens in a new tab)
Wild, K. (9. März 2023). The Dach Hub. CI/CD.
Abgerufen von: https://thedachhub.merkleinc.com/pages/viewpage.action?pageId=897224118 (opens in a new tab)
Wild, K. (7. März 2023). Wiki. AJAX.
Abgerufen von: https://wiki.namics.com/display/lehrlinge/AJAX (opens in a new tab)
Wild, K. (7. März 2023). Wiki. Keyframes vs. Transitions.
Abgerufen von: https://wiki.namics.com/display/lehrlinge/Keyframes+vs.+Transition (opens in a new tab)