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.poc;
35  
36  import static com.vaadin.server.Sizeable.Unit.*;
37  
38  import info.magnolia.ui.vaadin.actionbar.Actionbar;
39  import info.magnolia.ui.vaadin.gwt.client.actionbar.shared.ActionbarItem;
40  
41  import javax.servlet.annotation.WebServlet;
42  
43  import com.vaadin.annotations.Theme;
44  import com.vaadin.annotations.Title;
45  import com.vaadin.annotations.VaadinServletConfiguration;
46  import com.vaadin.annotations.Widgetset;
47  import com.vaadin.server.ThemeResource;
48  import com.vaadin.server.VaadinRequest;
49  import com.vaadin.server.VaadinServlet;
50  import com.vaadin.shared.ui.ContentMode;
51  import com.vaadin.ui.Button;
52  import com.vaadin.ui.Component;
53  import com.vaadin.ui.CssLayout;
54  import com.vaadin.ui.FormLayout;
55  import com.vaadin.ui.HorizontalLayout;
56  import com.vaadin.ui.Image;
57  import com.vaadin.ui.Label;
58  import com.vaadin.ui.TextArea;
59  import com.vaadin.ui.TextField;
60  import com.vaadin.ui.UI;
61  import com.vaadin.ui.VerticalLayout;
62  
63  @Theme("poctheme")
64  @Title("Magnolia 6 Resurface")
65  @Widgetset("info.magnolia.poc.Widgetset")
66  public class TaskDetailUI extends UI {
67  
68      private HorizontalLayout header = new HorizontalLayout();
69      private CssLayout viewPort = new CssLayout();
70  
71      @Override
72      protected void init(VaadinRequest request) {
73          header.setStyleName("header");
74          header.setSpacing(false);
75  
76          // Create logo
77          CssLayout logoWrapper = createLogoComponent();
78  
79          // Create finder bar
80          CssLayout finderBarContainer = new CssLayout();
81          finderBarContainer.setStyleName("periscope-wrapper");
82  
83          Component finderBar = createFinderBar();
84  
85          finderBarContainer.addComponent(finderBar);
86  
87          // Create tasks indicator
88          CssLayout tasksWrapper = new CssLayout();
89          tasksWrapper.setStyleName("tasks-wrapper");
90          Component taskIndicator = createIndicatorComponent("New Tasks", "5", "green");
91          tasksWrapper.addComponent(taskIndicator);
92  
93          // Create message indicator
94          CssLayout messageWrapper = new CssLayout();
95          messageWrapper.setStyleName("messages-wrapper");
96          Component messageIndicator = createIndicatorComponent("New Messages", "10", "green");
97          messageWrapper.addComponent(messageIndicator);
98  
99          // Create profile component
100         Component profileWrapper = createProfileComponent();
101         profileWrapper.setStyleName("profile-wrapper");
102 
103         header.addComponents(logoWrapper, finderBarContainer, tasksWrapper, messageWrapper, profileWrapper);
104 
105         Component taskDetailWrapper = createTaskDetailComponent();
106         taskDetailWrapper.addStyleName("taskdetail");
107 
108         viewPort.setStyleName("viewport");
109         viewPort.setSizeFull();
110         viewPort.addComponent(taskDetailWrapper);
111 
112         final VerticalLayout layout = new VerticalLayout();
113         layout.setStyleName("main-wrapper");
114         layout.setSpacing(false);
115         layout.addComponents(header, viewPort);
116         layout.setMargin(false);
117         layout.setExpandRatio(header, 0f);
118         layout.setExpandRatio(viewPort, 1f);
119         layout.setSizeFull();
120 
121         setContent(layout);
122     }
123 
124     private CssLayout createLogoComponent() {
125         CssLayout logoWrapper = new CssLayout();
126         logoWrapper.setStyleName("logo-wrapper");
127 
128         ThemeResource resource = new ThemeResource("img/logo-magnolia.svg");
129         // Show the image in the application
130         Image image = new Image("Magnolia logo", resource);
131         image.addStyleName("header-component");
132         logoWrapper.addComponent(image);
133         return logoWrapper;
134     }
135 
136     private HorizontalLayout createFinderBar() {
137         HorizontalLayout finderBar = new HorizontalLayout();
138         finderBar.addStyleName("header-component");
139         finderBar.setSpacing(false);
140         finderBar.setMargin(false);
141         finderBar.setSizeFull();
142         Button shellButton = new Button();
143         shellButton.addStyleName("btn-shell icon-appslauncher btn-appslauncher");
144         finderBar.addComponent(shellButton);
145         finderBar.setExpandRatio(shellButton, 0f);
146 
147         CssLayout searchField = new CssLayout();
148         searchField.setStyleName("search-field");
149         TextField textField = new TextField();
150         textField.addStyleNames("search-textfield", "heading-2");
151         textField.setPlaceholder("Type to find");
152         searchField.addComponent(textField);
153         Label searchIcon = new Label();
154         searchIcon.setStyleName("icon-search");
155         searchField.addComponent(searchIcon);
156 
157         finderBar.addComponent(searchField);
158         finderBar.setExpandRatio(searchField, 1f);
159 
160         Button voiceButton = new Button();
161         voiceButton.addStyleName("btn-shell icon-target-app btn-voice");
162         finderBar.addComponent(voiceButton);
163         finderBar.setExpandRatio(voiceButton, 0f);
164 
165         return finderBar;
166     }
167 
168     private Component createIndicatorComponent(String label, String value, String status) {
169         return createHeaderComponent(label, value + "<span class='status icon-status-" + status + " color-" + status + "'></span>");
170     }
171 
172     private Component createHeaderComponent(String label, String value) {
173 
174         VerticalLayout tasksComponent = new VerticalLayout();
175         tasksComponent.setSpacing(false);
176         tasksComponent.setMargin(false);
177         tasksComponent.setStyleName("header-component");
178         Label taskNumber = new Label();
179         taskNumber.addStyleName("indicator heading-2");
180         taskNumber.setValue(value);
181         taskNumber.setContentMode(ContentMode.HTML);
182         Label taskLabel = new Label(label);
183         taskLabel.addStyleNames("text-tiny");
184         tasksComponent.addComponents(taskNumber, taskLabel);
185 
186         return tasksComponent;
187     }
188 
189     private HorizontalLayout createProfileComponent() {
190         HorizontalLayout profileWrapper = new HorizontalLayout();
191         profileWrapper.setSpacing(false);
192         profileWrapper.setMargin(false);
193 
194         Label avatar = new Label();
195         avatar.setContentMode(ContentMode.HTML);
196         avatar.addStyleName("header-component");
197         avatar.setValue("<span class='indicator number icon-user-role'></span>");
198         profileWrapper.addComponent(avatar);
199 
200         Component profileComponent = createHeaderComponent("public-01", "INT");
201         profileWrapper.addComponent(profileComponent);
202         return profileWrapper;
203     }
204 
205     private Component createTaskDetailComponent() {
206         VerticalLayout browser = new VerticalLayout();
207         browser.addStyleName("browser");
208         browser.setSizeFull();
209         browser.setMargin(false);
210 
211         VerticalLayout workbench = new VerticalLayout();
212         workbench.addStyleName("workbench");
213         workbench.setSizeFull();
214         workbench.setMargin(false);
215         Component header = buildHeader();
216         Component contentView = buildContentView();
217         workbench.addComponents(header, contentView);
218         workbench.setExpandRatio(header, 0f);
219         workbench.setExpandRatio(contentView, 1f);
220 
221         Component actionbar = buildActionBar();
222 
223         HorizontalLayout workbenchWrapper = new HorizontalLayout();
224         workbenchWrapper.setSizeFull();
225         workbenchWrapper.addComponents(workbench, actionbar);
226         workbenchWrapper.setExpandRatio(workbench, 1f);
227         workbenchWrapper.setExpandRatio(actionbar, 0f);
228 
229         Component bannerComponent = createBannerComponent();
230 
231         Component statusBar = buildStatusBar();
232 
233         browser.addComponents(bannerComponent, workbenchWrapper, statusBar);
234         browser.setExpandRatio(bannerComponent, 0f);
235         browser.setExpandRatio(workbenchWrapper, 1f);
236         browser.setExpandRatio(statusBar, 0f);
237 
238 
239         return browser;
240     }
241 
242     private Component buildContentView() {
243         // Create component with text fields
244         HorizontalLayout formLayoutWrapper = new HorizontalLayout();
245         formLayoutWrapper.setSpacing(false);
246         formLayoutWrapper.setMargin(false);
247         formLayoutWrapper.addStyleName("formlayout-wrapper");
248 
249         Component formLayout = createForm();
250 
251         formLayoutWrapper.addComponent(formLayout);
252         formLayoutWrapper.setExpandRatio(formLayout, 1l);
253 
254         return formLayoutWrapper;
255     }
256 
257     private Component buildHeader() {
258         // Create back button
259         Button backButton = new Button("back");
260         backButton.setCaptionAsHtml(true);
261         backButton.setPrimaryStyleName("icon-arrow2_w");
262         CssLayout backLayout = new CssLayout();
263         backLayout.addComponents(backButton);
264 
265         // Create header component
266         Label title = new Label();
267         title.setHeight(52, PIXELS);
268         title.addStyleNames("heading-1", "title");
269         title.setValue("Publication request");
270 
271         VerticalLayout header = new VerticalLayout();
272         header.addStyleName("header");
273         header.setWidth(100, PERCENTAGE);
274         header.setHeight(150, PIXELS);
275         header.setMargin(false);
276         header.setSpacing(false);
277         header.addComponents(backLayout, title);
278         header.setExpandRatio(backLayout, 1l);
279         header.setExpandRatio(title, 0l);
280 
281         return header;
282     }
283 
284     private Component buildStatusBar() {
285         HorizontalLayout statusBar = new HorizontalLayout();
286         statusBar.addStyleName("statusbar");
287         statusBar.setWidth(100, PERCENTAGE);
288 
289         Label label = new Label("Profile images / Directors / Managing directors /");
290         label.setWidth(100, PERCENTAGE);
291 
292         statusBar.addComponent(label);
293 
294         return statusBar;
295     }
296 
297     private Component createBannerComponent() {
298         HorizontalLayout bannerWrapper = new HorizontalLayout();
299         bannerWrapper.setWidth(100, Unit.PERCENTAGE);
300         bannerWrapper.setHeight(50, Unit.PIXELS);
301         bannerWrapper.setSpacing(false);
302         bannerWrapper.setMargin(false);
303         bannerWrapper.addStyleName("banner");
304 
305         HorizontalLayout emptyLayout = new HorizontalLayout();
306         emptyLayout.setSizeFull();
307 
308         Button closeButton = new Button();
309         closeButton.setCaptionAsHtml(true);
310         closeButton.setPrimaryStyleName("icon-close");
311         closeButton.addStyleName("close-button");
312         bannerWrapper.addComponents(emptyLayout, closeButton);
313         bannerWrapper.setExpandRatio(emptyLayout, 1l);
314         bannerWrapper.setExpandRatio(closeButton, 0l);
315         return bannerWrapper;
316     }
317 
318     private Component createForm() {
319 
320         FormLayout form = new FormLayout();
321         form.setMargin(false);
322         form.setSpacing(false);
323         form.setSizeFull();
324         form.addStyleName("formlayout");
325 
326         TextField submittedBy = new TextField("Submitted by");
327         submittedBy.setReadOnly(true);
328         submittedBy.setValue("eric");
329 
330         TextField date = new TextField("Date");
331         date.setReadOnly(true);
332         date.setValue("Nov 19, 2018, 10:37 AM");
333 
334         TextField assignee = new TextField("Assignee");
335         assignee.setReadOnly(true);
336         assignee.setValue("Peter");
337 
338         TextField workspace = new TextField("Workspace");
339         workspace.setReadOnly(true);
340         workspace.setValue("website");
341 
342         TextField path = new TextField("Path");
343         path.setReadOnly(true);
344         path.setValue("/travel/about/careers");
345 
346         TextField scheduledDate = new TextField("Scheduled date");
347         scheduledDate.setReadOnly(true);
348         scheduledDate.setValue("-");
349 
350         TextField recursive = new TextField("Recursive");
351         recursive.setReadOnly(true);
352         recursive.setValue("false");
353 
354         TextArea comment = new TextArea("Comment");
355         comment.setReadOnly(true);
356         comment.setHeight(72, PIXELS);
357         comment.setValue("Nullam quis risus eget urna mollis ornare vel eu leo. Sed posuere consec tetur est at lobortis. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Etiam porta.");
358 
359         form.addComponents(submittedBy, date, assignee, workspace, path, scheduledDate, recursive, comment);
360 
361         form.iterator().forEachRemaining(
362                 component -> component.setWidth(640, PIXELS)
363         );
364 
365         return form;
366     }
367 
368     private Component buildActionBar() {
369         Actionbar actionbar = new Actionbar();
370         actionbar.addSection("main", "Tasks");
371 
372         actionbar.addAction(new ActionbarItem("assignToMeAction", "Assign to me", "icon-user-public", "publishActions"), "main");
373         actionbar.addAction(new ActionbarItem("approveAndPublishAction", "Approve & publish", "icon-publish", "publishActions"), "main");
374         actionbar.addAction(new ActionbarItem("rejectAction", "Reject", "icon-delete", "publishActions"), "main");
375         actionbar.addAction(new ActionbarItem("abortAction", "Abort", "icon-publish", "publishActions"), "main");
376 
377         actionbar.addAction(new ActionbarItem("retryPublicationAction", "Retry publication", "icon-publish", "retryActions"), "main");
378 
379         actionbar.addAction(new ActionbarItem("previewPageAction", "Preview page", "icon-view", "showActions"), "main");
380         actionbar.addAction(new ActionbarItem("showChangesAction", "Show changes", "icon-view", "showActions"), "main");
381 
382         CssLayout wrapper = new CssLayout();
383         wrapper.addComponent(actionbar);
384         wrapper.setWidthUndefined();
385         wrapper.setHeight(100, Unit.PERCENTAGE);
386         wrapper.addStyleName("actionbar");
387         return wrapper;
388     }
389 
390     @WebServlet(value = "/taskDetail/*", asyncSupported = true)
391     @VaadinServletConfiguration(productionMode = false, ui = TaskDetailUI.class)
392     public static class Servlet extends VaadinServlet {
393     }
394 
395 }