This commit is contained in:
Francesco
2023-09-25 10:10:30 +02:00
parent 95e8dea90f
commit cdbad51641
50 changed files with 1171 additions and 218 deletions

View File

@@ -10,6 +10,7 @@
<script type="text/javascript" src="/js/autocomplete.js"></script>
<script type="text/javascript" src="/js/autocomplete-multi.js"></script>
<script type="text/javascript" src="/js/filters.js"></script>
<script type="text/javascript" src="/js/logs.js"></script>
<script type="text/javascript" src="/js/create.js"></script>
<title th:text="${title != null ? title + ' | Spring Boot DB Admin Panel' : 'Spring Boot DB Admin Panel'}"></title>
<script th:inline="javascript">
@@ -30,7 +31,9 @@
<nav class="navbar fixed-top navbar-expand-lg bg-accent color-white" th:fragment="navbar">
<div class="container-fluid">
<a class=" fw-bold navbar-brand" href="/"><i class="bi bi-hexagon-fill"></i> Spring Boot DB Admin Panel</a>
<a class=" fw-bold navbar-brand" href="/"><i class="bi bi-hexagon-fill"></i>
[[ ${userConf.get('brandName')} ]]
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -64,6 +67,30 @@
</div>
</a>
</li>
<li th:class="${#strings.equals(activePage, 'logs') ? 'active' : ''}">
<a th:href="|/${baseUrl}/logs|">
<div class="d-flex align-items-center">
<div class="menu-icon">
<i class="bi bi-file-text"></i>
</div>
<div class="menu-entry-text d-none d-md-block">
Logs
</div>
</div>
</a>
</li>
<li th:class="${#strings.equals(activePage, 'settings') ? 'active' : ''}">
<a th:href="|/${baseUrl}/settings|">
<div class="d-flex align-items-center">
<div class="menu-icon">
<i class="bi bi-gear"></i>
</div>
<div class="menu-entry-text d-none d-md-block">
Settings
</div>
</div>
</a>
</li>
<!--
<li th:class="${#strings.equals(activePage, 'console') ? 'active' : ''}">
<a href="/live">
@@ -89,18 +116,6 @@
</div>
</a>
</li>
<li th:class="${#strings.equals(activePage, 'settings') ? 'active' : ''}">
<a th:href="|/${baseUrl}/settings|">
<div class="d-flex align-items-center">
<div class="menu-icon">
<i class="bi bi-gear"></i>
</div>
<div class="menu-entry-text d-none d-md-block">
Settings
</div>
</div>
</a>
</li>
-->
</ul>
</div>
@@ -123,14 +138,15 @@
</div>
</div>
</div>
<nav aria-label="Results pagination" th:fragment="pagination(page)">
<div class="d-flex justify-content-between">
<div th:if="${page != null && page.getPagination().getMaxPage() != 1}" class="d-flex">
<ul class="pagination me-3">
<li class="page-item" th:if="${page.getPagination().getCurrentPage() != 1}">
<a class="page-link"
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() - 1)}|}"
th:href="@{|${requestUrl}${page.getPagination().getLink(page.getPagination.getCurrentPage() - 1)}|}"
aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
@@ -139,7 +155,7 @@
<li class="page-item" th:each="p : ${page.getPagination().getBeforePages()}">
<a class="page-link"
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}" th:text="${p}"></a>
th:href="@{|${requestUrl}${page.getPagination().getLink(p)}|}" th:text="${p}"></a>
</li>
<li class="page-item active">
@@ -148,13 +164,13 @@
<li class="page-item" th:each="p : ${page.getPagination().getAfterPages()}">
<a class="page-link"
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}"
th:href="@{|${requestUrl}${page.getPagination().getLink(p)}|}"
th:text="${p}"></a>
</li>
<li class="page-item">
<a class="page-link"
th:if="${!page.getPagination().isLastPage()}"
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() + 1)}|}"
th:href="@{|${requestUrl}${page.getPagination().getLink(page.getPagination.getCurrentPage() + 1)}|}"
aria-label="Next">
<span class="sr-only">Next</span>
<span aria-hidden="true">&raquo;</span>
@@ -162,15 +178,15 @@
</li>
</ul>
<div class="me-3">
<form method="GET" th:action="@{|/${baseUrl}/model/${schema.getClassName()}|}">
<form method="GET" th:action="@{|${requestUrl}|}">
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
<input type="hidden" th:value="${query}" th:name="query">
<input type="hidden" name="pageSize">
<th:block th:each="p : ${queryParams.keySet()}">
<input th:each="v : ${queryParams.get(p)}"
th:name="${p}" th:value="${v}" type="hidden"
th:if="${p.startsWith('filter_')}">
</th:block>
<input th:each="v : ${queryParams.get(p)}"
th:name="${p}" th:value="${v}" type="hidden"
th:if="${p.startsWith('filter_')}">
</th:block>
<select class="form-select page-size">
<option disabled>Page size</option>
<option th:selected="${page.getPagination().getPageSize() == 50}">50</option>
@@ -183,14 +199,14 @@
<div class="d-flex align-items-center" th:if="${page.getPagination().getMaxPage() > 1}">
<p class="m-0 p-0">
<i>Showing [[ ${page.getActualResults()} ]] of [[ ${page.getPagination().getMaxElement()} ]] results</i>
<i>Showing [[ ${page.getNumberOfResults()} ]] of [[ ${page.getPagination().getMaxElement()} ]] results</i>
</p>
</div>
</div>
<div class="d-flex align-items-center" th:if="${page.getPagination().getMaxPage() == 1}">
<div class="me-3">
<form method="GET" th:action="@{|/${baseUrl}/model/${schema.getClassName()}|}">
<form method="GET" th:action="@{|${requestUrl}|}">
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
<input type="hidden" th:value="${query}" th:name="query">
<input type="hidden" name="pageSize">
@@ -204,13 +220,14 @@
</form>
</div>
<p class="m-0 p-0">
<i>Showing [[ ${page.getActualResults()} ]] of [[ ${page.getPagination().getMaxElement()} ]] results</i>
<i>Showing [[ ${page.getNumberOfResults()} ]] of [[ ${page.getPagination().getMaxElement()} ]] results</i>
</p>
</div>
<div class="bulk-actions">
</div>
</div>
</nav>
</html>

