package au.com.vaadinutils.dashboard;
import java.util.Iterator;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.vaadin.alump.gridstack.GridStackLayoutNoJQuery;
import org.vaadin.sliderpanel.SliderPanel;
import org.vaadin.sliderpanel.SliderPanelBuilder;
import org.vaadin.sliderpanel.SliderPanelStyles;
import org.vaadin.sliderpanel.client.SliderMode;
import org.vaadin.sliderpanel.client.SliderTabPosition;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import au.com.vaadinutils.dao.EntityManagerProvider;
import au.com.vaadinutils.dao.JpaBaseDao;
import au.com.vaadinutils.dao.JpaDslBuilder;
import au.com.vaadinutils.editors.InputFormDialog;
import au.com.vaadinutils.editors.InputFormDialogRecipient;
import au.com.vaadinutils.js.JSCallWithReturnValue;
import au.com.vaadinutils.js.JavaScriptCallback;
/** A start view for navigating to the main view */
public abstract class DashBoardView extends VerticalLayout implements View
{
private static final long serialVersionUID = 1L;
Logger logger = LogManager.getLogger();
private GridStackLayoutNoJQuery dashBoard;
private ListSelect dashBoardSelector;
private BeanItemContainer<Tblportallayout> container;
private SliderPanel dashboardsSlider;
UI ui = UI.getCurrent();
private boolean loadJQuery;
private VerticalLayout toolbarHolder;
private String style;
private boolean loading = false;
Panel dashBoardHolderPanel = new Panel();
protected DashBoardView(boolean loadJQuery, String style)
{
this.loadJQuery = loadJQuery;
if (style == null)
{
this.style = SliderPanelStyles.COLOR_GREEN;
}
this.style = style;
}
public void closeToolBar()
{
dashboardsSlider.collapse();
}
@Override
public void enter(ViewChangeEvent event)
{
setMargin(new MarginInfo(false, false, false, false));
setSizeFull();
final Label preparing = new Label("Preparing your dashboard...");
preparing.setStyleName(ValoTheme.LABEL_H1);
addComponent(preparing);
// defer the load of the dashboard to a separate request, otherwise on a
// refresh(F5) it will be blank. I think this is due to the DashBoard
// widget needing to be initialized (client side) first
new JSCallWithReturnValue("true").callBoolean(new JavaScriptCallback<Boolean>()
{
@Override
public void callback(Boolean value)
{
final UI ui = UI.getCurrent();
new Thread(getLoadRunner(preparing, ui), "Dash Board Delayed Loader").start();
}
private Runnable getLoadRunner(final Label preparing, final UI ui)
{
return new Runnable()
{
@Override
public void run()
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e1)
{
logger.error(e1);
}
try (AutoCloseable closer = EntityManagerProvider.setThreadLocalEntityManagerTryWithResources())
{
ui.access(new Runnable()
{
@Override
public void run()
{
removeComponent(preparing);
postLoad();
}
});
}
catch (Exception e)
{
logger.error(e, e);
}
}
};
}
});
}
void postLoad()
{
VerticalLayout sliderHolder = new VerticalLayout();
sliderHolder.setWidth("80%");
sliderHolder.setHeight("40");
addComponent(sliderHolder);
setComponentAlignment(sliderHolder, Alignment.TOP_CENTER);
dashboardsSlider = new SliderPanelBuilder(dashboardPanels()).expanded(false).mode(SliderMode.TOP)
.tabPosition(SliderTabPosition.MIDDLE).style(style).caption("Dashboards").animationDuration(400)
.tabSize(30).autoCollapseSlider(true).build();
sliderHolder.addComponent(dashboardsSlider);
Tblportallayout portalLayout = findDefaultPortal();
createDashboard(portalLayout);
dashBoardSelector.select(portalLayout);
dashBoardHolderPanel.setSizeFull();
addComponent(dashBoardHolderPanel);
setExpandRatio(dashBoardHolderPanel, 1);
}
void createDashboard(Tblportallayout portalLayout)
{
if (portalLayout == null)
{
portalLayout = new Tblportallayout();
portalLayout.setName("Dashboard " + (getNumberOfPortals() + 1));
portalLayout.setAccount(getAccountId());
EntityManagerProvider.persist(portalLayout);
container.addBean(portalLayout);
}
if (loadJQuery)
{
dashBoard = new DashBoard();
}
else
{
dashBoard = new DashBoardNoJQuery();
}
// this wrapper is necessary so the portals in the dashboard resize
// correctly
VerticalLayout wrapper = new VerticalLayout();
wrapper.setSizeFull();
wrapper.addComponent(dashBoard);
dashBoard.setSizeFull();
dashBoardHolderPanel.setContent(wrapper);
AbstractLayout dashboardToolBar = createToolBar(new DashBoardController(dashBoard), portalLayout.getGuid());
toolbarHolder.removeAllComponents();
toolbarHolder.addComponent(dashboardToolBar);
loading = true;
dashBoardSelector.setValue(portalLayout);
loadDashboard(portalLayout, new DashBoardController(dashBoard));
loading = false;
dashboardsSlider.setCaption(portalLayout.getName());
}
public abstract AbstractLayout createToolBar(DashBoardController dashBoard2, String guid);
public abstract Long getAccountId();
private Component dashboardPanels()
{
HorizontalLayout layout = new HorizontalLayout();
layout.setMargin(true);
layout.setSpacing(true);
Component dashboardManagement = dashboardManagement();
layout.addComponent(dashboardManagement);
layout.setComponentAlignment(dashboardManagement, Alignment.TOP_CENTER);
toolbarHolder = new VerticalLayout();
layout.addComponent(toolbarHolder);
layout.setComponentAlignment(toolbarHolder, Alignment.TOP_CENTER);
return layout;
}
private Component dashboardManagement()
{
VerticalLayout layout = new VerticalLayout();
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setWidth("100%");
Button newDashboard = new Button(FontAwesome.PLUS);
newDashboard.setDescription("New Dashboard");
newDashboard.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
newDashboard.addStyleName(ValoTheme.BUTTON_FRIENDLY);
Button rename = createRenameButton();
Button copy = new Button(FontAwesome.COPY);
copy.setDescription("Copy");
copy.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
Button share = new Button(FontAwesome.SHARE);
share.setDescription("Share");
share.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
Button defaultButton = new Button(FontAwesome.STAR);
defaultButton.setDescription("Default");
defaultButton.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
newDashboard.addClickListener(new ClickListener()
{
private static final long serialVersionUID = -609738416141590613L;
@Override
public void buttonClick(ClickEvent event)
{
createDashboard(null);
}
});
buttonLayout.addComponent(newDashboard);
buttonLayout.addComponent(rename);
buttonLayout.addComponent(createMakeDefaultButton());
// buttonLayout.addComponent(copy);
// buttonLayout.addComponent(share);
createDashboardSelector();
buttonLayout.addComponent(createDeleteButton());
TabSheet selectorHolder = new TabSheet();
selectorHolder.addTab(layout, "Dashboards");
layout.addComponent(dashBoardSelector);
layout.setExpandRatio(dashBoardSelector, 1);
layout.addComponent(buttonLayout);
// layout.setSizeFull();
return selectorHolder;
}
private Button createRenameButton()
{
Button rename = new Button(FontAwesome.EDIT);
rename.setDescription("Rename Dashboard");
rename.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
rename.addClickListener(new ClickListener()
{
private static final long serialVersionUID = 1058348590862935257L;
@Override
public void buttonClick(ClickEvent event)
{
Tblportallayout portalLayout = (Tblportallayout) dashBoardSelector.getValue();
final TextField primaryFocusField = new TextField("New Dashboard Name");
AbstractLayout form = new FormLayout();
form.setSizeFull();
form.addComponent(primaryFocusField);
InputFormDialogRecipient recipient = new InputFormDialogRecipient()
{
@Override
public boolean onOK()
{
Tblportallayout portalLayout = (Tblportallayout) dashBoardSelector.getValue();
container.removeItem(portalLayout);
portalLayout = JpaBaseDao.getGenericDao(Tblportallayout.class).findById(portalLayout.getId());
portalLayout.setName(primaryFocusField.getValue());
container.addBean(portalLayout);
dashBoardSelector.select(portalLayout);
dashboardsSlider.setCaption("Dashboards: " + portalLayout.getName());
return true;
}
@Override
public boolean onCancel()
{
return true;
}
};
InputFormDialog dialog = new InputFormDialog(UI.getCurrent(),
"Rename " + portalLayout.getName() + " to:", primaryFocusField, form, recipient);
}
});
return rename;
}
private Button createMakeDefaultButton()
{
Button rename = new Button(FontAwesome.STAR);
rename.setDescription("Make Default Dashboard");
rename.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
rename.addClickListener(new ClickListener()
{
private static final long serialVersionUID = 1058348590862935257L;
@Override
public void buttonClick(ClickEvent event)
{
// set all portals to not default
JpaDslBuilder<Tblportallayout> q = JpaBaseDao.getGenericDao(Tblportallayout.class).select();
List<Tblportallayout> portals = q.where(q.eq(Tblportallayout_.account, getAccountId())).getResultList();
for (Tblportallayout portal : portals)
{
portal.setDefault_(false);
}
// set selected portal to default
Tblportallayout portalLayout = (Tblportallayout) dashBoardSelector.getValue();
portalLayout = JpaBaseDao.getGenericDao(Tblportallayout.class).findById(portalLayout.getId());
portalLayout.setDefault_(true);
// load list and select and display portal
loadDashboardList();
dashBoardSelector.select(portalLayout);
dashboardsSlider.setCaption("Dashboards: " + portalLayout.getName());
}
});
return rename;
}
private Button createDeleteButton()
{
Button delete = new Button(FontAwesome.TRASH);
delete.setDescription("Delete Dashboard");
delete.setStyleName(ValoTheme.BUTTON_ICON_ONLY);
delete.addStyleName(ValoTheme.BUTTON_DANGER);
delete.addClickListener(new ClickListener()
{
private static final long serialVersionUID = 4136469280694751393L;
@Override
public void buttonClick(ClickEvent event)
{
Tblportallayout portalLayout = (Tblportallayout) dashBoardSelector.getValue();
dashBoardSelector.removeItem(portalLayout);
portalLayout = JpaBaseDao.getGenericDao(Tblportallayout.class).findById(portalLayout.getId());
EntityManagerProvider.remove(portalLayout);
final Iterator<?> iterator = dashBoardSelector.getContainerDataSource().getItemIds().iterator();
if (iterator.hasNext())
{
Tblportallayout next = (Tblportallayout) iterator.next();
dashBoardSelector.select(next);
}
else
{
createDashboard(null);
}
}
});
return delete;
}
private void createDashboardSelector()
{
dashBoardSelector = new ListSelect();
dashBoardSelector.setHeight("100%");
dashBoardSelector.setWidth("300");
// dashBoardSelector.setItemCaptionPropertyId(Tblportallayout_.name.getName());
// dashBoardSelector.setItemCaptionMode(ItemCaptionMode.PROPERTY);
container = new BeanItemContainer<>(Tblportallayout.class);
loadDashboardList();
dashBoardSelector.setContainerDataSource(container);
dashBoardSelector.setNullSelectionAllowed(false);
dashBoardSelector.addValueChangeListener(new ValueChangeListener()
{
private static final long serialVersionUID = 2850017605363067882L;
@Override
public void valueChange(ValueChangeEvent event)
{
if (!loading)
{
Tblportallayout portalLayout = (Tblportallayout) event.getProperty().getValue();
if (portalLayout != null)
{
portalLayout = JpaBaseDao.getGenericDao(Tblportallayout.class).findByEntityId(portalLayout);
createDashboard(portalLayout);
closeToolBar();
}
}
}
});
}
private void loadDashboardList()
{
Long account = getAccountId();
JpaDslBuilder<Tblportallayout> q = JpaBaseDao.getGenericDao(Tblportallayout.class).select();
List<Tblportallayout> layouts = q.where(q.eq(Tblportallayout_.account, account))
.orderBy(Tblportallayout_.default_, false).orderBy(Tblportallayout_.name, true).getResultList();
container.removeAllItems();
container.addAll(layouts);
}
private void loadDashboard(Tblportallayout portalLayout, DashBoardController dashBoard2)
{
logger.info("Load dash board");
for (Tblportal portal : portalLayout.getPortals())
{
try
{
PortalAdderIfc panel = getEnumFromType(portal.getType()).instancePortalAdder(portalLayout.getGuid());
panel.addPortal(dashBoard2, portal);
}
catch (Throwable e)
{
logger.error(e, e);
}
}
}
protected abstract PortalEnumIfc getEnumFromType(String type);
private Tblportallayout findDefaultPortal()
{
Long account = getAccountId();
JpaDslBuilder<Tblportallayout> q = JpaBaseDao.getGenericDao(Tblportallayout.class).select();
List<Tblportallayout> layouts = q.where(q.eq(Tblportallayout_.account, account))
.orderBy(Tblportallayout_.default_, false).orderBy(Tblportallayout_.name, true).getResultList();
if (layouts.size() == 0)
{
return null;
}
return layouts.get(0);
}
private long getNumberOfPortals()
{
Long account = getAccountId();
JpaDslBuilder<Tblportallayout> q = JpaBaseDao.getGenericDao(Tblportallayout.class).select();
return q.where(q.eq(Tblportallayout_.account, account)).count();
}
}