removed calendar
This commit is contained in:
1 parent
a4029cb71d
commit
b53802c813
48 files changed
+16
-3117
No files matched your search
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
|
||||||
Whitespace-only changes.
@@ -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>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
[].push.apply(FullCalendar.globalLocales,function(){"use strict";return[{code:"af",week:{dow:1,doy:4},buttonText:{prev:"Vorige",next:"Volgende",today:"Vandag",year:"Jaar",month:"Maand",week:"Week",day:"Dag",list:"Agenda"},allDayText:"Heeldag",moreLinkText:"Addisionele",noEventsText:"Daar is geen gebeurtenisse nie"},{code:"ar-dz",week:{dow:0,doy:4},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar-kw",week:{dow:0,doy:12},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar-ly",week:{dow:6,doy:12},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar-ma",week:{dow:6,doy:12},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar-sa",week:{dow:0,doy:6},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar-tn",week:{dow:1,doy:4},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"ar",week:{dow:6,doy:12},direction:"rtl",buttonText:{prev:"السابق",next:"التالي",today:"اليوم",month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},weekText:"أسبوع",allDayText:"اليوم كله",moreLinkText:"أخرى",noEventsText:"أي أحداث لعرض"},{code:"az",week:{dow:1,doy:4},buttonText:{prev:"Əvvəl",next:"Sonra",today:"Bu Gün",month:"Ay",week:"Həftə",day:"Gün",list:"Gündəm"},weekText:"Həftə",allDayText:"Bütün Gün",moreLinkText:function(e){return"+ daha çox "+e},noEventsText:"Göstərmək üçün hadisə yoxdur"},{code:"bg",week:{dow:1,doy:7},buttonText:{prev:"назад",next:"напред",today:"днес",month:"Месец",week:"Седмица",day:"Ден",list:"График"},allDayText:"Цял ден",moreLinkText:function(e){return"+още "+e},noEventsText:"Няма събития за показване"},{code:"bs",week:{dow:1,doy:7},buttonText:{prev:"Prošli",next:"Sljedeći",today:"Danas",month:"Mjesec",week:"Sedmica",day:"Dan",list:"Raspored"},weekText:"Sed",allDayText:"Cijeli dan",moreLinkText:function(e){return"+ još "+e},noEventsText:"Nema događaja za prikazivanje"},{code:"ca",week:{dow:1,doy:4},buttonText:{prev:"Anterior",next:"Següent",today:"Avui",month:"Mes",week:"Setmana",day:"Dia",list:"Agenda"},weekText:"Set",allDayText:"Tot el dia",moreLinkText:"més",noEventsText:"No hi ha esdeveniments per mostrar"},{code:"cs",week:{dow:1,doy:4},buttonText:{prev:"Dříve",next:"Později",today:"Nyní",month:"Měsíc",week:"Týden",day:"Den",list:"Agenda"},weekText:"Týd",allDayText:"Celý den",moreLinkText:function(e){return"+další: "+e},noEventsText:"Žádné akce k zobrazení"},{code:"cy",week:{dow:1,doy:4},buttonText:{prev:"Blaenorol",next:"Nesaf",today:"Heddiw",year:"Blwyddyn",month:"Mis",week:"Wythnos",day:"Dydd",list:"Rhestr"},weekText:"Wythnos",allDayText:"Trwy'r dydd",moreLinkText:"Mwy",noEventsText:"Dim digwyddiadau"},{code:"da",week:{dow:1,doy:4},buttonText:{prev:"Forrige",next:"Næste",today:"I dag",month:"Måned",week:"Uge",day:"Dag",list:"Agenda"},weekText:"Uge",allDayText:"Hele dagen",moreLinkText:"flere",noEventsText:"Ingen arrangementer at vise"},{code:"de-at",week:{dow:1,doy:4},buttonText:{prev:"Zurück",next:"Vor",today:"Heute",year:"Jahr",month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},weekText:"KW",allDayText:"Ganztägig",moreLinkText:function(e){return"+ weitere "+e},noEventsText:"Keine Ereignisse anzuzeigen"},{code:"de",week:{dow:1,doy:4},buttonText:{prev:"Zurück",next:"Vor",today:"Heute",year:"Jahr",month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},weekText:"KW",allDayText:"Ganztägig",moreLinkText:function(e){return"+ weitere "+e},noEventsText:"Keine Ereignisse anzuzeigen"},{code:"el",week:{dow:1,doy:4},buttonText:{prev:"Προηγούμενος",next:"Επόμενος",today:"Line truncated
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
.fc-icon,.fc-unselectable{-moz-user-select:none;-ms-user-select:none}.fc .fc-button,.fc-icon{text-transform:none;text-align:center}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc .fc-button:not(:disabled),.fc a[data-navlink],.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-unselectable{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.fc{display:flex;flex-direction:column;font-size:1em}.fc .fc-button,.fc-icon{display:inline-block;font-weight:400}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{vertical-align:top;padding:0}.fc .fc-button,.fc .fc-button .fc-icon,.fc .fc-button-group,.fc .fc-timegrid-slot-label{vertical-align:middle}.fc a[data-navlink]:hover{text-decoration:underline}.fc .fc-button:hover,.fc .fc-list-event-title a,a.fc-event,a.fc-event:hover{text-decoration:none}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid #ddd;border:1px solid var(--fc-border-color,#ddd)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format('truetype');font-weight:400;font-style:normal}.fc-icon{width:1em;height:1em;-webkit-user-select:none;user-select:none;font-family:fcicons!important;speak:none;font-style:normal;font-variant:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fc-icon-chevron-left:before{content:"\e900"}.fc-icon-chevron-right:before{content:"\e901"}.fc-icon-chevrons-left:before{content:"\e902"}.fc-icon-chevrons-right:before{content:"\e903"}.fc-icon-minus-square:before{content:"\e904"}.fc-icon-plus-square:before{content:"Line truncated
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/*!
|
|
||||||
FullCalendar v5.5.1
|
|
||||||
Docs & License: https://fullcalendar.io/
|
|
||||||
(c) 2020 Adam Shaw
|
|
||||||
*/
|
|
||||||
var FullCalendar=function(e){"use strict";var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};function n(e,n){function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}var r=function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function o(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],a=0,s=i.length;a<s;a++,o++)r[o]=i[a];return r}var i,a,s,l,u,c,d={},p=[],f=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function h(e,t){for(var n in t)e[n]=t[n];return e}function v(e){var t=e.parentNode;t&&t.removeChild(e)}function g(e,t,n){var r,o,i,a=arguments,s={};for(i in t)"key"==i?r=t[i]:"ref"==i?o=t[i]:s[i]=t[i];if(arguments.length>3)for(n=[n],i=3;i<arguments.length;i++)n.push(a[i]);if(null!=n&&(s.children=n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===s[i]&&(s[i]=e.defaultProps[i]);return m(e,s,r,o,null)}function m(e,t,n,r,o){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++i.__v:o};return null!=i.vnode&&i.vnode(a),a}function y(e){return e.children}function E(e,t){this.props=e,this.context=t}function S(e,t){if(null==t)return e.__?S(e.__,e.__.__k.indexOf(e)+1):null;for(var n;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e)return n.__e;return"function"==typeof e.type?S(e):null}function D(e){var t,n;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e){e.__e=e.__c.base=n.__e;break}return D(e)}}function b(e){(!e.__d&&(e.__d=!0)&&a.push(e)&&!C.__r++||l!==i.debounceRendering)&&((l=i.debounceRendering)||s)(C)}function C(){for(var e;C.__r=a.length;)e=a.sort((function(e,t){return e.__v.__b-t.__v.__b})),a=[],e.some((function(e){var t,n,r,o,i,a,s;e.__d&&(a=(i=(t=e).__v).__e,(s=t.__P)&&(n=[],(r=h({},i)).__v=i.__v+1,o=I(s,i,r,t.__n,void 0!==s.ownerSVGElement,null!=i.__h?[a]:null,n,null==a?S(i):a,i.__h),P(n,i),o!=a&&D(i)))}))}function w(e,t,n,r,o,i,a,s,l,u){var c,f,h,g,E,D,b,C=r&&r.__k||p,w=C.length;for(l==d&&(l=null!=a?a[0]:w?S(r,0):null),n.__k=[],c=0;c<t.length;c++)if(null!=(g=n.__k[c]=null==(g=t[c])||"boolean"==typeof g?null:"string"==typeof g||"number"==typeof g?m(null,g,null,null,g):Array.isArray(g)?m(y,{children:g},null,null,null):null!=g.__e||null!=g.__c?m(g.type,g.props,g.key,null,g.__v):g)){if(g.__=n,g.__b=n.__b+1,null===(h=C[c])||h&&g.key==h.key&&g.type===h.type)C[c]=void 0;else for(f=0;f<w;f++){if((h=C[f])&&g.key==h.key&&g.type===h.type){C[f]=void 0;break}h=null}E=I(e,g,h=h||d,o,i,a,s,l,u),(f=g.ref)&&h.ref!=f&&(b||(b=[]),h.ref&&b.push(h.ref,null,g),b.push(f,g.__c||E,g)),null!=E?(null==D&&(D=E),l=R(e,g,h,C,a,E,l),u||"option"!=n.type?"function"==typeof n.type&&(n.__d=l):e.value=""):l&&h.__e==l&&l.parentNode!=e&&(l=S(h))}if(n.__e=D,null!=a&&"function"!=typeof n.type)for(c=a.length;c--;)null!=a[c]&&v(a[c]);for(c=w;c--;)null!=C[c]&&O(C[c],C[c]);if(b)for(c=0;c<b.length;c++)H(b[c],b[++c],b[++c])}function R(e,t,n,r,o,i,a){var s,l,u;if(void 0!==t.__d)s=t.__d,t.__d=void 0;else if(o==n||i!=a||null==i.parentNode)e:if(null==a||a.parentNode!==e)e.appendChild(i),s=null;else{for(l=a,u=0;(l=l.nextSibling)&&u<r.length;u+=2)if(l==i)break e;e.insertBefore(i,a),s=a}return void 0!==s?s:i.nextSibling}function T(e,t,n){"-"===t[0]?e.setProperty(t,n):e[t]=null==n?"":"number"!=typeof n||f.test(t)?n:n+"px"}function k(e,t,n,r,o){var i,a,s;if(o&&"className"==t&&(t="class"),"style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||T(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||T(e.style,t,n[t])}else"o"===t[0]&&"n"===t[1]?(i=t!==(t=t.replace(/Capture$/,"")),(a=t.toLowerCase())in e&&(t=a),t=t.slice(2),e.l||(e.l={}),e.l[t+i]=n,s=i?x:M,n?r||e.addEventListener(t,s,i):e.removeEventListener(t,s,i)):"list"!==t&&"tagName"!==t&&"form"!==t&&"type"!==t&&"size"!==t&&"download"!==t&&"href"!==t&&!o&&t in e?e[t]=null==n?"":n:"function"!=typeof n&&"dangerouslySetInnerHTML"!==t&&(t!==(t=t.replace(/xlink:?/,""))?null==n||!1===n?e.removeAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase()):e.setAttributeNS("http://www.w3.org/1999/xlink",t.toLowerCase(),n):null==n||!1===n&&!/^ar/.test(t)?e.removeAttribute(t):e.setAttribute(t,n))}function M(e){this.l[e.type+!1](i.event?i.event(e):e)}function x(e){this.l[e.type+!0](i.event?i.event(e):e)}function _(e,t,n){var r,o;for(r=0;r<e.__k.length;r++)(o=e.__k[r])&&(o.__=e,o.__e&&("function"==typeof o.type&&o.__k.length>1&&_(o,t,n),t=R(n,o,o,e.__k,null,o.__e,t),"function"==typeof e.type&&(e.__d=t)))}function I(e,t,n,r,o,a,s,l,u){var c,d,Line truncated
|
|
||||||
@@ -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