2023
Merkle Info-Screens (IPA)

Merkle Info-Screens

Datum: März 2022
Lesedauer: 80 Minuten


21.03.2023
Individuelle praktische Arbeit
Merkle Info-Screens - Frontend Webapplikation

merkle-info-screens 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.

RolleAbkürzungBeschreibung
ChefexperteCEXAufsicht über die IPA.
HauptexperteHEXHauptansprechpartner für KAND und VF. Begleitet VF und KAND durch IPA.
NebenexperteNEXStellvertretender Ansprechpartner für KAND und VF während der IPA. Begleitet VF und KAND durch die IPA.
BerufsbildnerBBVerantwortlich für die betriebliche Ausbildung des KAND.
Vorgesetzte FachkraftVFPerson, welche dem KAND während der IPA als Ansprechperson zur Verfügung steht. Ansprechperson für die Experten für die jeweilige IPA.
KandidatKANDDer 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:

legende Abbildung 2: Legende
Quelle: Selbst erstellt in Excel

Soll-Zeit

soll-zeit Abbildung 3: Soll-Zeit
Quelle: Selbst erstellt in Excel

Ist-Zeit

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:

  1. Begrüssung (Welcome)
  2. Reminders & Regeln (Input)
  3. Wetter Standorte (WeatherLocations)
  4. Flachwitz (Joke)
  5. Reminder & Regeln (Input)

Im Figma habe ich diesen Ablauf noch visualisiert:

ablauf-screen-loop 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:

git-workflow 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.

MeilensteinTag der Erreichung geplantTag der Erreichung
Setup (Gitlab, Nitro, Linting, Prettier und CI)3
Welcome Screen4
Input Screen5
WeatherLocations Screen6
Joke Screen7
Loop mit Animation7
Tests erfolgreich8
Auswertung erledigt9
Abgegeben10

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:

  1. Applikation exportieren: npm run nitro:server
  2. dist Ordner per USB-Stick auf den Rechner kopieren
  3. Mit der Kommandozeile in den dist Ordner navigieren
  4. Mit nvs use zur korrekten Node-Version wechseln
  5. Pakete per npm i installieren
  6. Software starten: npm start
  7. Port aus der Konsole lesen und die Anwendung im Chrome-Browser per Localhost öffnen
  8. Stockwerksbildschirm einschalten und Laptop mit HDMI-Kabel verbinden
  9. Displayeinstellungen des Rechners anpassen, sodass "Only Extended Display"
  10. F11 klicken, um den Browser im Fullscreen anzuzeigen
  11. 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
1.0TechnischErstellung Git-RepositoryAuf git.namics.com gehen und nachschauen, ob das Projekt vom Nutzer "Kay Wild" erstellt wurde.Repository ist unter den persönlichen Projekten auffindbar.
1.1TechnischGenerierung Nitro-ProjektEs wird überprüft, ob ein Nitro-Projekt existiert. In der .node-version Datei wird die Version überprüftEin Nitro-Projekt wurde mit einer möglichst aktuellen Node-Version erstellt.
1.2TechnischLauffähigkeit ProjektexportDas Projekt wird wie im README.md beschrieben exportiert und gestartet.Die Applikation ist lauffähig.
1.3TVDarstellung Screens in LoopDie 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.4TVZufälligkeit der Inhalte und FarbvariantenDie 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
2.0TechnischQualität README.mdIm 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.1TechnischRun-Scriptspackage.json wird untersucht und die Scripts werden ausprobiert.Alle vorhandenen Scripts können ausgeführt werden. Es sind keine unrelevanten Aufgaben enthalten.
2.2TechnischSensible Daten im RepositoryDas Ergebnis eines Security Analyzers wird angeschaut.Die Analyse zeigt, dass das Repository sauber ist.

Linting und Testing

