layout optimization
This commit is contained in:
		| @@ -0,0 +1,20 @@ | ||||
| package de.jottyfan.timetrack.spring.done; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class DoneBean implements Serializable, Comparable<DoneBean>{ | ||||
|  | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(DoneBean bean) { | ||||
| 		// TODO: implement | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,63 @@ | ||||
| package de.jottyfan.timetrack.spring.done; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.annotation.security.RolesAllowed; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.ui.Model; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMethod; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @Controller | ||||
| public class DoneController { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(DoneController.class); | ||||
|  | ||||
| 	private final HttpServletRequest request; | ||||
|  | ||||
| 	@Autowired | ||||
| 	private IDoneService doneService; | ||||
|  | ||||
| 	@Autowired | ||||
| 	public DoneController(HttpServletRequest request) { | ||||
| 		this.request = request; | ||||
| 	} | ||||
|  | ||||
| 	@RolesAllowed("timetrack_user") | ||||
| 	@RequestMapping(value = "/done/list") | ||||
| 	public String getList(Model model) { | ||||
| 		List<DoneBean> list = doneService.getList(); | ||||
| 		model.addAttribute("doneList", list); | ||||
| 		return "done/list"; | ||||
| 	} | ||||
|  | ||||
| 	@RolesAllowed("timetrack_user") | ||||
| 	@RequestMapping(value = "/done/add", method = RequestMethod.GET) | ||||
| 	public String toAdd(Model model) { | ||||
| 		return toItem(null, model); | ||||
| 	} | ||||
|  | ||||
| 	@RolesAllowed("timetrack_user") | ||||
|   @GetMapping("/done/edit/{id}") | ||||
| 	public String toItem(@PathVariable Integer id, Model model) { | ||||
| 		DoneBean bean = doneService.getBean(id); | ||||
| 		if (bean == null) { | ||||
| 			bean = new DoneBean(); // the add case | ||||
| 		} | ||||
| 		model.addAttribute("doneBean", bean); | ||||
| //		model.addAttribute("types", Arrays.asList(EnumNotetype.values())); | ||||
| //		model.addAttribute("categories", Arrays.asList(EnumCategory.values())); | ||||
| 		return "done/item"; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| package de.jottyfan.timetrack.spring.done; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public interface IDoneService { | ||||
| 	public List<DoneBean> getList(); | ||||
|  | ||||
| 	public DoneBean getBean(Integer id); | ||||
|  | ||||
| 	public String getCurrentUser(HttpServletRequest request); | ||||
| } | ||||
| @@ -0,0 +1,57 @@ | ||||
| package de.jottyfan.timetrack.spring.done.impl; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.DSLContext; | ||||
| import org.keycloak.KeycloakSecurityContext; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import de.jottyfan.timetrack.spring.done.DoneBean; | ||||
| import de.jottyfan.timetrack.spring.done.IDoneService; | ||||
| import de.jottyfan.timetrack.spring.note.NoteBean; | ||||
| import de.jottyfan.timetrack.spring.note.impl.NoteGateway; | ||||
| import de.jottyfan.timetrack.spring.note.impl.NoteService; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @Service | ||||
| @Transactional(transactionManager = "transactionManager") | ||||
| public class DoneService implements IDoneService { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(NoteService.class); | ||||
|  | ||||
| 	@Autowired | ||||
| 	private DSLContext dsl; | ||||
| 	 | ||||
| 	@Override | ||||
|   public String getCurrentUser(HttpServletRequest request) { | ||||
| 		KeycloakSecurityContext ksc = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); | ||||
| 		return ksc == null ? "" : ksc.getIdToken().getPreferredUsername(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public List<DoneBean> getList() { | ||||
| //		try { | ||||
| //			return new DoneGateway(dsl).getAll(); | ||||
| //		} catch (Exception e) { | ||||
| //			LOGGER.error(e); | ||||
| 			return new ArrayList<>(); | ||||
| //		} | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public DoneBean getBean(Integer id) { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -1,91 +0,0 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.note.enums.EnumCategory; | ||||
| import de.jottyfan.timetrack.db.note.enums.EnumNotetype; | ||||
| import de.jottyfan.timetrack.modules.Bean; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class NoteBean implements Bean, Serializable | ||||
| { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private final Integer pk; | ||||
| 	private String title; | ||||
| 	private EnumCategory category; | ||||
| 	private EnumNotetype type; | ||||
| 	private String content; | ||||
| 	private LocalDateTime lastchange; | ||||
|  | ||||
| 	public NoteBean(Integer pk) | ||||
| 	{ | ||||
| 		super(); | ||||
| 		this.pk = pk; | ||||
| 	} | ||||
|  | ||||
| 	public String getTitle() | ||||
| 	{ | ||||
| 		return title; | ||||
| 	} | ||||
|  | ||||
| 	public void setTitle(String title) | ||||
| 	{ | ||||
| 		this.title = title; | ||||
| 	} | ||||
|  | ||||
| 	public EnumCategory getCategory() | ||||
| 	{ | ||||
| 		return category; | ||||
| 	} | ||||
|  | ||||
| 	public void setCategory(EnumCategory category) | ||||
| 	{ | ||||
| 		this.category = category; | ||||
| 	} | ||||
|  | ||||
| 	public EnumNotetype getType() | ||||
| 	{ | ||||
| 		return type; | ||||
| 	} | ||||
|  | ||||
| 	public void setType(EnumNotetype type) | ||||
| 	{ | ||||
| 		this.type = type; | ||||
| 	} | ||||
|  | ||||
| 	public String getContent() | ||||
| 	{ | ||||
| 		return content; | ||||
| 	} | ||||
|  | ||||
| 	public void setContent(String content) | ||||
| 	{ | ||||
| 		this.content = content; | ||||
| 	} | ||||
|  | ||||
| 	public LocalDateTime getLastchange() | ||||
| 	{ | ||||
| 		return lastchange; | ||||
| 	} | ||||
|  | ||||
| 	public void setLastchange(LocalDateTime lastchange) | ||||
| 	{ | ||||
| 		this.lastchange = lastchange; | ||||
| 	} | ||||
|  | ||||
| 	public static long getSerialversionuid() | ||||
| 	{ | ||||
| 		return serialVersionUID; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getPk() | ||||
| 	{ | ||||
| 		return pk; | ||||
| 	} | ||||
| } | ||||
| @@ -1,104 +0,0 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.enterprise.context.RequestScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import de.jooqfaces.JooqFacesContext; | ||||
| import de.jottyfan.timetrack.help.Navigation; | ||||
| import de.jottyfan.timetrack.help.Pages; | ||||
| import de.jottyfan.timetrack.modules.ControlInterface; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  *  | ||||
|  */ | ||||
| @Named | ||||
| @RequestScoped | ||||
| public class NoteControl extends Navigation implements ControlInterface, Serializable | ||||
| { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@Inject | ||||
| 	@Named("noteModel") | ||||
| 	private NoteModel model; | ||||
|  | ||||
| 	public String toStart() | ||||
| 	{ | ||||
| 		return navigateTo(Pages.START); | ||||
| 	} | ||||
| 	 | ||||
| 	public String toList() | ||||
| 	{ | ||||
| 		boolean ready = model.init((JooqFacesContext) FacesContext.getCurrentInstance()); | ||||
| 		return ready ? navigateTo(Pages.NOTE_LIST) : ""; | ||||
| 	} | ||||
|  | ||||
| 	public String toItem(NoteBean bean) | ||||
| 	{ | ||||
| 		model.setBean(bean); | ||||
| 		return navigateTo(Pages.NOTE_ITEM); | ||||
| 	} | ||||
| 	 | ||||
| 	public String toAdd() | ||||
| 	{ | ||||
| 		return toItem(new NoteBean(null)); | ||||
| 	} | ||||
|  | ||||
| 	public String doAdd() | ||||
| 	{ | ||||
| 		boolean ready = model.add((JooqFacesContext) FacesContext.getCurrentInstance()); | ||||
| 		return ready ? toList() : toItem(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doUpdate() | ||||
| 	{ | ||||
| 		boolean ready = model.update((JooqFacesContext) FacesContext.getCurrentInstance()); | ||||
| 		return ready ? toList() : toItem(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doDelete() | ||||
| 	{ | ||||
| 		boolean ready = model.delete((JooqFacesContext) FacesContext.getCurrentInstance()); | ||||
| 		return ready ? toList() : toItem(model.getBean()); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * trim s to maxLength; if s > maxLength, append ... | ||||
| 	 *  | ||||
| 	 * @param s | ||||
| 	 * @param maxLength | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public String trimTo(String s, Integer maxLength) | ||||
| 	{ | ||||
| 		if (s == null) | ||||
| 		{ | ||||
| 			return s; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			String firstLine = s.contains("\n") ? s.substring(0, s.indexOf("\n")) : s; | ||||
| 			if (firstLine.length() > maxLength) | ||||
| 			{ | ||||
| 				return firstLine.substring(0, maxLength).concat("..."); | ||||
| 			} | ||||
| 			else if (s.contains("\n")) | ||||
| 			{ | ||||
| 				return firstLine.concat("..."); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				return firstLine; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public Long getAmount() { | ||||
| 		return model.getAmount((JooqFacesContext) FacesContext.getCurrentInstance()); | ||||
| 	} | ||||
| } | ||||
| @@ -1,125 +0,0 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import static de.jottyfan.timetrack.db.note.Tables.T_NOTE; | ||||
|  | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.CloseableDSLContext; | ||||
| import org.jooq.DeleteConditionStep; | ||||
| import org.jooq.InsertValuesStep4; | ||||
| import org.jooq.Record; | ||||
| import org.jooq.SelectJoinStep; | ||||
| import org.jooq.UpdateConditionStep; | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jooqfaces.JooqFacesContext; | ||||
| import de.jottyfan.timetrack.db.note.enums.EnumCategory; | ||||
| import de.jottyfan.timetrack.db.note.enums.EnumNotetype; | ||||
| import de.jottyfan.timetrack.db.note.tables.records.TNoteRecord; | ||||
| import de.jottyfan.timetrack.modules.JooqGateway; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class NoteGateway extends JooqGateway { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(NoteGateway.class); | ||||
|  | ||||
| 	public NoteGateway(JooqFacesContext facesContext) { | ||||
| 		super(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * insert into t_note | ||||
| 	 *  | ||||
| 	 * @param noteBean | ||||
| 	 * @throws DataAccessException | ||||
| 	 * @throws SQLException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 * @returns amount of affected rows in db | ||||
| 	 */ | ||||
| 	public void insert(NoteBean bean) throws DataAccessException, ClassNotFoundException, SQLException { | ||||
| 		try (CloseableDSLContext jooq = getJooq()) { | ||||
| 			InsertValuesStep4<TNoteRecord, String, EnumCategory, EnumNotetype, String> sql = jooq | ||||
| 			// @formatter:off | ||||
| 				.insertInto(T_NOTE,  | ||||
| 										T_NOTE.TITLE,  | ||||
| 										T_NOTE.CATEGORY,  | ||||
| 										T_NOTE.NOTETYPE,  | ||||
| 										T_NOTE.CONTENT) | ||||
| 				.values(bean.getTitle(), bean.getCategory(), bean.getType(), bean.getContent()); | ||||
| 		  // @formatter:on | ||||
| 			LOGGER.debug(sql.toString()); | ||||
| 			sql.execute(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * update content of bean | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 * @throws DataAccessException | ||||
| 	 * @throws SQLException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 */ | ||||
| 	public void update(NoteBean bean) throws DataAccessException, ClassNotFoundException, SQLException { | ||||
| 		try (CloseableDSLContext jooq = getJooq()) { | ||||
| 			UpdateConditionStep<TNoteRecord> sql = jooq | ||||
| 			// @formatter:off | ||||
| 				.update(T_NOTE) | ||||
| 				.set(T_NOTE.TITLE, bean.getTitle()) | ||||
| 				.set(T_NOTE.CONTENT, bean.getContent()) | ||||
| 				.where(T_NOTE.PK.eq(bean.getPk())); | ||||
| 			// @formatter:on | ||||
| 			LOGGER.debug(sql.toString()); | ||||
| 			sql.execute(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * delete from t_note | ||||
| 	 *  | ||||
| 	 * @param pk | ||||
| 	 * @throws DataAccessException | ||||
| 	 * @throws SQLException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 */ | ||||
| 	public void delete(Integer pk) throws DataAccessException, ClassNotFoundException, SQLException { | ||||
| 		try (CloseableDSLContext jooq = getJooq()) { | ||||
| 			DeleteConditionStep<TNoteRecord> sql = jooq.deleteFrom(T_NOTE).where(T_NOTE.PK.eq(pk)); | ||||
| 			LOGGER.debug(sql.toString()); | ||||
| 			sql.execute(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all from t_note | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 * @throws DataAccessException | ||||
| 	 * @throws SQLException  | ||||
| 	 * @throws ClassNotFoundException  | ||||
| 	 */ | ||||
| 	public List<NoteBean> getAll() throws DataAccessException, ClassNotFoundException, SQLException { | ||||
| 		try (CloseableDSLContext jooq = getJooq()) { | ||||
| 			SelectJoinStep<Record> sql = jooq.select().from(T_NOTE); | ||||
| 			LOGGER.debug(sql.toString()); | ||||
| 			List<NoteBean> list = new ArrayList<>(); | ||||
| 			for (Record r : sql.fetch()) { | ||||
| 				NoteBean bean = new NoteBean(r.get(T_NOTE.PK)); | ||||
| 				bean.setTitle(r.get(T_NOTE.TITLE)); | ||||
| 				bean.setCategory(r.get(T_NOTE.CATEGORY)); | ||||
| 				bean.setContent(r.get(T_NOTE.CONTENT)); | ||||
| 				bean.setType(r.get(T_NOTE.NOTETYPE)); | ||||
| 				bean.setLastchange(r.get(T_NOTE.LASTCHANGE)); | ||||
| 				list.add(bean); | ||||
| 			} | ||||
| 			return list; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -1,112 +0,0 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.sql.SQLException; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.enterprise.context.SessionScoped; | ||||
| import javax.faces.application.FacesMessage; | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jooqfaces.JooqFacesContext; | ||||
| import de.jottyfan.timetrack.db.note.Tables; | ||||
| import de.jottyfan.timetrack.modules.Model; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @Named | ||||
| @SessionScoped | ||||
| public class NoteModel implements Model, Serializable | ||||
| { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private List<NoteBean> beans; | ||||
| 	private NoteBean bean; | ||||
|  | ||||
| 	public boolean init(JooqFacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			beans = new NoteGateway(facesContext).getAll(); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException | ClassNotFoundException | SQLException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean add(JooqFacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).insert(bean); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException | ClassNotFoundException | SQLException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean update(JooqFacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).update(bean); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException | ClassNotFoundException | SQLException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean delete(JooqFacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).delete(bean.getPk()); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException | ClassNotFoundException | SQLException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public Long getAmount(JooqFacesContext facesContext) | ||||
| 	{ | ||||
| 		try { | ||||
| 			return new NoteGateway(facesContext).getAmount(Tables.T_NOTE); | ||||
| 		} catch (ClassNotFoundException | SQLException e) { | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return -1l; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public NoteBean getBean() | ||||
| 	{ | ||||
| 		return bean; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setBean(NoteBean bean) | ||||
| 	{ | ||||
| 		this.bean = bean; | ||||
| 	} | ||||
|  | ||||
| 	public List<NoteBean> getBeans() | ||||
| 	{ | ||||
| 		return beans; | ||||
| 	} | ||||
| } | ||||
| @@ -7,6 +7,31 @@ body { | ||||
| 	height: calc(100% - 56px); | ||||
| } | ||||
|  | ||||
| .titlemod { | ||||
| 	font-weight: bolder; | ||||
| 	color: darkcyan !important; | ||||
| 	font-variant: small-caps; | ||||
| } | ||||
|  | ||||
| .navlinkstyle { | ||||
| 	color: black; | ||||
| } | ||||
|  | ||||
| .navlinkstyle:hover { | ||||
| 	color: #1a5fb4; | ||||
| } | ||||
|  | ||||
| .navback { | ||||
| 	background-color: ghostwhite; | ||||
| } | ||||
|  | ||||
| .tabdivblurred { | ||||
| 	padding: 8px; | ||||
| 	padding-bottom: 0px; | ||||
| 	background-color: rgba(255, 255, 255, 0.5); | ||||
| 	height: calc(100% - 42px); | ||||
| } | ||||
|  | ||||
| .float-right { | ||||
| 	float: right; | ||||
| } | ||||
| @@ -16,7 +41,7 @@ body { | ||||
| } | ||||
|  | ||||
| .glassy { | ||||
| 	background-color: rgba(1,1,1,0.1); | ||||
| 	background-color: rgba(0, 0, 0s, 0.1); | ||||
| } | ||||
|  | ||||
| .formpane { | ||||
| @@ -47,7 +72,6 @@ body { | ||||
|  | ||||
| .page { | ||||
| 	width: 100%; | ||||
| 	padding-bottom: 12px; | ||||
| 	background-image: linear-gradient(to bottom, #99c1f1, #1a5f64) !important; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,65 +5,60 @@ | ||||
| <title>Kontakte</title> | ||||
| </head> | ||||
| <body> | ||||
| 	<ul layout:fragment="title"> | ||||
| 		<li class="nav-item"><a class="nav-link titlemod">Kontakte</a></li> | ||||
| 	</ul> | ||||
| 	<ul layout:fragment="menu"> | ||||
| 		<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/contact/add}">Neuen | ||||
| 				Kontakt anlegen</a></li> | ||||
| 	</ul> | ||||
| 	<main layout:fragment="content"> | ||||
| 		<div class="accordion" id="acdiv"> | ||||
| 			<div class="accordion-item glassy"> | ||||
| 				<h2 class="accordion-header" id="headingDashboard"> | ||||
| 					<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#dashboard" aria-expanded="true" | ||||
| 						aria-controls="dashboard">Dashboard</button> | ||||
| 				</h2> | ||||
| 				<div id="dashboard" class="accordion-collapse collapse show" aria-labelledby="headingDashboard" data-bs-parent="#acdiv"> | ||||
| 					<div class="accordion-body"> | ||||
| 						<div class="row row-cols-12 ro-cols-lg-4 ro-cols-md-3 ro-cols-sd-2 g-4" style="margin: 8px"> | ||||
| 							<div class="col" th:each="contact : ${contactList}"> | ||||
| 								<div class="card text-dark bg-light shadow" style="width: 18rem"> | ||||
| 									<div class="card-header text-center"> | ||||
| 										<font th:text="${contact.forename} + ' ' + ${contact.surname}" style="font-size: larger"></font> | ||||
| 									</div> | ||||
| 									<div class="card-body"> | ||||
| 										<div class="d-flex justify-content-center align-items-center"> | ||||
| 											<span th:text="${contact.type} + ': ' + ${contact.contact}"></span> <a | ||||
| 												th:href="@{/contact/edit/{id}(id=${contact.pk})}" sec:authorize="hasRole('timetrack_user')" | ||||
| 												style="margin-left: 8px;"> <i class="fa fa-edit"></i> | ||||
| 											</a> | ||||
| 										</div> | ||||
| 		<ul class="nav nav-tabs navback" role="tablist"> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_dashboard">Dashboard</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_list">Liste</a></li> | ||||
| 		</ul> | ||||
| 		<div class="tabdivblurred tab-content"> | ||||
| 			<div id="div_dashboard" class="tab-pane active"> | ||||
| 				<div class="accordion-body"> | ||||
| 					<div class="row row-cols-12 ro-cols-lg-4 ro-cols-md-3 ro-cols-sd-2 g-4" style="margin: 8px"> | ||||
| 						<div class="col" th:each="contact : ${contactList}"> | ||||
| 							<div class="card text-dark bg-light shadow" style="width: 18rem"> | ||||
| 								<div class="card-header text-center"> | ||||
| 									<font th:text="${contact.forename} + ' ' + ${contact.surname}" style="font-size: larger"></font> | ||||
| 								</div> | ||||
| 								<div class="card-body"> | ||||
| 									<div class="d-flex justify-content-center align-items-center"> | ||||
| 										<span th:text="${contact.type} + ': ' + ${contact.contact}"></span> <a | ||||
| 											th:href="@{/contact/edit/{id}(id=${contact.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;"> | ||||
| 											<i class="fa fa-edit"></i> | ||||
| 										</a> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="accordion-item glassy"> | ||||
| 					<h2 class="accordion-header" id="headingTable"> | ||||
| 						<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#list" | ||||
| 							aria-expanded="false" aria-controls="list">Liste</button> | ||||
| 					</h2> | ||||
| 					<div id="list" class="accordion-collapse collapse" aria-labelledby="headingTable" data-bs-parent="#acdiv"> | ||||
| 						<div class="accordion-body" style="background-color: white"> | ||||
| 							<table class="table table-striped table-condensed"> | ||||
| 								<thead> | ||||
| 									<tr> | ||||
| 										<th>Vorname</th> | ||||
| 										<th>Nachname</th> | ||||
| 										<th>Kontakt</th> | ||||
| 										<th>Typ</th> | ||||
| 									</tr> | ||||
| 								</thead> | ||||
| 								<tbody> | ||||
| 									<tr th:each="contact : ${contactList}"> | ||||
| 										<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.forename}"></span></a></td> | ||||
| 										<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.surname}"></span></a></td> | ||||
| 										<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.contact}"></span></a></td> | ||||
| 										<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.type}"></span></a></td> | ||||
| 									</tr> | ||||
| 								</tbody> | ||||
| 							</table> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 			</div> | ||||
| 			<div id="div_list" class="tab-pane fade"> | ||||
| 				<div class="accordion-body" style="background-color: white"> | ||||
| 					<table class="table table-striped table-condensed"> | ||||
| 						<thead> | ||||
| 							<tr> | ||||
| 								<th>Vorname</th> | ||||
| 								<th>Nachname</th> | ||||
| 								<th>Kontakt</th> | ||||
| 								<th>Typ</th> | ||||
| 							</tr> | ||||
| 						</thead> | ||||
| 						<tbody> | ||||
| 							<tr th:each="contact : ${contactList}"> | ||||
| 								<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.forename}"></span></a></td> | ||||
| 								<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.surname}"></span></a></td> | ||||
| 								<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.contact}"></span></a></td> | ||||
| 								<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.type}"></span></a></td> | ||||
| 							</tr> | ||||
| 						</tbody> | ||||
| 					</table> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
|   | ||||
							
								
								
									
										38
									
								
								src/main/resources/templates/done/list.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/main/resources/templates/done/list.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <!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>Notizen</title> | ||||
| </head> | ||||
| <body> | ||||
| 	<ul layout:fragment="title"> | ||||
| 		<li class="nav-item"><a class="nav-link titlemod">Arbeitszeit</a></li> | ||||
| 	</ul> | ||||
| 	<ul layout:fragment="menu"> | ||||
| 		<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/done/add}">Neuer | ||||
| 				Eintrag</a></li> | ||||
| 	</ul> | ||||
| 	<main layout:fragment="content"> | ||||
| 		<ul class="nav nav-tabs navback" role="tablist"> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_summary">Zusammenfassung</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_attachment">Anhang</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_calendar">Kalender</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Tätigkeit</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_budget">Abrechnung</a></li> | ||||
| 		</ul> | ||||
| 		<div class="tabdivblurred tab-content"> | ||||
| 			<div id="div_list" class="tab-pane active">Liste</div> | ||||
| 			<div id="div_summary" class="tab-pane fade">Zusammenfassung</div> | ||||
| 			<div id="div_attachment" class="tab-pane fade">Anhang</div> | ||||
| 			<div id="div_calendar" class="tab-pane fade">Kalender</div> | ||||
| 			<div id="div_project" class="tab-pane fade">Projekt</div> | ||||
| 			<div id="div_module" class="tab-pane fade">Modul</div> | ||||
| 			<div id="div_job" class="tab-pane fade">Tätigkeit</div> | ||||
| 			<div id="div_budget" class="tab-pane fade">Abrechnung</div> | ||||
| 		</div> | ||||
| 	</main> | ||||
| </body> | ||||
| </html> | ||||
| @@ -31,11 +31,13 @@ | ||||
| 					<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> | ||||
| 						<ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown"> | ||||
| 							<li><a class="dropdown-item" th:href="@{/done/list}">Arbeitszeit</a></li> | ||||
| 							<li><a class="dropdown-item" th:href="@{/contact/list}">Kontakte</a></li> | ||||
| 							<li><a class="dropdown-item" th:href="@{/note/list}">Notizen</a></li> | ||||
| 							<li><hr /></li> | ||||
| 							<li><a class="dropdown-item" th:href="@{/logout}">[[${currentUser}]] abmelden</a></li> | ||||
| 						</ul></li> | ||||
| 					<li layout:fragment="title" style="list-style-type: none"></li> | ||||
| 					<li layout:fragment="menu" style="list-style-type: none"></li> | ||||
| 				</ul> | ||||
| 			</div> | ||||
|   | ||||
| @@ -5,69 +5,62 @@ | ||||
| <title>Notizen</title> | ||||
| </head> | ||||
| <body> | ||||
| 	<ul layout:fragment="title"> | ||||
| 		<li class="nav-item"><a class="nav-link titlemod">Notizen</a></li> | ||||
| 	</ul> | ||||
| 	<ul layout:fragment="menu"> | ||||
| 		<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/note/add}">Neue Notiz | ||||
| 				anlegen</a></li> | ||||
| 	</ul> | ||||
| 	<main layout:fragment="content"> | ||||
| 		<div class="accordion" id="acdiv"> | ||||
| 			<div class="accordion-item noty"> | ||||
| 				<h2 class="accordion-header" id="headingDashboard"> | ||||
| 					<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#dashboard" aria-expanded="true" | ||||
| 						aria-controls="dashboard">Dashboard</button> | ||||
| 				</h2> | ||||
| 				<div id="dashboard" class="accordion-collapse collapse show" aria-labelledby="headingDashboard" data-bs-parent="#acdiv"> | ||||
| 					<div class="accordion-body"> | ||||
| 						<div class="row row-cols-12 ro-cols-lg-3 ro-cols-md-2 ro-cols-sd-1 g-4" style="margin: 8px"> | ||||
| 							<div class="col" th:each="note : ${noteList}"> | ||||
| 								<div class="card text-dark bg-light shadow" style="width: 100%"> | ||||
| 									<div class="card-header text-center"> | ||||
| 										<font th:text="${note.category}" style="font-size: larger">:</font> <font th:text="${note.title}" | ||||
| 											style="font-size: larger; font-weight: bolder"></font> | ||||
| 									</div> | ||||
| 									<div class="card-body"> | ||||
| 										<div class="d-flex justify-content-center align-items-center"> | ||||
| 											<pre th:text="${note.content}"></pre> | ||||
| 											<a th:href="@{/note/edit/{id}(id=${note.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;"> | ||||
| 												<i class="fa fa-edit"></i> | ||||
| 											</a> | ||||
| 										</div> | ||||
| 									</div> | ||||
| 									<div class="card-footer"> | ||||
| 										<span th:text="${note.type}"></span> | ||||
| 									</div> | ||||
| 		<ul class="nav nav-tabs navback" role="tablist"> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_dashboard">Dashboard</a></li> | ||||
| 			<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_list">Liste</a></li> | ||||
| 		</ul> | ||||
| 		<div class="tabdivblurred tab-content"> | ||||
| 			<div id="div_dashboard" class="tab-pane active"> | ||||
| 				<div class="row row-cols-12 ro-cols-lg-3 ro-cols-md-2 ro-cols-sd-1 g-4" style="margin: 8px"> | ||||
| 					<div class="col" th:each="note : ${noteList}"> | ||||
| 						<div class="card text-dark bg-light shadow" style="width: 100%"> | ||||
| 							<div class="card-header text-center"> | ||||
| 								<font th:text="${note.category}" style="font-size: larger">:</font> <font th:text="${note.title}" | ||||
| 									style="font-size: larger; font-weight: bolder"></font> | ||||
| 							</div> | ||||
| 							<div class="card-body"> | ||||
| 								<div class="d-flex justify-content-center align-items-center"> | ||||
| 									<pre th:text="${note.content}"></pre> | ||||
| 									<a th:href="@{/note/edit/{id}(id=${note.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;"> | ||||
| 										<i class="fa fa-edit"></i> | ||||
| 									</a> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 							<div class="card-footer"> | ||||
| 								<span th:text="${note.type}"></span> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="accordion-item glassy"> | ||||
| 					<h2 class="accordion-header" id="headingTable"> | ||||
| 						<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#list" | ||||
| 							aria-expanded="false" aria-controls="list">Liste</button> | ||||
| 					</h2> | ||||
| 					<div id="list" class="accordion-collapse collapse" aria-labelledby="headingTable" data-bs-parent="#acdiv"> | ||||
| 						<div class="accordion-body" style="background-color: white"> | ||||
| 							<table class="table table-striped table-condensed"> | ||||
| 								<thead> | ||||
| 									<tr> | ||||
| 										<th>Titel</th> | ||||
| 										<th>Kategorie</th> | ||||
| 										<th>Inhalt</th> | ||||
| 										<th>Typ</th> | ||||
| 									</tr> | ||||
| 								</thead> | ||||
| 								<tbody> | ||||
| 									<tr th:each="note : ${noteList}"> | ||||
| 										<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.title}"></span></a></td> | ||||
| 										<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.category}"></span></a></td> | ||||
| 										<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.content}"></span></a></td> | ||||
| 										<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.type}"></span></a></td> | ||||
| 									</tr> | ||||
| 								</tbody> | ||||
| 							</table> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 			</div> | ||||
| 			<div id="div_list" class="tab-pane fade"> | ||||
| 				<div class="accordion-body" style="background-color: white"> | ||||
| 					<table class="table table-striped table-condensed"> | ||||
| 						<thead> | ||||
| 							<tr> | ||||
| 								<th>Titel</th> | ||||
| 								<th>Kategorie</th> | ||||
| 								<th>Inhalt</th> | ||||
| 								<th>Typ</th> | ||||
| 							</tr> | ||||
| 						</thead> | ||||
| 						<tbody> | ||||
| 							<tr th:each="note : ${noteList}"> | ||||
| 								<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.title}"></span></a></td> | ||||
| 								<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.category}"></span></a></td> | ||||
| 								<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.content}"></span></a></td> | ||||
| 								<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.type}"></span></a></td> | ||||
| 							</tr> | ||||
| 						</tbody> | ||||
| 					</table> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user