added camp document editor, see #24

This commit is contained in:
Jottyfan
2025-10-22 23:04:52 +02:00
parent 13773f54de
commit a1fc517911
16 changed files with 353 additions and 59 deletions

View File

@@ -11,7 +11,6 @@ import org.springframework.security.oauth2.client.registration.InMemoryClientReg
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
/**
*
@@ -35,16 +34,11 @@ public class SecurityConfiguration {
// @formatter:off
.oauth2Login(o -> o.defaultSuccessUrl("/"))
.logout(o -> o.logoutSuccessHandler(new OidcClientInitiatedLogoutSuccessHandler(crr)))
.authorizeHttpRequests(o -> o.requestMatchers(
AntPathRequestMatcher.antMatcher("/dashboard/**"),
AntPathRequestMatcher.antMatcher("/business/**"),
AntPathRequestMatcher.antMatcher("/confirmation/**"),
AntPathRequestMatcher.antMatcher("/userlogin/**")
).authenticated()
.authorizeHttpRequests(o -> o.requestMatchers("/dashboard/**", "/business/**", "/confirmation/**","/userlogin/**").authenticated()
.anyRequest().permitAll())
.oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()))
.sessionManagement(o -> o.init(sec));
// @formatter:on
return sec.build();
}
}
}

View File

@@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import de.jottyfan.camporganizer.module.admin.model.CampBean;
import de.jottyfan.camporganizer.module.admin.model.CampDocumentBean;
import de.jottyfan.camporganizer.module.admin.model.DocumentBean;
import de.jottyfan.camporganizer.module.admin.model.LocationBean;
import de.jottyfan.camporganizer.module.camplist.CommonController;
@@ -192,4 +193,41 @@ public class AdminController extends CommonController {
redirect.addAttribute("error", error);
return error != null ? "redirect:/admin/camp/edit/" + id : "redirect:/admin/camp";
}
@GetMapping("/admin/campdocument")
public String getCampDocumentList(Model model, HttpServletRequest request) {
model.addAttribute("campmap", service.getCampMap());
model.addAttribute("documentmap", service.getDocumentsMap());
model.addAttribute("camps", service.getAllCamps());
model.addAttribute("documents", service.getDocumentsForCamps());
model.addAttribute("campdocuments", service.getAllCampDocuments());
model.addAttribute("campdocument", new CampDocumentBean());
return "/admin/campdocument";
}
@PostMapping("/admin/campdocument/add")
public String addCampDocument(@Valid @ModelAttribute("bean") CampDocumentBean bean, final BindingResult bindingResult,
Model model, HttpServletRequest request, RedirectAttributes redirect) {
if (bindingResult.hasErrors()) {
for (ObjectError error : bindingResult.getAllErrors()) {
LOGGER.error("error {}: {}", error.getCode(), error.getDefaultMessage());
}
model.addAttribute("campmap", service.getCampMap());
model.addAttribute("documentmap", service.getDocumentsMap());
model.addAttribute("camps", service.getAllCamps());
model.addAttribute("documents", service.getDocumentsForCamps());
model.addAttribute("campdocuments", service.getAllCampDocuments());
return "/admin/campdocument";
}
service.upsertCampDocument(bean);
return "redirect:/admin/campdocument";
}
@GetMapping("/admin/campdocument/delete/{id}")
public String deleteCampDocument(@PathVariable("id") Integer id, Model model, HttpServletRequest request,
RedirectAttributes redirect) {
service.deleteCampDocument(id);
return "redirect:/admin/campdocument";
}
}

View File

@@ -1,6 +1,7 @@
package de.jottyfan.camporganizer.module.admin;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPDOCUMENT;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENT;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENTROLE;
@@ -38,6 +39,7 @@ import org.jooq.UpdateSetMoreStep;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@@ -46,6 +48,7 @@ import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument;
import de.jottyfan.camporganizer.db.jooq.enums.EnumFiletype;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.tables.records.TCampRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TCampdocumentRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TCampprofileRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TDocumentRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TDocumentroleRecord;
@@ -53,6 +56,7 @@ import de.jottyfan.camporganizer.db.jooq.tables.records.TLocationRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TProfileRecord;
import de.jottyfan.camporganizer.module.admin.model.CampBean;
import de.jottyfan.camporganizer.module.admin.model.CampDocumentBean;
import de.jottyfan.camporganizer.module.admin.model.DocumentBean;
import de.jottyfan.camporganizer.module.admin.model.IntKeyValueBean;
import de.jottyfan.camporganizer.module.admin.model.LocationBean;
@@ -70,11 +74,17 @@ import jakarta.validation.Valid;
@Transactional(transactionManager = "transactionManager")
public class AdminRepository {
private final GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak;
private static final Logger LOGGER = LogManager.getLogger(AdminRepository.class);
@Autowired
private DSLContext jooq;
AdminRepository(GrantedAuthoritiesMapper userAuthoritiesMapperForKeycloak) {
this.userAuthoritiesMapperForKeycloak = userAuthoritiesMapperForKeycloak;
}
/**
* get the document with that ID
*
@@ -669,4 +679,64 @@ public class AdminRepository {
LOGGER.trace(sql);
sql.execute();
}
/**
* get all camp document beans
*
* @return a list of camp document beans; an empty list at least
*/
public List<CampDocumentBean> getAllCampDocuments() {
SelectWhereStep<TCampdocumentRecord> sql = jooq.selectFrom(T_CAMPDOCUMENT);
LOGGER.trace(sql);
return sql.fetchInto(CampDocumentBean.class);
}
/**
* add a camp document combination; if the combination already exists, ignore this
*
* @param fkCamp the camp id
* @param fkDocument the document id
*/
public void insertCampDocument(Integer fkCamp, Integer fkDocument) {
InsertReturningStep<TCampdocumentRecord> sql = jooq
// @formatter:off
.insertInto(T_CAMPDOCUMENT,
T_CAMPDOCUMENT.FK_CAMP,
T_CAMPDOCUMENT.FK_DOCUMENT)
.values(fkCamp, fkDocument)
.onConflict(T_CAMPDOCUMENT.FK_CAMP, T_CAMPDOCUMENT.FK_DOCUMENT)
.doNothing();
// @formatter:off
LOGGER.trace(sql);
sql.execute();
}
/**
* update the camp document combination
*
* @param pk the ID of the combination
* @param fkCamp the ID of the camp
* @param fkDocument the ID of the document
*/
public void updateCampDocument(Integer pk, Integer fkCamp, Integer fkDocument) {
UpdateConditionStep<TCampdocumentRecord> sql = jooq
// @formatter:off
.update(T_CAMPDOCUMENT)
.set(T_CAMPDOCUMENT.FK_CAMP, fkCamp)
.set(T_CAMPDOCUMENT.FK_DOCUMENT, fkDocument)
.where(T_CAMPDOCUMENT.PK.eq(pk));
// @formatter:on
LOGGER.trace(sql);
sql.execute();
}
/**
* delete from camp document
* @param id the ID of the camp document
*/
public void deleteCampDocument(Integer id) {
DeleteConditionStep<TCampdocumentRecord> sql = jooq.deleteFrom(T_CAMPDOCUMENT).where(T_CAMPDOCUMENT.PK.eq(id));
LOGGER.trace(sql);
sql.execute();
}
}

