mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-06-09 05:48:20 +00:00
@DisableDelete
WIP
This commit is contained in:
parent
5fdf7e18e7
commit
7e7089ea72
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableCreate.java
vendored
Normal file
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableCreate.java
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Spring Boot Database Admin - An automatically generated CRUD admin UI for Spring Boot apps
|
||||||
|
* Copyright (C) 2023 Ailef (http://ailef.tech)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables create actions on the Entity class.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface DisableCreate {
|
||||||
|
}
|
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableDelete.java
vendored
Normal file
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableDelete.java
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Spring Boot Database Admin - An automatically generated CRUD admin UI for Spring Boot apps
|
||||||
|
* Copyright (C) 2023 Ailef (http://ailef.tech)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables delete actions on the Entity class.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface DisableDelete {
|
||||||
|
}
|
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableEdit.java
vendored
Normal file
33
src/main/java/tech/ailef/dbadmin/external/annotations/DisableEdit.java
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Spring Boot Database Admin - An automatically generated CRUD admin UI for Spring Boot apps
|
||||||
|
* Copyright (C) 2023 Ailef (http://ailef.tech)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables edit actions on the Entity class.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface DisableEdit {
|
||||||
|
}
|
@ -309,6 +309,12 @@ public class DefaultDbAdminController {
|
|||||||
public String delete(@PathVariable String className, @PathVariable String id, RedirectAttributes attr) {
|
public String delete(@PathVariable String className, @PathVariable String id, RedirectAttributes attr) {
|
||||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||||
|
|
||||||
|
if (!schema.isDeleteEnabled()) {
|
||||||
|
attr.addFlashAttribute("errorTitle", "Unable to DELETE row");
|
||||||
|
attr.addFlashAttribute("error", "DELETE operations have been disabled on this table.");
|
||||||
|
return "redirect:/" + properties.getBaseUrl() + "/model/" + className;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
repository.delete(schema, id);
|
repository.delete(schema, id);
|
||||||
} catch (DataIntegrityViolationException e) {
|
} catch (DataIntegrityViolationException e) {
|
||||||
@ -332,6 +338,12 @@ public class DefaultDbAdminController {
|
|||||||
public String delete(@PathVariable String className, @RequestParam String[] ids, RedirectAttributes attr) {
|
public String delete(@PathVariable String className, @RequestParam String[] ids, RedirectAttributes attr) {
|
||||||
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
DbObjectSchema schema = dbAdmin.findSchemaByClassName(className);
|
||||||
|
|
||||||
|
if (!schema.isDeleteEnabled()) {
|
||||||
|
attr.addFlashAttribute("errorTitle", "Unable to DELETE rows");
|
||||||
|
attr.addFlashAttribute("error", "DELETE operations have been disabled on this table.");
|
||||||
|
return "redirect:/" + properties.getBaseUrl() + "/model/" + className;
|
||||||
|
}
|
||||||
|
|
||||||
int countDeleted = 0;
|
int countDeleted = 0;
|
||||||
for (String id : ids) {
|
for (String id : ids) {
|
||||||
try {
|
try {
|
||||||
|
@ -38,6 +38,9 @@ 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.DisableCreate;
|
||||||
|
import tech.ailef.dbadmin.external.annotations.DisableDelete;
|
||||||
|
import tech.ailef.dbadmin.external.annotations.DisableEdit;
|
||||||
import tech.ailef.dbadmin.external.annotations.HiddenColumn;
|
import tech.ailef.dbadmin.external.annotations.HiddenColumn;
|
||||||
import tech.ailef.dbadmin.external.dto.MappingError;
|
import tech.ailef.dbadmin.external.dto.MappingError;
|
||||||
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
import tech.ailef.dbadmin.external.exceptions.DbAdminException;
|
||||||
@ -335,6 +338,18 @@ public class DbObjectSchema {
|
|||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDeleteEnabled() {
|
||||||
|
return entityClass.getAnnotation(DisableDelete.class) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEditEnabled() {
|
||||||
|
return entityClass.getAnnotation(DisableEdit.class) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreateEnabled() {
|
||||||
|
return entityClass.getAnnotation(DisableCreate.class) == null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the data in this schema, as `DbObject`s
|
* Returns all the data in this schema, as `DbObject`s
|
||||||
* @return
|
* @return
|
||||||
|
@ -30,6 +30,15 @@ a {
|
|||||||
background: #EDECEF;
|
background: #EDECEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-secondary.disable {
|
||||||
|
background-color: #A8ADB3;
|
||||||
|
border: 1px solid #A8ADB3;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.delete-form button.disable .bi {
|
||||||
|
color: #9298A0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.null-label {
|
.null-label {
|
||||||
background-color: #EEE;
|
background-color: #EEE;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
function updateBulkActions(table, selected) {
|
function updateBulkActions(table, selected) {
|
||||||
|
let deleteEnabled = table.dataset.deleteenabled;
|
||||||
|
|
||||||
let divs = document.querySelectorAll(".bulk-actions");
|
let divs = document.querySelectorAll(".bulk-actions");
|
||||||
divs.forEach(div => {
|
divs.forEach(div => {
|
||||||
div.innerHTML = `${selected} items selected <input type="submit" form="multi-delete-form" class="ui-btn btn btn-secondary" value="Delete">`;
|
if (deleteEnabled === "true") {
|
||||||
|
div.innerHTML = `${selected} items selected
|
||||||
|
<input type="submit" form="multi-delete-form"
|
||||||
|
class="ui-btn btn btn-secondary ${deleteEnabled === "false" ? 'disable' : ''} " value="Delete">`;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
div.innerHTML = `<p class="text-muted m-0 mt-1">DELETE not allowed on this table</p>`;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,15 @@
|
|||||||
<tr th:fragment="data_row(row, selectable)" class="table-data-row">
|
<tr th:fragment="data_row(row, selectable)" class="table-data-row">
|
||||||
<td th:if=${selectable} class="table-checkbox">
|
<td th:if=${selectable} class="table-checkbox">
|
||||||
<input type="checkbox" class="form-check-input" name="ids"
|
<input type="checkbox" class="form-check-input" name="ids"
|
||||||
th:value="${row.getPrimaryKeyValue()}" form="multi-delete-form">
|
th:value="${row.getPrimaryKeyValue()}" form="multi-delete-form"
|
||||||
|
th:classAppend="|${!schema.isDeleteEnabled() ? 'disable' : ''}|">
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center row-icons">
|
<td class="text-center row-icons">
|
||||||
<a class="ps-1" th:href="|/${baseUrl}/model/${schema.getJavaClass().getName()}/edit/${row.getPrimaryKeyValue()}|">
|
<a class="ps-1" th:href="|/${baseUrl}/model/${schema.getJavaClass().getName()}/edit/${row.getPrimaryKeyValue()}|">
|
||||||
<i class="bi bi-pencil-square"></i></a>
|
<i class="bi bi-pencil-square"></i></a>
|
||||||
<form class="delete-form" method="POST"
|
<form class="delete-form" method="POST"
|
||||||
th:action="|/${baseUrl}/model/${schema.getJavaClass().getName()}/delete/${row.getPrimaryKeyValue()}|">
|
th:action="|/${baseUrl}/model/${schema.getJavaClass().getName()}/delete/${row.getPrimaryKeyValue()}|">
|
||||||
<button><i class="bi bi-trash"></i></button>
|
<button th:class="|${!schema.isDeleteEnabled() ? 'disable' : ''}|"><i class="bi bi-trash"></i></button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td th:each="field : ${schema.getSortedFields()}"
|
<td th:each="field : ${schema.getSortedFields()}"
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
</a>
|
</a>
|
||||||
</th:block>
|
</th:block>
|
||||||
</th:block>
|
</th:block>
|
||||||
<div class="table-selectable table-responsive" th:fragment="table(results, schema)">
|
<div class="table-selectable table-responsive" th:fragment="table(results, schema)"
|
||||||
|
th:data-deleteenabled="${schema.isDeleteEnabled()}"
|
||||||
|
th:data-editenabled="${schema.isEditEnabled()}">
|
||||||
<div th:if="${results.isEmpty()}">
|
<div th:if="${results.isEmpty()}">
|
||||||
<p>This table contains no data.</p>
|
<p>This table contains no data.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -30,7 +32,8 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<table class="table table-striped align-middle mt-3">
|
<table class="table table-striped align-middle mt-3">
|
||||||
<tr class="table-data-row">
|
<tr class="table-data-row">
|
||||||
<th class="table-checkbox"><input type="checkbox" class="form-check-input check-all"></th>
|
<th class="table-checkbox"><input type="checkbox" class="form-check-input check-all"
|
||||||
|
th:classAppend="|${!schema.isDeleteEnabled() ? 'disable' : ''}|"></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th class="table-data-row" th:each="field : ${schema.getSortedFields()}">
|
<th class="table-data-row" th:each="field : ${schema.getSortedFields()}">
|
||||||
<div class="m-0 p-0 d-flex justify-content-between">
|
<div class="m-0 p-0 d-flex justify-content-between">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user