package org.ovirt.engine.ui.webadmin.widget.host;
import java.util.HashMap;
import java.util.Map;
import org.gwtbootstrap3.client.ui.Button;
import org.gwtbootstrap3.client.ui.Column;
import org.gwtbootstrap3.client.ui.Row;
import org.gwtbootstrap3.client.ui.constants.ColumnSize;
import org.gwtbootstrap3.client.ui.constants.IconType;
import org.ovirt.engine.ui.common.css.OvirtCss;
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.IntegerEntityModelLabel;
import org.ovirt.engine.ui.common.widget.renderer.StringRenderer;
import org.ovirt.engine.ui.common.widget.uicommon.popup.AbstractModelBoundPopupWidget;
import org.ovirt.engine.ui.uicommonweb.models.hosts.FenceAgentModel;
import org.ovirt.engine.ui.uicompat.external.StringUtils;
import org.ovirt.engine.ui.webadmin.ApplicationConstants;
import org.ovirt.engine.ui.webadmin.gin.AssetProvider;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasEnabled;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.Widget;
public class FenceAgentWidget extends AbstractModelBoundPopupWidget<FenceAgentModel>
implements HasValueChangeHandlers<FenceAgentModel>, HasEnabled {
interface Driver extends UiCommonEditorDriver<FenceAgentModel, FenceAgentWidget> {
}
public interface Style extends CssResource {
String highlightRow();
String fakeAnchor();
}
public interface WidgetUiBinder extends UiBinder<Widget, FenceAgentWidget> {
WidgetUiBinder uiBinder = GWT.create(WidgetUiBinder.class);
}
private final Driver driver = GWT.create(Driver.class);
private static final ApplicationConstants constants = AssetProvider.getConstants();
@UiField
PushButton editFenceAgent;
@UiField
Button up;
@UiField
Button down;
@UiField
@Path(value = "managementIp.entity")
Label agentLabel;
@UiField
@Ignore
Label concurrentGroupLabel;
@UiField
@Path(value = "order.entity")
IntegerEntityModelLabel orderLabel;
@UiField(provided = true)
@Path(value = "concurrentSelectList.selectedItem")
ListModelListBoxEditor<String> concurrentList;
@UiField
Column labelColumn;
@UiField
Column concurrentListColumn;
@UiField
FlowPanel concurrentPanel;
@UiField
Row topRow;
@UiField
Style style;
FenceAgentModel model;
private Map<FenceAgentModel, ClickHandler> removeConcurrentGroupClickHandlerMap = new HashMap<>();
public FenceAgentWidget() {
initEditors();
initWidget(WidgetUiBinder.uiBinder.createAndBindUi(this));
driver.initialize(this);
concurrentGroupLabel.setText(constants.concurrentAgentGroupLabel());
up.setIcon(IconType.ARROW_UP);
down.setIcon(IconType.ARROW_DOWN);
}
private void initEditors() {
concurrentList = new ListModelListBoxEditor<>(new StringRenderer<String>());
concurrentList.setUsePatternFly(true);
concurrentList.hideLabel();
}
@Override
public void edit(FenceAgentModel fenceAgentModel) {
if (this.model != null && fenceAgentModel != null && !fenceAgentModel.equals(this.model)) {
// Clean up the model.
driver.cleanup();
}
if (fenceAgentModel != null) {
driver.edit(fenceAgentModel);
this.model = fenceAgentModel;
determineLabelValue(fenceAgentModel);
fenceAgentModel.getManagementIp().getEntityChangedEvent().addListener((ev, sender, args) -> determineLabelValue(model));
fenceAgentModel.getConcurrentSelectList().getPropertyChangedEvent().addListener(
(ev, sender, args) -> {
if ("IsAvailable".equals(args.propertyName)) { //$NON-NLS-1$
determineLabelValue(model);
}
});
}
}
private void determineLabelValue(FenceAgentModel model) {
if (StringUtils.isEmpty(model.getManagementIp().getEntity())) {
showControls(false);
} else if (model.isInConcurrentGroup()) {
agentLabel.setVisible(false);
concurrentGroupLabel.setVisible(true);
topRow.addStyleName(style.highlightRow());
showControls(true);
showConcurrentGroup(model);
} else {
agentLabel.setVisible(true);
topRow.removeStyleName(style.highlightRow());
concurrentGroupLabel.setVisible(false);
agentLabel.setText(model.getDisplayString());
showControls(true);
}
}
private void showConcurrentGroup(FenceAgentModel model) {
editFenceAgent.setVisible(false);
FenceAgentConcurrentWidget concurrentWidget = new FenceAgentConcurrentWidget();
concurrentWidget.addRemoveConcurrentGroupClickHandler(removeConcurrentGroupClickHandlerMap.get(model));
concurrentWidget.edit(model);
concurrentPanel.add(concurrentWidget);
for (FenceAgentModel concurrentModel : model.getConcurrentList()) {
concurrentWidget = new FenceAgentConcurrentWidget();
concurrentWidget.addRemoveConcurrentGroupClickHandler(
removeConcurrentGroupClickHandlerMap.get(concurrentModel));
concurrentWidget.edit(concurrentModel);
concurrentPanel.add(concurrentWidget);
}
}
private void clearConcurrentGroup() {
concurrentPanel.clear();
}
private void showControls(boolean visible) {
clearConcurrentGroup();
editFenceAgent.setVisible(visible);
up.setVisible(visible);
down.setVisible(visible);
orderLabel.setVisible(visible);
concurrentListColumn.setVisible(model.getConcurrentSelectList().getIsAvailable()
&& !model.isInConcurrentGroup());
if (concurrentListColumn.isVisible()) {
labelColumn.setSize(ColumnSize.LG_5);
} else {
labelColumn.setSize(ColumnSize.LG_9);
}
}
@Override
public FenceAgentModel flush() {
return driver.flush();
}
@Override
public void cleanup() {
// Don't cleanup the model here as it will stop the edit dialog from opening twice, the model gets cleaned
// up when the host dialog closes.
}
@UiHandler("editFenceAgent")
void handleEditClick(ClickEvent event) {
edit();
}
@UiHandler("agentLabel")
void handleFenceNameClick(ClickEvent event) {
edit();
}
private void edit() {
if (isEnabled()) {
model.edit();
}
}
public void addUpClickHandler(ClickHandler handler) {
up.addClickHandler(handler);
}
public void addDownClickHandler(ClickHandler handler) {
down.addClickHandler(handler);
}
public void addRemoveConcurrentGroupClickHandler(FenceAgentModel model, ClickHandler handler) {
removeConcurrentGroupClickHandlerMap.put(model, handler);
}
/**
* Enabled or disable the 'up' button in the widget.
* @param value {@code true} to enable, {@code false} to disable
*/
public void enableUpButton(boolean value) {
up.setEnabled(value);
}
/**
* Enabled or disable the 'down' button in the widget.
* @param value {@code true} to enable, {@code false} to disable
*/
public void enableDownButton(boolean value) {
down.setEnabled(value);
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<FenceAgentModel> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
@Override
public boolean isEnabled() {
return editFenceAgent.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
concurrentList.setEnabled(enabled);
for (int i = 0; i < concurrentPanel.getWidgetCount(); i++) {
IsWidget widget = concurrentPanel.getWidget(i);
if (widget instanceof HasEnabled) {
((HasEnabled)widget).setEnabled(enabled);
}
}
editFenceAgent.setEnabled(enabled);
if (enabled) {
orderLabel.removeStyleName(OvirtCss.LABEL_DISABLED);
concurrentGroupLabel.removeStyleName(OvirtCss.LABEL_DISABLED);
agentLabel.removeStyleName(OvirtCss.LABEL_DISABLED);
agentLabel.addStyleName(style.fakeAnchor());
} else {
orderLabel.addStyleName(OvirtCss.LABEL_DISABLED);
concurrentGroupLabel.addStyleName(OvirtCss.LABEL_DISABLED);
agentLabel.addStyleName(OvirtCss.LABEL_DISABLED);
agentLabel.removeStyleName(style.fakeAnchor());
}
}
public void refresh() {
determineLabelValue(model);
}
}