Nr.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
3.0TechnischKonfigurationen für Linting und TestingREADME.md wird gelesen.Es ist verständlich, wie das Linting und Testing ausgeführt werden kann.
3.1TechnischGithookEin Commit wird getätigt.Alle im package.json unter lint-staged aufgeführten Scripts werden ausgeführt.
3.2TechnischPrettier und LinterDie folgenden zwei Befehle werden in der Konsole ausgeführt: npm run lint npm run prettierEs werden keine Probleme in der Konsole gemeldet.
3.3TechnischCI-PipelineAuf 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
4.0TVDarstellung StockwerkscreenProjekt wird wie beschrieben exportiert und auf dem Bildschirm gestartet.Die Applikation wird sauber dargestellt.
4.1TV und technischStabilitätDie 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.2TVAnimationenGestartete Applikation wird im Browser beobachtet.Die Animationen werden ohne Ruckeln dargestellt.
4.3TVDatums- und ZeitsteuerungURL-Query-Parameter wird getestet. Dabei werden drei verschiedene Tage und Zeitpunkte ausprobiert. Beispiel: ?date=2023-02-20&time=09-30Die Screens müssen Daten anzeigen, welche zum Wochentag und der Uhrzeit passen.
4.4TVÜbergängeDie Übergänge des Screens werden genaustens angeschaut.Die Animationen zwischen den Screens sind fliessend und ohne Wartepausen.
4.5TV und technischAuslagerung AnimationsdauerIn 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
5.0TechnischSpeicherung Inhalte und RegelnEs wird im Projekt nachgeschaut, ob die Daten sinnvoll angelegt wurden.Es sollte ein sinnvoll strukturiertes JSON-File vorhanden sein.
5.1TVAnimationenApplikation wird gestartet und die Animationen angeschaut.Die Elemente erscheinen und verschwinden gemäss der Designvorgabe.
5.2TechnischEinhaltung RegelnEs wird mit den Regeln verglichen, ob auch die korrekten Inhalte dargestellt werden.Die Auswahl der Inhalte sollte genau eingehalten werden.
5.3TVSchriftEs wird überprüft, wie die Schrift aussieht.Es wurden die vorgegebenen Webfonts (Plage Bold und Proxima Nova) angezeigt. Die Texte sind zentriert.
5.4TVDarstellung Text Welcome ScreenDer Welcome Screen wird angeschaut.Der Begrüssungstext und der optionale Sekundärtext werden beide jeweils in einer Zeile dargestellt.
5.5TVDarstellung Text Input ScreenDie 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
6.0TechnischSpeicherung InhalteEs wird im Projekt nachgeschaut, ob die Daten sinnvoll angelegt wurden.Es sollte ein sinnvoll strukturiertes JSON-File vorhanden sein.
6.1TVDarstellung TextDer 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.2TVAnimationEs wird angeschaut, wie der Flachwitz aufgelöst wird.Die Texte werden, wie in der Designvorgabe beschrieben, ein- und ausgeblendet.
6.3TVPulsierenBeim 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.4TVHintergrundfarbeDer 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.5TechnischKonfigurierbarkeitIm 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.ArtWas wird getestet?Wie wird getestet?Erwartetes Ergebnis
7.0TVAnimationEs wird beobachtet, wie sich der Screen auf- und abbaut.Der Screen wird gemäss der Vorgabe animiert.
7.1TVAuswahl StandorteDie Standorte des Screens werden über mehrere Durchläufe hinweg beobachtet.Es werden immer drei zufällige Standorte dargestellt. Keinerlei Regelmässigkeiten sind erkennbar.
7.2TVDarstellung WetterdatenDas 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.3TVZwischenspeicherung DatenDie 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.4TVFarblicher FokusDie Animation des Screens wird beobachtet.Die einzelnen Standorte werden nacheinander farblich fokussiert. Auch die Outlines werden korrekt eingesetzt.
7.5TVUmgang mit FehlernDer 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:

