https://visualhunt.com/photo/6356/

Widoki aplikacji webowej

Od piątkowego wpisu nie minęło zbyt wiele czasu, ale mimo to w weekend udało mi się trochę popracować nad projektem. W dalszym ciągu nie mam zintegrowanego Hibernate z Play Framework, jednak nie chciałem tracić na to kolejnego wieczoru i zająłem się innym tematem, aby mieć o czym pisać tu na blogu.

W projekcie pojawiły się modyfikacje niektórych widoków. Jest to mało ambitna dla mnie część, jednak chciałem pokazać za ich pomocą trochę więcej planowanej funkcjonalności.

Plan mieszkania

Plan mieszkania
Widok z planem mieszkania

Finalny Plan mieszkania będzie widokiem opartym o element canvas z HTML5, na którym wyświetlany będzie rozkład pomieszczeń wraz z naniesionymi elementami systemu, tj. czujnikami oraz sterowanymi elementami wyjściowymi. Szczegóły czujnika będą dostępne w rozwijanym panelu po lewej stronie ekranu po naciśnięciu na wybrany sensor. Interakcja z użytkownikiem oraz wyświetlanie całości będzie realizowane za pomocą JavaScript (jQuery). Na chwilę obecną widok zawiera element <canvas> z zaimportowanym, statycznym planem mieszkania. Pierwsze próby obsługi tego znacznika już za mną. Na zrzucie ekranu widać czerwony prostokąt, na którym ćwiczyłem obsługę myszki. Z kolei naniesione wartości liczbowe to przykładowe temperatury otrzymane z zapytania asynchronicznego do metody getPresentTemperature(int id) kontrolera SensorController. Prawdopodobnie do tego typu zastosowania obsługa znacznika canvas z poziomu czystego JS z dodatkiem jQuery będzie wystarczająca, jednak planuję przyjrzeć się bliżej dostępnym bibliotekom. Na oku mam Fabric.js. Wykraczając poza plany na DSP2017 związane z tym projektem, chciałbym zrealizować możliwość importu planu mieszkania z pliku, np. *.svg z naniesionymi w odpowiednich miejscach sensorami.

Tablica informacyjna

Tablica informacyjna
Widok z tablicą informacyjną

Tablica informacyjna jest widokiem agregującym informacje o stanie wszystkich czujników, jednak bez możliwości zmiany stanu elementów załączających, tj. przekaźników i modułów z triakiem. Widok będzie w zasadzie podobny do planu mieszkania, tylko bez graficznego bajeru. Planuję cykliczną aktualizację wartości temperatur, wilgotności oraz stanów pozostałych sensorów, co początkowo zrealizowałem za pomocą odświeżania całej strony. W przyszłości chcę w tym miejscu wykorzystać zapytania asynchroniczne AJAX.

@import scala.Predef; var counter = 0
 
@(counter = 0)
@for(sensor <- sensors) {
    @if(sensor.sensorType.direction == DirectionENUM.OUT){
        @(counter = counter + 1)
        <tr>
            <td>@counter</td>
            <td>@sensor.sensorType.sensorType</td>
            <td>@sensor.room.name</td>
            <td>@sensor.description</td>
        </tr>
    } 
}

W tym widoku dane prezentowane będą w formie tabelarycznej. W związku z tym, że informacje filtruję dopiero w widoku, nie mogłem użyć konstrukcji z zipWithIndex. Wtedy numerowany byłby każdy obieg pętli, a ja chciałem numerować tylko te pozycje spełniające warunek @if. Oczywiście można to zrobić w inny sposób w Scali, jednak nie wnikam w szczegóły, bo w tym temacie jestem całkowicie zielony. Rozważałem również przygotowanie przefiltrowanych wyników po stronie serwera, jednak oznaczałoby to konieczność napisania większej ilości kodu, co przy tak mocno ograniczonej liczbie czujników wydaje się być nieopłacalne. Sądzę, że w tym przypadku mogę sobie pozwolić na zapytanie typu SELECT * FROM sensors.

Konfiguracja -> Sensory

Sensory w systemie
Widok z listą zainstalowanych czujników w systemie

Widok dostępny w trybie konfiguracji, czyli docelowo dla administratora systemu. Informacje tu zawarte będą analogiczne go widoku tablicy informacyjnej, za wyjątkiem ostatniego stanu sensorów. Administrator do dyspozycji będzie miał możliwość dodania nowego elementu do systemu oraz jego rozmieszczenia na planie mieszkania.

Konfiguracja -> Pomieszczenia

Pomieszczenia
Widok z listą pomieszczeń w mieszkaniu

Podobnie jak w przypadku konfiguracji sensorów, administrator będzie mógł zarządzać pomieszczeniami w mieszkaniu (początkowo nazwa i opis pomieszczenia). Widok zawiera listę pomieszczeń oraz odsyłacze umożliwiające wyświetlenie formularza dodania nowego lub edycji istniejącego pomieszczenia.

Formularz konfiguracji nowego sensora

Formularz sensora
Widok z formularzem dodawania/edycji sensora w systemie

Jest! Pierwszy formularz w moim projekcie. Wstawiłem jedno pole tekstowe i dwa typu <select> w których administrator wybiera wartości z ograniczonego zakresu. Na tym prostym przykładzie będę rozpoznawał działanie zapytań CRUD. Będzie też na pewno jakaś prosta walidacja, chociażby blokująca możliwość dodania złośliwego kodu w polu description (@SafeHtml).

@(message: String)(sensorTypes: Array[SensorTypesENUM])(rooms: List[Room])
 
@main("Home Controller") {
<form method="POST" action="@routes.SensorController.addEditSensor()" class="form-horizontal">
     <!-- (...) -->
     <div class="row col-lg-offset-2">
        <div class="form-group">
           <label for="sensorType" class="col-lg-3">Rodzaj czujnika:</label>
              <div class="col-lg-6">
                 <select name="types" class="form-control" id="sensorType">
                    @for(sType <- sensorTypes) {
                       <option value="@sType">@sType</option>
                    }
                 </select>
              </div>
        </div>
     </div>
     <!-- (...) -->
     <div class="row col-lg-offset-2">
         <div class="form-group">
             <div class="col-lg-offset-7 col-lg-1">
                 <button type="submit" id="btnAdd" class="btn btn-primary" value="Zapisz">
                     Zapisz <span class="glyphicon glyphicon-hand-right"></span> 
                 </button>
             </div>
         </div>
     </div>
</form>
}

Za wygląd formularza odpowiedzialne są klasy z Bootstrap. Wysłanie (Zapisz) generuje zapytanie typu POST do metody addEditSensor() kontrolera SensorController. Do widoku przekazuję tablicę typów sensorów oraz listę dostępnych pomieszczeń, które są wyświetlane w znaczniku option elementu select za pomocą składni @for().

Formularz konfiguracji pomieszczenia

Formularz pomieszczenia
Widok z formularzem dodawania/edycji pomieszczenia

Widok służy do dodawania/edycji pomieszczenia w mieszkaniu. Właściwie nie ma się o czym w tym miejscu rozpisywać, jest to jeszcze prostsza forma niż formularz dla sensorów.

W tym temacie to tyle. Początkowo chciałem w tym wpisie opisać dodatkowo architekturę aplikacji, jednak stwierdziłem, że to jest całkiem inny temat i zdecydowałem się podzielić całość na dwa posty. W kolejnym odcinku będzie właśnie o strukturze aplikacji (MVC i te sprawy) – zapraszam ponownie na mojego bloga!

Literatura obowiązkowa:

The template engine
Bootstrap – Getting started

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *