full calendar instead of bootsfaces calendar
This commit is contained in:
@ -122,15 +122,6 @@ public class DoneBean implements Bean, Serializable, Comparable<DoneBean> {
|
||||
return ldt;
|
||||
}
|
||||
|
||||
public String getProjectNameWithBilling() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(project == null ? "" : project.getName());
|
||||
if (billing != null) {
|
||||
buf.append(" (").append(billing.getShortcut()).append(")");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return project == null ? "" : project.getName();
|
||||
}
|
||||
@ -146,6 +137,14 @@ public class DoneBean implements Bean, Serializable, Comparable<DoneBean> {
|
||||
public String getBillingName() {
|
||||
return billing == null ? "" : billing.getName();
|
||||
}
|
||||
|
||||
public String getBillingShortcut() {
|
||||
return billing == null ? "" : billing.getShortcut();
|
||||
}
|
||||
|
||||
public String getBillingCsskey() {
|
||||
return billing == null ? "" : billing.getCsskey();
|
||||
}
|
||||
|
||||
public String getTimeFromString() {
|
||||
return timeFrom == null ? "" : timeFrom.format(hhmm);
|
||||
|
@ -33,7 +33,6 @@ import org.jooq.Record;
|
||||
import org.jooq.Record3;
|
||||
import org.jooq.Record4;
|
||||
import org.jooq.Record5;
|
||||
import org.jooq.Record6;
|
||||
import org.jooq.Record7;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.SelectJoinStep;
|
||||
@ -48,8 +47,8 @@ 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 net.bootsfaces.component.fullCalendar.FullCalendarEventBean;
|
||||
import net.bootsfaces.component.fullCalendar.FullCalendarEventList;
|
||||
import de.jottyfan.timetrack.modules.done.fullcalendar.ColorfulFCEventBean;
|
||||
import de.jottyfan.timetrack.modules.done.fullcalendar.FCEventList;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -386,14 +385,15 @@ public class DoneGateway extends JooqGateway {
|
||||
*/
|
||||
public String getAllCalendarEvents() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
try (CloseableDSLContext jooq = getJooq()) {
|
||||
SelectConditionStep<Record6<LocalDateTime, LocalDateTime, String, String, String, String>> sql = jooq
|
||||
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.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))
|
||||
@ -402,7 +402,7 @@ public class DoneGateway extends JooqGateway {
|
||||
.where(T_DONE.FK_LOGIN.eq(getFkLogin()));
|
||||
// @formatter:on
|
||||
LOGGER.debug(sql.toString());
|
||||
FullCalendarEventList list = new FullCalendarEventList();
|
||||
FCEventList list = new FCEventList();
|
||||
for (Record r : sql.fetch()) {
|
||||
String projectName = r.get(T_PROJECT.NAME);
|
||||
String moduleName = r.get(T_MODULE.NAME);
|
||||
@ -410,6 +410,7 @@ public class DoneGateway extends JooqGateway {
|
||||
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);
|
||||
@ -418,14 +419,14 @@ public class DoneGateway extends JooqGateway {
|
||||
buf.append(": ");
|
||||
buf.append(jobName);
|
||||
|
||||
FullCalendarEventBean bean = new FullCalendarEventBean(buf.toString(),
|
||||
java.util.Date.from(timeFrom.atZone(ZoneId.systemDefault()).toInstant())) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void addExtendedFields(StringBuilder buf) {
|
||||
}
|
||||
};
|
||||
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()) {
|
||||
|
@ -58,4 +58,14 @@ public class RgbColor {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,10 @@
|
||||
<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.projectNameWithBilling}" contentStyleClass="doneoverviewtextemph" style="width: 160px !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" />
|
||||
@ -87,10 +90,8 @@
|
||||
<b:inputTextarea value="#{doneModel.attach}" readonly="true" />
|
||||
</p>
|
||||
</b:tab>
|
||||
<b:tab title="Kalender">
|
||||
<b:fullCalendar editable="false" events="#{doneModel.calendarEvents}" height="600"
|
||||
defaultDate="#{doneModel.dayIso8601}" defaultView="agendaDay" hidden="xs" scrollTime="08:00:00"
|
||||
slotDuration="00:15:00" span="half" allDaySlot="false" lang="de" />
|
||||
<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">
|
||||
|
@ -92,4 +92,8 @@
|
||||
.version {
|
||||
font-size: small;
|
||||
color: silver;
|
||||
}
|
||||
}
|
||||
|
||||
.fc-content {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
1
src/main/webapp/resources/jslibs/fullcalendar/locales-all.min.js
vendored
Normal file
1
src/main/webapp/resources/jslibs/fullcalendar/locales-all.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/main/webapp/resources/jslibs/fullcalendar/main.min.css
vendored
Normal file
1
src/main/webapp/resources/jslibs/fullcalendar/main.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6
src/main/webapp/resources/jslibs/fullcalendar/main.min.js
vendored
Normal file
6
src/main/webapp/resources/jslibs/fullcalendar/main.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
83
src/main/webapp/resources/my/fullcalendar.xhtml
Normal file
83
src/main/webapp/resources/my/fullcalendar.xhtml
Normal file
@ -0,0 +1,83 @@
|
||||
<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>
|
Reference in New Issue
Block a user