finalized contacts

This commit is contained in:
Jörg Henke
2022-04-09 14:42:58 +02:00
parent 9fe9555853
commit 4e966ed56e
9 changed files with 146 additions and 57 deletions

View File

@ -12,12 +12,17 @@ import de.jottyfan.timetrack.db.contact.enums.EnumContacttype;
public class ContactBean implements Serializable, Comparable<ContactBean> { public class ContactBean implements Serializable, Comparable<ContactBean> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final Integer pk; private Integer pk;
private String forename; private String forename;
private String surname; private String surname;
private String contact; private String contact;
private EnumContacttype type; private EnumContacttype type;
public ContactBean() {
super();
this.pk = null;
}
public ContactBean(Integer pk) { public ContactBean(Integer pk) {
super(); super();
this.pk = pk; this.pk = pk;
@ -77,4 +82,7 @@ public class ContactBean implements Serializable, Comparable<ContactBean> {
return pk; return pk;
} }
public void setPk(Integer pk) {
this.pk = pk;
}
} }

View File

@ -1,5 +1,6 @@
package de.jottyfan.timetrack.spring.contact; package de.jottyfan.timetrack.spring.contact;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.annotation.security.RolesAllowed; import javax.annotation.security.RolesAllowed;
@ -18,6 +19,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import de.jottyfan.timetrack.db.contact.enums.EnumContacttype;
/** /**
* *
* @author henkej * @author henkej
@ -55,36 +58,44 @@ public class ContactController {
} }
@RolesAllowed("timetrack_user") @RolesAllowed("timetrack_user")
@RequestMapping(value = "/contact/contacts") @RequestMapping(value = "/contact/list")
public String getList(Model model, @ModelAttribute ContactBean bean) { public String getList(Model model) {
List<ContactBean> list = contactService.toList(); List<ContactBean> list = contactService.getList();
model.addAttribute("contactList", list); model.addAttribute("contactList", list);
return "contact/contacts"; return "contact/list";
} }
@RolesAllowed("timetrack_user") @RolesAllowed("timetrack_user")
@RequestMapping(value = "/contact/add/") @RequestMapping(value = "/contact/add", method = RequestMethod.GET)
public String toAdd(Model model) { public String toAdd(Model model) {
return "contact/item"; return toItem(null, model);
}
@RolesAllowed("timetrack_user")
@RequestMapping(value = "/contact/insert", method = RequestMethod.POST)
public String doInsert(Model model, @ModelAttribute ContactBean bean) {
Integer amount = contactService.doInsert(bean);
return amount.equals(1) ? "contact/contacts" : "concact/item";
} }
@RolesAllowed("timetrack_user") @RolesAllowed("timetrack_user")
@GetMapping("/contact/edit/{id}") @GetMapping("/contact/edit/{id}")
public String toEdit(@PathVariable Integer id, Model model) { public String toItem(@PathVariable Integer id, Model model) {
return "not yet implemented"; ContactBean bean = contactService.getBean(id);
if (bean == null) {
bean = new ContactBean(); // the add case
}
model.addAttribute("contactBean", bean);
model.addAttribute("types", Arrays.asList(EnumContacttype.values()));
return "contact/item";
} }
@RolesAllowed("timetrack_user") @RolesAllowed("timetrack_user")
@RequestMapping(value = "/contact/delete/") @RequestMapping(value = "/contact/upsert", method = RequestMethod.POST)
public String doDelete(Model model, @ModelAttribute ContactBean bean) { public String doUpsert(Model model, @ModelAttribute ContactBean bean) {
Integer amount = contactService.doDelete(bean.getPk()); Integer amount = contactService.doUpsert(bean);
return amount.equals(1) ? "contact/contacts" : "contact/contacts"; return amount.equals(1) ? getList(model) : toItem(bean.getPk(), model);
}
@RolesAllowed("timetrack_user")
@GetMapping(value = "/contact/delete/{id}")
public String doDelete(@PathVariable Integer id, Model model) {
LOGGER.info("up to delete bean {}", id);
Integer amount = contactService.doDelete(id);
LOGGER.info("deleted {} rows", amount);
return amount.equals(1) ? getList(model) : toItem(id, model);
} }
} }

View File

@ -10,10 +10,10 @@ import javax.servlet.http.HttpServletRequest;
* *
*/ */
public interface IContactService { public interface IContactService {
public List<ContactBean> toList(); public List<ContactBean> getList();
public Integer doInsert(ContactBean bean); public Integer doUpsert(ContactBean bean);
public Integer doUdate(ContactBean bean);
public Integer doDelete(Integer pk); public Integer doDelete(Integer pk);
public Integer getAmount(); public Integer getAmount();
public String getCurrentUser(HttpServletRequest request); public String getCurrentUser(HttpServletRequest request);
public ContactBean getBean(Integer id);
} }

