add, edit and delete apps
This commit is contained in:
@@ -3,10 +3,14 @@ package de.jottyfan.timetrack.modules.projectmanagement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.projectmanagement.model.AppBean;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
/**
|
||||
@@ -19,6 +23,43 @@ public class AppController extends CommonController {
|
||||
|
||||
@Autowired
|
||||
private AppService service;
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping("/projectmanagement/app/add")
|
||||
public String getAppForAdd(final Model model) {
|
||||
model.addAttribute("bean", new AppBean());
|
||||
model.addAttribute("apps", service.getApps());
|
||||
model.addAttribute("bundles", service.getBundleMap().values());
|
||||
return "/projectmanagement/app/item";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping("/projectmanagement/app/{pkApp}")
|
||||
public String getAppForEdit(@PathVariable("pkApp") Integer pkApp, final Model model) {
|
||||
model.addAttribute("bean", service.getApp(pkApp));
|
||||
model.addAttribute("apps", service.getApps());
|
||||
model.addAttribute("bundles", service.getBundleMap().values());
|
||||
return "/projectmanagement/app/item";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@PostMapping("/projectmanagement/app/upsert")
|
||||
public String updateApp(@ModelAttribute("bean") AppBean bean, BindingResult bindingResult, final Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("apps", service.getApps());
|
||||
model.addAttribute("bundles", service.getBundleMap().values());
|
||||
return "/projectmanagement/app/item";
|
||||
}
|
||||
service.upsert(bean);
|
||||
return "redirect:/projectmanagement/apps";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping("/projectmanagement/app/{pkApp}/delete")
|
||||
public String deleteApp(@PathVariable("pkApp") Integer pkApp) {
|
||||
service.deleteApp(pkApp);
|
||||
return "redirect:/projectmanagement/apps";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping("/projectmanagement/apps")
|
||||
|
||||
@@ -192,4 +192,64 @@ public class AppRepository {
|
||||
.fetchOneInto(ProjectBean.class);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* get all apps ordered by name
|
||||
*
|
||||
* @return the apps list; an empty list at least
|
||||
*/
|
||||
public List<AppBean> getAllApps() {
|
||||
return jooq.selectFrom(T_APP).orderBy(T_APP.NAME).fetchInto(AppBean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete the app
|
||||
*
|
||||
* @param pkApp the ID of the app
|
||||
*/
|
||||
public void deleteApp(Integer pkApp) {
|
||||
jooq.deleteFrom(T_APP).where(T_APP.PK_APP.eq(pkApp)).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* update the app bean
|
||||
*
|
||||
* @param bean the bean
|
||||
*/
|
||||
public void updateApp(AppBean bean) {
|
||||
jooq
|
||||
// @formatter:off
|
||||
.update(T_APP)
|
||||
.set(T_APP.NAME, bean.getName())
|
||||
.set(T_APP.DESCRIPTION, bean.getDescription())
|
||||
.set(T_APP.FK_BUNDLE, bean.getFkBundle())
|
||||
.set(T_APP.BASIC_FUNCTIONALITY, bean.getBasicFunctionality())
|
||||
.set(T_APP.FK_REPLACED_BY_APP, bean.getFkReplacedByApp())
|
||||
.set(T_APP.REPOSITORY_URL, bean.getRepositoryUrl())
|
||||
.where(T_APP.PK_APP.eq(bean.getPkApp()))
|
||||
.execute();
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* insert the bean
|
||||
*
|
||||
* @param bean the bean
|
||||
* @return the new ID of the bean
|
||||
*/
|
||||
public Integer insertApp(AppBean bean) {
|
||||
return jooq
|
||||
// @formatter:off
|
||||
.insertInto(T_APP,
|
||||
T_APP.NAME,
|
||||
T_APP.DESCRIPTION,
|
||||
T_APP.FK_BUNDLE,
|
||||
T_APP.BASIC_FUNCTIONALITY,
|
||||
T_APP.FK_REPLACED_BY_APP,
|
||||
T_APP.REPOSITORY_URL)
|
||||
.values(bean.getName(), bean.getDescription(), bean.getFkBundle(), bean.getBasicFunctionality(), bean.getFkReplacedByApp(), bean.getRepositoryUrl())
|
||||
.returning(T_APP.PK_APP)
|
||||
.fetchOne(T_APP.PK_APP);
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,5 +52,21 @@ public class AppService {
|
||||
|
||||
public ProjectBean getProjectOfWorkpackage(Integer pkWorkpackage) {
|
||||
return repository.getProjectOfWorkpackage(pkWorkpackage);
|
||||
}
|
||||
|
||||
public List<AppBean> getApps() {
|
||||
return repository.getAllApps();
|
||||
}
|
||||
|
||||
public void deleteApp(Integer pkApp) {
|
||||
repository.deleteApp(pkApp);
|
||||
}
|
||||
|
||||
public void upsert(AppBean bean) {
|
||||
if (bean.getPkApp() != null) {
|
||||
repository.updateApp(bean);
|
||||
} else {
|
||||
repository.insertApp(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
81
src/main/resources/templates/projectmanagement/app/item.html
Normal file
81
src/main/resources/templates/projectmanagement/app/item.html
Normal file
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{layout/main.html}">
|
||||
<head>
|
||||
<title>Projektmanagement</title>
|
||||
</head>
|
||||
<body>
|
||||
<font layout:fragment="title">App</font>
|
||||
<ul layout:fragment="menu">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')">
|
||||
<a class="nav-link btn btn-secondary btn-white-text" th:href="@{/projectmanagement/apps}">abbrechen</a>
|
||||
</li>
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
<div class="container">
|
||||
<div class="alert alert-danger" th:if="${error}" th:text="${error}"></div>
|
||||
<form th:action="@{/projectmanagement/app/upsert}" method="post" th:object="${bean}">
|
||||
<div class="container m-2">
|
||||
<div class="row g-2">
|
||||
<div class="col-2" th:if="${bean.pkApp}">ID</div>
|
||||
<div class="col-10" th:if="${bean.pkApp}">
|
||||
<input type="text" class="form-control" th:field="*{pkApp}" readonly="readonly" />
|
||||
</div>
|
||||
<div class="col-2">Name</div>
|
||||
<div class="col-10">
|
||||
<input type="text" class="form-control" th:field="*{name}" />
|
||||
</div>
|
||||
<div class="col-2">Beschreibung</div>
|
||||
<div class="col-10">
|
||||
<textarea class="form-control" th:field="*{description}"></textarea>
|
||||
</div>
|
||||
<div class="col-2">Git-URL</div>
|
||||
<div class="col-10">
|
||||
<input type="text" class="form-control" th:field="*{repositoryUrl}" />
|
||||
</div>
|
||||
<div class="col-2">Basisfunktion</div>
|
||||
<div class="col-10">
|
||||
<textarea class="form-control" th:field="*{basicFunctionality}"></textarea>
|
||||
</div>
|
||||
<div class="col-2">Bundle</div>
|
||||
<div class="col-10">
|
||||
<select th:field="*{fkBundle}" class="form-select">
|
||||
<option value="" label="--- bitte wählen ---" />
|
||||
<option th:each="b : ${bundles}" th:label="${b.name}" th:value="${b.pkBundle}" />
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-2">ersetzt durch</div>
|
||||
<div class="col-10">
|
||||
<select th:field="*{fkReplacedByApp}" class="form-select">
|
||||
<option value="" label="--- bitte wählen ---" />
|
||||
<option th:each="a : ${apps}" th:value="${a.pkApp}" th:title="${a.repositoryUrl}" th:label="${a.name}" />
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-2"></div>
|
||||
<div class="col-5">
|
||||
<input type="submit" class="btn btn-primary" value="Speichern">
|
||||
</div>
|
||||
<div class="col-5" th:if="${bean.pkApp}">
|
||||
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">Löschen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="deleteModalLabel">Bestätigung für Löschvorgang</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
|
||||
</div>
|
||||
<div class="modal-body">Bist du sicher, dass du dieses Element löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<a th:href="@{/projectmanagement/app/{p}/delete(p=${bean.pkApp})}" class="btn btn-danger">Löschen</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,8 @@
|
||||
<font layout:fragment="title">Projekt</font>
|
||||
<ul layout:fragment="menu">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')">
|
||||
<a class="nav-link btn btn-secondary btn-white-text" th:href="@{/projectmanagement}">zur Projektübersicht</a>
|
||||
<a class="btn btn-outline-secondary" th:href="@{/projectmanagement}">zur Projektübersicht</a>
|
||||
<a class="btn btn-outline-primary" th:href="@{/projectmanagement/app/add}" th:unless="${bean}">neue App anlegen</a>
|
||||
</li>
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
@@ -48,7 +49,7 @@
|
||||
<tbody>
|
||||
<tr th:each="b : ${apps}">
|
||||
<td th:text="${b.workpackagesString}" th:unless="${bean}"></td>
|
||||
<td th:text="${b.name}"></td>
|
||||
<td><a th:href="@{/projectmanagement/app/{id}(id=${b.pkApp})}" th:text="${b.name}"></a></td>
|
||||
<td th:text="${b.description}"></td>
|
||||
<td><a th:href="${b.repositoryUrl}" target="_blank">gitlab</a></td>
|
||||
<td><a th:href="@{/projectmanagement/app/{id}/assign(id=${b.pkApp})}">zuordnen</a></td>
|
||||
|
||||
Reference in New Issue
Block a user