Implemented @HiddenColumn

This commit is contained in:
Francesco 2023-09-30 20:44:52 +02:00
parent ea1a94916b
commit 869e276fb4
3 changed files with 44 additions and 9 deletions

View File

@ -0,0 +1,20 @@
package tech.ailef.dbadmin.external.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a column as hidden. This column and its values will not be shown
* in the list and detail view for objects of this type.
* If the column is nullable, it will be hidden in the create and edit
* forms as well (and this will result in the column having being NULL
* when the objects are created/edited). If, instead, it's not a nullable
* column, it will be included in the create and edit forms.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface HiddenColumn {
}

View File

@ -19,6 +19,7 @@ import jakarta.persistence.OneToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import tech.ailef.dbadmin.external.DbAdmin; import tech.ailef.dbadmin.external.DbAdmin;
import tech.ailef.dbadmin.external.annotations.ComputedColumn; import tech.ailef.dbadmin.external.annotations.ComputedColumn;
import tech.ailef.dbadmin.external.annotations.HiddenColumn;
import tech.ailef.dbadmin.external.exceptions.DbAdminException; import tech.ailef.dbadmin.external.exceptions.DbAdminException;
import tech.ailef.dbadmin.external.misc.Utils; import tech.ailef.dbadmin.external.misc.Utils;
@ -185,15 +186,28 @@ public class DbObjectSchema {
} }
/** /**
* Returns a sorted list of physical fields (i.e., fields that correspond to * See {@link DbObjectSchema#getSortedFields()}
* a column in the table as opposed to fields that are just present as
* instance variables, like relationship fields). Sorted alphabetically
* with priority to the primary key.
*
* @return * @return
*/ */
@JsonIgnore @JsonIgnore
public List<DbField> getSortedFields() { public List<DbField> getSortedFields() {
return getSortedFields(true);
}
/**
* Returns a sorted list of physical fields (i.e., fields that correspond to
* a column in the table as opposed to fields that are just present as
* instance variables, like relationship fields). Sorted alphabetically
* with priority the primary key, and non nullable fields.
*
* If readOnly is true, `@HiddenColumn`s are not returned. If instead
* readOnly is false, i.e. how it gets called in the create/edit page,
* hidden columns are included if they are not nullable.
*
* @param readOnly whether we only need to read the fields are create/edit
* @return
*/
public List<DbField> getSortedFields(boolean readOnly) {
return getFields().stream() return getFields().stream()
.filter(f -> { .filter(f -> {
boolean toMany = f.getPrimitiveField().getAnnotation(OneToMany.class) == null boolean toMany = f.getPrimitiveField().getAnnotation(OneToMany.class) == null
@ -202,7 +216,10 @@ public class DbObjectSchema {
OneToOne oneToOne = f.getPrimitiveField().getAnnotation(OneToOne.class); OneToOne oneToOne = f.getPrimitiveField().getAnnotation(OneToOne.class);
boolean mappedBy = oneToOne != null && !oneToOne.mappedBy().isBlank(); boolean mappedBy = oneToOne != null && !oneToOne.mappedBy().isBlank();
return toMany && !mappedBy; boolean hidden = f.getPrimitiveField().getAnnotation(HiddenColumn.class) != null;
return toMany && !mappedBy && (!hidden || !readOnly);
}) })
.sorted((a, b) -> { .sorted((a, b) -> {
if (a.isPrimaryKey() && !b.isPrimaryKey()) if (a.isPrimaryKey() && !b.isPrimaryKey())
@ -315,6 +332,4 @@ public class DbObjectSchema {
return Objects.equals(tableName, other.tableName); return Objects.equals(tableName, other.tableName);
} }
} }

View File

@ -30,7 +30,7 @@
<h3 class="fw-bold mb-4" th:text="${create ? schema.getJavaClass().getSimpleName() : object.getDisplayName()}"></h3> <h3 class="fw-bold mb-4" th:text="${create ? schema.getJavaClass().getSimpleName() : object.getDisplayName()}"></h3>
<form class="form" enctype="multipart/form-data" method="post" th:action="|/${baseUrl}/model/${className}/create|"> <form class="form" enctype="multipart/form-data" method="post" th:action="|/${baseUrl}/model/${className}/create|">
<input type="hidden" name="__dbadmin_create" th:value="${create}"> <input type="hidden" name="__dbadmin_create" th:value="${create}">
<div th:each="field : ${schema.getSortedFields()}" class="mt-2"> <div th:each="field : ${schema.getSortedFields(false)}" class="mt-2">
<label th:for="|__id_${field.getName()}|" class="mb-1 fw-bold"> <label th:for="|__id_${field.getName()}|" class="mb-1 fw-bold">
<span th:if="${!field.isNullable() && !field.isPrimaryKey()}"> <span th:if="${!field.isNullable() && !field.isPrimaryKey()}">
* *