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.admincentral.badge;
35
36 import info.magnolia.context.Context;
37 import info.magnolia.i18nsystem.SimpleTranslator;
38 import info.magnolia.icons.MagnoliaIcons;
39 import info.magnolia.ui.api.location.Location;
40 import info.magnolia.ui.api.location.LocationController;
41 import info.magnolia.ui.theme.ResurfaceTheme;
42
43 import javax.inject.Inject;
44
45 import com.vaadin.shared.ui.ContentMode;
46 import com.vaadin.ui.Button;
47 import com.vaadin.ui.Composite;
48 import com.vaadin.ui.CssLayout;
49 import com.vaadin.ui.Label;
50 import com.vaadin.ui.VerticalLayout;
51
52
53
54
55 public abstract class AbstractBadge extends Composite {
56
57 private static final String BADGE_INDICATOR = "%s<span class='status " + MagnoliaIcons.RADIO_FILL.getCssClass() + " color-green'></span>";
58 private final VerticalLayout layout = new VerticalLayout();
59 private final Label itemCount = new Label();
60 private final String userName;
61 private final SimpleTranslator i18n;
62
63 @Inject
64 AbstractBadge(LocationController controller, Context context, SimpleTranslator i18n) {
65 this.userName = context.getUser().getName();
66 this.i18n = i18n;
67
68 layout.setSizeUndefined();
69 layout.setMargin(true);
70 layout.setSpacing(false);
71 layout.addStyleName("header-component");
72
73 itemCount.addStyleNames("indicator", "heading-2");
74 itemCount.setContentMode(ContentMode.HTML);
75
76 Button openArrow = new Button(MagnoliaIcons.ARROW1_S);
77 openArrow.addStyleNames(ResurfaceTheme.BUTTON_ICON, "open-arrow");
78 openArrow.addClickListener(event -> {
79 if (getLocation().getAppName().equals(controller.getWhere().getAppName())) {
80 onBadgeDeselected();
81 } else {
82 controller.goTo(getLocation());
83 }
84 });
85
86 CssLayout cssLayout = new CssLayout();
87 cssLayout.addComponents(itemCount, openArrow);
88
89 Label label = new Label(getCaption());
90 label.addStyleName("label");
91
92 layout.addComponents(cssLayout, label);
93
94 setCompositionRoot(layout);
95 }
96
97 protected void onBadgeDeselected() {
98 }
99
100
101
102
103
104 void update() {
105 final Status status = getStatus();
106 layout.setDescription(status.getDescription());
107
108 if (status.newItemsAvailable()) {
109 itemCount.setValue(String.format(BADGE_INDICATOR, status.getItemCountAsString()));
110 } else {
111 itemCount.setValue(status.getItemCountAsString());
112 }
113 }
114
115
116
117
118 abstract Status getStatus();
119
120
121
122
123 abstract Location getLocation();
124
125 String getUserName() {
126 return userName;
127 }
128
129 SimpleTranslator getI18n() {
130 return i18n;
131 }
132
133
134
135
136
137
138 static final class Status {
139 private final boolean newItemsAvailable;
140 private final int itemCount;
141 private final String description;
142
143 Status(boolean newItemsAvailable, int itemCount, String description) {
144 this.newItemsAvailable = newItemsAvailable;
145 this.itemCount = itemCount;
146 this.description = description;
147 }
148
149 boolean newItemsAvailable() {
150 return newItemsAvailable;
151 }
152
153 int getItemCount() {
154 return itemCount;
155 }
156
157 String getDescription() {
158 return description;
159 }
160
161 String getItemCountAsString() {
162 return itemCount >= 100 ? "99+" : String.valueOf(itemCount);
163 }
164 }
165 }