package com.griddynamics.jagger.webclient.client.components;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor.Path;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.griddynamics.jagger.webclient.client.SessionDataService;
import com.griddynamics.jagger.dbapi.dto.SessionDataDto;
import com.griddynamics.jagger.dbapi.dto.TagDto;
import com.griddynamics.jagger.webclient.client.resources.JaggerResources;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.*;
import com.sencha.gxt.dnd.core.client.DndDropEvent;
import com.sencha.gxt.dnd.core.client.GridDragSource;
import com.sencha.gxt.dnd.core.client.GridDropTarget;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.event.RowMouseDownEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.treegrid.TreeGrid;
public class TagBox extends AbstractWindow implements IsWidget {
private SessionComparisonPanel.TreeItem currentTreeItem;
private TextArea descriptionPanel;
private Grid<TagDto> gridStorageL;
private Grid<TagDto> gridStorageR;
private ListStore<TagDto> storeFrom;
private ListStore<TagDto> storeTo;
private final boolean ADD_NEW = true;
private final String DEFAULT_TITLE = "Click on any row...";
private TextButton allRight, right, left, allLeft;
private TreeGrid<SessionComparisonPanel.TreeItem> treeGrid;
private SessionDataDto currentSession;
interface TagDtoProperties extends PropertyAccess<TagDto> {
@Path("name")
ModelKeyProvider<TagDto> name();
@Path("name")
ValueProvider<TagDto, String> descriptionProp();
}
public TagBox() {
super();
buttonInitialization();
defaultButtonInitialization();
TagDtoProperties props = GWT.create(TagDtoProperties.class);
storeFrom = new ListStore<TagDto>(props.name());
storeTo = new ListStore<TagDto>(props.name());
descriptionPanel = new TextArea();
descriptionPanel.setReadOnly(true);
descriptionPanel.setStyleName(JaggerResources.INSTANCE.css().descriptionPanel());
descriptionPanel.setPixelSize(width, 70);
allRight.addSelectHandler(new SelectEvent.SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
onButtonAll(ADD_NEW);
}
});
right.addSelectHandler(new SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
onButtonOne(ADD_NEW);
}
});
left.addSelectHandler(new SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
onButtonOne(!ADD_NEW);
}
});
allLeft.addSelectHandler(new SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
onButtonAll(!ADD_NEW);
}
});
VerticalPanel arrowsButtonBar;
arrowsButtonBar = new VerticalPanel();
arrowsButtonBar.getElement().getStyle().setProperty("margin", "1px");
arrowsButtonBar.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
arrowsButtonBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
arrowsButtonBar.setVisible(true);
arrowsButtonBar.setPixelSize(100, 150);
arrowsButtonBar.add(allRight);
arrowsButtonBar.add(right);
arrowsButtonBar.add(left);
arrowsButtonBar.add(allLeft);
DockPanel dockSaveAndCancel = new DockPanel();
dockSaveAndCancel.setPixelSize(width, 50);
dockSaveAndCancel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
dockSaveAndCancel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
dockSaveAndCancel.setSpacing(5);
dockSaveAndCancel.add(getDefaultButtonBar(), DockPanel.EAST);
dockSaveAndCancel.add(new Label(""), DockPanel.CENTER);
gridStorageL = new Grid<TagDto>(storeFrom, createColumnList(props, "Available tags"));
gridStorageL.setBorders(true);
gridStorageL.getView().setForceFit(true);
gridStorageR = new Grid<TagDto>(storeTo, createColumnList(props, "Session's tags"));
gridStorageR.setBorders(true);
gridStorageR.getView().setForceFit(true);
new GridDragSource<TagDto>(gridStorageL);
new GridDragSource<TagDto>(gridStorageR);
new GridDropTarget<TagDto>(gridStorageL).addDropHandler(new DndDropEvent.DndDropHandler() {
@Override
public void onDrop(DndDropEvent dndDropEvent) {
descriptionPanel.setText(DEFAULT_TITLE);
}
});
new GridDropTarget<TagDto>(gridStorageR).addDropHandler(new DndDropEvent.DndDropHandler() {
@Override
public void onDrop(DndDropEvent dndDropEvent) {
descriptionPanel.setText(DEFAULT_TITLE);
}
});
gridStorageL.setPixelSize(250, 380);
gridStorageR.setPixelSize(250, 380);
DockPanel dockGridsAndButtons = new DockPanel();
dockGridsAndButtons.setPixelSize(width, 390);
dockGridsAndButtons.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
dockGridsAndButtons.add(gridStorageL, DockPanel.WEST);
dockGridsAndButtons.add(arrowsButtonBar, DockPanel.CENTER);
dockGridsAndButtons.add(gridStorageR, DockPanel.EAST);
gridStorageL.addRowMouseDownHandler(new RowMouseDownEvent.RowMouseDownHandler() {
@Override
public void onRowMouseDown(RowMouseDownEvent rowMouseDownEvent) {
descriptionPanel.setText(gridStorageL.getStore().get(rowMouseDownEvent.getRowIndex()).getDescription());
gridStorageR.getSelectionModel().deselectAll();
}
});
gridStorageR.addRowMouseDownHandler(new RowMouseDownEvent.RowMouseDownHandler() {
@Override
public void onRowMouseDown(RowMouseDownEvent rowMouseDownEvent) {
descriptionPanel.setText(gridStorageR.getStore().get(rowMouseDownEvent.getRowIndex()).getDescription());
gridStorageL.getSelectionModel().deselectAll();
}
});
if (gridStorageR.getSelectionModel().getSelectedItems().isEmpty() ||
gridStorageL.getSelectionModel().getSelectedItems().isEmpty())
descriptionPanel.setText(DEFAULT_TITLE);
VerticalPanel descriptionShell = new VerticalPanel();
descriptionShell.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
descriptionShell.add(descriptionPanel);
descriptionShell.setPixelSize(width, 30);
descriptionPanel.setReadOnly(true);
VerticalPanel mainPanel;
mainPanel = new VerticalPanel();
mainPanel.setPixelSize(width, height);
mainPanel.add(dockGridsAndButtons);
mainPanel.add(descriptionShell);
mainPanel.add(dockSaveAndCancel);
setAutoHideEnabled(true);
addCloseHandler(new CloseHandler<PopupPanel>() {
@Override
public void onClose(CloseEvent<PopupPanel> popupPanelCloseEvent) {
atClose();
}
});
add(mainPanel);
}
public void setTreeGrid(TreeGrid<SessionComparisonPanel.TreeItem> treeGrid) {
this.treeGrid = treeGrid;
}
public void popUpForEdit(SessionDataDto currentSession, SessionComparisonPanel.TreeItem item, List<TagDto> allTags) {
if (currentSession == null) {
new ExceptionPanel("The session data has a value null. The session's id is wrong.");
}
getApplyButton().removeFromParent();
this.currentSession = currentSession;
setText("Session " + currentSession.getSessionId());
setGrids(allTags, currentSession.getTags());
currentTreeItem = item;
show();
}
private Set<String> tagNamesSet;
public void popUpForFilter(List<TagDto> allTags, Set<String> sessionTags) {
getSaveButton().removeFromParent();
tagNamesSet = sessionTags;
setText("Session filter by tags");
setGrids(allTags);
show();
}
private ColumnModel<TagDto> createColumnList(TagDtoProperties props, String columnName) {
ColumnConfig<TagDto, String> cc1 = new ColumnConfig<TagDto, String>(props.descriptionProp());
cc1.setHeader(SafeHtmlUtils.fromString(columnName));
cc1.setFixed(true);
cc1.setMenuDisabled(true);
cc1.setWidth(250);
List<ColumnConfig<TagDto, ?>> l = new ArrayList<ColumnConfig<TagDto, ?>>();
l.add(cc1);
return new ColumnModel<TagDto>(l);
}
@Override
protected void onSaveButtonClick() {
treeGrid.getTreeView().refresh(false);
saveTagToDataBase();
}
@Override
protected void onApplyButtonClick() {
tagNamesSet.clear();
for (int i = 0; i < storeTo.size(); i++) {
tagNamesSet.add(storeTo.get(i).getName());
}
atClose();
}
@Override
protected void onCancelButtonClick() {
atClose();
}
private void onButtonOne(boolean action) {
if (action) {
move(gridStorageL, gridStorageR);
} else {
move(gridStorageR, gridStorageL);
}
}
private void move(Grid<TagDto> gridFrom, Grid<TagDto> gridTo) {
if (gridFrom.getSelectionModel().getSelectedItems().isEmpty())
return;
List<TagDto> selectedList = gridFrom.getSelectionModel().getSelectedItems();
gridFrom.getSelectionModel().selectNext(false);
descriptionPanel.setText(gridFrom.getSelectionModel().getSelectedItem().getDescription());
gridTo.getSelectionModel().deselectAll();
gridTo.getStore().addAll(selectedList);
for (int i = 0; i < selectedList.size(); i++) {
gridFrom.getStore().remove(selectedList.get(i));
}
}
private void moveAll(Grid<TagDto> gridFrom, Grid<TagDto> gridTo) {
gridTo.getStore().addAll(gridFrom.getStore().getAll());
gridFrom.getStore().clear();
descriptionPanel.setText(DEFAULT_TITLE);
}
private void onButtonAll(boolean action) {
if (action) {
moveAll(gridStorageL, gridStorageR);
} else {
moveAll(gridStorageR, gridStorageL);
}
}
public void setGrids(List<TagDto> allTags, List<TagDto> sessionTags) {
gridStorageL.getStore().addAll(allTags);
gridStorageR.getStore().addAll(sessionTags);
for (TagDto tag : allTags) {
for (int i = 0; i < gridStorageR.getStore().size(); i++) {
if (gridStorageR.getStore().get(i).equals(tag))
gridStorageL.getStore().remove(tag);
}
}
}
public void setGrids(List<TagDto> allTags) {
gridStorageL.getStore().addAll(allTags);
}
private void saveTagToDataBase() {
final List<TagDto> list = new ArrayList<TagDto>();
list.addAll(gridStorageR.getStore().getAll());
SessionDataService.Async.getInstance().saveTags(currentSession.getId(), list, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
new ExceptionPanel("Fail to save into DB session's tags : " + caught.getMessage());
atClose();
}
@Override
public void onSuccess(Void result) {
String tags = "";
for (int i = 0; i < storeTo.size(); i++) {
if (i == storeTo.size() - 1)
tags += storeTo.get(i).getName();
else
tags += storeTo.get(i).getName() + ", ";
}
currentTreeItem.put(getText(), tags);
currentSession.setTags(list);
treeGrid.getTreeView().refresh(false);
atClose();
}
});
}
private void buttonInitialization() {
allRight = new TextButton(">>>");
allRight.setPixelSize(40, 15);
right = new TextButton(">");
right.setPixelSize(40, 15);
left = new TextButton("<");
left.setPixelSize(40, 15);
allLeft = new TextButton("<<<");
allLeft.setPixelSize(40, 15);
}
private void atClose() {
gridStorageL.getStore().clear();
gridStorageR.getStore().clear();
descriptionPanel.setText(DEFAULT_TITLE);
hide();
}
}