Skip to content

Commit

Permalink
Merge pull request #11 from PavelUd/module7-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
keksobot authored May 26, 2024
2 parents ce87c9d + 91401a5 commit 1c11a58
Show file tree
Hide file tree
Showing 20 changed files with 534 additions and 91 deletions.
2 changes: 0 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ <h2 class="visually-hidden">Filter events</h2>
<!-- Фильтры -->
</div>
</div>

<button class="trip-main__event-add-btn btn btn--big btn--yellow" type="button">New event</button>
</div>
</div>
</header>
Expand Down
17 changes: 17 additions & 0 deletions src/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ export const TYPES = [
'restaurant',
];

export const UpdateType = {
PATCH: 'PATCH',
MINOR: 'MINOR',
MAJOR: 'MAJOR'
};

export const EditType = {
EDITING: 'EDITING',
CREATING: 'CREATING',
};

export const UserAction = {
UPDATE_POINT: 'UPDATE_POINT',
ADD_POINT: 'ADD_POINT',
DELETE_POINT: 'DELETE_POINT',
};

export const FILTER_TYPES = {
EVERYTHING: 'everything',
FUTURE: 'future',
Expand Down
25 changes: 20 additions & 5 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import FilterView from './view/filter-view.js';
import TripInfoView from './view/trip-info-view.js';
import {render, RenderPosition} from '../src/framework/render.js';
import BoardPresenter from './presenter/board-presenter.js';
import DestinationsModel from './model/destinations-model.js';
import OffersModel from './model/offers-model.js';
import PointsModel from './model/point-model.js';
import MockService from './service/mock-service.js';
import { generateFilter } from './mock/filter.js';
import FilterModel from './model/filter-model.js';
import FilterPresenter from './presenter/filter-presenter.js';
import NewPointButtonPresenter from './presenter/new-point-button-presenter.js';


const siteMainContainer = document.querySelector('.trip-main');
Expand All @@ -17,18 +18,32 @@ const service = new MockService();
const destinationsModel = new DestinationsModel(service);
const offersModel = new OffersModel(service);
const pointsModel = new PointsModel(service);
const filterModel = new FilterModel();

const newPointButtonPresenter = new NewPointButtonPresenter({
container: tripEventsContainer
});
const boardPresenter = new BoardPresenter({
container: tripEventsContainer,
destinationsModel,
offersModel,
pointsModel
pointsModel,
filterModel,
newPointButtonPresenter
});

const filters = generateFilter(pointsModel.points);
const filterPresenter = new FilterPresenter({
container: filterContainer,
pointsModel,
filterModel,
});


render(new TripInfoView(), siteMainContainer, RenderPosition.AFTERBEGIN);
render(new FilterView(filters), filterContainer);

newPointButtonPresenter.init({
onButtonClick:boardPresenter.handleNewPointClick
});

filterPresenter.init();
boardPresenter.init();
2 changes: 2 additions & 0 deletions src/mock/point.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const getRandomPoint = (type, destinationId, offerIds) => ({
offers: offerIds,
type
});


14 changes: 14 additions & 0 deletions src/model/filter-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Observable from '../framework/observable.js';
import {FILTER_TYPES} from '../const.js';

export default class FilterModel extends Observable {
#filter = FILTER_TYPES.EVERYTHING;
get() {
return this.#filter;
}

set(updteType, update){
this.#filter = update;
this._notify(updteType, update);
}
}
37 changes: 33 additions & 4 deletions src/model/point-model.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
export default class PointsModel {
import Observable from '../framework/observable';
import { updateItem } from '../mock/util.js';

export default class PointsModel extends Observable {
#points;
#service;

constructor(service) {
this.service = service;
this.points = this.service.getPoints();
super();
this.#service = service;
this.#points = this.#service.getPoints();
}

getAll() {
return this.points;
return this.#points;
}

getById(id) {
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);
}

update(type, point) {
const updatedPoint = this.#service.updatePoint(point);
this.#points = updateItem(this.#points, updatedPoint);
this._notify(type, updatedPoint);
}

delete(type, deletedPoint) {
this.#service.deletePoint(deletedPoint);
this.#points = this.#points.filter((point) => point.id !== deletedPoint.id);
this._notify(type);
}
}
142 changes: 116 additions & 26 deletions src/presenter/board-presenter.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,125 @@
import EventListView from '../view/event-list-view';
import EmptyView from '../view/empty-view';
import PointPresenter from './point-presenter';
import NewPointPresenter from './new-point-presenter';
import SortPresenter from './sort-presenter';
import {render} from '../framework/render';
import { updateItem } from '../mock/util';
import { sort } from '../utils';
import {remove, render} from '../framework/render';
import { filter, sort } from '../utils';
import {FILTER_TYPES, POINT_SORTS, UpdateType, UserAction} from '../const.js';

export default class BoardPresenter {
#sortPresenter = null;
#eventListComponent = new EventListView();
#emptyListElement = null;
#eventListElement = new EventListView();
#pointPresenters = new Map();
#destinationsModel;
#offersModel;
#points = [];
#filterModel;
#pointsModel;
#newPointButtonPresenter;
#currentSortType = POINT_SORTS.DAY;
#isCreating = false;
#container;
#newPointPresenter;

constructor({container, destinationsModel, offersModel, pointsModel}) {
this.container = container;
constructor({container, destinationsModel, offersModel, pointsModel, filterModel, newPointButtonPresenter}) {
this.#container = container;
this.#destinationsModel = destinationsModel;
this.#offersModel = offersModel;
this.pointsModel = pointsModel;
this.#points = sort([...pointsModel.getAll()]);
this.#pointsModel = pointsModel;
this.#filterModel = filterModel;
this.#newPointButtonPresenter = newPointButtonPresenter;

this.#newPointPresenter = new NewPointPresenter({
container: this.#eventListElement.element,
destinationsModel: this.#destinationsModel,
offersModel: this.#offersModel,
onDataChange: this.#onPointChangeHandler,
onDestroy: this.#handleNewPointDestroy
});

this.#pointsModel.addObserver(this.#modelEventHandler);
this.#filterModel.addObserver(this.#modelEventHandler);
}

get points() {
const filterType = this.#filterModel.get();
const filteredPoints = filter[filterType](this.#pointsModel.getAll());

return sort(filteredPoints, this.#currentSortType);
}

init(){
this.#renderBoard();
}

#renderBoard = () =>{
if (!this.points.length && !this.#isCreating) {
this.#renderEmptyList();
return;
}

this.#renderSort();
render(this.#eventListComponent, this.container);
render(this.#eventListElement, this.#container);
this.#renderPointList();
if (this.#points.length === 0){
render(new EmptyView(), this.container);
};

#renderEmptyList = () => {
this.#emptyListElement = new EmptyView({
filterType: this.#filterModel.get(),
});
render(this.#emptyListElement, this.#container);
};

#clearBoard = ({resetSortType = false} = {}) => {
this.#clearTaskList();
remove(this.#emptyListElement);
if (this.#sortPresenter) {
this.#sortPresenter.destroy();
this.#sortPresenter = null;
}
}

if (resetSortType) {
this.#currentSortType = POINT_SORTS.DAY;
}
};

#renderPointList = () =>{
this.#points.forEach((point) => this.#renderPoint(point));
this.points.forEach((point) => this.#renderPoint(point));
};

#renderSort = () =>{
this.#sortPresenter = new SortPresenter({
container: this.container,
container: this.#container,
handleSortChange: this.#handleSortChange,
});
this.#sortPresenter.init();
};

