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.ui.contentapp.browser;
35  
36  import info.magnolia.ui.api.app.SubAppContext;
37  import info.magnolia.ui.contentapp.ContentBrowserSubApp;
38  import info.magnolia.ui.contentapp.browser.actions.ActionbarView;
39  import info.magnolia.ui.contentapp.browser.context.LocationContext;
40  import info.magnolia.ui.contentapp.browser.context.ValueContext;
41  import info.magnolia.ui.contentapp.configuration.BrowserDescriptor;
42  import info.magnolia.ui.contentapp.configuration.WorkbenchDefinition;
43  import info.magnolia.ui.framework.ContextProperty;
44  import info.magnolia.ui.framework.UiFrameworkView;
45  import info.magnolia.ui.framework.ViewDefinition;
46  import info.magnolia.ui.framework.datasource.components.ItemResolver;
47  import info.magnolia.ui.framework.datasource.definition.DatasourceDefinition;
48  
49  import java.util.Collection;
50  import java.util.Objects;
51  import java.util.Optional;
52  
53  import javax.inject.Inject;
54  
55  import com.vaadin.ui.Composite;
56  import com.vaadin.ui.HorizontalLayout;
57  import com.vaadin.ui.VerticalLayout;
58  
59  /**
60   * View part of the new browser sub-app.
61   *
62   * @param <T> item type.
63   * @param <DS> data source definition type.
64   */
65  public class Browser<T, DS extends DatasourceDefinition> extends Composite implements UiFrameworkView {
66  
67      private final ContextProperty<ContentBrowserSubApp.BrowserLocation> location;
68      private final SubAppContext subAppContext;
69      private final ItemResolver<T> itemResolver;
70  
71      @Inject
72      public Browser(
73              ValueContext<T> valueContext,
74              LocationContext locationContext,
75              BrowserDescriptor<T, DS> descriptor,
76              SubAppContext subAppContext,
77              ItemResolver<T> itemResolver) {
78          this.subAppContext = subAppContext;
79          this.itemResolver = itemResolver;
80          this.location = locationContext.location();
81  
82          valueContext.observe(selectedItems ->
83                  location.mutate(location ->
84                          pushItemPathIntoLocation(selectedItems, location)
85                  )
86          );
87  
88          location.observe(locationOptional ->
89                  locationOptional.ifPresent(location -> {
90                      Optional<String> currentPath = valueContext.getSingle().map(itemResolver::getPath);
91                      if (currentPath.map(path -> !Objects.equals(path, location.getNodePath())).orElse(true)) {
92                          itemResolver.getItemByPath(location.getNodePath()).ifPresent(valueContext::set);
93                      }
94                  }));
95  
96          layout(descriptor);
97      }
98  
99      private void pushItemPathIntoLocation(Collection<T> selectedItems, ContentBrowserSubApp.BrowserLocation location) {
100         location.updateNodePath(selectedItems.stream().findFirst().map(itemResolver::getPath).orElse(""));
101         updateLocation(location);
102     }
103 
104     private void updateLocation(ContentBrowserSubApp.BrowserLocation location) {
105         subAppContext.getAppContext().updateSubAppLocation(subAppContext, location);
106     }
107 
108     private void layout(BrowserDescriptor<T, DS> descriptor) {
109         final HorizontalLayout workbenchWrapper = new HorizontalLayout();
110         workbenchWrapper.setSizeFull();
111 
112         WorkbenchDefinition<T> workbenchDefinition = descriptor.getWorkbench();
113         Workbench<T> workbench = create("workbench", workbenchDefinition);
114 
115         workbench.onContentViewTypeChange(viewId -> location.mutate(location -> location.updateViewType(viewId)));
116         workbench.setTitle(descriptor.getLabel());
117 
118         workbenchWrapper.addComponentsAndExpand(workbench);
119         workbenchWrapper.addComponents(create("actionbar", ActionbarView.class, descriptor.getActionbar()));
120 
121         StatusBar<T> statusBar = create(
122                 ViewDefinition.<StatusBar<T>>builder()
123                         .withName("statusbar")
124                         .withImplementationClass(StatusBar.class)
125                         .build());
126 
127         VerticalLayout browser = new VerticalLayout(workbenchWrapper, statusBar.asVaadinComponent());
128         browser.setSizeFull();
129         browser.setSpacing(false);
130         browser.setMargin(false);
131         browser.setExpandRatio(workbenchWrapper, 1f);
132         browser.setExpandRatio(statusBar.asVaadinComponent(), 0);
133         browser.addStyleName("browser");
134 
135         setCompositionRoot(browser);
136         setSizeFull();
137     }
138 
139     public void setLocation(ContentBrowserSubApp.BrowserLocation location) {
140         this.location.set(location);
141     }
142 }