mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-06-09 05:48:20 +00:00
WIP
This commit is contained in:
parent
cad093899a
commit
24e271664a
18
README.md
18
README.md
@ -28,9 +28,14 @@ a sample database and already configured code.
|
|||||||
If you wish to integrate it into your project instead, the first step is adding these to your `application.properties` file:
|
If you wish to integrate it into your project instead, the first step is adding these to your `application.properties` file:
|
||||||
|
|
||||||
```
|
```
|
||||||
dbadmin.enabled=true # Optional, default true
|
# Optional, default true
|
||||||
dbadmin.baseUrl=admin # The first-level part of the URL path: http://localhost:8080/${baseUrl}/
|
dbadmin.enabled=true
|
||||||
dbadmin.modelsPackage=tech.ailef.dbadmin.test.models # The package that contains your @Entity classes
|
|
||||||
|
# The first-level part of the URL path: http://localhost:8080/${baseUrl}/
|
||||||
|
dbadmin.baseUrl=admin
|
||||||
|
|
||||||
|
# The package that contains your @Entity classes
|
||||||
|
dbadmin.modelsPackage=tech.ailef.dbadmin.test.models
|
||||||
```
|
```
|
||||||
|
|
||||||
The last step is to annotate your `@SpringBootApplication` class containing the `main` method with the following:
|
The last step is to annotate your `@SpringBootApplication` class containing the `main` method with the following:
|
||||||
@ -39,14 +44,13 @@ The last step is to annotate your `@SpringBootApplication` class containing the
|
|||||||
@ImportAutoConfiguration(DbAdminAutoConfiguration.class)
|
@ImportAutoConfiguration(DbAdminAutoConfiguration.class)
|
||||||
```
|
```
|
||||||
|
|
||||||
This tells Spring to scan the `tech.ailef.dbadmin` packages and look for components there as well. Remember to also include
|
This will autoconfigure the various DbAdmin components when your application starts.
|
||||||
your original root package as shown, or Spring will not scan it otherwise.
|
|
||||||
|
|
||||||
3. At this point, when you run your application, you should be able to visit `http://localhost:$PORT/dbadmin` and access the web interface.
|
3. At this point, when you run your application, you should be able to visit `http://localhost:$PORT/${baseUrl}` and access the web interface.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Once you are correctly running Spring Boot Database Admin you will see the web interface at `http://localhost:$PORT/dbadmin`. Most of the features are already available with the basic configuration. However, some customization to the interface might be applied by using appropriate annotations on your classes fields or methods.
|
Once you are correctly running Spring Boot Database Admin, you will be able to access the web interface. Most of the features are already available with the basic configuration. However, some customization to the interface might be applied by using appropriate annotations on your classes fields or methods.
|
||||||
The following annotations are supported.
|
The following annotations are supported.
|
||||||
|
|
||||||
### @DisplayName
|
### @DisplayName
|
||||||
|
@ -66,6 +66,7 @@ public class DbAdmin {
|
|||||||
for (BeanDefinition bd : beanDefs) {
|
for (BeanDefinition bd : beanDefs) {
|
||||||
schemas.add(processBeanDefinition(bd));
|
schemas.add(processBeanDefinition(bd));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Spring Boot Database Admin initialized. Loaded " + schemas.size() + " table definitions");
|
logger.info("Spring Boot Database Admin initialized. Loaded " + schemas.size() + " table definitions");
|
||||||
logger.info("Spring Boot Database Admin web interface at: http://YOUR_HOST:YOUR_PORT/" + properties.getBaseUrl());
|
logger.info("Spring Boot Database Admin web interface at: http://YOUR_HOST:YOUR_PORT/" + properties.getBaseUrl());
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,25 @@ package tech.ailef.dbadmin;
|
|||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'dbadmin.*' properties that can be set in the properties file
|
||||||
|
* to configure the behaviour of Spring Boot Admin Panel.
|
||||||
|
*/
|
||||||
@ConfigurationProperties("dbadmin")
|
@ConfigurationProperties("dbadmin")
|
||||||
public class DbAdminProperties {
|
public class DbAdminProperties {
|
||||||
|
/**
|
||||||
|
* Whether Spring Boot Database Admin is enabled.
|
||||||
|
*/
|
||||||
public boolean enabled = true;
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix that is prepended to all routes registered by Spring Boot Database Admin.
|
||||||
|
*/
|
||||||
private String baseUrl;
|
private String baseUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path of the package that contains your JPA `@Entity` classes to be scanned.
|
||||||
|
*/
|
||||||
private String modelsPackage;
|
private String modelsPackage;
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
|
@ -30,6 +30,11 @@ public class GlobalController {
|
|||||||
return request.getParameterMap();
|
return request.getParameterMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The baseUrl as specified in the properties file by the user
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@ModelAttribute("baseUrl")
|
@ModelAttribute("baseUrl")
|
||||||
public String getBaseUrl(HttpServletRequest request) {
|
public String getBaseUrl(HttpServletRequest request) {
|
||||||
return props.getBaseUrl();
|
return props.getBaseUrl();
|
||||||
|
@ -36,7 +36,6 @@ public class DbAdminRepository {
|
|||||||
|
|
||||||
public DbAdminRepository(JdbcTemplate jdbcTemplate) {
|
public DbAdminRepository(JdbcTemplate jdbcTemplate) {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,7 +118,7 @@ public class DbAdminRepository {
|
|||||||
|
|
||||||
|
|
||||||
return new PaginatedResult(
|
return new PaginatedResult(
|
||||||
new PaginationInfo(page, maxPage, pageSize, maxElement, null, sortKey, sortOrder, new HashSet<>()),
|
new PaginationInfo(page, maxPage, pageSize, maxElement, null, new HashSet<>()),
|
||||||
results
|
results
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -229,7 +228,7 @@ public class DbAdminRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new PaginatedResult(
|
return new PaginatedResult(
|
||||||
new PaginationInfo(page, maxPage, pageSize, maxElement, query, sortKey, sortOrder, queryFilters),
|
new PaginationInfo(page, maxPage, pageSize, maxElement, query, queryFilters),
|
||||||
jpaRepository.search(query, page, pageSize, sortKey, sortOrder, queryFilters).stream()
|
jpaRepository.search(query, page, pageSize, sortKey, sortOrder, queryFilters).stream()
|
||||||
.map(o -> new DbObject(o, schema))
|
.map(o -> new DbObject(o, schema))
|
||||||
.toList()
|
.toList()
|
||||||
|
@ -41,20 +41,13 @@ public class PaginationInfo {
|
|||||||
|
|
||||||
private String query;
|
private String query;
|
||||||
|
|
||||||
private String sortKey;
|
public PaginationInfo(int currentPage, int maxPage, int pageSize, long maxElement, String query, Set<QueryFilter> queryFilters) {
|
||||||
|
|
||||||
private String sortOrder;
|
|
||||||
|
|
||||||
public PaginationInfo(int currentPage, int maxPage, int pageSize, long maxElement, String query,
|
|
||||||
String sortKey, String sortOrder, Set<QueryFilter> queryFilters) {
|
|
||||||
this.currentPage = currentPage;
|
this.currentPage = currentPage;
|
||||||
this.maxPage = maxPage;
|
this.maxPage = maxPage;
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.maxElement = maxElement;
|
this.maxElement = maxElement;
|
||||||
this.queryFilters = queryFilters;
|
this.queryFilters = queryFilters;
|
||||||
this.sortKey = sortKey;
|
|
||||||
this.sortOrder = sortOrder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentPage() {
|
public int getCurrentPage() {
|
||||||
@ -122,7 +115,14 @@ public class PaginationInfo {
|
|||||||
public List<Integer> getAfterPages() {
|
public List<Integer> getAfterPages() {
|
||||||
return IntStream.range(currentPage + 1, Math.min(currentPage + PAGE_RANGE, maxPage + 1)).boxed().collect(Collectors.toList());
|
return IntStream.range(currentPage + 1, Math.min(currentPage + PAGE_RANGE, maxPage + 1)).boxed().collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// public String getSortKey() {
|
||||||
|
// return sortKey;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public String getSortOrder() {
|
||||||
|
// return sortOrder;
|
||||||
|
// }
|
||||||
|
|
||||||
public boolean isLastPage() {
|
public boolean isLastPage() {
|
||||||
return currentPage == maxPage;
|
return currentPage == maxPage;
|
||||||
|
@ -127,7 +127,7 @@
|
|||||||
<ul class="pagination me-3">
|
<ul class="pagination me-3">
|
||||||
<li class="page-item" th:if="${page.getPagination().getCurrentPage() != 1}">
|
<li class="page-item" th:if="${page.getPagination().getCurrentPage() != 1}">
|
||||||
<a class="page-link"
|
<a class="page-link"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() - 1)}|}"
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() - 1)}|}"
|
||||||
aria-label="Previous">
|
aria-label="Previous">
|
||||||
<span aria-hidden="true">«</span>
|
<span aria-hidden="true">«</span>
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">Previous</span>
|
||||||
@ -136,7 +136,7 @@
|
|||||||
|
|
||||||
<li class="page-item" th:each="p : ${page.getPagination().getBeforePages()}">
|
<li class="page-item" th:each="p : ${page.getPagination().getBeforePages()}">
|
||||||
<a class="page-link"
|
<a class="page-link"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}" th:text="${p}"></a>
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}" th:text="${p}"></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="page-item active">
|
<li class="page-item active">
|
||||||
@ -145,13 +145,13 @@
|
|||||||
|
|
||||||
<li class="page-item" th:each="p : ${page.getPagination().getAfterPages()}">
|
<li class="page-item" th:each="p : ${page.getPagination().getAfterPages()}">
|
||||||
<a class="page-link"
|
<a class="page-link"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}"
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(p)}|}"
|
||||||
th:text="${p}"></a>
|
th:text="${p}"></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link"
|
<a class="page-link"
|
||||||
th:if="${!page.getPagination().isLastPage()}"
|
th:if="${!page.getPagination().isLastPage()}"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() + 1)}|}"
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getLink(page.getPagination.getCurrentPage() + 1)}|}"
|
||||||
aria-label="Next">
|
aria-label="Next">
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">Next</span>
|
||||||
<span aria-hidden="true">»</span>
|
<span aria-hidden="true">»</span>
|
||||||
@ -159,7 +159,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="me-3">
|
<div class="me-3">
|
||||||
<form method="GET" th:action="@{|${baseUrl}/model/${schema.getClassName()}|}">
|
<form method="GET" th:action="@{|/${baseUrl}/model/${schema.getClassName()}|}">
|
||||||
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
|
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
|
||||||
<input type="hidden" th:value="${query}" th:name="query">
|
<input type="hidden" th:value="${query}" th:name="query">
|
||||||
<input type="hidden" name="pageSize">
|
<input type="hidden" name="pageSize">
|
||||||
@ -187,7 +187,7 @@
|
|||||||
|
|
||||||
<div class="d-flex align-items-center" th:if="${page.getPagination().getMaxPage() == 1}">
|
<div class="d-flex align-items-center" th:if="${page.getPagination().getMaxPage() == 1}">
|
||||||
<div class="me-3">
|
<div class="me-3">
|
||||||
<form method="GET" th:action="@{|${baseUrl}/model/${schema.getClassName()}|}">
|
<form method="GET" th:action="@{|/${baseUrl}/model/${schema.getClassName()}|}">
|
||||||
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
|
<input type="hidden" th:value="${page.getPagination().getCurrentPage()}" th:name="page">
|
||||||
<input type="hidden" th:value="${query}" th:name="query">
|
<input type="hidden" th:value="${query}" th:name="query">
|
||||||
<input type="hidden" name="pageSize">
|
<input type="hidden" name="pageSize">
|
||||||
|
@ -29,17 +29,17 @@
|
|||||||
<div class="align-items-center">
|
<div class="align-items-center">
|
||||||
<h4 class="m-0" th:if="${page}">
|
<h4 class="m-0" th:if="${page}">
|
||||||
<th:block th:if="${sortKey != field.getJavaName()}" >
|
<th:block th:if="${sortKey != field.getJavaName()}" >
|
||||||
<a th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'DESC')}|}">
|
<a th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'DESC')}|}">
|
||||||
<i title="Sort" class="bi bi-caret-up"></i>
|
<i title="Sort" class="bi bi-caret-up"></i>
|
||||||
</a>
|
</a>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:unless="${sortKey != field.getJavaName()}">
|
<th:block th:unless="${sortKey != field.getJavaName()}">
|
||||||
<a th:if="${sortOrder == 'DESC'}"
|
<a th:if="${sortOrder == 'DESC'}"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'ASC')}|}">
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'ASC')}|}">
|
||||||
<i title="Sort" class="bi bi-caret-down-fill"></i>
|
<i title="Sort" class="bi bi-caret-down-fill"></i>
|
||||||
</a>
|
</a>
|
||||||
<a th:if="${sortOrder == 'ASC'}"
|
<a th:if="${sortOrder == 'ASC'}"
|
||||||
th:href="@{|${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'DESC')}|}">
|
th:href="@{|/${baseUrl}/model/${schema.getClassName()}${page.getPagination().getSortedPageLink(field.getJavaName(), 'DESC')}|}">
|
||||||
<i title="Sort" class="bi bi-caret-up-fill"></i>
|
<i title="Sort" class="bi bi-caret-up-fill"></i>
|
||||||
</a>
|
</a>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user