View File

@ -14,6 +14,7 @@ import org.jooq.DeleteConditionStep;
import org.jooq.InsertValuesStep4; import org.jooq.InsertValuesStep4;
import org.jooq.Record1; import org.jooq.Record1;
import org.jooq.Record5; import org.jooq.Record5;
import org.jooq.SelectConditionStep;
import org.jooq.SelectJoinStep; import org.jooq.SelectJoinStep;
import org.jooq.UpdateConditionStep; import org.jooq.UpdateConditionStep;
import org.jooq.exception.DataAccessException; import org.jooq.exception.DataAccessException;
@ -166,4 +167,27 @@ public class ContactGateway {
public List<EnumContacttype> getTypes() { public List<EnumContacttype> getTypes() {
return new ArrayList<>(Arrays.asList(EnumContacttype.values())); return new ArrayList<>(Arrays.asList(EnumContacttype.values()));
} }
public ContactBean getBean(Integer id) {
SelectConditionStep<Record5<Integer, String, String, String, EnumContacttype>> sql = getJooq()
// @formatter:off
.select(T_CONTACT.PK,
T_CONTACT.FORENAME,
T_CONTACT.SURNAME,
T_CONTACT.CONTACT,
T_CONTACT.TYPE)
.from(T_CONTACT)
.where(T_CONTACT.PK.eq(id));
// @formatter:on
LOGGER.debug("{}", sql.toString());
for (Record5<Integer, String, String, String, EnumContacttype> r : sql.fetch()) {
ContactBean bean = new ContactBean(r.get(T_CONTACT.PK));
bean.setForename(r.get(T_CONTACT.FORENAME));
bean.setSurname(r.get(T_CONTACT.SURNAME));
bean.setContact(r.get(T_CONTACT.CONTACT));
bean.setType(r.get(T_CONTACT.TYPE));
return bean;
}
return null;
}
} }

View File

