Compare commits

..

No commits in common. "50f2844319ff7458bb9d788900bd7964fa0a6e2c" and "2e3e11aafb0b76781d8fcb23c6aba438fc11ee6f" have entirely different histories.

17 changed files with 53 additions and 353 deletions

11
.idea/snap-admin.iml generated
View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Chameleon" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/build/resources/main/templates" />
</list>
</option>
</component>
</module>

View File

@ -49,8 +49,6 @@ dependencies {
api(libs.org.springframework.boot.spring.boot.starter.validation) api(libs.org.springframework.boot.spring.boot.starter.validation)
api(libs.org.springframework.boot.spring.boot.starter.web) api(libs.org.springframework.boot.spring.boot.starter.web)
api(libs.org.springframework.boot.spring.boot.configuration.processor) api(libs.org.springframework.boot.spring.boot.configuration.processor)
api("io.swagger.core.v3:swagger-annotations:2.2.15")
testImplementation(libs.org.springframework.boot.spring.boot.starter.test) testImplementation(libs.org.springframework.boot.spring.boot.starter.test)
} }

View File

@ -51,7 +51,6 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import space.mori.dalbodeule.snapadmin.external.annotations.Disable; import space.mori.dalbodeule.snapadmin.external.annotations.Disable;
import space.mori.dalbodeule.snapadmin.external.annotations.DisableEditField;
import space.mori.dalbodeule.snapadmin.external.annotations.DisplayFormat; import space.mori.dalbodeule.snapadmin.external.annotations.DisplayFormat;
import space.mori.dalbodeule.snapadmin.external.dbmapping.CustomJpaRepository; import space.mori.dalbodeule.snapadmin.external.dbmapping.CustomJpaRepository;
import space.mori.dalbodeule.snapadmin.external.dbmapping.DbObjectSchema; import space.mori.dalbodeule.snapadmin.external.dbmapping.DbObjectSchema;
@ -220,7 +219,6 @@ public class SnapAdmin {
Field[] fields = klass.getDeclaredFields(); Field[] fields = klass.getDeclaredFields();
for (Field f : fields) { for (Field f : fields) {
try { try {
if(f.getName().contains("hibernate")) continue;
DbField field = mapField(f, schema); DbField field = mapField(f, schema);
field.setSchema(schema); field.setSchema(schema);
schema.addField(field); schema.addField(field);
@ -354,8 +352,7 @@ public class SnapAdmin {
} }
DisplayFormat displayFormat = f.getAnnotation(DisplayFormat.class); DisplayFormat displayFormat = f.getAnnotation(DisplayFormat.class);
DisableEditField disableEdit = f.getAnnotation(DisableEditField.class);
DbField field = new DbField(f.getName(), fieldName, f, fieldType, schema, displayFormat != null ? displayFormat.format() : null); DbField field = new DbField(f.getName(), fieldName, f, fieldType, schema, displayFormat != null ? displayFormat.format() : null);
field.setConnectedType(connectedType); field.setConnectedType(connectedType);
@ -366,8 +363,6 @@ public class SnapAdmin {
if (field.isPrimaryKey()) if (field.isPrimaryKey())
field.setNullable(false); field.setNullable(false);
field.setDisableEditField(disableEdit != null);
return field; return field;
} }

View File

@ -28,6 +28,6 @@ import java.lang.annotation.Target;
* Disables edit actions on the Entity class. * Disables edit actions on the Entity class.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.TYPE)
public @interface DisableEditField { public @interface DisableEdit {
} }

View File

@ -1,11 +0,0 @@
package space.mori.dalbodeule.snapadmin.external.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 HiddenEditForm {
}

View File

@ -29,7 +29,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import io.swagger.v3.oas.annotations.Hidden;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVPrinter;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
@ -76,7 +75,6 @@ import space.mori.dalbodeule.snapadmin.internal.repository.ConsoleQueryRepositor
@Controller @Controller
@RequestMapping(value = { "/${snapadmin.baseUrl}/", "/${snapadmin.baseUrl}" }) @RequestMapping(value = { "/${snapadmin.baseUrl}/", "/${snapadmin.baseUrl}" })
@Import(ObjectMapper.class) @Import(ObjectMapper.class)
@Hidden
public class DataExportController { public class DataExportController {
private static final Logger logger = LoggerFactory.getLogger(DataExportFormat.class); private static final Logger logger = LoggerFactory.getLogger(DataExportFormat.class);
private final SnapAdmin snapAdmin; private final SnapAdmin snapAdmin;

View File

@ -21,7 +21,6 @@ package space.mori.dalbodeule.snapadmin.external.controller;
import java.util.Optional; import java.util.Optional;
import io.swagger.v3.oas.annotations.Hidden;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.apache.tika.mime.MimeTypeException; import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes; import org.apache.tika.mime.MimeTypes;
@ -49,7 +48,6 @@ import space.mori.dalbodeule.snapadmin.external.exceptions.SnapAdminException;
*/ */
@Controller @Controller
@RequestMapping(value = {"/${snapadmin.baseUrl}/download", "/${snapadmin.baseUrl}/download/"}) @RequestMapping(value = {"/${snapadmin.baseUrl}/download", "/${snapadmin.baseUrl}/download/"})
@Hidden
public class FileDownloadController { public class FileDownloadController {
@Autowired @Autowired
private SnapAdminRepository repository; private SnapAdminRepository repository;

View File

@ -32,7 +32,6 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import io.swagger.v3.oas.annotations.Hidden;
import org.hibernate.id.IdentifierGenerationException; import org.hibernate.id.IdentifierGenerationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -87,7 +86,6 @@ import space.mori.dalbodeule.snapadmin.internal.service.UserSettingsService;
*/ */
@Controller @Controller
@RequestMapping(value= {"/${snapadmin.baseUrl}", "/${snapadmin.baseUrl}/"}) @RequestMapping(value= {"/${snapadmin.baseUrl}", "/${snapadmin.baseUrl}/"})
@Hidden
public class SnapAdminController { public class SnapAdminController {
private static final Logger logger = LoggerFactory.getLogger(SnapAdminController.class); private static final Logger logger = LoggerFactory.getLogger(SnapAdminController.class);
@ -529,14 +527,9 @@ public class SnapAdminController {
} else { } else {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} catch (Exception e) {
// 추가: 일반적인 예외 처리
logger.error("Unexpected error during data submission: ", e);
attr.addFlashAttribute("errorTitle", "System Error");
attr.addFlashAttribute("error", e.getMessage());
attr.addFlashAttribute("params", params);
} }
if (attr.getFlashAttributes().containsKey("error")) { if (attr.getFlashAttributes().containsKey("error")) {
if (create) if (create)
return "redirect:/" + properties.getBaseUrl() + "/model/" + schema.getClassName() + "/create"; return "redirect:/" + properties.getBaseUrl() + "/model/" + schema.getClassName() + "/create";

View File

@ -22,7 +22,6 @@ package space.mori.dalbodeule.snapadmin.external.controller.rest;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import io.swagger.v3.oas.annotations.Hidden;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -41,7 +40,6 @@ import space.mori.dalbodeule.snapadmin.external.dto.AutocompleteSearchResult;
*/ */
@RestController @RestController
@RequestMapping(value= {"/${snapadmin.baseUrl}/api/autocomplete", "/${snapadmin.baseUrl}/api/autocomplete/"}) @RequestMapping(value= {"/${snapadmin.baseUrl}/api/autocomplete", "/${snapadmin.baseUrl}/api/autocomplete/"})
@Hidden
public class AutocompleteController { public class AutocompleteController {
@Autowired @Autowired
private SnapAdmin snapAdmin; private SnapAdmin snapAdmin;

View File

@ -123,7 +123,6 @@ public class CustomJpaRepository extends SimpleJpaRepository {
for (DbField field : schema.getSortedFields()) { for (DbField field : schema.getSortedFields()) {
if (field.isPrimaryKey()) continue; if (field.isPrimaryKey()) continue;
if (field.isReadOnly()) continue; if (field.isReadOnly()) continue;
if (field.isDisableEditField()) continue;
boolean keepValue = params.getOrDefault("__keep_" + field.getName(), "off").equals("on"); boolean keepValue = params.getOrDefault("__keep_" + field.getName(), "off").equals("on");
if (keepValue) continue; if (keepValue) continue;

View File

@ -43,7 +43,7 @@ import space.mori.dalbodeule.snapadmin.external.SnapAdmin;
import space.mori.dalbodeule.snapadmin.external.annotations.ComputedColumn; import space.mori.dalbodeule.snapadmin.external.annotations.ComputedColumn;
import space.mori.dalbodeule.snapadmin.external.annotations.DisableCreate; import space.mori.dalbodeule.snapadmin.external.annotations.DisableCreate;
import space.mori.dalbodeule.snapadmin.external.annotations.DisableDelete; import space.mori.dalbodeule.snapadmin.external.annotations.DisableDelete;
import space.mori.dalbodeule.snapadmin.external.annotations.DisableEditField; import space.mori.dalbodeule.snapadmin.external.annotations.DisableEdit;
import space.mori.dalbodeule.snapadmin.external.annotations.DisableExport; import space.mori.dalbodeule.snapadmin.external.annotations.DisableExport;
import space.mori.dalbodeule.snapadmin.external.annotations.HiddenColumn; import space.mori.dalbodeule.snapadmin.external.annotations.HiddenColumn;
import space.mori.dalbodeule.snapadmin.external.dbmapping.fields.DbField; import space.mori.dalbodeule.snapadmin.external.dbmapping.fields.DbField;
@ -351,7 +351,7 @@ public class DbObjectSchema {
} }
public boolean isEditEnabled() { public boolean isEditEnabled() {
return entityClass.getAnnotation(DisableEditField.class) == null; return entityClass.getAnnotation(DisableEdit.class) == null;
} }
public boolean isCreateEnabled() { public boolean isCreateEnabled() {

View File

@ -87,8 +87,6 @@ public class DbField {
* annotation has been applied. * annotation has been applied.
*/ */
private String format; private String format;
private boolean disableEditField = false;
/** /**
* The schema this field belongs to * The schema this field belongs to
@ -191,14 +189,6 @@ public class DbField {
public boolean isText() { public boolean isText() {
return type instanceof TextFieldType; return type instanceof TextFieldType;
} }
public boolean isDisableEditField() {
return disableEditField;
}
public void setDisableEditField(boolean managed) {
this.disableEditField = managed;
}
/** /**
* Returns the value to use in the "step" HTML attribute * Returns the value to use in the "step" HTML attribute

View File

@ -24,116 +24,26 @@ import java.time.ZoneOffset;
import java.util.List; import java.util.List;
import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator; import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator;
import java.time.*;
import java.time.format.*;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
public class InstantFieldType extends DbFieldType { public class InstantFieldType extends DbFieldType {
// 다양한 날짜/시간 형식을 처리할 있는 포맷터들 @Override
private static final DateTimeFormatter[] FORMATTERS = { public String getFragmentName() {
DateTimeFormatter.ISO_INSTANT, return "datetime";
DateTimeFormatter.ISO_DATE_TIME, }
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
};
@Override @Override
public String getFragmentName() { public Object parseValue(Object value) {
return "datetime"; if (value == null || value.toString().isBlank()) return null;
} return LocalDateTime.parse(value.toString()).toInstant(ZoneOffset.UTC);
}
@Override @Override
public Object parseValue(Object value) { public Class<?> getJavaClass() {
if (value == null) return null; return Instant.class;
}
// 이미 Instant 타입인 경우
if (value instanceof Instant) { @Override
return value; public List<CompareOperator> getCompareOperators() {
} return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE);
}
// LocalDateTime에서 Instant로 변환
if (value instanceof LocalDateTime) {
return ((LocalDateTime) value)
.atZone(ZoneId.systemDefault())
.toInstant();
}
// Date에서 Instant로 변환
if (value instanceof Date) {
return ((Date) value).toInstant();
}
// LocalDate에서 Instant로 변환
if (value instanceof LocalDate) {
return ((LocalDate) value)
.atStartOfDay(ZoneId.systemDefault())
.toInstant();
}
// 문자열 처리
String stringValue = value.toString();
if (stringValue.isBlank()) return null;
stringValue = stringValue.trim();
// 직접 Instant 파싱 시도
try {
return Instant.parse(stringValue);
} catch (DateTimeParseException e) {
// 실패, 다른 방법으로 시도
}
// 다른 날짜/시간 형식을 통해 변환 시도
for (DateTimeFormatter formatter : FORMATTERS) {
try {
// ISO_INSTANT의 경우 Instant.parse() 동일하므로 스킵
if (formatter == DateTimeFormatter.ISO_INSTANT) {
continue;
}
// ISO_DATE_TIME 형식은 ZoneId가 필요
if (formatter == DateTimeFormatter.ISO_DATE_TIME) {
return ZonedDateTime.parse(stringValue, formatter).toInstant();
}
// Z로 끝나는 형식은 UTC 시간으로 파싱
if (stringValue.endsWith("Z")) {
return ZonedDateTime.parse(stringValue, formatter.withZone(ZoneOffset.UTC))
.toInstant();
}
// 기타 형식은 시스템 기본 시간대 사용
TemporalAccessor ta = formatter.parse(stringValue);
return LocalDateTime.from(ta)
.atZone(ZoneId.systemDefault())
.toInstant();
} catch (DateTimeParseException e) {
// 다음 형식 시도
continue;
}
}
// 밀리초 타임스탬프로 시도
try {
long timestamp = Long.parseLong(stringValue);
return Instant.ofEpochMilli(timestamp);
} catch (NumberFormatException e) {
// 숫자 파싱 실패, 무시
}
// 모든 파싱 시도 실패
return null;
}
@Override
public Class<?> getJavaClass() {
return Instant.class;
}
@Override
public List<CompareOperator> getCompareOperators() {
return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE);
}
} }

View File

@ -18,65 +18,30 @@
package space.mori.dalbodeule.snapadmin.external.dbmapping.fields; package space.mori.dalbodeule.snapadmin.external.dbmapping.fields;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List; import java.util.List;
import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator; import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator;
public class LocalDateTimeFieldType extends DbFieldType { public class LocalDateTimeFieldType extends DbFieldType {
private static final DateTimeFormatter[] FORMATTERS = { @Override
DateTimeFormatter.ISO_LOCAL_DATE_TIME, public String getFragmentName() {
DateTimeFormatter.ISO_DATE_TIME, return "datetime";
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"), }
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS"),
DateTimeFormatter.ofPattern("yyyy-MM-dd")
};
@Override @Override
public String getFragmentName() { public Object parseValue(Object value) {
return "datetime"; if (value == null || value.toString().isBlank()) return null;
} return LocalDateTime.parse(value.toString());
}
@Override @Override
public Object parseValue(Object value) { public Class<?> getJavaClass() {
if (value == null || value.toString().isBlank()) return null; return LocalDateTime.class;
}
// 이미 LocalDateTime 객체인 경우
if (value instanceof LocalDateTime) { @Override
return value; public List<CompareOperator> getCompareOperators() {
} return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE);
}
String stringValue = value.toString().trim();
// 여러 형식으로 파싱 시도
for (DateTimeFormatter formatter : FORMATTERS) {
try {
// 날짜만 있는 형식인 경우 시간을 00:00:00으로 설정
if (formatter.equals(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) {
return LocalDate.parse(stringValue, formatter).atStartOfDay();
}
return LocalDateTime.parse(stringValue, formatter);
} catch (DateTimeParseException e) {
// 형식으로 파싱 실패, 다음 형식 시도
continue;
}
}
// 모든 형식 파싱 실패 예외 발생
throw new IllegalArgumentException("날짜/시간 형식을 파싱할 수 없습니다: " + stringValue);
}
@Override
public Class<?> getJavaClass() {
return LocalDateTime.class;
}
@Override
public List<CompareOperator> getCompareOperators() {
return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE);
}
} }

View File

@ -18,23 +18,12 @@
package space.mori.dalbodeule.snapadmin.external.dbmapping.fields; package space.mori.dalbodeule.snapadmin.external.dbmapping.fields;
import java.time.*; import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List; import java.util.List;
import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator; import space.mori.dalbodeule.snapadmin.external.dto.CompareOperator;
public class OffsetDateTimeFieldType extends DbFieldType { public class OffsetDateTimeFieldType extends DbFieldType {
// 다양한 날짜/시간 형식을 처리할 있는 포맷터들
private static final DateTimeFormatter[] FORMATTERS = {
DateTimeFormatter.ISO_OFFSET_DATE_TIME,
DateTimeFormatter.ISO_ZONED_DATE_TIME,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssXXX")
};
@Override @Override
public String getFragmentName() { public String getFragmentName() {
return "datetime"; return "datetime";
@ -42,110 +31,8 @@ public class OffsetDateTimeFieldType extends DbFieldType {
@Override @Override
public Object parseValue(Object value) { public Object parseValue(Object value) {
if (value == null) return null; if (value == null || value.toString().isBlank()) return null;
return OffsetDateTime.parse(value.toString());
// 이미 OffsetDateTime 타입인 경우
if (value instanceof OffsetDateTime) {
return value;
}
// ZonedDateTime에서 OffsetDateTime으로 변환
if (value instanceof ZonedDateTime) {
return ((ZonedDateTime) value).toOffsetDateTime();
}
// LocalDateTime에서 OffsetDateTime으로 변환 (시스템 기본 오프셋 사용)
if (value instanceof LocalDateTime) {
return ((LocalDateTime) value)
.atZone(ZoneId.systemDefault())
.toOffsetDateTime();
}
// Instant에서 OffsetDateTime으로 변환
if (value instanceof Instant) {
return ((Instant) value)
.atZone(ZoneId.systemDefault())
.toOffsetDateTime();
}
// LocalDate에서 OffsetDateTime으로 변환
if (value instanceof LocalDate) {
return ((LocalDate) value)
.atStartOfDay()
.atZone(ZoneId.systemDefault())
.toOffsetDateTime();
}
// 문자열 처리
String stringValue = value.toString();
if (stringValue.isBlank()) return null;
stringValue = stringValue.trim();
// 직접 OffsetDateTime 파싱 시도
try {
return OffsetDateTime.parse(stringValue);
} catch (DateTimeParseException e) {
// 실패, 다른 방법으로 시도
}
// 여러 가지 형식으로 파싱 시도
for (DateTimeFormatter formatter : FORMATTERS) {
try {
// ISO_OFFSET_DATE_TIME은 이미 위에서 시도했으므로 스킵
if (formatter == DateTimeFormatter.ISO_OFFSET_DATE_TIME) {
continue;
}
if (formatter == DateTimeFormatter.ISO_ZONED_DATE_TIME) {
return ZonedDateTime.parse(stringValue, formatter).toOffsetDateTime();
}
return OffsetDateTime.parse(stringValue, formatter);
} catch (DateTimeParseException e) {
// 다음 형식 시도
continue;
}
}
// ISO 날짜/시간 형식에 시스템 기본 오프셋 추가 시도
try {
LocalDateTime ldt = LocalDateTime.parse(stringValue);
return ldt.atZone(ZoneId.systemDefault()).toOffsetDateTime();
} catch (DateTimeParseException e) {
// 실패, 다음 방법 시도
}
// 날짜만 있는 경우 (UTC 자정으로 처리)
try {
LocalDate date = LocalDate.parse(stringValue);
return date.atStartOfDay().atZone(ZoneId.systemDefault()).toOffsetDateTime();
} catch (DateTimeParseException e) {
// 날짜 파싱 실패, 무시
}
// 밀리초 타임스탬프로 시도
try {
long timestamp = Long.parseLong(stringValue);
return Instant.ofEpochMilli(timestamp)
.atZone(ZoneId.systemDefault())
.toOffsetDateTime();
} catch (NumberFormatException e) {
// 숫자 파싱 실패, 무시
}
// Z로 끝나는 UTC 시간 문자열 처리 시도
if (stringValue.endsWith("Z")) {
try {
Instant instant = Instant.parse(stringValue);
return instant.atZone(ZoneId.systemDefault()).toOffsetDateTime();
} catch (DateTimeParseException e) {
// 실패, 무시
}
}
// 모든 파싱 시도 실패
return null;
} }
@Override @Override
@ -157,4 +44,4 @@ public class OffsetDateTimeFieldType extends DbFieldType {
public List<CompareOperator> getCompareOperators() { public List<CompareOperator> getCompareOperators() {
return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE); return List.of(CompareOperator.AFTER, CompareOperator.STRING_EQ, CompareOperator.BEFORE);
} }
} }

View File

@ -20,7 +20,6 @@ package space.mori.dalbodeule.snapadmin.internal.service;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -36,18 +35,11 @@ public class ConsoleQueryService {
@Autowired @Autowired
private ConsoleQueryRepository repo; private ConsoleQueryRepository repo;
private final Logger logger = Logger.getLogger(ConsoleQueryService.class.getName());
public ConsoleQuery save(ConsoleQuery q) { public ConsoleQuery save(ConsoleQuery q) {
try { return internalTransactionTemplate.execute((status) -> {
return internalTransactionTemplate.execute((status) -> { return repo.save(q);
return repo.save(q); });
});
} catch(Exception e) {
logger.severe("Error while saving console query: " + e.getMessage());
throw e;
}
} }
public void delete(String id) { public void delete(String id) {

View File

@ -31,8 +31,8 @@
<form class="form" enctype="multipart/form-data" method="post" th:action="|/${snapadmin_baseUrl}/model/${className}/create|"> <form class="form" enctype="multipart/form-data" method="post" th:action="|/${snapadmin_baseUrl}/model/${className}/create|">
<input type="hidden" name="__snapadmin_create" th:value="${create}"> <input type="hidden" name="__snapadmin_create" th:value="${create}">
<div th:each="field : ${schema.getSortedFields(false)}" class="mt-2" <div th:each="field : ${schema.getSortedFields(false)}" class="mt-2"
th:unless="${field.isGeneratedValue() && create || field.isDisableEditField()}" th:if="${!field.isGeneratedValue() || !create}"
th:classAppend="|${validationErrors != null && validationErrors.hasErrors(field.getJavaName()) ? 'invalid' : ''}|"> th:classAppend="|${validationErrors != null && validationErrors.hasErrors(field.getJavaName()) ? 'invalid' : ''}|">
<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()}">
* *
@ -66,8 +66,7 @@
<div class="separator mt-3 mb-2 separator-light"></div> <div class="separator mt-3 mb-2 separator-light"></div>
</div> </div>
<div th:each="field : ${schema.getManyToManyOwnedFields()}" class="mt-3" <div th:each="field : ${schema.getManyToManyOwnedFields()}" class="mt-3">
th:if="${!field.isDisableEditField()}">
<h2><span th:title="|${field.getType()} relationship|"><i class="bi bi-share"></i> [[ ${field.getJavaName()} ]]</span></h2> <h2><span th:title="|${field.getType()} relationship|"><i class="bi bi-share"></i> [[ ${field.getJavaName()} ]]</span></h2>
<div th:replace="~{snapadmin/fragments/forms :: input_autocomplete_multi(field=${field}, <div th:replace="~{snapadmin/fragments/forms :: input_autocomplete_multi(field=${field},
values=${object != null ? object.traverseMany(field) : null } )}"> values=${object != null ? object.traverseMany(field) : null } )}">