View File

@@ -4,8 +4,9 @@ import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENT;
import java.io.IOException;
import java.util.List;
import jakarta.validation.Valid;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -14,11 +15,13 @@ import org.springframework.stereotype.Service;
import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument;
import de.jottyfan.camporganizer.module.admin.model.CampBean;
import de.jottyfan.camporganizer.module.admin.model.CampDocumentBean;
import de.jottyfan.camporganizer.module.admin.model.DocumentBean;
import de.jottyfan.camporganizer.module.admin.model.LocationBean;
import de.jottyfan.camporganizer.module.admin.model.ProfileBean;
import de.jottyfan.camporganizer.module.mail.MailBean;
import de.jottyfan.camporganizer.module.mail.MailRepository;
import jakarta.validation.Valid;
/**
*
@@ -186,4 +189,62 @@ public class AdminService {
public String deleteCamp(Integer id) {
return adminRepository.deleteCamp(id);
}
/**
* get all camp documents
*
* @return a list of camp documents; an empty list at least
*/
public List<CampDocumentBean> getAllCampDocuments() {
return adminRepository.getAllCampDocuments();
}
/**
* get all documents for camps
*
* @return the list of documents for camps
*/
public List<DocumentBean> getDocumentsForCamps() {
return adminRepository.getAllDocumentsWith(T_DOCUMENT.DOCTYPE.eq(EnumDocument.camp));
}
/**
* get a map of camp beans
*
* @return the map
*/
public Map<Integer, CampBean> getCampMap() {
return getAllCamps().stream().collect(Collectors.toMap(CampBean::getPk, Function.identity()));
}
/**
* get a map of document beans
*
* @return the map
*/
public Map<Integer, DocumentBean> getDocumentsMap() {
return getAllDocuments().stream().collect(Collectors.toMap(DocumentBean::getPk, Function.identity()));
}
/**
* upsert a camp document bean
*
* @param bean the bean
*/
public void upsertCampDocument(@Valid CampDocumentBean bean) {
if (bean.getPk() == null) {
adminRepository.insertCampDocument(bean.getFkCamp(), bean.getFkDocument());
} else {
adminRepository.updateCampDocument(bean.getPk(), bean.getFkCamp(), bean.getFkDocument());
}
}
/**
* delete the camp document combination
*
* @param id the ID of the combination
*/
public void deleteCampDocument(Integer id) {
adminRepository.deleteCampDocument(id);
}
}

View File

@@ -94,6 +94,11 @@ public class CampBean implements Serializable {
return bean;
}
@Override
public String toString() {
return getFullname();
}
public String getFullname() {
return new StringBuilder().append(name).append(" ").append(arrive == null ? "?" : arrive.format(DateTimeFormatter.ofPattern("yyyy"))).toString();
}

View File

@@ -0,0 +1,58 @@
package de.jottyfan.camporganizer.module.admin.model;
import java.io.Serializable;
/**
*
* @author jotty
*
*/
public class CampDocumentBean implements Serializable {
private static final long serialVersionUID = 1L;
private Integer pk;
private Integer fkCamp;
private Integer fkDocument;
/**
* @return the pk
*/
public Integer getPk() {
return pk;
}
/**
* @param pk the pk to set
*/
public void setPk(Integer pk) {
this.pk = pk;
}
/**
* @return the fkCamp
*/
public Integer getFkCamp() {
return fkCamp;
}
/**
* @param fkCamp the fkCamp to set
*/
public void setFkCamp(Integer fkCamp) {
this.fkCamp = fkCamp;
}
/**
* @return the fkDocument
*/
public Integer getFkDocument() {
return fkDocument;
}
/**
* @param fkDocument the fkDocument to set
*/
public void setFkDocument(Integer fkDocument) {
this.fkDocument = fkDocument;
}
}

View File

@@ -51,6 +51,13 @@ public class DocumentBean implements Serializable{
}
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append(name).append(".").append(filetype);
return buf.toString();
}
public Integer getPk() {
return pk;
}