mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-06-08 21:38:21 +00:00
WIP
This commit is contained in:
parent
c0801cc69d
commit
0bd5ce19f1
@ -95,7 +95,6 @@ public class DbAdmin {
|
||||
field.setSchema(schema);
|
||||
|
||||
schema.addField(field);
|
||||
System.out.println(field);
|
||||
}
|
||||
|
||||
return schema;
|
||||
|
11
src/main/java/tech/ailef/dbadmin/annotations/Filterable.java
Normal file
11
src/main/java/tech/ailef/dbadmin/annotations/Filterable.java
Normal file
@ -0,0 +1,11 @@
|
||||
package tech.ailef.dbadmin.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Filterable {
|
||||
}
|
@ -45,6 +45,10 @@ import tech.ailef.dbadmin.exceptions.InvalidPageException;
|
||||
* - Pagination in one to many results?
|
||||
* - BLOB upload (WIP: check edit not working)
|
||||
* - AI console (PRO)
|
||||
* - Action logs
|
||||
* - Boolean icons
|
||||
* - @Filterable
|
||||
* - Boolean in create/edit is checkbox
|
||||
* - SQL console (PRO)
|
||||
* - JPA Validation (PRO)
|
||||
* - Logging
|
||||
|
@ -74,4 +74,20 @@ public class AdvancedJpaRepository extends SimpleJpaRepository {
|
||||
return entityManager.createQuery(query).setMaxResults(pageSize)
|
||||
.setFirstResult((page - 1) * pageSize).getResultList();
|
||||
}
|
||||
|
||||
public List<Object> distinctFieldValues(DbField field) {
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
|
||||
Class<?> outputType = field.getType().getJavaClass();
|
||||
if (field.getConnectedType() != null) {
|
||||
outputType = field.getConnectedSchema().getPrimaryKey().getType().getJavaClass();
|
||||
}
|
||||
|
||||
CriteriaQuery query = cb.createQuery(outputType);
|
||||
Root root = query.from(schema.getJavaClass());
|
||||
|
||||
query.select(root.get(field.getJavaName()).as(outputType)).distinct(true);
|
||||
|
||||
return entityManager.createQuery(query).getResultList();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package tech.ailef.dbadmin.dbmapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -19,6 +20,7 @@ import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import tech.ailef.dbadmin.DbAdmin;
|
||||
import tech.ailef.dbadmin.annotations.ComputedColumn;
|
||||
import tech.ailef.dbadmin.annotations.Filterable;
|
||||
import tech.ailef.dbadmin.exceptions.DbAdminException;
|
||||
import tech.ailef.dbadmin.misc.Utils;
|
||||
|
||||
@ -174,6 +176,17 @@ public class DbObjectSchema {
|
||||
return computedColumns.get(name);
|
||||
}
|
||||
|
||||
public List<DbField> getFilterableFields() {
|
||||
return getSortedFields().stream().filter(f -> {
|
||||
return !f.isBinary() && !f.isPrimaryKey()
|
||||
&& f.getPrimitiveField().getAnnotation(Filterable.class) != null;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
public List<Object> getFieldValues(DbField field) {
|
||||
return jpaRepository.distinctFieldValues(field);
|
||||
}
|
||||
|
||||
public Object[] getInsertArray(Map<String, String> params, Map<String, MultipartFile> files) {
|
||||
int currentIndex = 0;
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
<span class="align-middle"> [[ ${schema.getJavaClass().getSimpleName()} ]] </span>
|
||||
</h1>
|
||||
<div class="row mt-4">
|
||||
<div class="col">
|
||||
<div th:class="${schema.getFilterableFields().isEmpty() ? 'col' : 'col-9'}">
|
||||
<div class="w-100 d-flex inner-navigation">
|
||||
<a th:href="|/dbadmin/model/${className}|" class="active">
|
||||
<div class="ui-tab ps-5 pe-5 p-3">
|
||||
@ -31,15 +31,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="box with-navigation">
|
||||
<form th:action="|/dbadmin/model/${className}|" method="GET" class="mb-3">
|
||||
<div class="input-group">
|
||||
<input type="text" th:value="${query}"
|
||||
placeholder="Type and press ENTER to search"
|
||||
class="ui-text-input form-control" name="query" autofocus>
|
||||
<button class="ui-btn btn btn-primary">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form th:action="|/dbadmin/model/${className}|" method="GET" class="mb-3">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
||||
<input type="text" th:value="${query}"
|
||||
placeholder="Type and press ENTER to search"
|
||||
class="ui-text-input form-control" name="query" autofocus>
|
||||
<button class="ui-btn btn btn-primary">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="separator mb-4 mt-4"></div>
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
|
||||
@ -57,10 +58,27 @@
|
||||
th:href="|/dbadmin/model/${schema.getClassName()}/create|"><i class="bi bi-plus-square"></i></a></h3>
|
||||
</div>
|
||||
|
||||
<div th:replace="~{fragments/table_selectable :: table(results=${page.getResults()}, schema=${schema})}"
|
||||
|
||||
<div th:replace="~{fragments/table_selectable :: table(results=${page.getResults()}, schema=${schema})}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:if="${!schema.getFilterableFields().isEmpty()}" class="col-3">
|
||||
<div class="box">
|
||||
<h3 class="fw-bold"><i class="bi bi-funnel"></i> Filters</h3>
|
||||
<ul>
|
||||
<li th:each="field : ${schema.getFilterableFields()}">
|
||||
<span class="fw-bold" th:text="${field.getName()}"></span>
|
||||
|
||||
<th:block th:if="${field.getConnectedType() != null}">
|
||||
<div th:each="val : ${schema.getFieldValues(field)}">
|
||||
<span th:text="${val}"></span>
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user