Implemented navigation

This commit is contained in:
Ziver Koc 2015-04-25 15:22:44 +00:00
parent 846ed78252
commit b3e0757b29
11 changed files with 203 additions and 90 deletions

View file

@ -24,16 +24,21 @@
<a class="navbar-brand" href="#">{{title}}</a>
<ul class="nav navbar-nav">
{{#top-nav}}
{{^.sub_navs.length}}
<li><a href="{{.url}}">{{.name}}</a></li>
{{/.sub_navs.length}}
{{#.sub_navs.length}}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{.name}} {{#.sub_nav.length}}<b class="caret"></b>{{/.sub_nav.length}}
{{.name}} <b class="caret"></b>
</a>
<ul class="dropdown-menu">
{{#.sub_nav}}
<li><a href="#">{{.name}}</a></li>
{{/.sub_nav}}
{{#.sub_navs}}
<li><a href="{{.url}}">{{.name}}</a></li>
{{/.sub_navs}}
</ul>
</li>
{{/.sub_navs.length}}
{{/top-nav}}
</ul>
</nav>
@ -44,16 +49,21 @@
<div id="side-bar" class="col-md-2">
<ul class="side-menu nav nav-pills nav-stacked">
{{#side-nav}}
{{^.sub_navs.length}}
<li><a href="{{.url}}">{{.name}}</a></li>
{{/.sub_navs.length}}
{{#.sub_nav.length}}
<li class="">
<a data-toggle="collapse" data-parent="#side-bar" href="#{{.name}}_collapse">
{{.name}} {{#.sub_nav.length}}<b class="caret"></b>{{/.sub_nav.length}}
{{.name}} <b class="caret"></b>
</a>
<ul id="{{.name}}_collapse" class="side-sub-menu collapse nav nav-pills nav-stacked ">
{{#.sub_nav}}
<li><a href="#">{{.name}}</a></li>
{{/.sub_nav}}
{{#.sub_navs}}
<li><a href="{{.url}}">{{.name}}</a></li>
{{/.sub_navs}}
</ul>
</li>
{{/.sub_nav.length}}
{{/side-nav}}
</ul>
</div>
@ -64,9 +74,9 @@
<!-- Page specific info -->
<div class="row">
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Library</a></li>
<li class="active">Data</li>
{{#breadcrumb}}
<li><a href="{{.url}}">{{.name}}</a></li>
{{/breadcrumb}}
</ol>
</div>
<!-- Alerts -->

File diff suppressed because one or more lines are too long

View file

@ -20,9 +20,13 @@
* THE SOFTWARE.
*/
package wa.server.page;
package wa.server;
import wa.server.WAContext;
import wa.server.page.ServicesPage;
import wa.server.page.StatusPage;
import wa.server.page.WAPage;
import wa.server.page.struct.WANavigation;
import zutil.io.file.FileUtil;
import zutil.log.LogUtil;
import zutil.net.http.HttpHeaderParser;
@ -31,23 +35,31 @@ import zutil.net.http.HttpPrintStream;
import zutil.parser.DataNode;
import zutil.parser.Templator;
import zutil.parser.json.JSONWriter;
import zutil.plugin.PluginManager;
import java.io.IOException;
import java.util.Map;
import java.sql.Array;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by Ziver on 2015-04-02.
*/
public abstract class AbstractPage implements HttpPage{
public class WAAbstractPage implements HttpPage{
private static final Logger log = LogUtil.getLogger();
private static final String TMPL_FILE = "WebContent/index.tmpl";
private List<WAPage> pages;
private Templator tmpl;
public AbstractPage() {
public WAAbstractPage(PluginManager pluginManager) {
try {
pages = Arrays.asList(new WAPage[] {
new StatusPage(pluginManager),
new ServicesPage(pluginManager)
});
tmpl = new Templator(FileUtil.find(TMPL_FILE));
} catch(IOException e){
log.log(Level.SEVERE, null, e);
@ -62,14 +74,20 @@ public abstract class AbstractPage implements HttpPage{
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request) throws IOException {
WAContext context = (WAContext)session.get("context");
if(context == null){
context = new WAContext();
WAContext context = new WAContext(request);
List<WANavigation> breadcrumb = context.getBreadcrumb();
WAPage page = null;
if(breadcrumb.size() > 0){
int i = pages.indexOf(breadcrumb.get(0).getResource());
if(i >= 0)
page = pages.get(i);
}
if(("application/json").equals(client_info.getHeader("ContentType")) ||
request.containsKey("json")){
DataNode node = jsonResponse(context, client_info, session, cookie, request);
DataNode node = null;
if(page != null)
node = page.jsonResponse(context, client_info, session, cookie, request);
if(node != null) {
out.setHeader("Content-Type", "application/json");
JSONWriter writer = new JSONWriter(out);
@ -83,11 +101,15 @@ public abstract class AbstractPage implements HttpPage{
tmpl.set("title", "WebAdmin");
tmpl.set("top-nav", context.getNavigation());
tmpl.set("side-nav-show", true);
tmpl.set("side-nav", context.getNavigation().get(0).getSubNav());
if(breadcrumb.size() >= 1)
tmpl.set("side-nav", breadcrumb.get(0).getSubNav());
tmpl.set("breadcrumb", breadcrumb);
tmpl.set("alerts", context.getAlerts());
//tmpl.set("footer", null);
Templator content = htmlResponse(context, client_info, session, cookie, request);
Templator content = null;
if(page != null)
content = page.htmlResponse(context, client_info, session, cookie, request);
if(content != null)
tmpl.set("content", content.compile());
@ -95,17 +117,4 @@ public abstract class AbstractPage implements HttpPage{
}
}
public abstract Templator htmlResponse(WAContext context,
HttpHeaderParser client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request);
public DataNode jsonResponse(WAContext context,
HttpHeaderParser client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request){
return null;
}
}

View file

@ -26,36 +26,36 @@ import wa.server.page.struct.WAAlert;
import wa.server.page.struct.WANavigation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Ziver on 2015-04-06.
*/
public class WAContext {
private WANavigation nav;
private ArrayList<WAAlert> alerts;
private List<WANavigation> nav;
private List<WANavigation> breadcrumb;
public WAContext(){
public WAContext(Map<String, String> request){
// Navigation
nav = WANavigation.getRootNav();
/*nav = new WANavigation[]{
new WANavigation("Status"),
new WANavigation("Services", new WANavigation[]{
new WANavigation("Apache"),
new WANavigation("Tomcat"),
new WANavigation("Samba")
}),
new WANavigation("Configure")
};
alerts = new ArrayList<WAAlert>();*/
// Breadcrumb
breadcrumb = WANavigation.getNavResource(request);
}
public List<WANavigation> getNavigation(){
return nav.getSubNav();
}
public ArrayList<WAAlert> getAlerts() {
return alerts;
}
public List<WANavigation> getNavigation(){
return nav;
}
public List<WANavigation> getBreadcrumb(){
return breadcrumb;
}
}

View file

@ -1,6 +1,5 @@
package wa.server;
import wa.server.page.AbstractPage;
import wa.server.page.StatusPage;
import zutil.io.file.FileUtil;
import zutil.log.CompactLogFormatter;
@ -29,7 +28,7 @@ public class WebAdminServer {
pluginManager = new PluginManager();
HttpServer http = new HttpServer(80);
http.setPage("/", new StatusPage(pluginManager));
http.setPage("/", new WAAbstractPage(pluginManager));
http.setDefaultPage(new HttpFilePage(FileUtil.find("WebContent/")));
http.start();

View file

@ -22,10 +22,10 @@
package wa.server.page;
import wa.server.WAAbstractPage;
import wa.server.WAContext;
import wa.server.page.struct.WANavigation;
import wa.server.plugin.WAService;
import wa.server.plugin.WAStatus;
import zutil.net.http.HttpHeaderParser;
import zutil.parser.DataNode;
import zutil.parser.Templator;
@ -37,7 +37,7 @@ import java.util.Map;
/**
* Created by Ziver on 2015-04-06.
*/
public class ServicesPage extends AbstractPage{
public class ServicesPage implements WAPage {
private ArrayList<WAService> plugins;
public ServicesPage(PluginManager pluginManager){
@ -46,7 +46,7 @@ public class ServicesPage extends AbstractPage{
WANavigation nav = new WANavigation("Services");
for(WAService plugin : plugins)
nav.addSubNav(new WANavigation(plugin.getName()));
WANavigation.getRootNav().addSubNav(nav);
WANavigation.addRootNav(nav);
}

View file

@ -22,6 +22,7 @@
package wa.server.page;
import wa.server.WAAbstractPage;
import wa.server.WAContext;
import wa.server.page.struct.WANavigation;
import wa.server.plugin.WAStatus;
@ -30,23 +31,22 @@ import zutil.parser.DataNode;
import zutil.parser.Templator;
import zutil.plugin.PluginManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
/**
* Created by Ziver on 2015-04-06.
*/
public class StatusPage extends AbstractPage{
public class StatusPage implements WAPage {
private ArrayList<WAStatus> plugins;
public StatusPage(PluginManager pluginManager){
this.plugins = pluginManager.toArray(WAStatus.class);
WANavigation nav = new WANavigation("Status");
WANavigation nav = new WANavigation("Status", this);
for(WAStatus plugin : plugins)
nav.addSubNav(new WANavigation(plugin.getName()));
WANavigation.getRootNav().addSubNav(nav);
nav.addSubNav(new WANavigation(plugin.getName(), plugin));
WANavigation.addRootNav(nav);
}
@ -56,14 +56,14 @@ public class StatusPage extends AbstractPage{
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request) {
WAStatus obj = null;
if(request.containsKey("i"))
obj = getPlugin(Integer.parseInt(request.get("i")));
else
obj = getPlugin(0);
if(obj != null)
return new Templator(obj.html());
WAStatus obj = getPlugin(context);
if(obj != null) {
Templator tmpl = new Templator(obj.html());
tmpl.set("nav", context.getBreadcrumb().get(1));
return tmpl;
}
return null;
}
@ -74,7 +74,7 @@ public class StatusPage extends AbstractPage{
Map<String, String> request){
if(request.containsKey("i")) {
WAStatus obj = getPlugin(Integer.parseInt(request.get("i")));
WAStatus obj = getPlugin(context);
DataNode root = new DataNode(DataNode.DataType.Map);
obj.jsonUpdate(request, root);
return root;
@ -82,9 +82,14 @@ public class StatusPage extends AbstractPage{
return null;
}
private WAStatus getPlugin(int i){
if(0 >= i && i < plugins.size())
return plugins.get(i);
private WAStatus getPlugin(WAContext context){
if(context.getBreadcrumb().size() >= 2){
int i = plugins.indexOf(context.getBreadcrumb().get(1).getResource());
if(i >= 0)
return plugins.get(i);
}
return null;
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2015 Ziver
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package wa.server.page;
import wa.server.WAContext;
import zutil.net.http.HttpHeaderParser;
import zutil.parser.DataNode;
import zutil.parser.Templator;
import java.util.Map;
/**
* Created by Ziver on 2015-04-25.
*/
public interface WAPage {
public abstract Templator htmlResponse(WAContext context,
HttpHeaderParser client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request);
public DataNode jsonResponse(WAContext context,
HttpHeaderParser client_info,
Map<String, Object> session,
Map<String, String> cookie,
Map<String, String> request);
}

View file

@ -22,42 +22,62 @@
package wa.server.page.struct;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
* Created by Ziver on 2015-04-02.
*/
public class WANavigation {
private static WANavigation rootNav;
private static int nextId;
private static List<WANavigation> root_nav = new ArrayList<WANavigation>();
private static HashMap<Integer, WANavigation> nav_map = new HashMap<Integer, WANavigation>();
private int id;
private String url;
private String name;
private ArrayList<WANavigation> subNavs;
private ArrayList<WANavigation> sub_navs;
private WANavigation parent_nav;
private Object resource;
public WANavigation(String name) {
this.id = nextId++;
this.nav_map.put(this.id, this);
this.url = "?i="+this.id;
this.name = name;
this.subNavs = new ArrayList<>();
this.sub_navs = new ArrayList<>();
}
public WANavigation(String name, WANavigation[] sub_nav) {
public WANavigation(String name, Object resource) {
this(name);
this.subNavs.addAll(Arrays.asList(sub_nav));
this.setResource(resource);
}
public void addSubNav(WANavigation subNav) {
this.subNavs.add(subNav);
this.sub_navs.add(subNav);
subNav.setParentNav(this );
}
public List<WANavigation> getSubNav() {
return subNavs;
return sub_navs;
}
public Object getSubNav(String name) {
int index = subNavs.indexOf(name);
int index = sub_navs.indexOf(name);
if(index >= 0)
return subNavs.get(index);
return sub_navs.get(index);
return null;
}
public Object getResource(){
return resource;
}
public void setResource(Object obj){
resource = obj;
}
private void setParentNav(WANavigation nav){
this.parent_nav = nav;
}
public boolean equals(Object o){
if(o instanceof String)
@ -67,9 +87,22 @@ public class WANavigation {
}
public static WANavigation getRootNav(){
if(rootNav == null)
rootNav = new WANavigation("root_nav");
return rootNav;
public static void addRootNav(WANavigation nav){
getRootNav().add(nav);
}
public static List<WANavigation> getRootNav(){
return root_nav;
}
public static List<WANavigation> getNavResource(Map<String, String> request) {
LinkedList list = new LinkedList();
if(request.containsKey("i")){
WANavigation current = nav_map.get(Integer.parseInt(request.get("i")));
while(current != null){
list.addFirst(current);
current = current.parent_nav;
}
}
return list;
}
}

View file

@ -47,7 +47,7 @@ var hdd_io_data = {
};
function updateHdd(){
$.getJSON("?i=0&json&hdd", function( data ) {
$.getJSON("{{nav.url}}&json&hdd", function( data ) {
$.each(data['hdd'], function( index, hdd ){
var element = null;
var html_id = "hdd-id-" + hdd.id;

View file

@ -54,7 +54,7 @@ var cpu_data = {
};
function updateCpuChart(){
$.getJSON("?i=0&json&cpu", function( data ) {
$.getJSON("{{nav.url}}&json&cpu", function( data ) {
// Setup graph
if(cpu_chart == null){
// Fill in cpus
@ -102,7 +102,7 @@ var mem_data = [
];
function updateMemChart(){
$.getJSON("?i=0&json&memory", function( data ) {
$.getJSON("{{nav.url}}&json&memory", function( data ) {
if(mem_chart == null){
var ctx = $("#mem-chart").get(0).getContext("2d");
mem_chart = new Chart(ctx).Doughnut(mem_data, {
@ -123,7 +123,7 @@ function updateMemChart(){
function updateProcTable(){
$.getJSON("?i=0&json&proc", function( data ) {
$.getJSON("{{nav.url}}&json&proc", function( data ) {
$('#proc-list').bootstrapTable({
data: data['proc']
});