finetuning

This commit is contained in:
Jörg Henke
2026-01-20 14:37:13 +01:00
parent 9568e77f52
commit c408e4d693
8 changed files with 79 additions and 16 deletions

View File

@@ -30,7 +30,7 @@ dependencies {
implementation 'org.webjars:font-awesome:7.1.0' implementation 'org.webjars:font-awesome:7.1.0'
implementation 'org.webjars:jquery:3.7.1' implementation 'org.webjars:jquery:3.7.1'
implementation 'org.webjars:popper.js:2.11.7' implementation 'org.webjars:popper.js:2.11.7'
implementation 'org.webjars:datatables:2.3.5' implementation 'org.webjars:datatables:2.3.6'
implementation 'org.webjars:jquery-ui:1.14.1' implementation 'org.webjars:jquery-ui:1.14.1'
implementation 'org.webjars.npm:fullcalendar:6.1.19' implementation 'org.webjars.npm:fullcalendar:6.1.19'

View File

@@ -1,12 +1,15 @@
package de.jottyfan.timetrack.modules.projectmanagement; package de.jottyfan.timetrack.modules.projectmanagement;
import static de.jottyfan.timetrack.db.project.Tables.T_PROJECT;
import static de.jottyfan.timetrack.db.project.Tables.T_APP; import static de.jottyfan.timetrack.db.project.Tables.T_APP;
import static de.jottyfan.timetrack.db.project.Tables.T_BUNDLE; import static de.jottyfan.timetrack.db.project.Tables.T_BUNDLE;
import static de.jottyfan.timetrack.db.project.Tables.T_PROJECT;
import static de.jottyfan.timetrack.db.project.Tables.T_WORKPACKAGE; import static de.jottyfan.timetrack.db.project.Tables.T_WORKPACKAGE;
import static de.jottyfan.timetrack.db.project.Tables.T_WORKPACKAGE_APP; import static de.jottyfan.timetrack.db.project.Tables.T_WORKPACKAGE_APP;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -19,6 +22,7 @@ import org.jooq.Record7;
import org.jooq.Record8; import org.jooq.Record8;
import org.jooq.SelectConditionStep; import org.jooq.SelectConditionStep;
import org.jooq.SelectHavingStep; import org.jooq.SelectHavingStep;
import org.jooq.SelectSeekStep1;
import org.jooq.impl.DSL; import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -101,7 +105,36 @@ public class AppRepository {
* @return the list; an empty list at least * @return the list; an empty list at least
*/ */
public List<WorkpackageBean> getWorkpackages() { public List<WorkpackageBean> getWorkpackages() {
return jooq.selectFrom(T_WORKPACKAGE).fetchInto(WorkpackageBean.class); SelectSeekStep1<Record8<Integer, String, String, Integer, String, String, LocalDate, String>, String> sql = jooq
// @formatter:off
.select(T_WORKPACKAGE.PK_WORKPACKAGE,
T_WORKPACKAGE.NAME,
T_WORKPACKAGE.DESCRIPTION,
T_WORKPACKAGE.FK_PROJECT,
T_WORKPACKAGE.CONTRACT_URL,
T_WORKPACKAGE.MILESTONE_URL,
T_WORKPACKAGE.PLANNED_DUEDATE,
T_PROJECT.NAME)
.from(T_WORKPACKAGE)
.leftJoin(T_PROJECT).on(T_PROJECT.PK_PROJECT.eq(T_WORKPACKAGE.FK_PROJECT))
.orderBy(T_WORKPACKAGE.NAME);
// @formatter:off
List<WorkpackageBean> list = new ArrayList<>();
Iterator<Record8<Integer, String, String, Integer, String, String, LocalDate, String>> i = sql.fetch().iterator();
while (i.hasNext()) {
Record8<Integer, String, String, Integer, String, String, LocalDate, String> r = i.next();
WorkpackageBean bean = new WorkpackageBean();
bean.setPkWorkpackage(r.get(T_WORKPACKAGE.PK_WORKPACKAGE));
bean.setName(r.get(T_WORKPACKAGE.NAME));
bean.setDescription(r.get(T_WORKPACKAGE.DESCRIPTION));
bean.setFkProject(r.get(T_WORKPACKAGE.FK_PROJECT));
bean.setContractUrl(r.get(T_WORKPACKAGE.CONTRACT_URL));
bean.setMilestoneUrl(r.get(T_WORKPACKAGE.MILESTONE_URL));
bean.setPlannedDuedate(r.get(T_WORKPACKAGE.PLANNED_DUEDATE));
bean.setProjectName(r.get(T_PROJECT.NAME));
list.add(bean);
}
return list;
} }
/** /**
@@ -230,7 +263,7 @@ public class AppRepository {
.execute(); .execute();
// @formatter:on // @formatter:on
} }
/** /**
* insert the bean * insert the bean
* *

View File

@@ -22,6 +22,8 @@ public class WorkpackageBean implements Serializable {
private String milestoneUrl; private String milestoneUrl;
private String contractUrl; private String contractUrl;
private LocalDate plannedDuedate; private LocalDate plannedDuedate;
private String projectName;
public static final WorkpackageBean of(TWorkpackageRecord r) { public static final WorkpackageBean of(TWorkpackageRecord r) {
WorkpackageBean bean = new WorkpackageBean(); WorkpackageBean bean = new WorkpackageBean();
@@ -142,4 +144,18 @@ public class WorkpackageBean implements Serializable {
public void setPlannedDuedate(LocalDate plannedDuedate) { public void setPlannedDuedate(LocalDate plannedDuedate) {
this.plannedDuedate = plannedDuedate; this.plannedDuedate = plannedDuedate;
} }
/**
* @return the projectName
*/
public String getProjectName() {
return projectName;
}
/**
* @param projectName the projectName to set
*/
public void setProjectName(String projectName) {
this.projectName = projectName;
}
} }