View File

@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head th:replace="~{fragments/resources::head}">
</head>
<body>
<div class="bg-light main-wrapper">
<nav th:replace="~{fragments/resources :: navbar}"></nav>
<div class="d-flex">
<div th:replace="~{fragments/resources :: sidebar('logs')}"></div>
<div class="main-content bg-lighter">
<th:block th:replace="~{fragments/resources :: alerts}"></th:block>
<h1 class="fw-bold mb-4"><i class="align-middle bi bi-gear"></i>
<span class="align-middle">Logs</span>
</h1>
<div class="row mt-4">
<div class="col">
<div class="box">
<h3 class="fw-bold">Logs</h3>
<div class="w-75">
<form th:action="|/${baseUrl}/logs|" class="mt-3" id="log-filter-form" method="GET">
<div class="input-group">
<span class="input-group-text">Action type</span>
<select name="actionType" class="form-select">
<option>Any</option>
<option value="CREATE"
th:selected="${searchRequest.getActionType() != null
&& searchRequest.getActionType().equalsIgnoreCase('CREATE') }">Create</option>
<option value="EDIT"
th:selected="${searchRequest.getActionType() != null
&& searchRequest.getActionType().equalsIgnoreCase('EDIT') }">Edit</option>
<option value="DELETE"
th:selected="${searchRequest.getActionType() != null
&& searchRequest.getActionType().equalsIgnoreCase('DELETE') }">Delete</option>
</select>
<span class="input-group-text ms-3">Table</span>
<select name="table" class="form-select">
<option value="Any">Any</option>
<option th:each="schema : ${schemas}"
th:value="${schema.getTableName()}"
th:text="${schema.getTableName()}"
th:selected="${schema.getTableName().equals(searchRequest.getTable())}">
</option>
</select>
<span class="input-group-text ms-3">Item ID</span>
<input type="text" class="form-control" name="itemId"
th:value="${searchRequest.getItemId()}">
<button class="ui-btn btn btn-primary ms-3">Filter</button>
</div>
</form>
</div>
<div class="separator mt-3 mb-3"></div>
<div class="mt-3" th:if="${page.isEmpty()}">
<div class="alert alert-warning">There are no results for your filtering criteria</div>
</div>
<div class="table-responsive mt-3" th:if="${!page.isEmpty()}">
<nav th:replace="~{fragments/resources :: pagination(page=${page})}"></nav>
<table class="table table-striped mt-3">
<tr class="table-data-row">
<th>Action type</th>
<th>Table</th>
<th>Item ID</th>
<th>Time</th>
<th></th>
</tr>
<tr th:each="entry : ${page.getResults()}" class="table-data-row align-middle">
<td th:text="${entry.getActionType()}">
</td>
<td th:text="${entry.getOnTable()}">
</td>
<td th:text="${entry.getPrimaryKey()}">
</td>
<td th:text="${entry.getFormattedDate()}">
</td>
<td>
<!--
<a href="#" class="ui-btn btn btn-primary">
Diff <i class="text-white bi bi-search"></i>
</a>
-->
</td>
</tr>
</table>
<nav th:replace="~{fragments/resources :: pagination(page=${page})}"></nav>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -17,19 +17,27 @@
<div class="w-100 d-flex inner-navigation">
<a href="#" class="active">
<div class="ui-tab ps-5 pe-5 p-3">
<i class="bi bi-database pe-2"></i> APPEARANCE
<i class="bi bi-database pe-2"></i> GENERAL
</div>
</a>
<a href="#">
<!-- <a href="#">
<div class="ui-tab ps-5 pe-5 p-3">
<i class="bi bi-table pe-2"></i> DATA
</div>
</a>
</a> -->
<div class="inner-navigation-border flex-grow-1">
</div>
</div>
<div class="box with-navigation">
SETTINGS
<h3 class="fw-bold">General</h3>
<form th:action="|/${baseUrl}/settings|" method="POST">
<label for="brandName">Brand name</label>
<span class="m-0 p-0 text-muted">What appears in the top bar</span>
<input class="form-control mt-2" type="text"
id="brandName" name="brandName"
th:value="${userConf.get('brandName')}">
<button class="ui-btn btn btn-primary mt-3">Save</button>
</form>
</div>
</div>
</div>