Skip to content

Commit

Permalink
Merge pull request #13 from PavelUd/module8-task2
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored May 27, 2024
2 parents 55b33d3 + a949183 commit dbd147f
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 32 deletions.
8 changes: 8 additions & 0 deletions src/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export const Method = {
DELETE: 'DELETE',
};

export const ButtonLabel = {
CANCEL: 'Cancel',
DELETE: 'Delete',
SAVE: 'Save',
DELETE_IN_PROGRESS: 'Deleting...',
SAVE_IN_PROGRESS: 'Saving...'
};

export const UpdateType = {
INIT: 'INIT',
PATCH: 'PATCH',
Expand Down
28 changes: 20 additions & 8 deletions src/model/point-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,17 @@ export default class PointsModel extends Observable {
return this.#points.find((point) => point.id === id);
}

add(type, point) {
const newPoint = this.#service.addPoint(point);
this.#points.push(newPoint);
this._notify(type, newPoint);
async add(type, point) {
try {
const adaptedToServerPoint = adaptToServer(point);
const newPoint = await this.#service.addPoint(adaptedToServerPoint);
const adaptedToClientPoint = adaptToClient(newPoint);

this.#points.push(adaptedToClientPoint);
this._notify(type, adaptedToClientPoint);
} catch {
throw new Error('Can\'t add point');
}
}

async update(type, point) {
Expand All @@ -59,9 +66,14 @@ export default class PointsModel extends Observable {
}
}

delete(type, deletedPoint) {
this.#service.deletePoint(deletedPoint);
this.#points = this.#points.filter((point) => point.id !== deletedPoint.id);
this._notify(type);
async delete(type, deletedPoint) {
try {
const adaptedToServerPoint = adaptToServer(deletedPoint);
await this.#service.deletePoint(adaptedToServerPoint);
this.#points = this.#points.filter((point) => point.id !== deletedPoint.id);
this._notify(type);
} catch {
throw new Error('Can\'t delete point');
}
}
}
14 changes: 12 additions & 2 deletions src/presenter/board-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,12 @@ export default class BoardPresenter {
this.#uiBlocker.block();
switch (action) {
case UserAction.ADD_POINT:
this.#pointsModel.add(updateType, point);
this.#newPointPresenter.setSaving();
try {
await this.#pointsModel.add(updateType, point);
} catch {
this.#newPointPresenter.setAborting();
}
break;
case UserAction.UPDATE_POINT:
this.#pointPresenters.get(point.id).setSaving();
Expand All @@ -154,7 +159,12 @@ export default class BoardPresenter {
}
break;
case UserAction.DELETE_POINT:
this.#pointsModel.delete(updateType, point);
this.#pointPresenters.get(point.id).setDeleting();
try {
await this.#pointsModel.delete(updateType, point);
} catch {
this.#pointPresenters.get(point.id).setAborting();
}
break;
}

Expand Down
19 changes: 19 additions & 0 deletions src/presenter/new-point-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ export default class NewPointPresenter {
this.destroy({ isCanceled: false });
};

setSaving = () => {
this.#newPointElement.updateElement({
isDisabled: true,
isSaving: true,
});
};

setAborting = () => {
this.#newPointElement.shake(this.#resetFormState);
};

#resetFormState = () => {
this.#newPointElement.updateElement({
isDisabled: false,
isSaving: false,
isDeleting: false,
});
};

#onCloseForm = () => {
this.destroy();
};
Expand Down
7 changes: 7 additions & 0 deletions src/presenter/point-presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ export default class PointPresenter {
}
};

setDeleting = () => {
this.#editPointElement.updateElement({
isDisabled: true,
isDeleting: true
});
};