View File

@@ -6,7 +6,8 @@
<title>Timetrack</title> <title>Timetrack</title>
<link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/5.3.8/css/bootstrap.min.css}" /> <link rel="stylesheet" type="text/css" th:href="@{/webjars/bootstrap/5.3.8/css/bootstrap.min.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/2.3.5/css/dataTables.dataTables.min.css}" /> <link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/2.3.6/css/dataTables.dataTables.min.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/webjars/datatables/2.3.6/css/dataTables.bootstrap5.min.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/webjars/font-awesome/7.1.0/css/all.min.css}" /> <link rel="stylesheet" type="text/css" th:href="@{/webjars/font-awesome/7.1.0/css/all.min.css}" />
<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}"> <link rel="stylesheet" type="text/css" th:href="@{/css/style.css}">
<link rel="stylesheet" type="text/css" th:href="@{/public/dynamicstyle.css}"> <link rel="stylesheet" type="text/css" th:href="@{/public/dynamicstyle.css}">
@@ -15,7 +16,9 @@
<script type="text/javascript" th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script> <script type="text/javascript" th:src="@{/webjars/jquery/3.7.1/jquery.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/bootstrap/5.3.8/js/bootstrap.bundle.min.js}"></script> <script type="text/javascript" th:src="@{/webjars/bootstrap/5.3.8/js/bootstrap.bundle.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/datatables/2.3.5/js/dataTables.dataTables.min.js}"></script> <script type="text/javascript" th:src="@{/webjars/datatables/2.3.6/js/dataTables.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/datatables/2.3.6/js/dataTables.dataTables.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/datatables/2.3.6/js/dataTables.bootstrap5.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/fullcalendar/6.1.19/index.global.min.js}"></script> <script type="text/javascript" th:src="@{/webjars/fullcalendar/6.1.19/index.global.min.js}"></script>
<script type="text/javascript" th:src="@{/js/helper.js}"></script> <script type="text/javascript" th:src="@{/js/helper.js}"></script>
<script type="text/javascript" th:src="@{/js/clock.js}"></script> <script type="text/javascript" th:src="@{/js/clock.js}"></script>

View File

