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.pages.app.detail;
35
36 import info.magnolia.pages.app.detail.context.MoveComponentContext;
37 import info.magnolia.pages.app.detail.context.NavigationContext;
38 import info.magnolia.ui.UIComponent;
39 import info.magnolia.ui.api.app.SubAppContext;
40 import info.magnolia.ui.api.location.Location;
41 import info.magnolia.ui.contentapp.browser.actions.ActionbarPresenter;
42 import info.magnolia.ui.contentapp.browser.actions.ActionbarView;
43 import info.magnolia.ui.contentapp.detail.AbstractDetailSubApp;
44 import info.magnolia.ui.contentapp.detail.ContentDetailSubApp;
45 import info.magnolia.ui.contentapp.detail.ContentDetailSubApp.DetailLocation;
46 import info.magnolia.ui.editor.LocaleContext;
47 import info.magnolia.ui.framework.WithImplementation;
48 import info.magnolia.ui.vaadin.editor.PageEditorListener;
49 import info.magnolia.ui.vaadin.editor.PageEditorView;
50
51 import java.util.Optional;
52
53 import javax.inject.Inject;
54 import javax.jcr.Node;
55
56 import com.vaadin.event.ShortcutAction;
57 import com.vaadin.event.ShortcutListener;
58 import com.vaadin.shared.Registration;
59 import com.vaadin.ui.Component;
60 import com.vaadin.ui.ComponentContainer;
61 import com.vaadin.ui.CssLayout;
62 import com.vaadin.ui.Panel;
63
64
65
66
67 public class PageDetailSubApp extends AbstractDetailSubApp<PageDetailSubApp.View> {
68
69 private final ContentDetailSubApp.LocationContext locationContext;
70 private final PageEditorStatus pageEditorStatus;
71
72 @Inject
73 protected PageDetailSubApp(
74 SubAppContext subAppContext,
75 PageDetailDescriptor subAppDescriptor,
76 ContentDetailSubApp.LocationContext locationContext,
77 MoveComponentContext moveComponentContext,
78 PageEditorStatus pageEditorStatus,
79 PageEditorView pageEditorView
80 ) {
81 super(subAppContext, new View(subAppDescriptor, locationContext, moveComponentContext, pageEditorView));
82 this.locationContext = locationContext;
83 this.pageEditorStatus = pageEditorStatus;
84 }
85
86 @Override
87 public View start(Location location) {
88 final View view = super.start(location);
89 bindInstance(UIComponent.class, getView());
90 locationContext.location().set(DetailLocation.wrap(location));
91 locationContext.location().observe(detailLocationOptional -> detailLocationOptional
92 .ifPresent(detailLocation -> getSubAppContext().getAppContext().updateSubAppLocation(getSubAppContext(), detailLocation)));
93 return view;
94 }
95
96 @Override
97 public void locationChanged(Location location) {
98 super.locationChanged(location);
99 locationContext.location().set(DetailLocation.wrap(location));
100 }
101
102 @Override
103 public String getCaption() {
104 return pageEditorStatus.getPageTitle();
105 }
106
107
108
109
110 static class View extends CssLayout implements UIComponent {
111
112 private final PageEditorPresenter pageEditorPresenter;
113 private final Panel panel = new Panel(this);
114
115 private View(PageDetailDescriptor descriptor, ContentDetailSubApp.LocationContext locationContext, MoveComponentContext moveComponentContext, PageEditorView pageEditorView) {
116 ActionbarPresenter<Node> actionbarPresenter = create(ActionbarPresenter.class, descriptor.getActions(), descriptor.getActionbar());
117
118
119
120
121 bindContext(LocaleContext.class);
122 bindContext(NavigationContext.class);
123 bindInstance(ActionbarPresenter.class, actionbarPresenter);
124 bindInstance(UIComponent.class, this);
125
126 ActionbarView<Node> actionbarView = create("actionbar", ActionbarView.class, descriptor.getActionbar(), actionbarPresenter);
127
128 CssLayout extensions = new CssLayout();
129 extensions.addStyleName("extensions");
130 descriptor.getExtensionViews()
131 .stream()
132 .map(WithImplementation::getImplementationClass)
133 .map(this::createStatusBarExtension)
134 .forEach(extensions::addComponent);
135
136 CssLayout statusbar = new CssLayout();
137 statusbar.addStyleName("statusbar");
138
139 statusbar.addComponent(extensions);
140
141 addComponents(actionbarView.asVaadinComponent(), statusbar);
142 addStyleName("pageeditor");
143 setSizeFull();
144 panel.setSizeFull();
145
146 addComponent(pageEditorView.asVaadinComponent());
147 this.pageEditorPresenter = create(PageEditorPresenter.class, create(descriptor.getItemProvider()));
148 addShortcutListener(new ShortcutListener(null, ShortcutAction.KeyCode.ESCAPE, (int[]) null) {
149 @Override
150 public void handleAction(Object sender, Object target) {
151 if (moveComponentContext.isMoving()) {
152 pageEditorPresenter.onAction(PageEditorListener.ACTION_STOP_MOVE_COMPONENT);
153 } else {
154
155 if (locationContext.location().value().map(DetailLocation::getViewType).map("edit"::equals).orElse(false)) {
156 pageEditorPresenter.onAction(PageEditorListener.ACTION_VIEW_PREVIEW);
157 } else {
158 pageEditorPresenter.onAction(PageEditorListener.ACTION_VIEW_EDIT);
159 }
160 }
161 }
162 });
163 }
164
165 private Component createStatusBarExtension(Class<? extends UIComponent> viewClass) {
166 UIComponent uiFrameworkView = create(viewClass);
167 Component component = uiFrameworkView.asVaadinComponent();
168 component.addStyleName("statusbar-extension");
169 return component;
170 }
171
172 @Override
173 public Registration addShortcutListener(ShortcutListener shortcut) {
174 return panel.addShortcutListener(shortcut);
175 }
176
177 @Override
178 public Component asVaadinComponent() {
179 return panel;
180 }
181
182 @Override
183 public void destroy() {
184 if (asVaadinComponent().getParent() instanceof ComponentContainer) {
185 ((ComponentContainer) asVaadinComponent().getParent()).removeComponent(this.asVaadinComponent());
186 }
187 Optional.ofNullable(pageEditorPresenter).ifPresent(PageEditorPresenter::destroy);
188 }
189 }
190 }