Base template for ccm-admin

Jens Pelzetter 2020-09-20 13:18:59 +02:00
parent db5734f3f7
commit fe94a7de50
12 changed files with 329 additions and 24 deletions

View File

@ -1571,6 +1571,11 @@
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.2.tgz", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.2.tgz",
"integrity": "sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A==" "integrity": "sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A=="
}, },
"bootstrap-icons": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.0.0.tgz",
"integrity": "sha512-PaQm3VtSqbUnWuyqGmFJG5iF9UMieDuk8raPOmKOtKeyWyiVshgLoKa+9EWGolGU/nvyBLEBWhZoQqhu9ccNBg=="
},
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

View File

@ -18,6 +18,7 @@
}, },
"dependencies": { "dependencies": {
"bootstrap": "^4.5.2", "bootstrap": "^4.5.2",
"bootstrap-icons": "^1.0.0",
"jquery": "^3.5.1", "jquery": "^3.5.1",
"popper.js": "^1.16.1" "popper.js": "^1.16.1"
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.libreccm.ui.admin; package org.libreccm.ui.admin;
import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
/** /**
@ -33,6 +34,16 @@ public interface AdminPage {
*/ */
Set<Class<?>> getControllerClasses(); Set<Class<?>> getControllerClasses();
/**
* The entry point for the admin module. Used to generate the URL for an
* admin page in the navigation etc. For example, with the return value will
* {@code systeminformation} the generated link is
* {@code #{contextPath}/@admin/#{path}}.
*
* @return The path fragment of the entry point of the admin page/module.
*/
String getPath();
/** /**
* Gets the resourcebundle which provides the label of the admin page. * Gets the resourcebundle which provides the label of the admin page.
* *
@ -62,6 +73,13 @@ public interface AdminPage {
*/ */
String getDescriptionKey(); String getDescriptionKey();
/**
* Name of icon to use.
*
* @return The icon to use for the page.
*/
String getIcon();
/** /**
* Gets the position of the page in the admin nav bar. * Gets the position of the page in the admin nav bar.
* *

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2020 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.ui.admin;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class AdminPageModel {
private String path;
private String label;
private String description;
private String icon;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2020 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.ui.admin;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("AdminPagesModel")
public class AdminPagesModel {
@Inject
private Instance<AdminPage> adminPages;
@Inject
private GlobalizationHelper globalizationHelper;
public List<AdminPageModel> getAdminPages() {
return adminPages
.stream()
.sorted(
(page1, page2) -> Integer.compare(
page1.getPosition(), page2.getPosition()
)
)
.map(this::buildAdminPageModel)
.collect(Collectors.toList());
}
private AdminPageModel buildAdminPageModel(final AdminPage fromAdminPage) {
final ResourceBundle labelBundle = ResourceBundle.getBundle(
fromAdminPage.getLabelBundle(),
globalizationHelper.getNegotiatedLocale()
);
final ResourceBundle descriptionBundle = ResourceBundle.getBundle(
fromAdminPage.getDescriptionBundle(),
globalizationHelper.getNegotiatedLocale()
);
final AdminPageModel model = new AdminPageModel();
model.setPath(fromAdminPage.getPath());
model.setLabel(labelBundle.getString(fromAdminPage.getLabelKey()));
model.setDescription(
descriptionBundle.getString(
fromAdminPage.getDescriptionKey()
)
);
model.setIcon(fromAdminPage.getIcon());
return model;
}
}

View File

@ -18,7 +18,6 @@
*/ */
package org.libreccm.ui.admin.systeminformation; package org.libreccm.ui.admin.systeminformation;
import com.arsdigita.util.SystemInformation;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import java.io.IOException; import java.io.IOException;
@ -26,7 +25,6 @@ import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Named; import javax.inject.Named;

View File

@ -40,6 +40,11 @@ public class SystemInformationPage implements AdminPage {
return classes; return classes;
} }
@Override
public String getPath() {
return "systeminformation";
}
@Override @Override
public String getLabelBundle() { public String getLabelBundle() {
return AdminConstants.ADMIN_BUNDLE; return AdminConstants.ADMIN_BUNDLE;
@ -60,6 +65,11 @@ public class SystemInformationPage implements AdminPage {
return "systeminformation.description"; return "systeminformation.description";
} }
@Override
public String getIcon() {
return "info-circle-fill";
}
@Override @Override
public int getPosition() { public int getPosition() {
return 80; return 80;

View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<head>
<title>#{title} - LibreCCM Admin</title>
<link href="#{request.contextPath}/assets/@admin/ccm-admin.css"
rel="stylesheet"/>
</head>
<body>
<header>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<!--<a class="navbar-brand" href="#">Navbar</a>-->
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#foo">
<svg class="bi"
width="1em"
height="1em"
fill="currentColor">
<use xlink:href="#{request.contextPath}/assets/bootstrap/bootstrap-icons.svg#info-circle-fill" />
</svg>
<span>Foo</span>
</a>
</li>
<c:forEach items="#{AdminPagesModel.adminPages}" var="page">
<li class="nav-item">
<a class="nav-link"
href="#{request.contextPath}/@admin/#{page.path}">
<svg class="bi"
width="1em"
height="1em"
fill="currentColor">
<use xlink:href="#{request.contextPath}/assets/bootstrap/bootstrap-icons.svg##{page.icon}" />
</svg>
<span>#{page.label}</span>
</a>
</li>
</c:forEach>
</ul>
</div>
</nav>
</header>
<main>
<ui:insert name="main"></ui:insert>
</main>
<script src="#{request.contextPath}/assets/@admin/ccm-admin.js"></script>
</body>
</html>

View File

@ -1,24 +1,24 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"> xmlns:h="http://xmlns.jcp.org/jsf/html"
<h:head> xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<title>System Information</title> <ui:composition template="/WEB-INF/views/org/libreccm/ui/admin/ccm-admin.xhtml">
<link href="#{request.contextPath}/assets/@admin/ccm-admin.css" <ui:param name="title" value="System Information" />
rel="stylesheet"/> <ui:define name="main">
</h:head> <div class="container">
<h:body> <h1>System Information</h1>
<h1>System Information</h1> <h2>LibreCCM System Information</h2>
<h2>LibreCCM System Information</h2> <dl>
<dl> <c:forEach items="#{SystemInformationModel.ccmSystemInformation}"
<c:forEach items="#{SystemInformationModel.ccmSystemInformation}" var="prop">
var="prop"> <div>
<div> <dt>#{prop.key}</dt>
<dt>#{prop.key}</dt> <dd>#{prop.value}</dd>
<dd>#{prop.value}</dd> </div>
</div> </c:forEach>
</c:forEach> </dl>
</dl> </div>
<script src="#{request.contextPath}/assets/@admin/ccm-admin.js"></script> </ui:define>
</h:body> </ui:composition>
</html> </html>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 579 KiB

View File

@ -0,0 +1,60 @@
$grid-breakpoints: (
xs: 0,
sm: 36rem,
md: 48rem,
lg: 62rem,
xl: 75rem
);
$container-max-widths: (
sm: 33.75rem,
md: 45rem,
lg: 60rem,
xl: 71.25rem
);
$grid-gutter-width: 1.875rem;
$form-grid-gutter-width: 0.625rem;
$tooltip-max-width: 12.5rem;
$popover-maxwidth: 17.25rem;
$toast-max-width: 21.875rem;
$modal-xl: 71.25rem;
$modal-lg: 50rem;
$modal-md: 31.25rem;
$modal-sm: 18.75rem;
$modal-fade-transform: translate(0, -3.125rem);
$carousel-indicator-width: 1.875rem;
$carousel-control-icon-width: 1.25rem;
$pre-scrollable-max-height: 21.25rem;
// Navbar default colors have insufficient contrast
$navbar-dark-color: #fff;
table.users-table,
table.groups-table,
table.roles-table {
tbody {
td.action-col {
width: 8em;
}
}
}
table.group-members,
table.group-roles,
table.role-members {
tbody {
td.action-col {
width: 8em;
}
}
}

View File

@ -1 +1,2 @@
@import "custom";
@import "../../../../node_modules/bootstrap/scss/bootstrap"; @import "../../../../node_modules/bootstrap/scss/bootstrap";