/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.geofence.gui.client.widget;
import org.geoserver.geofence.gui.client.widget.GeofenceGridWidget;
import org.geoserver.geofence.gui.client.widget.SearchFilterField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.LoadEvent;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FieldEvent;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.LoadListener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
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.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.google.gwt.user.client.rpc.AsyncCallback;
import org.geoserver.geofence.gui.client.Constants;
import org.geoserver.geofence.gui.client.GeofenceEvents;
import org.geoserver.geofence.gui.client.Resources;
import org.geoserver.geofence.gui.client.i18n.I18nProvider;
import org.geoserver.geofence.gui.client.model.BeanKeyValue;
import org.geoserver.geofence.gui.client.model.GSUserModel;
//import org.geoserver.geofence.gui.client.model.Profile;
import org.geoserver.geofence.gui.client.service.GsUsersManagerRemoteServiceAsync;
import org.geoserver.geofence.gui.client.service.ProfilesManagerRemoteServiceAsync;
// TODO: Auto-generated Javadoc
/**
* The Class UserGridWidget.
*/
public class UserGridWidget extends GeofenceGridWidget<GSUserModel>
{
/** The gs users service. */
private GsUsersManagerRemoteServiceAsync gsUsersService;
/** The profiles service. */
private ProfilesManagerRemoteServiceAsync profilesService;
/** The proxy. */
private RpcProxy<PagingLoadResult<GSUserModel>> proxy;
/** The loader. */
private PagingLoader<PagingLoadResult<ModelData>> loader;
/** The tool bar. */
private PagingToolBar toolBar;
/**
* Instantiates a new user grid widget.
*
* @param service
* the service
* @param profilesService
* the profiles service
*/
public UserGridWidget(GsUsersManagerRemoteServiceAsync service,
ProfilesManagerRemoteServiceAsync profilesService)
{
super();
this.gsUsersService = service;
this.profilesService = profilesService;
}
/**
* Instantiates a new user grid widget.
*
* @param models
* the models
*/
public UserGridWidget(List<GSUserModel> models)
{
super(models);
}
/*
* (non-Javadoc)
*
* @see org.geoserver.geofence.gui.client.widget.GEOFENCEGridWidget#setGridProperties ()
*/
@Override
public void setGridProperties()
{
grid.setHeight(Constants.SOUTH_PANEL_DIMENSION - 25);
}
/*
* (non-Javadoc)
*
* @see org.geoserver.geofence.gui.client.widget.GEOFENCEGridWidget# prepareColumnModel()
*/
@Override
public ColumnModel prepareColumnModel()
{
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig userNameColumn = new ColumnConfig();
userNameColumn.setId(BeanKeyValue.NAME.getValue());
userNameColumn.setHeader("User Name");
TextField<String> userNameField = new TextField<String>();
userNameField.setAllowBlank(false);
userNameColumn.setEditor(new CellEditor(userNameField));
userNameColumn.setWidth(100);
configs.add(userNameColumn);
ColumnConfig dateCreationColumn = new ColumnConfig();
dateCreationColumn.setId(BeanKeyValue.DATE_CREATION.getValue());
dateCreationColumn.setHeader("Date Creation");
dateCreationColumn.setWidth(180);
configs.add(dateCreationColumn);
ColumnConfig userEnabledColumn = new ColumnConfig();
userEnabledColumn.setId(BeanKeyValue.USER_ENABLED.getValue());
userEnabledColumn.setHeader("Enabled");
userEnabledColumn.setWidth(80);
userEnabledColumn.setRenderer(this.createEnableCheckBox());
userEnabledColumn.setMenuDisabled(true);
userEnabledColumn.setSortable(false);
configs.add(userEnabledColumn);
ColumnConfig userAdminColumn = new ColumnConfig();
userAdminColumn.setId(BeanKeyValue.USER_ADMIN.getValue());
userAdminColumn.setHeader("Admin");
userAdminColumn.setWidth(80);
userAdminColumn.setRenderer(this.createAdminCheckBox());
userAdminColumn.setMenuDisabled(true);
userAdminColumn.setSortable(false);
configs.add(userAdminColumn);
ColumnConfig emailColumn = new ColumnConfig();
emailColumn.setId(BeanKeyValue.EMAIL.getValue());
emailColumn.setHeader("E-mail");
emailColumn.setWidth(180);
emailColumn.setRenderer(this.createEMailTextBox());
emailColumn.setMenuDisabled(true);
emailColumn.setSortable(false);
configs.add(emailColumn);
ColumnConfig passwordColumn = new ColumnConfig();
passwordColumn.setId(BeanKeyValue.PASSWORD.getValue());
passwordColumn.setHeader("Password");
passwordColumn.setWidth(180);
passwordColumn.setRenderer(this.createPasswordTextBox());
passwordColumn.setMenuDisabled(true);
passwordColumn.setSortable(false);
configs.add(passwordColumn);
ColumnConfig detailsUserColumn = new ColumnConfig();
detailsUserColumn.setId("detailsUser");
detailsUserColumn.setWidth(80);
detailsUserColumn.setRenderer(this.createUserDetailsButton());
detailsUserColumn.setMenuDisabled(true);
detailsUserColumn.setSortable(false);
configs.add(detailsUserColumn);
ColumnConfig removeActionColumn = new ColumnConfig();
removeActionColumn.setId("removeUser");
removeActionColumn.setWidth(80);
removeActionColumn.setRenderer(this.createUserDeleteButton());
removeActionColumn.setMenuDisabled(true);
removeActionColumn.setSortable(false);
configs.add(removeActionColumn);
return new ColumnModel(configs);
}
/*
* (non-Javadoc)
*
* @see org.geoserver.geofence.gui.client.widget.GEOFENCEGridWidget#createStore()
*/
@Override
public void createStore()
{
this.toolBar = new PagingToolBar(
org.geoserver.geofence.gui.client.Constants.DEFAULT_PAGESIZE);
// Loader fro gsUsersService
this.proxy = new RpcProxy<PagingLoadResult<GSUserModel>>()
{
@Override
protected void load(Object loadConfig, AsyncCallback<PagingLoadResult<GSUserModel>> callback)
{
gsUsersService.getGsUsers(((PagingLoadConfig) loadConfig).getOffset(), ((PagingLoadConfig) loadConfig).getLimit(), false, callback);
}
};
loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy);
loader.setRemoteSort(false);
store = new ListStore<GSUserModel>(loader);
// Search tool
SearchFilterField<GSUserModel> filter = new SearchFilterField<GSUserModel>()
{
@Override
protected boolean doSelect(Store<GSUserModel> store, GSUserModel parent, GSUserModel record,
String property, String filter)
{
String name = parent.get(BeanKeyValue.NAME.getValue());
name = name.toLowerCase();
if (name.indexOf(filter.toLowerCase()) != -1)
{
return true;
}
return false;
}
};
filter.setWidth(130);
filter.setIcon(Resources.ICONS.search());
// Bind the filter field to your grid store (grid.getStore())
filter.bind(store);
// Add User button
Button addUserButton = new Button("Add User");
addUserButton.setIcon(Resources.ICONS.add());
addUserButton.setEnabled(false);
addUserButton.addListener(Events.OnClick, new Listener<ButtonEvent>()
{
public void handleEvent(ButtonEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[] { "GeoServer Users", "Add User" });
Dispatcher.forwardEvent(GeofenceEvents.CREATE_NEW_USER);
}
});
this.toolBar.bind(loader);
this.toolBar.add(new SeparatorToolItem());
this.toolBar.add(addUserButton);
this.toolBar.add(new SeparatorToolItem());
this.toolBar.add(filter);
this.toolBar.add(new SeparatorToolItem());
setUpLoadListener();
}
/**
* Gets the loader.
*
* @return the loader
*/
public PagingLoader<PagingLoadResult<ModelData>> getLoader()
{
return loader;
}
/**
* Gets the tool bar.
*
* @return the tool bar
*/
public PagingToolBar getToolBar()
{
return toolBar;
}
/**
* Clear grid elements.
*/
public void clearGridElements()
{
this.store.removeAll();
this.toolBar.clear();
this.toolBar.disable();
}
/**
* Sets the up load listener.
*/
private void setUpLoadListener()
{
loader.addLoadListener(new LoadListener()
{
@Override
public void loaderBeforeLoad(LoadEvent le)
{
if (!toolBar.isEnabled())
{
toolBar.enable();
}
}
@Override
public void loaderLoad(LoadEvent le)
{
// TODO: change messages here!!
BasePagingLoadResult<?> result = le.getData();
if (!result.getData().isEmpty())
{
int size = result.getData().size();
String message = "";
if (size == 1)
{
message = I18nProvider.getMessages().recordLabel();
}
else
{
message = I18nProvider.getMessages().recordPluralLabel();
}
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[]
{
"User Service",
I18nProvider.getMessages().foundLabel() + " " + result.getData().size() +
" " + message
});
}
else
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[]
{
"User Service",
I18nProvider.getMessages().recordNotFoundMessage()
});
}
}
});
}
/**
* Creates the enable check box.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createEnableCheckBox()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
CheckBox userEnabledButton = new CheckBox();
userEnabledButton.setValue(model.isEnabled());
userEnabledButton.addListener(Events.OnClick, new Listener<FieldEvent>()
{
public void handleEvent(FieldEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[] { "GeoServer Users", "Enable check!" });
model.setEnabled((Boolean) be.getField().getValue());
Dispatcher.forwardEvent(GeofenceEvents.UPDATE_USER, model);
}
});
return userEnabledButton;
}
};
return buttonRendered;
}
/**
* Creates the admin check box.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createAdminCheckBox()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
CheckBox userAdminButton = new CheckBox();
userAdminButton.setValue(model.isAdmin());
userAdminButton.addListener(Events.OnClick, new Listener<FieldEvent>()
{
public void handleEvent(FieldEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[] { "GeoServer Users", "Admin check!" });
model.setAdmin((Boolean) be.getField().getValue());
Dispatcher.forwardEvent(GeofenceEvents.UPDATE_USER, model);
}
});
return userAdminButton;
}
};
return buttonRendered;
}
/**
* Creates the user password text box.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createPasswordTextBox()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
TextField<String> userPasswordTextBox = new TextField<String>();
userPasswordTextBox.setWidth(150);
userPasswordTextBox.setPassword(true);
userPasswordTextBox.setValue(model.getPassword());
userPasswordTextBox.addListener(Events.Change, new Listener<FieldEvent>()
{
public void handleEvent(FieldEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[]
{
"GeoServer User",
"User password changed to -> " + be.getField().getValue()
});
model.setPassword((String) be.getField().getValue());
Dispatcher.forwardEvent(GeofenceEvents.UPDATE_USER, model);
}
});
return userPasswordTextBox;
}
};
return buttonRendered;
}
/**
* Creates the user password text box.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createEMailTextBox()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
TextField<String> emailTextBox = new TextField<String>();
emailTextBox.setWidth(150);
emailTextBox.setValue(model.getEmailAddress());
emailTextBox.addListener(Events.Change, new Listener<FieldEvent>()
{
public void handleEvent(FieldEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[]
{
"GeoServer User",
"User e-mail changed to -> " + be.getField().getValue()
});
model.setEmailAddress((String) be.getField().getValue());
Dispatcher.forwardEvent(GeofenceEvents.UPDATE_USER, model);
}
});
return emailTextBox;
}
};
return buttonRendered;
}
/**
* Creates the user delete button.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createUserDeleteButton()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
Button removeUserButton = new Button("Remove");
removeUserButton.setIcon(Resources.ICONS.delete());
removeUserButton.addListener(Events.OnClick, new Listener<ButtonEvent>()
{
public void handleEvent(ButtonEvent be)
{
final Listener<MessageBoxEvent> l = new Listener<MessageBoxEvent>()
{
public void handleEvent(MessageBoxEvent ce)
{
Button btn = ce.getButtonClicked();
if (btn.getText().equalsIgnoreCase("Yes"))
{
Dispatcher.forwardEvent(GeofenceEvents.DELETE_USER, model);
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[]
{
"GeoServer Users", "Remove User: " + model.getName()
});
}
}
};
MessageBox.confirm("Confirm",
"The User will be deleted. Are you sure you want to do that?", l);
}
});
return removeUserButton;
}
};
return buttonRendered;
}
/**
* Creates the user details button.
*
* @return the grid cell renderer
*/
private GridCellRenderer<GSUserModel> createUserDetailsButton()
{
GridCellRenderer<GSUserModel> buttonRendered = new GridCellRenderer<GSUserModel>()
{
private boolean init;
public Object render(final GSUserModel model, String property, ColumnData config,
int rowIndex, int colIndex, ListStore<GSUserModel> store, Grid<GSUserModel> grid)
{
if (!init)
{
init = true;
grid.addListener(Events.ColumnResize, new Listener<GridEvent<GSUserModel>>()
{
public void handleEvent(GridEvent<GSUserModel> be)
{
for (int i = 0; i < be.getGrid().getStore().getCount(); i++)
{
if ((be.getGrid().getView().getWidget(i, be.getColIndex()) != null) &&
(be.getGrid().getView().getWidget(i, be.getColIndex()) instanceof BoxComponent))
{
((BoxComponent) be.getGrid().getView().getWidget(i,
be.getColIndex())).setWidth(be.getWidth() - 10);
}
}
}
});
}
Button groupsUserButton = new Button("Roles");
groupsUserButton.setIcon(Resources.ICONS.table());
groupsUserButton.addListener(Events.OnClick, new Listener<ButtonEvent>()
{
public void handleEvent(ButtonEvent be)
{
Dispatcher.forwardEvent(GeofenceEvents.SEND_INFO_MESSAGE,
new String[] { "GeoServer User", "User roles: " + model.getName() });
Dispatcher.forwardEvent(GeofenceEvents.EDIT_USER_DETAILS, model);
}
});
return groupsUserButton;
}
};
return buttonRendered;
}
}