from branch of project todolist
This commit is contained in:
		
							
								
								
									
										18
									
								
								src/main/java/de/jottyfan/timetrack/help/Application.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/main/java/de/jottyfan/timetrack/help/Application.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| package de.jottyfan.timetrack.help; | ||||
|  | ||||
| public enum Application | ||||
| { | ||||
| 	CONNECTION("connection"); | ||||
|  | ||||
| 	private final String value; | ||||
|  | ||||
| 	private Application(String value) | ||||
| 	{ | ||||
| 		this.value = value; | ||||
| 	} | ||||
|  | ||||
| 	public String get() | ||||
| 	{ | ||||
| 		return value; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										37
									
								
								src/main/java/de/jottyfan/timetrack/help/EncodingFilter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/main/java/de/jottyfan/timetrack/help/EncodingFilter.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| package de.jottyfan.timetrack.help; | ||||
|  | ||||
| import java.io.*; | ||||
|  | ||||
| import javax.servlet.*; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  *  | ||||
|  */ | ||||
| public class EncodingFilter implements Filter | ||||
| { | ||||
| 	private String encoding; | ||||
|  | ||||
| 	@Override | ||||
| 	public void destroy() | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException | ||||
| 	{ | ||||
| 		servletRequest.setCharacterEncoding(encoding); | ||||
| 		filterChain.doFilter(servletRequest, servletResponse); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void init(FilterConfig filterConfig) throws ServletException | ||||
| 	{ | ||||
| 		encoding = filterConfig.getInitParameter("encoding"); | ||||
| 		if (encoding == null) | ||||
| 		{ | ||||
| 			encoding = "UTF-8"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/main/java/de/jottyfan/timetrack/help/Navigation.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/main/java/de/jottyfan/timetrack/help/Navigation.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| package de.jottyfan.timetrack.help; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public abstract class Navigation | ||||
| { | ||||
| 	/** | ||||
| 	 * navigate to page referenced by p | ||||
| 	 *  | ||||
| 	 * @param p | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public String navigateTo(Pages p) | ||||
| 	{ | ||||
| 		return p.get(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										90
									
								
								src/main/java/de/jottyfan/timetrack/help/Pages.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/main/java/de/jottyfan/timetrack/help/Pages.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| package de.jottyfan.timetrack.help; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public enum Pages | ||||
| { | ||||
| 	/** | ||||
| 	 * contact list | ||||
| 	 */ | ||||
| 	CONTACT_LIST("/pages/contact/list.jsf"), | ||||
| 	/** | ||||
| 	 * contact item | ||||
| 	 */ | ||||
| 	CONTACT_ITEM("/pages/contact/item.jsf"), | ||||
| 	/** | ||||
| 	 * note list | ||||
| 	 */ | ||||
| 	NOTE_LIST("/pages/note/list.jsf"), | ||||
| 	/** | ||||
| 	 * note item | ||||
| 	 */ | ||||
| 	NOTE_ITEM("/pages/note/item.jsf"), | ||||
| 	/** | ||||
| 	 * todo list | ||||
| 	 */ | ||||
| 	TODO_LIST("/pages/todo/list.jsf"),  | ||||
| 	/** | ||||
| 	 * todo item | ||||
| 	 */ | ||||
| 	TODO_ITEM("/pages/todo/item.jsf"), | ||||
| 	/** | ||||
| 	 * done init | ||||
| 	 */ | ||||
| 	DONE_INIT("/pages/done/init.jsf"), | ||||
| 	/** | ||||
| 	 * done edit | ||||
| 	 */ | ||||
| 	DONE_EDIT("/pages/done/edit.jsf"), | ||||
| 	/** | ||||
| 	 * done delete | ||||
| 	 */ | ||||
| 	DONE_DELETE("/pages/done/delete.jsf"), | ||||
| 	/** | ||||
| 	 * done add | ||||
| 	 */ | ||||
| 	DONE_ADD("/pages/done/add.jsf"), | ||||
| 	/** | ||||
| 	 * done clear | ||||
| 	 */ | ||||
| 	DONE_CLEAR("/pages/done/clear.jsf"), | ||||
| 	/** | ||||
| 	 * organize init | ||||
| 	 */ | ||||
| 	ORGANIZE_LIST("/pages/organize/list.jsf"), | ||||
| 	/** | ||||
| 	 * organize week | ||||
| 	 */ | ||||
| 	ORGANIZE_WEEK("/pages/organize/week.jsf"), | ||||
| 	/** | ||||
| 	 * organize delete | ||||
| 	 */ | ||||
| 	ORGANIZE_DELETE("/pages/organize/delete.jsf"),  | ||||
| 	/** | ||||
| 	 * organize add | ||||
| 	 */ | ||||
| 	ORGANIZE_ADD("/pages/organize/add.jsf"), | ||||
| 	/** | ||||
| 	 * organize edit | ||||
| 	 */ | ||||
| 	ORGANIZE_EDIT("/pages/organize/edit.jsf"), | ||||
| 	/** | ||||
| 	 * start | ||||
| 	 */ | ||||
| 	START("/pages/start.jsf"); | ||||
|  | ||||
| 	private final String value; | ||||
|  | ||||
| 	private Pages(String value) | ||||
| 	{ | ||||
| 		this.value = value; | ||||
| 	} | ||||
|  | ||||
| 	public String get() | ||||
| 	{ | ||||
| 		return value; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/main/java/de/jottyfan/timetrack/help/ThemeBean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/main/java/de/jottyfan/timetrack/help/ThemeBean.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| package de.jottyfan.timetrack.help; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| import javax.faces.bean.*; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @SessionScoped | ||||
| public class ThemeBean | ||||
| { | ||||
| 	private String currentTheme; | ||||
|  | ||||
| 	public List<String> getValidThemes(){ | ||||
| 		List<String> list = new ArrayList<>(); | ||||
| 		list.add("cerulean"); | ||||
| 		list.add("cosmo"); | ||||
| 		list.add("cyborg"); | ||||
| 		list.add("darkly"); | ||||
| 		list.add("default"); | ||||
| 		list.add("flatly"); | ||||
| 		list.add("journal"); | ||||
| 		list.add("lumen"); | ||||
| 		list.add("other"); | ||||
| 		list.add("paper"); | ||||
| 		list.add("readable"); | ||||
| 		list.add("sandstone"); | ||||
| 		list.add("simplex"); | ||||
| 		list.add("slate"); | ||||
| 		list.add("spacelab"); | ||||
| 		list.add("superhero"); | ||||
| 		list.add("united"); | ||||
| 		list.add("yeti"); | ||||
| 		return list; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setCurrentTheme(String currentTheme) | ||||
| 	{ | ||||
| 		this.currentTheme = currentTheme; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * contains current theme for web.xml's theme chooser | ||||
| 	 *  | ||||
| 	 * @return current theme | ||||
| 	 */ | ||||
| 	public String getCurrentTheme() | ||||
| 	{ | ||||
| 		return currentTheme == null ? "default" : (getValidThemes().contains(currentTheme) ? currentTheme : "default");  | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/main/java/de/jottyfan/timetrack/modules/Bean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/main/java/de/jottyfan/timetrack/modules/Bean.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public interface Bean | ||||
| { | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public interface ControlInterface | ||||
| { | ||||
| 	/** | ||||
| 	 * navigate to init page of module | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 * @throws DBException | ||||
| 	 */ | ||||
| 	public String toList(); | ||||
| 	 | ||||
| 	/** | ||||
| 	 * return model of bean container | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public Model getModel(); | ||||
| } | ||||
							
								
								
									
										44
									
								
								src/main/java/de/jottyfan/timetrack/modules/JooqGateway.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/main/java/de/jottyfan/timetrack/modules/JooqGateway.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.jooq.DSLContext; | ||||
| import org.jooq.TableLike; | ||||
|  | ||||
| import de.jooqFaces.EJooqApplicationScope; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class JooqGateway | ||||
| { | ||||
| 	private final FacesContext facesContext; | ||||
|  | ||||
| 	public JooqGateway(FacesContext facesContext) | ||||
| 	{ | ||||
| 		this.facesContext = facesContext; | ||||
| 	} | ||||
|  | ||||
| 	public DSLContext getJooq() | ||||
| 	{ | ||||
| 		return (DSLContext) facesContext.getExternalContext().getApplicationMap().get(EJooqApplicationScope.JOOQ_FACES_DSLCONTEXT.get()); | ||||
| 	} | ||||
| 	 | ||||
| 	public Integer getFkLogin() { | ||||
| 		// TODO: make a login, add the profile id to the session and read it here from facesContext | ||||
| 		return 1; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * return amount of "select count(1) as amount " + subQuery | ||||
| 	 *  | ||||
| 	 * @param subQuery | ||||
| 	 * @return number of entries | ||||
| 	 */ | ||||
| 	public Long getAmount(TableLike<?> table) | ||||
| 	{ | ||||
| 		return getJooq().selectCount().from(table).fetchOne(0, long.class); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/main/java/de/jottyfan/timetrack/modules/Model.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/main/java/de/jottyfan/timetrack/modules/Model.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public interface Model | ||||
| { | ||||
| 	/** | ||||
| 	 * get bean of model | ||||
| 	 *  | ||||
| 	 * @return bean | ||||
| 	 */ | ||||
| 	public Bean getBean(); | ||||
| } | ||||
							
								
								
									
										79
									
								
								src/main/java/de/jottyfan/timetrack/modules/SessionBean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/main/java/de/jottyfan/timetrack/modules/SessionBean.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.SessionScoped; | ||||
|  | ||||
| import org.jasypt.util.password.StrongPasswordEncryptor; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @SessionScoped | ||||
| public class SessionBean implements Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private Integer login; | ||||
| 	private String username; | ||||
| 	private String secret; | ||||
| 	private String forename; | ||||
| 	private String surname; | ||||
|  | ||||
| 	public Boolean getHasLogin() { | ||||
| 		return login != null; | ||||
| 	} | ||||
|  | ||||
| 	public Boolean getHasNoLogin() { | ||||
| 		return login == null; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getLogin() { | ||||
| 		return login; | ||||
| 	} | ||||
|  | ||||
| 	public void setLogin(Integer login) { | ||||
| 		this.login = login; | ||||
| 	} | ||||
|  | ||||
| 	public String getSecret() { | ||||
| 		StrongPasswordEncryptor spe = new StrongPasswordEncryptor(); | ||||
| 		return spe.encryptPassword(secret); | ||||
| 	} | ||||
|  | ||||
| 	public boolean checkSecret(String encrypted) { | ||||
| 		StrongPasswordEncryptor spe = new StrongPasswordEncryptor(); | ||||
| 		return spe.checkPassword(secret, encrypted); | ||||
| 	} | ||||
| 	 | ||||
| 	public void setSecret(String secret) { | ||||
| 		this.secret = secret; | ||||
| 	} | ||||
|  | ||||
| 	public String getForename() { | ||||
| 		return forename; | ||||
| 	} | ||||
|  | ||||
| 	public void setForename(String forename) { | ||||
| 		this.forename = forename; | ||||
| 	} | ||||
|  | ||||
| 	public String getSurname() { | ||||
| 		return surname; | ||||
| 	} | ||||
|  | ||||
| 	public void setSurname(String surname) { | ||||
| 		this.surname = surname; | ||||
| 	} | ||||
|  | ||||
| 	public String getUsername() { | ||||
| 		return username; | ||||
| 	} | ||||
|  | ||||
| 	public void setUsername(String username) { | ||||
| 		this.username = username; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| import javax.faces.bean.RequestScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import de.jottyfan.timetrack.help.Pages; | ||||
|  | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.ManagedProperty; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @RequestScoped | ||||
| public class SessionControl { | ||||
|  | ||||
| 	@ManagedProperty(value = "#{facesContext}") | ||||
| 	private FacesContext facesContext; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{sessionBean}") | ||||
| 	private SessionBean bean; | ||||
|  | ||||
| 	public String doLogin() { | ||||
| 		SessionModel model = new SessionModel(); | ||||
| 		model.doLogin(facesContext, bean); | ||||
| 		return Pages.START.get(); | ||||
| 	} | ||||
|  | ||||
| 	public String doLogout() { | ||||
| 		bean.setLogin(null); | ||||
| 		return Pages.START.get(); | ||||
| 	} | ||||
|  | ||||
| 	public FacesContext getFacesContext() { | ||||
| 		return facesContext; | ||||
| 	} | ||||
|  | ||||
| 	public void setFacesContext(FacesContext facesContext) { | ||||
| 		this.facesContext = facesContext; | ||||
| 	} | ||||
|  | ||||
| 	public SessionBean getBean() { | ||||
| 		return bean; | ||||
| 	} | ||||
|  | ||||
| 	public void setBean(SessionBean bean) { | ||||
| 		this.bean = bean; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,59 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN; | ||||
|  | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.Record4; | ||||
| import org.jooq.SelectConditionStep; | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class SessionGateway extends JooqGateway { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(); | ||||
|  | ||||
| 	public SessionGateway(FacesContext facesContext) { | ||||
| 		super(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * seek login and set bean's login to that; if not found, return false | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 *          the bean | ||||
| 	 * @return true or false | ||||
| 	 */ | ||||
| 	public boolean seekAndSetLogin(SessionBean bean) { | ||||
| 		SelectConditionStep<Record4<Integer, String, String, String>> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.select(T_LOGIN.PK, | ||||
| 					    T_LOGIN.FORENAME, | ||||
| 					    T_LOGIN.SURNAME, | ||||
| 					    T_LOGIN.PASSWORD) | ||||
| 			.from(T_LOGIN) | ||||
| 			.where(T_LOGIN.LOGIN.eq(bean.getUsername())); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		Record4<Integer, String, String, String> r = sql.fetchOne(); | ||||
| 		if (r != null) { | ||||
| 			String encrypted = r.get(T_LOGIN.PASSWORD); | ||||
| 			if (bean.checkSecret(encrypted)) { | ||||
| 				bean.setLogin(r.get(T_LOGIN.PK)); | ||||
| 				bean.setForename(r.get(T_LOGIN.FORENAME)); | ||||
| 				bean.setSurname(r.get(T_LOGIN.SURNAME)); | ||||
| 				return true; | ||||
| 			} else { | ||||
| 				throw new DataAccessException("wrong password"); | ||||
| 			} | ||||
| 		} else { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| package de.jottyfan.timetrack.modules; | ||||
|  | ||||
| import javax.faces.application.FacesMessage; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class SessionModel { | ||||
|  | ||||
| 	public boolean doLogin(FacesContext facesContext, SessionBean bean) { | ||||
| 		try { | ||||
| 			return new SessionGateway(facesContext).seekAndSetLogin(bean); | ||||
| 		} catch (DataAccessException e) { | ||||
| 			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on login", e.getMessage()); | ||||
| 			facesContext.addMessage(null, msg); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,81 @@ | ||||
| package de.jottyfan.timetrack.modules.contact; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.contact.enums.EnumContacttype; | ||||
| import de.jottyfan.timetrack.modules.Bean; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class ContactBean implements Bean, Serializable, Comparable<ContactBean> { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private final Integer pk; | ||||
| 	private String forename; | ||||
| 	private String surname; | ||||
| 	private String contact; | ||||
| 	private EnumContacttype type; | ||||
|  | ||||
| 	public ContactBean(Integer pk) { | ||||
| 		super(); | ||||
| 		this.pk = pk; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(ContactBean o) { | ||||
| 		return o == null ? 0 : getSortname().compareTo(o.getSortname()); | ||||
| 	} | ||||
|  | ||||
| 	public String getSortname() { | ||||
| 		StringBuilder buf = new StringBuilder(); | ||||
| 		buf.append(surname).append(forename); | ||||
| 		return buf.toString().toLowerCase(); | ||||
| 	} | ||||
|  | ||||
| 	public String getFullname() { | ||||
| 		StringBuilder buf = new StringBuilder(); | ||||
| 		buf.append(forename).append(" "); | ||||
| 		buf.append(surname); | ||||
| 		return buf.toString(); | ||||
| 	} | ||||
|  | ||||
| 	public String getForename() { | ||||
| 		return forename; | ||||
| 	} | ||||
|  | ||||
| 	public void setForename(String forename) { | ||||
| 		this.forename = forename; | ||||
| 	} | ||||
|  | ||||
| 	public String getSurname() { | ||||
| 		return surname; | ||||
| 	} | ||||
|  | ||||
| 	public void setSurname(String surname) { | ||||
| 		this.surname = surname; | ||||
| 	} | ||||
|  | ||||
| 	public String getContact() { | ||||
| 		return contact; | ||||
| 	} | ||||
|  | ||||
| 	public void setContact(String contact) { | ||||
| 		this.contact = contact; | ||||
| 	} | ||||
|  | ||||
| 	public EnumContacttype getType() { | ||||
| 		return type; | ||||
| 	} | ||||
|  | ||||
| 	public void setType(EnumContacttype type) { | ||||
| 		this.type = type; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getPk() { | ||||
| 		return pk; | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,79 @@ | ||||
| package de.jottyfan.timetrack.modules.contact; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.ManagedProperty; | ||||
| import javax.faces.bean.RequestScoped; | ||||
|  | ||||
| import de.jooqFaces.JooqFacesContext; | ||||
| import de.jottyfan.timetrack.help.Navigation; | ||||
| import de.jottyfan.timetrack.help.Pages; | ||||
| import de.jottyfan.timetrack.modules.ControlInterface; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author jotty | ||||
|  *  | ||||
|  */ | ||||
| @ManagedBean | ||||
| @RequestScoped | ||||
| public class ContactControl extends Navigation implements ControlInterface, Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{contactModel}") | ||||
| 	private ContactModel model; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{facesContext}") | ||||
| 	private JooqFacesContext facesContext; | ||||
|  | ||||
| 	public String toStart() { | ||||
| 		return navigateTo(Pages.START); | ||||
| 	} | ||||
|  | ||||
| 	public String toList() { | ||||
| 		boolean ready = model.init(facesContext); | ||||
| 		return ready ? navigateTo(Pages.CONTACT_LIST) : toStart(); | ||||
| 	} | ||||
|  | ||||
| 	public String toItem(ContactBean bean) { | ||||
| 		model.setBean(bean); | ||||
| 		return navigateTo(Pages.CONTACT_ITEM); | ||||
| 	} | ||||
|  | ||||
| 	public String toItem() { | ||||
| 		model.setBean(new ContactBean(null)); | ||||
| 		return navigateTo(Pages.CONTACT_ITEM); | ||||
| 	} | ||||
|  | ||||
| 	public String doAdd() { | ||||
| 		boolean ready = model.add(facesContext); | ||||
| 		return ready ? toList() : navigateTo(Pages.CONTACT_ITEM); | ||||
| 	} | ||||
|  | ||||
| 	public String doUpdate() { | ||||
| 		boolean ready = model.update(facesContext); | ||||
| 		return ready ? toList() : navigateTo(Pages.CONTACT_ITEM); | ||||
| 	} | ||||
|  | ||||
| 	public String doDelete() { | ||||
| 		boolean ready = model.delete(facesContext); | ||||
| 		return ready ? toList() : navigateTo(Pages.CONTACT_ITEM); | ||||
| 	} | ||||
| 	 | ||||
| 	public Integer getAmount() { | ||||
| 		return model.getAmount(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	public ContactModel getModel() { | ||||
| 		return model; | ||||
| 	} | ||||
|  | ||||
| 	public void setModel(ContactModel model) { | ||||
| 		this.model = model; | ||||
| 	} | ||||
|  | ||||
| 	public void setFacesContext(JooqFacesContext facesContext) { | ||||
| 		this.facesContext = facesContext; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,149 @@ | ||||
| package de.jottyfan.timetrack.modules.contact; | ||||
|  | ||||
| import static de.jottyfan.timetrack.db.contact.Tables.T_CONTACT; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.DeleteConditionStep; | ||||
| import org.jooq.InsertValuesStep4; | ||||
| import org.jooq.Record1; | ||||
| import org.jooq.Record5; | ||||
| import org.jooq.SelectJoinStep; | ||||
| import org.jooq.UpdateConditionStep; | ||||
| import org.jooq.impl.DSL; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.contact.enums.EnumContacttype; | ||||
| import de.jottyfan.timetrack.db.contact.tables.records.TContactRecord; | ||||
| import de.jottyfan.timetrack.modules.JooqGateway; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class ContactGateway extends JooqGateway { | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(ContactGateway.class); | ||||
|  | ||||
| 	public ContactGateway(FacesContext facesContext) { | ||||
| 		super(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get sorted list of contacts | ||||
| 	 *  | ||||
| 	 * @return a list (an empty one at least) | ||||
| 	 */ | ||||
| 	public List<ContactBean> getAll() { | ||||
| 		SelectJoinStep<Record5<Integer, String, String, String, EnumContacttype>> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.select(T_CONTACT.PK, | ||||
| 					    T_CONTACT.FORENAME, | ||||
| 					    T_CONTACT.SURNAME, | ||||
| 					    T_CONTACT.CONTACT, | ||||
| 					    T_CONTACT.TYPE) | ||||
| 			.from(T_CONTACT); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug("{}", sql.toString()); | ||||
| 		List<ContactBean> list = new ArrayList<>(); | ||||
| 		for (Record5<Integer, String, String, String, EnumContacttype> r : sql.fetch()) { | ||||
| 			ContactBean bean = new ContactBean(r.get(T_CONTACT.PK)); | ||||
| 			bean.setForename(r.get(T_CONTACT.FORENAME)); | ||||
| 			bean.setSurname(r.get(T_CONTACT.SURNAME)); | ||||
| 			bean.setContact(r.get(T_CONTACT.CONTACT)); | ||||
| 			bean.setType(r.get(T_CONTACT.TYPE)); | ||||
| 			list.add(bean); | ||||
| 		} | ||||
| 		list.sort((o1, o2) -> o1 == null ? 0 : o1.compareTo(o2)); | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * delete a contact from the database | ||||
| 	 *  | ||||
| 	 * @param pk | ||||
| 	 *          the id of the contact | ||||
| 	 * @return the number of affected database rows, should be 1 | ||||
| 	 */ | ||||
| 	public Integer delete(Integer pk) { | ||||
| 		DeleteConditionStep<TContactRecord> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.deleteFrom(T_CONTACT) | ||||
| 			.where(T_CONTACT.PK.eq(pk)); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug("{}", sql.toString()); | ||||
| 		return sql.execute(); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * add a contact to the database | ||||
| 	 * | ||||
| 	 * @param bean | ||||
| 	 *          the contact information | ||||
| 	 * @return the number of affected database rows, should be 1 | ||||
| 	 */ | ||||
| 	public Integer add(ContactBean bean) { | ||||
| 		InsertValuesStep4<TContactRecord, String, String, String, EnumContacttype> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.insertInto(T_CONTACT, | ||||
| 					        T_CONTACT.FORENAME, | ||||
| 									T_CONTACT.SURNAME, | ||||
| 									T_CONTACT.CONTACT, | ||||
| 									T_CONTACT.TYPE) | ||||
| 			.values(bean.getForename(), bean.getSurname(), bean.getContact(), bean.getType()); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug("{}", sql.toString()); | ||||
| 		return sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * update a contact in the database, referencing its pk | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 *          the contact information | ||||
| 	 * @return the number of affected database rows, should be 1 | ||||
| 	 */ | ||||
| 	public Integer update(ContactBean bean) { | ||||
| 		UpdateConditionStep<TContactRecord> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.update(T_CONTACT) | ||||
| 			.set(T_CONTACT.FORENAME, bean.getForename()) | ||||
| 			.set(T_CONTACT.SURNAME, bean.getSurname()) | ||||
| 			.set(T_CONTACT.CONTACT, bean.getContact()) | ||||
| 			.set(T_CONTACT.TYPE, bean.getType()) | ||||
| 			.where(T_CONTACT.PK.eq(bean.getPk())); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug("{}", sql.toString()); | ||||
| 		return sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get number of entries in t_contact | ||||
| 	 *  | ||||
| 	 * @return number of entries | ||||
| 	 */ | ||||
| 	public Integer getAmount() { | ||||
| 		SelectJoinStep<Record1<Integer>> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.selectCount() | ||||
| 			.from(T_CONTACT); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug("{}", sql.toString()); | ||||
| 		return sql.fetchOne(DSL.count()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all enum types | ||||
| 	 *  | ||||
| 	 * @return list of enum types | ||||
| 	 */ | ||||
| 	public List<EnumContacttype> getTypes() { | ||||
| 		return new ArrayList<>(Arrays.asList(EnumContacttype.values())); | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,110 @@ | ||||
| package de.jottyfan.timetrack.modules.contact; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.faces.application.FacesMessage; | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.SessionScoped; | ||||
|  | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jooqFaces.JooqFacesContext; | ||||
| import de.jottyfan.timetrack.db.contact.enums.EnumContacttype; | ||||
| import de.jottyfan.timetrack.modules.Model; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @SessionScoped | ||||
| public class ContactModel implements Model, Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private ContactBean bean; | ||||
| 	private List<ContactBean> list; | ||||
| 	private List<EnumContacttype> types; | ||||
|  | ||||
| 	public boolean init(JooqFacesContext facesContext) { | ||||
| 		bean = new ContactBean(null); | ||||
| 		try { | ||||
| 			ContactGateway gw = new ContactGateway(facesContext); | ||||
| 			list = gw.getAll(); | ||||
| 			types = gw.getTypes(); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on loading data from db", e.getMessage())); | ||||
| 			list = new ArrayList<>(); | ||||
| 			types = new ArrayList<>(); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean delete(JooqFacesContext facesContext) { | ||||
| 		try { | ||||
| 			Integer affected = new ContactGateway(facesContext).delete(bean.getPk()); | ||||
| 			return affected.equals(1); | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on deleting data from db", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean add(JooqFacesContext facesContext) { | ||||
| 		try { | ||||
| 			Integer affected = new ContactGateway(facesContext).add(bean); | ||||
| 			return affected.equals(1); | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on adding data to db", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean update(JooqFacesContext facesContext) { | ||||
| 		try { | ||||
| 			Integer affected = new ContactGateway(facesContext).update(bean); | ||||
| 			return affected.equals(1); | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on updating data to db", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public Integer getAmount(JooqFacesContext facesContext) { | ||||
| 		try { | ||||
| 			return new ContactGateway(facesContext).getAmount(); | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on getting size of contacts", e.getMessage())); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public List<ContactBean> getList() { | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	public void setBean(ContactBean bean) { | ||||
| 		this.bean = bean; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public ContactBean getBean() { | ||||
| 		return bean; | ||||
| 	} | ||||
|  | ||||
| 	public List<EnumContacttype> getTypes() { | ||||
| 		return types; | ||||
| 	} | ||||
|  | ||||
| 	public void setTypes(List<EnumContacttype> types) { | ||||
| 		this.types = types; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,37 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class DailySummaryBean { | ||||
| 	private final String projectName; | ||||
| 	private final String moduleName; | ||||
| 	private final String jobName; | ||||
| 	private final String duration; | ||||
|  | ||||
| 	public DailySummaryBean(String projectName, String moduleName, String jobName, String duration) { | ||||
| 		super(); | ||||
| 		this.projectName = projectName; | ||||
| 		this.moduleName = moduleName; | ||||
| 		this.jobName = jobName; | ||||
| 		this.duration = duration; | ||||
| 	} | ||||
|  | ||||
| 	public String getProjectName() { | ||||
| 		return projectName; | ||||
| 	} | ||||
|  | ||||
| 	public String getModuleName() { | ||||
| 		return moduleName; | ||||
| 	} | ||||
|  | ||||
| 	public String getJobName() { | ||||
| 		return jobName; | ||||
| 	} | ||||
|  | ||||
| 	public String getDuration() { | ||||
| 		return duration; | ||||
| 	}; | ||||
| } | ||||
							
								
								
									
										166
									
								
								src/main/java/de/jottyfan/timetrack/modules/done/DoneBean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/main/java/de/jottyfan/timetrack/modules/done/DoneBean.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.sql.Timestamp; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.time.Duration; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Map; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TJobRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord; | ||||
| import de.jottyfan.timetrack.modules.Bean; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class DoneBean implements Bean, Serializable, Comparable<DoneBean> { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private Integer pk; | ||||
| 	private Timestamp timeFrom; | ||||
| 	private Timestamp timeUntil; | ||||
| 	private TProjectRecord project; | ||||
| 	private TModuleRecord module; | ||||
| 	private TJobRecord activity; | ||||
|  | ||||
| 	public DoneBean() { | ||||
| 	} | ||||
|  | ||||
| 	public DoneBean(TDoneRecord r, Map<Integer, TProjectRecord> projectMap, Map<Integer, TModuleRecord> moduleMap, | ||||
| 			Map<Integer, TJobRecord> jobMap) { | ||||
| 		this.pk = r.getPk(); | ||||
| 		this.timeFrom = r.getTimeFrom(); | ||||
| 		this.timeUntil = r.getTimeUntil(); | ||||
| 		this.project = projectMap.get(r.getFkProject()); | ||||
| 		this.module = moduleMap.get(r.getFkModule()); | ||||
| 		this.activity = jobMap.get(r.getFkJob()); | ||||
| 	} | ||||
|  | ||||
| 	public String getTimeSummary() { | ||||
| 		StringBuilder buf = new StringBuilder(); | ||||
| 		if (timeFrom != null) { | ||||
| 			buf.append(new SimpleDateFormat("HH:mm").format(timeFrom)); | ||||
| 		} | ||||
| 		if (timeUntil != null) { | ||||
| 			buf.append(" - "); | ||||
| 			buf.append(new SimpleDateFormat("HH:mm").format(timeUntil)); | ||||
| 		} | ||||
| 		return buf.toString(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(DoneBean o) { | ||||
| 		return o == null || timeFrom == null || o.getTimeFrom() == null ? 0 : timeFrom.compareTo(o.getTimeFrom()); | ||||
| 	} | ||||
|  | ||||
| 	public String getTimeDiff() { | ||||
| 		LocalDateTime earlier = timeFrom != null ? timeFrom.toLocalDateTime() : LocalDateTime.now(); | ||||
| 		LocalDateTime later = timeUntil != null ? timeUntil.toLocalDateTime() : LocalDateTime.now(); | ||||
| 		Duration diff = Duration.between(earlier, later); | ||||
| 		return String.format("%02d:%02d", diff.toHours(), diff.toMinutes() % 60); | ||||
| 	} | ||||
|  | ||||
| 	public LocalDateTime getLocalDateTimeFromHHmm(String s) { | ||||
| 		if (s == null || s.trim().isEmpty()) { | ||||
| 			return null; | ||||
| 		} | ||||
| 		String[] hm = s.split(":"); | ||||
| 		Integer hours = 0; | ||||
| 		Integer minutes = 0; | ||||
| 		if (hm.length > 0) { | ||||
| 			hours = Integer.valueOf(hm[0]); | ||||
| 		} | ||||
| 		if (hm.length > 1) { | ||||
| 			minutes = Integer.valueOf(hm[1]); | ||||
| 		} | ||||
| 		LocalDateTime ldt = LocalDateTime.now(); | ||||
| 		ldt = ldt.withHour(hours); | ||||
| 		ldt = ldt.withMinute(minutes); | ||||
| 		ldt = ldt.withSecond(0); | ||||
| 		ldt = ldt.withNano(0); | ||||
| 		return ldt; | ||||
| 	} | ||||
|  | ||||
| 	public String getProjectName() { | ||||
| 		return project == null ? "" : project.getName(); | ||||
| 	} | ||||
|  | ||||
| 	public String getModuleName() { | ||||
| 		return module == null ? "" : module.getName(); | ||||
| 	} | ||||
|  | ||||
| 	public String getJobName() { | ||||
| 		return activity == null ? "" : activity.getName(); | ||||
| 	} | ||||
|  | ||||
| 	public String getTimeFromString() { | ||||
| 		return timeFrom == null ? "" : new SimpleDateFormat("HH:mm").format(timeFrom); | ||||
| 	} | ||||
|  | ||||
| 	public void setTimeFromString(String s) { | ||||
| 		LocalDateTime ldt = getLocalDateTimeFromHHmm(s); | ||||
| 		this.timeFrom = ldt == null ? null : Timestamp.valueOf(ldt); | ||||
| 	} | ||||
|  | ||||
| 	public String getTimeUntilString() { | ||||
| 		return timeUntil == null ? "" : new SimpleDateFormat("HH:mm").format(timeUntil); | ||||
| 	} | ||||
|  | ||||
| 	public void setTimeUntilString(String s) { | ||||
| 		LocalDateTime ldt = getLocalDateTimeFromHHmm(s); | ||||
| 		this.timeUntil = ldt == null ? null : Timestamp.valueOf(ldt); | ||||
| 	} | ||||
|  | ||||
| 	public Integer getPk() { | ||||
| 		return this.pk; | ||||
| 	} | ||||
|  | ||||
| 	public void setPk(Integer pk) { | ||||
| 		this.pk = pk; | ||||
| 	} | ||||
|  | ||||
| 	public Timestamp getTimeFrom() { | ||||
| 		return timeFrom; | ||||
| 	} | ||||
|  | ||||
| 	public void setTimeFrom(Timestamp timeFrom) { | ||||
| 		this.timeFrom = timeFrom; | ||||
| 	} | ||||
|  | ||||
| 	public Timestamp getTimeUntil() { | ||||
| 		return timeUntil; | ||||
| 	} | ||||
|  | ||||
| 	public void setTimeUntil(Timestamp timeUntil) { | ||||
| 		this.timeUntil = timeUntil; | ||||
| 	} | ||||
|  | ||||
| 	public TProjectRecord getProject() { | ||||
| 		return project; | ||||
| 	} | ||||
|  | ||||
| 	public void setProject(TProjectRecord project) { | ||||
| 		this.project = project; | ||||
| 	} | ||||
|  | ||||
| 	public TModuleRecord getModule() { | ||||
| 		return module; | ||||
| 	} | ||||
|  | ||||
| 	public void setModule(TModuleRecord module) { | ||||
| 		this.module = module; | ||||
| 	} | ||||
|  | ||||
| 	public TJobRecord getActivity() { | ||||
| 		return activity; | ||||
| 	} | ||||
|  | ||||
| 	public void setActivity(TJobRecord activity) { | ||||
| 		this.activity = activity; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,95 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.sql.Timestamp; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.ManagedProperty; | ||||
| import javax.faces.bean.RequestScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import de.jottyfan.timetrack.help.Navigation; | ||||
| import de.jottyfan.timetrack.help.Pages; | ||||
| import de.jottyfan.timetrack.modules.ControlInterface; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  *  | ||||
|  */ | ||||
| @ManagedBean | ||||
| @RequestScoped | ||||
| public class DoneControl extends Navigation implements ControlInterface, Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{doneModel}") | ||||
| 	private DoneModel model; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{facesContext}") | ||||
| 	private FacesContext facesContext; | ||||
|  | ||||
| 	public String toStart() { | ||||
| 		return navigateTo(Pages.START); | ||||
| 	} | ||||
|  | ||||
| 	public String toList() { | ||||
| 		boolean ready = model.init(facesContext); | ||||
| 		return ready ? navigateTo(Pages.DONE_INIT) : toStart(); | ||||
| 	} | ||||
|  | ||||
| 	public String toAdd() { | ||||
| 		DoneBean bean = new DoneBean(); | ||||
| 		bean.setTimeFrom(getCurrentDate()); | ||||
| 		model.setBean(bean); | ||||
| 		boolean ready = model.loadDefaults(facesContext); | ||||
| 		return ready ? navigateTo(Pages.DONE_ADD) : toList(); | ||||
| 	} | ||||
|  | ||||
| 	public String toEdit(DoneBean bean) { | ||||
| 		model.setBean(bean); | ||||
| 		boolean ready = model.loadDefaults(facesContext); | ||||
| 		return ready ? navigateTo(Pages.DONE_EDIT) : toList(); | ||||
| 	} | ||||
|  | ||||
| 	public String toDelete(DoneBean bean) { | ||||
| 		model.setBean(bean); | ||||
| 		return navigateTo(Pages.DONE_DELETE); | ||||
| 	} | ||||
|  | ||||
| 	public String doUpdate() { | ||||
| 		boolean ready = model.update(facesContext); | ||||
| 		return ready ? toList() : toEdit(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doDelete() { | ||||
| 		boolean ready = model.delete(facesContext); | ||||
| 		return ready ? toList() : toDelete(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doAdd() { | ||||
| 		boolean ready = model.insert(facesContext); | ||||
| 		return ready ? toList() : toAdd(); | ||||
| 	} | ||||
|  | ||||
| 	public String getCurrentTimeAsString() { | ||||
| 		return new SimpleDateFormat("HH:mm:ss").format(getCurrentDate()); | ||||
| 	} | ||||
|  | ||||
| 	public Timestamp getCurrentDate() { | ||||
| 		return Timestamp.valueOf(LocalDateTime.now()); | ||||
| 	} | ||||
|  | ||||
| 	public DoneModel getModel() { | ||||
| 		return model; | ||||
| 	} | ||||
|  | ||||
| 	public void setModel(DoneModel model) { | ||||
| 		this.model = model; | ||||
| 	} | ||||
|  | ||||
| 	public void setFacesContext(FacesContext facesContext) { | ||||
| 		this.facesContext = facesContext; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,290 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| import static de.jottyfan.timetrack.db.done.Tables.T_DONE; | ||||
| import static de.jottyfan.timetrack.db.done.Tables.T_JOB; | ||||
| import static de.jottyfan.timetrack.db.done.Tables.T_MODULE; | ||||
| import static de.jottyfan.timetrack.db.done.Tables.T_PROJECT; | ||||
| import static de.jottyfan.timetrack.db.done.Tables.V_TASKLIST; | ||||
| import static de.jottyfan.timetrack.db.done.Tables.V_TOTALOFDAY; | ||||
|  | ||||
| import java.sql.Timestamp; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.time.Duration; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jooq.DeleteConditionStep; | ||||
| import org.jooq.InsertValuesStep6; | ||||
| import org.jooq.Record; | ||||
| import org.jooq.Record4; | ||||
| import org.jooq.SelectConditionStep; | ||||
| import org.jooq.SelectWhereStep; | ||||
| import org.jooq.UpdateConditionStep; | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TJobRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord; | ||||
| import de.jottyfan.timetrack.modules.JooqGateway; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class DoneGateway extends JooqGateway { | ||||
| 	private final static Logger LOGGER = LogManager.getLogger(DoneGateway.class); | ||||
|  | ||||
| 	public DoneGateway(FacesContext facesContext) { | ||||
| 		super(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all modules from db | ||||
| 	 *  | ||||
| 	 * @return modules | ||||
| 	 */ | ||||
| 	public List<TModuleRecord> getAllModules() throws DataAccessException { | ||||
| 		List<TModuleRecord> list = new ArrayList<>(); | ||||
| 		SelectWhereStep<TModuleRecord> sql = getJooq().selectFrom(T_MODULE); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		for (TModuleRecord r : sql.fetch()) { | ||||
| 			list.add(r); | ||||
| 		} | ||||
| 		list.sort((o1, o2) -> o1 == null || o2 == null || o1.getName() == null || o2.getName() == null ? 0 | ||||
| 				: o1.getName().compareTo(o2.getName())); | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all activities from db | ||||
| 	 *  | ||||
| 	 * @return activities | ||||
| 	 */ | ||||
| 	public List<TJobRecord> getAllActivities() throws DataAccessException { | ||||
| 		List<TJobRecord> list = new ArrayList<>(); | ||||
| 		SelectWhereStep<TJobRecord> sql = getJooq().selectFrom(T_JOB); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		for (TJobRecord r : sql.fetch()) { | ||||
| 			list.add(r); | ||||
| 		} | ||||
| 		list.sort((o1, o2) -> o1 == null || o2 == null || o1.getName() == null || o2.getName() == null ? 0 | ||||
| 				: o1.getName().compareTo(o2.getName())); | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all projects from db | ||||
| 	 *  | ||||
| 	 * @return projects | ||||
| 	 */ | ||||
| 	public List<TProjectRecord> getAllProjects() throws DataAccessException { | ||||
| 		List<TProjectRecord> list = new ArrayList<>(); | ||||
| 		SelectWhereStep<TProjectRecord> sql = getJooq().selectFrom(T_PROJECT); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		for (TProjectRecord r : sql.fetch()) { | ||||
| 			list.add(r); | ||||
| 		} | ||||
| 		list.sort((o1, o2) -> o1 == null || o2 == null || o1.getName() == null || o2.getName() == null ? 0 | ||||
| 				: o1.getName().compareTo(o2.getName())); | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	private Map<Integer, TProjectRecord> generateProjectMap(List<TProjectRecord> list) { | ||||
| 		Map<Integer, TProjectRecord> map = new HashMap<>(); | ||||
| 		for (TProjectRecord r : list) { | ||||
| 			map.put(r.getPk(), r); | ||||
| 		} | ||||
| 		return map; | ||||
| 	} | ||||
|  | ||||
| 	private Map<Integer, TModuleRecord> generateModuleMap(List<TModuleRecord> list) { | ||||
| 		Map<Integer, TModuleRecord> map = new HashMap<>(); | ||||
| 		for (TModuleRecord r : list) { | ||||
| 			map.put(r.getPk(), r); | ||||
| 		} | ||||
| 		return map; | ||||
| 	} | ||||
|  | ||||
| 	private Map<Integer, TJobRecord> generateJobMap(List<TJobRecord> list) { | ||||
| 		Map<Integer, TJobRecord> map = new HashMap<>(); | ||||
| 		for (TJobRecord r : list) { | ||||
| 			map.put(r.getPk(), r); | ||||
| 		} | ||||
| 		return map; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all from t_done of the given day | ||||
| 	 *  | ||||
| 	 * @param day | ||||
| 	 *          the day; if null, the current date is used | ||||
| 	 *  | ||||
| 	 * @return a list of found times, an empty one at least | ||||
| 	 */ | ||||
| 	public List<DoneBean> getAll(LocalDateTime day) throws DataAccessException { | ||||
| 		Map<Integer, TProjectRecord> projectMap = generateProjectMap(getAllProjects()); | ||||
| 		Map<Integer, TModuleRecord> moduleMap = generateModuleMap(getAllModules()); | ||||
| 		Map<Integer, TJobRecord> jobMap = generateJobMap(getAllActivities()); | ||||
|  | ||||
| 		if (day == null) { | ||||
| 			day = LocalDateTime.now(); | ||||
| 		} | ||||
| 		LocalDateTime yesterday = day.minusDays(1).withHour(23).withMinute(0).withSecond(0).withNano(0); | ||||
| 		LocalDateTime tomorrow = day.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); | ||||
|  | ||||
| 		List<DoneBean> list = new ArrayList<>(); | ||||
| 		SelectConditionStep<TDoneRecord> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.selectFrom(T_DONE) | ||||
| 			.where(T_DONE.FK_LOGIN.eq(getFkLogin())) | ||||
| 			.and(T_DONE.TIME_FROM.isNull() | ||||
| 				.or(T_DONE.TIME_FROM.greaterThan(Timestamp.valueOf(yesterday)) | ||||
| 					.and(T_DONE.TIME_FROM.lessThan(Timestamp.valueOf(tomorrow))))) | ||||
| 			.and(T_DONE.TIME_UNTIL.isNull() | ||||
| 				.or(T_DONE.TIME_UNTIL.lessThan(Timestamp.valueOf(tomorrow)) | ||||
| 					.and(T_DONE.TIME_UNTIL.greaterThan(Timestamp.valueOf(yesterday))))); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		for (TDoneRecord r : sql.fetch()) { | ||||
| 			list.add(new DoneBean(r, projectMap, moduleMap, jobMap)); | ||||
| 		} | ||||
| 		list.sort((o1, o2) -> o1 == null || o2 == null ? 0 : o1.compareTo(o2)); | ||||
| 		return list; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * insert data into t_done | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 */ | ||||
| 	public void insert(DoneBean bean) throws DataAccessException { | ||||
| 		Integer fkProject = bean.getProject() == null ? null : bean.getProject().getPk(); | ||||
| 		Integer fkModule = bean.getModule() == null ? null : bean.getModule().getPk(); | ||||
| 		Integer fkJob = bean.getActivity() == null ? null : bean.getActivity().getPk(); | ||||
| 		Integer fkLogin = getFkLogin(); | ||||
|  | ||||
| 		InsertValuesStep6<TDoneRecord, Timestamp, Timestamp, Integer, Integer, Integer, Integer> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.insertInto(T_DONE,  | ||||
| 									T_DONE.TIME_FROM,  | ||||
| 									T_DONE.TIME_UNTIL,  | ||||
| 									T_DONE.FK_PROJECT,  | ||||
| 									T_DONE.FK_MODULE,  | ||||
| 									T_DONE.FK_JOB, | ||||
| 									T_DONE.FK_LOGIN) | ||||
| 			.values(bean.getTimeFrom(), bean.getTimeUntil(), fkProject, fkModule, fkJob, fkLogin); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * update bean in t_done | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 */ | ||||
| 	public void update(DoneBean bean) throws DataAccessException { | ||||
| 		UpdateConditionStep<TDoneRecord> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.update(T_DONE) | ||||
| 			.set(T_DONE.TIME_FROM, bean.getTimeFrom()) | ||||
| 			.set(T_DONE.TIME_UNTIL, bean.getTimeUntil()) | ||||
| 			.set(T_DONE.FK_PROJECT, bean.getProject() == null ? null : bean.getProject().getPk()) | ||||
| 			.set(T_DONE.FK_JOB, bean.getActivity() == null ? null : bean.getActivity().getPk()) | ||||
| 			.set(T_DONE.FK_MODULE, bean.getModule() == null ? null : bean.getModule().getPk()) | ||||
| 			.where(T_DONE.PK.eq(bean.getPk())); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * delete bean from t_done | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 */ | ||||
| 	public void delete(DoneBean bean) throws DataAccessException { | ||||
| 		DeleteConditionStep<TDoneRecord> sql = getJooq().deleteFrom(T_DONE).where(T_DONE.PK.eq(bean.getPk())); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get day summary | ||||
| 	 *  | ||||
| 	 * @param day | ||||
| 	 *          the day | ||||
| 	 * @return the day summary if found, an empty map otherwise | ||||
| 	 */ | ||||
| 	public WholeDaySummaryBean getDaySummary(Date day) { | ||||
| 		SelectConditionStep<Record4<String, String, String, String>> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.select(V_TOTALOFDAY.STARTTIME, | ||||
| 							V_TOTALOFDAY.ENDTIME, | ||||
| 					    V_TOTALOFDAY.WORKTIME, | ||||
| 					    V_TOTALOFDAY.BREAKTIME) | ||||
| 			.from(V_TOTALOFDAY) | ||||
| 			.where(V_TOTALOFDAY.DAY.eq(new SimpleDateFormat("yyyy-MM-dd").format(day))) | ||||
| 			.and(V_TOTALOFDAY.FK_LOGIN.eq(getFkLogin())); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		Record r = sql.fetchOne(); | ||||
| 		if (r != null) { | ||||
| 			String startTime = r.get(V_TOTALOFDAY.STARTTIME); | ||||
| 			String endTime = r.get(V_TOTALOFDAY.ENDTIME); | ||||
| 			String workTime = r.get(V_TOTALOFDAY.WORKTIME); | ||||
| 			String breakTime = r.get(V_TOTALOFDAY.BREAKTIME); | ||||
| 			return new WholeDaySummaryBean(startTime, endTime, workTime, breakTime); | ||||
| 		} | ||||
| 		return new WholeDaySummaryBean("", "", "", ""); | ||||
| 	} | ||||
|  | ||||
| 	private String toStringFromDuration(Duration i) { | ||||
| 		StringBuilder buf = new StringBuilder(); | ||||
| 		if (i != null) { | ||||
| 			buf.append(i.toHours()).append(":"); | ||||
| 			buf.append(i.toMinutes() % 60); | ||||
| 		} | ||||
| 		return buf.toString(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all jobs of day | ||||
| 	 *  | ||||
| 	 * @param day | ||||
| 	 *          the day | ||||
| 	 * @return list of found jobs; an empty list at least | ||||
| 	 */ | ||||
| 	public List<DailySummaryBean> getAllJobs(Date day) { | ||||
| 		SelectConditionStep<Record4<String, String, String, String>> sql = getJooq() | ||||
| 		// @formatter:off | ||||
| 			.select(V_TASKLIST.DURATION, | ||||
| 							V_TASKLIST.PROJECT_NAME, | ||||
| 							V_TASKLIST.MODULE_NAME, | ||||
| 							V_TASKLIST.JOB_NAME) | ||||
| 			.from(V_TASKLIST) | ||||
| 			.where(V_TASKLIST.DAY.eq(new SimpleDateFormat("yyyy-MM-dd").format(day))) | ||||
| 			.and(V_TASKLIST.FK_LOGIN.eq(getFkLogin())); | ||||
| 		// @formatter:on | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		List<DailySummaryBean> list = new ArrayList<>(); | ||||
| 		for (Record4<String, String, String, String> r : sql.fetch()) { | ||||
| 			String duration = r.get(V_TASKLIST.DURATION); | ||||
| 			String projectName = r.get(V_TASKLIST.PROJECT_NAME); | ||||
| 			String moduleName = r.get(V_TASKLIST.MODULE_NAME); | ||||
| 			String jobName = r.get(V_TASKLIST.JOB_NAME); | ||||
| 			list.add(new DailySummaryBean(projectName, moduleName, jobName, duration)); | ||||
| 		} | ||||
| 		return list; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										205
									
								
								src/main/java/de/jottyfan/timetrack/modules/done/DoneModel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								src/main/java/de/jottyfan/timetrack/modules/done/DoneModel.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.ZoneId; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.GregorianCalendar; | ||||
| import java.util.List; | ||||
| import java.util.TimeZone; | ||||
|  | ||||
| import javax.faces.application.FacesMessage; | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.SessionScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TJobRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord; | ||||
| import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord; | ||||
| import de.jottyfan.timetrack.modules.Model; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @SessionScoped | ||||
| public class DoneModel implements Model, Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private DoneBean bean; | ||||
| 	private List<DoneBean> beans; | ||||
| 	private List<TProjectRecord> projects; | ||||
| 	private List<TModuleRecord> modules; | ||||
| 	private List<TJobRecord> activities; | ||||
| 	private List<TimeBean> times; | ||||
| 	private List<DailySummaryBean> allJobs; | ||||
| 	private WholeDaySummaryBean daySummary; | ||||
| 	private Date day; | ||||
|  | ||||
| 	public boolean init(FacesContext facesContext) { | ||||
| 		try { | ||||
| 			day = day == null ? new Date() : day; | ||||
| 			beans = getAllOfDay(facesContext, day); | ||||
| 			DoneGateway gw = new DoneGateway(facesContext); | ||||
| 			modules = gw.getAllModules(); | ||||
| 			activities = gw.getAllActivities(); | ||||
| 			projects = gw.getAllProjects(); | ||||
| 			daySummary = gw.getDaySummary(day); | ||||
| 			allJobs = gw.getAllJobs(day); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean loadDefaults(FacesContext facesContext) { | ||||
| 		try { | ||||
| 			defineTimes(); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, | ||||
| 					new FacesMessage(FacesMessage.SEVERITY_ERROR, "error loading defaults", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private void defineTimes() { | ||||
| 		times = new ArrayList<>(); | ||||
| 		Integer currentHour = getCurrentTime().get(GregorianCalendar.HOUR_OF_DAY); | ||||
| 		Integer currentMinute = getCurrentTime().get(GregorianCalendar.MINUTE); | ||||
| 		if (currentMinute < 15) { | ||||
| 			currentMinute = 0; | ||||
| 		} else if (currentMinute < 30) { | ||||
| 			currentMinute = 15; | ||||
| 		} else if (currentMinute < 45) { | ||||
| 			currentMinute = 30; | ||||
| 		} else { | ||||
| 			currentMinute = 45; | ||||
| 		} | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 120), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 105), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 90), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 75), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 60), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 45), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 30), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute - 15), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute), "default")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute + 15), "default")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute + 30), "link")); | ||||
| 		times.add(new TimeBean(defineNewTime(currentHour, currentMinute + 45), "link")); | ||||
| 	} | ||||
|  | ||||
| 	private Calendar getCurrentTime() { | ||||
| 		return new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); | ||||
| 	} | ||||
|  | ||||
| 	private Calendar defineNewTime(Integer hours, Integer minutes) { | ||||
| 		Calendar cal = new GregorianCalendar(); | ||||
| 		if (minutes < 0) { | ||||
| 			hours--; | ||||
| 			minutes += 60; | ||||
| 		} else if (minutes > 59) { | ||||
| 			hours++; | ||||
| 			minutes -= 60; | ||||
| 		} | ||||
| 		cal.set(0, 0, 0, hours, minutes, 0); | ||||
| 		return cal; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all entries of t_done | ||||
| 	 *  | ||||
| 	 * @param facesContext | ||||
| 	 * @param day | ||||
| 	 *          the day to look up for | ||||
| 	 * @param login | ||||
| 	 *          the user to look up for | ||||
| 	 * @return all entries | ||||
| 	 */ | ||||
| 	private List<DoneBean> getAllOfDay(FacesContext facesContext, Date day) throws DataAccessException { | ||||
| 		LocalDateTime ldt = day.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); | ||||
| 		return new DoneGateway(facesContext).getAll(ldt); | ||||
| 	} | ||||
|  | ||||
| 	public boolean insert(FacesContext facesContext) { | ||||
| 		try { | ||||
| 			new DoneGateway(facesContext).insert(bean); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean update(FacesContext facesContext) { | ||||
| 		try { | ||||
| 			new DoneGateway(facesContext).update(bean); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean delete(FacesContext facesContext) { | ||||
| 		try { | ||||
| 			new DoneGateway(facesContext).delete(bean); | ||||
| 			return true; | ||||
| 		} catch (DataAccessException e) { | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void setBean(DoneBean bean) { | ||||
| 		this.bean = bean; | ||||
| 	} | ||||
|  | ||||
| 	public DoneBean getBean() { | ||||
| 		return bean; | ||||
| 	} | ||||
|  | ||||
| 	public List<TProjectRecord> getProjects() { | ||||
| 		return projects; | ||||
| 	} | ||||
|  | ||||
| 	public List<TModuleRecord> getModules() { | ||||
| 		return modules; | ||||
| 	} | ||||
|  | ||||
| 	public List<TJobRecord> getActivities() { | ||||
| 		return activities; | ||||
| 	} | ||||
|  | ||||
| 	public List<DailySummaryBean> getAllJobs() { | ||||
| 		return allJobs; | ||||
| 	} | ||||
|  | ||||
| 	public WholeDaySummaryBean getDaySummary() { | ||||
| 		return daySummary; | ||||
| 	} | ||||
|  | ||||
| 	public List<DoneBean> getBeans() { | ||||
| 		return beans; | ||||
| 	} | ||||
|  | ||||
| 	public List<TimeBean> getTimes() { | ||||
| 		return times; | ||||
| 	} | ||||
|  | ||||
| 	public Date getDay() { | ||||
| 		return day; | ||||
| 	} | ||||
|  | ||||
| 	public void setDay(Date day) { | ||||
| 		this.day = day; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class TimeBean { | ||||
| 	private final String value; | ||||
| 	private final String look; | ||||
|  | ||||
| 	public TimeBean(String value, String look) { | ||||
| 		super(); | ||||
| 		this.value = value; | ||||
| 		this.look = look; | ||||
| 	} | ||||
|  | ||||
| 	public TimeBean(Calendar calendar, String look) { | ||||
| 		this(new SimpleDateFormat("HH:mm").format(calendar.getTime()), look); | ||||
| 	} | ||||
| 	 | ||||
| 	public String getValue() { | ||||
| 		return value; | ||||
| 	} | ||||
|  | ||||
| 	public String getLook() { | ||||
| 		return look; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,63 @@ | ||||
| package de.jottyfan.timetrack.modules.done; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class WholeDaySummaryBean { | ||||
| 	private final String startTime; | ||||
| 	private final String endTime; | ||||
| 	private final String workTime; | ||||
| 	private final String breakTime; | ||||
|  | ||||
| 	public WholeDaySummaryBean(String startTime, String endTime, String workTime, String breakTime) { | ||||
| 		super(); | ||||
| 		this.startTime = startTime; | ||||
| 		this.endTime = endTime; | ||||
| 		this.workTime = workTime; | ||||
| 		this.breakTime = breakTime; | ||||
| 	} | ||||
|  | ||||
| 	public String getOvertime() { | ||||
| 		if (workTime != null && !workTime.trim().isEmpty() && workTime.contains(":")) { | ||||
| 			try { | ||||
| 				Integer hours = Integer.valueOf(workTime.substring(0, workTime.indexOf(":"))); | ||||
| 				Integer minutes = Integer.valueOf(workTime.substring(workTime.indexOf(":") + 1)); | ||||
| 				Integer wholeMinutes = hours * 60 + minutes; | ||||
| 				Integer overtime = wholeMinutes - (7 * 60 + 48); | ||||
| 				Integer overtimeHours = overtime / 60; | ||||
| 				Integer overtimeMinutes = overtime % 60; | ||||
| 				StringBuilder buf = new StringBuilder(); | ||||
| 				if (overtime < 0) { | ||||
| 					buf.append("-"); | ||||
| 					overtimeHours *= -1; | ||||
| 					overtimeMinutes *= -1; | ||||
| 				} | ||||
| 				buf.append(String.format("%02d", overtimeHours)); | ||||
| 				buf.append(":"); | ||||
| 				buf.append(String.format("%02d", overtimeMinutes)); | ||||
| 				return buf.toString(); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 				return ""; | ||||
| 			} | ||||
| 		} | ||||
| 		return "-07:48"; | ||||
| 	} | ||||
|  | ||||
| 	public String getStartTime() { | ||||
| 		return startTime; | ||||
| 	} | ||||
|  | ||||
| 	public String getEndTime() { | ||||
| 		return endTime; | ||||
| 	} | ||||
|  | ||||
| 	public String getWorkTime() { | ||||
| 		return workTime; | ||||
| 	} | ||||
|  | ||||
| 	public String getBreakTime() { | ||||
| 		return breakTime; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,91 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.*; | ||||
| import java.util.*; | ||||
|  | ||||
| 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 Date 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 Date getLastchange() | ||||
| 	{ | ||||
| 		return lastchange; | ||||
| 	} | ||||
|  | ||||
| 	public void setLastchange(Date lastchange) | ||||
| 	{ | ||||
| 		this.lastchange = lastchange; | ||||
| 	} | ||||
|  | ||||
| 	public static long getSerialversionuid() | ||||
| 	{ | ||||
| 		return serialVersionUID; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getPk() | ||||
| 	{ | ||||
| 		return pk; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,122 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.ManagedProperty; | ||||
| import javax.faces.bean.RequestScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import de.jottyfan.timetrack.help.Navigation; | ||||
| import de.jottyfan.timetrack.help.Pages; | ||||
| import de.jottyfan.timetrack.modules.ControlInterface; | ||||
| import de.jottyfan.timetrack.modules.Model; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  *  | ||||
|  */ | ||||
| @ManagedBean | ||||
| @RequestScoped | ||||
| public class NoteControl extends Navigation implements ControlInterface, Serializable | ||||
| { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{noteModel}") | ||||
| 	private NoteModel model; | ||||
|  | ||||
| 	@ManagedProperty(value = "#{facesContext}") | ||||
| 	private FacesContext facesContext; | ||||
|  | ||||
| 	public String toStart() | ||||
| 	{ | ||||
| 		return navigateTo(Pages.START); | ||||
| 	} | ||||
| 	 | ||||
| 	public String toList() | ||||
| 	{ | ||||
| 		boolean ready = model.init(facesContext); | ||||
| 		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(facesContext); | ||||
| 		return ready ? toList() : toItem(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doUpdate() | ||||
| 	{ | ||||
| 		boolean ready = model.update(facesContext); | ||||
| 		return ready ? toList() : toItem(model.getBean()); | ||||
| 	} | ||||
|  | ||||
| 	public String doDelete() | ||||
| 	{ | ||||
| 		boolean ready = model.delete(facesContext); | ||||
| 		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(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Model getModel() | ||||
| 	{ | ||||
| 		return model; | ||||
| 	} | ||||
|  | ||||
| 	public void setModel(NoteModel model) | ||||
| 	{ | ||||
| 		this.model = model; | ||||
| 	} | ||||
|  | ||||
| 	public void setFacesContext(FacesContext facesContext) | ||||
| 	{ | ||||
| 		this.facesContext = facesContext; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,102 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import static de.jottyfan.timetrack.db.note.Tables.T_NOTE; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| 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.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(FacesContext facesContext) | ||||
| 	{ | ||||
| 		super(facesContext); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * insert into t_note | ||||
| 	 *  | ||||
| 	 * @param noteBean | ||||
| 	 * @throws DataAccessException | ||||
| 	 * @returns amount of affected rows in db | ||||
| 	 */ | ||||
| 	public void insert(NoteBean bean) throws DataAccessException | ||||
| 	{ | ||||
| 		InsertValuesStep4<TNoteRecord, String, EnumCategory, EnumNotetype, String> sql = getJooq().insertInto(T_NOTE, T_NOTE.TITLE, T_NOTE.CATEGORY, T_NOTE.NOTETYPE, T_NOTE.CONTENT).values(bean.getTitle(), bean.getCategory(), bean.getType(), | ||||
| 				bean.getContent()); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * update content of bean | ||||
| 	 *  | ||||
| 	 * @param bean | ||||
| 	 * @throws DataAccessException | ||||
| 	 */ | ||||
| 	public void update(NoteBean bean) throws DataAccessException | ||||
| 	{ | ||||
| 		UpdateConditionStep<TNoteRecord> sql = getJooq().update(T_NOTE).set(T_NOTE.TITLE, bean.getTitle()).set(T_NOTE.CONTENT, bean.getContent()).where(T_NOTE.PK.eq(bean.getPk())); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * delete from t_note | ||||
| 	 *  | ||||
| 	 * @param pk | ||||
| 	 * @throws DataAccessException | ||||
| 	 */ | ||||
| 	public void delete(Integer pk) throws DataAccessException | ||||
| 	{ | ||||
| 		DeleteConditionStep<TNoteRecord> sql = getJooq().deleteFrom(T_NOTE).where(T_NOTE.PK.eq(pk)); | ||||
| 		LOGGER.debug(sql.toString()); | ||||
| 		sql.execute(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * get all from t_note | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 * @throws DataAccessException | ||||
| 	 */ | ||||
| 	public List<NoteBean> getAll() throws DataAccessException | ||||
| 	{ | ||||
| 		SelectJoinStep<Record> sql = getJooq().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; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										106
									
								
								src/main/java/de/jottyfan/timetrack/modules/note/NoteModel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/main/java/de/jottyfan/timetrack/modules/note/NoteModel.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| package de.jottyfan.timetrack.modules.note; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| import javax.faces.application.FacesMessage; | ||||
| import javax.faces.bean.ManagedBean; | ||||
| import javax.faces.bean.SessionScoped; | ||||
| import javax.faces.context.FacesContext; | ||||
|  | ||||
| import org.jooq.exception.DataAccessException; | ||||
|  | ||||
| import de.jottyfan.timetrack.db.note.Tables; | ||||
| import de.jottyfan.timetrack.modules.Model; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @ManagedBean | ||||
| @SessionScoped | ||||
| public class NoteModel implements Model, Serializable | ||||
| { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private List<NoteBean> beans; | ||||
| 	private NoteBean bean; | ||||
|  | ||||
| 	public boolean init(FacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			beans = new NoteGateway(facesContext).getAll(); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean add(FacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).insert(bean); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean update(FacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).update(bean); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public boolean delete(FacesContext facesContext) | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			new NoteGateway(facesContext).delete(bean.getPk()); | ||||
| 			return true; | ||||
| 		} | ||||
| 		catch (DataAccessException e) | ||||
| 		{ | ||||
| 			facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage())); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public Long getAmount(FacesContext facesContext) | ||||
| 	{ | ||||
| 		return new NoteGateway(facesContext).getAmount(Tables.T_NOTE); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public NoteBean getBean() | ||||
| 	{ | ||||
| 		return bean; | ||||
| 	} | ||||
| 	 | ||||
| 	public void setBean(NoteBean bean) | ||||
| 	{ | ||||
| 		this.bean = bean; | ||||
| 	} | ||||
|  | ||||
| 	public List<NoteBean> getBeans() | ||||
| 	{ | ||||
| 		return beans; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/main/resources/log4j2.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/main/resources/log4j2.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN" packages="rsslogger"> | ||||
|   <Appenders> | ||||
|     <Console name="Console" target="SYSTEM_OUT"> | ||||
|       <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss,SSS} [%5p] %t (%C.%M:%L) %m%n" /> | ||||
|     </Console> | ||||
|   </Appenders> | ||||
|   <Loggers> | ||||
|     <Root level="info"> | ||||
|       <AppenderRef ref="Console" /> | ||||
|     </Root> | ||||
|   </Loggers> | ||||
| </Configuration> | ||||
							
								
								
									
										14
									
								
								src/main/webapp/WEB-INF/faces-config.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/main/webapp/WEB-INF/faces-config.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
|  | ||||
| <faces-config xmlns="http://java.sun.com/xml/ns/javaee" | ||||
| 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" | ||||
| 	version="2.0"> | ||||
| 	<lifecycle> | ||||
| 		<phase-listener>de.jooqFaces.JooqFacesRenderResponsePhaseListener</phase-listener> | ||||
| 		<phase-listener>de.jooqFaces.JooqFacesRestoreViewPhaseListener</phase-listener> | ||||
| 	</lifecycle> | ||||
| 	<factory> | ||||
| 		<faces-context-factory>de.jooqFaces.JooqFacesContextFactory</faces-context-factory> | ||||
| 	</factory> | ||||
| </faces-config> | ||||
							
								
								
									
										69
									
								
								src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| <?xml version='1.0' encoding='UTF-8'?> | ||||
| <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" | ||||
| 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> | ||||
| 	<display-name>timetrack</display-name> | ||||
| 	<filter> | ||||
| 		<filter-name>EncodingFilter</filter-name> | ||||
| 		<filter-class>de.jottyfan.timetrack.help.EncodingFilter</filter-class> | ||||
| 		<init-param> | ||||
| 			<param-name>encoding</param-name> | ||||
| 			<param-value>UTF-8</param-value> | ||||
| 		</init-param> | ||||
| 	</filter> | ||||
| 	<servlet> | ||||
| 		<servlet-name>Faces Servlet</servlet-name> | ||||
| 		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class> | ||||
| 		<load-on-startup>1</load-on-startup> | ||||
| 	</servlet> | ||||
| 	<servlet-mapping> | ||||
| 		<servlet-name>Faces Servlet</servlet-name> | ||||
| 		<url-pattern>*.jsf</url-pattern> | ||||
| 	</servlet-mapping> | ||||
| 	<session-config> | ||||
| 		<session-timeout>580</session-timeout> | ||||
| 	</session-config> | ||||
| 	<welcome-file-list> | ||||
| 		<welcome-file>pages/start.jsf</welcome-file> | ||||
| 	</welcome-file-list> | ||||
| 	<context-param> | ||||
| 		<param-name>org.apache.myfaces.RENDER_VIEWSTATE_ID</param-name> | ||||
| 		<param-value>false</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name> | ||||
| 		<param-value>true</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>javax.faces.STATE_SAVING_METHOD</param-name> | ||||
| 		<param-value>client</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> | ||||
| 		<param-value>true</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>javax.faces.PROJECT_STAGE</param-name> | ||||
| 		<param-value>Production</param-value> | ||||
| 		<!-- <param-value>Development</param-value> --> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>org.apache.myfaces.LOG_WEB_CONTEXT_PARAMS</param-name> | ||||
| 		<param-value>false</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>BootsFaces_USETHEME</param-name> | ||||
| 		<param-value>true</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>BootsFaces_THEME</param-name> | ||||
| 		<param-value>#{themeBean.currentTheme}</param-value> | ||||
| 	</context-param> | ||||
| 	<context-param> | ||||
| 		<param-name>jooqFacesProperties</param-name> | ||||
| 		<param-value>/etc/tomcat8/timetrack.properties</param-value> | ||||
| 	</context-param> | ||||
| 	<listener> | ||||
|     <listener-class>de.jooqFaces.PropertiesDeploymentListener</listener-class> | ||||
|   </listener> | ||||
| </web-app> | ||||
							
								
								
									
										42
									
								
								src/main/webapp/pages/contact/item.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/main/webapp/pages/contact/item.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
|   <title>Kontakte</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"></ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Kontakt" look="primary"> | ||||
|         <h:form> | ||||
|           <b:panelGrid colSpans="3,9"> | ||||
|             <h:outputText value="Vorname" /> | ||||
|             <b:inputText value="#{contactModel.bean.forename}" /> | ||||
|             <h:outputText value="Nachname" /> | ||||
|             <b:inputText value="#{contactModel.bean.surname}" /> | ||||
|             <h:outputText value="Kontakt" /> | ||||
|             <b:inputText value="#{contactModel.bean.contact}" /> | ||||
|             <h:outputText value="Typ" /> | ||||
|             <b:selectOneMenu value="#{contactModel.bean.type}"> | ||||
|               <f:selectItems value="#{contactModel.types}" var="t" itemValue="#{t}" itemLabel="#{t.literal}" /> | ||||
|             </b:selectOneMenu> | ||||
|             <h:outputText value="" /> | ||||
|             <b:buttonGroup> | ||||
|               <b:commandButton action="#{contactControl.toList}" value="Abbrechen" /> | ||||
|               <b:commandButton action="#{contactControl.doAdd}" value="Hinzufügen" look="success" iconAwesome="plus" | ||||
|                 rendered="#{contactModel.bean.pk == null}" /> | ||||
|               <b:commandButton action="#{contactControl.doUpdate}" value="Übernehmen" look="primary" iconAwesome="pencil" | ||||
|                 rendered="#{contactModel.bean.pk != null}" /> | ||||
|               <b:dropButton value="Löschen" iconAwesome="trash" look="danger" rendered="#{contactModel.bean.pk != null}"> | ||||
|                 <b:navCommandLink action="#{contactControl.doDelete}" value="ja, wirklich" /> | ||||
|               </b:dropButton> | ||||
|             </b:buttonGroup> | ||||
|           </b:panelGrid> | ||||
|         </h:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										41
									
								
								src/main/webapp/pages/contact/list.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/main/webapp/pages/contact/list.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
| 	<title>Kontakte</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
| 	<ui:composition template="/pages/template.xhtml"> | ||||
| 		<ui:define name="top"> | ||||
| 		</ui:define> | ||||
| 		<ui:define name="main"> | ||||
| 			<b:panel title="Kontakte" look="primary"> | ||||
| 				<b:form> | ||||
| 					<b:dataTable value="#{contactModel.list}" var="bean" lang="de"> | ||||
| 						<b:dataTableColumn label="Vorname"> | ||||
| 							<b:commandButton action="#{(contactControl.toItem(bean))}" value="#{bean.forename}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Nachname"> | ||||
| 							<b:commandButton action="#{(contactControl.toItem(bean))}" value="#{bean.surname}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Kontakt"> | ||||
| 							<b:commandButton action="#{(contactControl.toItem(bean))}" value="#{bean.contact}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Typ"> | ||||
| 							<b:commandButton action="#{(contactControl.toItem(bean))}" value="#{bean.type.literal}" look="link" rendered="#{bean.type != null}" /> | ||||
| 						</b:dataTableColumn> | ||||
| 					</b:dataTable> | ||||
| 				</b:form> | ||||
| 			</b:panel> | ||||
| 		</ui:define> | ||||
| 		<ui:define name="navigation"> | ||||
| 			<h:form> | ||||
| 				<b:buttonGroup> | ||||
| 					<b:commandButton action="#{contactControl.toStart}" value="zurück" look="primary" iconAwesome="arrow-left" /> | ||||
|           <b:commandButton action="#{contactControl.toItem}" value="hinzufügen" look="success" iconAwesome="plus" /> | ||||
| 				</b:buttonGroup> | ||||
| 			</h:form> | ||||
| 		</ui:define> | ||||
| 	</ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										79
									
								
								src/main/webapp/pages/done/add.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/main/webapp/pages/done/add.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:b="http://bootsfaces.net/ui" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" | ||||
|   xmlns:p="http://xmlns.jcp.org/jsf/passthrough"> | ||||
| <h:head> | ||||
|   <title>Arbeitszeit</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"> | ||||
|     </ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Arbeitszeit für #{doneModel.day}, aktualisiert um #{doneControl.currentTimeAsString}" look="success"> | ||||
|         <b:form id="formular"> | ||||
|           <h:panelGrid columns="2" columnClasses="tdtop, tdtop"> | ||||
|             <b:inputText id="time_from" value="#{doneModel.bean.timeFromString}"> | ||||
|               <f:facet name="prepend"> | ||||
|                 <h:outputText value="Von" /> | ||||
|               </f:facet> | ||||
|             </b:inputText> | ||||
|             <b:buttonGroup p:class="form-group"> | ||||
|               <b:button value="--:--" onclick="document.getElementById('input_formular:time_from').value = ''; return false;" | ||||
|                 look="danger" /> | ||||
|               <ui:repeat var="time" value="#{doneModel.times}"> | ||||
|                 <b:button onclick="document.getElementById('input_formular:time_from').value = '#{time.value}'; return false;" | ||||
|                   value="#{time.value}" look="#{time.look}" /> | ||||
|               </ui:repeat> | ||||
|             </b:buttonGroup> | ||||
|             <b:inputText id="time_until" value="#{doneModel.bean.timeUntilString}"> | ||||
|               <f:facet name="prepend"> | ||||
|                 <h:outputText value="Bis" /> | ||||
|               </f:facet> | ||||
|             </b:inputText> | ||||
|             <b:buttonGroup p:class="form-group"> | ||||
|               <b:button value="--:--" onclick="document.getElementById('input_formular:time_until').value = ''; return false;" | ||||
|                 look="danger" /> | ||||
|               <ui:repeat var="time" value="#{doneModel.times}"> | ||||
|                 <b:button onclick="document.getElementById('input_formular:time_until').value = '#{time.value}'; return false;" | ||||
|                   value="#{time.value}" look="#{time.look}" /> | ||||
|               </ui:repeat> | ||||
|             </b:buttonGroup> | ||||
|           </h:panelGrid> | ||||
|           <b:panelGrid colSpans="4,4,4" size="xs"> | ||||
|             <h:outputText value="Projekt" /> | ||||
|             <h:outputText value="Modul" /> | ||||
|             <h:outputText value="Tätigkeit" /> | ||||
|             <b:selectOneMenu id="project" value="#{doneModel.bean.project}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.projects}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|             <b:selectOneMenu id="module" value="#{doneModel.bean.module}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.modules}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|             <b:selectOneMenu id="activity" value="#{doneModel.bean.activity}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.activities}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|           </b:panelGrid> | ||||
|           <b:buttonGroup> | ||||
|             <b:commandButton action="#{doneControl.toList}" immediate="true" value="Abbrechen" /> | ||||
|             <b:commandButton action="#{doneControl.doAdd}" value="Eintrag hinzufügen" look="success" iconAwesome="plus" /> | ||||
|           </b:buttonGroup> | ||||
|           <script type="text/javascript"> | ||||
| 											$(document).ready(function() { | ||||
| 												$("[id='formular:projectInner']").attr("size", 25); | ||||
| 												$("[id='formular:moduleInner']").attr("size", 25); | ||||
| 												$("[id='formular:activityInner']").attr("size", 25); | ||||
| 											}); | ||||
| 										</script> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|     <ui:define name="navigation"> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										37
									
								
								src/main/webapp/pages/done/delete.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/main/webapp/pages/done/delete.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
|   <title>Arbeitszeit</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"> | ||||
| 			Arbeitszeit | ||||
| 		</ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Löschen eines Eintrags" look="danger" style="font-size: initial"> | ||||
|         <b:panelGrid colSpans="6,6" style="max-width: 200px" size="xs"> | ||||
|           <h:outputText value="Von: " /> | ||||
|           <h:outputText value="#{doneModel.bean.timeFromString}" style="font-weight: bolder" /> | ||||
|           <h:outputText value="Bis: " /> | ||||
|           <h:outputText value="#{doneModel.bean.timeUntilString}" style="font-weight: bolder" /> | ||||
|           <h:outputText value="Projekt: " /> | ||||
|           <h:outputText value="#{doneModel.bean.projectName}" style="font-weight: bolder" /> | ||||
|           <h:outputText value="Modul: " /> | ||||
|           <h:outputText value="#{doneModel.bean.moduleName}" style="font-weight: bolder" /> | ||||
|           <h:outputText value="Tätigkeit: " /> | ||||
|           <h:outputText value="#{doneModel.bean.jobName}" style="font-weight: bolder" /> | ||||
|         </b:panelGrid> | ||||
|         <b:form> | ||||
|           <b:buttonGroup> | ||||
|             <b:commandButton action="#{doneControl.toInit}" immediate="true" value="Abbrechen" /> | ||||
|             <b:commandButton action="#{doneControl.doDelete}" value="Entfernen" look="danger" iconAwesome="trash" /> | ||||
|           </b:buttonGroup> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										79
									
								
								src/main/webapp/pages/done/edit.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/main/webapp/pages/done/edit.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:b="http://bootsfaces.net/ui" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" | ||||
|   xmlns:p="http://xmlns.jcp.org/jsf/passthrough"> | ||||
| <h:head> | ||||
|   <title>Arbeitszeit</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"> | ||||
|     </ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Arbeitszeit für #{doneModel.day}, aktualisiert um #{doneControl.currentTimeAsString}" look="warning"> | ||||
|         <b:form id="formular"> | ||||
|           <h:panelGrid columns="2" columnClasses="tdtop, tdtop"> | ||||
|             <b:inputText id="time_from" value="#{doneModel.bean.timeFromString}"> | ||||
|               <f:facet name="prepend"> | ||||
|                 <h:outputText value="Von" /> | ||||
|               </f:facet> | ||||
|             </b:inputText> | ||||
|             <b:buttonGroup p:class="form-group"> | ||||
|               <b:button value="--:--" onclick="document.getElementById('input_formular:time_from').value = ''; return false;" | ||||
|                 look="danger" /> | ||||
|               <ui:repeat var="time" value="#{doneModel.times}"> | ||||
|                 <b:button onclick="document.getElementById('input_formular:time_from').value = '#{time.value}'; return false;" | ||||
|                   value="#{time.value}" look="#{time.look}" /> | ||||
|               </ui:repeat> | ||||
|             </b:buttonGroup> | ||||
|             <b:inputText id="time_until" value="#{doneModel.bean.timeUntilString}"> | ||||
|               <f:facet name="prepend"> | ||||
|                 <h:outputText value="Bis" /> | ||||
|               </f:facet> | ||||
|             </b:inputText> | ||||
|             <b:buttonGroup p:class="form-group"> | ||||
|               <b:button value="--:--" onclick="document.getElementById('input_formular:time_until').value = ''; return false;" | ||||
|                 look="danger" /> | ||||
|               <ui:repeat var="time" value="#{doneModel.times}"> | ||||
|                 <b:button onclick="document.getElementById('input_formular:time_until').value = '#{time.value}'; return false;" | ||||
|                   value="#{time.value}" look="#{time.look}" /> | ||||
|               </ui:repeat> | ||||
|             </b:buttonGroup> | ||||
|           </h:panelGrid> | ||||
|           <b:panelGrid colSpans="4,4,4" size="xs"> | ||||
|             <h:outputText value="Projekt (#{doneModel.bean.projectName})" /> | ||||
|             <h:outputText value="Modul (#{doneModel.bean.moduleName})" /> | ||||
|             <h:outputText value="Tätigkeit (#{doneModel.bean.jobName})" /> | ||||
|             <b:selectOneMenu id="project" value="#{doneModel.bean.project}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.projects}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|             <b:selectOneMenu id="module" value="#{doneModel.bean.module}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.modules}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|             <b:selectOneMenu id="activity" value="#{doneModel.bean.activity}"> | ||||
|               <f:selectItem itemValue="" itemLabel="--- bitte wählen ---" /> | ||||
|               <f:selectItems value="#{doneModel.activities}" var="i" itemValue="#{i}" itemLabel="#{i.name}" /> | ||||
|             </b:selectOneMenu> | ||||
|           </b:panelGrid> | ||||
|           <b:buttonGroup> | ||||
|             <b:commandButton action="#{doneControl.toList}" immediate="true" value="Abbrechen" /> | ||||
|             <b:commandButton action="#{doneControl.doUpdate}" value="Aktualisieren" iconAwesome="pencil" look="warning" /> | ||||
|           </b:buttonGroup> | ||||
|           <script type="text/javascript"> | ||||
| 											$(document).ready(function() { | ||||
| 												$("[id='formular:projectInner']").attr("size", 25); | ||||
| 												$("[id='formular:moduleInner']").attr("size", 25); | ||||
| 												$("[id='formular:activityInner']").attr("size", 25); | ||||
| 											}); | ||||
| 										</script> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|     <ui:define name="navigation"> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										97
									
								
								src/main/webapp/pages/done/init.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/main/webapp/pages/done/init.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
|   <title>Arbeitszeit</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"></ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Arbeitszeit" look="primary"> | ||||
|         <b:form> | ||||
|           <h:panelGrid columns="3"> | ||||
|             <h:outputText value="für den Tag" /> | ||||
|             <b:dateTimePicker value="#{doneModel.day}" showTime="false" style="padding-left: 4px" /> | ||||
|             <b:commandButton action="#{doneControl.toList}" value="neu laden" look="default" iconAwesome="refresh" | ||||
|               style="padding-left: 4px" /> | ||||
|           </h:panelGrid> | ||||
|           <b:tabView> | ||||
|             <b:tab title="Liste"> | ||||
|               <b:dataTable value="#{doneModel.beans}" var="b" border="false" info="false" paginated="false" searching="false" | ||||
|                 styleClass="doneoverview"> | ||||
|                 <b:dataTableColumn label="" orderable="false"> | ||||
|                   <b:commandButton action="#{doneControl.toDelete(b)}" value="Entfernen" look="danger" iconAwesome="trash" /> | ||||
|                 </b:dataTableColumn> | ||||
|                 <b:dataTableColumn label="" value="#{b.timeSummary}" contentStyleClass="doneoverviewtext" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{b.projectName}" contentStyleClass="doneoverviewtextemph" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{b.timeDiff}" contentStyleClass="doneoverviewtextemph" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" orderable="false"> | ||||
|                   <b:commandButton action="#{doneControl.toEdit(b)}" value="Editieren" look="warning" iconAwesome="pencil" /> | ||||
|                 </b:dataTableColumn> | ||||
|                 <b:dataTableColumn label="" value="#{b.moduleName}" contentStyleClass="doneoverviewtext" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{b.jobName}" contentStyleClass="doneoverviewtext" orderable="false" /> | ||||
|               </b:dataTable> | ||||
|             </b:tab> | ||||
|             <b:tab title="Zusammenfassung"> | ||||
|               <b:dataTable value="#{doneModel.allJobs}" var="col" border="false" info="false" paginated="false" | ||||
|                 searching="false"> | ||||
|                 <b:dataTableColumn label="" value="#{col.projectName}" contentStyle="font-size: 120%" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{col.moduleName}" contentStyle="font-size: 120%" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{col.jobName}" contentStyle="font-size: 120%" orderable="false" /> | ||||
|                 <b:dataTableColumn label="" value="#{col.duration}" contentStyle="font-size: 120%" orderable="false" /> | ||||
|               </b:dataTable> | ||||
|             </b:tab> | ||||
|           </b:tabView> | ||||
|           <b:row rendered="#{doneModel.daySummary != null}"> | ||||
|             <b:column colXs="4"> | ||||
|               <b:well styleClass="dangerWell">Pause | ||||
|               <h3> | ||||
|                   <h:outputText value="#{doneModel.daySummary.breakTime}" /> | ||||
|                 </h3> | ||||
|               </b:well> | ||||
|             </b:column> | ||||
|             <b:column colXs="4"> | ||||
|               <b:well>Startzeit | ||||
|               <h3> | ||||
|                   <h:outputText value="#{doneModel.daySummary.startTime}" /> | ||||
|                 </h3> | ||||
|               </b:well> | ||||
|             </b:column> | ||||
|             <b:column colXs="4"> | ||||
|               <b:well>Überstunden | ||||
|               <h3> | ||||
|                   <h:outputText value="#{doneModel.daySummary.overtime}" /> | ||||
|                 </h3> | ||||
|               </b:well> | ||||
|             </b:column> | ||||
|             <b:column colXs="4"> | ||||
|               <b:well styleClass="successWell">Arbeitszeit | ||||
|               <h3> | ||||
|                   <h:outputText value="#{doneModel.daySummary.workTime}" /> | ||||
|                 </h3> | ||||
|               </b:well> | ||||
|             </b:column> | ||||
|             <b:column colXs="4"> | ||||
|               <b:well>Endzeit | ||||
|               <h3> | ||||
|                   <h:outputText value="#{doneModel.daySummary.endTime}" /> | ||||
|                 </h3> | ||||
|               </b:well> | ||||
|             </b:column> | ||||
|           </b:row> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|     <ui:define name="navigation"> | ||||
|       <b:form> | ||||
|         <b:buttonGroup> | ||||
|           <b:commandButton action="#{doneControl.toStart}" value="zurück" look="primary" iconAwesome="arrow-left" /> | ||||
|           <b:commandButton action="#{doneControl.toAdd}" value="Neuer Eintrag" look="success" iconAwesome="plus" /> | ||||
|         </b:buttonGroup> | ||||
|       </b:form> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										47
									
								
								src/main/webapp/pages/note/item.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/main/webapp/pages/note/item.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
| 	<title>Aufgaben</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
| 	<ui:composition template="/pages/template.xhtml"> | ||||
| 		<ui:define name="top"></ui:define> | ||||
| 		<ui:define name="main"> | ||||
| 			<b:panel title="Notizen" look="primary"> | ||||
| 				<h:form> | ||||
| 					<b:panelGrid colSpans="3,9"> | ||||
| 						<h:outputText value="Titel" /> | ||||
| 						<b:inputText value="#{noteModel.bean.title}" /> | ||||
| 						<h:outputText value="Kategorie" /> | ||||
| 						<b:selectOneMenu value="#{noteModel.bean.category}"> | ||||
| 							<f:selectItem itemLabel="PostgreSQL" itemValue="PostgreSQL" /> | ||||
| 							<f:selectItem itemLabel="R" itemValue="R" /> | ||||
| 							<f:selectItem itemLabel="Bootsfaces" itemValue="Bootsfaces" /> | ||||
| 							<f:selectItem itemLabel="MyFaces" itemValue="MyFaces" /> | ||||
| 							<f:selectItem itemLabel="Java" itemValue="Java" /> | ||||
| 							<f:selectItem itemLabel="Bash" itemValue="Bash" /> | ||||
| 							<f:selectItem itemLabel="Apache" itemValue="Apache" /> | ||||
| 							<f:selectItem itemLabel="Tomcat" itemValue="Tomcat" /> | ||||
| 						</b:selectOneMenu> | ||||
| 						<h:outputText value="Typ" /> | ||||
| 						<b:selectOneMenu value="#{noteModel.bean.type}"> | ||||
| 							<f:selectItem itemLabel="Administration" itemValue="Administration" /> | ||||
| 							<f:selectItem itemLabel="HowTo" itemValue="HowTo" /> | ||||
| 						</b:selectOneMenu> | ||||
| 						<h:outputText value="Inhalt" /> | ||||
| 						<b:inputTextarea value="#{noteModel.bean.content}" /> | ||||
| 						<h:outputText value="" /> | ||||
| 						<b:buttonGroup> | ||||
| 							<b:commandButton action="#{noteControl.toList}" value="Abbrechen" /> | ||||
| 							<b:commandButton action="#{noteControl.doAdd}" value="Hinzufügen" look="success" iconAwesome="plus" rendered="#{noteModel.bean.pk == null}" /> | ||||
| 							<b:commandButton action="#{noteControl.doUpdate}" value="Übernehmen" look="primary" iconAwesome="pencil" rendered="#{noteModel.bean.pk != null}" /> | ||||
| 							<b:commandButton action="#{noteControl.doDelete}" value="Löschen" look="danger" iconAwesome="trash" rendered="#{noteModel.bean.pk != null}" /> | ||||
| 						</b:buttonGroup> | ||||
| 					</b:panelGrid> | ||||
| 				</h:form> | ||||
| 			</b:panel> | ||||
| 		</ui:define> | ||||
| 	</ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										45
									
								
								src/main/webapp/pages/note/list.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/main/webapp/pages/note/list.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
| 	<title>Aufgaben</title> | ||||
| </h:head> | ||||
| <h:body> | ||||
| 	<ui:composition template="/pages/template.xhtml"> | ||||
| 		<ui:define name="top"> | ||||
| 			<b:messages /> | ||||
| 		</ui:define> | ||||
| 		<ui:define name="main"> | ||||
| 			<b:panel title="Notizen" look="primary"> | ||||
| 				<h:form> | ||||
| 					<b:dataTable value="#{noteModel.beans}" var="n" lang="de" pageLength="5" pageLengthMenu="5,10,20,50,100" saveState="true" striped="false"> | ||||
| 						<b:dataTableColumn label="Titel"> | ||||
| 							<b:commandButton action="#{noteControl.toItem(n)}" value="#{n.title}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Kategorie"> | ||||
| 							<b:commandButton action="#{noteControl.toItem(n)}" value="#{n.category}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Typ"> | ||||
| 							<b:commandButton action="#{noteControl.toItem(n)}" value="#{n.type}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Inhalt"> | ||||
| 							<b:commandButton action="#{noteControl.toItem(n)}" value="#{noteControl.trimTo(n.content, 32)}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 						<b:dataTableColumn label="Angelegt"> | ||||
| 							<b:commandButton action="#{noteControl.toItem(n)}" value="#{n.lastchange}" look="link" /> | ||||
| 						</b:dataTableColumn> | ||||
| 					</b:dataTable> | ||||
| 				</h:form> | ||||
| 			</b:panel> | ||||
| 		</ui:define> | ||||
| 		<ui:define name="navigation"> | ||||
| 			<h:form> | ||||
| 				<b:buttonGroup> | ||||
| 					<b:commandButton action="#{noteControl.toStart}" value="zurück" look="primary" iconAwesome="arrow-left" /> | ||||
| 					<b:commandButton action="#{noteControl.toAdd}" value="hinzufügen" look="success" iconAwesome="plus" /> | ||||
| 				</b:buttonGroup> | ||||
| 			</h:form> | ||||
| 		</ui:define> | ||||
| 	</ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										52
									
								
								src/main/webapp/pages/start.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/main/webapp/pages/start.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||||
|         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" | ||||
|   xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
| </h:head> | ||||
| <h:body> | ||||
|   <ui:composition template="/pages/template.xhtml"> | ||||
|     <ui:define name="top"> | ||||
|       <b:messages /> | ||||
|     </ui:define> | ||||
|     <ui:define name="main"> | ||||
|       <b:panel title="Einstellungen" collapsed="true" rendered="#{sessionBean.hasLogin}"> | ||||
|         <b:form> | ||||
|           <b:selectOneMenu value="#{themeBean.currentTheme}"> | ||||
|             <f:selectItems value="#{themeBean.validThemes}" var="t" itemValue="#{t}" itemLabel="#{t}" /> | ||||
|           </b:selectOneMenu> | ||||
|           <b:commandButton action="#{doneControl.toStart}" value="ändern" iconAwesome="pencil" look="warning" /> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|       <b:panel title="Login" rendered="#{sessionBean.hasNoLogin}" styleClass="loginpanel"> | ||||
|         <b:form> | ||||
|           <b:selectOneMenu value="#{sessionBean.username}"> | ||||
|             <f:facet name="prepend"> | ||||
|               <h:outputText value="Username" /> | ||||
|             </f:facet> | ||||
|             <f:selectItem itemValue="henkej" itemLabel="Jörg Henke" /> | ||||
|           </b:selectOneMenu> | ||||
|           <b:inputSecret value="#{sessionBean.secret}"> | ||||
|             <f:facet name="prepend"> | ||||
|               <h:outputText value="Passwort" /> | ||||
|             </f:facet> | ||||
|           </b:inputSecret> | ||||
|           <b:commandButton action="#{sessionControl.doLogin}" value="Login" look="primary" /> | ||||
|         </b:form> | ||||
|       </b:panel> | ||||
|     </ui:define> | ||||
|     <ui:define name="navigation"> | ||||
|       <b:form rendered="#{sessionBean.hasLogin}"> | ||||
|         <b:buttonGroup> | ||||
|           <b:commandButton action="#{noteControl.toList}" value="#{noteControl.amount} Notizen verwalten" look="primary" | ||||
|             iconAwesome="comments-o" /> | ||||
|           <b:commandButton action="#{contactControl.toList}" value="#{contactControl.amount} Kontakte verwalten" look="primary" | ||||
|             iconAwesome="group" /> | ||||
|           <b:commandButton action="#{doneControl.toList}" value="Arbeitszeit verwalten" look="primary" iconAwesome="clock-o" /> | ||||
|           <b:commandButton action="#{sessionControl.doLogout}" value="abmelden" look="danger" iconAwesome="sign-out" /> | ||||
|         </b:buttonGroup> | ||||
|       </b:form> | ||||
|     </ui:define> | ||||
|   </ui:composition> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										24
									
								
								src/main/webapp/pages/template.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/main/webapp/pages/template.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||||
| <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:my="http://xmlns.jcp.org/jsf/composite/my" xmlns:b="http://bootsfaces.net/ui"> | ||||
| <h:head> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||||
| </h:head> | ||||
| <h:body styleClass="body"> | ||||
|   <h:outputStylesheet name="css/style.css" /> | ||||
|   <h:outputScript library="bsf" name="jq/jquery.js" target="head" /> | ||||
|   <div class="page"> | ||||
|     <div class="top"> | ||||
|       <ui:insert name="top" /> | ||||
|     </div> | ||||
|     <div> | ||||
|       <b:messages /> | ||||
|     </div> | ||||
|     <div class="body"> | ||||
|       <ui:insert name="main" /> | ||||
|     </div> | ||||
|     <div class="navigation"> | ||||
|       <ui:insert name="navigation" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </h:body> | ||||
| </html> | ||||
							
								
								
									
										36
									
								
								src/main/webapp/resources/css/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/main/webapp/resources/css/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| .emph { | ||||
| 	border-radius: 3px !important; | ||||
| 	border: 1px solid #3070b0 !important; | ||||
| 	color: #ffffff !important; | ||||
| 	background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%) | ||||
| 		!important; | ||||
| } | ||||
|  | ||||
| .doneoverview { | ||||
| 	max-width: 850px !important; | ||||
| 	width: 850px !important; | ||||
| } | ||||
|  | ||||
| .doneoverviewtext { | ||||
| 	font-size: 120%; | ||||
| } | ||||
|  | ||||
| .doneoverviewtextemph { | ||||
| 	font-size: 120%; | ||||
| 	font-weight: bolder; | ||||
| } | ||||
|  | ||||
| .loginpanel { | ||||
| 	margin-top: 100px !important; | ||||
| 	margin: 0 auto; | ||||
| 	max-width: 400px !important; | ||||
| 	width: 400px !important; | ||||
| } | ||||
|  | ||||
| .successWell { | ||||
| 	background-image: linear-gradient(to bottom, #ceeaca 0%, #f7fff7 100%) !important; | ||||
| } | ||||
|  | ||||
| .dangerWell { | ||||
| 	background-image: linear-gradient(to bottom, #eacaca 0%, #fff7f7 100%) !important; | ||||
| } | ||||
							
								
								
									
										29
									
								
								src/main/webapp/resources/my/selectOneMenu.xhtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/webapp/resources/my/selectOneMenu.xhtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:cc="http://xmlns.jcp.org/jsf/composite" | ||||
|   xmlns:b="http://bootsfaces.net/ui"> | ||||
|   <cc:interface> | ||||
|     <cc:attribute name="list" required="true" type="java.util.List" /> | ||||
|     <cc:attribute name="value" required="true" default="" /> | ||||
|     <cc:attribute name="styleClass" required="false" default="" /> | ||||
|     <cc:attribute name="readonly" required="false" default="true" /> | ||||
|   </cc:interface> | ||||
|   <cc:implementation> | ||||
|     <h:outputScript library="bsf" name="jq/jquery.js" target="head" /> | ||||
|     <script type="text/javascript"> | ||||
| 	function setValue(dest, content) | ||||
| 	{ | ||||
| 	  $("[id='" + dest + "']").val(content); | ||||
| 	} | ||||
|     </script> | ||||
|     <b:inputText id="input" value="#{cc.attrs.value}" styleClass="#{cc.attrs.styleClass}" readonly="#{cc.attrs.readonly}"> | ||||
|       <f:facet name="prepend"> | ||||
|         <b:dropButton value=""> | ||||
|           <h:dataTable value="#{cc.attrs.list}" var="l"> | ||||
|             <h:column> | ||||
|               <b:button value="#{l}" onclick="setValue('input_#{cc.clientId}:input', '#{l}'); return false;" look="link" /> | ||||
|             </h:column> | ||||
|           </h:dataTable> | ||||
|         </b:dropButton> | ||||
|       </f:facet> | ||||
|     </b:inputText> | ||||
|   </cc:implementation> | ||||
| </ui:composition> | ||||
		Reference in New Issue
	
	Block a user