View Javadoc
1   /**
2    * This file Copyright (c) 2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.admincentral;
35  
36  import info.magnolia.event.EventBus;
37  import info.magnolia.icons.MagnoliaAppIcon;
38  import info.magnolia.icons.MagnoliaIcons;
39  import info.magnolia.ui.api.app.AppView;
40  import info.magnolia.ui.api.event.AdmincentralEventBus;
41  import info.magnolia.ui.api.shell.CloseAppEvent;
42  import info.magnolia.ui.api.view.View;
43  import info.magnolia.ui.vaadin.extension.CloseIcon;
44  
45  import javax.inject.Named;
46  
47  import org.apache.commons.lang3.StringUtils;
48  import org.slf4j.Logger;
49  import org.slf4j.LoggerFactory;
50  
51  import com.google.inject.Inject;
52  import com.vaadin.server.KeyMapper;
53  import com.vaadin.ui.Component;
54  import com.vaadin.ui.Label;
55  import com.vaadin.ui.TabSheet;
56  import com.vaadin.ui.themes.ValoTheme;
57  
58  /**
59   * The Admincentral app view consists of a plain Vaadin TabSheet component, where each sub-app turns into a new tab..
60   *
61   * @see info.magnolia.ui.api.app.AppView
62   */
63  public class AdmincentralAppView implements AppView {
64      private static final Logger log = LoggerFactory.getLogger(AdmincentralAppView.class);
65  
66      // TODO candidate for extraction to ResurfaceTheme constants
67      private static final String TABSHEET_APP = "app";
68  
69      private final TabSheet tabsheet;
70  
71      private Listener listener;
72      private KeyMapper<TabSheet.Tab> mapper = new KeyMapper<>();
73  
74      @Inject
75      public AdmincentralAppView(@Named(AdmincentralEventBus.NAME) EventBus eventBus) {
76          TabSheet tabsheet = new TabSheet();
77          tabsheet.setSizeFull();
78          tabsheet.addStyleNames(ValoTheme.TABSHEET_FRAMED, TABSHEET_APP);
79  
80          tabsheet.addSelectedTabChangeListener(event -> {
81              Component selectedTabContent = event.getTabSheet().getSelectedTab();
82              String instanceId = mapper.key(tabsheet.getTab(selectedTabContent));
83              log.debug("FOCUS " + instanceId);
84              listener.onFocus(instanceId);
85          });
86  
87          tabsheet.setCloseHandler((ts, tabContent) -> {
88              TabSheet.Tab tab = ts.getTab(tabContent);
89              String instanceId = mapper.key(tab);
90              log.debug("CLOSE " + instanceId);
91              // if close handler was set, then tabsheet should remove its tab manually
92              ts.removeTab(tab);
93              listener.onClose(instanceId);
94          });
95  
96          this.tabsheet = tabsheet;
97          CloseIcon.extend(this.tabsheet, () -> eventBus.fireEvent(new CloseAppEvent()));
98      }
99  
100     @Override
101     public String addSubAppView(View view, String caption, boolean closable) {
102         return addSubAppView(view, caption, "", closable);
103     }
104 
105     @Override
106     public String addSubAppView(View view, String caption, String icon, boolean closable) {
107         if (view == null) {
108             view = () -> new Label("No sub-app view to display");
109         }
110 
111         TabSheet.Tab tab = tabsheet.addTab(view.asVaadinComponent(), caption);
112         MagnoliaIcons.forCssClass(icon).ifPresent(tab::setIcon);
113 
114         tab.setClosable(closable);
115         tabsheet.setSelectedTab(tab);
116 
117         /* TODO check what for and evolve AppView contract */
118         return mapper.key(tab);
119     }
120 
121     @Override
122     public void setActiveSubAppView(String instanceId) {
123         tabsheet.setSelectedTab(mapper.get(instanceId));
124     }
125 
126     @Override
127     public String getActiveSubAppView() {
128         Component selectedTabContent = tabsheet.getSelectedTab();
129         return mapper.key(tabsheet.getTab(selectedTabContent));
130     }
131 
132     @Override
133     public void updateCaption(String instanceId, String caption) {
134         TabSheet.Tab tab = mapper.get(instanceId);
135         tab.setCaption(caption);
136     }
137 
138     @Override
139     public void setTheme(String themeName) {
140         // TODO port app themes
141     }
142 
143     @Override
144     public void setListener(Listener listener) {
145         this.listener = listener;
146     }
147 
148     @Override
149     public View getSubAppViewContainer(String instanceId) {
150         TabSheet.Tab tab = mapper.get(instanceId);
151         return tab::getComponent;
152     }
153 
154     @Override
155     public void closeSubAppView(String instanceId) {
156         TabSheet.Tab tab = mapper.get(instanceId);
157         tabsheet.removeTab(tab);
158     }
159 
160     @Override
161     public void setAppLogo(String logo) {
162         TabSheet.Tab mainTab = tabsheet.getTab(0);
163         MagnoliaAppIcon.forName(logo)
164                 .or(MagnoliaIcons::forCssClass)
165                 .or(MagnoliaIcons.APP)
166                 .ifPresent(mainTab::setIcon);
167     }
168 
169     @Override
170     public void setAppLogo(String logo, String bgcolor) {
171         setAppLogo(logo);
172     }
173 
174     // TODO Deprecate?
175     @Override
176     public void setAppName(String appName) {
177         TabSheet.Tab tab = tabsheet.getTab(0);
178         if (tab != null && StringUtils.isEmpty(tab.getCaption())) {
179             tab.setCaption(appName);
180         }
181     }
182 
183     @Override
184     public void setTabCaptionsAsHtml() {
185         tabsheet.setTabCaptionsAsHtml(true);
186     }
187 
188     @Override
189     public TabSheet asVaadinComponent() {
190         return tabsheet;
191     }
192 }