calendar like slot overview
This commit is contained in:
@ -60,7 +60,8 @@ public class DoneController extends CommonController {
|
||||
model.addAttribute("sum", sumBean);
|
||||
model.addAttribute("daysum", doneService.getDaysum(day, username));
|
||||
model.addAttribute("overtimeBean", doneService.getOvertimeBean(username));
|
||||
model.addAttribute("slots", doneService.getSlots(username));
|
||||
model.addAttribute("slots", doneService.getSlots(day, username));
|
||||
model.addAttribute("slotOffset", doneService.getSlotOffset(day));
|
||||
model.addAttribute("schedule", weekBean.toJson());
|
||||
model.addAttribute("recentList", doneService.getListRecent(username, 10));
|
||||
model.addAttribute("projectList", doneService.getProjects(false));
|
||||
|
@ -9,9 +9,9 @@ import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -156,7 +156,7 @@ public class DoneRepository {
|
||||
sql.execute();
|
||||
}
|
||||
|
||||
public List<SlotBean> getSlots(String login) {
|
||||
public Map<LocalDate, SlotBean> getSlots(LocalDate from, LocalDate until, String login) {
|
||||
SelectSeekStep1<Record3<Integer, LocalDate, Integer>, LocalDate> sql = jooq
|
||||
// @formatter:off
|
||||
.select(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME,
|
||||
@ -165,17 +165,21 @@ public class DoneRepository {
|
||||
.from(T_REQUIRED_WORKTIME)
|
||||
.innerJoin(T_LOGIN).on(T_LOGIN.PK.eq(T_REQUIRED_WORKTIME.FK_LOGIN))
|
||||
.where(T_LOGIN.LOGIN.eq(login))
|
||||
.and(T_REQUIRED_WORKTIME.DAY.ge(from))
|
||||
.and(T_REQUIRED_WORKTIME.DAY.le(until))
|
||||
.orderBy(T_REQUIRED_WORKTIME.DAY);
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
Iterator<Record3<Integer, LocalDate, Integer>> i = sql.fetch().iterator();
|
||||
List<SlotBean> list = new ArrayList<>();
|
||||
Map<LocalDate, SlotBean> map = new HashMap<>();
|
||||
while (i.hasNext()) {
|
||||
Record3<Integer, LocalDate, Integer> n = i.next();
|
||||
list.add(SlotBean.of(n.get(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME), n.get(T_REQUIRED_WORKTIME.DAY),
|
||||
n.get(T_REQUIRED_WORKTIME.REQUIRED_MINUTES)));
|
||||
LocalDate day = n.get(T_REQUIRED_WORKTIME.DAY);
|
||||
Integer pk = n.get(T_REQUIRED_WORKTIME.PK_REQUIRED_WORKTIME);
|
||||
Integer minutes = n.get(T_REQUIRED_WORKTIME.REQUIRED_MINUTES);
|
||||
map.put(day, SlotBean.of(pk, day, minutes));
|
||||
}
|
||||
return list;
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,8 +2,11 @@ package de.jottyfan.timetrack.modules.done;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.YearMonth;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -39,7 +42,7 @@ public class DoneService {
|
||||
|
||||
@Autowired
|
||||
private TimeService timeService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private DoneRepository repository;
|
||||
|
||||
@ -246,11 +249,42 @@ public class DoneService {
|
||||
repository.upsertOvertime(bean.getId(), username, bean.getImpact(), bean.getOvertimeMinutes());
|
||||
}
|
||||
|
||||
public List<SlotBean> getSlots(String username) {
|
||||
return repository.getSlots(username);
|
||||
public List<SlotBean> getSlots(LocalDate day, String username) {
|
||||
YearMonth ym = YearMonth.from(day);
|
||||
LocalDate from = ym.atDay(1);
|
||||
LocalDate until = ym.atEndOfMonth();
|
||||
Map<LocalDate, SlotBean> map = new HashMap<>();
|
||||
LocalDate i = from;
|
||||
while (i.isBefore(until.plusDays(1))) {
|
||||
map.put(i, SlotBean.of(i));
|
||||
i = i.plusDays(1);
|
||||
}
|
||||
map.putAll(repository.getSlots(from, until, username));
|
||||
List<SlotBean> list = new ArrayList<>(map.values());
|
||||
list.sort((o1, o2) -> {
|
||||
return o1 == null || o2 == null || o1.getDay() == null ? 0 : o1.getDay().compareTo(o2.getDay());
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
public SlotBean getSlot(Integer id, String username) {
|
||||
return repository.getSlot(id, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a list of days until the 1st of the month starts in the calendar - start
|
||||
* with sunday for the matrix
|
||||
*
|
||||
* @param day the day; only the month will be used
|
||||
* @return a list of numbers
|
||||
*/
|
||||
public List<Integer> getSlotOffset(LocalDate day) {
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
YearMonth ym = YearMonth.from(day);
|
||||
LocalDate first = ym.atDay(1);
|
||||
for (int i = 0; i < first.getDayOfWeek().getValue(); i++) {
|
||||
list.add(i);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,12 @@ public class SlotBean implements Serializable {
|
||||
bean.setMinutes(minutes);
|
||||
return bean;
|
||||
}
|
||||
|
||||
public static final SlotBean of(LocalDate day) {
|
||||
SlotBean bean = new SlotBean();
|
||||
bean.setDay(day);
|
||||
return bean;
|
||||
}
|
||||
|
||||
public String printTime() {
|
||||
Integer hours = 0;
|
||||
@ -74,6 +80,4 @@ public class SlotBean implements Serializable {
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ body {
|
||||
|
||||
.slot_badge {
|
||||
white-space: nowrap;
|
||||
margin-bottom: 2px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.slot_badge_left {
|
||||
@ -415,6 +415,8 @@ body {
|
||||
background-color: #ccc;
|
||||
color: black;
|
||||
padding-left: 2px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] .slot_badge_left {
|
||||
@ -424,8 +426,8 @@ body {
|
||||
.slot_badge_middle {
|
||||
border-top: 1px solid silver;
|
||||
border-bottom: 1px solid silver;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
padding: 2px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.slot_badge_middle:hover {
|
||||
@ -439,8 +441,24 @@ body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
padding-right: 2px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] .slot_badge_right {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.flex-row-weekday {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
|
||||
.row-weekday > .col {
|
||||
flex: 0 1 calc(100%/7);
|
||||
max-width: calc(100%/7);
|
||||
}
|
||||
|
||||
.boldy {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
@ -243,17 +243,33 @@
|
||||
<div id="div_slot" class="tab-pane fade tab-pane-table">
|
||||
<div class="alert alert-info">
|
||||
Zur Berechnung der täglichen Überstunden müssen Slots angelegt werden, die definieren, an welchen Tagen wieviele Stunden zu arbeiten ist.
|
||||
Urlaub und Arbeitsbefreiung können durch das Entfernen des jeweiligen Slots ermöglicht werden.
|
||||
Die Überstundenberechnung hängt von der Vollständigkeit der vorhandenen Slots ab; fehlen Slots, wird die Arbeitszeit jener Tage nicht eingerechnet.
|
||||
Die Überstundenberechnung hängt von der Vollständigkeit der vorhandenen Slots ab; fehlen Slots, wird die Arbeitszeit jener Tage nicht eingerechnet.<br />
|
||||
Hier werden nur die Slots für diesen Monat angezeigt.
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="row row-weekday">
|
||||
<div class="col">Sonntag</div>
|
||||
<div class="col">Montag</div>
|
||||
<div class="col">Dienstag</div>
|
||||
<div class="col">Mittwoch</div>
|
||||
<div class="col">Donnerstag</div>
|
||||
<div class="col">Freitag</div>
|
||||
<div class="col">Samstag</div>
|
||||
</div>
|
||||
<div class="row row-weekday">
|
||||
<div class="col slot_badge" th:each="o : ${slotOffset}"></div>
|
||||
<div class="col slot_badge" th:each="s : ${slots}">
|
||||
<span class="slot_badge_left" th:text="${#temporals.format(s.day, 'EEE, dd.MM.yyyy')}"></span><a th:href="@{/done/slot/{id}(id=${s.id})}" class="slot_badge_middle"><i class="fas fa-pencil"></i></a><span class="slot_badge_right" th:text="${s.printTime()}"></span>
|
||||
<span class="slot_badge_left" th:text="${#temporals.format(s.day, 'dd.MM.')}">
|
||||
</span><a th:href="@{/done/slot/{id}(id=${s.id})}" class="slot_badge_middle" th:if="${s.id}">
|
||||
<i class="fas fa-pencil"></i>
|
||||
</a><a th:href="@{/done/slot/add?day=${d}(d=${s.day})}" class="slot_badge_middle" th:unless="${s.id}">
|
||||
<i class="fas fa-plus"></i>
|
||||
</a>
|
||||
<span class="slot_badge_right boldy" th:text="${s.printTime()}" th:if="${s.id}"></span>
|
||||
<span class="slot_badge_right" th:unless="${s.id}"> --:-- </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
TODO: nur die Slots dieses Monats anzeigen, damit die Ladezeit nicht unnötig belastet wird
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
Reference in New Issue
Block a user