InhaltBeschreibung
NameEin aussagekräftiger Name soll das Ticket beschreiben.
Definition of ReadyIm ersten Abschnitt werden die DoR-Kriterien beschrieben. Da wird aufgeführt, was erledigt sein muss, damit mit dem Ticket gestartet werden darf.
TodoUnter Todo wird aufgezeigt, was die Aufgabe ist. Dieser Abschnitt darf auch mit Hinweisen versehen werden.
Definition of DoneIm 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.

jira-kanban-board 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.

flussdiagramm-kommunikation 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.

3-layer-architektur 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:

uml-klassendiagramm-screen 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:

AbfrageErklärungMöglichkeitenMeine WahlBegründung
Desired nameName des ProjektesFreie Wahlmerkle-info-screensAussagekräftig
Desired js compilerJS- oder TS-Projekt erstellenjs / tsjsIch bin erfahrener in JS.
Desired template engineOb man Handlebars oder Twig als Template Engine verwenden will.hbs / twighbsIch kenne hbs besser.
Including example codeOb das Projekt mit Beispielcode erstellt werden soll.y / nnIch will von der grünen Wiese starten.
Static exporting functionalitiesOb der Exporter, welcher die Files zusammenstellen und exportieren kann, hinzugefügt werden soll.y / nnDas Projekt muss nicht statisch exportiert werden können. Der Export soll dynamisch sein.
Using client side templatesOb man dynamische Daten beim Client rendern will.y / nnBenötige ich nicht.
Using theming featuresOb man Theming einsetzen will.y / nnIch 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:

PaketLinkSnyk Health Score
fittyhttps://www.npmjs.com/package/fitty (opens in a new tab)59
textfithttps://www.npmjs.com/package/textfit (opens in a new tab)51
use-fit-texthttps://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:

NameBeschreibungLinkSnyk Health Score
@gondel/coreDamit 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
jqueryjQuery ist eine JS-Library. Damit kann vereinfachter JS-Code geschrieben werden.https://www.npmjs.com/package/jquery (opens in a new tab)93
fittyPasst 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ürzungSchriftartBeschreibung
EOTEmbedded Open TypeDies ist ein veraltetes Format, welches speziell für den Internet Explorer entwickelt wurde.
OTFOpen Type FormatBei diesem Format wurde darauf geachtet, dass es viele Zeichen beinhaltet und von Plattformen unterstützt werden kann.
WOFFWeb Open Font FormatDie 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.

erstellung-repository 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:

terminal
git clone git@git.namics.com:kwild/merkle-info-screens.git

Daraufhin erstellte ich einen Master Branch:

terminal
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:

terminal
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.

terminal
.-------------------------------------------.
| 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:

terminal
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.

terminal
     _-----_     ╭──────────────────────────╮
    |       |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:

terminal
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.

