[sigma-h] r408 committed - Separated the project presenter from the project dashboard presenter.

0 views
Skip to first unread message

sig...@googlecode.com

unread,
Oct 13, 2010, 5:21:20 AM10/13/10
to sigma...@googlegroups.com
Revision: 408
Author: raphael.calabro
Date: Wed Oct 13 02:20:44 2010
Log: Separated the project presenter from the project dashboard presenter.
http://code.google.com/p/sigma-h/source/detail?r=408

Added:
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/Presenter.java
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/ProjectDashboardPresenter.java

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/ProjectDashboardView.java

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/RequiredValueState.java

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/RequiredValueStateList.java
Modified:

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectModule.java

/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectPresenter.java
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectView.java

=======================================
--- /dev/null
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/Presenter.java
Wed Oct 13 02:20:44 2010
@@ -0,0 +1,16 @@
+/*
+ * All Sigmah code is released under the GNU General Public License v3
+ * See COPYRIGHT.txt and LICENSE.txt.
+ */
+
+package org.sigmah.client.page.project;
+
+import com.extjs.gxt.ui.client.widget.Component;
+
+/**
+ *
+ * @author rca
+ */
+public interface Presenter {
+ public Component getView();
+}
=======================================
--- /dev/null
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/ProjectDashboardPresenter.java
Wed Oct 13 02:20:44 2010
@@ -0,0 +1,730 @@
+/*
+ * All Sigmah code is released under the GNU General Public License v3
+ * See COPYRIGHT.txt and LICENSE.txt.
+ */
+package org.sigmah.client.page.project.dashboard;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.extjs.gxt.ui.client.event.ButtonEvent;
+import com.extjs.gxt.ui.client.event.ComponentEvent;
+import com.extjs.gxt.ui.client.event.Events;
+import com.extjs.gxt.ui.client.event.Listener;
+import com.extjs.gxt.ui.client.event.MessageBoxEvent;
+import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.Dialog;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.MessageBox;
+import com.extjs.gxt.ui.client.widget.TabItem;
+import com.extjs.gxt.ui.client.widget.TabPanel;
+import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.form.FieldSet;
+import com.extjs.gxt.ui.client.widget.form.FormPanel;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.extjs.gxt.ui.client.widget.layout.FormData;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Grid;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import org.sigmah.client.dispatch.Dispatcher;
+import org.sigmah.client.dispatch.monitor.MaskingAsyncMonitor;
+import org.sigmah.client.dispatch.remote.Authentication;
+import org.sigmah.client.i18n.I18N;
+import org.sigmah.client.page.project.Presenter;
+import org.sigmah.client.page.project.ProjectPresenter;
+import org.sigmah.shared.command.ChangePhase;
+import org.sigmah.shared.command.GetValue;
+import org.sigmah.shared.command.UpdateProject;
+import org.sigmah.shared.command.result.ProjectListResult;
+import org.sigmah.shared.command.result.ValueResult;
+import org.sigmah.shared.command.result.VoidResult;
+import org.sigmah.shared.dto.PhaseDTO;
+import org.sigmah.shared.dto.PhaseModelDTO;
+import org.sigmah.shared.dto.ProjectDTO;
+import org.sigmah.shared.dto.element.FlexibleElementDTO;
+import org.sigmah.shared.dto.element.handler.RequiredValueEvent;
+import org.sigmah.shared.dto.element.handler.RequiredValueHandler;
+import org.sigmah.shared.dto.element.handler.ValueEvent;
+import org.sigmah.shared.dto.element.handler.ValueHandler;
+import org.sigmah.shared.dto.layout.LayoutConstraintDTO;
+import org.sigmah.shared.dto.layout.LayoutGroupDTO;
+
+/**
+ *
+ * @author Raphaël Calabro (rcal...@ideia.fr)
+ */
+public class ProjectDashboardPresenter implements Presenter {
+
+ public static abstract class View extends LayoutContainer {
+
+ public abstract LayoutContainer getPanelProjectModel();
+
+ public abstract LayoutContainer getPanelSelectedPhase();
+
+ public abstract ContentPanel getPanelReminders();
+
+ public abstract ContentPanel getPanelWatchedPoints();
+
+ public abstract ContentPanel getPanelFinancialProjects();
+
+ public abstract ContentPanel getPanelLocalProjects();
+
+ public abstract TabPanel getTabPanelPhases();
+
+ public abstract
com.extjs.gxt.ui.client.widget.grid.Grid<FlexibleElementDTO>
getGridRequiredElements();
+
+ public abstract Button getButtonSavePhase();
+
+ public abstract Button getButtonActivatePhase();
+
+ public abstract Button getButtonPhaseGuide();
+
+ public abstract TabPanel getTabPanelProject();
+ }
+ /**
+ * The view managed by this presenter.
+ */
+ private View view;
+ private ProjectPresenter projectPresenter;
+ private Dispatcher dispatcher;
+ private final Authentication authentication;
+ /**
+ * List of values changes.
+ */
+ private ArrayList<ValueEvent> valueChanges = new
ArrayList<ValueEvent>();
+ /**
+ * Mapping between phases models ids and tabs items (to quickly get a
tab).
+ */
+ private final HashMap<Integer, TabItem> tabItemsMap;
+ /**
+ * A map to maintain the current active phase required elements states.
+ */
+ private final RequiredValueStateList activePhaseRequiredElements = new
RequiredValueStateList();
+ /**
+ * A map to maintain the current displayed phase required elements
states.
+ */
+ private final RequiredValueStateList currentPhaseRequiredElements =
new RequiredValueStateList();
+ /**
+ * The counter before the main panel is unmasked.
+ */
+ private int maskCount;
+
+ public ProjectDashboardPresenter(Dispatcher dispatcher, Authentication
authentication, ProjectPresenter projectPresenter) {
+ this.authentication = authentication;
+ this.dispatcher = dispatcher;
+ this.projectPresenter = projectPresenter;
+
+ this.tabItemsMap = new HashMap<Integer, TabItem>();
+ }
+
+ @Override
+ public View getView() {
+ if (view == null) {
+ view = new ProjectDashboardView(); // Inject this ?
+
+ // Hides unimplemented panels and actions.
+ view.getPanelFinancialProjects().setVisible(false);
+ view.getPanelLocalProjects().setVisible(false);
+ view.getPanelReminders().setVisible(false);
+ view.getPanelWatchedPoints().setVisible(false);
+ }
+
+ valueChanges.clear();
+ view.getButtonSavePhase().setEnabled(false);
+ loadProjectDashboard(projectPresenter.getCurrentProjectDTO());
+
+ return view;
+ }
+
+ /**
+ * Mask the main panel and set the mask counter.
+ *
+ * @param count
+ * The mask counter.
+ */
+ private void mask(int count) {
+ maskCount = count;
+ view.getTabPanelPhases().mask(I18N.CONSTANTS.loading());
+ }
+
+ /**
+ * Decrements the mask counter and unmask the main panel if the counter
+ * reaches <code>0</code>.
+ */
+ private void unmask() {
+ maskCount--;
+ if (maskCount == 0) {
+ view.getTabPanelPhases().unmask();
+ }
+ }
+
+ public void loadProjectDashboard(final ProjectDTO projectDTO) {
+ // Sets current project status (for the first display, the active
phase
+ // is rendered).
+ final PhaseDTO currentPhaseDTO = projectDTO.getCurrentPhaseDTO();
+
+ projectPresenter.setCurrentPhaseDTO(currentPhaseDTO);
+
+ // Clears the required elements maps .
+ activePhaseRequiredElements.clear();
+ currentPhaseRequiredElements.clear();
+
+ // Sorts phases to be displayed in the correct order.
+ Collections.sort(projectDTO.getPhasesDTO());
+
+ // --
+ // -- TABS CREATION
+ // --
+
+ // Removes old tabs configuration (from the previous displayed
project).
+ view.getTabPanelPhases().removeAll();
+ view.getTabPanelPhases().removeAllListeners();
+ tabItemsMap.clear();
+
+ // Creates tabs for each phase.
+ for (final PhaseDTO phaseDTO : projectDTO.getPhasesDTO()) {
+
+ // Creates the default tab.
+ final TabItem tabItem = new
TabItem(phaseDTO.getPhaseModelDTO().getName());
+ tabItem.setLayout(new FitLayout());
+ tabItem.setEnabled(false);
+ tabItem.setAutoHeight(true);
+
+ // Map the tab item with the phase id.
+ tabItemsMap.put(phaseDTO.getPhaseModelDTO().getId(), tabItem);
+
+ // Adds the tab to the view.
+ view.getTabPanelPhases().add(tabItem);
+
+ // If the phase is the active one.
+ if (isActivePhase(phaseDTO)) {
+ // Enables it, apply the correct style and selects it.
+ tabItem.setEnabled(true);
+ tabItem.getHeader().addStyleName("project-phase-active");
+ view.getTabPanelPhases().setSelection(tabItem);
+ }
+
+ // If the phase is ended.
+ if (isEndedPhase(phaseDTO)) {
+ // Enables it and apply the correct style.
+ tabItem.setEnabled(true);
+ tabItem.getHeader().addStyleName("project-phase-closed");
+ }
+ }
+
+ // Enables successors tabs of the current phase.
+ enableSuccessorsTabs();
+
+ // --
+ // -- TABS LISTENERS
+ // --
+
+ // Adds tabs listeners for selection changes (must be added after
tabs
+ // creation or event fired for each tab).
+ for (final PhaseDTO phaseDTO : projectDTO.getPhasesDTO()) {
+ final TabItem tabItem =
tabItemsMap.get(phaseDTO.getPhaseModelDTO().getId());
+ tabItem.addListener(Events.Select, new
Listener<ComponentEvent>() {
+
+ /**
+ * Id of the phase to display. <br/>
+ * Important: it's better to manipulate the id instead of
the
+ * phases instances to keep coherence after a project
update.
+ */
+ private int phaseDTOId = phaseDTO.getId();
+
+ private PhaseDTO retrievePhaseDTO() {
+ // Loads the phase of the selected tab (loaded from the
+ // current project instance).
+ for (final PhaseDTO p : projectDTO.getPhasesDTO()) {
+ if (p.getId() == phaseDTOId) {
+ return p;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void handleEvent(ComponentEvent tpe) {
+
+ final PhaseDTO toDisplayPhase = retrievePhaseDTO();
+
+ // If the current phase has been modified and it isn't
+ // ended.
+ if (view.getButtonSavePhase().isEnabled()
&& !isEndedPhase(currentPhaseDTO)) {
+
+ // Asks the client to save the unsaved elements
before
+ // switching phases.
+
MessageBox.confirm(I18N.CONSTANTS.projectPhaseChangeAlert(),
+
I18N.CONSTANTS.projectPhaseChangeAlertDetails(), new
Listener<MessageBoxEvent>() {
+
+ @Override
+ public void handleEvent(MessageBoxEvent ce) {
+
+ // If 'YES' is clicked, saves the
+ // modifications.
+ if
(Dialog.YES.equals(ce.getButtonClicked().getItemId())) {
+
view.getButtonSavePhase().fireEvent(Events.OnClick);
+ if (isActivePhase(currentPhaseDTO)) {
+
activePhaseRequiredElements.saveState();
+
+ }
+ } else if
(Dialog.NO.equals(ce.getButtonClicked().getItemId())) {
+ // If the last displayed phase was
+ // the active one, modifications are
+ // discarded then the required
+ // elements map is cleared (to
+ // prevent inconsistent successor
+ // activation).
+ if (isActivePhase(currentPhaseDTO)) {
+
activePhaseRequiredElements.clearState();
+ }
+ }
+
+ loadPhaseOnTab(toDisplayPhase);
+ }
+ });
+ } else {
+ loadPhaseOnTab(toDisplayPhase);
+ }
+ }
+ });
+ }
+
+ // --
+ // -- ACTIVE PHASE SELECTION
+ // --
+
+ // Manually fires the first tab selection (active phase).
+ // loadPhaseOnTab(currentPhaseDTO);
+ }
+
+ /**
+ * Loads a project phase into the selected tab panel.
+ *
+ * @param phaseDTO
+ * The phase to display.
+ */
+ private void loadPhaseOnTab(final PhaseDTO phaseDTO) {
+ // Masks the main panel.
+ int count = 0;
+ for (final LayoutGroupDTO groupDTO :
phaseDTO.getPhaseModelDTO().getLayoutDTO().getLayoutGroupsDTO()) {
+ count += groupDTO.getLayoutConstraintsDTO().size();
+ }
+ mask(count);
+
+ // Sets current project status.
+ projectPresenter.setCurrentPhaseDTO(phaseDTO);
+
+ // Clears the required elements map for the current displayed
phase.
+ currentPhaseRequiredElements.clear();
+ valueChanges.clear();
+
+ // --
+ // -- CLEARS PANELS
+ // --
+
+ // Clears all tabs.
+ for (final TabItem tab : view.getTabPanelPhases().getItems()) {
+ tab.removeAll();
+ }
+
+ // Clears panels.
+ view.getPanelSelectedPhase().removeAll();
+ view.getGridRequiredElements().getStore().removeAll();
+
view.getTabPanelPhases().getSelectedItem().add(view.getPanelProjectModel());
+
+ // --
+ // -- TOOLBAR
+ // --
+
+ refreshActionsToolbar();
+
+ // --
+ // -- PHASE LAYOUT
+ // --
+
+ final Grid layoutGrid = (Grid)
phaseDTO.getPhaseModelDTO().getWidget();
+ view.getPanelSelectedPhase().add(layoutGrid);
+
+ // For each layout group.
+ for (final LayoutGroupDTO groupDTO :
phaseDTO.getPhaseModelDTO().getLayoutDTO().getLayoutGroupsDTO()) {
+
+ // Creates the fieldset and positions it.
+ final FieldSet fieldSet = (FieldSet) groupDTO.getWidget();
+ final FormPanel formPanel = (FormPanel) fieldSet.getWidget(0);
+ layoutGrid.setWidget(groupDTO.getRow(), groupDTO.getColumn(),
fieldSet);
+
+ // For each constraint in the current layout group.
+ for (LayoutConstraintDTO constraintDTO :
groupDTO.getLayoutConstraintsDTO()) {
+
+ // Gets the element managed by this constraint.
+ final FlexibleElementDTO elementDTO =
constraintDTO.getFlexibleElementDTO();
+
+ // --
+ // -- ELEMENT VALUE
+ // --
+
+ // Remote call to ask for this element value.
+ final GetValue command = new
GetValue(projectPresenter.getCurrentProjectDTO().getId(),
elementDTO.getId(),
+ elementDTO.getEntityName());
+ dispatcher.execute(command, null, new
AsyncCallback<ValueResult>() {
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ Log.error("Error, element value not loaded.");
+ unmask();
+ }
+
+ @Override
+ public void onSuccess(ValueResult valueResult) {
+
+ if (Log.isDebugEnabled()) {
+ Log.debug("Element value(s) object : " +
valueResult);
+ }
+
+ // --
+ // -- ELEMENT COMPONENT
+ // --
+
+ // Configures the flexible element for the current
+ // application state before generating its
component.
+ elementDTO.setService(dispatcher);
+ elementDTO.setAuthentication(authentication);
+
elementDTO.setCurrentProjectDTO(projectPresenter.getCurrentProjectDTO());
+ elementDTO.assignValue(valueResult);
+
+ // Generates element component (with the value).
+ elementDTO.init();
+ final Component elementComponent =
elementDTO.getComponent(valueResult);
+ elementComponent.addStyleName("sigmah-element");
+
+ // Component width.
+ final FormData formData;
+ if (elementDTO.getPreferredWidth() == 0) {
+ formData = new FormData("100%");
+ } else {
+ formData = new
FormData(elementDTO.getPreferredWidth(), -1);
+ }
+
+ formPanel.add(elementComponent, formData);
+ formPanel.layout();
+
+ // --
+ // -- ELEMENT HANDLERS
+ // --
+
+ // Adds a value change handler to this element.
+ elementDTO.addValueHandler(new ValueHandlerImpl());
+
+ // If this element id a required one.
+ if (elementDTO.getValidates()) {
+
+ // Adds a specific handler.
+ elementDTO.addRequiredValueHandler(new
RequiredValueHandlerImpl(elementDTO));
+
+ // Adds the element to the 'required panel'.
+
view.getGridRequiredElements().getStore().add(elementDTO);
+
+ // Map the required element for the current
+ // displayed phase.
+
currentPhaseRequiredElements.putSaved(elementDTO.getId(),
elementDTO.isFilledIn());
+
+ // If the current displayed phase is the
active one,
+ // map the required element for the active
phase.
+ if
(isCurrentPhase(projectPresenter.getCurrentProjectDTO().getCurrentPhaseDTO()))
{
+
activePhaseRequiredElements.putSaved(elementDTO.getId(),
elementDTO.isFilledIn());
+ }
+ }
+
+ unmask();
+ }
+ });
+ }
+ }
+
+ // View layouts update.
+ view.getTabPanelPhases().addStyleName("x-border-panel"); //FIXME:
This should be done by Ext, not be the developer!
+ view.layout();
+ }
+
+ /**
+ * Internal class handling the value changes of the flexible elements.
+ */
+ private class ValueHandlerImpl implements ValueHandler {
+
+ @Override
+ public void onValueChange(ValueEvent event) {
+
+ // Stores the change to be saved later.
+ valueChanges.add(event);
+ // Enables the save action.
+ view.getButtonSavePhase().setEnabled(true);
+ }
+ }
+
+ /**
+ * Internal class handling the value changes of the required elements.
+ */
+ private class RequiredValueHandlerImpl implements RequiredValueHandler
{
+
+ private FlexibleElementDTO elementDTO;
+
+ public RequiredValueHandlerImpl(FlexibleElementDTO elementDTO) {
+ this.elementDTO = elementDTO;
+ }
+
+ @Override
+ public void onRequiredValueChange(RequiredValueEvent event) {
+
+ // Updates the element state for the new value.
+ elementDTO.setFilledIn(event.isValueOn());
+ view.getGridRequiredElements().getStore().update(elementDTO);
+
+ // Map the required element for the current displayed phase.
+ currentPhaseRequiredElements.putActual(elementDTO.getId(),
event.isValueOn());
+
+ // If the current displayed phase is the active one,
+ // map the required element for the active phase.
+ if
(isCurrentPhase(projectPresenter.getCurrentProjectDTO().getCurrentPhaseDTO()))
{
+ activePhaseRequiredElements.putActual(elementDTO.getId(),
event.isValueOn());
+ }
+ }
+ }
+
+ /**
+ * Refreshes the actions toolbar for the current displayed phase.
+ */
+ private void refreshActionsToolbar() {
+
+ // --
+ // -- ACTION: ACTIVE PHASE
+ // --
+
+ // Always enabled (the listener is in charge of this action
validation).
+
view.getButtonActivatePhase().setEnabled(activePhaseRequiredElements.isTrue());
+ view.getButtonActivatePhase().removeAllListeners();
+
+ // If the current displayed phase is the active one or it is
ended, hide
+ if
(isCurrentPhase(projectPresenter.getCurrentProjectDTO().getCurrentPhaseDTO())
+ || isEndedPhase(projectPresenter.getCurrentPhaseDTO())) {
+ view.getButtonActivatePhase().setVisible(false);
+ } // Else shows it for the current displayed phase successors.
+ else {
+ view.getButtonActivatePhase().setVisible(true);
+ view.getButtonActivatePhase().addListener(Events.Select, new
ActivatePhaseListener());
+ }
+
+ // --
+ // -- ACTION: SAVE MODIFICATIONS
+ // --
+
+ // Disabled until a field is modified.
+ view.getButtonSavePhase().setEnabled(false);
+ view.getButtonSavePhase().removeAllListeners();
+
+ // If the phase is ended, hide the save action.
+ if (projectPresenter.getCurrentPhaseDTO().isEnded()) {
+ view.getButtonSavePhase().setVisible(false);
+ } // Else shows it (for the active phase and its successors).
+ else {
+ view.getButtonSavePhase().setVisible(true);
+ view.getButtonSavePhase().addListener(Events.OnClick, new
SaveListener());
+ }
+
+ // --
+ // -- ACTION: PHASE GUIDE
+ // --
+
+ // For the moment, always visible and disabled.
+ // TODO Check guide availability to enable this action.
+ view.getButtonPhaseGuide().setVisible(true);
+ view.getButtonPhaseGuide().removeAllListeners();
+ view.getButtonPhaseGuide().setEnabled(false);
+ }
+
+ /**
+ * Returns if a phase is the current displayed phase.
+ *
+ * @param phaseDTO
+ * The phase to test.
+ * @return If the phase is currently displayed.
+ */
+ public boolean isCurrentPhase(PhaseDTO phaseDTO) {
+ final PhaseDTO currentPhaseDTO =
projectPresenter.getCurrentPhaseDTO();
+ return currentPhaseDTO != null && phaseDTO != null &&
currentPhaseDTO.getId() == phaseDTO.getId();
+ }
+
+ /**
+ * Returns if a phase is the active phase of the current project.
+ *
+ * @param phaseDTO
+ * The phase to test.
+ * @return If the phase is active.
+ */
+ public boolean isActivePhase(PhaseDTO phaseDTO) {
+ final ProjectDTO currentProjectDTO =
projectPresenter.getCurrentProjectDTO();
+
+ return currentProjectDTO != null &&
currentProjectDTO.getCurrentPhaseDTO() != null && phaseDTO != null
+ && currentProjectDTO.getCurrentPhaseDTO().getId() ==
phaseDTO.getId();
+ }
+
+ /**
+ * Returns if a phase is ended.
+ *
+ * @param phaseDTO
+ * The phase to test.
+ * @return If the phase is ended.
+ */
+ public boolean isEndedPhase(PhaseDTO phaseDTO) {
+ return phaseDTO != null && phaseDTO.isEnded();
+ }
+
+ /**
+ * Returns if the active phase of the current project is filled in.
+ *
+ * @return If the active phase of the current project is filled in.
+ */
+ public boolean isActivePhaseFilledIn() {
+
+ // Checks id the map contains only true booleans.
+ return activePhaseRequiredElements.isTrue();
+ //
return !activePhaseRequiredElements.containsValue(Boolean.FALSE);
+ }
+
+ /**
+ * Enables the successors tabs of the current displayed phase.
+ */
+ private void enableSuccessorsTabs() {
+
+ for (final PhaseModelDTO successor :
projectPresenter.getCurrentPhaseDTO().getPhaseModelDTO().getSuccessorsDTO())
{
+ final TabItem successorTabItem =
tabItemsMap.get(successor.getId());
+ if (successorTabItem != null) {
+ successorTabItem.setEnabled(true);
+ }
+ }
+ }
+
+ /**
+ * Internal class handling the phases activation.
+ */
+ private class ActivatePhaseListener implements Listener<ButtonEvent> {
+
+ @Override
+ public void handleEvent(ButtonEvent be) {
+
+ // If the active phase required elements aren't filled, shows
an
+ // alert.
+ if (!isActivePhaseFilledIn()) {
+
MessageBox.info(I18N.CONSTANTS.projectPhaseActivationError(),
+
I18N.CONSTANTS.projectPhaseActivationErrorDetails(), null);
+ } // Else, remote call to ask a new phase activation.
+ else {
+ final ProjectDTO currentProjectDTO =
projectPresenter.getCurrentProjectDTO();
+ final PhaseDTO currentPhaseDTO =
projectPresenter.getCurrentPhaseDTO();
+
+ // Activates the current displayed phase.
+ dispatcher.execute(new
ChangePhase(currentProjectDTO.getId(), currentPhaseDTO.getId()), null,
+ new AsyncCallback<ProjectListResult>() {
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ Log.error("Error, phase #" +
currentPhaseDTO.getId() + " not activated.");
+ }
+
+ @Override
+ public void onSuccess(ProjectListResult
result) {
+
+ if (Log.isDebugEnabled()) {
+ Log.debug("Phase activated : " +
currentPhaseDTO.getId());
+ }
+
+ // Sets current project status.
+ final ProjectDTO newProjectDTO =
result.getList().get(0);
+
projectPresenter.setCurrentProjectDTO(newProjectDTO);
+
projectPresenter.setCurrentPhaseDTO(newProjectDTO.getCurrentPhaseDTO());
+
+ // Map the required element for the active
phase
+ // from the current displayed phase map.
+ activePhaseRequiredElements.clear();
+
activePhaseRequiredElements.putAll(currentPhaseRequiredElements);
+
+ // --
+ // -- BANNER
+ // --
+
+ projectPresenter.refreshBanner();
+
+ // --
+ // -- TOOLBAR
+ // --
+
+ refreshActionsToolbar();
+
+ // --
+ // -- UPDATES TABS
+ // --
+
+ // Updates ended phases styles.
+ for (PhaseDTO phase :
currentProjectDTO.getPhasesDTO()) {
+ final TabItem successorTabItem =
tabItemsMap.get(phase.getPhaseModelDTO().getId());
+ if (phase.isEnded()) {
+
successorTabItem.getHeader().setStyleName("sigmah-closed-phase");
+ }
+ }
+
+ // Updates active phase styles.
+ for (TabItem item :
view.getTabPanelPhases().getItems()) {
+
item.getHeader().removeStyleName("sigmah-active-phase");
+ }
+
tabItemsMap.get(currentPhaseDTO.getPhaseModelDTO().getId()).getHeader().addStyleName("sigmah-active-phase");
+
+ // Enables successors tabs of the current
phase.
+ enableSuccessorsTabs();
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Internal class handling the modifications saving.
+ */
+ private class SaveListener implements Listener<ButtonEvent> {
+
+ @Override
+ public void handleEvent(ButtonEvent be) {
+ view.getButtonSavePhase().disable();
+ final UpdateProject updateProject = new
UpdateProject(projectPresenter.getCurrentProjectDTO().getId(),
valueChanges);
+
+ dispatcher.execute(updateProject,
+ new MaskingAsyncMonitor(view.getTabPanelPhases(),
I18N.CONSTANTS.loading()),
+ new AsyncCallback<VoidResult>() {
+
+ @Override
+ public void onFailure(Throwable caught) {
+ MessageBox.info(I18N.CONSTANTS.cancelled(),
I18N.CONSTANTS.error(), null);
+
+ currentPhaseRequiredElements.clearState();
+
+ if
(isActivePhase(projectPresenter.getCurrentPhaseDTO())) {
+ activePhaseRequiredElements.clearState();
+ }
+ }
+
+ @Override
+ public void onSuccess(VoidResult result) {
+ valueChanges.clear();
+ MessageBox.info(I18N.CONSTANTS.ok(),
I18N.CONSTANTS.saved(), null);
+
+ currentPhaseRequiredElements.saveState();
+
+ if
(isActivePhase(projectPresenter.getCurrentPhaseDTO())) {
+ activePhaseRequiredElements.saveState();
+ }
+ }
+ });
+ }
+ }
+}
=======================================
--- /dev/null
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/ProjectDashboardView.java
Wed Oct 13 02:20:44 2010
@@ -0,0 +1,288 @@
+/*
+ * All Sigmah code is released under the GNU General Public License v3
+ * See COPYRIGHT.txt and LICENSE.txt.
+ */
+
+package org.sigmah.client.page.project.dashboard;
+
+import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
+import com.extjs.gxt.ui.client.Style.LayoutRegion;
+import com.extjs.gxt.ui.client.Style.Orientation;
+import com.extjs.gxt.ui.client.Style.Scroll;
+import com.extjs.gxt.ui.client.store.ListStore;
+import com.extjs.gxt.ui.client.store.Store;
+import com.extjs.gxt.ui.client.store.StoreSorter;
+import com.extjs.gxt.ui.client.util.Margins;
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.TabPanel;
+import com.extjs.gxt.ui.client.widget.VerticalPanel;
+import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.grid.CheckColumnConfig;
+import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
+import com.extjs.gxt.ui.client.widget.grid.ColumnData;
+import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
+import com.extjs.gxt.ui.client.widget.grid.Grid;
+import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
+import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
+import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
+import com.extjs.gxt.ui.client.widget.layout.FitData;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.extjs.gxt.ui.client.widget.layout.RowData;
+import com.extjs.gxt.ui.client.widget.layout.RowLayout;
+import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
+import java.util.Arrays;
+import org.sigmah.client.i18n.I18N;
+import org.sigmah.client.icon.IconImageBundle;
+import org.sigmah.shared.dto.element.FlexibleElementDTO;
+import org.sigmah.shared.dto.element.FlexibleElementType;
+
+/**
+ *
+ * @author rca
+ */
+public class ProjectDashboardView extends ProjectDashboardPresenter.View {
+ private final ToolBar toolBar;
+
+ private TabPanel tabPanelPhases;
+ private LayoutContainer panelProjectModel;
+ private LayoutContainer panelSelectedPhase;
+
+ private Button buttonSavePhase;
+ private Button buttonActivatePhase;
+ private Button buttonPhaseGuide;
+
+ private ContentPanel panelReminders;
+ private ContentPanel panelWatchedPoints;
+ private ContentPanel panelFinancialProjects;
+ private ContentPanel panelLocalProjects;
+ private Grid<FlexibleElementDTO> gridRequiredElements;
+
+ public ProjectDashboardView() {
+ final BorderLayout borderLayout = new BorderLayout();
+ //borderLayout.setContainerStyle("x-border-layout-ct
panel-background"); -- White background
+ setLayout(borderLayout);
+ setHeight("100%");
+
+ /* Center panel */
+ ListStore<FlexibleElementDTO> storeRequiredElements = new
ListStore<FlexibleElementDTO>();
+ storeRequiredElements.setStoreSorter(new
StoreSorter<FlexibleElementDTO>() {
+ @Override
+ public int compare(Store<FlexibleElementDTO> store,
FlexibleElementDTO m1, FlexibleElementDTO m2,
+ String property) {
+ if ("type".equals(property)) {
+ return
FlexibleElementType.getFlexibleElementTypeName(m1).compareTo(
+
FlexibleElementType.getFlexibleElementTypeName(m2));
+ } else {
+ return super.compare(store, m1, m2, property);
+ }
+ }
+ });
+ gridRequiredElements = new
Grid<FlexibleElementDTO>(storeRequiredElements, getColumModel());
+ gridRequiredElements.addStyleName("sigmah-required-elements-grid");
+ gridRequiredElements.setAutoExpandColumn("label");
+ gridRequiredElements.getView().setForceFit(true);
+
+ // Phases tab panel
+ tabPanelPhases = new TabPanel();
+ tabPanelPhases.setPlain(true);
+ tabPanelPhases.addStyleName("sigmah-tabPhases");
+ tabPanelPhases.setHeight("100%");
+ tabPanelPhases.setBorders(false);
+ tabPanelPhases.setBodyBorder(false);
+
+ // Toolbar
+ toolBar = new ToolBar();
+ toolBar.setAlignment(HorizontalAlignment.RIGHT);
+ toolBar.setBorders(false);
+
+ buttonSavePhase = new
Button(I18N.CONSTANTS.projectSavePhaseButton());
+ buttonActivatePhase = new
Button(I18N.CONSTANTS.projectActivatePhaseButton());
+ buttonPhaseGuide = new
Button(I18N.CONSTANTS.projectPhaseGuideHeader());
+
+ buttonSavePhase.setEnabled(false);
+
+ toolBar.add(buttonSavePhase);
+ toolBar.add(buttonActivatePhase);
+ toolBar.add(buttonPhaseGuide);
+
+ // Tab item main panel
+ panelProjectModel = new LayoutContainer(new BorderLayout());
+ panelProjectModel.setBorders(false);
+
+ panelSelectedPhase = new LayoutContainer(new FitLayout());
+
+ final BorderLayoutData wd = new
BorderLayoutData(LayoutRegion.WEST, 250);
+ wd.setMargins(new Margins(4));
+
+ final ContentPanel cp = new ContentPanel(new FitLayout());
+ cp.setBorders(false);
+ cp.setBodyBorder(false);
+ cp.setHeading(I18N.CONSTANTS.projectRequiredElements());
+
+ cp.add(gridRequiredElements);
+ panelProjectModel.add(cp, wd);
+
+ final BorderLayoutData cd = new
BorderLayoutData(LayoutRegion.CENTER);
+ cd.setMargins(new Margins(4));
+
+ final ContentPanel cp2 = new ContentPanel(new FitLayout());
+ cp2.setBorders(false);
+ cp2.setBodyBorder(false);
+ cp2.setHeading(I18N.CONSTANTS.phaseDetails());
+ cp2.setScrollMode(Scroll.AUTO);
+
+ cp2.setTopComponent(toolBar);
+ cp2.add(panelSelectedPhase, new FitData(new Margins(4)));
+
+ panelProjectModel.add(cp2, cd);
+
+ /* West panel */
+ VerticalPanel westPanel = new VerticalPanel();
+ panelReminders = new ContentPanel();
+ panelReminders.setHeading(I18N.CONSTANTS.projectRemindersHeader());
+ panelReminders.addText("This panel displays the reminders.");
+ panelReminders.setBorders(false);
+ panelReminders.setCollapsible(true);
+ panelReminders.setWidth(250);
+ panelReminders.addStyleName("sigmah-panelReminders");
+
+ panelWatchedPoints = new ContentPanel();
+
panelWatchedPoints.setHeading(I18N.CONSTANTS.projectWatchedPointsHeader());
+ panelWatchedPoints.addText("This panel displays the watched
points.");
+ panelWatchedPoints.setBorders(false);
+ panelWatchedPoints.setCollapsible(true);
+ panelWatchedPoints.setWidth(250);
+
+ westPanel.add(panelReminders);
+ westPanel.add(panelWatchedPoints);
+
+ /* South panel */
+ LayoutContainer southPanel = new LayoutContainer(new
RowLayout(Orientation.VERTICAL));
+ panelFinancialProjects = new ContentPanel();
+ panelFinancialProjects.setBorders(false);
+
panelFinancialProjects.setHeading(I18N.CONSTANTS.projectFinancialProjectsHeader());
+ panelFinancialProjects.addText("This panel displays the financial
projects.");
+
+ panelLocalProjects = new ContentPanel();
+
panelLocalProjects.setHeading(I18N.CONSTANTS.projectLocalPartnerProjectsHeader());
+ panelLocalProjects.setBorders(false);
+ panelLocalProjects.addText("This panel displays the local partner
projects.");
+ southPanel.add(panelFinancialProjects, new RowData(1, 0.5, new
Margins(0, 0, 10, 0)));
+ southPanel.add(panelLocalProjects, new RowData(1, 0.5));
+
+ /* BorderLayoutData */
+ BorderLayoutData southData = new
BorderLayoutData(LayoutRegion.SOUTH, 170);
+ southData.setMargins(new Margins(5));
+ BorderLayoutData westData = new
BorderLayoutData(LayoutRegion.WEST, 250);
+ westData.setMargins(new Margins(5));
+ BorderLayoutData centerData = new
BorderLayoutData(LayoutRegion.CENTER);
+ centerData.setMargins(new Margins(5));
+
+ add(westPanel, westData);
+ add(tabPanelPhases, centerData);
+ add(southPanel, southData);
+ }
+
+ /**
+ * Generates the {@link ColumnModel} for the required elements grid.
+ *
+ * @return the {@link ColumnModel} for the required elements grid.
+ */
+ private ColumnModel getColumModel() {
+
+ // Element's label.
+ final ColumnConfig labelColumn = new ColumnConfig("label",
I18N.CONSTANTS.projectRequiredElementsGridLabel(),
+ 150);
+
+ // Element's completion.
+ final CheckColumnConfig filledInColumn = new
CheckColumnConfig("filledIn",
+ I18N.CONSTANTS.projectRequiredElementsGridChecked(), 40);
+ filledInColumn.setMenuDisabled(false);
+ filledInColumn.setSortable(false);
+ filledInColumn.setRenderer(new
GridCellRenderer<FlexibleElementDTO>() {
+ @Override
+ public Object render(FlexibleElementDTO model, String
property, ColumnData config, int rowIndex,
+ int colIndex, ListStore<FlexibleElementDTO> store,
Grid<FlexibleElementDTO> grid) {
+ if (model.isFilledIn()) {
+ return IconImageBundle.ICONS.checked().createImage();
+ } else {
+ return IconImageBundle.ICONS.unchecked().createImage();
+ }
+ }
+ });
+
+ // Element's type.
+ final ColumnConfig typeColumn = new ColumnConfig("type",
I18N.CONSTANTS.projectRequiredElementsElementType(),
+ 75);
+ typeColumn.setRenderer(new GridCellRenderer<FlexibleElementDTO>() {
+ @Override
+ public Object render(FlexibleElementDTO model, String
property, ColumnData config, int rowIndex,
+ int colIndex, ListStore<FlexibleElementDTO> store,
Grid<FlexibleElementDTO> grid) {
+ return
FlexibleElementType.getFlexibleElementTypeName(model);
+ }
+ });
+
+ return new ColumnModel(Arrays.asList(filledInColumn, labelColumn,
typeColumn));
+ }
+
+ @Override
+ public Button getButtonActivatePhase() {
+ return buttonActivatePhase;
+ }
+
+ @Override
+ public Button getButtonPhaseGuide() {
+ return buttonPhaseGuide;
+ }
+
+ @Override
+ public Button getButtonSavePhase() {
+ return buttonSavePhase;
+ }
+
+ @Override
+ public Grid<FlexibleElementDTO> getGridRequiredElements() {
+ return gridRequiredElements;
+ }
+
+ @Override
+ public ContentPanel getPanelFinancialProjects() {
+ return panelFinancialProjects;
+ }
+
+ @Override
+ public ContentPanel getPanelLocalProjects() {
+ return panelLocalProjects;
+ }
+
+ @Override
+ public LayoutContainer getPanelProjectModel() {
+ return panelProjectModel;
+ }
+
+ @Override
+ public ContentPanel getPanelReminders() {
+ return panelReminders;
+ }
+
+ @Override
+ public LayoutContainer getPanelSelectedPhase() {
+ return panelSelectedPhase;
+ }
+
+ @Override
+ public ContentPanel getPanelWatchedPoints() {
+ return panelWatchedPoints;
+ }
+
+ @Override
+ public TabPanel getTabPanelPhases() {
+ return tabPanelPhases;
+ }
+
+ @Override
+ public TabPanel getTabPanelProject() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
=======================================
--- /dev/null
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/RequiredValueState.java
Wed Oct 13 02:20:44 2010
@@ -0,0 +1,65 @@
+/*
+ * All Sigmah code is released under the GNU General Public License v3
+ * See COPYRIGHT.txt and LICENSE.txt.
+ */
+
+package org.sigmah.client.page.project.dashboard;
+
+/**
+ * Useful internal class to manage the required elements completion.
+ *
+ * @author tmi
+ *
+ */
+public class RequiredValueState {
+
+ /**
+ * The required element saved value completion (in db).
+ */
+ private Boolean savedState;
+ /**
+ * The actual element saved value completion (in local).
+ */
+ private Boolean actualState;
+
+ public void setSavedState(Boolean savedState) {
+ this.savedState = savedState;
+ }
+
+ public void setActualState(Boolean actualState) {
+ this.actualState = actualState;
+ }
+
+ /**
+ * Informs that the actual value completion has been saved to the data
+ * layer.
+ */
+ public void saveState() {
+ if (actualState != null) {
+ savedState = actualState;
+ actualState = null;
+ }
+ }
+
+ /**
+ * Informs that the actual value completion has been discarded.
+ */
+ public void clearState() {
+ actualState = null;
+ }
+
+ /**
+ * Returns if the saved value completion is valid.
+ *
+ * @return If the saved value completion is valid.
+ */
+ public boolean isTrue() {
+ return !Boolean.FALSE.equals(savedState);
+ }
+
+ @Override
+ public String toString() {
+ return "saved: " + savedState + " ; actual: " + actualState;
+ }
+}
+
=======================================
--- /dev/null
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/dashboard/RequiredValueStateList.java
Wed Oct 13 02:20:44 2010
@@ -0,0 +1,123 @@
+/*
+ * All Sigmah code is released under the GNU General Public License v3
+ * See COPYRIGHT.txt and LICENSE.txt.
+ */
+package org.sigmah.client.page.project.dashboard;
+
+import java.util.HashMap;
+
+/**
+ * Useful internal class to manage the required elements completions list.
+ *
+ * @author tmi
+ *
+ */
+public class RequiredValueStateList {
+
+ /**
+ * Map the required element, its saved value completion (in db) and its
+ * actual value completion (not yet saved).
+ */
+ private final HashMap<Integer, RequiredValueState> list;
+
+ public RequiredValueStateList() {
+ list = new HashMap<Integer, RequiredValueState>();
+ }
+
+ /**
+ * Clears the list of required elements.
+ */
+ public void clear() {
+ list.clear();
+ }
+
+ /**
+ * Copies a list of required elements from another manager.
+ *
+ * @param other
+ * The other required elements manager.
+ */
+ public void putAll(RequiredValueStateList other) {
+ list.putAll(other.list);
+ }
+
+ /**
+ * Sets a required element saved value completion (in db). Adds it if
+ * necessary.
+ *
+ * @param elementDTOId
+ * The required element id.
+ * @param savedState
+ * The saved value completion.
+ */
+ public void putSaved(Integer elementDTOId, Boolean savedState) {
+
+ RequiredValueState state = list.get(elementDTOId);
+
+ if (state == null) {
+ state = new RequiredValueState();
+ list.put(elementDTOId, state);
+ }
+
+ state.setSavedState(savedState);
+ }
+
+ /**
+ * Sets a required element actual value completion (in local). Adds it
+ * if necessary.
+ *
+ * @param elementDTOId
+ * The required element id.
+ * @param actualState
+ * The actual value completion.
+ */
+ public void putActual(Integer elementDTOId, Boolean actualState) {
+
+ RequiredValueState state = list.get(elementDTOId);
+
+ if (state == null) {
+ state = new RequiredValueState();
+ list.put(elementDTOId, state);
+ }
+
+ state.setActualState(actualState);
+ }
+
+ /**
+ * Informs that all actual values completions has been saved to the
data
+ * layer.
+ */
+ public void saveState() {
+ for (final RequiredValueState state : list.values()) {
+ state.saveState();
+ }
+ }
+
+ /**
+ * Informs that all actual values completions has been discarded.
+ */
+ public void clearState() {
+ for (final RequiredValueState state : list.values()) {
+ state.clearState();
+ }
+ }
+
+ /**
+ * Returns if all saved values completions are valid.
+ *
+ * @return If all saved values completions are valid.
+ */
+ public boolean isTrue() {
+ for (final RequiredValueState state : list.values()) {
+ if (!state.isTrue()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return list.toString();
+ }
+}
=======================================
---
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectModule.java
Thu Aug 5 06:08:18 2010
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectModule.java
Wed Oct 13 02:20:44 2010
@@ -6,6 +6,8 @@
package org.sigmah.client.page.project;

import com.google.gwt.inject.client.AbstractGinModule;
+import org.sigmah.client.page.project.dashboard.ProjectDashboardPresenter;
+import org.sigmah.client.page.project.dashboard.ProjectDashboardView;

/**
* Project module.
@@ -16,5 +18,6 @@
@Override
protected void configure() {
bind(ProjectPresenter.View.class).to(ProjectView.class);
+
//bind(ProjectDashboardPresenter.View.class).to(ProjectDashboardView.class);
}
}
=======================================
---
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectPresenter.java
Wed Sep 29 05:10:36 2010
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectPresenter.java
Wed Oct 13 02:20:44 2010
@@ -2,16 +2,10 @@
* All Sigmah code is released under the GNU General Public License v3
* See COPYRIGHT.txt and LICENSE.txt.
*/
-
package org.sigmah.client.page.project;

-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-
import org.sigmah.client.dispatch.AsyncMonitor;
import org.sigmah.client.dispatch.Dispatcher;
-import org.sigmah.client.dispatch.monitor.MaskingAsyncMonitor;
import org.sigmah.client.dispatch.remote.Authentication;
import org.sigmah.client.i18n.I18N;
import org.sigmah.client.page.Frame;
@@ -20,47 +14,24 @@
import org.sigmah.client.page.PageId;
import org.sigmah.client.page.PageState;
import org.sigmah.client.page.TabPage;
-import org.sigmah.shared.command.ChangePhase;
import org.sigmah.shared.command.GetProject;
-import org.sigmah.shared.command.GetValue;
-import org.sigmah.shared.command.UpdateProject;
-import org.sigmah.shared.command.result.ProjectListResult;
-import org.sigmah.shared.command.result.ValueResult;
-import org.sigmah.shared.command.result.VoidResult;
import org.sigmah.shared.dto.PhaseDTO;
-import org.sigmah.shared.dto.PhaseModelDTO;
import org.sigmah.shared.dto.ProjectDTO;
-import org.sigmah.shared.dto.element.FlexibleElementDTO;
-import org.sigmah.shared.dto.element.handler.RequiredValueEvent;
-import org.sigmah.shared.dto.element.handler.RequiredValueHandler;
-import org.sigmah.shared.dto.element.handler.ValueEvent;
-import org.sigmah.shared.dto.element.handler.ValueHandler;
-import org.sigmah.shared.dto.layout.LayoutConstraintDTO;
-import org.sigmah.shared.dto.layout.LayoutGroupDTO;

import com.allen_sauer.gwt.log.client.Log;
-import com.extjs.gxt.ui.client.event.ButtonEvent;
-import com.extjs.gxt.ui.client.event.ComponentEvent;
-import com.extjs.gxt.ui.client.event.Events;
-import com.extjs.gxt.ui.client.event.Listener;
-import com.extjs.gxt.ui.client.event.MessageBoxEvent;
-import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
-import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.Label;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.MessageBox;
-import com.extjs.gxt.ui.client.widget.TabItem;
-import com.extjs.gxt.ui.client.widget.TabPanel;
-import com.extjs.gxt.ui.client.widget.button.Button;
-import com.extjs.gxt.ui.client.widget.form.FieldSet;
-import com.extjs.gxt.ui.client.widget.form.FormPanel;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
-import com.extjs.gxt.ui.client.widget.layout.FormData;
+import com.extjs.gxt.ui.client.widget.layout.HBoxLayoutData;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Grid;
+import com.google.gwt.user.client.ui.Widget;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
+import org.sigmah.client.page.project.calendar.ProjectCalendarPresenter;
+import org.sigmah.client.page.project.dashboard.ProjectDashboardPresenter;
+import org.sigmah.client.ui.ToggleAnchor;

/**
* Project presenter which manages the {@link ProjectView}.
@@ -71,53 +42,85 @@

public static final PageId PAGE_ID = new PageId("project");

+ /**
+ * Description of the view managed by this presenter.
+ */
+ @ImplementedBy(ProjectView.class)
+ public interface View {
+
+ public ContentPanel getPanelProjectBanner();
+
+ public ContentPanel getTabPanel();
+
+ public void setMainPanel(Widget widget);
+ }
private final View view;
private final Dispatcher dispatcher;
private final Authentication authentication;
private Page activePage;
-
- /**
- * List of values changes.
- */
- private ArrayList<ValueEvent> valueChanges = new
ArrayList<ValueEvent>();
-
+ private ToggleAnchor currentTab;
/**
* The current displayed project.
*/
private ProjectDTO currentProjectDTO;
-
/**
* The current displayed phase.
*/
private PhaseDTO currentPhaseDTO;
-
- /**
- * Mapping between phases models ids and tabs items (to quickly get a
tab).
- */
- private final HashMap<Integer, TabItem> tabItemsMap;
-
- /**
- * A map to maintain the current active phase required elements states.
- */
- private final RequiredValueStateList activePhaseRequiredElements = new
RequiredValueStateList();
-
- /**
- * A map to maintain the current displayed phase required elements
states.
- */
- private final RequiredValueStateList currentPhaseRequiredElements =
new RequiredValueStateList();
+ private final static String[] MAIN_TABS = {
+ I18N.CONSTANTS.projectTabDashboard(),
+ I18N.CONSTANTS.projectTabLogFrame(),
I18N.CONSTANTS.projectTabIndicators(),
+ I18N.CONSTANTS.projectTabCalendar(),
I18N.CONSTANTS.projectTabReports(),
+ I18N.CONSTANTS.projectTabSecurityIncident()
+ };
+ private final Presenter[] presenters;

@Inject
public ProjectPresenter(final Dispatcher dispatcher, View view,
Authentication authentication) {
this.dispatcher = dispatcher;
this.view = view;
this.authentication = authentication;
- this.tabItemsMap = new HashMap<Integer, TabItem>();
-
- // Hides unimplemented panels and actions.
- view.getPanelFinancialProjects().setVisible(false);
- view.getPanelLocalProjects().setVisible(false);
- view.getPanelReminders().setVisible(false);
- view.getPanelWatchedPoints().setVisible(false);
+
+ this.presenters = new Presenter[] {
+ new ProjectDashboardPresenter(dispatcher, authentication,
this), // Dashboard
+ null, // Logical Framework
+ null, // Indicators
+ null, // Calendar
+ null, // Reports
+ null // Security incidents
+ };
+
+ for (int i = 0; i < MAIN_TABS.length; i++) {
+ final int index = i;
+
+ String tabTitle = MAIN_TABS[i];
+
+ final HBoxLayoutData layoutData = new HBoxLayoutData();
+ layoutData.setMargins(new Margins(0, 10, 0, 0));
+
+ final ToggleAnchor anchor = new ToggleAnchor(tabTitle);
+ anchor.setAnchorMode(i != 0);
+
+ if (i == 0) {
+ currentTab = anchor;
+ }
+
+ anchor.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ if (currentTab != anchor) {
+ currentTab.toggleAnchorMode();
+ anchor.toggleAnchorMode();
+ currentTab = anchor;
+
+
ProjectPresenter.this.view.setMainPanel(presenters[index].getView());
+ }
+ }
+ });
+
+ this.view.getTabPanel().add(anchor, layoutData);
+ }
}

@Override
@@ -130,6 +133,7 @@
}

dispatcher.execute(new GetProject(projectId), null, new
AsyncCallback<ProjectDTO>() {
+
@Override
public void onFailure(Throwable throwable) {
Log.error("Error, project #" + projectId + " not loaded.");
@@ -142,6 +146,7 @@
}
projectState.setTabTitle(projectDTO.getName());
loadProjectOnView(projectDTO);
+ view.setMainPanel(presenters[0].getView());
}
});

@@ -155,512 +160,34 @@
* the {@link ProjectDTO} object loaded on the view
*/
private void loadProjectOnView(ProjectDTO projectDTO) {
-
- // Sets current project status (for the first display, the active
phase
- // is rendered).
currentProjectDTO = projectDTO;
- currentPhaseDTO = currentProjectDTO.getCurrentPhaseDTO();
-
- // Clears the required elements maps .
- activePhaseRequiredElements.clear();
- currentPhaseRequiredElements.clear();
-
- // Sorts phases to be displayed in the correct order.
- Collections.sort(currentProjectDTO.getPhasesDTO());
-
- // --
- // -- TABS CREATION
- // --
-
- // Removes old tabs configuration (from the previous displayed
project).
- view.getTabPanelPhases().removeAll();
- view.getTabPanelPhases().removeAllListeners();
- tabItemsMap.clear();
-
- // Creates tabs for each phase.
- for (final PhaseDTO phaseDTO : currentProjectDTO.getPhasesDTO()) {
-
- // Creates the default tab.
- final TabItem tabItem = new
TabItem(phaseDTO.getPhaseModelDTO().getName());
- tabItem.setLayout(new FitLayout());
- tabItem.setEnabled(false);
- tabItem.setAutoHeight(true);
-
- // Map the tab item with the phase id.
- tabItemsMap.put(phaseDTO.getPhaseModelDTO().getId(), tabItem);
-
- // Adds the tab to the view.
- view.getTabPanelPhases().add(tabItem);
-
- // If the phase is the active one.
- if (isActivePhase(phaseDTO)) {
- // Enables it, apply the correct style and selects it.
- tabItem.setEnabled(true);
- tabItem.getHeader().addStyleName("project-phase-active");
- view.getTabPanelPhases().setSelection(tabItem);
- }
-
- // If the phase is ended.
- if (isEndedPhase(phaseDTO)) {
- // Enables it and apply the correct style.
- tabItem.setEnabled(true);
- tabItem.getHeader().addStyleName("project-phase-closed");
- }
- }
-
- // Enables successors tabs of the current phase.
- enableSuccessorsTabs();
-
- // --
- // -- TABS LISTENERS
- // --
-
- // Adds tabs listeners for selection changes (must be added after
tabs
- // creation or event fired for each tab).
- for (final PhaseDTO phaseDTO : currentProjectDTO.getPhasesDTO()) {
- final TabItem tabItem =
tabItemsMap.get(phaseDTO.getPhaseModelDTO().getId());
- tabItem.addListener(Events.Select, new
Listener<ComponentEvent>() {
-
- /**
- * Id of the phase to display. <br/>
- * Important: it's better to manipulate the id instead of
the
- * phases instances to keep coherence after a project
update.
- */
- private int phaseDTOId = phaseDTO.getId();
-
- private PhaseDTO retrievePhaseDTO() {
- // Loads the phase of the selected tab (loaded from the
- // current project instance).
- for (final PhaseDTO p :
currentProjectDTO.getPhasesDTO()) {
- if (p.getId() == phaseDTOId) {
- return p;
- }
- }
-
- return null;
- }
-
- @Override
- public void handleEvent(ComponentEvent tpe) {
-
- final PhaseDTO toDisplayPhase = retrievePhaseDTO();
-
- // If the current phase has been modified and it isn't
- // ended.
- if (view.getButtonSavePhase().isEnabled()
&& !isEndedPhase(currentPhaseDTO)) {
-
- // Asks the client to save the unsaved elements
before
- // switching phases.
-
MessageBox.confirm(I18N.CONSTANTS.projectPhaseChangeAlert(),
-
I18N.CONSTANTS.projectPhaseChangeAlertDetails(), new
Listener<MessageBoxEvent>() {
- @Override
- public void
handleEvent(MessageBoxEvent ce) {
-
- // If 'YES' is clicked, saves the
- // modifications.
- if
(Dialog.YES.equals(ce.getButtonClicked().getItemId())) {
-
view.getButtonSavePhase().fireEvent(Events.OnClick);
- if
(isActivePhase(currentPhaseDTO)) {
-
activePhaseRequiredElements.saveState();
-
- }
- } else if
(Dialog.NO.equals(ce.getButtonClicked().getItemId())) {
- // If the last displayed phase
was
- // the active one,
modifications are
- // discarded then the required
- // elements map is cleared (to
- // prevent inconsistent
successor
- // activation).
- if
(isActivePhase(currentPhaseDTO)) {
-
activePhaseRequiredElements.clearState();
- }
- }
-
- loadPhaseOnTab(toDisplayPhase);
- }
- });
- } else {
- loadPhaseOnTab(toDisplayPhase);
- }
- }
- });
- }
-
- // --
- // -- BANNER
- // --
+ currentPhaseDTO = projectDTO.getCurrentPhaseDTO();

refreshBanner();

- // --
- // -- ACTIVE PHASE SELECTION
- // --
-
- // Manually fires the first tab selection (active phase).
- loadPhaseOnTab(currentPhaseDTO);
+ // TODO: Call the sub-presenter
}

- /**
- * Loads a project phase into the selected tab panel.
- *
- * @param phaseDTO
- * The phase to display.
- */
- private void loadPhaseOnTab(final PhaseDTO phaseDTO) {
-
- // Masks the main panel.
- int count = 0;
- for (final LayoutGroupDTO groupDTO :
phaseDTO.getPhaseModelDTO().getLayoutDTO().getLayoutGroupsDTO()) {
- count += groupDTO.getLayoutConstraintsDTO().size();
- }
- mask(count);
-
- // Sets current project status.
- currentPhaseDTO = phaseDTO;
-
- // Clears the required elements map for the current displayed
phase.
- currentPhaseRequiredElements.clear();
- valueChanges.clear();
-
- // --
- // -- CLEARS PANELS
- // --
-
- // Clears all tabs.
- for (final TabItem tab : view.getTabPanelPhases().getItems()) {
- tab.removeAll();
- }
-
- // Clears panels.
- view.getPanelSelectedPhase().removeAll();
- view.getGridRequiredElements().getStore().removeAll();
-
view.getTabPanelPhases().getSelectedItem().add(view.getPanelProjectModel());
-
- // --
- // -- TOOLBAR
- // --
-
- refreshActionsToolbar();
-
- // --
- // -- PHASE LAYOUT
- // --
-
- final Grid layoutGrid = (Grid)
phaseDTO.getPhaseModelDTO().getWidget();
- view.getPanelSelectedPhase().add(layoutGrid);
-
- // For each layout group.
- for (final LayoutGroupDTO groupDTO :
phaseDTO.getPhaseModelDTO().getLayoutDTO().getLayoutGroupsDTO()) {
-
- // Creates the fieldset and positions it.
- final FieldSet fieldSet = (FieldSet) groupDTO.getWidget();
- final FormPanel formPanel = (FormPanel) fieldSet.getWidget(0);
- layoutGrid.setWidget(groupDTO.getRow(), groupDTO.getColumn(),
fieldSet);
-
- // For each constraint in the current layout group.
- for (LayoutConstraintDTO constraintDTO :
groupDTO.getLayoutConstraintsDTO()) {
-
- // Gets the element managed by this constraint.
- final FlexibleElementDTO elementDTO =
constraintDTO.getFlexibleElementDTO();
-
- // --
- // -- ELEMENT VALUE
- // --
-
- // Remote call to ask for this element value.
- final GetValue command = new
GetValue(currentProjectDTO.getId(), elementDTO.getId(),
- elementDTO.getEntityName());
- dispatcher.execute(command, null, new
AsyncCallback<ValueResult>() {
-
- @Override
- public void onFailure(Throwable throwable) {
- Log.error("Error, element value not loaded.");
- unmask();
- }
-
- @Override
- public void onSuccess(ValueResult valueResult) {
-
- if (Log.isDebugEnabled()) {
- Log.debug("Element value(s) object : " +
valueResult.toString());
- }
-
- // --
- // -- ELEMENT COMPONENT
- // --
-
- // Configures the flexible element for the current
- // application state before generating its
component.
- elementDTO.setService(dispatcher);
- elementDTO.setAuthentication(authentication);
- elementDTO.setCurrentProjectDTO(currentProjectDTO);
- elementDTO.assignValue(valueResult);
-
- // Generates element component (with the value).
- elementDTO.init();
- final Component elementComponent =
elementDTO.getComponent(valueResult);
- elementComponent.addStyleName("sigmah-element");
-
- // Component width.
- final FormData formData;
- if (elementDTO.getPreferredWidth() == 0) {
- formData = new FormData("100%");
- } else {
- formData = new
FormData(elementDTO.getPreferredWidth(), -1);
- }
-
- formPanel.add(elementComponent, formData);
- formPanel.layout();
-
- // --
- // -- ELEMENT HANDLERS
- // --
-
- // Adds a value change handler to this element.
- elementDTO.addValueHandler(new ValueHandlerImpl());
-
- // If this element id a required one.
- if (elementDTO.getValidates()) {
-
- // Adds a specific handler.
- elementDTO.addRequiredValueHandler(new
RequiredValueHandlerImpl(elementDTO));
-
- // Adds the element to the 'required panel'.
-
view.getGridRequiredElements().getStore().add(elementDTO);
-
- // Map the required element for the current
- // displayed phase.
-
currentPhaseRequiredElements.putSaved(elementDTO.getId(),
elementDTO.isFilledIn());
-
- // If the current displayed phase is the
active one,
- // map the required element for the active
phase.
- if
(isCurrentPhase(currentProjectDTO.getCurrentPhaseDTO())) {
-
activePhaseRequiredElements.putSaved(elementDTO.getId(),
elementDTO.isFilledIn());
- }
- }
-
- unmask();
- }
- });
- }
- }
-
- // View layouts update.
- ((ProjectView) view).layout();
+ public ProjectDTO getCurrentProjectDTO() {
+ return currentProjectDTO;
}

- /**
- * The counter before the main panel is unmasked.
- */
- private int maskCount;
-
- /**
- * Mask the main panel and set the mask counter.
- *
- * @param count
- * The mask counter.
- */
- private void mask(int count) {
- maskCount = count;
- view.getTabPanelPhases().mask(I18N.CONSTANTS.loading());
+ public void setCurrentProjectDTO(ProjectDTO currentProjectDTO) {
+ this.currentProjectDTO = currentProjectDTO;
}

- /**
- * Decrements the mask counter and unmask the main panel if the counter
- * reaches <code>0</code>.
- */
- private void unmask() {
- maskCount--;
- if (maskCount == 0) {
- view.getTabPanelPhases().unmask();
- }
+ public PhaseDTO getCurrentPhaseDTO() {
+ return currentPhaseDTO;
}

- /**
- * Internal class handling the phases activation.
- */
- private class ActivatePhaseListener implements Listener<ButtonEvent> {
-
- @Override
- public void handleEvent(ButtonEvent be) {
-
- // If the active phase required elements aren't filled, shows
an
- // alert.
- if (!isActivePhaseFilledIn()) {
-
MessageBox.info(I18N.CONSTANTS.projectPhaseActivationError(),
-
I18N.CONSTANTS.projectPhaseActivationErrorDetails(), null);
- }
- // Else, remote call to ask a new phase activation.
- else {
-
- // Activates the current displayed phase.
- dispatcher.execute(new
ChangePhase(currentProjectDTO.getId(), currentPhaseDTO.getId()), null,
- new AsyncCallback<ProjectListResult>() {
-
- @Override
- public void onFailure(Throwable throwable) {
- Log.error("Error, phase #" +
currentPhaseDTO.getId() + " not activated.");
- }
-
- @Override
- public void onSuccess(ProjectListResult
result) {
-
- if (Log.isDebugEnabled()) {
- Log.debug("Phase activated : " +
currentPhaseDTO.getId());
- }
-
- // Sets current project status.
- currentProjectDTO =
result.getList().get(0);
- currentPhaseDTO =
currentProjectDTO.getCurrentPhaseDTO();
-
- // Map the required element for the active
phase
- // from the current displayed phase map.
- activePhaseRequiredElements.clear();
-
activePhaseRequiredElements.putAll(currentPhaseRequiredElements);
-
- // --
- // -- BANNER
- // --
-
- refreshBanner();
-
- // --
- // -- TOOLBAR
- // --
-
- refreshActionsToolbar();
-
- // --
- // -- UPDATES TABS
- // --
-
- // Updates ended phases styles.
- for (PhaseDTO phase :
currentProjectDTO.getPhasesDTO()) {
- final TabItem successorTabItem =
tabItemsMap.get(phase.getPhaseModelDTO().getId());
- if (phase.isEnded()) {
-
successorTabItem.getHeader().setStyleName("project-phase-closed");
- }
- }
-
- // Updates active phase styles.
- for (TabItem item :
view.getTabPanelPhases().getItems()) {
-
item.getHeader().removeStyleName("project-phase-active");
- }
-
tabItemsMap.get(currentPhaseDTO.getPhaseModelDTO().getId()).getHeader()
- .addStyleName("project-phase-active");
-
- // Enables successors tabs of the current
phase.
- enableSuccessorsTabs();
- }
- });
- }
- }
- }
-
- /**
- * Internal class handling the modifications saving.
- */
- private class SaveListener implements Listener<ButtonEvent> {
-
- @Override
- public void handleEvent(ButtonEvent be) {
-
- view.getButtonSavePhase().disable();
- final UpdateProject updateProject = new
UpdateProject(currentProjectDTO.getId(), valueChanges);
-
- dispatcher.execute(updateProject,
- new MaskingAsyncMonitor(view.getTabPanelPhases(),
I18N.CONSTANTS.loading()),
- new AsyncCallback<VoidResult>() {
-
- @Override
- public void onFailure(Throwable caught) {
- MessageBox.info(I18N.CONSTANTS.cancelled(),
I18N.CONSTANTS.error(), null);
-
- currentPhaseRequiredElements.clearState();
-
- if (isActivePhase(currentPhaseDTO)) {
- activePhaseRequiredElements.clearState();
- }
- }
-
- @Override
- public void onSuccess(VoidResult result) {
- valueChanges.clear();
- MessageBox.info(I18N.CONSTANTS.ok(),
I18N.CONSTANTS.saved(), null);
-
- currentPhaseRequiredElements.saveState();
-
- if (isActivePhase(currentPhaseDTO)) {
- activePhaseRequiredElements.saveState();
- }
- }
- });
- }
- }
-
- /**
- * Returns if a phase is the current displayed phase.
- *
- * @param phaseDTO
- * The phase to test.
- * @return If the phase is currently displayed.
- */
- private boolean isCurrentPhase(PhaseDTO phaseDTO) {
- return currentPhaseDTO != null && phaseDTO != null &&
currentPhaseDTO.getId() == phaseDTO.getId();
- }
-
- /**
- * Returns if a phase is the active phase of the current project.
- *
- * @param phaseDTO
- * The phase to test.
- * @return If the phase is active.
- */
- private boolean isActivePhase(PhaseDTO phaseDTO) {
- return currentProjectDTO != null &&
currentProjectDTO.getCurrentPhaseDTO() != null && phaseDTO != null
- && currentProjectDTO.getCurrentPhaseDTO().getId() ==
phaseDTO.getId();
- }
-
- /**
- * Returns if a phase is ended.
- *
- * @param phaseDTO
- * The phase to test.
- * @return If the phase is ended.
- */
- private boolean isEndedPhase(PhaseDTO phaseDTO) {
- return phaseDTO != null && phaseDTO.isEnded();
- }
-
- /**
- * Returns if the active phase of the current project is filled in.
- *
- * @return If the active phase of the current project is filled in.
- */
- private boolean isActivePhaseFilledIn() {
-
- // Checks id the map contains only true booleans.
- return activePhaseRequiredElements.isTrue();
- //
return !activePhaseRequiredElements.containsValue(Boolean.FALSE);
- }
-
- /**
- * Enables the successors tabs of the current displayed phase.
- */
- private void enableSuccessorsTabs() {
-
- for (final PhaseModelDTO successor :
currentPhaseDTO.getPhaseModelDTO().getSuccessorsDTO()) {
- final TabItem successorTabItem =
tabItemsMap.get(successor.getId());
- if (successorTabItem != null) {
- successorTabItem.setEnabled(true);
- }
- }
+ public void setCurrentPhaseDTO(PhaseDTO currentPhaseDTO) {
+ this.currentPhaseDTO = currentPhaseDTO;
}

/**
* Refreshes the project banner for the current project.
*/
- private void refreshBanner() {
+ public void refreshBanner() {

view.getPanelProjectBanner().removeAll();

@@ -672,315 +199,11 @@
new Label(I18N.CONSTANTS.projectManager() + ": " +
currentProjectDTO.getOwnerName()));
view.getPanelProjectBanner().add(
new Label(I18N.CONSTANTS.projectActivePhase() + ": "
- +
currentProjectDTO.getCurrentPhaseDTO().getPhaseModelDTO().getName()));
+ +
currentProjectDTO.getCurrentPhaseDTO().getPhaseModelDTO().getName()));

view.getPanelProjectBanner().layout();
}
}
-
- /**
- * Refreshes the actions toolbar for the current displayed phase.
- */
- private void refreshActionsToolbar() {
-
- // --
- // -- ACTION: ACTIVE PHASE
- // --
-
- // Always enabled (the listener is in charge of this action
validation).
-
view.getButtonActivatePhase().setEnabled(activePhaseRequiredElements.isTrue());
- view.getButtonActivatePhase().removeAllListeners();
-
- // If the current displayed phase is the active one or it is
ended, hide
- if (isCurrentPhase(currentProjectDTO.getCurrentPhaseDTO()) ||
isEndedPhase(currentPhaseDTO)) {
- view.getButtonActivatePhase().setVisible(false);
- }
- // Else shows it for the current displayed phase successors.
- else {
- view.getButtonActivatePhase().setVisible(true);
- view.getButtonActivatePhase().addListener(Events.Select, new
ActivatePhaseListener());
- }
-
- // --
- // -- ACTION: SAVE MODIFICATIONS
- // --
-
- // Disabled until a field is modified.
- view.getButtonSavePhase().setEnabled(false);
- view.getButtonSavePhase().removeAllListeners();
-
- // If the phase is ended, hide the save action.
- if (currentPhaseDTO.isEnded()) {
- view.getButtonSavePhase().setVisible(false);
- }
- // Else shows it (for the active phase and its successors).
- else {
- view.getButtonSavePhase().setVisible(true);
- view.getButtonSavePhase().addListener(Events.OnClick, new
SaveListener());
- }
-
- // --
- // -- ACTION: PHASE GUIDE
- // --
-
- // For the moment, always visible and disabled.
- // TODO Check guide availability to enable this action.
- view.getButtonPhaseGuide().setVisible(true);
- view.getButtonPhaseGuide().removeAllListeners();
- view.getButtonPhaseGuide().setEnabled(false);
- }
-
- /**
- * Internal class handling the value changes of the flexible elements.
- */
- private class ValueHandlerImpl implements ValueHandler {
-
- @Override
- public void onValueChange(ValueEvent event) {
-
- // Stores the change to be saved later.
- valueChanges.add(event);
- // Enables the save action.
- view.getButtonSavePhase().setEnabled(true);
- }
-
- }
-
- /**
- * Internal class handling the value changes of the required elements.
- */
- private class RequiredValueHandlerImpl implements RequiredValueHandler
{
-
- private FlexibleElementDTO elementDTO;
-
- public RequiredValueHandlerImpl(FlexibleElementDTO elementDTO) {
- this.elementDTO = elementDTO;
- }
-
- @Override
- public void onRequiredValueChange(RequiredValueEvent event) {
-
- // Updates the element state for the new value.
- elementDTO.setFilledIn(event.isValueOn());
- view.getGridRequiredElements().getStore().update(elementDTO);
-
- // Map the required element for the current displayed phase.
- currentPhaseRequiredElements.putActual(elementDTO.getId(),
event.isValueOn());
-
- // If the current displayed phase is the active one,
- // map the required element for the active phase.
- if (isCurrentPhase(currentProjectDTO.getCurrentPhaseDTO())) {
- activePhaseRequiredElements.putActual(elementDTO.getId(),
event.isValueOn());
- }
- }
- }
-
- /**
- * Useful internal class to manage the required elements completions
list.
- *
- * @author tmi
- *
- */
- private class RequiredValueStateList {
-
- /**
- * Map the required element, its saved value completion (in db)
and its
- * actual value completion (not yet saved).
- */
- private final HashMap<Integer, RequiredValueState> list;
-
- public RequiredValueStateList() {
- list = new HashMap<Integer, RequiredValueState>();
- }
-
- /**
- * Clears the list of required elements.
- */
- public void clear() {
- list.clear();
- }
-
- /**
- * Copies a list of required elements from another manager.
- *
- * @param other
- * The other required elements manager.
- */
- public void putAll(RequiredValueStateList other) {
- list.putAll(other.list);
- }
-
- /**
- * Sets a required element saved value completion (in db). Adds it
if
- * necessary.
- *
- * @param elementDTOId
- * The required element id.
- * @param savedState
- * The saved value completion.
- */
- public void putSaved(Integer elementDTOId, Boolean savedState) {
-
- RequiredValueState state = list.get(elementDTOId);
-
- if (state == null) {
- state = new RequiredValueState();
- list.put(elementDTOId, state);
- }
-
- state.setSavedState(savedState);
- }
-
- /**
- * Sets a required element actual value completion (in local).
Adds it
- * if necessary.
- *
- * @param elementDTOId
- * The required element id.
- * @param actualState
- * The actual value completion.
- */
- public void putActual(Integer elementDTOId, Boolean actualState) {
-
- RequiredValueState state = list.get(elementDTOId);
-
- if (state == null) {
- state = new RequiredValueState();
- list.put(elementDTOId, state);
- }
-
- state.setActualState(actualState);
- }
-
- /**
- * Informs that all actual values completions has been saved to
the data
- * layer.
- */
- public void saveState() {
- for (final RequiredValueState state : list.values()) {
- state.saveState();
- }
- }
-
- /**
- * Informs that all actual values completions has been discarded.
- */
- public void clearState() {
- for (final RequiredValueState state : list.values()) {
- state.clearState();
- }
- }
-
- /**
- * Returns if all saved values completions are valid.
- *
- * @return If all saved values completions are valid.
- */
- public boolean isTrue() {
- for (final RequiredValueState state : list.values()) {
- if (!state.isTrue()) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- return list.toString();
- }
- }
-
- /**
- * Useful internal class to manage the required elements completion.
- *
- * @author tmi
- *
- */
- private class RequiredValueState {
-
- /**
- * The required element saved value completion (in db).
- */
- private Boolean savedState;
-
- /**
- * The actual element saved value completion (in local).
- */
- private Boolean actualState;
-
- public void setSavedState(Boolean savedState) {
- this.savedState = savedState;
- }
-
- public void setActualState(Boolean actualState) {
- this.actualState = actualState;
- }
-
- /**
- * Informs that the actual value completion has been saved to the
data
- * layer.
- */
- public void saveState() {
- if (actualState != null) {
- savedState = actualState;
- actualState = null;
- }
- }
-
- /**
- * Informs that the actual value completion has been discarded.
- */
- public void clearState() {
- actualState = null;
- }
-
- /**
- * Returns if the saved value completion is valid.
- *
***The diff for this file has been truncated for email.***
=======================================
---
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectView.java
Wed Sep 29 05:10:36 2010
+++
/trunk/sigmah/src/main/java/org/sigmah/client/page/project/ProjectView.java
Wed Oct 13 02:20:44 2010
@@ -5,46 +5,22 @@

package org.sigmah.client.page.project;

-import com.google.gwt.event.dom.client.ClickEvent;
-import java.util.Arrays;

import org.sigmah.client.i18n.I18N;
-import org.sigmah.client.icon.IconImageBundle;
-import org.sigmah.shared.dto.element.FlexibleElementDTO;
-import org.sigmah.shared.dto.element.FlexibleElementType;

import com.allen_sauer.gwt.log.client.Log;
-import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Orientation;
-import com.extjs.gxt.ui.client.Style.Scroll;
-import com.extjs.gxt.ui.client.store.ListStore;
-import com.extjs.gxt.ui.client.store.Store;
-import com.extjs.gxt.ui.client.store.StoreSorter;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.TabPanel;
-import com.extjs.gxt.ui.client.widget.VerticalPanel;
-import com.extjs.gxt.ui.client.widget.button.Button;
-import com.extjs.gxt.ui.client.widget.grid.CheckColumnConfig;
-import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
-import com.extjs.gxt.ui.client.widget.grid.ColumnData;
-import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
-import com.extjs.gxt.ui.client.widget.grid.Grid;
-import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
-import com.extjs.gxt.ui.client.widget.layout.FitData;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
-import com.extjs.gxt.ui.client.widget.layout.HBoxLayoutData;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout;
-import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
-import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.ui.Widget;
import org.sigmah.client.ui.StylableHBoxLayout;
-import org.sigmah.client.ui.ToggleAnchor;

/**
* Initializes the view elements of a project page.
@@ -52,31 +28,11 @@
* @author Denis Colliot (dcol...@ideia.fr)
*/
public class ProjectView extends LayoutContainer implements
ProjectPresenter.View {
-
- private ContentPanel panelProjectBanner;
- private TabPanel tabPanelProject;
-
- private TabPanel tabPanelPhases;
- private LayoutContainer panelProjectModel;
- private LayoutContainer panelSelectedPhase;
-
- private final ToolBar toolBar;
- private Button buttonSavePhase;
- private Button buttonActivatePhase;
- private Button buttonPhaseGuide;
-
- private ContentPanel panelReminders;
- private ContentPanel panelWatchedPoints;
- private ContentPanel panelFinancialProjects;
- private ContentPanel panelLocalProjects;
- private Grid<FlexibleElementDTO> gridRequiredElements;
-
- private ToggleAnchor currentTab;
-
- private final static String[] MAIN_TABS = {
I18N.CONSTANTS.projectTabDashboard(),
- I18N.CONSTANTS.projectTabLogFrame(),
I18N.CONSTANTS.projectTabIndicators(),
- I18N.CONSTANTS.projectTabCalendar(),
I18N.CONSTANTS.projectTabReports(),
- I18N.CONSTANTS.projectTabSecurityIncident() };
+ private final ContentPanel panelProjectBanner;
+ private final ContentPanel tabPanel;
+ private final ContentPanel bottomPanel;
+
+ private Widget widget;

/**
* Initializes a new ProjectView object.
@@ -95,255 +51,41 @@
panelProjectBanner.setLayout(new VBoxLayout());
panelProjectBanner.addStyleName("project-label-10");

- final ContentPanel bottomPanel = new ContentPanel(new
BorderLayout());
+ bottomPanel = new ContentPanel(new BorderLayout());
bottomPanel.setHeaderVisible(false);
bottomPanel.setBodyBorder(false);
bottomPanel.setBorders(false);

/* Project tab panel (main tab panel) */
- final ContentPanel tabPanel = new ContentPanel(new
StylableHBoxLayout("main-background project-top-bar"));
+ tabPanel = new ContentPanel(new
StylableHBoxLayout("main-background project-top-bar"));
tabPanel.setHeaderVisible(false);
tabPanel.setBodyBorder(false);
tabPanel.setBorders(false);

- for (int i = 0; i < MAIN_TABS.length; i++) {
- String tabTitle = MAIN_TABS[i];
-
- final HBoxLayoutData layoutData = new HBoxLayoutData();
- layoutData.setMargins(new Margins(0, 10, 0, 0));
-
- final ToggleAnchor anchor = new ToggleAnchor(tabTitle);
- anchor.setAnchorMode(i != 0);
-
- if(i == 0)
- currentTab = anchor;
-
- anchor.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- if(currentTab != anchor) {
- currentTab.toggleAnchorMode();
- anchor.toggleAnchorMode();
- currentTab = anchor;
- }
- }
- });
-
- tabPanel.add(anchor, layoutData);
- }
-
bottomPanel.add(tabPanel, new BorderLayoutData(LayoutRegion.NORTH,
20));

- LayoutContainer tabProjectContainer = new LayoutContainer(new
BorderLayout());
- tabProjectContainer.setHeight("100%");
-
- /* Center panel */
- ListStore<FlexibleElementDTO> storeRequiredElements = new
ListStore<FlexibleElementDTO>();
- storeRequiredElements.setStoreSorter(new
StoreSorter<FlexibleElementDTO>() {
- @Override
- public int compare(Store<FlexibleElementDTO> store,
FlexibleElementDTO m1, FlexibleElementDTO m2,
- String property) {
- if ("type".equals(property)) {
- return
FlexibleElementType.getFlexibleElementTypeName(m1).compareTo(
-
FlexibleElementType.getFlexibleElementTypeName(m2));
- } else {
- return super.compare(store, m1, m2, property);
- }
- }
- });
- gridRequiredElements = new
Grid<FlexibleElementDTO>(storeRequiredElements, getColumModel());
- gridRequiredElements.setAutoExpandColumn("label");
- gridRequiredElements.getView().setForceFit(true);
-
- // Phases tab panel
- tabPanelPhases = new TabPanel();
- tabPanelPhases.setStyleName("project-tabPhases");
- tabPanelPhases.setHeight("100%");
-
- // Toolbar
- toolBar = new ToolBar();
- toolBar.setAlignment(HorizontalAlignment.RIGHT);
- toolBar.setBorders(false);
-
- buttonSavePhase = new
Button(I18N.CONSTANTS.projectSavePhaseButton());
- buttonActivatePhase = new
Button(I18N.CONSTANTS.projectActivatePhaseButton());
- buttonPhaseGuide = new
Button(I18N.CONSTANTS.projectPhaseGuideHeader());
-
- toolBar.add(buttonSavePhase);
- toolBar.add(buttonActivatePhase);
- toolBar.add(buttonPhaseGuide);
-
- // Tab item main panel
- panelProjectModel = new LayoutContainer(new BorderLayout());
- panelProjectModel.setBorders(false);
-
- panelSelectedPhase = new LayoutContainer(new FitLayout());
-
- final BorderLayoutData wd = new
BorderLayoutData(LayoutRegion.WEST, 250);
- wd.setMargins(new Margins(4));
-
- final ContentPanel cp = new ContentPanel(new FitLayout());
- cp.setHeading(I18N.CONSTANTS.projectRequiredElements());
-
- cp.add(gridRequiredElements);
- panelProjectModel.add(cp, wd);
-
- final BorderLayoutData cd = new
BorderLayoutData(LayoutRegion.CENTER);
- cd.setMargins(new Margins(4));
-
- final ContentPanel cp2 = new ContentPanel(new FitLayout());
- cp2.setHeading(I18N.CONSTANTS.phaseDetails());
- cp2.setScrollMode(Scroll.AUTO);
-
- cp2.setTopComponent(toolBar);
- cp2.add(panelSelectedPhase, new FitData(new Margins(4)));
-
- panelProjectModel.add(cp2, cd);
-
- /* West panel */
- VerticalPanel westPanel = new VerticalPanel();
- panelReminders = new ContentPanel();
- panelReminders.setHeading(I18N.CONSTANTS.projectRemindersHeader());
- panelReminders.addText("This panel displays the reminders.");
- panelReminders.setBorders(false);
- panelReminders.setCollapsible(true);
- panelReminders.setWidth(250);
- panelReminders.setStyleName("project-panelReminders");
-
- panelWatchedPoints = new ContentPanel();
-
panelWatchedPoints.setHeading(I18N.CONSTANTS.projectWatchedPointsHeader());
- panelWatchedPoints.addText("This panel displays the watched
points.");
- panelWatchedPoints.setBorders(false);
- panelWatchedPoints.setCollapsible(true);
- panelWatchedPoints.setWidth(250);
-
- westPanel.add(panelReminders);
- westPanel.add(panelWatchedPoints);
-
- /* South panel */
- LayoutContainer southPanel = new LayoutContainer(new
RowLayout(Orientation.VERTICAL));
- panelFinancialProjects = new ContentPanel();
- panelFinancialProjects.setBorders(false);
-
panelFinancialProjects.setHeading(I18N.CONSTANTS.projectFinancialProjectsHeader());
- panelFinancialProjects.addText("This panel displays the financial
projects.");
-
- panelLocalProjects = new ContentPanel();
-
panelLocalProjects.setHeading(I18N.CONSTANTS.projectLocalPartnerProjectsHeader());
- panelLocalProjects.setBorders(false);
- panelLocalProjects.addText("This panel displays the local partner
projects.");
- southPanel.add(panelFinancialProjects, new RowData(1, 0.5, new
Margins(0, 0, 10, 0)));
- southPanel.add(panelLocalProjects, new RowData(1, 0.5));
-
- /* BorderLayoutData */
- BorderLayoutData southData = new
BorderLayoutData(LayoutRegion.SOUTH, 170);
- southData.setMargins(new Margins(5));
- BorderLayoutData westData = new
BorderLayoutData(LayoutRegion.WEST, 250);
- westData.setMargins(new Margins(5));
- BorderLayoutData centerData = new
BorderLayoutData(LayoutRegion.CENTER);
- centerData.setMargins(new Margins(5));
-
- tabProjectContainer.add(westPanel, westData);
- tabProjectContainer.add(tabPanelPhases, centerData);
- tabProjectContainer.add(southPanel, southData);
-
- bottomPanel.add(tabProjectContainer, new
BorderLayoutData(LayoutRegion.CENTER));
-
add(panelProjectBanner, new RowData(1, -1, new Margins(0, 0, 10,
0)));
add(bottomPanel, new RowData(1, 1));
}

- /**
- * Generates the {@link ColumnModel} for the required elements grid.
- *
- * @return the {@link ColumnModel} for the required elements grid.
- */
- private ColumnModel getColumModel() {
-
- // Element's label.
- final ColumnConfig labelColumn = new ColumnConfig("label",
I18N.CONSTANTS.projectRequiredElementsGridLabel(),
- 150);
-
- // Element's completion.
- final CheckColumnConfig filledInColumn = new
CheckColumnConfig("filledIn",
- I18N.CONSTANTS.projectRequiredElementsGridChecked(), 40);
- filledInColumn.setMenuDisabled(false);
- filledInColumn.setSortable(false);
- filledInColumn.setRenderer(new
GridCellRenderer<FlexibleElementDTO>() {
- @Override
- public Object render(FlexibleElementDTO model, String
property, ColumnData config, int rowIndex,
- int colIndex, ListStore<FlexibleElementDTO> store,
Grid<FlexibleElementDTO> grid) {
- if (model.isFilledIn()) {
- return IconImageBundle.ICONS.checked().createImage();
- } else {
- return IconImageBundle.ICONS.unchecked().createImage();
- }
- }
- });
-
- // Element's type.
- final ColumnConfig typeColumn = new ColumnConfig("type",
I18N.CONSTANTS.projectRequiredElementsElementType(),
- 75);
- typeColumn.setRenderer(new GridCellRenderer<FlexibleElementDTO>() {
- @Override
- public Object render(FlexibleElementDTO model, String
property, ColumnData config, int rowIndex,
- int colIndex, ListStore<FlexibleElementDTO> store,
Grid<FlexibleElementDTO> grid) {
- return
FlexibleElementType.getFlexibleElementTypeName(model);
- }
- });
-
- return new ColumnModel(Arrays.asList(filledInColumn, labelColumn,
typeColumn));
- }
-
- public LayoutContainer getPanelProjectModel() {
- return panelProjectModel;
- }
-
+ @Override
public ContentPanel getPanelProjectBanner() {
return panelProjectBanner;
}

- public ContentPanel getPanelReminders() {
- return panelReminders;
+ @Override
+ public ContentPanel getTabPanel() {
+ return tabPanel;
}

- public ContentPanel getPanelWatchedPoints() {
- return panelWatchedPoints;
- }
-
- public ContentPanel getPanelFinancialProjects() {
- return panelFinancialProjects;
- }
-
- public ContentPanel getPanelLocalProjects() {
- return panelLocalProjects;
- }
-
- public TabPanel getTabPanelPhases() {
- return tabPanelPhases;
- }
-
- public Grid<FlexibleElementDTO> getGridRequiredElements() {
- return gridRequiredElements;
- }
-
- public LayoutContainer getPanelSelectedPhase() {
- return panelSelectedPhase;
- }
-
- public Button getButtonSavePhase() {
- return buttonSavePhase;
- }
-
- public Button getButtonActivatePhase() {
- return buttonActivatePhase;
- }
-
- public Button getButtonPhaseGuide() {
- return buttonPhaseGuide;
- }
-
- public TabPanel getTabPanelProject() {
- return tabPanelProject;
- }
-
-}
+ @Override
+ public void setMainPanel(Widget widget) {
+ if(this.widget != null)
+ bottomPanel.remove(this.widget);
+
+ bottomPanel.add(widget, new BorderLayoutData(LayoutRegion.CENTER));
+ this.widget = widget;
+
+ bottomPanel.layout();
+ }
+}
Reply all
Reply to author
Forward
0 new messages