#renderPoint(point){
const pointPresenter = new PointPresenter({
container: this.#eventListComponent.element,
container: this.#eventListElement.element,
destinationsModel: this.#destinationsModel,
offersModel: this.#offersModel,
onPointsChange: this.#onPointChangeHandler,
handleModeChange: this.#handleModeChange
handleModeChange: this.#modelEventHandler
});
pointPresenter.init(point);
this.#pointPresenters.set(point.id, pointPresenter);
}


#onPointChangeHandler = (changedPoint) => {
this.#points = updateItem(this.#points, changedPoint);
this.#pointPresenters.get(changedPoint.id).init(changedPoint);
};

#handleModeChange = () => {
this.#pointPresenters.forEach((presenter) => presenter.resetView());
#onPointChangeHandler = (action, updateType, point) => {
switch (action) {
case UserAction.ADD_POINT:
this.#pointsModel.add(updateType, point);
break;
case UserAction.UPDATE_POINT:
this.#pointsModel.update(updateType, point);
break;
case UserAction.DELETE_POINT:
this.#pointsModel.delete(updateType, point);
break;
}
};

#clearTaskList = () => {
Expand All @@ -71,8 +128,41 @@ export default class BoardPresenter {
};

#handleSortChange = (sortType) => {
this.#points = sort(this.#points, sortType);
this.#currentSortType = sortType;
this.#clearTaskList();
this.#renderPointList();
};

#modelEventHandler = (updateType, data) => {
switch (updateType) {
case UpdateType.PATCH:
this.#pointPresenters.get(data.id).init(data);
break;
case UpdateType.MINOR:
this.#clearBoard();
this.#renderBoard();
break;
case UpdateType.MAJOR:
this.#clearBoard();
this.#renderBoard({resetSortType: true});
break;
}
};

handleNewPointClick = () => {
this.#isCreating = true;
this.#currentSortType = POINT_SORTS.DAY;
this.#filterModel.set(UpdateType.MAJOR, FILTER_TYPES.EVERYTHING);
this.#newPointButtonPresenter.disableButton();
this.#newPointPresenter.init();
};

#handleNewPointDestroy = ({isCanceled}) => {
this.#isCreating = false;
this.#newPointButtonPresenter.enableButton();
if (!this.points.length && isCanceled) {
this.#clearBoard();
this.#renderBoard();
}
};
}
Loading

0 comments on commit 1c11a58

Please sign in to comment.