@@ -7,7 +7,7 @@
<font layout:fragment="title">Projekt</font> <font layout:fragment="title">Projekt</font>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"> <li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<a class="nav-link btn btn-secondary btn-white-text" th:href="@{/projectmanagement}">zur Projektübersicht</a> <a class="btn btn-outline-secondary" th:href="@{/projectmanagement}">zur Projektübersicht</a>
</li> </li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
@@ -39,7 +39,7 @@
</div> </div>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<table class="table table-striped"> <table name="table" class="table table-striped">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
@@ -49,13 +49,23 @@
</thead> </thead>
<tbody> <tbody>
<tr th:each="p : ${workpackages}"> <tr th:each="p : ${workpackages}">
<td><input type="checkbox" th:checked="${p.isIn(linked)}" /> <a th:href="@{/projectmanagement/workpackage/{w}/apps(w=${p.pkWorkpackage})}" th:text="${p.name}"></a></td> <td><input type="checkbox" th:checked="${p.isIn(linked)}" /> <a th:href="@{/projectmanagement/workpackage/{w}/apps(w=${p.pkWorkpackage})}" th:text="${p.name}" th:title="${p.projectName}"></a></td>
<td th:text="${p.description}"></td> <td th:text="${p.description}"></td>
<td><a th:href="@{/projectmanagement/workpackage/{w}/app/{a}/toggle(w=${p.pkWorkpackage},a=${app.pkApp})}" class="btn btn-outline-secondary"> <td><a th:href="@{/projectmanagement/workpackage/{w}/app/{a}/toggle(w=${p.pkWorkpackage},a=${app.pkApp})}" class="btn btn-outline-secondary">
<span th:if="${p.isIn(linked)}">rausschmeißen</span> <span th:unless="${p.isIn(linked)}">zuweisen</span> <span th:if="${p.isIn(linked)}">rausschmeißen</span> <span th:unless="${p.isIn(linked)}">zuweisen</span>
</a></td> </a></td>
</tr> </tr>
</table> </table>
<script type="text/javascript">
$(document).ready(function() {
var localeUrl = '[[@{/js/dataTables/de.json}]]';
$("#table").DataTable({
"language" : {
"url" : localeUrl
}
});
});
</script>
</div> </div>
</div> </div>
</main> </main>

View File

@@ -7,8 +7,8 @@
<font layout:fragment="title">Projekte</font> <font layout:fragment="title">Projekte</font>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"> <li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<a class="btn btn-outline-success" th:href="@{/projectmanagement/project/add}">Neues Projekt anlegen</a>
<a class="btn btn-outline-secondary" th:href="@{/projectmanagement/download}">Export</a> <a class="btn btn-outline-secondary" th:href="@{/projectmanagement/download}">Export</a>
<a class="btn btn-outline-secondary" th:href="@{/projectmanagement/apps}">alle Apps</a>
</li> </li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
@@ -32,10 +32,11 @@
</div> </div>
<div class="col-sm-12 col-md-3 col-lg-2 dashboardcard"> <div class="col-sm-12 col-md-3 col-lg-2 dashboardcard">
<div class="card"> <div class="card">
<div class="card-header">Alles</div> <div class="card-header">
<div class="card-body"> <a class="btn btn-outline-secondary" th:href="@{/projectmanagement/project/add}">Projekt anlegen</a>
<a th:href="@{/projectmanagement/apps}">alle apps auflisten</a>
</div> </div>
<div class="card-body"></div>
<div class="card-footer"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,7 +7,7 @@
<font layout:fragment="title">Projekt</font> <font layout:fragment="title">Projekt</font>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"> <li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<a class="nav-link btn btn-secondary btn-white-text" th:href="@{/projectmanagement}">abbrechen</a> <a class="btn btn-outline-secondary" th:href="@{/projectmanagement}">abbrechen</a>
</li> </li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
@@ -30,7 +30,7 @@
</div> </div>
<div class="col-2">Geldgeber</div> <div class="col-2">Geldgeber</div>
<div class="col-10"> <div class="col-10">
<select th:field="*{fkFunder}" class="select-field"> <select th:field="*{fkFunder}" class="form-select">
<option value="" label="--- bitte wählen ---" /> <option value="" label="--- bitte wählen ---" />
<option th:each="f : ${funders}" th:label="${f.name}" th:value="${f.pkFunder}" /> <option th:each="f : ${funders}" th:label="${f.name}" th:value="${f.pkFunder}" />
</select> </select>

View File

@@ -7,7 +7,7 @@
<font layout:fragment="title">Workpackage</font> <font layout:fragment="title">Workpackage</font>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"> <li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<a class="nav-link btn btn-secondary btn-white-text" th:href="@{/projectmanagement}">abbrechen</a> <a class="btn btn-outline-secondary" th:href="@{/projectmanagement}">abbrechen</a>
</li> </li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">