package.json
{
    "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.

experimental-decorators 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.

linter Abbildung 13: Linter
Quelle: Screenshot Terminal

Gelintet wird mit den folgenden Tools.

ScriptBeschreibung
lint:cssDas CSS wird mit Stylelint überprüft https://stylelint.io/ (opens in a new tab)
lint:dataDer Nitro-Environment-Linter überprüft, ob die Patterns valide sind.
lint:htmlUm das HTML zu überprüfen, wird html-validate eingesetzt. https://gitlab.com/html-validate/html-validate (opens in a new tab)
lint:jseslint ist der JS Linter. https://eslint.org/ (opens in a new tab)
lint:licenseDie 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.

prettier 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.

linting-testing-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:

  1. Bei einem Commit erkennt dies Husky und führt das pre-commit File aus.

  2. 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
  3. lint-staged ist im package.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:

.gitlab-ci.yml
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.

gitlab-pipeline 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.

shared-runners 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:

ci-cd-pipelines 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:

erstellung-branches 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.

struktur-fonts-shared 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.

webfont-plageboldtext.scss
@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.

ui.js
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.

document.scss
* {
    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.

plage-bold-text 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.

messages.json
{
    "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.

endpoint 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.

welcome.js
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.

screen.js
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.

pattern-generator 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:

welcome.js
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.

welcome.js
// 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.

welcome.scss
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:

langer-welcome-text Abbildung 24: Anzeige langer Welcome Text
Quelle: Screenshot Browser

Entry Animation
Animiert wird in der folgenden Reihenfolge:

  1. Die Bubbles erscheinen von oben und unten
  2. Die Bubbles bewegen sich bis zum Ende des Screens
  3. Die Hauptnachricht wird eingeblendet
  4. Der Sekundärtext wird eingeblendet
  5. Der Sekundärtext pulsiert drei Mal
4.7.5 Resultat

Der aufgebaute Screen sieht so aus:

welcome-screen 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:

  1. Refactoring: Gesamthaft wird der Code erst zum Schluss überarbeitet. Trotzdem versuchte ich die Dateien ein wenig aufzuräumen.

  2. Überprüfung der Akzeptanzkriterien: Um die Erfüllung des Auftrags sicherzustellen, wurde die Komponente auf die Akzeptanzkriterien überprüft.

  3. 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. mr-screen-welcome Abbildung 26: MR Screen Welcome
    Quelle: Screenshot GitLab

  4. Merge: Aktion in GitLab ausführen.

  5. Ticket aktualisieren: Der MR wurde noch im Jira verlinkt und das Ticket als abgeschlossen markiert.

  6. 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.

inputs.json
{
    "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.

inputs.json
// 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.

input.scss
.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.

langer-text-input 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)

response-wetter-api 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: &deg;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 valueIcon used
drizzlerainy.svg
rainrain.svg
snoWsnow.svg
mistfoggy.svg
hazefoggy.svg
dustfoggy.svg
fogfog.svg
sandunkown.svg
ashfog.svg
squallwind.svg
tornadostorm.svg
clearsun.svg
cloudsclouds.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.

weather-locations.js
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.

wetter-screen 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.

joke-screen 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:

  1. Der Controller nimmt einen Screen aus dem Loop und startet diesen.
  2. Der gestartete Screen animiert sich selbst, stellt die nötigen Inhalte dar und baut sich auch wieder selbst ab.
  3. Nachdem der Screen fertig ist, meldet er dies dem Controller.
  4. 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.

ablauf-input-screen 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.

app.js
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.

rand-zwischen-screens 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.

export-problem Abbildung 33: Export Problem
Quelle: Screenshot Terminal

Die VF wies auf zwei Lösungswege hin:

  1. Die zwei Ordner wieder hinzufügen
  2. 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.

NameURLRequestResponse
Inputapi/inputZeitpunktZufälliger Input
Jokeapi/joke-Zufälliger Joke
Locationsapi/locations-Drei zufällige Standorte
Weatherapi/weatherStandortWetter des Standorts
Welcomeapi/inputZeitpunktZufä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.

package.json
{
    "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.ZeitpunktWas wird getestet?Ergebnis
1.013:30Erstellung Git-RepositoryGitLab Repository wurde im privaten Bereich angelegt. gitlab-projektAbbildung 34: GitLab Projekt; Quelle: Screenshot GitLab
1.113:30Generierung Nitro-ProjektEin Nitro Projekt ist vorhanden. In der .node-version Datei ist die Version 16.19.0 notiert. nitro-setup-gitlabAbbildung 35: Nitro Setup; Quelle: Screenshot GitLab
1.213:30Lauffähigkeit ProjektexportEin Export kann mit npm run nitro:server erstellt und wie in der Abbildung gestartet werden. Beschrieben ist dies im Readme. lauffaehiger-exportAbbildung 36: Lauffähiger Export; Quelle: Screenshot Terminal
1.313:30Darstellung Screens in LoopDie Reihenfolge der Screens stimmt auch noch nach fünf Minuten.
1.413:30Zufälligkeit der Inhalte und FarbvariantenNach fünf Minuten Beobachtungszeit konnten keine Muster erkannt werden. Die Farben und Inhalte sind zufällig.
5.2.2 Standards und Conventions
Nr.ZeitpunktWas wird getestet?Ergebnis
2.014:00Qualität README.mdDas 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. einleitung-readmeAbbildung 37: Einleitung Readme; Quelle: Screenshot VSC
2.114:00Run-ScriptsDie Scripts wurden mit npm run getestet und funktionieren.
2.214:00Sensible Daten im RepositoryIn der Abbildung ist erkennbar, dass das Projekt laut dem Security-Job beim Master-Merge keine sensiblen Daten enthält. secret-detection-jobAbbildung 38: secret_detection Job; Quelle: Screenshot Terminal
5.2.3 Linting und Testing
Nr.ZeitpunktWas wird getestet?Ergebnis
3.014:30Konfigurationen für Linting und Testing❌ Das Readme enthält keine Informationen über die Verwendung des Linters und Prettiers.
3.114:30GithookAlle Scripts laufen durch. githookAbbildung 39: Githook; Quelle: Screenshot Terminal
3.214:30Prettier und LinterDer Linter läuft ohne Fehler oder Warnungen durch. linting-resultatAbbildung 40: Linting Resultat; Quelle: Screenshot Terminal; Dieser Ausschnitt zeigt, dass auch der Prettier fehlerfrei funktioniert. resultat-prettierAbbildung 41: Resultat Prettier; Quelle: Screenshot Terminal
3.314:30CI-PipelineAuf GitLab ist ersichtlich, dass die Pipeline schon seit Anbeginn des Projekts korrekt konfiguriert ist. ci-pipelineAbbildung 42: CI-Pipeline; Quelle: Screenshot GitLab
5.2.4 Verwendbarkeit der Applikation auf einem Screen im Merkle Office St. Gallen
Nr.ZeitpunktWas wird getestet?Ergebnis
4.015:00Darstellung Stockwerkscreen❌ Die Inhalte des Input- und Wetterscreens werden nicht richtig platziert. stockwerkbildschirmAbbildung 43: WeatherLocations Screen auf Stockwerksbildschirm; Quelle: Selbst erstellt
4.115:00StabilitätUm 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. profiling-ergebnisAbbildung 44: Profiling Ergebnis; Quelle: Screenshot Browser
4.215:30AnimationenDie Animationen werden flüssig dargestellt.
4.315:30Datums- und ZeitsteuerungUm die Zeitsteuerung zu überprüfen, wurden drei verschiedene Daten mitgegeben.; 1. ?date=2023-02-20&time=09-30 welcome-montagmorgenAbbildung 45: Welcome Montagmorgen; Quelle: Screenshot Browser; 2. ?date=2003-02-12&time=22-14 welcome-mittwochabendAbbildung 46: Welcome Mittwochabend; Quelle: Screenshot Browser; 3. ?date=2023-02-10&time=12-14 welcome-freitagmittagAbbildung 47: Welcome Freitagmittag; Quelle: Screenshot Browser; An den Screenshots ist zu erkennen, dass alle korrekt verwertet wurden.
4.415:30ÜbergängeDie Übergänge sehen ansprechend aus.
4.515:30Auslagerung AnimationsdauerEs 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. animationsdauer-screen-klasseAbbildung 48: Animationsdauer in Screen-Klasse; Quelle: Screenshot VSC
5.2.5 Screen Welcome und Input
Nr.ZeitpunktWas wird getestet?Ergebnis
5.016:00Speicherung Inhalte und RegelnAlle Daten befinden sich an einem zentralen Ort und sind auch sinnvoll strukturiert. json-datenAbbildung 49: JSON-Daten; Quelle: Screenshot VSC
5.116:00Animationen⚠️ 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.216:00Einhaltung RegelnDa am Nachmittag getestet wurde, stimmte der angezeigte Input. input-screen-nachmittagAbbildung 50: Input Screen Nachmittag; Quelle: Selbst erstellt; Darüber hinaus wurde auch kontrolliert, ob sich diese Inhalte mit einem URL-Query- Parameter korrekt verändern. Auch dies ist der Fall.
5.316:00Schrift❌ Die Schriften haben die vorgegeben Schriftarten und sind zentriert. Der Rand sieht jedoch in seltenen Fällen nicht perfekt aus.
5.416:00Darstellung Text Welcome ScreenEgal wie lang der Text oder klein das Fenster ist, er bleibt lesbar. welcome-ipad-groesseAbbildung 51: Welcome Text iPad Air Grösse; Quelle: Screenshot Browser
5.516:00Darstellung Text Input Screen❌ Bei manchen äusserst langen Texten sieht das Resultat noch nicht zufriedenstellend aus. langer-inputAbbildung 52: Langer Input; Quelle: Screenshot Browser
5.2.6 Screen Joke
Nr.ZeitpunktWas wird getestet?Ergebnis
6.016:00Speicherung InhalteDie Daten sind ansprechend strukturiert in einer JSON-Datei abgelegt.
6.116:00Darstellung TextAuch lange Witze können vollständig angezeigt werden. langer-witzAbbildung 53: Langer Witz; Quelle: Screenshot Browser
6.216:30AnimationDie Frage pulsiert zweimal und wird danach ausgeblendet. Daraufhin erscheint eine Punchline, welche einmal pulsiert.
6.316:30PulsierenDie Frage pulsiert zweimal und wird danach ausgeblendet. Daraufhin erscheint eine Punchline, welche einmal pulsiert.
6.416:30HintergrundfarbeDieser Test wurde gestrichen, da der Test 1.4 dies bereits überprüft hat.
6.516:30KonfigurierbarkeitEs stehen zwei Variablen zur Anpassung der zwei Längen zur Verfügung. joke-zeitenAbbildung 54: Joke-Zeiten; Quelle: Screenshot VSC; Auch im Readme steht dies beschrieben. joke-ausschnittAbbildung 55: Joke-Ausschnitt Readme; Quelle: Screenshot VSC
5.2.6 Screen WeatherLocations
Nr.ZeitpunktWas wird getestet?Ergebnis
7.016:30AnimationWie in der Vorgabe geschrieben steht, wird der Screen korrekt auf- und abgebaut.
7.116:30Auswahl StandorteBei 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. antwort-locations-routeAbbildung 56: Ausschnitt Antwort Locations Route; Quelle: Screenshot Browser
7.216:30Darstellung WetterdatenDie Temperaturen sind korrekt und werden immer auf ganze Zahlen gerundet.
7.316:30Zwischenspeicherung DatenNachdem jeder Standort bereits angezeigt wurde, wurde das WLAN deaktiviert. Danach konnten immer noch Daten angezeigt werden. Die Zwischenspeicherung funktioniert also.
7.416:30Farblicher 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.516:30Umgang mit FehlernAls 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.

testauswertung 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.

  1. Der Overflow des Containers, in welchem das Wetter dargestellt wird, wurde auf hidden gesetzt.
  2. Der Text erhielt eine maximale Breite von 90 Prozent.
  3. white-space des Textes wurde auf nowrap 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:

  1. Das Icon als Hintergrundbild eines Divs einbinden. Dadurch kann eine Transition auf der Source definiert werden.
  2. Es werden beide Icons dem HTML hinzugefügt. Das farblose wird dann mit einem Übergang unsichtbar. Das aktive Icon wird langsam angezeigt.
  3. 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.ZeitpunktWas wird getestet?Ergebnis
3.08:30Konfiguration für Linting und TestingIm Readme ist nun vermerkt, wie der Linter und Prettier ausgeführt werden können. linter-prettier-beschreibungAbbildung 58: Linter und Prettier Beschreibung; Quelle: Screenshot VSC
4.08:30Darstellung StockwerksscreenAlle Screens werden korrekt dargestellt. wetterscreen-korrektAbbildung 59: Korrekte Darstellung Wetterscreen; Quelle: Selbst erstellt
5.18:30AnimationenUm 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. welcome-browserkonsoleAbbildung 60: Welcome Browserkonsole; Quelle: Screenshot Browser
5.38:30SchriftDer Textschatten ist nun nicht mehr mit Pixeln, sondern im Verhältnis zur Schriftgrösse gesetzt. Die Schrift sieht auf allen Screens ansprechend aus. textschatten-updatedAbbildung 61: Überarbeiteter Textschatten; Quelle: Screenshot VSC
5.58:30Darstellung Text Input ScreenDer Text läuft über höchstens drei Linien und wird mit drei Punkten abgeschnitten, falls er zu lange ist. input-text-korrektAbbildung 62: Korrekter Input-Text; Quelle: Selbst erstellt
7.4-Farblicher FokusDiese 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.

nutzung-jira 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.

gitlab-commits Abbildung 64: GitLab Commits
Quelle: Screenshot GitLab

Auch die Nachrichten dieser Commits entsprechen den definierten Vorgaben.

commit-messages 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.

onedrive 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.

  1. Mit der online Version arbeiten
  2. 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.

onedrive-403 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.

soll-ist-zeit 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.

MeilensteinTag der Erreichung geplantTag der Erreichung
Setup Gitlab, Nitro, Linting, Prettier und CI33
Welcome Screen44
Input Screen55
WeatherLocations Screen66
Joke Screen77
Loop mit Animation77
Tests erfolgreich8⚠️ 9
Auswertung erledigt99
Abgegeben1010

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.

info-screen-stockwerk-wetter Abbildung 69: Info-Screen sechster Stock - Wetter
Quelle: Selbst erstellt

info-screen-stockwerk-welcome 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.

jira-backlog 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

BegriffDefinition
APIEine Schnittstelle, die es Anwendungen ermöglicht, untereinander zu kommunizieren und Daten auszutauschen.
AssetsDateien wie Bilder oder Videos, die in eine Website oder Anwendung eingebunden werden.
Black-Box-TestingEin Testverfahren, bei dem die interne Funktionsweise einer Anwendung nicht bekannt ist und nur das Ergebnis getestet wird.
CommitEine 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.
ContainerEin 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.
CookiesKleine Textdateien, die auf dem Computer eines Nutzers gespeichert werden und Informationen über den Besuch einer Website enthalten.
CSSCascading Style Sheets ist da zur Gestaltung von Webseiten.
CSS-Vendor-PrefixesWird von verschiedenen Browsern hinzugefügt, um neue CSS-Features zu implementieren, bevor sie offiziell standardisiert sind.
DockerEin Open-Source-Tool zur Erstellung, Bereitstellung und Verwaltung von Containern.
DOM-NodesElemente, welche im Dokument einer Webseite enthalten sind.
DivEin HTML-Element zur Kennzeichnung oder Gestaltung eines Abschnitts.
EndpointEine spezifische URL, über die eine API aufgerufen werden kann, um Daten abzurufen oder zu ändern.
Event ListenerDamit kann eine Aktion beim Eintritt eines Ereignisses ausgeführt werden.
Experimental DecoratorsIst 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.
ExtensionsZusätzliche Software-Module, zur Erweiterung der IDE-Funktionalität.
FallbackEine alternative Option, welche zum Tragen kommt, wenn das ursprüngliche Element oder die Funktion nicht verfügbar ist.
FetchEine Funktion in JS, um asynchron Daten von einer API abzurufen.
FigmaEine Design-Software.
FlexboxEin CSS-Layout.
Font-faceEine CSS-Regel zur Definition von Schriftarten.
GanttEine grafische Darstellung von Projektphasen und Aufgaben. Gantt wird in der Projektmanagement-Planung verwendet.
HandlebarsEine Templating-Engine, um dynamisch HTML-Code zu generieren.
HeadersInformationen, welche in einer HTTP-Anfrage oder -Antwort enthalten sind, um Details über die Übertragung von Daten zwischen Client und Server zu geben.
HelperEine Funktion, um wiederkehrende Aufgaben zu automatisieren und vereinfachen.
XMLHttpRequestEin Objekt in JS zur asynchronen Abfrage von API-Daten.
IDEEine Entwicklungsumgebung, die speziell für die Softwareentwicklung entwickelt wurde.
ImageEin Docker-Image ist eine Vorlage, die alle notwendigen Bestandteile enthält, um einen Docker-Container zu erstellen.
JiraEin Tool zur Projektmanagement-Planung und -verfolgung.
JSJavaScript ist eine Skriptsprache, welche für Webbrowser entwickelt wurde.
JSONEin Datenformat zur Speicherung strukturierter Daten.
LibraryEin Satz von wiederverwendbaren Code-Modulen, welche zur Vereinfachung von Entwicklungsprozessen verwendet werden.
LightweightEine Anwendung oder ein Framework, das auf Einfachheit und geringen Ressourcenbedarf ausgelegt ist.
LocalhostDer Hostname, welcher auf die eigene lokale Maschine verweist.
LTSEine langfristig unterstützte Version einer Software oder eines Betriebssystems.
MemoryBezieht sich auf den Bereich des Speichers, in dem Daten temporär abgelegt werden, während ein Programm ausgeführt wird.
Merge RequestEine Anfrage an ein Git-Repository, um Änderungen von einem Branch in einen anderen zu überführen.
Mock DatenKünstlich erstellte Testdaten, welche oft zu Testzwecken erstellt werden.
MockupDas Design der Webseite. In diesem Fall wurde es mit Figma erstellt.
Node Version SwitcherEin Tool, das verwendet wird, um zwischen verschiedenen Versionen von Node.js zu wechseln.
NPMNPM ist ein Werkzeug zum Installieren und Verwalten von Bibliotheken und Tools für Node.js-Anwendungen.
Opening- und Closing-TagDie öffnenden und schliessenden HTML-Tags, die den Anfang und das Ende eines HTML-Elements markieren.
PackageEine Sammlung von Code-Modulen und Abhängigkeiten. Packages können installiert und verwaltet werden.
package.jsonEine Datei in einem Node.js-Projekt, welche Informationen über das Projekt und seine Abhängigkeiten enthält.
PatternEin wiederkehrendes Design- oder Codierungselement, das zur Vereinfachung und Standardisierung von Entwicklungsprozessen verwendet wird.
PrefixEine vorangestellte Zeichenfolge.
ProfilingDie Sammlung und Analyse von Informationen über die Leistung und das Verhalten einer Webseite.
PushEine Aktion, bei welcher Änderungen auf das Repository gesendet werden.
ReadmeEine Datei, die Informationen und Anweisungen zur Verwendung des Codes enthält.
RefactoringDie Überarbeitung des Quellcodes, um diesen effizienter und wartbarer zu gestalten.
RootDer oberste Verzeichnisordner in einer Verzeichnisstruktur.
RoutesIn Nitro geschriebene APIs, die Funktionen unter einer URL bereitstellen.
SVGEin Vektor-basiertes Grafikformat.
TerminalEin Programm zur Nutzung einer Shell.
ThemingDie Anpassung des Erscheinungsbilds einer Webseite.
TSTypeScript ist JS mit einer starken Typisierung.
TwigEine PHP-Templating-Engine zur Generierung von dynamischem HTML-Code.
Unit TestsTests, welche einzelne Teile einer Anwendung auf ihre Funktionalität überprüfen.
Vanilla-JSIst reines JS, ohne die Verwendung von Frameworks.
ViewportsDer sichtbare Bereich einer Webseite auf verschiedenen Geräten, wie Desktops, Tablets und Smartphones.
VSCVisual Studio Code ist eine integrierte Entwicklungsumgebung von Microsoft.
White-Box-TestingEin 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)