destroy = () => {
remove(this.#editPointElement);
remove(this.#pointElement);
Expand Down
21 changes: 19 additions & 2 deletions src/service/points-api-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ export default class PointsApiService extends ApiService
return ApiService.parseResponse(response);
}

addPoint = (point) => ({...point, id: crypto.randomUUID()});
deletePoint = () => {};
async addPoint(point) {
const response = await this._load({
url: 'points',
method: Method.POST,
body: JSON.stringify(point),
headers: new Headers({
'Content-Type': 'application/json',
}),
});

return ApiService.parseResponse(response);
}

async deletePoint(point) {
await this._load({
url: `points/${point.id}`,
method: Method.DELETE,
});
}
}
45 changes: 25 additions & 20 deletions src/view/point-edit-view.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { POINT_EMPTY, TYPES,EditType } from '../const.js';
import { POINT_EMPTY, TYPES,EditType, ButtonLabel } from '../const.js';
import AbstractStatefulView from '../framework/view/abstract-stateful-view.js';
import {formatToSlashDate} from '../utils/utils.js';
import CalendarView from './calendar-view.js';
import he from 'he';

const DEFAULT_TYPE = 'flight';

Expand Down Expand Up @@ -58,13 +57,18 @@ function createOfferSelector(pointOffers, offersArray){

return offersElements;
}
function createSaveButton() {
return '<button class="event__save-btn btn btn--blue" type="submit">Save</button>';
function createSaveButton({isDisabled, isSaving}) {
const saveLabel = isSaving ? ButtonLabel.SAVE_IN_PROGRESS : ButtonLabel.SAVE;
return `<button class="event__save-btn btn btn--blue" ${(isDisabled) ? 'disabled' : ''} type="submit">${saveLabel}</button>`;
}

function createDeleteButton({type}){
const label = type === EditType.CREATING ? 'Cancel' : 'Delete';
return `<button class="event__reset-btn" type="reset">${label}</button>`;
function createDeleteButton({isDisabled, type, isDeleting}){

let label = type === EditType.CREATING ? ButtonLabel.CANCEL : ButtonLabel.DELETE;
if(label === ButtonLabel.DELETE && isDeleting){
label = ButtonLabel.DELETE_IN_PROGRESS;
}
return `<button class="event__reset-btn" type="reset" ${(isDisabled) ? 'disabled' : ''}>${label}</button>`;
}

function createRollupButton(){
Expand All @@ -73,21 +77,22 @@ function createRollupButton(){
</button>`;
}

function createPointControls({type}){
return `${createSaveButton()}
${createDeleteButton({type})}
function createPointControls({type, isDeleting, isSaving, isDisabled}){
return `${createSaveButton(isSaving, isDisabled)}
${createDeleteButton({type, isDeleting})}
${type === EditType.CREATING ? '' : createRollupButton()}`;
}

function createPointEditElement({state, destinations, offers, pointType}) {
const { point } = state;
const { point, isDeleting, isDisabled, isSaving } = state;
const pointDestination = destinations.find((destination) => destination.id === point.destination);
const pointOffers = offers.find((subOffers) => subOffers.type === point.type)?.offers;
const name = pointType === EditType.CREATING ? '' : he.encode(pointDestination.name);
const name = pointDestination === undefined ? '' : pointDestination.name;

const {basePrice} = point;
const type = pointType === EditType.CREATING ? DEFAULT_TYPE : point.type;
const dateFrom = pointType === EditType.CREATING ? '' : formatToSlashDate(point.dateFrom);
const dateTo = pointType === EditType.CREATING ? '' : formatToSlashDate(point.dateTo);
const type = point.type === null ? DEFAULT_TYPE : point.type;
const dateFrom = point.dateFrom === null ? '' : formatToSlashDate(point.dateFrom);
const dateTo = point.dateTo === null ? '' : formatToSlashDate(point.dateTo);

return `<li class="trip-events__item">
<form class="event event--edit" action="#" method="post">
Expand All @@ -112,24 +117,24 @@ function createPointEditElement({state, destinations, offers, pointType}) {
${type}
</label>
<input class="event__input event__input--destination" id="event-destination-1" type="text" name="event-destination" value="${name}" list="destination-list-1">
<input class="event__input event__input--destination" id="event-destination-1" type="text" name="event-destination" ${(isDisabled) ? 'disabled' : ''} value="${name}" list="destination-list-1">
${createDestinationList(destinations)}
</div>
<div class="event__field-group event__field-group--time">
<label class="visually-hidden" for="event-start-time-1">From</label>
<input class="event__input event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${dateFrom}">
<input class="event__input ${(isDisabled) ? 'disabled' : ''} event__input--time" id="event-start-time-1" type="text" name="event-start-time" value="${dateFrom}">
&mdash;
<label class="visually-hidden" for="event-end-time-1">To</label>
<input class="event__input event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${dateTo}">
<input class="event__input ${(isDisabled) ? 'disabled' : ''} event__input--time" id="event-end-time-1" type="text" name="event-end-time" value="${dateTo}">
</div>
<div class="event__field-group event__field-group--price">
<label class="event__label" for="event-price-1">
<span class="visually-hidden">Price</span>
&euro;
</label>
<input class="event__input event__input--price" id="event-price-1" type="number" name="event-price" value="${basePrice}">
<input class="event__input ${(isDisabled) ? 'disabled' : ''} event__input--price" id="event-price-1" type="number" name="event-price" value="${basePrice}">
</div>
${createPointControls({type : pointType})}
${createPointControls({type : pointType, isDeleting: isDeleting, isDisabled: isDisabled, isSaving: isSaving})}
</header>
<section class="event__details">
${createOfferSelector(point?.offers, pointOffers)}
Expand Down

0 comments on commit dbd147f

Please sign in to comment.