removed calendar
This commit is contained in:
@ -4,12 +4,8 @@ import static de.jottyfan.timetrack.db.done.Tables.T_BILLING;
|
|||||||
import static de.jottyfan.timetrack.db.done.Tables.T_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_JOB;
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.T_MODULE;
|
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.profile.Tables.T_LOGIN;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_BILLING;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_JOB;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_MODULE;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_PROJECT;
|
import static de.jottyfan.timetrack.db.done.Tables.V_PROJECT;
|
||||||
|
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -32,8 +28,8 @@ import org.jooq.exception.DataAccessException;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VBillingRecord;
|
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord;
|
||||||
|
import de.jottyfan.timetrack.db.done.tables.records.VBillingRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||||
@ -68,7 +64,7 @@ public class DoneGateway {
|
|||||||
Result<TLoginRecord> r = getJooq().selectFrom(T_LOGIN).where(T_LOGIN.LOGIN.eq(username)).fetch();
|
Result<TLoginRecord> r = getJooq().selectFrom(T_LOGIN).where(T_LOGIN.LOGIN.eq(username)).fetch();
|
||||||
return r == null || r.size() < 1 ? null : r.get(0).getPk();
|
return r == null || r.size() < 1 ? null : r.get(0).getPk();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get all projects from the database
|
* get all projects from the database
|
||||||
*
|
*
|
||||||
|
@ -128,5 +128,4 @@ public class DoneService implements IDoneService {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface Bean
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ControlInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* navigate to init page of module
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws DBException
|
|
||||||
*/
|
|
||||||
public String toList();
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import javax.faces.application.FacesMessage;
|
|
||||||
|
|
||||||
import org.jooq.CloseableDSLContext;
|
|
||||||
import org.jooq.TableLike;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JooqGateway {
|
|
||||||
private final JooqFacesContext facesContext;
|
|
||||||
|
|
||||||
public JooqGateway(JooqFacesContext facesContext) {
|
|
||||||
this.facesContext = facesContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloseableDSLContext getJooq() throws ClassNotFoundException, SQLException {
|
|
||||||
return facesContext.getJooq();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addToSessionMap(String key, Object value) {
|
|
||||||
facesContext.getExternalContext().getSessionMap().put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getFkLogin() {
|
|
||||||
SessionBean bean = (SessionBean) facesContext.getExternalContext().getSessionMap().get("sessionBean");
|
|
||||||
if (bean == null) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "schwerer Anwendungsfehler",
|
|
||||||
"no sessionBean found in session, therefore, set fkLogin to 1"));
|
|
||||||
bean = new SessionBean();
|
|
||||||
bean.setLogin(1);
|
|
||||||
}
|
|
||||||
return bean.getLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return amount of "select count(1) as amount " + subQuery
|
|
||||||
*
|
|
||||||
* @param subQuery
|
|
||||||
* @return number of entries
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public Long getAmount(TableLike<?> table) throws ClassNotFoundException, SQLException {
|
|
||||||
return getJooq().selectCount().from(table).fetchOne(0, long.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface Model
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* get bean of model
|
|
||||||
*
|
|
||||||
* @return bean
|
|
||||||
*/
|
|
||||||
public Bean getBean();
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.enterprise.context.SessionScoped;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import org.jasypt.util.password.StrongPasswordEncryptor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@SessionScoped
|
|
||||||
public class SessionBean implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private Set<String> privileges;
|
|
||||||
private Integer login;
|
|
||||||
private String username;
|
|
||||||
private String secret;
|
|
||||||
private String forename;
|
|
||||||
private String surname;
|
|
||||||
|
|
||||||
public SessionBean() {
|
|
||||||
this.privileges = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Boolean hasPrivilege(String privilege) {
|
|
||||||
return privileges.contains(privilege);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the privileges
|
|
||||||
*/
|
|
||||||
public Set<String> getPrivileges() {
|
|
||||||
return privileges;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
|
||||||
import javax.faces.application.FacesMessage;
|
|
||||||
import javax.faces.context.FacesContext;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
import de.jottyfan.timetrack.help.Pages;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@RequestScoped
|
|
||||||
public class SessionControl {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private SessionBean sessionBean;
|
|
||||||
|
|
||||||
private String secretNew1;
|
|
||||||
private String secretNew2;
|
|
||||||
|
|
||||||
public String doLogin() {
|
|
||||||
SessionModel model = new SessionModel();
|
|
||||||
model.doLogin((JooqFacesContext) FacesContext.getCurrentInstance(), sessionBean);
|
|
||||||
return Pages.START.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doLogout() {
|
|
||||||
sessionBean.setLogin(null);
|
|
||||||
sessionBean.setSecret(null);
|
|
||||||
sessionBean.setForename(null);
|
|
||||||
sessionBean.setSurname(null);
|
|
||||||
sessionBean.setUsername(null);
|
|
||||||
sessionBean.getPrivileges().clear();
|
|
||||||
return Pages.START.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doChangePassword() {
|
|
||||||
if (!secretNew1.equals(secretNew2)) {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on changing password",
|
|
||||||
"passwords are not equal");
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null, msg);
|
|
||||||
return "";
|
|
||||||
} else if (new SessionModel().doChangePassword((JooqFacesContext) FacesContext.getCurrentInstance(), secretNew1)) {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "successfully changed password",
|
|
||||||
"the new password has been saved");
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null, msg);
|
|
||||||
return Pages.START.get();
|
|
||||||
} else {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on changing password",
|
|
||||||
"database change was not successful");
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null, msg);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the version from the mainfest file
|
|
||||||
*
|
|
||||||
* @return the version
|
|
||||||
*/
|
|
||||||
public String getVersion() {
|
|
||||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
|
||||||
try (InputStream is = facesContext.getExternalContext().getResourceAsStream("META-INF/MANIFEST.MF")){
|
|
||||||
// from servletcontext
|
|
||||||
Properties attributes = new Properties();
|
|
||||||
attributes.load(is);
|
|
||||||
return attributes.getProperty("Implementation-Version", "no Implementation-Version attribute found in MANIFEST");
|
|
||||||
} catch (Exception e) {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on loading the version from the Manifest file", e.getMessage());
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null, msg);
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the secretNew1
|
|
||||||
*/
|
|
||||||
public String getSecretNew1() {
|
|
||||||
return secretNew1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param secretNew1 the secretNew1 to set
|
|
||||||
*/
|
|
||||||
public void setSecretNew1(String secretNew1) {
|
|
||||||
this.secretNew1 = secretNew1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the secretNew2
|
|
||||||
*/
|
|
||||||
public String getSecretNew2() {
|
|
||||||
return secretNew2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param secretNew2 the secretNew2 to set
|
|
||||||
*/
|
|
||||||
public void setSecretNew2(String secretNew2) {
|
|
||||||
this.secretNew2 = secretNew2;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
|
|
||||||
import static de.jottyfan.timetrack.db.profile.Tables.V_LOGINROLE;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.jooq.CloseableDSLContext;
|
|
||||||
import org.jooq.Record1;
|
|
||||||
import org.jooq.Record4;
|
|
||||||
import org.jooq.SelectConditionStep;
|
|
||||||
import org.jooq.UpdateConditionStep;
|
|
||||||
import org.jooq.exception.DataAccessException;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SessionGateway extends JooqGateway {
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
|
|
||||||
public SessionGateway(JooqFacesContext 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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws DataAccessException
|
|
||||||
*/
|
|
||||||
public boolean seekAndSetLogin(SessionBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectConditionStep<Record4<Integer, String, String, String>> sql = jooq
|
|
||||||
// @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));
|
|
||||||
|
|
||||||
SelectConditionStep<Record1<String>> sql2 = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.select(V_LOGINROLE.ROLE_NAME)
|
|
||||||
.from(V_LOGINROLE)
|
|
||||||
.where(V_LOGINROLE.LOGIN.eq(bean.getUsername()));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql2.toString());
|
|
||||||
for (Record1<String> privilege : sql2.fetch()) {
|
|
||||||
bean.getPrivileges().add(privilege.get(V_LOGINROLE.ROLE_NAME));
|
|
||||||
}
|
|
||||||
addToSessionMap("sessionBean", bean);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
throw new DataAccessException("wrong password");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* change the password
|
|
||||||
*
|
|
||||||
* @param bean
|
|
||||||
* the bean containing the new password
|
|
||||||
* @return true or false
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws DataAccessException
|
|
||||||
*/
|
|
||||||
public boolean changePassword(SessionBean bean, String newPassword)
|
|
||||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
bean.setSecret(newPassword);
|
|
||||||
String encryptedPassword = bean.getSecret();
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
UpdateConditionStep<TLoginRecord> sql = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.update(T_LOGIN)
|
|
||||||
.set(T_LOGIN.PASSWORD, encryptedPassword)
|
|
||||||
.where(T_LOGIN.PK.eq(bean.getLogin()));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug("updating password, disable log here");
|
|
||||||
return sql.execute() == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import javax.faces.application.FacesMessage;
|
|
||||||
|
|
||||||
import org.jooq.exception.DataAccessException;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SessionModel {
|
|
||||||
|
|
||||||
public boolean doLogin(JooqFacesContext facesContext, SessionBean bean) {
|
|
||||||
try {
|
|
||||||
return new SessionGateway(facesContext).seekAndSetLogin(bean);
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on login", e.getMessage());
|
|
||||||
facesContext.addMessage(null, msg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean doChangePassword(JooqFacesContext facesContext, String secretNew) {
|
|
||||||
try {
|
|
||||||
SessionBean bean = (SessionBean) facesContext.getExternalContext().getSessionMap().get("sessionBean");
|
|
||||||
return new SessionGateway(facesContext).changePassword(bean, secretNew);
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "error on changing password", e.getMessage());
|
|
||||||
facesContext.addMessage(null, msg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,181 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
public class TimetrackController {
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(TimetrackController.class);
|
|
||||||
|
|
||||||
private final HttpServletRequest request;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ITimetrackService fuelService;
|
|
||||||
|
|
||||||
private List<FuelBean> cachedFuels;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TimetrackController(HttpServletRequest request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/logout")
|
|
||||||
public String getLogout(HttpServletRequest request) throws ServletException {
|
|
||||||
request.logout();
|
|
||||||
return "redirect:/";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@GetMapping("/secure/welcome")
|
|
||||||
public String getWelcome() {
|
|
||||||
return "secure/welcome";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/")
|
|
||||||
public String getIndex() {
|
|
||||||
this.cachedFuels = null;
|
|
||||||
return "public/index";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@GetMapping("/secure/to_table")
|
|
||||||
public String getTable() {
|
|
||||||
this.cachedFuels = null;
|
|
||||||
return "secure/table";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@RequestMapping(value = "/secure/to_bean", method = RequestMethod.GET)
|
|
||||||
public String getBean(Model model) {
|
|
||||||
FuelBean bean = model.containsAttribute("fuelBean") ? (FuelBean) model.getAttribute("fuelBean") : new FuelBean();
|
|
||||||
model.addAttribute("fuelBean", bean);
|
|
||||||
return "secure/bean";
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@RequestMapping(value = "/secure/to_existing_bean/{fkFuelBean}", method = RequestMethod.GET)
|
|
||||||
public String getBean(Model model, @PathVariable Integer fkFuelBean) throws Exception {
|
|
||||||
FuelBean bean = getFuelBean(fkFuelBean);
|
|
||||||
model.addAttribute("fuelBean", bean);
|
|
||||||
return "secure/bean";
|
|
||||||
}
|
|
||||||
|
|
||||||
private FuelBean getFuelBean(Integer fkFuelBean) throws Exception {
|
|
||||||
for (FuelBean bean : getFuels()) {
|
|
||||||
if (bean.getPk().equals(fkFuelBean)) {
|
|
||||||
return bean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Exception("bean not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@RequestMapping(value = "/secure/do_upsert", method = RequestMethod.POST)
|
|
||||||
public String getUpsert(Model model, @ModelAttribute FuelBean fuelBean) {
|
|
||||||
Integer affected = fuelService.upsert(fuelBean);
|
|
||||||
model.addAttribute("fuelBean", fuelBean);
|
|
||||||
LOGGER.info("affected rows: {}", affected);
|
|
||||||
return affected > 0 ? getTable() : getBean(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RolesAllowed("car_user")
|
|
||||||
@GetMapping("/secure/jsonfuels")
|
|
||||||
@ResponseBody
|
|
||||||
public List<FuelBean> getJsonFuels() {
|
|
||||||
List<FuelBean> fuels = fuelService.findAll();
|
|
||||||
return fuels;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("fuels")
|
|
||||||
public List<FuelBean> getFuels() {
|
|
||||||
if (cachedFuels == null || cachedFuels.size() < 1) {
|
|
||||||
cachedFuels = fuelService.findAll();
|
|
||||||
}
|
|
||||||
return cachedFuels;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("currentUser")
|
|
||||||
@ResponseBody
|
|
||||||
public String getCurrentUser() {
|
|
||||||
return fuelService.getCurrentUser(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("averagelkm")
|
|
||||||
@ResponseBody
|
|
||||||
public BigDecimal getAverageLiterPerKm() {
|
|
||||||
List<FuelBean> fuels = getFuels();
|
|
||||||
Integer minMileage = 1000000; // my car won't even reach this milestone :)
|
|
||||||
Integer maxMileage = 0;
|
|
||||||
BigDecimal summedAmount = new BigDecimal(0);
|
|
||||||
for (FuelBean bean : fuels) {
|
|
||||||
summedAmount = summedAmount.add(bean.getAmount());
|
|
||||||
minMileage = bean.getMileage() < minMileage ? bean.getMileage() : minMileage;
|
|
||||||
maxMileage = bean.getMileage() > maxMileage ? bean.getMileage() : maxMileage;
|
|
||||||
}
|
|
||||||
BigDecimal totalMileage = new BigDecimal(maxMileage - minMileage);
|
|
||||||
BigDecimal calculated = totalMileage.intValue() != 0
|
|
||||||
? new BigDecimal((summedAmount.doubleValue() / totalMileage.doubleValue()) * 100d)
|
|
||||||
: new BigDecimal(0);
|
|
||||||
return calculated;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("averageel")
|
|
||||||
@ResponseBody
|
|
||||||
public BigDecimal getAverageEuroPerLiter() {
|
|
||||||
List<FuelBean> fuels = getFuels();
|
|
||||||
BigDecimal summedLiter = new BigDecimal(0);
|
|
||||||
BigDecimal summedEuro = new BigDecimal(0);
|
|
||||||
for (FuelBean bean : fuels) {
|
|
||||||
summedLiter = summedLiter.add(bean.getAmount());
|
|
||||||
summedEuro = summedEuro.add(bean.getPrice());
|
|
||||||
}
|
|
||||||
BigDecimal calculated = summedLiter.intValue() != 0
|
|
||||||
? new BigDecimal(summedEuro.doubleValue() / summedLiter.doubleValue())
|
|
||||||
: new BigDecimal(0);
|
|
||||||
return calculated;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("chartjsdata")
|
|
||||||
@ResponseBody
|
|
||||||
public List<BigDecimal> getChartjsData() {
|
|
||||||
List<FuelBean> fuels = getFuels();
|
|
||||||
List<BigDecimal> list = new ArrayList<>();
|
|
||||||
for (FuelBean bean : fuels) {
|
|
||||||
list.add(bean.getEuro_per_l());
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("chartjslabel")
|
|
||||||
@ResponseBody
|
|
||||||
public List<Integer> getChartjsLabel() {
|
|
||||||
List<FuelBean> fuels = getFuels();
|
|
||||||
List<Integer> list = new ArrayList<>();
|
|
||||||
for (FuelBean bean : fuels) {
|
|
||||||
list.add(bean.getMileage());
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
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;
|
|
||||||
private final String billingShortcut;
|
|
||||||
private final String billingCsskey;
|
|
||||||
private final Double durationHours;
|
|
||||||
|
|
||||||
public DailySummaryBean(String projectName, String moduleName, String jobName, String duration, String billingShortcut, String billingCsskey, Double durationHours) {
|
|
||||||
super();
|
|
||||||
this.projectName = projectName;
|
|
||||||
this.moduleName = moduleName;
|
|
||||||
this.jobName = jobName;
|
|
||||||
this.duration = duration;
|
|
||||||
this.billingShortcut = billingShortcut;
|
|
||||||
this.billingCsskey = billingCsskey;
|
|
||||||
this.durationHours = durationHours;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProjectName() {
|
|
||||||
return projectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getModuleName() {
|
|
||||||
return moduleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getJobName() {
|
|
||||||
return jobName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDuration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the billing shortcut
|
|
||||||
*/
|
|
||||||
public String getBillingShortcut() {
|
|
||||||
return billingShortcut;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the billing csskey
|
|
||||||
*/
|
|
||||||
public String getBillingCsskey() {
|
|
||||||
return billingCsskey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the durationHours
|
|
||||||
*/
|
|
||||||
public Double getDurationHours() {
|
|
||||||
return durationHours;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
|
||||||
import javax.faces.context.FacesContext;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
import de.jottyfan.timetrack.help.Navigation;
|
|
||||||
import de.jottyfan.timetrack.help.Pages;
|
|
||||||
import de.jottyfan.timetrack.modules.ControlInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@RequestScoped
|
|
||||||
public class DoneControl extends Navigation implements ControlInterface, Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
@Named("doneModel")
|
|
||||||
private DoneModel model;
|
|
||||||
|
|
||||||
public String toStart() {
|
|
||||||
return navigateTo(Pages.START);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toList() {
|
|
||||||
boolean ready = model.init((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? navigateTo(Pages.DONE_INIT) : toStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toAdd() {
|
|
||||||
DoneBean bean = new DoneBean();
|
|
||||||
bean.setTimeFrom(LocalDateTime.now());
|
|
||||||
model.setBean(bean);
|
|
||||||
boolean ready = model.loadDefaults((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? navigateTo(Pages.DONE_ADD) : toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toEdit(DoneBean bean) {
|
|
||||||
model.setBean(bean);
|
|
||||||
boolean ready = model.loadDefaults((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? navigateTo(Pages.DONE_EDIT) : toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toDelete(DoneBean bean) {
|
|
||||||
model.setBean(bean);
|
|
||||||
return navigateTo(Pages.DONE_DELETE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toRead() {
|
|
||||||
boolean ready = model.prepareRead((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? navigateTo(Pages.DONE_READ) : toStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doUpdate() {
|
|
||||||
boolean ready = model.update((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? toList() : toEdit(model.getBean());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doDelete() {
|
|
||||||
boolean ready = model.delete((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? toList() : toDelete(model.getBean());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doAdd() {
|
|
||||||
boolean ready = model.insert((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? toList() : toAdd();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String doDownload() {
|
|
||||||
boolean ready = model.download((JooqFacesContext) FacesContext.getCurrentInstance());
|
|
||||||
return ready ? "" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurrentTimeAsString() {
|
|
||||||
DateTimeFormatter hhmmss = DateTimeFormatter.ofPattern("HH:mm:ss");
|
|
||||||
return LocalDateTime.now().format(hhmmss);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,495 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.T_BILLING;
|
|
||||||
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_HAMSTERSUMMARY;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_TOTALOFDAY;
|
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_WORKTIME;
|
|
||||||
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.jooq.CloseableDSLContext;
|
|
||||||
import org.jooq.DeleteConditionStep;
|
|
||||||
import org.jooq.InsertValuesStep7;
|
|
||||||
import org.jooq.Record;
|
|
||||||
import org.jooq.Record3;
|
|
||||||
import org.jooq.Record4;
|
|
||||||
import org.jooq.Record5;
|
|
||||||
import org.jooq.Record7;
|
|
||||||
import org.jooq.SelectConditionStep;
|
|
||||||
import org.jooq.SelectJoinStep;
|
|
||||||
import org.jooq.SelectWhereStep;
|
|
||||||
import org.jooq.UpdateConditionStep;
|
|
||||||
import org.jooq.exception.DataAccessException;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.TBillingRecord;
|
|
||||||
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;
|
|
||||||
import de.jottyfan.timetrack.modules.done.fullcalendar.ColorfulFCEventBean;
|
|
||||||
import de.jottyfan.timetrack.modules.done.fullcalendar.FCEventList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DoneGateway extends JooqGateway {
|
|
||||||
private final static Logger LOGGER = LogManager.getLogger(DoneGateway.class);
|
|
||||||
private final Integer requested;
|
|
||||||
|
|
||||||
public DoneGateway(JooqFacesContext facesContext) {
|
|
||||||
super(facesContext);
|
|
||||||
String dailyMinutes = facesContext.getExternalContext().getInitParameter("requestedDailyMinutes");
|
|
||||||
this.requested = dailyMinutes == null ? 480 : Integer.valueOf(dailyMinutes); // defaults to 8 hours/day
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get all modules from db
|
|
||||||
*
|
|
||||||
* @return modules
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public List<TModuleRecord> getAllModules() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
List<TModuleRecord> list = new ArrayList<>();
|
|
||||||
SelectWhereStep<TModuleRecord> sql = jooq.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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public List<TJobRecord> getAllActivities() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
List<TJobRecord> list = new ArrayList<>();
|
|
||||||
SelectWhereStep<TJobRecord> sql = jooq.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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public List<TProjectRecord> getAllProjects() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
List<TProjectRecord> list = new ArrayList<>();
|
|
||||||
SelectWhereStep<TProjectRecord> sql = jooq.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get all billings from db
|
|
||||||
*
|
|
||||||
* @return billings
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public List<TBillingRecord> getAllBillings() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
List<TBillingRecord> list = new ArrayList<>();
|
|
||||||
SelectWhereStep<TBillingRecord> sql = jooq.selectFrom(T_BILLING);
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
for (TBillingRecord 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Integer, TBillingRecord> generateBillingMap(List<TBillingRecord> list) {
|
|
||||||
Map<Integer, TBillingRecord> map = new HashMap<>();
|
|
||||||
for (TBillingRecord 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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public List<DoneBean> getAll(LocalDateTime day) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
Map<Integer, TProjectRecord> projectMap = generateProjectMap(getAllProjects());
|
|
||||||
Map<Integer, TModuleRecord> moduleMap = generateModuleMap(getAllModules());
|
|
||||||
Map<Integer, TJobRecord> jobMap = generateJobMap(getAllActivities());
|
|
||||||
Map<Integer, TBillingRecord> billingMap = generateBillingMap(getAllBillings());
|
|
||||||
|
|
||||||
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<>();
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
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(yesterday)
|
|
||||||
.and(T_DONE.TIME_FROM.lessThan(tomorrow))))
|
|
||||||
.and(T_DONE.TIME_UNTIL.isNull()
|
|
||||||
.or(T_DONE.TIME_UNTIL.lessThan(tomorrow)
|
|
||||||
.and(T_DONE.TIME_UNTIL.greaterThan(yesterday))));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
for (TDoneRecord r : sql.fetch()) {
|
|
||||||
list.add(new DoneBean(r, projectMap, moduleMap, jobMap, billingMap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list.sort((o1, o2) -> o1 == null || o2 == null ? 0 : o1.compareTo(o2));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* insert data into t_done
|
|
||||||
*
|
|
||||||
* @param bean
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public void insert(DoneBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
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 fkBilling = bean.getBilling() == null ? null : bean.getBilling().getPk();
|
|
||||||
Integer fkLogin = getFkLogin();
|
|
||||||
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
InsertValuesStep7<TDoneRecord, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer, Integer> sql = jooq
|
|
||||||
// @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_BILLING,
|
|
||||||
T_DONE.FK_LOGIN)
|
|
||||||
.values(bean.getTimeFrom(), bean.getTimeUntil(), fkProject, fkModule, fkJob, fkBilling, fkLogin);
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
sql.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* update bean in t_done
|
|
||||||
*
|
|
||||||
* @param bean
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public void update(DoneBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
UpdateConditionStep<TDoneRecord> sql = jooq
|
|
||||||
// @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())
|
|
||||||
.set(T_DONE.FK_BILLING, bean.getBilling() == null ? null : bean.getBilling().getPk())
|
|
||||||
.where(T_DONE.PK.eq(bean.getPk()));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
sql.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* delete bean from t_done
|
|
||||||
*
|
|
||||||
* @param bean
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
public void delete(DoneBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
DeleteConditionStep<TDoneRecord> sql = jooq.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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws DataAccessException
|
|
||||||
*/
|
|
||||||
public WholeDaySummaryBean getDaySummary(java.util.Date day)
|
|
||||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectConditionStep<Record4<String, String, String, String>> sql = jooq
|
|
||||||
// @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, requested);
|
|
||||||
}
|
|
||||||
return new WholeDaySummaryBean("", "", "", "", requested);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get all jobs of day
|
|
||||||
*
|
|
||||||
* @param day the day
|
|
||||||
* @return list of found jobs; an empty list at least
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws DataAccessException
|
|
||||||
*/
|
|
||||||
public List<DailySummaryBean> getAllJobs(java.util.Date day)
|
|
||||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectConditionStep<Record7<String, Double, String, String, String, String, String>> sql = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.select(V_WORKTIME.DURATION,
|
|
||||||
V_WORKTIME.DURATION_HOURS,
|
|
||||||
V_WORKTIME.PROJECT_NAME,
|
|
||||||
V_WORKTIME.MODULE_NAME,
|
|
||||||
V_WORKTIME.JOB_NAME,
|
|
||||||
V_WORKTIME.BILLING_SHORTCUT,
|
|
||||||
V_WORKTIME.BILLING_CSSKEY)
|
|
||||||
.from(V_WORKTIME)
|
|
||||||
.where(V_WORKTIME.DAY.eq(new SimpleDateFormat("yyyy-MM-dd").format(day)))
|
|
||||||
.and(V_WORKTIME.FK_LOGIN.eq(getFkLogin()));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
List<DailySummaryBean> list = new ArrayList<>();
|
|
||||||
for (Record7<String, Double, String, String, String, String, String> r : sql.fetch()) {
|
|
||||||
String duration = r.get(V_WORKTIME.DURATION);
|
|
||||||
Double durationHours = r.get(V_WORKTIME.DURATION_HOURS);
|
|
||||||
String projectName = r.get(V_WORKTIME.PROJECT_NAME);
|
|
||||||
String moduleName = r.get(V_WORKTIME.MODULE_NAME);
|
|
||||||
String jobName = r.get(V_WORKTIME.JOB_NAME);
|
|
||||||
String billingShortcut = r.get(V_WORKTIME.BILLING_SHORTCUT);
|
|
||||||
String billingCsskey = r.get(V_WORKTIME.BILLING_CSSKEY);
|
|
||||||
durationHours = durationHours == null ? null
|
|
||||||
: new BigDecimal(durationHours).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
|
||||||
list.add(new DailySummaryBean(projectName, moduleName, jobName, duration, billingShortcut, billingCsskey,
|
|
||||||
durationHours));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get json representation of all calendar events of user
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws DataAccessException
|
|
||||||
*/
|
|
||||||
public String getAllCalendarEvents() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectConditionStep<Record7<LocalDateTime, LocalDateTime, String, String, String, String, String>> sql = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.select(T_DONE.TIME_FROM,
|
|
||||||
T_DONE.TIME_UNTIL,
|
|
||||||
T_PROJECT.NAME,
|
|
||||||
T_MODULE.NAME,
|
|
||||||
T_JOB.NAME,
|
|
||||||
T_BILLING.CSSKEY,
|
|
||||||
T_BILLING.SHORTCUT)
|
|
||||||
.from(T_DONE)
|
|
||||||
.leftJoin(T_PROJECT).on(T_PROJECT.PK.eq(T_DONE.FK_PROJECT))
|
|
||||||
.leftJoin(T_MODULE).on(T_MODULE.PK.eq(T_DONE.FK_MODULE))
|
|
||||||
.leftJoin(T_JOB).on(T_JOB.PK.eq(T_DONE.FK_JOB))
|
|
||||||
.leftJoin(T_BILLING).on(T_BILLING.PK.eq(T_DONE.FK_BILLING))
|
|
||||||
.where(T_DONE.FK_LOGIN.eq(getFkLogin()));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
FCEventList list = new FCEventList();
|
|
||||||
for (Record r : sql.fetch()) {
|
|
||||||
String projectName = r.get(T_PROJECT.NAME);
|
|
||||||
String moduleName = r.get(T_MODULE.NAME);
|
|
||||||
String jobName = r.get(T_JOB.NAME);
|
|
||||||
LocalDateTime timeFrom = r.get(T_DONE.TIME_FROM);
|
|
||||||
LocalDateTime timeUntil = r.get(T_DONE.TIME_UNTIL);
|
|
||||||
String cssKey = r.get(T_BILLING.CSSKEY);
|
|
||||||
String shortcut = r.get(T_BILLING.SHORTCUT);
|
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
buf.append(projectName);
|
|
||||||
buf.append(", ");
|
|
||||||
buf.append(moduleName);
|
|
||||||
buf.append(": ");
|
|
||||||
buf.append(jobName);
|
|
||||||
|
|
||||||
Date theDate = Date.from(timeFrom.atZone(ZoneId.systemDefault()).toInstant());
|
|
||||||
|
|
||||||
ColorfulFCEventBean bean = new ColorfulFCEventBean(buf.toString(),
|
|
||||||
theDate, new RgbColor().determineTextcolorFromCssKey(cssKey));
|
|
||||||
bean.setProject(projectName);
|
|
||||||
bean.setModule(moduleName);
|
|
||||||
bean.setJob(jobName);
|
|
||||||
bean.setBilling(shortcut);
|
|
||||||
Date endDate = timeUntil == null ? null : Date.from(timeUntil.atZone(ZoneId.systemDefault()).toInstant());
|
|
||||||
bean.setEnd(endDate);
|
|
||||||
if (cssKey != null && !cssKey.isBlank()) {
|
|
||||||
bean.setColor(new RgbColor().determineColorFromCssKey(cssKey));
|
|
||||||
} else {
|
|
||||||
bean.setColor(new RgbColor().determineRgbColor(projectName, moduleName, jobName));
|
|
||||||
}
|
|
||||||
list.getList().add(bean);
|
|
||||||
}
|
|
||||||
return list.toJson();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UserBean> getAllUsers() throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
List<UserBean> list = new ArrayList<>();
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectJoinStep<Record3<String, String, String>> sql = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.select(T_LOGIN.LOGIN,
|
|
||||||
T_LOGIN.FORENAME,
|
|
||||||
T_LOGIN.SURNAME)
|
|
||||||
.from(T_LOGIN);
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
for (Record r : sql.fetch()) {
|
|
||||||
String username = r.get(T_LOGIN.LOGIN);
|
|
||||||
String forename = r.get(T_LOGIN.FORENAME);
|
|
||||||
String surname = r.get(T_LOGIN.SURNAME);
|
|
||||||
list.add(new UserBean(username, forename, surname));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String download(DownloadBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
try (CloseableDSLContext jooq = getJooq()) {
|
|
||||||
SelectConditionStep<Record5<LocalDate, String, String, String, String>> sql = jooq
|
|
||||||
// @formatter:off
|
|
||||||
.select(V_HAMSTERSUMMARY.WORKDAY,
|
|
||||||
V_HAMSTERSUMMARY.DURATION,
|
|
||||||
V_HAMSTERSUMMARY.PROJECT_NAME,
|
|
||||||
V_HAMSTERSUMMARY.MODULE_NAME,
|
|
||||||
V_HAMSTERSUMMARY.JOB_NAME)
|
|
||||||
.from(V_HAMSTERSUMMARY)
|
|
||||||
.where(V_HAMSTERSUMMARY.LOGIN.eq(bean.getUsername()))
|
|
||||||
.and(V_HAMSTERSUMMARY.WORKDAY.le(bean.getUntilDate())
|
|
||||||
.and(V_HAMSTERSUMMARY.WORKDAY.ge(bean.getFromDate())));
|
|
||||||
// @formatter:on
|
|
||||||
LOGGER.debug(sql.toString());
|
|
||||||
String sep = ";";
|
|
||||||
buf.append("day").append(sep).append("duration").append(sep).append("project").append(sep).append("module")
|
|
||||||
.append(sep).append("activity\n");
|
|
||||||
for (Record r : sql.fetch()) {
|
|
||||||
LocalDate workday = r.get(V_HAMSTERSUMMARY.WORKDAY);
|
|
||||||
String date = workday.format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
|
||||||
buf.append(date).append(sep);
|
|
||||||
buf.append(r.get(V_HAMSTERSUMMARY.DURATION)).append(sep);
|
|
||||||
buf.append(r.get(V_HAMSTERSUMMARY.PROJECT_NAME)).append(sep);
|
|
||||||
buf.append(r.get(V_HAMSTERSUMMARY.MODULE_NAME)).append(sep);
|
|
||||||
buf.append(r.get(V_HAMSTERSUMMARY.JOB_NAME)).append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,345 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
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.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import javax.enterprise.context.SessionScoped;
|
|
||||||
import javax.faces.application.FacesMessage;
|
|
||||||
import javax.inject.Named;
|
|
||||||
|
|
||||||
import org.jooq.exception.DataAccessException;
|
|
||||||
|
|
||||||
import de.jooqfaces.JooqFacesContext;
|
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.TBillingRecord;
|
|
||||||
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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Named
|
|
||||||
@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<TBillingRecord> billings;
|
|
||||||
private List<TimeBean> times;
|
|
||||||
private List<DailySummaryBean> allJobs;
|
|
||||||
private WholeDaySummaryBean daySummary;
|
|
||||||
private java.util.Date day;
|
|
||||||
private String calendarEvents;
|
|
||||||
private List<UserBean> users;
|
|
||||||
private DownloadBean downloadBean;
|
|
||||||
|
|
||||||
public boolean init(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
day = day == null ? new java.util.Date() : day;
|
|
||||||
beans = getAllOfDay(facesContext, day);
|
|
||||||
DoneGateway gw = new DoneGateway(facesContext);
|
|
||||||
modules = gw.getAllModules();
|
|
||||||
activities = gw.getAllActivities();
|
|
||||||
projects = gw.getAllProjects();
|
|
||||||
billings = gw.getAllBillings();
|
|
||||||
daySummary = gw.getDaySummary(day);
|
|
||||||
allJobs = gw.getAllJobs(day);
|
|
||||||
calendarEvents = gw.getAllCalendarEvents();
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean loadDefaults(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
defineTimes();
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException e) {
|
|
||||||
facesContext.addMessage(null,
|
|
||||||
new FacesMessage(FacesMessage.SEVERITY_ERROR, "error loading defaults", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean prepareRead(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
users = new DoneGateway(facesContext).getAllUsers();
|
|
||||||
downloadBean = new DownloadBean();
|
|
||||||
downloadBean.setFromDate(LocalDate.of(LocalDate.now().getYear(), 1, 1));
|
|
||||||
downloadBean.setUntilDate(LocalDate.now());
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException 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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* summarizes the billings in horizon2020 notation
|
|
||||||
*
|
|
||||||
* @return the billings summary
|
|
||||||
*/
|
|
||||||
public String getSummaryBilling() {
|
|
||||||
Map<String, Double> map = new HashMap<>();
|
|
||||||
for (DailySummaryBean bean : getAllJobs()) {
|
|
||||||
String shortcut = bean.getBillingShortcut();
|
|
||||||
Double time = bean.getDurationHours();
|
|
||||||
Double sumTime = map.get(shortcut);
|
|
||||||
sumTime = sumTime == null ? time : (sumTime + time);
|
|
||||||
map.put(shortcut, sumTime);
|
|
||||||
}
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
boolean first = true;
|
|
||||||
for (Entry<String, Double> entry : map.entrySet()) {
|
|
||||||
buf.append(first ? "" : ", ");
|
|
||||||
String key = entry.getKey();
|
|
||||||
if (key == null || key.equals("null")) {
|
|
||||||
buf.append("$ ");
|
|
||||||
} else {
|
|
||||||
buf.append(entry.getKey()).append(" ");
|
|
||||||
}
|
|
||||||
buf.append("(").append(entry.getValue()).append(")");
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* summarizes the time of a days work in commaseparated values
|
|
||||||
*
|
|
||||||
* @return the summarized times
|
|
||||||
*/
|
|
||||||
public String getSummaryTime() {
|
|
||||||
Double sum = 0d;
|
|
||||||
for (DailySummaryBean bean : getAllJobs()) {
|
|
||||||
sum += bean.getDurationHours();
|
|
||||||
}
|
|
||||||
return sum.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
* @throws SQLException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
*/
|
|
||||||
private List<DoneBean> getAllOfDay(JooqFacesContext facesContext, Date day)
|
|
||||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
|
||||||
LocalDateTime ldt = day.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
||||||
return new DoneGateway(facesContext).getAll(ldt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean insert(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
bean.setDay(day);
|
|
||||||
new DoneGateway(facesContext).insert(bean);
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean update(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
// day contains the correct date; with that, refresh the current date after possibly changing the day
|
|
||||||
bean.setDay(day);
|
|
||||||
new DoneGateway(facesContext).update(bean);
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean delete(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
new DoneGateway(facesContext).delete(bean);
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException e) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean download(JooqFacesContext facesContext) {
|
|
||||||
try {
|
|
||||||
String csvContent = new DoneGateway(facesContext).download(downloadBean);
|
|
||||||
facesContext.getExternalContext().responseReset();
|
|
||||||
facesContext.getExternalContext().setResponseContentType("text/csv");
|
|
||||||
facesContext.getExternalContext().setResponseHeader("Content-Disposition", "attachment; filename=\"worktime.csv\"");
|
|
||||||
facesContext.getExternalContext().getResponseOutputWriter().append(csvContent);
|
|
||||||
facesContext.responseComplete();
|
|
||||||
return true;
|
|
||||||
} catch (DataAccessException | ClassNotFoundException | SQLException | IOException e) {
|
|
||||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAttach() {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
String thatday = new SimpleDateFormat("dd.MM.yyyy").format(day);
|
|
||||||
for (DailySummaryBean sdb : allJobs) {
|
|
||||||
buf.append(thatday).append("\t");
|
|
||||||
buf.append(sdb.getDuration()).append("\t");
|
|
||||||
buf.append(sdb.getProjectName());
|
|
||||||
if (sdb.getBillingShortcut() != null && !sdb.getBillingShortcut().isBlank()) {
|
|
||||||
buf.append(" (").append(sdb.getBillingShortcut()).append(")");
|
|
||||||
}
|
|
||||||
buf.append("\t");
|
|
||||||
buf.append(sdb.getModuleName()).append("\t");
|
|
||||||
buf.append(sdb.getJobName()).append("\t");
|
|
||||||
buf.append("\n");
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDayIso8601() {
|
|
||||||
return day == null ? "" : new SimpleDateFormat("yyyy-MM-dd").format(day);
|
|
||||||
}
|
|
||||||
|
|
||||||
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<TBillingRecord> getBillings() {
|
|
||||||
return billings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DailySummaryBean> getAllJobs() {
|
|
||||||
return allJobs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WholeDaySummaryBean getDaySummary() {
|
|
||||||
return daySummary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DoneBean> getBeans() {
|
|
||||||
return beans;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TimeBean> getTimes() {
|
|
||||||
return times;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGermanFormattedDay() {
|
|
||||||
return day == null ? "null" : new SimpleDateFormat("EEEE, dd.MMMM yyyy").format(day);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDay() {
|
|
||||||
return day;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDay(Date day) {
|
|
||||||
this.day = day;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCalendarEvents() {
|
|
||||||
return calendarEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the users
|
|
||||||
*/
|
|
||||||
public List<UserBean> getUsers() {
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the downloadBean
|
|
||||||
*/
|
|
||||||
public DownloadBean getDownloadBean() {
|
|
||||||
return downloadBean;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author jotty
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DownloadBean implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private LocalDate fromDate;
|
|
||||||
private LocalDate untilDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the fromDate
|
|
||||||
*/
|
|
||||||
public LocalDate getFromDate() {
|
|
||||||
return fromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param fromDate
|
|
||||||
* the fromDate to set
|
|
||||||
*/
|
|
||||||
public void setFromDate(LocalDate fromDate) {
|
|
||||||
this.fromDate = fromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the untilDate
|
|
||||||
*/
|
|
||||||
public LocalDate getUntilDate() {
|
|
||||||
return untilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param untilDate
|
|
||||||
* the untilDate to set
|
|
||||||
*/
|
|
||||||
public void setUntilDate(LocalDate untilDate) {
|
|
||||||
this.untilDate = untilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the username
|
|
||||||
*/
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param username the username to set
|
|
||||||
*/
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class RgbColor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* find a rgb color code for the combination of the given params
|
|
||||||
*
|
|
||||||
* @param bigInfluence
|
|
||||||
* @param mediumInfluence
|
|
||||||
* @param littleInfluence
|
|
||||||
* @return the hex color code
|
|
||||||
*/
|
|
||||||
public String determineRgbColor(String bigInfluence, String mediumInfluence, String littleInfluence) {
|
|
||||||
int big = bigInfluence == null ? 0 : bigInfluence.hashCode();
|
|
||||||
int med = mediumInfluence == null ? 0 : mediumInfluence.hashCode();
|
|
||||||
int lit = littleInfluence == null ? 0 : littleInfluence.hashCode();
|
|
||||||
|
|
||||||
float bI = (1f / String.valueOf(big).length());
|
|
||||||
float mI = (0.5f / String.valueOf(med).length());
|
|
||||||
float lI = (0.25f / String.valueOf(lit).length());
|
|
||||||
|
|
||||||
float r = 0.0f + bI + mI + lI; // + makes it brighter
|
|
||||||
float g = 0.5f - bI - mI - lI; // - makes it darker
|
|
||||||
float b = 0.5f - bI - mI - lI;
|
|
||||||
|
|
||||||
r = r < 0 ? r * -1 : r;
|
|
||||||
r = r > 1.0f ? 1 / r : r;
|
|
||||||
g = g < 0 ? g * -1 : g;
|
|
||||||
g = g > 1.0f ? 1 / g : g;
|
|
||||||
b = b < 0 ? b * -1 : b;
|
|
||||||
b = b > 1.0f ? 1 / b : b;
|
|
||||||
|
|
||||||
Color c = new Color(r, g, b);
|
|
||||||
return new StringBuilder("rgb(").append(c.getRed()).append(",").append(c.getGreen()).append(",").append(c.getBlue())
|
|
||||||
.append(")").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* find the corresponding rgb color for the css key
|
|
||||||
* @param cssKey the key
|
|
||||||
* @return the hex color code
|
|
||||||
*/
|
|
||||||
public String determineColorFromCssKey(String cssKey) {
|
|
||||||
// for now, only map the css key to a defined list
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("TA3", "rgb(0, 255, 0)");
|
|
||||||
map.put("WP2", "rgb(192, 192, 0)");
|
|
||||||
map.put("WP4", "rgb(32, 192, 255)");
|
|
||||||
map.put("WP5", "rgb(255, 0, 0)");
|
|
||||||
return map.get(cssKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String determineTextcolorFromCssKey(String cssKey) {
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("TA3", "rgb(0, 0, 0)");
|
|
||||||
map.put("WP2", "rgb(0, 0, 0)");
|
|
||||||
map.put("WP4", "rgb(0, 0, 0)");
|
|
||||||
map.put("WP5", "rgb(0, 0, 0)");
|
|
||||||
String value = map.get(cssKey);
|
|
||||||
return value == null ? "rgb(255, 255, 255)" : value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author jotty
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class UserBean implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final String username;
|
|
||||||
private final String forename;
|
|
||||||
private final String surname;
|
|
||||||
|
|
||||||
public UserBean(String username, String forename, String surname) {
|
|
||||||
super();
|
|
||||||
this.username = username;
|
|
||||||
this.forename = forename;
|
|
||||||
this.surname = surname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the forename
|
|
||||||
*/
|
|
||||||
public String getForename() {
|
|
||||||
return forename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the surname
|
|
||||||
*/
|
|
||||||
public String getSurname() {
|
|
||||||
return surname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the username
|
|
||||||
*/
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
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;
|
|
||||||
private final Integer dayrequests;
|
|
||||||
|
|
||||||
public WholeDaySummaryBean(String startTime, String endTime, String workTime, String breakTime, Integer dayrequests) {
|
|
||||||
super();
|
|
||||||
this.startTime = startTime;
|
|
||||||
this.endTime = endTime;
|
|
||||||
this.workTime = workTime;
|
|
||||||
this.breakTime = breakTime;
|
|
||||||
this.dayrequests = dayrequests == null ? 468 : dayrequests; // 7:48 by default
|
|
||||||
}
|
|
||||||
|
|
||||||
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 - dayrequests;
|
|
||||||
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 "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Integer requestHours = dayrequests / 60;
|
|
||||||
Integer requestMinutes = dayrequests % 60;
|
|
||||||
StringBuilder buf = new StringBuilder("-");
|
|
||||||
buf.append(requestHours < 10 ? "0" : "").append(requestHours);
|
|
||||||
buf.append(":");
|
|
||||||
buf.append(requestMinutes < 10 ? "0" : "").append(requestMinutes);
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStartTime() {
|
|
||||||
return startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWorkTime() {
|
|
||||||
return workTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBreakTime() {
|
|
||||||
return breakTime;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done.fullcalendar;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ColorfulFCEventBean extends FCEventBean {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private final String textColor;
|
|
||||||
private String billing;
|
|
||||||
private String project;
|
|
||||||
private String module;
|
|
||||||
private String job;
|
|
||||||
|
|
||||||
public ColorfulFCEventBean(String title, Date start, String textColor) {
|
|
||||||
super(title, start);
|
|
||||||
this.textColor = textColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getExtendedFields() {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
addParam(buf, "textColor", textColor);
|
|
||||||
addParam(buf, "billing", billing);
|
|
||||||
addParam(buf, "project", project);
|
|
||||||
addParam(buf, "module", module);
|
|
||||||
addParam(buf, "job", job);
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the billing
|
|
||||||
*/
|
|
||||||
public String getBilling() {
|
|
||||||
return billing;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param billing the billing to set
|
|
||||||
*/
|
|
||||||
public void setBilling(String billing) {
|
|
||||||
this.billing = billing;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the project
|
|
||||||
*/
|
|
||||||
public String getProject() {
|
|
||||||
return project;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param project the project to set
|
|
||||||
*/
|
|
||||||
public void setProject(String project) {
|
|
||||||
this.project = project;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the module
|
|
||||||
*/
|
|
||||||
public String getModule() {
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param module the module to set
|
|
||||||
*/
|
|
||||||
public void setModule(String module) {
|
|
||||||
this.module = module;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the job
|
|
||||||
*/
|
|
||||||
public String getJob() {
|
|
||||||
return job;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param job the job to set
|
|
||||||
*/
|
|
||||||
public void setJob(String job) {
|
|
||||||
this.job = job;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,198 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done.fullcalendar;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class FCEventBean implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String title;
|
|
||||||
private Boolean allDay;
|
|
||||||
private Date start;
|
|
||||||
private Date end;
|
|
||||||
private Boolean editable;
|
|
||||||
private Boolean startEditable;
|
|
||||||
private Boolean durationEditable;
|
|
||||||
private String color;
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
public FCEventBean(String title, Date start) {
|
|
||||||
super();
|
|
||||||
this.title = title;
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String toJavascriptDate(Date date){
|
|
||||||
if (date == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
StringBuilder buf = new StringBuilder("new Date(");
|
|
||||||
Calendar cal = new GregorianCalendar();
|
|
||||||
cal.setTime(date);
|
|
||||||
buf.append(cal.get(Calendar.YEAR)).append(",");
|
|
||||||
buf.append(cal.get(Calendar.MONTH)).append(",");
|
|
||||||
buf.append(cal.get(Calendar.DAY_OF_MONTH)).append(",");
|
|
||||||
buf.append(cal.get(Calendar.HOUR_OF_DAY)).append(",");
|
|
||||||
buf.append(cal.get(Calendar.MINUTE)).append(",");
|
|
||||||
buf.append(cal.get(Calendar.SECOND));
|
|
||||||
buf.append(")");
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get extended fields to json string
|
|
||||||
*/
|
|
||||||
public abstract String getExtendedFields();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* adds a param to buf if value is not null
|
|
||||||
*
|
|
||||||
* @param buf the buffer
|
|
||||||
* @param name the name
|
|
||||||
* @param value the value
|
|
||||||
* @param encapsulate if true, encapsulate value by '
|
|
||||||
* @param appendComma if true, append a comma
|
|
||||||
*/
|
|
||||||
public void addParam(StringBuilder buf, String name, String value, boolean encapsulate, boolean appendComma) {
|
|
||||||
if (value != null) {
|
|
||||||
buf.append(name).append(":");
|
|
||||||
buf.append(encapsulate ? "'" : "").append(value).append(encapsulate ? "'" : "");
|
|
||||||
buf.append(appendComma ? "," : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* adds a param to buf if value is not null and append a comma
|
|
||||||
*
|
|
||||||
* @param buf the buffer
|
|
||||||
* @param name the name
|
|
||||||
* @param value the value
|
|
||||||
* @param encapsulate if true, encapsulate value by '
|
|
||||||
*/
|
|
||||||
public void addParam(StringBuilder buf, String name, String value, boolean encapsulate) {
|
|
||||||
addParam(buf, name, value, encapsulate, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* adds a param to buf if value is not null and encapsulate it with ' and add a comma
|
|
||||||
*
|
|
||||||
* @param buf the buffer
|
|
||||||
* @param name the name
|
|
||||||
* @param value the value
|
|
||||||
*/
|
|
||||||
public void addParam(StringBuilder buf, String name, String value) {
|
|
||||||
addParam(buf, name, value, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* adds a param to buf if value is not null and do not encapsulate it with ' but add a comma
|
|
||||||
*
|
|
||||||
* @param buf the buffer
|
|
||||||
* @param name the name
|
|
||||||
* @param value the value
|
|
||||||
*/
|
|
||||||
public void addParam(StringBuilder buf, String name, Boolean value) {
|
|
||||||
addParam(buf, name, value == null ? null : value.toString(), false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toJson() {
|
|
||||||
StringBuilder buf = new StringBuilder("{");
|
|
||||||
addParam(buf, "title", title);
|
|
||||||
addParam(buf, "allDay", allDay);
|
|
||||||
addParam(buf, "editable", editable);
|
|
||||||
addParam(buf, "startEditable", startEditable);
|
|
||||||
addParam(buf, "durationEditable", durationEditable);
|
|
||||||
addParam(buf, "color", color);
|
|
||||||
addParam(buf, "end", toJavascriptDate(end), false);
|
|
||||||
addParam(buf, "url", url);
|
|
||||||
|
|
||||||
buf.append(getExtendedFields());
|
|
||||||
// this is the last element, we need no trailing ,
|
|
||||||
addParam(buf, "start", toJavascriptDate(start), false, false);
|
|
||||||
buf.append("}");
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getAllDay() {
|
|
||||||
return allDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllDay(Boolean allDay) {
|
|
||||||
this.allDay = allDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStart(Date start) {
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getEnd() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnd(Date end) {
|
|
||||||
this.end = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getEditable() {
|
|
||||||
return editable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEditable(Boolean editable) {
|
|
||||||
this.editable = editable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getDurationEditable() {
|
|
||||||
return durationEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDurationEditable(Boolean durationEditable) {
|
|
||||||
this.durationEditable = durationEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(String color) {
|
|
||||||
this.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getSerialversionuid() {
|
|
||||||
return serialVersionUID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getStartEditable() {
|
|
||||||
return startEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartEditable(Boolean startEditable) {
|
|
||||||
this.startEditable = startEditable;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package de.jottyfan.timetrack.modules.done.fullcalendar;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author henkej
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class FCEventList implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private List<FCEventBean> list;
|
|
||||||
|
|
||||||
public FCEventList() {
|
|
||||||
super();
|
|
||||||
this.list = new ArrayList<FCEventBean>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toJson() {
|
|
||||||
StringBuilder buf = new StringBuilder("[");
|
|
||||||
Iterator<FCEventBean> iterator = list.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
buf.append(iterator.next().toJson());
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
buf.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf.append("]");
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FCEventBean> getList() {
|
|
||||||
return this.list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -74,7 +74,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
height: 100%;
|
height: calc(100% - 2px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
@ -236,4 +236,6 @@ body {
|
|||||||
.tab-pane-table {
|
.tab-pane-table {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid silver;
|
||||||
}
|
}
|
@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="div_list" class="tab-pane fade">
|
<div id="div_list" class="tab-pane fade tab-pane-table">
|
||||||
<div class="accordion-body" style="background-color: white">
|
<div class="accordion-body" style="background-color: white">
|
||||||
<table class="table table-striped table-condensed">
|
<table class="table table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -25,14 +25,13 @@
|
|||||||
<main layout:fragment="content">
|
<main layout:fragment="content">
|
||||||
<ul class="nav nav-tabs navback" role="tablist">
|
<ul class="nav nav-tabs navback" role="tablist">
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li>
|
<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li>
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_calendar">Kalender</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li>
|
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li>
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li>
|
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li>
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Aufgabe</a></li>
|
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Aufgabe</a></li>
|
||||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_billing">Abrechnung</a></li>
|
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_billing">Abrechnung</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tabdivblurred tab-content">
|
<div class="tabdivblurred tab-content">
|
||||||
<div id="div_list" class="tab-pane active" style="background-color: white">
|
<div id="div_list" class="tab-pane active tab-pane-table" style="background-color: white">
|
||||||
<table class="table table-striped table-condensed">
|
<table class="table table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -76,7 +75,6 @@
|
|||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id="div_calendar" class="tab-pane fade">Kalender: TODO</div>
|
|
||||||
<div id="div_project" class="tab-pane fade tab-pane-table">
|
<div id="div_project" class="tab-pane fade tab-pane-table">
|
||||||
<table id="project_table" class="table table-striped table-condensed">
|
<table id="project_table" class="table table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -3,22 +3,26 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
|
||||||
|
<title>Timetrack</title>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/5.1.3/css/bootstrap.min.css}" />
|
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/5.1.3/css/bootstrap.min.css}" />
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/1.11.3/css/dataTables.bootstrap5.min.css}" />
|
<link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/1.11.3/css/dataTables.bootstrap5.min.css}" />
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/webjars/font-awesome/5.15.4/css/all.min.css}">
|
<link rel="stylesheet" type="text/css" th:href="@{/webjars/font-awesome/5.15.4/css/all.min.css}" />
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/css/fullCalendar/main.min.css}" />
|
||||||
<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}">
|
<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" th:href="@{/png/favicon/favicon-32x32.png}">
|
<link rel="icon" type="image/png" sizes="32x32" th:href="@{/png/favicon/favicon-32x32.png}" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" th:href="@{/png/favicon/favicon-16x16.png}">
|
<link rel="icon" type="image/png" sizes="16x16" th:href="@{/png/favicon/favicon-16x16.png}" />
|
||||||
|
|
||||||
<script th:src="@{/webjars/jquery/3.6.0/jquery.min.js}"></script>
|
<script th:src="@{/webjars/jquery/3.6.0/jquery.min.js}"></script>
|
||||||
<script th:src="@{/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js}"></script>
|
<script th:src="@{/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js}"></script>
|
||||||
<script th:src="@{/webjars/datatables/1.11.3/js/jquery.dataTables.min.js}"></script>
|
<script th:src="@{/webjars/datatables/1.11.3/js/jquery.dataTables.min.js}"></script>
|
||||||
<script th:src="@{/webjars/datatables/1.11.3/js/dataTables.bootstrap5.min.js}"></script>
|
<script th:src="@{/webjars/datatables/1.11.3/js/dataTables.bootstrap5.min.js}"></script>
|
||||||
|
<script th:src="@{/js/fullCalendar/main.min.js}"></script>
|
||||||
|
<script th:src="@{/js/fullCalendar/locales-all.min.js}"></script>
|
||||||
<script th:src="@{/js/helper.js}"></script>
|
<script th:src="@{/js/helper.js}"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Navigation -->
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light static-top">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light static-top">
|
||||||
<div class="container-fluid" style="width: 98%">
|
<div class="container-fluid" style="width: 98%">
|
||||||
<i class="fa fa-calendar-alt"></i> <a class="navbar-brand" style="margin-left: 8px; z-index: 1" th:href="@{/}">Timetrack</a><br />
|
<i class="fa fa-calendar-alt"></i> <a class="navbar-brand" style="margin-left: 8px; z-index: 1" th:href="@{/}">Timetrack</a><br />
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="div_list" class="tab-pane fade">
|
<div id="div_list" class="tab-pane fade tab-pane-table">
|
||||||
<div class="accordion-body" style="background-color: white">
|
<div class="accordion-body" style="background-color: white">
|
||||||
<table class="table table-striped table-condensed">
|
<table class="table table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<Context>
|
|
||||||
<Resource name="BeanManager" auth="Container"
|
|
||||||
type="javax.enterprise.inject.api.BeanManager"
|
|
||||||
factory="org.jboss.weld.resources.ManagerObjectFactory" />
|
|
||||||
</Context>
|
|
@ -1,10 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<factory>
|
|
||||||
<faces-context-factory>de.jooqfaces.JooqFacesContextFactory</faces-context-factory>
|
|
||||||
</factory>
|
|
||||||
</faces-config>
|
|
@ -1,69 +0,0 @@
|
|||||||
<?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/timetrack.properties</param-value>
|
|
||||||
</context-param>
|
|
||||||
<listener>
|
|
||||||
<listener-class>de.jooqfaces.PropertiesDeploymentListener</listener-class>
|
|
||||||
</listener>
|
|
||||||
</web-app>
|
|
@ -1,42 +0,0 @@
|
|||||||
<!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>
|
|
@ -1,41 +0,0 @@
|
|||||||
<!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>
|
|
@ -1,80 +0,0 @@
|
|||||||
<!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 type="button" class="btn btn-danger" value="--:--" onclick="document.getElementById('input_formular:time_from').value = ''; return false;" />
|
|
||||||
</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="3,3,3,3" size="xs">
|
|
||||||
<h:outputText value="Projekt" />
|
|
||||||
<h:outputText value="Modul" />
|
|
||||||
<h:outputText value="Tätigkeit" />
|
|
||||||
<h:outputText value="Abrechnung" />
|
|
||||||
<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:selectOneMenu id="billing" value="#{doneModel.bean.billing}">
|
|
||||||
<f:selectItem itemValue="" itemLabel="--- bitte wählen ---" />
|
|
||||||
<f:selectItems value="#{doneModel.billings}" 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);
|
|
||||||
$("[id='formular:billingInner']").attr("size", 25);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</b:form>
|
|
||||||
</b:panel>
|
|
||||||
</ui:define>
|
|
||||||
<ui:define name="navigation">
|
|
||||||
</ui:define>
|
|
||||||
</ui:composition>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
@ -1,39 +0,0 @@
|
|||||||
<!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" />
|
|
||||||
<h:outputText value="Abrechnung: " />
|
|
||||||
<h:outputText value="#{doneModel.bean.billingName}" 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>
|
|
@ -1,85 +0,0 @@
|
|||||||
<!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="3,3,3,3" size="xs">
|
|
||||||
<h:outputText value="Projekt (#{doneModel.bean.projectName})" />
|
|
||||||
<h:outputText value="Modul (#{doneModel.bean.moduleName})" />
|
|
||||||
<h:outputText value="Tätigkeit (#{doneModel.bean.jobName})" />
|
|
||||||
<h:outputText value="Abrechnung (#{doneModel.bean.billingName})" />
|
|
||||||
<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:selectOneMenu id="billing" value="#{doneModel.bean.billing}">
|
|
||||||
<f:selectItem itemValue="" itemLabel="--- bitte wählen ---" />
|
|
||||||
<f:selectItems value="#{doneModel.billings}" 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);
|
|
||||||
$("[id='formular:billingInner']").attr("size", 25);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</b:form>
|
|
||||||
</b:panel>
|
|
||||||
</ui:define>
|
|
||||||
<ui:define name="navigation">
|
|
||||||
</ui:define>
|
|
||||||
</ui:composition>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
@ -1,139 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<b:dataTableColumn label="" style="width: 100px !important" orderable="false">
|
|
||||||
<b:commandButton action="#{doneControl.toDelete(b)}" value="Entfernen" look="danger" iconAwesome="trash" />
|
|
||||||
</b:dataTableColumn>
|
|
||||||
<b:dataTableColumn label="" value="#{b.timeSummary}" contentStyleClass="doneoverviewtext" style="width: 128px !important" orderable="false" />
|
|
||||||
<b:dataTableColumn label="" value="#{b.projectName}" contentStyleClass="doneoverviewtextemph" style="width: 160px !important" orderable="false" />
|
|
||||||
<b:dataTableColumn label="" orderable="false">
|
|
||||||
<b:badge value="#{b.billingShortcut}" styleClass="#{b.billingCsskey}" />
|
|
||||||
</b:dataTableColumn>
|
|
||||||
<b:dataTableColumn label="" value="#{b.timeDiff}" contentStyleClass="doneoverviewtextemph" style="width: 64px !important" orderable="false" />
|
|
||||||
<b:dataTableColumn label="" style="width: 100px !important" orderable="false">
|
|
||||||
<b:commandButton action="#{doneControl.toEdit(b)}" value="Editieren" look="warning" iconAwesome="pencil" />
|
|
||||||
</b:dataTableColumn>
|
|
||||||
<b:dataTableColumn label="" value="#{b.moduleName}" contentStyleClass="doneoverviewtext" style="width: 128px !important" orderable="false" />
|
|
||||||
<b:dataTableColumn label="" value="#{b.jobName}" contentStyleClass="doneoverviewtext" orderable="false" />
|
|
||||||
</b:dataTable>
|
|
||||||
<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: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="" orderable="false">
|
|
||||||
<b:badge value="#{col.billingShortcut}" styleClass="#{col.billingCsskey}" />
|
|
||||||
</b:dataTableColumn>
|
|
||||||
<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.durationHours} h" contentStyle="font-size: 120%" orderable="false" />
|
|
||||||
</b:dataTable>
|
|
||||||
<h:panelGrid columns="3" style="width: 100%">
|
|
||||||
<h:outputText value="Zusammenfassung" style="font-size: 120%; font-weight: bold" />
|
|
||||||
<h:outputText value="#{doneModel.summaryBilling}" style="font-size: 120%; font-weight: bold" />
|
|
||||||
<h:outputText value="#{doneModel.summaryTime} h" style="font-size: 120%; font-weight: bold" />
|
|
||||||
</h:panelGrid>
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Anhang">
|
|
||||||
<p>
|
|
||||||
<b:inputTextarea value="#{doneModel.attach}" readonly="true" />
|
|
||||||
</p>
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Kalender" contentStyle="height: 75vh">
|
|
||||||
<my:fullcalendar value="#{doneModel.calendarEvents}" defaultDate="#{doneModel.dayIso8601}" />
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Projekt">
|
|
||||||
<ui:repeat value="#{doneModel.projects}" var="col">
|
|
||||||
<b:badge value="#{col.name}" class="prompt" />
|
|
||||||
</ui:repeat>
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Modul">
|
|
||||||
<ui:repeat value="#{doneModel.modules}" var="col">
|
|
||||||
<b:badge value="#{col.name}" class="prompt" />
|
|
||||||
</ui:repeat>
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Tätigkeit">
|
|
||||||
<ui:repeat value="#{doneModel.activities}" var="col">
|
|
||||||
<b:badge value="#{col.name}" class="prompt" />
|
|
||||||
</ui:repeat>
|
|
||||||
</b:tab>
|
|
||||||
<b:tab title="Abrechnung">
|
|
||||||
<b:dataTable value="#{doneModel.billings}" var="col" border="false" info="false">
|
|
||||||
<b:dataTableColumn label="Kürzel" value="#{col.shortcut}" />
|
|
||||||
<b:dataTableColumn label="Name" value="#{col.name}" />
|
|
||||||
<b:dataTableColumn label="Stil">
|
|
||||||
<b:badge value="#{col.csskey}" styleClass="#{col.csskey}" />
|
|
||||||
</b:dataTableColumn>
|
|
||||||
</b:dataTable>
|
|
||||||
</b:tab>
|
|
||||||
</b:tabView>
|
|
||||||
</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>
|
|
@ -1,46 +0,0 @@
|
|||||||
<!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="Arbeitszeiten" look="primary">
|
|
||||||
<b:form>
|
|
||||||
<b:panelGrid colSpans="4,3,3,2">
|
|
||||||
<b:selectOneMenu value="#{doneModel.downloadBean.username}">
|
|
||||||
<f:selectItems value="#{doneModel.users}" var="u" itemValue="#{u.username}" itemLabel="#{u.forename} #{u.surname}" />
|
|
||||||
</b:selectOneMenu>
|
|
||||||
<b:dateTimePicker value="#{doneModel.downloadBean.fromDate}" format="DD.MM.YYYY" locale="de" disableTimeInterval="true" required="true"
|
|
||||||
requiredMessage="von muss ausgefüllt werden">
|
|
||||||
<f:facet name="prepend">
|
|
||||||
<h:outputText value="von" />
|
|
||||||
</f:facet>
|
|
||||||
<f:converter converterId="de.jottyfan.timetrack.help.LocalDateConverter" />
|
|
||||||
</b:dateTimePicker>
|
|
||||||
<b:dateTimePicker value="#{doneModel.downloadBean.untilDate}" format="DD.MM.YYYY" locale="de" disableTimeInterval="true" required="true"
|
|
||||||
requiredMessage="bis muss ausgefüllt werden">
|
|
||||||
<f:facet name="prepend">
|
|
||||||
<h:outputText value="bis" />
|
|
||||||
</f:facet>
|
|
||||||
<f:converter converterId="de.jottyfan.timetrack.help.LocalDateConverter" />
|
|
||||||
</b:dateTimePicker>
|
|
||||||
<b:commandButton action="#{doneControl.doDownload}" value="herunterladen" look="primary" iconAwesome="download" />
|
|
||||||
</b:panelGrid>
|
|
||||||
</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:buttonGroup>
|
|
||||||
</b:form>
|
|
||||||
</ui:define>
|
|
||||||
</ui:composition>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
@ -1,47 +0,0 @@
|
|||||||
<!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>
|
|
@ -1,45 +0,0 @@
|
|||||||
<!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>
|
|
@ -1,77 +0,0 @@
|
|||||||
<!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">
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function(){
|
|
||||||
$("div.page").css("overflow", "hidden");
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<b:panel title="Einstellungen" collapsed="true" rendered="#{sessionBean.hasLogin}">
|
|
||||||
<b:accordion expandedPanels="layout">
|
|
||||||
<b:panel id="layout" title="Layout">
|
|
||||||
<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 id="password" title="Passwort">
|
|
||||||
<b:form>
|
|
||||||
<b:inputSecret value="#{sessionControl.secretNew1}" required="true" requiredMessage="Das Feld Passwort muss ausgefüllt werden.">
|
|
||||||
<f:facet name="prepend">
|
|
||||||
<h:outputText value="Passwort" />
|
|
||||||
</f:facet>
|
|
||||||
</b:inputSecret>
|
|
||||||
<b:inputSecret value="#{sessionControl.secretNew2}" required="true" requiredMessage="Das Feld Passwort nochmal muss ausgefüllt werden.">
|
|
||||||
<f:facet name="prepend">
|
|
||||||
<h:outputText value="Passwort nochmal" />
|
|
||||||
</f:facet>
|
|
||||||
</b:inputSecret>
|
|
||||||
<b:commandButton action="#{sessionControl.doChangePassword}" value="übernehmen" look="warning" />
|
|
||||||
</b:form>
|
|
||||||
</b:panel>
|
|
||||||
</b:accordion>
|
|
||||||
</b:panel>
|
|
||||||
<b:panel title="Anmeldung" collapsible="false" styleClass="loginpanel" rendered="#{sessionBean.hasNoLogin}">
|
|
||||||
<b:form>
|
|
||||||
<b:selectOneMenu value="#{sessionBean.username}">
|
|
||||||
<f:facet name="prepend">
|
|
||||||
<h:outputText value="Benutzer" />
|
|
||||||
</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>
|
|
||||||
<h:panelGrid columns="2" columnClasses="left,right" style="width: 100%">
|
|
||||||
<h:outputText value="Version: #{sessionControl.version}" styleClass="version" />
|
|
||||||
<b:commandButton action="#{sessionControl.doLogin}" value="Anmelden" look="primary" style="width: 100%" />
|
|
||||||
</h:panelGrid>
|
|
||||||
</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" rendered="#{sessionBean.hasPrivilege('write_note')}" />
|
|
||||||
<b:commandButton action="#{contactControl.toList}" value="#{contactControl.amount} Kontakte verwalten" look="primary" iconAwesome="group" rendered="#{sessionBean.hasPrivilege('write_contact')}" />
|
|
||||||
<b:commandButton action="#{doneControl.toList}" value="Arbeitszeit verwalten" look="primary" iconAwesome="clock-o" rendered="#{sessionBean.hasPrivilege('write_done')}" />
|
|
||||||
<b:commandButton action="#{doneControl.toRead}" value="Arbeitszeiten anzeigen" look="primary" iconAwesome="clock-o" rendered="#{sessionBean.hasPrivilege('read_done')}" />
|
|
||||||
<b:commandButton action="#{sessionControl.doLogout}" value="abmelden" look="danger" iconAwesome="sign-out" />
|
|
||||||
</b:buttonGroup>
|
|
||||||
</b:form>
|
|
||||||
</ui:define>
|
|
||||||
</ui:composition>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
@ -1,24 +0,0 @@
|
|||||||
<!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" style="height: 100%; width: 100%">
|
|
||||||
<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="main">
|
|
||||||
<ui:insert name="main" />
|
|
||||||
</div>
|
|
||||||
<div class="navigation">
|
|
||||||
<ui:insert name="navigation" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</h:body>
|
|
||||||
</html>
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,83 +0,0 @@
|
|||||||
<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="value" required="true" default="" />
|
|
||||||
<cc:attribute name="defaultDate" required="true" />
|
|
||||||
</cc:interface>
|
|
||||||
<cc:implementation>
|
|
||||||
<h:outputStylesheet name="jslibs/fullcalendar/main.min.css" />
|
|
||||||
<h:outputScript library="bsf" name="jq/jquery.js" target="head" />
|
|
||||||
<h:outputScript library="jslibs" name="fullcalendar/main.min.js" target="head" />
|
|
||||||
<h:outputScript library="jslibs" name="fullcalendar/locales-all.min.js" target="head" />
|
|
||||||
<script type="text/javascript">
|
|
||||||
function lz(x) {
|
|
||||||
if (x < 10){
|
|
||||||
return "0" + x;
|
|
||||||
} else {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document)
|
|
||||||
.ready(
|
|
||||||
function() {
|
|
||||||
var calendarEl = document
|
|
||||||
.getElementById('calendar');
|
|
||||||
var calendar = new FullCalendar.Calendar(
|
|
||||||
calendarEl,
|
|
||||||
{
|
|
||||||
initialView : 'timeGridDay',
|
|
||||||
initialDate : "#{cc.attrs.defaultDate}",
|
|
||||||
headerToolbar : {
|
|
||||||
left : 'prev,next today',
|
|
||||||
center : 'title',
|
|
||||||
right : 'dayGridMonth,timeGridWeek,timeGridDay'
|
|
||||||
},
|
|
||||||
height : "75vh",
|
|
||||||
locale : 'de',
|
|
||||||
events : <h:outputText value="#{cc.attrs.value}" escape="FALSE" />,
|
|
||||||
eventClick : function(info) {
|
|
||||||
from = info.event.start;
|
|
||||||
until = info.event.end;
|
|
||||||
fromS = from == null ? "?" : lz(from.getHours()) + ":" + lz(from.getMinutes());
|
|
||||||
untilS = until == null ? "?" : lz(until.getHours()) + ":" + lz(until.getMinutes());
|
|
||||||
$("#modaltitle").html(fromS + " - " + untilS);
|
|
||||||
$("#modalsummary").html(info.event.title);
|
|
||||||
$("#modalproject").html(info.event.project);
|
|
||||||
$("#modalmodule").html(info.event.module);
|
|
||||||
$("#modaljob").html(info.event.job);
|
|
||||||
$("#modalbilling").html(info.event.billing);
|
|
||||||
$("#calmodal").show();
|
|
||||||
},
|
|
||||||
firstDay : 0
|
|
||||||
});
|
|
||||||
calendar.setOption('locale', 'de');
|
|
||||||
calendar.render();
|
|
||||||
});
|
|
||||||
$(document).ready(function() {
|
|
||||||
var calendarEl = document.getElementById('calendar');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<div id="calendar"></div>
|
|
||||||
<!-- div id="calmodal" class="modal" fade" tabindex="-1" role="dialog" -->
|
|
||||||
<div id="calmodal" class="modal" tabindex="-1" role="dialog" style="background: rgba(0, 0, 0, 0.5) !important;">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="$('#calmodal').hide()">
|
|
||||||
<span aria-hidden="true" class="fa fa-times"></span>
|
|
||||||
</button>
|
|
||||||
<h4 id="modaltitle" class="modal-title"></h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<h1 id="modalsummary"></h1>
|
|
||||||
<h2 id="modalproject"></h2>
|
|
||||||
<h3 id="modalmodule"></h3>
|
|
||||||
<h4 id="modaljob"></h4>
|
|
||||||
<div id="modalbilling"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</cc:implementation>
|
|
||||||
</ui:composition>
|
|
@ -1,29 +0,0 @@
|
|||||||
<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