package fr.openwide.maven.artifact.notifier.web.application.common.template;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.TransparentWebMarkupContainer;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import com.google.common.collect.Lists;
import fr.openwide.core.wicket.behavior.ClassAttributeAppender;
import fr.openwide.core.wicket.more.markup.html.feedback.AnimatedGlobalFeedbackPanel;
import fr.openwide.core.wicket.more.markup.html.template.AbstractWebPageTemplate;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.analytics.GoogleAnalyticsBehavior;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.dropdown.BootstrapDropdownBehavior;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.popover.BootstrapPopoverBehavior;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.popover.BootstrapPopoverOptions;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.popover.PopoverPlacement;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.tooltip.BootstrapTooltip;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.tooltip.BootstrapTooltipDocumentBehavior;
import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.scrolltotop.ScrollToTopBehavior;
import fr.openwide.core.wicket.more.markup.html.template.model.BreadCrumbElement;
import fr.openwide.core.wicket.more.markup.html.template.model.NavigationMenuItem;
import fr.openwide.core.wicket.more.security.page.LogoutPage;
import fr.openwide.maven.artifact.notifier.core.business.user.model.User;
import fr.openwide.maven.artifact.notifier.core.config.application.MavenArtifactNotifierConfigurer;
import fr.openwide.maven.artifact.notifier.web.application.MavenArtifactNotifierApplication;
import fr.openwide.maven.artifact.notifier.web.application.MavenArtifactNotifierSession;
import fr.openwide.maven.artifact.notifier.web.application.administration.page.AdministrationArtifactPortfolioPage;
import fr.openwide.maven.artifact.notifier.web.application.artifact.page.ArtifactPomSearchPage;
import fr.openwide.maven.artifact.notifier.web.application.artifact.page.ArtifactSearchPage;
import fr.openwide.maven.artifact.notifier.web.application.common.component.FooterPanel;
import fr.openwide.maven.artifact.notifier.web.application.common.component.IdentificationPopoverPanel;
import fr.openwide.maven.artifact.notifier.web.application.common.component.navigation.MavenArtifactNotifierBodyBreadCrumbPanel;
import fr.openwide.maven.artifact.notifier.web.application.common.template.styles.StylesLessCssResourceReference;
import fr.openwide.maven.artifact.notifier.web.application.navigation.page.DashboardPage;
import fr.openwide.maven.artifact.notifier.web.application.navigation.page.HomePage;
import fr.openwide.maven.artifact.notifier.web.application.navigation.page.ViewProfilePage;
import fr.openwide.maven.artifact.notifier.web.application.project.page.ProjectListPage;
public abstract class MainTemplate extends AbstractWebPageTemplate {
private static final long serialVersionUID = -1312989780696228848L;
@SpringBean
private MavenArtifactNotifierConfigurer configurer;
private List<String> bodyCssClasses = Lists.newArrayList();
public MainTemplate(PageParameters parameters) {
super(parameters);
MarkupContainer htmlRootElement = new TransparentWebMarkupContainer("htmlRootElement");
htmlRootElement.add(AttributeAppender.append("lang", MavenArtifactNotifierSession.get().getLocale().getLanguage()));
add(htmlRootElement);
MarkupContainer bodyElement = new TransparentWebMarkupContainer("bodyElement");
bodyElement.add(new ClassAttributeAppender(new LoadableDetachableModel<String>() {
private static final long serialVersionUID = 1L;
@Override
protected String load() {
StringBuilder cssClassesSb = new StringBuilder();
for (String cssClasse : bodyCssClasses) {
cssClassesSb.append(cssClasse).append(" ");
}
return cssClassesSb.toString();
}
}));
add(bodyElement);
add(new AnimatedGlobalFeedbackPanel("animatedGlobalFeedbackPanel"));
addHeadPageTitlePrependedElement(new BreadCrumbElement(new ResourceModel("common.rootPageTitle")));
add(createHeadPageTitle("headPageTitle"));
Link<Void> homePageLink = MavenArtifactNotifierApplication.get().getHomePageLinkDescriptor().link("homePageLink");
if (HomePage.class.equals(getClass())) {
homePageLink.setBeforeDisabledLink("");
homePageLink.setAfterDisabledLink("");
homePageLink.setEnabled(false);
} else {
homePageLink.add(new AttributeAppender("title", new ResourceModel("navigation.backToHome")));
}
add(homePageLink);
// Bread crumb
add(createBodyBreadCrumb("breadCrumb"));
// Main navigation bar
add(new ListView<NavigationMenuItem>("mainNav", getMainNav()) {
private static final long serialVersionUID = -2257358650754295013L;
@Override
protected void populateItem(ListItem<NavigationMenuItem> item) {
NavigationMenuItem navItem = item.getModelObject();
AbstractLink navLink = navItem.link("navLink");
navLink.add(new Label("navLabel", navItem.getLabelModel()));
item.setVisible(navItem.isAccessible());
if (navItem.isActive(MainTemplate.this.getFirstMenuPage())) {
item.add(new ClassAttributeAppender("active"));
}
item.add(navLink);
// Dropdown
List<NavigationMenuItem> subMenuItems = navItem.getSubMenuItems();
WebMarkupContainer caret = new WebMarkupContainer("caret");
navLink.add(caret);
WebMarkupContainer dropdownMenu = new ListView<NavigationMenuItem>("dropdownMenu", subMenuItems) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<NavigationMenuItem> subMenuItem) {
NavigationMenuItem subMenu = subMenuItem.getModelObject();
AbstractLink navLink = subMenu.link("subMenuLink");
navLink.add(new Label("subMenuLabel", subMenu.getLabelModel()));
subMenuItem.setVisible(subMenu.isAccessible());
subMenuItem.add(navLink);
}
};
item.add(dropdownMenu);
if (!subMenuItems.isEmpty()) {
item.add(new ClassAttributeAppender("dropdown"));
navLink.add(new ClassAttributeAppender("dropdown-toggle"));
navLink.add(new AttributeAppender("data-toggle", "dropdown"));
navLink.add(new AttributeModifier("href", "#"));
caret.setVisible(true);
dropdownMenu.setVisible(true);
} else {
caret.setVisible(false);
dropdownMenu.setVisible(false);
}
}
});
// Second level navigation bar
add(new ListView<NavigationMenuItem>("subNav", getSubNav()) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<NavigationMenuItem> item) {
NavigationMenuItem navItem = item.getModelObject();
AbstractLink navLink = navItem.link("navLink");
navLink.add(new Label("navLabel", navItem.getLabelModel()));
item.setVisible(navItem.isAccessible());
if (navItem.isActive(MainTemplate.this.getSecondMenuPage())) {
item.add(new ClassAttributeAppender("active"));
}
item.add(navLink);
}
@Override
protected void onConfigure() {
super.onConfigure();
List<NavigationMenuItem> navigationMenuItems = getModelObject();
setVisible(navigationMenuItems != null && !navigationMenuItems.isEmpty());
}
});
// User menu
IModel<String> userDisplayNameModel = new LoadableDetachableModel<String>() {
private static final long serialVersionUID = 1L;
@Override
protected String load() {
String userDisplayName = null;
User user = MavenArtifactNotifierSession.get().getUser();
if (user != null) {
userDisplayName = user.getDisplayName();
}
return userDisplayName;
}
};
WebMarkupContainer userMenuContainer = new WebMarkupContainer("userMenuContainer", userDisplayNameModel) {
private static final long serialVersionUID = 1L;
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(getDefaultModelObject() != null);
}
};
add(userMenuContainer);
Link<Void> viewProfileLink = new BookmarkablePageLink<Void>("viewProfileLink", ViewProfilePage.class);
viewProfileLink.add(new Label("userDisplayName", userDisplayNameModel));
userMenuContainer.add(viewProfileLink);
userMenuContainer.add(new BookmarkablePageLink<Void>("logoutLink", LogoutPage.class));
// Navigation bar right part
// > Sign in
Button signIn = new Button("signIn") {
private static final long serialVersionUID = 1L;
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(!AuthenticatedWebSession.exists() || !AuthenticatedWebSession.get().isSignedIn());
}
};
add(signIn);
IdentificationPopoverPanel identificationPopoverPanel = new IdentificationPopoverPanel("identificationPopoverPanel");
add(identificationPopoverPanel);
BootstrapPopoverOptions popoverOptions = new BootstrapPopoverOptions();
popoverOptions.setTitleText(new ResourceModel("navigation.signIn").getObject());
popoverOptions.setContentComponent(identificationPopoverPanel);
popoverOptions.setPlacement(PopoverPlacement.BOTTOM);
popoverOptions.setHtml(true);
popoverOptions.setContainer(".navbar");
signIn.add(new BootstrapPopoverBehavior(popoverOptions));
signIn.add(new ClassAttributeAppender(Model.of("popover-btn")));
// Footer
add(new FooterPanel("footer"));
// Tooltip
add(new BootstrapTooltipDocumentBehavior(getBootstrapTooltip()));
// Dropdown
add(new BootstrapDropdownBehavior());
// Scroll to top
WebMarkupContainer scrollToTop = new WebMarkupContainer("scrollToTop");
scrollToTop.add(new ScrollToTopBehavior());
add(scrollToTop);
// Google Analytics
add(new GoogleAnalyticsBehavior(configurer.getGoogleAnalyticsTrackingId()));
}
protected List<NavigationMenuItem> getMainNav() {
List<NavigationMenuItem> mainNav = Lists.newArrayList();
mainNav.add(DashboardPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.dashboard")));
NavigationMenuItem searchMenuItem = ArtifactSearchPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.search"));
searchMenuItem.addSubMenuItem(ArtifactPomSearchPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.search.pom")));
searchMenuItem.addSubMenuItem(ArtifactSearchPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.search.mavenCentral")));
mainNav.add(searchMenuItem);
mainNav.add(ProjectListPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.projects")));
mainNav.add(ViewProfilePage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.viewProfile")));
mainNav.add(AdministrationArtifactPortfolioPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.administration")));
return mainNav;
}
protected void addBodyCssClass(String cssClass) {
bodyCssClasses.add(cssClass);
}
protected List<NavigationMenuItem> getSubNav() {
return Lists.newArrayList();
}
public static BootstrapTooltip getBootstrapTooltip() {
BootstrapTooltip bootstrapTooltip = new BootstrapTooltip();
bootstrapTooltip.setSelector("[title],[data-original-title]");
bootstrapTooltip.setAnimation(true);
bootstrapTooltip.setPlacement(BootstrapTooltip.Placement.BOTTOM);
bootstrapTooltip.setContainer("body");
return bootstrapTooltip;
}
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(CssHeaderItem.forReference(StylesLessCssResourceReference.get()));
}
@Override
public String getVariation() {
return BOOTSTRAP3_VARIATION;
}
@Override
protected Component createBodyBreadCrumb(String wicketId) {
return new MavenArtifactNotifierBodyBreadCrumbPanel(wicketId, bodyBreadCrumbPrependedElementsModel, breadCrumbElementsModel)
.setDividerModel(Model.of(""))
.setTrailingSeparator(true);
}
@Override
protected Class<? extends WebPage> getSecondMenuPage() {
return null;
}
}