@ -36,7 +36,7 @@ public class ContactService implements IContactService {
} }
@Override @Override
public List<ContactBean> toList() { public List<ContactBean> getList() {
try { try {
return new ContactGateway(dsl).getAll(); return new ContactGateway(dsl).getAll();
} catch (Exception e) { } catch (Exception e) {
@ -46,19 +46,10 @@ public class ContactService implements IContactService {
} }
@Override @Override
public Integer doInsert(ContactBean bean) { public Integer doUpsert(ContactBean bean) {
try { try {
return new ContactGateway(dsl).add(bean); ContactGateway gw = new ContactGateway(dsl);
} catch (Exception e) { return bean.getPk() == null ? gw.add(bean) : gw.update(bean);
LOGGER.error(e);
return 0;
}
}
@Override
public Integer doUdate(ContactBean bean) {
try {
return new ContactGateway(dsl).update(bean);
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e); LOGGER.error(e);
return 0; return 0;
@ -77,6 +68,16 @@ public class ContactService implements IContactService {
@Override @Override
public Integer getAmount() { public Integer getAmount() {
return toList().size(); return getList().size();
}
@Override
public ContactBean getBean(Integer id) {
try {
return new ContactGateway(dsl).getBean(id);
} catch (Exception e) {
LOGGER.error(e);
return null;
}
} }
} }

View File

@ -3,10 +3,30 @@ html {
} }
body { body {
background-color: #eee; background-color: #99c1f1;
height: calc(100% - 76px); height: calc(100% - 76px);
} }
.formpane {
margin: 24px;
border: 1px solid silver;
border-radius: 4px;
padding: 24px;
background: whitesmoke;
}
.menudangerbutton {
color: #e00 !important;
border: 1px solid rgba(0,0,0,0);
}
.menudangerbutton:hover {
color: #f00 !important;
border: 1px solid silver;
border-radius: 4px;
background: rgba(255,0,0,0.2);
}
.body { .body {
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -14,11 +34,9 @@ body {
} }
.page { .page {
height: 100%;
width: 100%; width: 100%;
padding-bottom: 12px; padding-bottom: 12px;
background-image: linear-gradient(to bottom, #eee, #777) background-image: linear-gradient(to bottom, #99c1f1, #1a5f64) !important;
!important;
} }
.emph { .emph {

View File

@ -6,26 +6,53 @@
</head> </head>
<body> <body>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/contact/contacts}">abbrechen</a></li> <li class="nav-item dropdown menudangerbutton" sec:authorize="hasRole('timetrack_user')"><a class="nav-link dropdown-toggle" href="#"
id="navbarScrollingDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">Eintrag löschen</a>
<ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown">
<li><a class="dropdown-item" th:href="@{/contact/delete/{id}(id=${contactBean.pk})}">endgültig löschen</a></li>
</ul></li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
<div class="container"> <div class="container formpane">
<form th:action="@{/contact/insert}" th:object="${contactBean}" method="post"> <form th:action="@{/contact/upsert}" th:object="${contactBean}" method="post">
<p> <div class="row mb-3">
Inhalt von Eintrag <span th:text="*{pk}"></span>: <label for="inputPk" class="col-sm-2 col-form-label">Inhalt von Eintrag</label>
</p> <div class="col-sm-10">
<input type="hidden" th:field="*{pk}" /> <input id="inputPk" type="text" th:field="*{pk}" class="form-control" readonly="readonly" />
<div class="form-group"> </div>
<label>Vorname</label> <input type="text" th:field="*{forename}" class="form-control" />
</div> </div>
<div class="form-group"> <div class="row mb-3">
<label>Nachname</label> <input type="text" th:field="*{surname}" class="form-control" /> <label for="inputForename" class="col-sm-2 col-form-label">Vorname</label>
<div class="col-sm-10">
<input id="inputForename" type="text" th:field="*{forename}" class="form-control" />
</div>
</div> </div>
<div class="form-group"> <div class="row mb-3">
<label>Kontakt</label> <input type="text" th:field="*{contact}" class="form-control" /> <label for="inputSurname" class="col-sm-2 col-form-label">Nachname</label>
<div class="col-sm-10">
<input id="inputSurname" type="text" th:field="*{surname}" class="form-control" />
</div>
</div> </div>
<div class="form-group"> <div class="row mb-3">
<label>Typ</label> <input type="text" th:field="*{type}" class="form-control" /> <label for="inputContact" class="col-sm-2 col-form-label">Kontakt</label>
<div class="col-sm-10">
<input id="inputContact" type="text" th:field="*{contact}" class="form-control" />
</div>
</div>
<div class="row mb-3">
<label for="inputType" class="col-sm-2 col-form-label">Typ</label>
<div class="col-sm-10">
<select id="inputType" class="form-control select2-single" th:field="*{type}">
<option th:each="i : ${types}" th:value="${i}" th:text="${i.literal}"></option>
</select>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-2">Änderung</div>
<div class="col-sm-10">
<button type="submit" class="btn btn-success">speichern</button>
<button type="submit" class="btn btn-danger" th:formaction="@{/contact/list}">verwerfen</button>
</div>
</div> </div>
</form> </form>
</div> </div>

View File

@ -32,7 +32,7 @@
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarScrollingDropdown" role="button" <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarScrollingDropdown" role="button"
data-bs-toggle="dropdown" aria-expanded="false"> Module </a> data-bs-toggle="dropdown" aria-expanded="false"> Module </a>
<ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown"> <ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown">
<li><a class="dropdown-item" th:href="@{/contact/contacts}">Kontakte</a></li> <li><a class="dropdown-item" th:href="@{/contact/list}">Kontakte</a></li>
<li><hr /></li> <li><hr /></li>
<li><a class="dropdown-item" th:href="@{/logout}">[[${currentUser}]] abmelden</a></li> <li><a class="dropdown-item" th:href="@{/logout}">[[${currentUser}]] abmelden</a></li>
</ul></li> </ul></li>