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 info.magnolia.icons.MagnoliaIcons;
37 import info.magnolia.ui.contentapp.browser.Workbench.WorkbenchContext;
38 import info.magnolia.ui.contentapp.configuration.ExtensionViewDefinition;
39 import info.magnolia.ui.contentapp.configuration.ContentViewDefinition;
40 import info.magnolia.ui.contentapp.configuration.ContentViewsDefinition;
41 import info.magnolia.ui.UIComponent;
42 import info.magnolia.ui.framework.ioc.SessionStore;
43 import info.magnolia.ui.theme.ResurfaceTheme;
44
45 import java.util.HashMap;
46 import java.util.LinkedHashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Optional;
50
51 import javax.inject.Inject;
52
53 import com.vaadin.shared.ui.ContentMode;
54 import com.vaadin.ui.Alignment;
55 import com.vaadin.ui.Button;
56 import com.vaadin.ui.Component;
57 import com.vaadin.ui.CssLayout;
58 import com.vaadin.ui.HorizontalLayout;
59 import com.vaadin.ui.Label;
60 import com.vaadin.ui.VerticalLayout;
61
62
63
64
65
66
67
68 public class ContentViews<T> extends VerticalLayout implements UIComponent {
69
70 private final Map<String, Component> contentViewToggleControls = new HashMap<>();
71 private final Map<String, Component> extensionViewToggleControls = new HashMap<>();
72 private final ContentViewsDefinition<T> definition;
73 private final Map<String, ExtensionViewDefinition> extensionViews;
74 private final HorizontalLayout toolBar;
75 private final Label title;
76
77 private ContentView currentActiveContentView;
78 private WorkbenchContext workbenchContext;
79
80 private String currentActiveExtensionViewId;
81 private UIComponent currentActiveExtensionView;
82
83 @Inject
84 public ContentViews(WorkbenchContext workbenchContext, ContentViewsDefinition<T> definition, List<ExtensionViewDefinition> extensionViews) {
85
86 this.workbenchContext = workbenchContext;
87 this.definition = definition;
88 this.extensionViews = extensionViews.stream().collect(LinkedHashMap::new, (map, item) -> map.put(item.getView().getName(), item), Map::putAll);
89
90 setSizeFull();
91 setSpacing(false);
92 setMargin(false);
93 addStyleName("content-views");
94
95 title = new Label();
96 title.addStyleName("heading-1 tab-header");
97
98 toolBar = new HorizontalLayout();
99 toolBar.addStyleName("toolbar");
100 toolBar.setWidth(100, Unit.PERCENTAGE);
101
102 toolBar.setSpacing(true);
103 toolBar.setDefaultComponentAlignment(Alignment.BOTTOM_LEFT);
104
105 toolBar.addComponent(title);
106 toolBar.setExpandRatio(title, 0);
107
108 final HorizontalLayout viewsWrapper = new HorizontalLayout();
109 viewsWrapper.addStyleName("tools");
110 toolBar.addComponent(viewsWrapper);
111 toolBar.setComponentAlignment(viewsWrapper, Alignment.BOTTOM_RIGHT);
112
113 final CssLayout viewModes = new CssLayout();
114 viewModes.addStyleName("view-modes");
115 viewsWrapper.addComponent(viewModes);
116
117 addComponents(toolBar);
118
119 definition.getViews().forEach((id, viewDefinition) -> {
120 final Button contentViewIcon = createViewIcon(id, false, viewDefinition.getIcon(), MagnoliaIcons.VIEW_LIST);
121 contentViewToggleControls.put(id, contentViewIcon);
122 viewModes.addComponent(contentViewIcon);
123 });
124
125 workbenchContext.displayedContentViewId().observe(viewId -> {
126 this.contentViewToggleControls.values().forEach(control -> control.removeStyleName("active"));
127 viewId.ifPresent(this::switchView);
128 });
129
130 if (!this.extensionViews.isEmpty()) {
131 final CssLayout extensionViewModes = new CssLayout();
132 extensionViewModes.addStyleName("extension-views");
133
134 this.extensionViews.forEach((id, extensionViewDefinition) -> {
135 final Button contentViewIcon = createViewIcon(id, true, extensionViewDefinition.getIcon(), MagnoliaIcons.ANALYTICS_APP);
136 extensionViewToggleControls.put(id, contentViewIcon);
137 extensionViewModes.addComponent(contentViewIcon);
138 });
139 viewsWrapper.addComponent(extensionViewModes, 0);
140 }
141 }
142
143 private void switchView(String viewId) {
144 Optional.ofNullable(currentActiveContentView)
145 .map(UIComponent::getCurrentViewReference)
146 .ifPresent(contentView -> SessionStore.access().releaseBeanStore(contentView));
147
148 ContentViewDefinition<T> contentViewDefinition = definition.getViews().get(viewId);
149 this.currentActiveContentView = create(contentViewDefinition);
150 this.contentViewToggleControls.get(viewId).addStyleName("active");
151
152 addComponent(currentActiveContentView.asVaadinComponent());
153 setExpandRatio(currentActiveContentView.asVaadinComponent(), 1f);
154 }
155
156 private void showHideExtensionViews(String viewId) {
157 boolean hideOnly = viewId.equals(currentActiveExtensionViewId);
158
159 Optional.ofNullable(currentActiveExtensionView)
160 .map(UIComponent::getCurrentViewReference)
161 .ifPresent(contentView -> {
162 SessionStore.access().releaseBeanStore(contentView);
163 extensionViewToggleControls.values().forEach(control -> control.removeStyleName("active"));
164 currentActiveExtensionViewId = null;
165 currentActiveExtensionView = null;
166 });
167
168 if (!hideOnly) {
169 ExtensionViewDefinition<?> extensionViewDefinition = extensionViews.get(viewId);
170 currentActiveExtensionView = create(extensionViewDefinition.getView());
171 currentActiveExtensionViewId = viewId;
172 extensionViewToggleControls.get(viewId).addStyleName("active");
173 currentActiveExtensionView.asVaadinComponent().addStyleName("extension-view");
174
175 addComponent(currentActiveExtensionView.asVaadinComponent(), 1);
176 setExpandRatio(currentActiveExtensionView.asVaadinComponent(), extensionViewDefinition.getExpandRatio());
177 }
178 }
179
180 protected Button createViewIcon(final String viewType, final boolean extension, final String icon, final MagnoliaIcons defaultIcon) {
181 Button button = new Button(MagnoliaIcons.forCssClass(icon).orElse(defaultIcon),
182 extension ? clickEvent -> showHideExtensionViews(viewType) : clickEvent -> workbenchContext.displayedContentViewId().set(viewType));
183 button.addStyleName(ResurfaceTheme.BUTTON_ICON);
184 return button;
185 }
186
187 public void setTitle(String title) {
188 this.title.setValue(title);
189 }
190
191 public void setTitle(String title, boolean isHtml) {
192 if (isHtml) {
193 this.title.setContentMode(ContentMode.HTML);
194 }
195 setTitle(title);
196 }
197
198 protected ContentViewsDefinition<T> getDefinition() {
199 return definition;
200 }
201
202 }