1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.contentapp.browser;
35
36 import static java.util.stream.Collectors.toSet;
37
38 import info.magnolia.ui.api.app.SubAppContext;
39 import info.magnolia.ui.contentapp.ContentBrowserSubApp;
40 import info.magnolia.ui.contentapp.browser.actions.ActionbarView;
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.UIComponent;
45 import info.magnolia.ui.ValueContext;
46 import info.magnolia.ui.ViewDefinition;
47 import info.magnolia.ui.datasource.ItemResolver;
48 import info.magnolia.ui.datasource.DatasourceDefinition;
49 import info.magnolia.ui.observation.DatasourceObservation;
50
51 import java.util.Collection;
52 import java.util.Objects;
53 import java.util.Optional;
54
55 import javax.inject.Inject;
56
57 import org.apache.commons.lang3.StringUtils;
58
59 import com.vaadin.ui.Composite;
60 import com.vaadin.ui.HorizontalLayout;
61 import com.vaadin.ui.VerticalLayout;
62
63
64
65
66
67
68
69 public class Browser<T, DS extends DatasourceDefinition> extends Composite implements UIComponent {
70
71 private final ContextProperty<ContentBrowserSubApp.BrowserLocation> location;
72 private final SubAppContext subAppContext;
73 private final ItemResolver<T> itemResolver;
74
75 @Inject
76 public Browser(
77 ValueContext<T> valueContext,
78 ContentBrowserSubApp.LocationContext locationContext,
79 BrowserDescriptor<T, DS> descriptor,
80 DatasourceObservation observation,
81 ItemInteractionAvailability<T> interactionAvailability,
82 SubAppContext subAppContext,
83 ItemResolver<T> itemResolver) {
84 this.subAppContext = subAppContext;
85 this.itemResolver = itemResolver;
86 this.location = locationContext.location();
87
88 observation.register(() -> valueContext.current().update(currentValue -> {
89 return currentValue.stream().filter(interactionAvailability::isItemAvailable).collect(toSet());
90 }));
91
92 valueContext.observe(selectedItems -> {
93 if (!location.value().isPresent()) {
94 return;
95 }
96
97 location.update(location -> {
98 pushItemPathIntoLocation(selectedItems, location);
99 });
100 });
101
102 location.observe(locationOptional -> locationOptional.ifPresent(location -> {
103 Optional<String> currentPath = valueContext.getSingle().map(itemResolver::getId);
104 String newPath = location.getNodePath();
105 if (currentPath.map(path -> !Objects.equals(path, newPath)).orElse(StringUtils.isNotBlank(newPath))) {
106 itemResolver.getItemById(newPath).ifPresent(valueContext::set);
107 }
108 })
109 );
110
111 layout(descriptor);
112 }
113
114 private void pushItemPathIntoLocation(Collection<T> selectedItems, ContentBrowserSubApp.BrowserLocation location) {
115 location.updateNodePath(selectedItems.stream().findFirst().map(itemResolver::getId).orElse(""));
116 updateLocation(location);
117 }
118
119 private void updateLocation(ContentBrowserSubApp.BrowserLocation location) {
120 subAppContext.getAppContext().updateSubAppLocation(subAppContext, location);
121 }
122
123 void layout(BrowserDescriptor<T, DS> descriptor) {
124 final HorizontalLayout workbenchWrapper = new HorizontalLayout();
125 workbenchWrapper.setSizeFull();
126
127 WorkbenchDefinition<T> workbenchDefinition = descriptor.getWorkbench();
128 Workbench<T> workbench = create("workbench", workbenchDefinition);
129
130 workbench.onContentViewTypeChange(viewId -> location.update(location -> {
131 location.updateViewType(viewId);
132 }));
133
134 workbench.setTitle(descriptor.getLabel());
135
136 workbenchWrapper.addComponentsAndExpand(workbench);
137 workbenchWrapper.addComponents(create("actionbar", ActionbarView.class, descriptor.getActionbar()));
138
139 StatusBar<T> statusBar = create(
140 ViewDefinition.<StatusBar<T>>builder()
141 .withName("statusbar")
142 .withImplementationClass(StatusBar.class)
143 .build());
144
145 VerticalLayout browser = new VerticalLayout(workbenchWrapper, statusBar.asVaadinComponent());
146 browser.setSizeFull();
147 browser.setSpacing(false);
148 browser.setMargin(false);
149 browser.setExpandRatio(workbenchWrapper, 1f);
150 browser.setExpandRatio(statusBar.asVaadinComponent(), 0);
151 browser.addStyleName("browser");
152
153 setCompositionRoot(browser);
154 setSizeFull();
155 }
156
157 public void setLocation(ContentBrowserSubApp.BrowserLocation location) {
158 this.location.set(location);
159 }
160 }