/** * Copyright 2012 Universitat Pompeu Fabra. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package org.onexus.website.api.pages.browser; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.EmptyPanel; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.string.Strings; import org.onexus.website.api.Website; import org.onexus.website.api.events.EventAddFilter; import org.onexus.website.api.events.EventRemoveFilter; import org.onexus.website.api.events.EventTabSelected; import org.onexus.website.api.events.EventViewChange; import org.onexus.website.api.pages.Page; import org.onexus.website.api.pages.browser.layouts.leftmain.LeftMainLayout; import org.onexus.website.api.pages.browser.layouts.single.SingleLayout; import org.onexus.website.api.pages.browser.layouts.topleft.TopleftLayout; import org.onexus.website.api.pages.browser.layouts.topmain.TopmainLayout; import org.onexus.website.api.utils.visible.VisiblePredicate; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class BrowserPage extends Page<BrowserPageConfig, BrowserPageStatus> { public BrowserPage(String componentId, IModel<BrowserPageStatus> statusModel) { super(componentId, statusModel); onEventFireUpdate(EventTabSelected.class, EventAddFilter.class, EventRemoveFilter.class); add(new SelectionPanel("selection", statusModel)); onEventFireUpdate(EventViewChange.class); } protected boolean isCurrentTab(String tabId) { return tabId.equals(getStatus().getCurrentTabId()); } protected TabConfig getCurrentTab() { String currentTabId = getStatus().getCurrentTabId(); return getConfig().getTab(currentTabId); } @Override protected void onBeforeRender() { VisibleTabs visibleTabs = new VisibleTabs(); // Tabs can change when we fix/unfix entities addOrReplace(new ListView<TabGroup>("tabs", visibleTabs) { @Override protected void populateItem(ListItem<TabGroup> item) { TabGroup tabGroup = item.getModelObject(); if (tabGroup.hasSubMenu()) { WebMarkupContainer link = new WebMarkupContainer("link"); link.add(new AttributeModifier("class", "dropdown-toggle")); link.add(new AttributeModifier("data-toggle", "dropdown")); link.add(new AttributeModifier("href", "#")); if (tabGroup.containsTab(getStatus().getCurrentTabId())) { item.add(new AttributeModifier("class", "dropdown active")); TabConfig currentTab = getConfig().getTab(getStatus().getCurrentTabId()); String tabTitle = StringUtils.abbreviate(currentTab.getTitle(), 14); String currentLabel = "<div style=\"position:relative;\"><div style=\"white-space: nowrap; position:absolute; left:13px; top: 13px; font-size: 9px;\"><em>" + tabTitle + "</em></div></div>"; link.add(new Label("label", currentLabel + "<b class='caret'></b> " + tabGroup.getGroupLabel()).setEscapeModelStrings(false)); } else { item.add(new AttributeModifier("class", "dropdown")); link.add(new Label("label", "<b class='caret'></b> " + tabGroup.getGroupLabel()).setEscapeModelStrings(false)); } item.add(link); WebMarkupContainer submenu = new WebMarkupContainer("submenu"); submenu.add(new ListView<TabConfig>("item", tabGroup.getTabConfigs()) { @Override protected void populateItem(ListItem<TabConfig> item) { TabConfig tab = item.getModelObject(); BrowserPageLink<String> link = new BrowserPageLink<String>("link", Model.of(tab.getId())) { @Override public void onClick(AjaxRequestTarget target) { getStatus().setCurrentTabId(getModelObject()); sendEvent(EventTabSelected.EVENT); } }; if (!Strings.isEmpty(tab.getHelp())) { item.add(new AttributeModifier("rel", "tooltip")); item.add(new AttributeModifier("data-placement", "right")); item.add(new AttributeModifier("title", tab.getHelp())); } link.add(new Label("label", tab.getTitle())); item.add(link); if (isCurrentTab(tab.getId())) { item.add(new AttributeModifier("class", new Model<String>("active"))); } } }); item.add(submenu); } else { TabConfig tab = tabGroup.getTabConfigs().get(0); BrowserPageLink<String> link = new BrowserPageLink<String>("link", Model.of(tab.getId())) { @Override public void onClick(AjaxRequestTarget target) { getStatus().setCurrentTabId(getModelObject()); sendEvent(EventTabSelected.EVENT); } }; if (!Strings.isEmpty(tab.getHelp())) { link.add(new AttributeModifier("rel", "tooltip")); link.add(new AttributeModifier("title", tab.getHelp())); } link.add(new Label("label", tab.getTitle())); item.add(link); if (isCurrentTab(tab.getId())) { item.add(new AttributeModifier("class", new Model<String>("active"))); } item.add(new WebMarkupContainer("submenu").setVisible(false)); } } }); // Check if the current selected tab is visible. String currentTabId = getStatus().getCurrentTabId(); // Set a current tab if there is no one. if (currentTabId == null) { List<TabConfig> tabs = getConfig().getTabs(); if (tabs != null && !tabs.isEmpty()) { currentTabId = tabs.get(0).getId(); getStatus().setCurrentTabId(currentTabId); // Init currentPage //TODO This is not a good solution PageParameters pageParameters = getPage().getPageParameters(); pageParameters.set(Website.PARAMETER_CURRENT_PAGE, getConfig().getId()); pageParameters.set("ptab", currentTabId); setResponsePage(Website.class, pageParameters); } } List<TabGroup> tabs = visibleTabs.getObject(); boolean hiddenTab = true; for (TabGroup tab : tabs) { if (tab.containsTab(currentTabId)) { hiddenTab = false; } } if (hiddenTab && !tabs.isEmpty()) { TabConfig firstTab = tabs.get(0).getTabConfigs().get(0); getStatus().setCurrentTabId(firstTab.getId()); } List<String> views = new ArrayList<String>(); if (getCurrentTab().getViews() != null) { for (ViewConfig view : getCurrentTab().getViews()) { views.add(view.getTitle()); } } if (getStatus().getCurrentView() == null && views.size() > 0) { getStatus().setCurrentView(views.get(0)); } // Check that the current view is visible List<ViewConfig> filteredViews = new ArrayList<ViewConfig>(); VisiblePredicate predicate = new VisiblePredicate(getStatus().getORI().getParent(), getStatus().getEntitySelections()); CollectionUtils.select(getCurrentTab().getViews(), predicate, filteredViews); boolean visibleView = false; String currentView = getStatus().getCurrentView(); for (ViewConfig view : filteredViews) { if (view.getTitle().equals(currentView)) { visibleView = true; break; } } if (!visibleView) { getStatus().setCurrentView(filteredViews.get(0).getTitle()); } ViewConfig viewConfig = null; if (getCurrentTab().getViews() != null) { for (ViewConfig view : getCurrentTab().getViews()) { if (view.getTitle().equals(getStatus().getCurrentView())) { viewConfig = view; break; } } } if (viewConfig == null) { addOrReplace(new EmptyPanel("content")); } else { if (viewConfig.getLeft() != null && viewConfig.getTop() != null) { addOrReplace(new TopleftLayout("content", viewConfig, getModel())); } else if (viewConfig.getLeft() != null) { addOrReplace(new LeftMainLayout("content", viewConfig, getModel())); } else if (viewConfig.getTop() != null || viewConfig.getTopRight() != null) { addOrReplace(new TopmainLayout("content", viewConfig, getModel())); } else { addOrReplace(new SingleLayout("content", viewConfig, getModel())); } } boolean visible = !isEmbed(); get("selection").setVisible(visible); get("tabs").setVisible(visible); //TODO viewSelector.setVisible(visible && views.size() > 1); super.onBeforeRender(); } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); if (isEmbed()) { response.render(CssHeaderItem.forCSS("div.tab-row { display: none; }", "embed-browser-page")); } } private class VisibleTabs extends AbstractReadOnlyModel<List<TabGroup>> { @Override public List<TabGroup> getObject() { List<TabConfig> allTabs = getConfig().getTabs(); // A predicate that filters the visible views Predicate filter = new VisiblePredicate(getStatus().getORI().getParent(), getStatus().getEntitySelections()); // Return a new collection with only the visible tabs List<TabConfig> tabs = new ArrayList<TabConfig>(); CollectionUtils.select(allTabs, filter, tabs); // Tab groups List<TabGroup> tabGroups = new ArrayList<TabGroup>(); Map<String, TabGroup> subMenus = new HashMap<String, TabGroup>(); for (TabConfig tab : tabs) { if (tab.getGroup() == null) { tabGroups.add(new TabGroup(tab)); } else { TabGroup group; if (!subMenus.containsKey(tab.getGroup())) { group = new TabGroup(tab.getGroup()); subMenus.put(tab.getGroup(), group); tabGroups.add(group); } else { group = subMenus.get(tab.getGroup()); } group.add(tab); } } return tabGroups; } } private static class TabGroup implements Serializable { private String groupLabel; private List<TabConfig> tabConfigs = new ArrayList<TabConfig>(); public TabGroup(String groupLabel) { super(); this.groupLabel = groupLabel; } public TabGroup(TabConfig tab) { super(); this.groupLabel = null; this.tabConfigs.add(tab); } public boolean hasSubMenu() { return groupLabel != null; } public void add(TabConfig tabConfig) { tabConfigs.add(tabConfig); } public boolean containsTab(String tabId) { for (TabConfig tab : tabConfigs) { if (tab.getId().equals(tabId)) { return true; } } return false; } public String getGroupLabel() { return groupLabel; } public List<TabConfig> getTabConfigs() { return tabConfigs; } } }