フロントエンド・アプリケーションの実行

フロントエンド・アプリケーションを実行するには、次の手順を実行します。(ソースコードをダウンロードしたフォルダにいると仮定しています:

  • ./tour-guide startを使用して、コマンドラインインターフェイス(今すぐCLIから)を使用してアプリケーションを起動します
  • tour-guide configure keyrockを使用して、Keyrockにユーザ、役割、権限を設定します
  • ./tour-guide configure oauthを使用して、KeyrockからOauth資格情報を取得し、それらをTourGuide設定に追加します。
  • ./tour-guide configure hostsを使用して、エイリアスを使ってサービスに接続するためにhostsファイルを設定します

上記のすべての手順を実行すると、フロントエンド・アプリケーションを使用できる状態になります。 Webブラウザでhttp://tourguide/clientを開くと、次のように表示されます:

FRONT END MAIN VIEW

You can log in using, for instance, the user `user1@test.com` with the password `test`. Once logged in, you can see a new menu at the top of the page:

* **Home**: Return to the main view where all restaurants are displayed.   
* **My franchises** (only available for users that belong to a franchise): Display information filtered by user franchises. The sub menu entries available for each franchise are: 
    * **Restaurants**: Filter restaurants shown in the map by the selected franchise.
    * **Reviews**: Display all reviews written about the selected franchise.
     * **Reservations**: Display all reservations of the selected franchise.
 * **My reservations**: Display a list with all the reservations made by the logged user.
 * **My reviews**: Display a list with all reviews written by the logged user.

ORGANIZATIONS MENU

フロントエンド・アプリケーションのメインビュー

このセクションでは、すべてのレストランが地図に表示されます。レストランのマーカーの重複を避けるために、クラスタリング手法を使用してグループ化されています。 グループを拡大またはクリックすると、レストランまたはそれ以上のグループが表示されます。 各グループには、いくつのレストランが集約されたことを表す数字があります。あなたが望むレストランを得るまでズームレベルを上げるか、グループをクリックする必要があります。 次の図は、レストランのマークとグループの表現を示しています:

RESTAURANTS AND GROUP MARKS

レストランのマークをクリックすると、一般情報といくつかの操作を含むポップアップが表示されます:

RESTAURANT POP UP

“Show reviews”(レビューの表示)と”Show reservations”(予約の表示)オプションは常に表示されます。 “Make a reservation”(予約する)オプションを表示するにはログインし、レビューを作成するにはどのフランチャイズにも属さないようにする必要があります。このオプションのいずれかをクリックすると、要求された情報を表示するモーダルウィンドウが表示されたり、操作を実行する入力メカニズムが提供されたり、します。

CREATE REVIEW

ユーザまたはフランチャイズによるレビュー

レストラン・レビューの表示方法とは異なり、ユーザまたはレストランによってフィルタリングされたレビューは、特定のセクションを使用して表示されます。 すべてのレビューは、次の図のようにリストされています:

CLIENT REVIEWS

“Edit review”(レビューの編集)と” Delete review”(レビューの削除)のオプションは “My reviews section”(マイレビューセクション)でのみ利用できます。

ユーザーまたは組織によってフィルタリングされた予約

このケースはレビューケースと似ていますが、レストランの予約はメインビューのポップアップとして表示され、ログに記録されたユーザーや組織によってフィルタリングされたレビューは特定のセクションに表示されます:

CLIENT RESERVATIONS

フロントエンド・アプリケーション構造

フロントエンド・アプリケーションは、HTML5, CSSおよびJSを使用して構築されています。これらは最も重要なモジュールです:

  • restaurantsAPI.js:このモジュールはサーバAPIに対してリクエストを実行します。
  • connectionsAPI.js:このモジュールには、ユーザセッションに関連する機能が含まれています。
  • drawModule.js:このモジュールには、UIを構築するメソッドが含まれています。
  • clientLogic.js:このモジュールは、アプリケーションの動作を指定します。 また、他のモジュールも相互接続します。
  • leaflet.js:インタラクティブマップをレンダリングするためのJSライブラリです。

FRONT END MODULES

restaurantsAPI.js

このモジュールは、フロントエンド・アプリケーションとサーバーAPIの間でほとんどの要求を実行します。 内部構成では、すべての要求が送信されるAPIエンドポイントが定義されます:

...
var baseURL = 'http://tourguide/api/orion/';
...

このモジュールが提供するすべての関数(simplifyRestaurantsFormatを除く)は、2つのコールバック関数を受け入れます。1つは成功した場合の結果データを処理し、もう1つは可能なエラーを処理するための関数です。 たとえば、次のようにgetAllRestaurantsが呼び出されたとします。

getAllRestaurants(func1, func2); 

API要求が200 OKで応答すると、入力パラメータとして応答を使用してfunc1が呼び出されます。ただし、APIがエラーを取得した場合(404 NOT FOUNDなど)、代わりにfunc2が呼び出されます。

このモジュールによって提供される関数は次のとおりです:

  • getAllRestaurants(sucessCallback, errorCallback): この関数は、すべてのレストランを取得するために使用されます。
  • getOrganizationRestaurants(organization, sucessCallback, errorCallback): この関数はgetAllRestaurantsのようなレストランを取得しますが、組織によってフィルタリングされます。
  • getOrganizationReviews(organization, sucessCallback, errorCallback): 指定された組織のすべてのレストランについて書かれたすべてのレビューを取得します。
  • getOrganizationRservations(organization, sucessCallback, errorCallback):指定された組織のすべての予約を取得します。
  • getRestaurantReviews(restaurantName, sucessCallback, errorCallback): 指定されたレストランに関するすべてのレビューを取得します。
  • getRestaurantReservations(restaurantName, sucessCallback, errorCallback): 指定されたレストランのすべての予約を取得します。
  • getUserReviews(username, sucessCallback, errorCallback): 指定されたユーザによって書き込まれたすべてのレビューを取得します。
  • getUserReservations(username, sucessCallback, errorCallback): 指定されたユーザが行った予約をすべて取得します。
  • getReview(reviewID, sucessCallback, errorCallback): 特定のレビューを取得します。
  • createNewReview(restaurantName, ratingValue, reviewBody, sucessCallback, errorCallback): 渡された評価値とレビュー内容を使用して、指定されたレストランの新しいレビューを作成します。
  • updateReview(reviewId, ratingValue, reviewBody, sucessCallback, errorCallback): 指定された新しい値を使用して、指定したレビューを更新します。
  • deleteReview(reviewId, sucessCallback, errorCallback): 指定されたレビューを削除します。
  • createNewReservation(restaurantName, partySize, reservationDatetime, sucessCallback, errorCallback):指定されたレストランと指定された日付にログインしたユーザの新しい予約を作成します。
  • cancelReservation(reservationId, sucessCallback, errorCallback): 指定された予約をキャンセルします。
  • simplifyRestaurantsFormat (restaurants): レストランの配列を取って、レストランを簡略化した別のものを返します。入力配列の想定される形式は、getOrganizationRestaurantsまたはgetAllRestaurantsに使用される形式と同じです。この機能は、無効な座標を持つレストランを除外します。

connectionsAPI.js

このモジュールは、ユーザ情報とトップメニューを管理します。役割とアクセス許可に関する情報があります。モジュールは、次の機能を提供します:

  • loginNeeded(action): ユーザがログインしている場合にのみ、指定された関数を実行します。
  • loggedIn(userInfo): Webブラウザのローカルストレージlocal storageにユーザ情報を格納し、ユーザ情報を使用してトップメニューを作成します。
  • notLoggedIn(): Webブラウザのローカルストレージlocal storageからユーザ情報を削除し、ログインオプション付きでトップメニューを作成します。
  • hasRole(userInfo, roleName): 指定されたユーザが指定されたロールを持つ場合にtrue値を返します。
  • getUser(): ログに記録されたユーザに関する情報を返す関数。
  • roles: 使用可能なロールを持つオブジェクト。

また、このモジュールは、ユーザを知るためにサーバーAPIに照会するinit関数を実行します。このような要求が成功すると、init関数はメニューを作成してユーザ情報を保管するloggedIn関数を実行します。それ以外の場合は、 notLoggedInを実行し、以前に格納されたすべてのユーザデータをすべて削除してメニューを作成します。

drawModule.js

このモジュールは、UIに厳密に関連したほとんどの操作を実行します。このモジュールを使用するには、Leaflet, jQuery, jQueryUI とtimepickerライブラリを追加する必要があります。他のモジュールとは異なり、このイベントは、イベントがトリガされたときに実行されるアクションで初期化する必要があります。このアクションは、次の機能を使用して設定できます。

  • setViewReservationAction(action)
  • setViewRestaurantReviewsAction(action)
  • setCreateNewReviewAction(action)
  • setCreateNewReservationAction(action)
  • setGetReservationsByDateAction(action)
  • setViewReviewAction(action)
  • setShowEditReviewAction(action)
  • setUpdateReviewAction(action)
  • setCancelReservationAction(action)
  • setDeleteReviewAction(action)

このモジュールによって提供される機能は次のとおりです:

  • addRestaurantstoMap(restaurants): この機能は、入力レストランごとにLeafletマップにマークを追加します。各マークには、レストランに関する関連情報と、ユーザがレストランで実行できるアクションが表示されます。
  • setPopupTitle(title): モーダルウィンドウのタイトルを設定します。
  • setPopupContent(contentDiv): モーダルウィンドウのコンテンツを指定されたdivに置き換えます。
  • createReviewsDiv(reviews): 各入力レビューの情報を含むリストを含む要素を作成します。
  • createReservationsDiv(reservations): 各予約の情報を含むリストを含む要素を作成します。
  • createReviewsTable(reviews): 各レビューの基本インフォーメーション情報を含むテーブルを作成します。また、View review, Delete review and Update reviewオプションを生成します。
  • createOrganizationReviewsTable(reviews): createReviewsTableと似ていますが、Delete reviewUpdate reviewオプションは作成されません。 また、レビューは組織によってフィルタリングされます。
  • createReservationsTable(reservations): 各入力予約の情報を含むテーブルを作成します。 Cancel reservationオプションも生成されます。
  • createReviewForm(restaurantName, review):指定されたレストランのレビューを作成するフォームを生成します。 レビューがパスされると、フォームはその値で初期化されるように準備され、フォームアクションはレビューの作成ではなくレビューを更新するように設定されます。
  • initializeReviewForm(review): 以前にcreateReviewFormによって作成されたレビューフォームを初期化します。
  • createViewReviewDiv(review): レビューに関するすべての情報を含むdivを作成します。
  • openPopUpWindow(): モーダルウィンドウを開きます。
  • closePopUpWindow(): モーダルウィンドウを閉じます。

clientLogic.js

このモジュールには、クライアントアプリケーションの動作が含まれます。 これは、ユーザ情報を取得するために’connectionsAPIモジュール、サーバーAPIに対して要求を実行するrestaurantsAPIモジュール、およびUIをレンダリングするdrawModuleを使用します。 このモジュールは、依存関係をdrawModuleにも設定します。 これにより、UIから実行するアクションをdrawModule`が知ることができます。 このモジュールには以下のメソッドが含まれています:

  • showAllRestaurants(): すべてのレストランを検索してLeafletの地図に表示するリクエストを実行します。
  • showOrganizationRestaurants(organization): 組織のすべてのレストランを検索し、Leafletの地図に表示する要求を実行します。
  • showReservationsByOrganization(organization): 組織のすべてのレストラン予約を取得する要求を実行し、リストを使用してそれらを表示します。
  • showRestaurantReviews(name): 指定されたレストランのすべてのレビューを取得し、モーダルウィンドウを使用して表示します。
  • showRestaurantReservations(name): 指定されたレストランのすべての予約を取得し、モーダルウィンドウを使用して表示します。
  • showReviewsByUser(username): 特定のユーザ用に作成されたすべてのレビューを取得し、それらを表示するテーブルを作成します。
  • showReviewsByOrganization(organization): 組織レストランのすべてのレビューを取得し、表示します。
  • createNewReview(name, rating, description): 指定されたレストランの新しいレビューを作成します。
  • createNewReservation(name, partySize, time): 指定されたレストランの新しいレビューを作成します。
  • updateReview(reviewId, rating, description): 指定されたレビューを更新します。
  • deleteReview(reviewId): 指定されたレビューを削除します。
  • showReservationsByUser(username): 指定されたユーザのすべての予約を取得し、テーブルを使用して表示します。
  • getMyReviews(): ログインしたユーザ情報を使用してshowReviewsByUserを呼び出します。
  • getMyReservations(): ログに記録されたユーザ情報を使用してshowReservationsByUserを呼び出します。
  • setUpDrawModule(): UIから実行されるすべてのアクションを初期化します。

フロントエンドアプリの仕組み

フロントエンド・アプリケーションのすべてのページには、connectionsAPIモジュールが含まれています。 このモジュールは、サーバーAPIエンドポイントtourguide/client/userに対して要求を実行するユーザ情報を取得しようとするinit関数を実行します。 要求が成功すると、ユーザ情報がさらに操作のために保存され、トップメニューが作成されます。 ユーザがログインしていない場合、要求は失敗し、以前に保管されたユーザ情報はすべて削除され、ログイン・メニューが生成されます。

ユーザがログインしている最中にトップメニューを生成するために、connectionsAPIはユーザロールとユーザ組織をチェックします。 たとえば、My organizationsニューの項目は、ユーザが少なくとも1つの組織に所属している場合にのみ生成されます。

...
if (organizations.length > 0) {
        var myOrganizationsLi = document.createElement('LI');
        myOrganizationsLi.className = 'dropdown';
...

メインビューのinitファイルはVitoria(スペインの都市・ビトリア=ガステイス)のビューを中心としたLeafletの地図を設定し、ズームレベルを8に設定してOpen Street Mapレイヤーを追加します:

  map = L.map('map').setView([42.90816007196054, -2.52960205078125], 8);

  // set tile layer
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution:
      '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);

地図を作成後、initファイルはdrawModuleを初期化し、すべてのレストランを表示します:

  clientLogic.setUpDrawModule();
  clientLogic.showAllRestaurants();

clientLogic.showAllRestaurants関数はrestaurantsAPI.getAllRestaurantsを使用してレストランを取得し、drawModule.addRestaurantstoMapを使用してレストランを地図に追加します。

drawModule.addRestaurantstoMapはレストランを繰り返し処理し、それぞれにポップアップを含むマークを作成します。 マークには、住所、電話番号、平均レーティングなどのレストランに関する基本情報が含まれています。マークにはレストランで利用できるアクションも表示されます。これらのアクションは、clientLogic.setUpDrawModule()によって挿入されたメソッドを使用してバインドされます。 たとえば、レビューの表示オプションをクリックすると、clientLogic.showRestaurantReviewsが呼び出されます。 次の図は、上から順に実行されるプロセスを説明しています。

PROCESS INVOLVED IN DRAW RESTAURANTS

My reviewsセクションには、ログインしたユーザが書き込んだレビューが表示されます。 ユーザが connectionsAPI.loginNeeded関数にログインしていることを確認するために、コールバックメソッドとしてclientLogic.getMyReviews()が呼び出されます。つまり、ユーザがclientLogic.getMyReviews()にログインしている場合は実行され、ユーザがログインしていない場合はログインを要求するエラーメッセージが表示されます。

// only gets reviews if the user is logged
  connectionsAPI.loginNeeded(function() {
    clientLogic.getMyReviews();
  });

clientLogic.getMyReviews()関数はconnectionsAPI.getUser()を使用してユーザ名を取得し、clientLogic.showReviewsByUserを使用してユーザのレビューを表示します。restaurantsAPI.getAllRestaurantsと同様に、この関数はrestaurantsAPIgetUserReviewsを使用してユーザレビューを取得し、drawModule.createReviewsTableを使用してレビュー・テーブルを作成します。

残りのセクションは、main viewMy reviewsセクションと同じ構造に従います。