/*
* Copyright (c) 2009-2011 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.web.client.ui.pages.profile.settings;
import java.util.HashSet;
import java.util.Set;
import org.eurekastreams.commons.client.ActionProcessor;
import org.eurekastreams.commons.client.ActionRequestImpl;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.server.domain.Organization;
import org.eurekastreams.server.domain.Page;
import org.eurekastreams.server.search.modelview.OrganizationModelView;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.eurekastreams.server.search.modelview.PersonModelView.Role;
import org.eurekastreams.web.client.events.EventBus;
import org.eurekastreams.web.client.events.Observer;
import org.eurekastreams.web.client.events.ShowNotificationEvent;
import org.eurekastreams.web.client.events.UpdateHistoryEvent;
import org.eurekastreams.web.client.events.data.AuthorizeUpdateOrganizationResponseEvent;
import org.eurekastreams.web.client.events.data.GotOrganizationModelViewInformationResponseEvent;
import org.eurekastreams.web.client.events.data.UpdatedOrganizationResponseEvent;
import org.eurekastreams.web.client.history.CreateUrlRequest;
import org.eurekastreams.web.client.jsni.WidgetJSNIFacadeImpl;
import org.eurekastreams.web.client.model.OrganizationModel;
import org.eurekastreams.web.client.ui.Session;
import org.eurekastreams.web.client.ui.common.SettingsPanel;
import org.eurekastreams.web.client.ui.common.form.FormBuilder;
import org.eurekastreams.web.client.ui.common.form.FormBuilder.Method;
import org.eurekastreams.web.client.ui.common.form.elements.BasicCheckBoxFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.BasicTextAreaFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.BasicTextBoxFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.PersonModelViewLookupFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.ValueOnlyFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.avatar.AvatarUploadFormElement;
import org.eurekastreams.web.client.ui.common.form.elements.avatar.strategies.AvatarUploadStrategy;
import org.eurekastreams.web.client.ui.common.form.elements.avatar.strategies.BannerUploadStrategy;
import org.eurekastreams.web.client.ui.common.notifier.Notification;
import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle;
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.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
/**
* A panel for changing the settings of an organization.
*/
public class OrganizationProfileSettingsPanel extends SettingsPanel
{
/**
* The panel.
*/
static FlowPanel panel = new FlowPanel();
/**
* Maximum name length.
*/
private static final int MAX_NAME = 50;
/**
* The delete-group button.
*/
private final Anchor deleteButton = new Anchor("");
/**
* The processing spinner.
*/
private final Label processingSpinny = new Label("Processing...");
/**
* Default constructor.
*
* @param orgName
* org.
*/
public OrganizationProfileSettingsPanel(final String orgName)
{
super(panel, "Configure Profile");
this.clearContentPanel();
this.setPreviousPage(new CreateUrlRequest(Page.ORGANIZATIONS, orgName), "< Return to Profile");
panel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().orgProfileSettingsPanel());
EventBus.getInstance().addObserver(GotOrganizationModelViewInformationResponseEvent.class,
new Observer<GotOrganizationModelViewInformationResponseEvent>()
{
public void update(final GotOrganizationModelViewInformationResponseEvent event)
{
setEntity(event.getResponse());
}
});
Session.getInstance().getEventBus().addObserver(AuthorizeUpdateOrganizationResponseEvent.class,
new Observer<AuthorizeUpdateOrganizationResponseEvent>()
{
public void update(final AuthorizeUpdateOrganizationResponseEvent event)
{
if (event.getResponse())
{
OrganizationModel.getInstance().fetch(orgName, true);
}
}
});
OrganizationModel.getInstance().authorize(orgName, true);
}
/**
* Setter.
*
* @param entity
* the organization whose settings will be changed
*/
public void setEntity(final OrganizationModelView entity)
{
ActionProcessor processor = Session.getInstance().getActionProcessor();
FormBuilder form = new FormBuilder("", OrganizationModel.getInstance(), Method.UPDATE);
Session.getInstance().getEventBus().addObserver(UpdatedOrganizationResponseEvent.class,
new Observer<UpdatedOrganizationResponseEvent>()
{
public void update(final UpdatedOrganizationResponseEvent arg1)
{
Session.getInstance().getEventBus().notifyObservers(
new UpdateHistoryEvent(new CreateUrlRequest(Page.ORGANIZATIONS, arg1.getResponse()
.getShortName())));
Session.getInstance().getEventBus().notifyObservers(
new ShowNotificationEvent(new Notification(
"Your organization has been successfully saved")));
}
});
form.addFormElement(new ValueOnlyFormElement(OrganizationModelView.ID_KEY, Long.toString(entity.getId())));
form.addFormElement(new ValueOnlyFormElement(OrganizationModelView.SHORT_NAME_KEY, entity.getShortName()));
form.addWidget(new AvatarUploadFormElement("Avatar",
"Select a JPG, PNG or GIF image from your computer. The maxium file size is 4MB"
+ " and will be cropped to 990 x 100 pixels high.", "/eurekastreams/orgavatarupload?orgName="
+ entity.getShortName(), processor, new AvatarUploadStrategy<OrganizationModelView>(entity,
"resizeOrgAvatar", EntityType.ORGANIZATION)));
form.addFormDivider();
form.addFormElement(new BasicTextBoxFormElement(MAX_NAME, false, "Organization Name",
OrganizationModelView.NAME_KEY, entity.getName(), "", true));
form.addFormElement(new BasicTextAreaFormElement(Organization.MAX_DESCRIPTION_LENGTH, "Description",
OrganizationModelView.DESCRIPTION_KEY, entity.getDescription(),
"Enter a few sentences that describe the purpose of your organization's stream. "
+ "This description will appear beneath your avatar "
+ "and in search results pages in the directory.", false));
form.addFormDivider();
form.addFormElement(new BasicTextBoxFormElement("Website URL", OrganizationModelView.URL_KEY, entity.getUrl(),
"If your organization has a website, you can enter the URL above", false));
form.addFormDivider();
String leaderinstructions = "Add the organization's leaders "
+ "in the order you would like them to appear on the profile.";
Set<PersonModelView> leaderList = new HashSet<PersonModelView>(entity.getLeaders());
form.addFormElement(new PersonModelViewLookupFormElement("Leadership", "Add Leader", leaderinstructions,
OrganizationModelView.LEADERSHIP_KEY, leaderList, false));
form.addFormDivider();
String coordinstructions = "The organization coordinators will be responsible "
+ "for setting up the organization profile, setting org policy " + "and managing adoption campaigns.";
Set<PersonModelView> coordinatorList = new HashSet<PersonModelView>(entity.getCoordinators());
form.addFormElement(new PersonModelViewLookupFormElement("Organization Coordinators", "Add Coordinator",
coordinstructions, OrganizationModelView.COORDINATORS_KEY, coordinatorList, true));
form.addFormDivider();
final AvatarUploadFormElement banner = new AvatarUploadFormElement("Banner",
"Select a JPG, PNG or GIF image from your computer. "
+ "The maximum file size is 4MB and will be cropped to 120 pixels high.",
"/eurekastreams/bannerupload?type=Organization&entityName=" + entity.getShortName(), processor,
new BannerUploadStrategy<OrganizationModelView>(entity, entity.getId()));
banner.addStyleName(StaticResourceBundle.INSTANCE.coreCss().bannerUploadFormElement());
form.addWidget(banner);
form.addFormDivider();
BasicCheckBoxFormElement groupCreationPolicy = new BasicCheckBoxFormElement("New Group Moderation",
OrganizationModelView.ALLOW_GROUP_CREATION_KEY, "Enable Moderation.",
"By enabling moderation, organization coordinators will be required to review new group requests. "
+ "Groups pending approval will be listed under the admin tab of your organization's profile.",
false, !entity.getAllUsersCanCreateGroups());
// The key is true for "allowing group creation" and the checkbox displays "allowing moderation". Since
// these are opposites, the value needs to be reversed when the form gets submitted.
groupCreationPolicy.setReverseValue(true);
groupCreationPolicy.addStyleName(StaticResourceBundle.INSTANCE.coreCss().orgGroupPolicy());
form.addFormElement(groupCreationPolicy);
form.addFormDivider();
form.setOnCancelHistoryToken(Session.getInstance().generateUrl(
new CreateUrlRequest(Page.ORGANIZATIONS, entity.getShortName())));
if (Session.getInstance().getCurrentPersonRoles().contains(Role.ROOT_ORG_COORDINATOR))
{
deleteButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formDeleteOrgButton());
deleteButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton());
deleteButton.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent event)
{
if (new WidgetJSNIFacadeImpl().confirm("Are sure you want to delete this organization? "
+ "Deleting the organization will remove the profile from the system "
+ "and will move all employees reporting to this organization to it’s "
+ "parent organization"))
{
processingSpinny.setVisible(true);
deleteButton.setVisible(false);
// TODO - should put this in OrganizationModel (and mark it as Deletable) but there's no
// custom onFailure ability there yet.
Session.getInstance().getActionProcessor().makeRequest(
new ActionRequestImpl<String>("deleteOrganizationAction", entity.getId()),
new AsyncCallback<String>()
{
public void onSuccess(final String result)
{
// adds notification to top of page
Session.getInstance().getEventBus().notifyObservers(
new ShowNotificationEvent(new Notification("The organization '"
+ entity.getName() + "' has been deleted")));
// navigates away from settings page to the parent org profile page
Session.getInstance().getEventBus()
.notifyObservers(
new UpdateHistoryEvent(new CreateUrlRequest(Page.ORGANIZATIONS,
result)));
}
public void onFailure(final Throwable caught)
{
// adds notification to top of page
Session.getInstance().getEventBus().notifyObservers(
new ShowNotificationEvent(new Notification(
"An error has occured and the organization '"
+ entity.getName() + "' was not deleted")));
processingSpinny.setVisible(false);
deleteButton.setVisible(true);
}
});
}
}
});
form.addWidgetToFormContainer(deleteButton);
processingSpinny.setVisible(false);
processingSpinny.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formSubmitSpinny());
form.addWidgetToFormContainer(processingSpinny);
}
panel.add(form);
}
}