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_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.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.profile.Tables.T_LOGIN;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
@@ -32,8 +28,8 @@ import org.jooq.exception.DataAccessException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.VBillingRecord;
|
||||
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.VProjectRecord;
|
||||
|
||||
@@ -128,5 +128,4 @@ public class DoneService implements IDoneService {
|
||||
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 {
|
||||
height: 100%;
|
||||
height: calc(100% - 2px);
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -236,4 +236,6 @@ body {
|
||||
.tab-pane-table {
|
||||
background-color: white;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid silver;
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
</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">
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
<main layout:fragment="content">
|
||||
<ul class="nav nav-tabs navback" role="tablist">
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li>
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_calendar">Kalender</a></li>
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li>
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li>
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Aufgabe</a></li>
|
||||
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_billing">Abrechnung</a></li>
|
||||
</ul>
|
||||
<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">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -76,7 +75,6 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="div_calendar" class="tab-pane fade">Kalender: TODO</div>
|
||||
<div id="div_project" class="tab-pane fade tab-pane-table">
|
||||
<table id="project_table" class="table table-striped table-condensed">
|
||||
<thead>
|
||||
|
||||
@@ -3,22 +3,26 @@
|
||||
<head>
|
||||
<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/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="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="32x32" th:href="@{/png/favicon/favicon-32x32.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/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/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>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light static-top">
|
||||
<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 />
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</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">
|
||||
<table class="table table-striped table-condensed">
|
||||
<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