ONOS-1478 - GUI -- Segment navigation menu into categories.
Change-Id: I54bddcada1541ebf2926a6536e4c14bb8a1d3a66
Showing
4 changed files
with
78 additions
and
22 deletions
... | @@ -41,7 +41,14 @@ public class UiView { | ... | @@ -41,7 +41,14 @@ public class UiView { |
41 | /** | 41 | /** |
42 | * Represents miscellaneous views. | 42 | * Represents miscellaneous views. |
43 | */ | 43 | */ |
44 | - OTHER("Other"); | 44 | + OTHER("Other"), |
45 | + | ||
46 | + /** | ||
47 | + * Represents views that do not show in the navigation menu. | ||
48 | + * This category should not be specified directly; rather, use | ||
49 | + * the {@link UiViewHidden} constructor instead of {@link UiView}. | ||
50 | + */ | ||
51 | + HIDDEN("(hidden)"); | ||
45 | 52 | ||
46 | private final String label; | 53 | private final String label; |
47 | 54 | ||
... | @@ -64,7 +71,8 @@ public class UiView { | ... | @@ -64,7 +71,8 @@ public class UiView { |
64 | private final Category category; | 71 | private final Category category; |
65 | 72 | ||
66 | /** | 73 | /** |
67 | - * Creates a new user interface view descriptor. | 74 | + * Creates a new user interface view descriptor. The navigation item |
75 | + * will appear in the navigation menu under the specified category. | ||
68 | * | 76 | * |
69 | * @param category view category | 77 | * @param category view category |
70 | * @param id view identifier | 78 | * @param id view identifier | ... | ... |
... | @@ -29,7 +29,7 @@ public class UiViewHidden extends UiView { | ... | @@ -29,7 +29,7 @@ public class UiViewHidden extends UiView { |
29 | * @param id view identifier | 29 | * @param id view identifier |
30 | */ | 30 | */ |
31 | public UiViewHidden(String id) { | 31 | public UiViewHidden(String id) { |
32 | - super(Category.OTHER, id, null); | 32 | + super(Category.HIDDEN, id, null); |
33 | } | 33 | } |
34 | 34 | ||
35 | @Override | 35 | @Override | ... | ... |
... | @@ -18,7 +18,6 @@ package org.onosproject.ui.impl; | ... | @@ -18,7 +18,6 @@ package org.onosproject.ui.impl; |
18 | import org.onosproject.ui.UiExtension; | 18 | import org.onosproject.ui.UiExtension; |
19 | import org.onosproject.ui.UiExtensionService; | 19 | import org.onosproject.ui.UiExtensionService; |
20 | import org.onosproject.ui.UiView; | 20 | import org.onosproject.ui.UiView; |
21 | -import org.onosproject.ui.UiViewHidden; | ||
22 | 21 | ||
23 | import javax.ws.rs.GET; | 22 | import javax.ws.rs.GET; |
24 | import javax.ws.rs.Path; | 23 | import javax.ws.rs.Path; |
... | @@ -29,6 +28,9 @@ import java.io.ByteArrayInputStream; | ... | @@ -29,6 +28,9 @@ import java.io.ByteArrayInputStream; |
29 | import java.io.IOException; | 28 | import java.io.IOException; |
30 | import java.io.InputStream; | 29 | import java.io.InputStream; |
31 | import java.io.SequenceInputStream; | 30 | import java.io.SequenceInputStream; |
31 | +import java.util.ArrayList; | ||
32 | +import java.util.List; | ||
33 | +import java.util.stream.Collectors; | ||
32 | 34 | ||
33 | import static com.google.common.collect.ImmutableList.of; | 35 | import static com.google.common.collect.ImmutableList.of; |
34 | import static com.google.common.io.ByteStreams.toByteArray; | 36 | import static com.google.common.io.ByteStreams.toByteArray; |
... | @@ -41,9 +43,13 @@ public class MainNavResource extends AbstractInjectionResource { | ... | @@ -41,9 +43,13 @@ public class MainNavResource extends AbstractInjectionResource { |
41 | 43 | ||
42 | private static final String NAV_HTML = "nav.html"; | 44 | private static final String NAV_HTML = "nav.html"; |
43 | 45 | ||
44 | - private static final String INJECT_VIEW_ITEMS_START = "<!-- {INJECTED-VIEW-NAV-START} -->"; | 46 | + private static final String INJECT_VIEW_ITEMS_START = |
45 | - private static final String INJECT_VIEW_ITEMS_END = "<!-- {INJECTED-VIEW-NAV-END} -->"; | 47 | + "<!-- {INJECTED-VIEW-NAV-START} -->"; |
48 | + private static final String INJECT_VIEW_ITEMS_END = | ||
49 | + "<!-- {INJECTED-VIEW-NAV-END} -->"; | ||
46 | 50 | ||
51 | + private static final String HDR_FORMAT = | ||
52 | + "<div class=\"nav-hdr\">%s</div>\n"; | ||
47 | private static final String NAV_FORMAT = | 53 | private static final String NAV_FORMAT = |
48 | "<a ng-click=\"navCtrl.hideNav()\" href=\"#/%s\">%s</a>\n"; | 54 | "<a ng-click=\"navCtrl.hideNav()\" href=\"#/%s\">%s</a>\n"; |
49 | 55 | ||
... | @@ -51,31 +57,60 @@ public class MainNavResource extends AbstractInjectionResource { | ... | @@ -51,31 +57,60 @@ public class MainNavResource extends AbstractInjectionResource { |
51 | @Produces(MediaType.TEXT_HTML) | 57 | @Produces(MediaType.TEXT_HTML) |
52 | public Response getNavigation() throws IOException { | 58 | public Response getNavigation() throws IOException { |
53 | UiExtensionService service = get(UiExtensionService.class); | 59 | UiExtensionService service = get(UiExtensionService.class); |
54 | - InputStream navTemplate = getClass().getClassLoader().getResourceAsStream(NAV_HTML); | 60 | + InputStream navTemplate = |
55 | - String js = new String(toByteArray(navTemplate)); | 61 | + getClass().getClassLoader().getResourceAsStream(NAV_HTML); |
62 | + String html = new String(toByteArray(navTemplate)); | ||
56 | 63 | ||
57 | - int p1s = split(js, 0, INJECT_VIEW_ITEMS_START); | 64 | + int p1s = split(html, 0, INJECT_VIEW_ITEMS_START); |
58 | - int p1e = split(js, 0, INJECT_VIEW_ITEMS_END); | 65 | + int p1e = split(html, 0, INJECT_VIEW_ITEMS_END); |
59 | - int p2s = split(js, p1e, null); | 66 | + int p2s = split(html, p1e, null); |
60 | 67 | ||
61 | StreamEnumeration streams = | 68 | StreamEnumeration streams = |
62 | - new StreamEnumeration(of(stream(js, 0, p1s), | 69 | + new StreamEnumeration(of(stream(html, 0, p1s), |
63 | includeNavItems(service), | 70 | includeNavItems(service), |
64 | - stream(js, p1e, p2s))); | 71 | + stream(html, p1e, p2s))); |
65 | 72 | ||
66 | return Response.ok(new SequenceInputStream(streams)).build(); | 73 | return Response.ok(new SequenceInputStream(streams)).build(); |
67 | } | 74 | } |
68 | 75 | ||
69 | - // Produces an input stream including nav item injections from all extensions. | 76 | + // Produces an input stream of nav item injections from all extensions. |
70 | private InputStream includeNavItems(UiExtensionService service) { | 77 | private InputStream includeNavItems(UiExtensionService service) { |
78 | + List<UiExtension> extensions = service.getExtensions(); | ||
71 | StringBuilder sb = new StringBuilder("\n"); | 79 | StringBuilder sb = new StringBuilder("\n"); |
72 | - for (UiExtension extension : service.getExtensions()) { | 80 | + |
73 | - for (UiView view : extension.views()) { | 81 | + for (UiView.Category cat : UiView.Category.values()) { |
74 | - if (!(view instanceof UiViewHidden)) { | 82 | + if (cat == UiView.Category.HIDDEN) { |
75 | - sb.append(String.format(NAV_FORMAT, view.id(), view.label())); | 83 | + continue; |
76 | } | 84 | } |
85 | + | ||
86 | + List<UiView> catViews = getViewsForCat(extensions, cat); | ||
87 | + if (!catViews.isEmpty()) { | ||
88 | + addCatHeader(sb, cat); | ||
89 | + addCatItems(sb, catViews); | ||
77 | } | 90 | } |
78 | } | 91 | } |
92 | + | ||
79 | return new ByteArrayInputStream(sb.toString().getBytes()); | 93 | return new ByteArrayInputStream(sb.toString().getBytes()); |
80 | } | 94 | } |
95 | + | ||
96 | + private List<UiView> getViewsForCat(List<UiExtension> extensions, | ||
97 | + UiView.Category cat) { | ||
98 | + List<UiView> views = new ArrayList<>(); | ||
99 | + for (UiExtension extension : extensions) { | ||
100 | + views.addAll(extension.views().stream().filter( | ||
101 | + view -> cat.equals(view.category()) | ||
102 | + ).collect(Collectors.toList())); | ||
103 | + } | ||
104 | + return views; | ||
105 | + } | ||
106 | + | ||
107 | + private void addCatHeader(StringBuilder sb, UiView.Category cat) { | ||
108 | + sb.append(String.format(HDR_FORMAT, cat.label())); | ||
109 | + } | ||
110 | + | ||
111 | + private void addCatItems(StringBuilder sb, List<UiView> catViews) { | ||
112 | + for (UiView view : catViews) { | ||
113 | + sb.append(String.format(NAV_FORMAT, view.id(), view.label())); | ||
114 | + } | ||
115 | + } | ||
81 | } | 116 | } | ... | ... |
... | @@ -22,8 +22,7 @@ | ... | @@ -22,8 +22,7 @@ |
22 | position: absolute; | 22 | position: absolute; |
23 | top: 45px; | 23 | top: 45px; |
24 | left: 1px; | 24 | left: 1px; |
25 | - Xwidth: 200px; | 25 | + padding: 0; |
26 | - padding: 0px; | ||
27 | z-index: 3000; | 26 | z-index: 3000; |
28 | visibility: hidden; | 27 | visibility: hidden; |
29 | } | 28 | } |
... | @@ -37,6 +36,22 @@ | ... | @@ -37,6 +36,22 @@ |
37 | box-shadow: 0 2px 8px #111; | 36 | box-shadow: 0 2px 8px #111; |
38 | } | 37 | } |
39 | 38 | ||
39 | +#nav .nav-hdr { | ||
40 | + font-style: italic; | ||
41 | + padding: 6px 8px 6px 8px; | ||
42 | +} | ||
43 | + | ||
44 | +.light #nav .nav-hdr { | ||
45 | + color: #ddd; | ||
46 | + border-bottom: solid 1px #999; | ||
47 | + background-color: #aaa; | ||
48 | +} | ||
49 | +.dark #nav .nav-hdr { | ||
50 | + color: #888; | ||
51 | + border-bottom: solid 1px #444; | ||
52 | + background-color: #555; | ||
53 | +} | ||
54 | + | ||
40 | #nav a { | 55 | #nav a { |
41 | text-decoration: none; | 56 | text-decoration: none; |
42 | font-size: 14pt; | 57 | font-size: 14pt; |
... | @@ -48,7 +63,6 @@ | ... | @@ -48,7 +63,6 @@ |
48 | color: #369; | 63 | color: #369; |
49 | border-bottom: solid #ccc 1px; | 64 | border-bottom: solid #ccc 1px; |
50 | } | 65 | } |
51 | - | ||
52 | .dark #nav a { | 66 | .dark #nav a { |
53 | color: #eee; | 67 | color: #eee; |
54 | border-bottom: solid #333 1px; | 68 | border-bottom: solid #333 1px; |
... | @@ -57,7 +71,6 @@ | ... | @@ -57,7 +71,6 @@ |
57 | .light #nav a:hover { | 71 | .light #nav a:hover { |
58 | background-color: #ddd; | 72 | background-color: #ddd; |
59 | } | 73 | } |
60 | - | ||
61 | .dark #nav a:hover { | 74 | .dark #nav a:hover { |
62 | background-color: #777; | 75 | background-color: #777; |
63 | } | 76 | } | ... | ... |
-
Please register or login to post a comment