prepared file upload
This commit is contained in:
		| @@ -18,7 +18,7 @@ apply plugin: 'war' | |||||||
| apply plugin: 'application' | apply plugin: 'application' | ||||||
|  |  | ||||||
| group = 'de.jottyfan.camporganizer' | group = 'de.jottyfan.camporganizer' | ||||||
| version = '0.2.8' | version = '0.2.9' | ||||||
| sourceCompatibility = 17 | sourceCompatibility = 17 | ||||||
| mainClassName = "de.jottyfan.camporganizer.Main" | mainClassName = "de.jottyfan.camporganizer.Main" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import org.springframework.validation.BindingResult; | |||||||
| import org.springframework.validation.ObjectError; | import org.springframework.validation.ObjectError; | ||||||
| import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||||
| import org.springframework.web.bind.annotation.ModelAttribute; | import org.springframework.web.bind.annotation.ModelAttribute; | ||||||
|  | import org.springframework.web.bind.annotation.PathVariable; | ||||||
| import org.springframework.web.bind.annotation.PostMapping; | import org.springframework.web.bind.annotation.PostMapping; | ||||||
|  |  | ||||||
| import de.jottyfan.camporganizer.module.camplist.CommonController; | import de.jottyfan.camporganizer.module.camplist.CommonController; | ||||||
| @@ -34,6 +35,17 @@ public class AdminController extends CommonController { | |||||||
| 	@Value("${spring.mail.username}") | 	@Value("${spring.mail.username}") | ||||||
| 	private String from; | 	private String from; | ||||||
|  |  | ||||||
|  | 	@GetMapping("/admin") | ||||||
|  | 	public String getMain(Model model, HttpServletRequest request) { | ||||||
|  | 		super.setupSession(model, request); | ||||||
|  | 		return "/admin/main"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@GetMapping("/admin/main") | ||||||
|  | 	public String getMainDirectly() { | ||||||
|  | 		return "redirect:/admin/main"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	@GetMapping("/admin/mail") | 	@GetMapping("/admin/mail") | ||||||
| 	public String getMail(Model model, HttpServletRequest request) { | 	public String getMail(Model model, HttpServletRequest request) { | ||||||
| 		super.setupSession(model, request); | 		super.setupSession(model, request); | ||||||
| @@ -57,14 +69,37 @@ public class AdminController extends CommonController { | |||||||
| 		return "redirect:/admin"; | 		return "redirect:/admin"; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@GetMapping("/admin") | 	@GetMapping("/admin/document") | ||||||
| 	public String getMain(Model model, HttpServletRequest request) { | 	public String getDocuments(Model model, HttpServletRequest request) { | ||||||
| 		super.setupSession(model, request); | 		super.setupSession(model, request); | ||||||
| 		return "/admin/main"; | 		model.addAttribute("documents", service.getAllDocuments()); | ||||||
|  | 		return "/admin/document"; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	@GetMapping("/admin/main") | 	@GetMapping("/admin/document/add") | ||||||
| 	public String getMainDirectly() { | 	public String prepareAddDocument(Model model, HttpServletRequest request) { | ||||||
| 		return "redirect:/admin/main"; | 		super.setupSession(model, request); | ||||||
|  | 		model.addAttribute("bean", new DocumentBean()); | ||||||
|  | 		return "/admin/document_edit"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@GetMapping("/admin/document/edit/{id}") | ||||||
|  | 	public String prepareAddDocument(@PathVariable Integer id, Model model, HttpServletRequest request) { | ||||||
|  | 		super.setupSession(model, request); | ||||||
|  | 		model.addAttribute("bean", service.getDocument(id)); | ||||||
|  | 		return "/admin/document_edit"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	@PostMapping("/admin/document/update") | ||||||
|  | 	public String updateDocument(@Valid @ModelAttribute("bean") DocumentBean bean, | ||||||
|  | 			final BindingResult bindingResult, Model model, HttpServletRequest request) { | ||||||
|  | 		super.setupSession(model, request); | ||||||
|  | 		if (bindingResult.hasErrors()) { | ||||||
|  | 			for (ObjectError error : bindingResult.getAllErrors()) | ||||||
|  | 				LOGGER.error("error {}: {}", error.getCode(), error.getDefaultMessage()); | ||||||
|  | 			return "/admin/document_edit"; | ||||||
|  | 		} | ||||||
|  | 		service.updateDocument(bean); | ||||||
|  | 		return "redirect:/admin/document"; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,186 @@ | |||||||
|  | package de.jottyfan.camporganizer.module.admin; | ||||||
|  |  | ||||||
|  | import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENT; | ||||||
|  | import static de.jottyfan.camporganizer.db.jooq.Tables.T_DOCUMENTROLE; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.jooq.DSLContext; | ||||||
|  | import org.jooq.DeleteConditionStep; | ||||||
|  | import org.jooq.Field; | ||||||
|  | import org.jooq.InsertResultStep; | ||||||
|  | import org.jooq.InsertReturningStep; | ||||||
|  | import org.jooq.Record5; | ||||||
|  | import org.jooq.SelectSeekStep1; | ||||||
|  | import org.jooq.UpdateConditionStep; | ||||||
|  | import org.jooq.exception.DataAccessException; | ||||||
|  | import org.jooq.impl.DSL; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.stereotype.Repository; | ||||||
|  | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumFiletype; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.tables.records.TDocumentRecord; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.tables.records.TDocumentroleRecord; | ||||||
|  | import de.jottyfan.camporganizer.module.camplist.LambdaResultWrapper; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | @Repository | ||||||
|  | @Transactional(transactionManager = "transactionManager") | ||||||
|  | public class AdminRepository { | ||||||
|  |  | ||||||
|  | 	private static final Logger LOGGER = LogManager.getLogger(AdminRepository.class); | ||||||
|  |  | ||||||
|  | 	@Autowired | ||||||
|  | 	private DSLContext jooq; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * get the document with that ID | ||||||
|  | 	 * | ||||||
|  | 	 * @param id the ID of the document | ||||||
|  | 	 * @return the document | ||||||
|  | 	 */ | ||||||
|  | 	public DocumentBean getDocument(Integer id) { | ||||||
|  | 		Field<EnumCamprole[]> ROLES = DSL.field("roles", EnumCamprole[].class); | ||||||
|  | 		SelectSeekStep1<Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]>, Integer> sql = jooq | ||||||
|  | 		// @formatter:off | ||||||
|  | 			.select(T_DOCUMENT.PK, | ||||||
|  | 					    T_DOCUMENT.NAME, | ||||||
|  | 					    T_DOCUMENT.DOCTYPE, | ||||||
|  | 					    T_DOCUMENT.FILETYPE, | ||||||
|  | 					    DSL.arrayAgg(T_DOCUMENTROLE.CAMPROLE).as(ROLES)) | ||||||
|  | 			.from(T_DOCUMENT) | ||||||
|  | 			.leftJoin(T_DOCUMENTROLE).on(T_DOCUMENTROLE.FK_DOCUMENT.eq(T_DOCUMENT.PK)) | ||||||
|  | 			.where(T_DOCUMENT.PK.eq(id)) | ||||||
|  | 			.groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE) | ||||||
|  | 			.orderBy(T_DOCUMENT.PK); | ||||||
|  | 		// @formatter:on | ||||||
|  | 		LOGGER.debug(sql.toString()); | ||||||
|  | 		Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]> r = sql.fetchOne(); | ||||||
|  | 		if (r != null ) { | ||||||
|  | 			DocumentBean bean = new DocumentBean(); | ||||||
|  | 			bean.setPk(r.get(T_DOCUMENT.PK)); | ||||||
|  | 			bean.setName(r.get(T_DOCUMENT.NAME)); | ||||||
|  | 			bean.setDoctype(r.get(T_DOCUMENT.DOCTYPE)); | ||||||
|  | 			bean.setFiletype(r.get(T_DOCUMENT.FILETYPE)); | ||||||
|  | 			bean.setRoles(r.get(ROLES)); | ||||||
|  | 			return bean; | ||||||
|  | 		} | ||||||
|  | 		return null; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * get all documents from the database | ||||||
|  | 	 * | ||||||
|  | 	 * @return all documents | ||||||
|  | 	 */ | ||||||
|  | 	public List<DocumentBean> getAllDocuments() { | ||||||
|  | 		Field<EnumCamprole[]> ROLES = DSL.field("roles", EnumCamprole[].class); | ||||||
|  | 		SelectSeekStep1<Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]>, Integer> sql = jooq | ||||||
|  | 		// @formatter:off | ||||||
|  | 			.select(T_DOCUMENT.PK, | ||||||
|  | 					    T_DOCUMENT.NAME, | ||||||
|  | 					    T_DOCUMENT.DOCTYPE, | ||||||
|  | 					    T_DOCUMENT.FILETYPE, | ||||||
|  | 					    DSL.arrayAgg(T_DOCUMENTROLE.CAMPROLE).as(ROLES)) | ||||||
|  | 			.from(T_DOCUMENT) | ||||||
|  | 			.leftJoin(T_DOCUMENTROLE).on(T_DOCUMENTROLE.FK_DOCUMENT.eq(T_DOCUMENT.PK)) | ||||||
|  | 			.groupBy(T_DOCUMENT.PK, T_DOCUMENT.NAME, T_DOCUMENT.DOCTYPE, T_DOCUMENT.FILETYPE) | ||||||
|  | 			.orderBy(T_DOCUMENT.PK); | ||||||
|  | 		// @formatter:on | ||||||
|  | 		LOGGER.debug(sql.toString()); | ||||||
|  | 		List<DocumentBean> list = new ArrayList<>(); | ||||||
|  | 		for (Record5<Integer, String, EnumDocument, EnumFiletype, EnumCamprole[]> r : sql.fetch()) { | ||||||
|  | 			DocumentBean bean = new DocumentBean(); | ||||||
|  | 			bean.setPk(r.get(T_DOCUMENT.PK)); | ||||||
|  | 			bean.setName(r.get(T_DOCUMENT.NAME)); | ||||||
|  | 			bean.setDoctype(r.get(T_DOCUMENT.DOCTYPE)); | ||||||
|  | 			bean.setFiletype(r.get(T_DOCUMENT.FILETYPE)); | ||||||
|  | 			bean.setRoles(r.get(ROLES)); | ||||||
|  | 			list.add(bean); | ||||||
|  | 		} | ||||||
|  | 		return list; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * upsert document in t_document | ||||||
|  | 	 * | ||||||
|  | 	 * @param document | ||||||
|  | 	 * @throws DataAccessException | ||||||
|  | 	 */ | ||||||
|  | 	public Integer upsert(DocumentBean bean) throws DataAccessException { | ||||||
|  | 		LambdaResultWrapper lrw = new LambdaResultWrapper(); | ||||||
|  | 		jooq.transaction(c -> { | ||||||
|  | 			Integer pk = bean.getPk(); | ||||||
|  | 			if (bean.getPk() != null) { | ||||||
|  | 				UpdateConditionStep<TDocumentRecord> sql = DSL.using(c) | ||||||
|  | 				// @formatter:off | ||||||
|  | 					.update(T_DOCUMENT) | ||||||
|  | 					.set(T_DOCUMENT.NAME, bean.getName()) | ||||||
|  | 					.set(T_DOCUMENT.DOCTYPE, bean.getDoctype()) | ||||||
|  | 					.set(T_DOCUMENT.DOCUMENT, bean.getDocument()) | ||||||
|  | 					.set(T_DOCUMENT.FILETYPE, bean.getFiletype()) | ||||||
|  | 					.where(T_DOCUMENT.PK.eq(bean.getPk())); | ||||||
|  | 			  // @formatter:on | ||||||
|  | 				LOGGER.debug("{}", sql.toString()); | ||||||
|  | 				lrw.add(sql.execute()); | ||||||
|  | 			} else { | ||||||
|  | 				InsertResultStep<TDocumentRecord> sql = DSL.using(c) | ||||||
|  | 				// @formatter:off | ||||||
|  | 				  .insertInto(T_DOCUMENT, | ||||||
|  | 				  		        T_DOCUMENT.NAME, | ||||||
|  | 				  		        T_DOCUMENT.DOCTYPE, | ||||||
|  | 				  		        T_DOCUMENT.DOCUMENT, | ||||||
|  | 				  		        T_DOCUMENT.FILETYPE) | ||||||
|  | 				  .values(bean.getName(), bean.getDoctype(), bean.getDocument(), bean.getFiletype()) | ||||||
|  | 				  .returning(T_DOCUMENT.PK); | ||||||
|  | 		  	// @formatter:on | ||||||
|  | 				LOGGER.debug("{}", sql.toString()); | ||||||
|  | 				pk = sql.fetchOne().get(T_DOCUMENT.PK); | ||||||
|  | 				lrw.add(1); | ||||||
|  | 			} | ||||||
|  | 			List<EnumCamprole> allEnums = Arrays.asList(EnumCamprole.values()); | ||||||
|  | 			Set<EnumCamprole> removeCandidates = new HashSet<>(); | ||||||
|  | 			removeCandidates.addAll(allEnums); | ||||||
|  | 			for (EnumCamprole role : bean.getRoles()) { | ||||||
|  | 				try { | ||||||
|  | 					InsertReturningStep<TDocumentroleRecord> sql = DSL.using(c) | ||||||
|  | 					// @formatter:off | ||||||
|  | 				  	.insertInto(T_DOCUMENTROLE, | ||||||
|  | 				  			        T_DOCUMENTROLE.FK_DOCUMENT, | ||||||
|  | 				  			        T_DOCUMENTROLE.CAMPROLE) | ||||||
|  | 				  	.values(pk, role) | ||||||
|  | 				  	.onConflict(T_DOCUMENTROLE.FK_DOCUMENT, T_DOCUMENTROLE.CAMPROLE) | ||||||
|  | 				  	.doNothing(); | ||||||
|  | 				  // @formatter:on | ||||||
|  | 					LOGGER.debug("{}", sql.toString()); | ||||||
|  | 					lrw.add(sql.execute()); | ||||||
|  | 					removeCandidates.remove(role); | ||||||
|  | 				} catch (IllegalArgumentException e) { | ||||||
|  | 					LOGGER.error(e); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			DeleteConditionStep<TDocumentroleRecord> sql = DSL.using(c) | ||||||
|  | 			// @formatter:off | ||||||
|  | 				.deleteFrom(T_DOCUMENTROLE) | ||||||
|  | 				.where(T_DOCUMENTROLE.FK_DOCUMENT.eq(pk)) | ||||||
|  | 				.and(T_DOCUMENTROLE.CAMPROLE.in(removeCandidates)); | ||||||
|  | 			// @formatter:on | ||||||
|  | 			LOGGER.debug("{}", sql.toString()); | ||||||
|  | 			lrw.add(sql.execute()); | ||||||
|  | 		}); | ||||||
|  | 		return lrw.getCounter(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -1,5 +1,7 @@ | |||||||
| package de.jottyfan.camporganizer.module.admin; | package de.jottyfan.camporganizer.module.admin; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
|  |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
| @@ -19,8 +21,39 @@ public class AdminService { | |||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private MailRepository mailRepository; | 	private MailRepository mailRepository; | ||||||
|  |  | ||||||
|  | 	@Autowired | ||||||
|  | 	private AdminRepository adminRepository; | ||||||
|  |  | ||||||
| 	public void sendMail(@Valid MailBean bean) { | 	public void sendMail(@Valid MailBean bean) { | ||||||
| 		mailRepository.sendMail(bean); | 		mailRepository.sendMail(bean); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * get all documents | ||||||
|  | 	 * | ||||||
|  | 	 * @return a list of documents; an empty one at least | ||||||
|  | 	 */ | ||||||
|  | 	public List<DocumentBean> getAllDocuments() { | ||||||
|  | 		return adminRepository.getAllDocuments(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * get document from the database | ||||||
|  | 	 * | ||||||
|  | 	 * @param id the ID of the document | ||||||
|  | 	 * @return the document or null | ||||||
|  | 	 */ | ||||||
|  | 	public DocumentBean getDocument(Integer id) { | ||||||
|  | 		return adminRepository.getDocument(id); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * upsert the document bean | ||||||
|  | 	 * | ||||||
|  | 	 * @param bean the bean | ||||||
|  | 	 * @return the number of affected database lines | ||||||
|  | 	 */ | ||||||
|  | 	public Integer updateDocument(@Valid DocumentBean bean) { | ||||||
|  | 		return adminRepository.upsert(bean); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,107 @@ | |||||||
|  | package de.jottyfan.camporganizer.module.admin; | ||||||
|  |  | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.Serializable; | ||||||
|  | import java.util.Base64; | ||||||
|  |  | ||||||
|  | import javax.servlet.http.Part; | ||||||
|  | import javax.validation.constraints.NotBlank; | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
|  |  | ||||||
|  | import org.apache.commons.io.IOUtils; | ||||||
|  |  | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumDocument; | ||||||
|  | import de.jottyfan.camporganizer.db.jooq.enums.EnumFiletype; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * | ||||||
|  |  * @author jotty | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | public class DocumentBean implements Serializable{ | ||||||
|  |  | ||||||
|  | 	private static final long serialVersionUID = 1L; | ||||||
|  |  | ||||||
|  | 	private Integer pk; | ||||||
|  | 	@NotNull | ||||||
|  | 	private EnumDocument doctype; | ||||||
|  | 	@NotBlank | ||||||
|  | 	private String name; | ||||||
|  | 	private String document; | ||||||
|  | 	@NotNull | ||||||
|  | 	private EnumFiletype filetype; | ||||||
|  | 	@NotNull | ||||||
|  | 	private Part uploadfile; | ||||||
|  | 	private EnumCamprole[] roles; | ||||||
|  |  | ||||||
|  | 	public void encodeUpload() throws IOException { | ||||||
|  | 		if (uploadfile != null) { | ||||||
|  | 			InputStream inputStream = uploadfile.getInputStream(); | ||||||
|  | 			byte[] bytes = IOUtils.toByteArray(inputStream); | ||||||
|  | 			if (bytes.length > 0) { | ||||||
|  | 				document = Base64.getEncoder().encodeToString(bytes); | ||||||
|  | 			} // not uploaded files should not be changed, so document must be kept as is | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public Integer getPk() { | ||||||
|  | 		return pk; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setDoctype(EnumDocument doctype) { | ||||||
|  | 		this.doctype = doctype; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public EnumDocument getDoctype() { | ||||||
|  | 		return doctype; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setName(String name) { | ||||||
|  | 		this.name = name; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public String getName() { | ||||||
|  | 		return name; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setDocument(String document) { | ||||||
|  | 		this.document = document; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public String getDocument() { | ||||||
|  | 		return document; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setFiletype(EnumFiletype filetype) { | ||||||
|  | 		this.filetype = filetype; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public EnumFiletype getFiletype() { | ||||||
|  | 		return filetype; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public Part getUploadfile() { | ||||||
|  | 		return uploadfile; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setUploadfile(Part uploadfile) { | ||||||
|  | 		this.uploadfile = uploadfile; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public EnumCamprole[] getRoles() { | ||||||
|  | 		return roles; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public void setRoles(EnumCamprole[] roles) { | ||||||
|  | 		this.roles = roles; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * @param pk the pk to set | ||||||
|  | 	 */ | ||||||
|  | 	public void setPk(Integer pk) { | ||||||
|  | 		this.pk = pk; | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -34,8 +34,8 @@ import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class BookingsGateway { | public class BookingsRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(BookingsGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(BookingsRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -16,7 +16,7 @@ import de.jottyfan.camporganizer.module.business.bookings.IBookingsService; | |||||||
| public class BookingsService implements IBookingsService { | public class BookingsService implements IBookingsService { | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private BookingsGateway bookingsGateway; | 	private BookingsRepository bookingsGateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public List<BookerBean> getBookers(String username) { | 	public List<BookerBean> getBookers(String username) { | ||||||
|   | |||||||
| @@ -33,8 +33,8 @@ import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class BusinessGateway { | public class BusinessRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(BusinessGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(BusinessRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -19,7 +19,7 @@ import de.jottyfan.camporganizer.module.business.business.IBusinessService; | |||||||
| @Service | @Service | ||||||
| public class BusinessService implements IBusinessService { | public class BusinessService implements IBusinessService { | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private BusinessGateway gateway; | 	private BusinessRepository gateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public String getCurrentUser(HttpServletRequest request) { | 	public String getCurrentUser(HttpServletRequest request) { | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class CampGateway { | public class CampRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(CampGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(CampRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -17,7 +17,7 @@ import de.jottyfan.camporganizer.module.business.camp.ICampService; | |||||||
| public class CampService implements ICampService { | public class CampService implements ICampService { | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private CampGateway campGateway; | 	private CampRepository campGateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public CampBean getCamp(Integer id, String username) { | 	public CampBean getCamp(Integer id, String username) { | ||||||
|   | |||||||
| @@ -29,8 +29,8 @@ import de.jottyfan.camporganizer.db.jooq.tables.records.TSalesprofileRecord; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class PrivilegesGateway { | public class PrivilegesRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(PrivilegesGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(PrivilegesRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -18,7 +18,7 @@ import de.jottyfan.camporganizer.module.business.privileges.IPrivilegesService; | |||||||
| @Service | @Service | ||||||
| public class PrivilegesService implements IPrivilegesService { | public class PrivilegesService implements IPrivilegesService { | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private PrivilegesGateway gateway; | 	private PrivilegesRepository gateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public Map<Integer, CampBean> getPrivileges() { | 	public Map<Integer, CampBean> getPrivileges() { | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
|  |  | ||||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord; | import de.jottyfan.camporganizer.db.jooq.tables.records.VCampRecord; | ||||||
| import de.jottyfan.camporganizer.module.dashboard.DashboardGateway; | import de.jottyfan.camporganizer.module.dashboard.DashboardRepository; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
| @@ -27,7 +27,7 @@ public class CamplistService { | |||||||
| 	private CamplistGateway gateway; | 	private CamplistGateway gateway; | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DashboardGateway dashboardGateway; | 	private DashboardRepository dashboardGateway; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * get all camps from the database and prepare them for the view | 	 * get all camps from the database and prepare them for the view | ||||||
|   | |||||||
| @@ -38,8 +38,8 @@ import de.jottyfan.camporganizer.db.jooq.enums.EnumModule; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class ConfirmationGateway { | public class ConfirmationRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(ConfirmationGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(ConfirmationRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -19,7 +19,7 @@ import de.jottyfan.camporganizer.module.confirmation.confirmation.IConfirmationS | |||||||
| @Service | @Service | ||||||
| public class ConfirmationService implements IConfirmationService { | public class ConfirmationService implements IConfirmationService { | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private ConfirmationGateway gateway; | 	private ConfirmationRepository gateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public String getCurrentUser(HttpServletRequest request) { | 	public String getCurrentUser(HttpServletRequest request) { | ||||||
|   | |||||||
| @@ -46,8 +46,8 @@ import de.jottyfan.camporganizer.module.mail.MailRepository; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class PersonGateway { | public class PersonRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(PersonGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(PersonRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -15,7 +15,7 @@ import de.jottyfan.camporganizer.module.confirmation.person.IPersonService; | |||||||
| @Service | @Service | ||||||
| public class PersonService implements IPersonService { | public class PersonService implements IPersonService { | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private PersonGateway gateway; | 	private PersonRepository gateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public PersonBean getPerson(String username, Integer pk) { | 	public PersonBean getPerson(String username, Integer pk) { | ||||||
|   | |||||||
| @@ -31,8 +31,8 @@ import de.jottyfan.camporganizer.module.camplist.LambdaResultWrapper; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class DashboardGateway { | public class DashboardRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(DashboardGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(DashboardRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -30,8 +30,8 @@ import biweekly.property.Summary; | |||||||
| */ | */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class ICalGateway { | public class ICalRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(ICalGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(ICalRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -20,7 +20,7 @@ import de.jottyfan.camporganizer.module.ical.IICalService; | |||||||
| public class ICalService implements IICalService { | public class ICalService implements IICalService { | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private ICalGateway gateway; | 	private ICalRepository gateway; | ||||||
|  |  | ||||||
| 	@Override | 	@Override | ||||||
| 	public Boolean generate(HttpServletResponse response) throws IOException { | 	public Boolean generate(HttpServletResponse response) throws IOException { | ||||||
|   | |||||||
| @@ -53,8 +53,8 @@ import de.jottyfan.camporganizer.module.camplist.LambdaResultWrapper; | |||||||
|  */ |  */ | ||||||
| @Repository | @Repository | ||||||
| @Transactional(transactionManager = "transactionManager") | @Transactional(transactionManager = "transactionManager") | ||||||
| public class RegistrationGateway { | public class RegistrationRepository { | ||||||
| 	private static final Logger LOGGER = LogManager.getLogger(RegistrationGateway.class); | 	private static final Logger LOGGER = LogManager.getLogger(RegistrationRepository.class); | ||||||
| 
 | 
 | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private DSLContext jooq; | 	private DSLContext jooq; | ||||||
| @@ -17,7 +17,7 @@ public class RegistrationService { | |||||||
| 	private final static Logger LOGGER = LogManager.getLogger(RegistrationService.class); | 	private final static Logger LOGGER = LogManager.getLogger(RegistrationService.class); | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private RegistrationGateway gateway; | 	private RegistrationRepository gateway; | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private KeycloakRepository keycloak; | 	private KeycloakRepository keycloak; | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import javax.validation.ConstraintValidatorContext; | |||||||
| import org.springframework.beans.BeanWrapperImpl; | import org.springframework.beans.BeanWrapperImpl; | ||||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  |  | ||||||
| import de.jottyfan.camporganizer.module.registration.RegistrationGateway; | import de.jottyfan.camporganizer.module.registration.RegistrationRepository; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
| @@ -19,7 +19,7 @@ public class UnusedUsernameValidator implements ConstraintValidator<UnusedUserna | |||||||
| 	private String message; | 	private String message; | ||||||
|  |  | ||||||
| 	@Autowired | 	@Autowired | ||||||
| 	private RegistrationGateway gateway; | 	private RegistrationRepository gateway; | ||||||
|  |  | ||||||
| 	public void initialize(UnusedUsername uu) { | 	public void initialize(UnusedUsername uu) { | ||||||
| 		this.field = uu.field(); | 		this.field = uu.field(); | ||||||
|   | |||||||
| @@ -4,11 +4,16 @@ | |||||||
| 	font-weight: 700; | 	font-weight: 700; | ||||||
| 	font-display: swap; | 	font-display: swap; | ||||||
| 	src: url('../fonts/Cabin-Sketch-700.eot'); /* IE9 */ | 	src: url('../fonts/Cabin-Sketch-700.eot'); /* IE9 */ | ||||||
|   src: url('../fonts/Cabin-Sketch-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ | 	src: url('../fonts/Cabin-Sketch-700.eot?#iefix') | ||||||
|     url('../fonts/Cabin-Sketch-700.woff2') format('woff2'), /* Modern Browsers */ | 		format('embedded-opentype'), /* IE6-IE8 */ | ||||||
|     url('../fonts/Cabin-Sketch-700.woff') format('woff'), /* Modern Browsers */ |     url('../fonts/Cabin-Sketch-700.woff2') format('woff2'), | ||||||
|     url('../fonts/Cabin-Sketch-700.ttf') format('truetype'), /* Safari, Android, iOS */ | 		/* Modern Browsers */ | ||||||
|     url('../fonts/Cabin-Sketch-700.svg#CabinSketch') format('svg'); /* Legacy iOS */ |     url('../fonts/Cabin-Sketch-700.woff') format('woff'), | ||||||
|  | 		/* Modern Browsers */ | ||||||
|  |     url('../fonts/Cabin-Sketch-700.ttf') format('truetype'), | ||||||
|  | 		/* Safari, Android, iOS */ | ||||||
|  |     url('../fonts/Cabin-Sketch-700.svg#CabinSketch') format('svg'); | ||||||
|  | 	/* Legacy iOS */ | ||||||
| } | } | ||||||
|  |  | ||||||
| /* fira-sans-regular - latin */ | /* fira-sans-regular - latin */ | ||||||
| @@ -16,13 +21,18 @@ | |||||||
| 	font-family: 'Fira Sans'; | 	font-family: 'Fira Sans'; | ||||||
| 	font-style: normal; | 	font-style: normal; | ||||||
| 	font-weight: 400; | 	font-weight: 400; | ||||||
|   src: url('../fonts/fira-sans-v16-latin-regular.eot'); /* IE9 Compat Modes */ | 	src: url('../fonts/fira-sans-v16-latin-regular.eot'); | ||||||
|   src: local(''), | 	/* IE9 Compat Modes */ | ||||||
|        url('../fonts/fira-sans-v16-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ | 	src: local(''), url('../fonts/fira-sans-v16-latin-regular.eot?#iefix') | ||||||
|        url('../fonts/fira-sans-v16-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ | 		format('embedded-opentype'), /* IE6-IE8 */ | ||||||
|        url('../fonts/fira-sans-v16-latin-regular.woff') format('woff'), /* Modern Browsers */ |        url('../fonts/fira-sans-v16-latin-regular.woff2') format('woff2'), | ||||||
|        url('../fonts/fira-sans-v16-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ | 		/* Super Modern Browsers */ | ||||||
|        url('../fonts/fira-sans-v16-latin-regular.svg#FiraSans') format('svg'); /* Legacy iOS */ |        url('../fonts/fira-sans-v16-latin-regular.woff') format('woff'), | ||||||
|  | 		/* Modern Browsers */ | ||||||
|  |        url('../fonts/fira-sans-v16-latin-regular.ttf') | ||||||
|  | 		format('truetype'), /* Safari, Android, iOS */ | ||||||
|  |        url('../fonts/fira-sans-v16-latin-regular.svg#FiraSans') | ||||||
|  | 		format('svg'); /* Legacy iOS */ | ||||||
| } | } | ||||||
|  |  | ||||||
| html { | html { | ||||||
| @@ -34,6 +44,11 @@ body { | |||||||
| 	background-image: url('../images/background.jpg'); | 	background-image: url('../images/background.jpg'); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .navbar-background { | ||||||
|  | 	background-image: url('../images/background.jpg'); | ||||||
|  | 	background-repeat: no-repeat; | ||||||
|  | } | ||||||
|  |  | ||||||
| a { | a { | ||||||
| 	font-family: 'Fira Sans'; | 	font-family: 'Fira Sans'; | ||||||
| } | } | ||||||
| @@ -96,19 +111,23 @@ div { | |||||||
| } | } | ||||||
|  |  | ||||||
| .acc_over { | .acc_over { | ||||||
| 	background-image: linear-gradient(to bottom right, #ccc, #aaa) !important; | 	background-image: linear-gradient(to bottom right, #ccc, #aaa) | ||||||
|  | 		!important; | ||||||
| } | } | ||||||
|  |  | ||||||
| .acc_true { | .acc_true { | ||||||
| 	background-image: linear-gradient(to bottom right, #cfc, #afa) !important; | 	background-image: linear-gradient(to bottom right, #cfc, #afa) | ||||||
|  | 		!important; | ||||||
| } | } | ||||||
|  |  | ||||||
| .acc_false { | .acc_false { | ||||||
| 	background-image: linear-gradient(to bottom right, #fcc, #faa) !important; | 	background-image: linear-gradient(to bottom right, #fcc, #faa) | ||||||
|  | 		!important; | ||||||
| } | } | ||||||
|  |  | ||||||
| .acc_null { | .acc_null { | ||||||
| 	background-image: linear-gradient(to bottom right, #fdb, #fca) !important; | 	background-image: linear-gradient(to bottom right, #fdb, #fca) | ||||||
|  | 		!important; | ||||||
| } | } | ||||||
|  |  | ||||||
| .right-dist { | .right-dist { | ||||||
| @@ -360,3 +379,19 @@ div { | |||||||
| 	text-align: center; | 	text-align: center; | ||||||
| 	padding-top: 45vh; | 	padding-top: 45vh; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .roleflag { | ||||||
|  | 	border-radius: 24px; | ||||||
|  | 	border: 1px solid gray; | ||||||
|  | 	padding: 4px; | ||||||
|  | 	margin: 2px; | ||||||
|  | 	background-image: linear-gradient(to right bottom, silver, white); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tablebox { | ||||||
|  | 	margin: 8px; | ||||||
|  | 	background-color: rgba(255, 255, 255, 0.5) !important; | ||||||
|  | 	padding: 6px; | ||||||
|  | 	border-radius: 8px; | ||||||
|  | 	border: 1px solid gray; | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								src/main/resources/templates/admin/document.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/main/resources/templates/admin/document.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> | ||||||
|  | <body> | ||||||
|  | 	<th:block layout:fragment="header"> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/rss/admin}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/admin}" class="btn btn-secondary btn-icon-silent">Administration</a></li> | ||||||
|  | 		</ul> | ||||||
|  | 	</th:block> | ||||||
|  | 	<th:block layout:fragment="content"> | ||||||
|  | 		<div class="tablebox" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<table id="docs" class="table table-striped" style="width: 100% !important"> | ||||||
|  | 				<thead> | ||||||
|  | 					<tr> | ||||||
|  | 						<td>Name</td> | ||||||
|  | 						<td>Dokumententyp</td> | ||||||
|  | 						<td>Zielgruppe</td> | ||||||
|  | 						<th>Inhalt</th> | ||||||
|  | 						<th>Dateityp</th> | ||||||
|  | 					</tr> | ||||||
|  | 				</thead> | ||||||
|  | 				<tbody> | ||||||
|  | 					<tr th:each="d : ${documents}"> | ||||||
|  | 						<td><a th:href="@{/admin/document/edit/{id}(id=${d.pk})}"><span th:text="${d.name}"></span></a></td> | ||||||
|  | 						<td><span th:if="${d.doctype.literal == 'location'}">Wegbeschreibung</span> <span th:if="${d.doctype.literal == 'camp'}">Bestätigung</span><span | ||||||
|  | 							th:if="${d.doctype.literal == 'camppass'}">Freizeitpass</span></td> | ||||||
|  | 						<td><th:block th:each="r : ${d.roles}"> | ||||||
|  | 								<span th:if="${r.literal == 'student'}" class="roleflag">Teilnehmer</span> | ||||||
|  | 								<span th:if="${r.literal == 'teacher'}" class="roleflag">Mitarbeiter</span> | ||||||
|  | 								<span th:if="${r.literal == 'director'}" class="roleflag">Leiter</span> | ||||||
|  | 								<span th:if="${r.literal == 'feeder'}" class="roleflag">Küche</span> | ||||||
|  | 							</th:block></td> | ||||||
|  | 						<td><a th:href="@{/document/{id}(id=${d.pk})}"><i class="fas fa-download"></i></a></td> | ||||||
|  | 						<td><span th:text="${d.filetype.literal}" th:if="${d.filetype}"></span></td> | ||||||
|  | 					</tr> | ||||||
|  | 				</tbody> | ||||||
|  | 				<tfoot> | ||||||
|  | 					<tr> | ||||||
|  | 						<td colspan="6" style="text-align: center"><a th:href="@{/admin/document/add}" class="btn btn-outline-primary">neues Dokument anlegen</a></td> | ||||||
|  | 					</tr> | ||||||
|  | 				</tfoot> | ||||||
|  | 			</table> | ||||||
|  | 			<script> | ||||||
|  | 				$(document).ready(function() { | ||||||
|  | 					$("#docs").DataTable({ | ||||||
|  | 						language : locale_de | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			</script> | ||||||
|  | 		</div> | ||||||
|  | 	</th:block> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										92
									
								
								src/main/resources/templates/admin/document_edit.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/main/resources/templates/admin/document_edit.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> | ||||||
|  | <body> | ||||||
|  | 	<th:block layout:fragment="header"> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/rss/admin}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/admin}" class="btn btn-secondary btn-icon-silent">Administration</a></li> | ||||||
|  | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/admin/document}" class="btn btn-secondary btn-icon-silent">Dokumente</a></li> | ||||||
|  | 		</ul> | ||||||
|  | 	</th:block> | ||||||
|  | 	<th:block layout:fragment="content"> | ||||||
|  | 		<div sec:authorize="hasRole('admin')"> | ||||||
|  | 			<form th:action="@{/admin/document/update}" th:object="${bean}" method="post" enctype="multipart/form-data"> | ||||||
|  | 				<div class="tablebox"> | ||||||
|  | 					<div class="container"> | ||||||
|  | 						<input type="hidden" th:field="*{pk}" /> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<label for="inputName" class="col-sm-2 col-form-label">Name</label> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<span class="error" th:each="error : ${#fields.errors('name')}">[[${error}]]<br /></span> <input id="inputName" type="text" th:field="*{name}" | ||||||
|  | 									th:class="${'form-control ' + (#fields.hasErrors('name') ? 'inputerror' : '')}"> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<label for="inputDoctype" class="col-sm-2 col-form-label">Dokumententyp</label> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<span class="error" th:each="error : ${#fields.errors('doctype')}">[[${error}]]<br /></span> <select id="inputDoctype" th:field="*{doctype}" | ||||||
|  | 									th:class="${'form-select ' + (#fields.hasErrors('doctype') ? 'inputerror' : '')}"> | ||||||
|  | 									<option value="">--- bitte wählen ---</option> | ||||||
|  | 									<option value="location">Wegbeschreibung</option> | ||||||
|  | 									<option value="camp">Bestätigung</option> | ||||||
|  | 									<option value="camppass">Freizeitpass</option> | ||||||
|  | 								</select> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<label for="inputRole" class="col-sm-2 col-form-label">Zielgruppe</label> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<span class="error" th:each="error : ${#fields.errors('roles')}">[[${error}]]<br /></span> <select id="inputRole" th:field="*{roles}" | ||||||
|  | 									th:class="${'form-control ' + (#fields.hasErrors('roles') ? 'inputerror' : '')}" multiple> | ||||||
|  | 									<option value="student">Teilnehmer</option> | ||||||
|  | 									<option value="teacher">Mitarbeiter</option> | ||||||
|  | 									<option value="director">Leiter</option> | ||||||
|  | 									<option value="feeder">Küche</option> | ||||||
|  | 								</select> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<label for="inputFile" class="col-sm-2 col-form-label">Dokument</label> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<span class="error" th:each="error : ${#fields.errors('uploadfile')}">[[${error}]]<br /></span> | ||||||
|  | 								<input type="file" id="inputFile" th:field="*{uploadfile}" th:class="${'form-control ' + (#fields.hasErrors('uploadfile') ? 'inputerror' : '')}" /> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<label for="inputFiletype" class="col-sm-2 col-form-label">Dateityp</label> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<span class="error" th:each="error : ${#fields.errors('filetype')}">[[${error}]]<br /></span> <select id="inputFiletype" th:field="*{filetype}" | ||||||
|  | 									th:class="${'form-select ' + (#fields.hasErrors('filetype') ? 'inputerror' : '')}"> | ||||||
|  | 									<option value="">--- bitte wählen ---</option> | ||||||
|  | 									<option value="pdf">PDF</option> | ||||||
|  | 									<option value="png">PNG</option> | ||||||
|  | 									<option value="jpg">JPG</option> | ||||||
|  | 								</select> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="row mb-2"> | ||||||
|  | 							<div class="col-sm-2"></div> | ||||||
|  | 							<div class="col-sm-10"> | ||||||
|  | 								<input type="submit" class="btn btn-success" value="Ok" /> | ||||||
|  | 								<a th:href="@{/admin/document}" class="btn btn-outline-secondary">Abbrechen</a> | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<!-- TODO: | ||||||
|  |  | ||||||
|  | 								delete from db th:if="${bean.pk}" | ||||||
|  | 							--> | ||||||
|  |  | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
|  | 			</form> | ||||||
|  | 		</div> | ||||||
|  | 	</th:block> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
| 			<li class="nav-item"><a th:href="@{/admin}" class="btn btn-seconary btn-icon-silent">Admin</a></li> | 			<li class="nav-item"><a th:href="@{/admin}" class="btn btn-seconary btn-icon-silent">Admin</a></li> | ||||||
|   | |||||||
| @@ -10,15 +10,18 @@ | |||||||
| 			<li class="nav-item"><a th:href="@{/rss/admin}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | 			<li class="nav-item"><a th:href="@{/rss/admin}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
| 			<li class="nav-item"><a th:href="@{/admin/mail}" class="btn btn-secondary btn-icon-silent">Testmail</a></li> | 			<li class="nav-item"><a th:href="@{/admin/mail}" class="btn btn-secondary btn-icon-silent">Testmail</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
|  | 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||||
|  | 			<li class="nav-item"><a th:href="@{/admin/document}" class="btn btn-secondary btn-icon-silent">Dokumente</a></li> | ||||||
|  | 		</ul> | ||||||
| 	</th:block> | 	</th:block> | ||||||
| 	<th:block layout:fragment="content"> | 	<th:block layout:fragment="content"> | ||||||
| 		<div sec:authorize="hasRole('admin')"> | 		<div sec:authorize="hasRole('admin')"> | ||||||
| 			TODO: implement | 			TODO: implement; list number of camps, registrations and documents or such | ||||||
| 		</div> | 		</div> | ||||||
| 	</th:block> | 	</th:block> | ||||||
| </body> | </body> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/business/bookings}" class="btn btn-secondary btn-icon-silent" sec:authorize="hasRole('business_booking')">Buchungsübersicht</a></li> | 			<li class="nav-item"><a th:href="@{/business/bookings}" class="btn btn-secondary btn-icon-silent" sec:authorize="hasRole('business_booking')">Buchungsübersicht</a></li> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
| 	<th:block layout:fragment="header"> | 	<th:block layout:fragment="header"> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | 			<li class="nav-item"><a th:href="@{/business/}" class="btn btn-secondary btn-icon-silent">Finanzübersicht</a></li> | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| 			<li class="nav-item"><a th:href="@{/rss/registrator}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | 			<li class="nav-item"><a th:href="@{/rss/registrator}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | 			<li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
| 		</ul> | 		</ul> | ||||||
| 	</th:block> | 	</th:block> | ||||||
| 	<th:block layout:fragment="content"> | 	<th:block layout:fragment="content"> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| <body> | <body> | ||||||
|   <th:block layout:fragment="header"> |   <th:block layout:fragment="header"> | ||||||
|     <ul class="navbar-nav mb-2 mb-lg-0"> |     <ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
|       <li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> |       <li class="nav-item"><a th:href="@{/dashboard}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||||
|     </ul> |     </ul> | ||||||
|     <ul class="navbar-nav mb-2 mb-lg-0"> |     <ul class="navbar-nav mb-2 mb-lg-0"> | ||||||
|       <li class="nav-item"><a th:href="@{/confirmation}" class="btn btn-secondary btn-icon-silent">Anmeldungen</a></li> |       <li class="nav-item"><a th:href="@{/confirmation}" class="btn btn-secondary btn-icon-silent">Anmeldungen</a></li> | ||||||
|   | |||||||
| @@ -18,10 +18,10 @@ | |||||||
| <script th:src="@{/js/mytoggle.js}"></script> | <script th:src="@{/js/mytoggle.js}"></script> | ||||||
| <script th:src="@{/js/myAjax.js}"></script> | <script th:src="@{/js/myAjax.js}"></script> | ||||||
| <script th:src="@{/js/progress.js}"></script> | <script th:src="@{/js/progress.js}"></script> | ||||||
| <th:block layout:fragment="libs"></th:block> |  | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
| 	<nav class="navbar navbar-expand-lg bg-light"> | 	<nav class="navbar navbar-expand-lg bg-light navbar-background"> | ||||||
|  | 		<span class="navbar-brand"><img th:src="@{/images/logo.png}" width="128px" /></span> | ||||||
| 		<div class="container-fluid"> | 		<div class="container-fluid"> | ||||||
|     	<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"> |     	<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"> | ||||||
|       	<span class="navbar-toggler-icon"></span> |       	<span class="navbar-toggler-icon"></span> | ||||||
| @@ -41,7 +41,7 @@ | |||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 	</nav> | 	</nav> | ||||||
| 	<div layout:fragment="content">Layout content</div> | 	<div layout:fragment="content">content</div> | ||||||
| 	<div class="versionclip"> | 	<div class="versionclip"> | ||||||
| 		<a href="https://gitlab.com/jottyfan/camporganizer2/-/issues" class="versionlink" target="_blank" th:text="${'Version ' + @manifestBean.getVersion()}"></a> | 		<a href="https://gitlab.com/jottyfan/camporganizer2/-/issues" class="versionlink" target="_blank" th:text="${'Version ' + @manifestBean.getVersion()}"></a> | ||||||
| 	</div> | 	</div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user