From 785c4f6c7c9e4450adbb16985b0d1415fde7beb0 Mon Sep 17 00:00:00 2001 From: ssftvyn Date: Tue, 18 Jun 2024 11:08:21 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 10 ++++++---- src/model/destinations-model.js | 5 +++-- src/model/offers-model.js | 3 ++- src/model/point-model.js | 4 +++- src/presenter/trip-presenter.js | 18 +++++++++++++++++- src/view/edit-point-view.js | 8 +++++--- src/view/new-point-button-view.js | 9 +++++++++ src/view/no-point-view.js | 15 ++++++++++++++- 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/main.js b/src/main.js index 8f05315..2827465 100644 --- a/src/main.js +++ b/src/main.js @@ -44,20 +44,22 @@ const newPointButtonComponent = new NewPointButtonView({ }); function newPointCloseHandler() { - newPointButtonComponent.element.disabled = false; + newPointButtonComponent.enableButton(); } function NewPointButtonClickHandler() { tripPresenter.createPoint(); - newPointButtonComponent.element.disabled = true; + newPointButtonComponent.disableButton(); } +render(newPointButtonComponent, headerContainer); + filterPresenter.init(); tripPresenter.init(); offersModel.init().finally(() => { destinationsModel.init().finally(() => { - pointsModel.init().finally(() => { - render(newPointButtonComponent, headerContainer); + pointsModel.init().then(() => { + newPointButtonComponent.enableButton(); }); }); }); diff --git a/src/model/destinations-model.js b/src/model/destinations-model.js index 559c05a..0197119 100644 --- a/src/model/destinations-model.js +++ b/src/model/destinations-model.js @@ -9,16 +9,17 @@ export default class DestinationModel extends Observable{ this.#destinationsApiService = destinationsApiService; } - get destinations(){ + get destinations() { return this.#destinations; } async init(){ try{ this.#destinations = await this.#destinationsApiService.destinations; + this._notify(UpdateType.INIT); } catch (error){ this.#destinations = null; + this._notify(UpdateType.INIT, {error}); } - this._notify(UpdateType.INIT); } } diff --git a/src/model/offers-model.js b/src/model/offers-model.js index 334e4b9..828a31a 100644 --- a/src/model/offers-model.js +++ b/src/model/offers-model.js @@ -16,9 +16,10 @@ export default class OfferModel extends Observable{ async init(){ try{ this.#offers = await this.#offersApiService.offers; + this._notify(UpdateType.INIT); } catch (error){ this.#offers = null; + this._notify(UpdateType.INIT, {error}); } - this._notify(UpdateType.INIT); } } diff --git a/src/model/point-model.js b/src/model/point-model.js index fc80a52..d082d3a 100644 --- a/src/model/point-model.js +++ b/src/model/point-model.js @@ -17,10 +17,12 @@ export default class PointModel extends Observable{ try{ const points = await this.#pointsApiService.points; this.#points = points.map(this.#adaptToClient); + this._notify(UpdateType.INIT); } catch (error){ this.#points = []; + this._notify(UpdateType.INIT, {error}); + throw new Error('Points fetch error'); } - this._notify(UpdateType.INIT); } async updatePoint(updateType, update) { diff --git a/src/presenter/trip-presenter.js b/src/presenter/trip-presenter.js index 45000a8..8217702 100644 --- a/src/presenter/trip-presenter.js +++ b/src/presenter/trip-presenter.js @@ -28,6 +28,7 @@ class TripPresenter { #filterType = FilterType.EVERYTHING; #headerContainer = document.querySelector('.trip-main'); #isLoading = true; + #isFetchError = false; #uiBlocker = new UiBlocker({ lowerLimit: TimeLimit.LOWER_LIMIT, upperLimit: TimeLimit.UPPER_LIMIT @@ -129,6 +130,9 @@ class TripPresenter { this.#renderBoard(); break; case UpdateType.INIT: + if (data && data.error) { + this.#isFetchError = true; + } this.#isLoading = false; remove(this.#loadingComponent); this.#renderBoard(); @@ -175,7 +179,15 @@ class TripPresenter { #renderNoPoints() { this.#noPoint = new NoPointView({ - filterType: this.#filterType + filterType: this.#filterType, + }); + render(this.#noPoint, this.#container, RenderPosition.AFTERBEGIN); + } + + #renderFetchError() { + this.#noPoint = new NoPointView({ + filterType: this.#filterType, + isFetchError: this.#isFetchError }); render(this.#noPoint, this.#container, RenderPosition.AFTERBEGIN); } @@ -193,6 +205,10 @@ class TripPresenter { #renderBoard() { const points = this.points; const pointsCount = points.length; + if (this.#isFetchError) { + this.#renderFetchError(); + return; + } if (pointsCount === 0 && !this.#isLoading) { this.#renderNoPoints(); return; diff --git a/src/view/edit-point-view.js b/src/view/edit-point-view.js index e537868..0abf4ed 100644 --- a/src/view/edit-point-view.js +++ b/src/view/edit-point-view.js @@ -234,9 +234,11 @@ export default class EditingPointView extends AbstractStatefulView{ #changeDestinationHandler = (event) => { event.preventDefault(); const destination = this.#destinations.find((dest) => dest.name === event.target.value); - this.updateElement({ - destination: destination.id, - }); + if(destination) { + this.updateElement({ + destination: destination.id, + }); + } }; #changeOfferHandler = (event) => { diff --git a/src/view/new-point-button-view.js b/src/view/new-point-button-view.js index 76ff26c..eebfe98 100644 --- a/src/view/new-point-button-view.js +++ b/src/view/new-point-button-view.js @@ -8,12 +8,21 @@ export default class NewPointButtonView extends AbstractView { super(); this.#handleClick = onClick; this.element.addEventListener('click', this.#clickHandler); + this.disableButton(); } get template() { return createNewPointButton(); } + disableButton() { + this.element.disabled = true; + } + + enableButton() { + this.element.disabled = false; + } + #clickHandler = (event) => { event.preventDefault(); this.#handleClick(); diff --git a/src/view/no-point-view.js b/src/view/no-point-view.js index 6e12c69..da62045 100644 --- a/src/view/no-point-view.js +++ b/src/view/no-point-view.js @@ -7,14 +7,27 @@ export const createNoPoint = (filterType) => { `

${noPointTextValue}

` ); }; + +const CreateFetchError = () => + `

+ Failed to load latest route information +

+ `; + export default class NoPointView extends AbstractView { #filterType = null; - constructor({filterType}) { + #isFetchError = null; + + constructor({filterType, isFetchError = false}) { super(); this.#filterType = filterType; + this.#isFetchError = isFetchError; } get template(){ + if (this.#isFetchError) { + return CreateFetchError(); + } return createNoPoint(this.#filterType); } }