package org.sigmah.client.ui.presenter.calendar; /* * #%L * Sigmah * %% * Copyright (C) 2010 - 2016 URD * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.sigmah.client.dispatch.CommandResultHandler; import org.sigmah.client.dispatch.DispatchQueue; import org.sigmah.client.event.UpdateEvent; import org.sigmah.client.event.handler.UpdateHandler; import org.sigmah.client.i18n.I18N; import org.sigmah.client.inject.Injector; import org.sigmah.client.page.Page; import org.sigmah.client.page.RequestParameter; import org.sigmah.client.ui.notif.N10N; import org.sigmah.client.ui.presenter.base.AbstractPresenter; import org.sigmah.client.ui.view.base.ViewInterface; import org.sigmah.client.ui.view.calendar.CalendarView; import org.sigmah.client.ui.widget.CalendarWidget; import org.sigmah.client.ui.widget.button.Button; import org.sigmah.client.util.ClientUtils; import org.sigmah.shared.command.Delete; import org.sigmah.shared.command.GetCalendar; import org.sigmah.shared.command.result.Calendar; import org.sigmah.shared.command.result.VoidResult; import org.sigmah.shared.dto.calendar.CalendarType; import org.sigmah.shared.dto.calendar.CalendarWrapper; import org.sigmah.shared.dto.calendar.Event; import org.sigmah.shared.dto.calendar.PersonalEventDTO; import org.sigmah.shared.dto.referential.GlobalPermissionEnum; import org.sigmah.shared.util.ProfileUtils; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.selection.AbstractStoreSelectionModel; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.ImplementedBy; import com.google.inject.Inject; import org.sigmah.client.ui.presenter.reminder.ReminderType; import org.sigmah.client.util.profiler.Profiler; import org.sigmah.client.util.profiler.Scenario; import org.sigmah.shared.dto.calendar.CalendarIdentifier; import org.sigmah.shared.dto.calendar.PersonalCalendarIdentifier; import org.sigmah.shared.util.ProjectUtils; /** * Calendar widget presenter. * * @author Denis Colliot (dcolliot@ideia.fr) */ public class CalendarPresenter extends AbstractPresenter<CalendarPresenter.View> { /** * Description of the view managed by this presenter. */ @ImplementedBy(CalendarView.class) public static interface View extends ViewInterface { void initializeCalendarWidget(final CalendarWidget calendarWidget); void setAddEventButtonEnabled(final boolean addEventButtonEnabled); AbstractStoreSelectionModel<CalendarWrapper> getCalendarsSelectionModel(); ListStore<CalendarWrapper> getCalendarsStore(); Button getAddEventButton(); Button getTodayButton(); Button getWeekButton(); Button getMonthButton(); Button getPreviousButton(); Button getNextButton(); Button getReminderAddButton(); Button getMonitoredPointsAddButton(); } /** * The calendar widget. */ private CalendarWidget calendar; private Integer projectId; /** * Presenters's initialization. * * @param view * Presenter's view interface. * @param injector * Injected client injector. */ @Inject protected CalendarPresenter(final View view, final Injector injector) { super(view, injector); } /** * {@inheritDoc} */ @Override public void onBind() { // -- // Initialize calendar widget. // -- calendar = new CalendarWidget(CalendarWidget.COLUMN_HEADERS, true, auth()); calendar.today(); // Reset the current date. calendar.setDisplayMode(CalendarWidget.DisplayMode.MONTH); view.initializeCalendarWidget(calendar); view.setAddEventButtonEnabled(false); // -- // Configuring calendar delegate. // -- calendar.setDelegate(new CalendarWidget.Delegate() { @Override public void edit(final Event event, final CalendarWidget calendarWidget) { eventBus.navigateRequest(Page.CALENDAR_EVENT.request().addData(RequestParameter.DTO, event).addData(RequestParameter.CONTENT, getCalendars())); } @Override public void delete(final Event event, final CalendarWidget calendarWidget) { final CalendarIdentifier calendarIdentifier = event.getParent().getIdentifier(); final Integer parentId = calendarIdentifier instanceof PersonalCalendarIdentifier ? ((PersonalCalendarIdentifier)calendarIdentifier).getId() : null; dispatch.execute(new Delete(PersonalEventDTO.ENTITY_NAME, event.getIdentifier(), parentId), new CommandResultHandler<VoidResult>() { @Override public void onCommandFailure(final Throwable caught) { N10N.error(I18N.CONSTANTS.error(), I18N.CONSTANTS.calendarDeleteEventError()); } @Override public void onCommandSuccess(final VoidResult result) { final List<Event> oldEventList = event.getParent().getEvents().get(event.getKey()); oldEventList.remove(event); calendar.refresh(); } }); } }); // -- // Calendars selection change event. // -- view.getCalendarsSelectionModel().addSelectionChangedListener(new SelectionChangedListener<CalendarWrapper>() { @Override public void selectionChanged(SelectionChangedEvent<CalendarWrapper> se) { final List<CalendarWrapper> wrappers = se.getSelection(); final ArrayList<Calendar> calendars = new ArrayList<Calendar>(); for (final CalendarWrapper wrapper : wrappers) { calendars.add(wrapper.getCalendar()); } calendar.setCalendars(calendars); } }); // -- // Add event button. // -- view.getAddEventButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { if (view.getCalendarsStore().getCount() == 0) { N10N.warn(I18N.CONSTANTS.calendar_addEvent_noCalendar_ko()); return; } eventBus.navigateRequest(Page.CALENDAR_EVENT.request().addData(RequestParameter.CONTENT, getCalendars())); } }); // -- // Today button. // -- view.getTodayButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { calendar.today(); } }); // -- // Week button. // -- view.getWeekButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { calendar.setDisplayMode(CalendarWidget.DisplayMode.WEEK); } }); // -- // Month button. // -- view.getMonthButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { calendar.setDisplayMode(CalendarWidget.DisplayMode.MONTH); } }); // -- // Previous button. // -- view.getPreviousButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { calendar.previous(); } }); // -- // Next button. // -- view.getNextButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent ce) { calendar.next(); } }); // -- // Reminders / Monitored Points add buttons handlers. // -- view.getReminderAddButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent event) { eventBus.navigateRequest(Page.REMINDER_EDIT.requestWith(RequestParameter.TYPE, ReminderType.REMINDER).addParameter(RequestParameter.ID, projectId)); } }); view.getMonitoredPointsAddButton().addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(final ButtonEvent event) { eventBus.navigateRequest(Page.REMINDER_EDIT.requestWith(RequestParameter.TYPE, ReminderType.MONITORED_POINT).addParameter(RequestParameter.ID, projectId)); } }); // -- // Update event handler. // -- registerHandler(eventBus.addHandler(UpdateEvent.getType(), new UpdateHandler() { @Override public void onUpdate(final UpdateEvent event) { if (event.concern(UpdateEvent.CALENDAR_EVENT_UPDATE)) { calendar.refresh(); } if (event.concern(UpdateEvent.REMINDER_UPDATED)) { // TODO appel reloadEventsOfReminderType((ReminderType) event.getParam(0)); calendar.refresh(); } } })); } /** * Reloads the calendars data (if necessary). * * @param calendars * The calendar types with their corresponding identifier. */ public void reload(final Map<CalendarType, Integer> calendars, boolean editable) { Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, "Before refresh."); calendar.refresh(); Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, "calendar.refresh ended."); this.projectId = calendars.get(CalendarType.Activity); view.setAddEventButtonEnabled(editable); Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, "Before refresh."); reloadEvents(calendars); } /** * {@inheritDoc}<br> * Updates the calendar view. */ @Override public void onViewRevealed() { calendar.refresh(); } /** * Returns the {@link CalendarWrapper} list from the view store. * * @return The collection. */ private List<CalendarWrapper> getCalendars() { final List<CalendarWrapper> calendars = new ArrayList<CalendarWrapper>(); final ListStore<CalendarWrapper> store = view.getCalendarsStore(); for (int i = 0; i < store.getCount(); i++) { calendars.add(store.getAt(i)); } return calendars; } /** * Reloads the calendar events using a {@link GetCalendar} command. * * @param calendars * The calendar types with their corresponding identifier. */ private void reloadEvents(final Map<CalendarType, Integer> calendars) { view.getCalendarsStore().removeAll(); if (ClientUtils.isEmpty(calendars)) { calendar.refresh(); Profiler.INSTANCE.endScenario(Scenario.AGENDA); return; } final DispatchQueue queue = new DispatchQueue(dispatch, true) { @Override protected void onComplete() { calendar.refresh(); Profiler.INSTANCE.endScenario(Scenario.AGENDA); } }; for (final Entry<CalendarType, Integer> calendarEntry : calendars.entrySet()) { if (calendarEntry == null) { continue; } final CalendarType calendarType = calendarEntry.getKey(); final Integer calendarId = calendarEntry.getValue(); queue.add(new GetCalendar(calendarType, CalendarType.getIdentifier(calendarType, calendarId)), new CommandResultHandler<Calendar>() { @Override public void onCommandSuccess(final Calendar result) { Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, calendarType + " ended."); if(result != null) { // Defines the color index of the calendar. result.setStyle(calendarType.getColorCode()); result.setType(calendarType); view.getCalendarsStore().add(new CalendarWrapper(result)); view.getCalendarsSelectionModel().select(view.getCalendarsStore().getCount() - 1, true); } } @Override protected void onCommandFailure(Throwable caught) { Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, calendarType + " ended with error."); super.onCommandFailure(caught); } }); } Profiler.INSTANCE.markCheckpoint(Scenario.AGENDA, "Before queue started."); queue.start(); } /** * Reload a given type of reminder into the calendar. * * @param reminderType Type of reminder to refresh. */ private void reloadEventsOfReminderType(final ReminderType reminderType) { final CalendarType calendarType = reminderType == ReminderType.REMINDER ? CalendarType.Reminder : CalendarType.MonitoredPoint; final List<Calendar> calendars = calendar.getCalendars(); for (int index = 0; index < calendars.size(); index++) { final Calendar currentCalendar = calendars.get(index); if (currentCalendar.getType() == calendarType) { final GetCalendar getCalendar = new GetCalendar(calendarType, currentCalendar.getIdentifier()); final int location = index; dispatch.execute(getCalendar, new CommandResultHandler<Calendar>() { @Override protected void onCommandSuccess(Calendar result) { if(result != null) { result.setStyle(calendarType.getColorCode()); result.setType(calendarType); calendars.set(location, result); calendar.refresh(); } } }); return; } } } }