prepared favorites
This commit is contained in:
@ -7,7 +7,7 @@ plugins {
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
|
||||
group = 'de.jottyfan'
|
||||
version = '1.3.9'
|
||||
version = '1.4.0'
|
||||
|
||||
description = """timetrack"""
|
||||
|
||||
@ -48,7 +48,7 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
||||
implementation 'de.jottyfan:timetrackjooq:0.1.2'
|
||||
implementation 'de.jottyfan:timetrackjooq:0.1.3'
|
||||
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.2.1'
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
||||
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -16,9 +16,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.modules.done.DoneBean;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.DoneService;
|
||||
import de.jottyfan.timetrack.modules.done.SummaryBean;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.SummaryBean;
|
||||
import de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.servlet.ServletException;
|
||||
|
@ -37,9 +37,11 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
private Integer fkModule;
|
||||
private Integer fkJob;
|
||||
private Integer fkBilling;
|
||||
private Boolean isFavorite;
|
||||
|
||||
public DoneBean() {
|
||||
this.day = null;
|
||||
isFavorite = false;
|
||||
}
|
||||
|
||||
public DoneBean(TDoneRecord r, Map<Integer, VProjectRecord> projectMap, Map<Integer, VModuleRecord> moduleMap,
|
||||
@ -56,6 +58,7 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
this.fkModule = module.getPk();
|
||||
this.fkJob = activity.getPk();
|
||||
this.fkBilling = billing.getPk();
|
||||
isFavorite = false;
|
||||
}
|
||||
|
||||
private final String nullable(Object o, String format) {
|
||||
@ -94,6 +97,7 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
buf.append(",module=").append(module == null ? "" : module.getName());
|
||||
buf.append(",activity=").append(activity == null ? "" : activity.getName());
|
||||
buf.append(",billing=").append(billing == null ? "" : billing.getName());
|
||||
buf.append(",isFavorite=").append(isFavorite);
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
@ -383,4 +387,18 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
public void setFkBilling(Integer fkBilling) {
|
||||
this.fkBilling = fkBilling;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isFavorite
|
||||
*/
|
||||
public Boolean getIsFavorite() {
|
||||
return isFavorite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isFavorite the isFavorite to set
|
||||
*/
|
||||
public void setIsFavorite(Boolean isFavorite) {
|
||||
this.isFavorite = isFavorite;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
|
||||
import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.SummaryBean;
|
||||
import de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
@ -62,6 +64,7 @@ public class DoneController extends CommonController {
|
||||
model.addAttribute("jobList", doneService.getJobs(false));
|
||||
model.addAttribute("billingList", doneService.getBillings(false));
|
||||
model.addAttribute("theme", profileService.getTheme(username));
|
||||
model.addAttribute("favorites", doneService.getFavorites(username));
|
||||
return "done/list";
|
||||
}
|
||||
|
||||
@ -157,4 +160,18 @@ public class DoneController extends CommonController {
|
||||
Integer amount = doneService.doDelete(id);
|
||||
return amount.equals(1) ? "redirect:/done/list" : "redirect:/" + toItem(id, model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/favorize/{id}")
|
||||
public String favorize(@PathVariable Integer id) {
|
||||
doneService.favorize(id);
|
||||
return "redirect:/done/list";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/unfavorize/{id}")
|
||||
public String unfavorize(@PathVariable Integer id) {
|
||||
doneService.unfavorize(id);
|
||||
return "redirect:/done/list";
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package de.jottyfan.timetrack.modules.done;
|
||||
|
||||
import static de.jottyfan.timetrack.db.done.Tables.T_DONE;
|
||||
import static de.jottyfan.timetrack.db.done.Tables.T_FAVORITE;
|
||||
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;
|
||||
@ -20,8 +21,11 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DeleteConditionStep;
|
||||
import org.jooq.InsertReturningStep;
|
||||
import org.jooq.InsertValuesStep7;
|
||||
import org.jooq.Record5;
|
||||
import org.jooq.Record7;
|
||||
import org.jooq.Record8;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.SelectLimitPercentStep;
|
||||
@ -32,12 +36,14 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.TDone;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TFavoriteRecord;
|
||||
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;
|
||||
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
|
||||
import de.jottyfan.timetrack.help.LocalDateHelper;
|
||||
import de.jottyfan.timetrack.modules.done.model.FavoriteBean;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -232,7 +238,7 @@ public class DoneGateway {
|
||||
*/
|
||||
private List<DoneBean> getAllOfInterval(LocalDateTime start, LocalDateTime end, Integer userId)
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
SelectConditionStep<Record7<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer>> sql = getJooq()
|
||||
SelectConditionStep<Record8<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer, Integer>> sql = getJooq()
|
||||
// @formatter:off
|
||||
.select(T_DONE.PK,
|
||||
T_DONE.TIME_FROM,
|
||||
@ -240,8 +246,14 @@ public class DoneGateway {
|
||||
T_DONE.FK_PROJECT,
|
||||
T_DONE.FK_MODULE,
|
||||
T_DONE.FK_JOB,
|
||||
T_DONE.FK_BILLING)
|
||||
T_DONE.FK_BILLING,
|
||||
T_FAVORITE.PK_FAVORITE)
|
||||
.from(T_DONE)
|
||||
.leftJoin(T_FAVORITE).on(T_FAVORITE.FK_LOGIN.eq(T_DONE.FK_LOGIN))
|
||||
.and(T_FAVORITE.FK_PROJECT.eq(T_DONE.FK_PROJECT).or(T_FAVORITE.FK_PROJECT.isNull().and(T_DONE.FK_PROJECT.isNull())))
|
||||
.and(T_FAVORITE.FK_MODULE.eq(T_DONE.FK_MODULE).or(T_FAVORITE.FK_MODULE.isNull().and(T_DONE.FK_MODULE.isNull())))
|
||||
.and(T_FAVORITE.FK_JOB.eq(T_DONE.FK_JOB).or(T_FAVORITE.FK_JOB.isNull().and(T_DONE.FK_JOB.isNull())))
|
||||
.and(T_FAVORITE.FK_BILLING.eq(T_DONE.FK_BILLING).or(T_FAVORITE.FK_BILLING.isNull().and(T_DONE.FK_BILLING.isNull())))
|
||||
.where(T_DONE.TIME_FROM.between(start, end).or(T_DONE.TIME_FROM.isNull()))
|
||||
.and(T_DONE.TIME_UNTIL.between(start, end).or(T_DONE.TIME_UNTIL.isNull()))
|
||||
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
|
||||
@ -252,7 +264,7 @@ public class DoneGateway {
|
||||
Map<Integer, VModuleRecord> moduleMap = getModuleMap();
|
||||
Map<Integer, VJobRecord> jobMap = getJobMap();
|
||||
Map<Integer, VBillingRecord> billingMap = getBillingMap();
|
||||
for (Record7<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer> r : sql.fetch()) {
|
||||
for (Record8<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer, Integer> r : sql.fetch()) {
|
||||
DoneBean bean = new DoneBean();
|
||||
bean.setPk(r.get(T_DONE.PK));
|
||||
bean.setTimeFrom(r.get(T_DONE.TIME_FROM));
|
||||
@ -262,6 +274,7 @@ public class DoneGateway {
|
||||
bean.setModule(moduleMap.get(r.get(T_DONE.FK_MODULE)));
|
||||
bean.setActivity(jobMap.get(r.get(T_DONE.FK_JOB)));
|
||||
bean.setBilling(billingMap.get(r.get(T_DONE.FK_BILLING)));
|
||||
bean.setIsFavorite(r.get(T_FAVORITE.PK_FAVORITE) != null);
|
||||
list.add(bean);
|
||||
}
|
||||
list.sort((o1, o2) -> o1 == null ? 0 : o1.compareTo(o2));
|
||||
@ -436,4 +449,72 @@ public class DoneGateway {
|
||||
LOGGER.debug(sql.toString());
|
||||
return sql.execute();
|
||||
}
|
||||
|
||||
public void favorize(Integer id) {
|
||||
InsertReturningStep<TFavoriteRecord> sql = getJooq()
|
||||
// @formatter:off
|
||||
.insertInto(T_FAVORITE,
|
||||
T_FAVORITE.FK_LOGIN,
|
||||
T_FAVORITE.FK_PROJECT,
|
||||
T_FAVORITE.FK_MODULE,
|
||||
T_FAVORITE.FK_JOB,
|
||||
T_FAVORITE.FK_BILLING)
|
||||
.select(getJooq()
|
||||
.select(T_DONE.FK_LOGIN, T_DONE.FK_PROJECT, T_DONE.FK_MODULE, T_DONE.FK_JOB, T_DONE.FK_BILLING)
|
||||
.from(T_DONE)
|
||||
.where(T_DONE.PK.eq(id)))
|
||||
// TODO: create unique constraint
|
||||
/*
|
||||
.onConflict(T_FAVORITE.FK_LOGIN, T_FAVORITE.FK_PROJECT, T_FAVORITE.FK_MODULE, T_FAVORITE.FK_JOB, T_FAVORITE.FK_BILLING)
|
||||
.doNothing()*/
|
||||
;
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
sql.execute();
|
||||
}
|
||||
|
||||
public void unfavorize(Integer id) {
|
||||
DeleteConditionStep<TFavoriteRecord> sql = getJooq()
|
||||
// @formatter:off
|
||||
.deleteFrom(T_FAVORITE)
|
||||
.using(T_DONE)
|
||||
.where(T_FAVORITE.FK_LOGIN.eq(T_DONE.FK_LOGIN))
|
||||
.and(T_FAVORITE.FK_PROJECT.eq(T_DONE.FK_PROJECT).or(T_FAVORITE.FK_PROJECT.isNull().and(T_DONE.FK_PROJECT.isNull())))
|
||||
.and(T_FAVORITE.FK_MODULE.eq(T_DONE.FK_MODULE).or(T_FAVORITE.FK_MODULE.isNull().and(T_DONE.FK_MODULE.isNull())))
|
||||
.and(T_FAVORITE.FK_JOB.eq(T_DONE.FK_JOB).or(T_FAVORITE.FK_JOB.isNull().and(T_DONE.FK_JOB.isNull())))
|
||||
.and(T_FAVORITE.FK_BILLING.eq(T_DONE.FK_BILLING).or(T_FAVORITE.FK_BILLING.isNull().and(T_DONE.FK_BILLING.isNull())))
|
||||
.and(T_DONE.PK.eq(id));
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
sql.execute();
|
||||
}
|
||||
|
||||
public List<FavoriteBean> getFavorites(Integer login) {
|
||||
SelectConditionStep<Record5<Integer, String, String, String, String>> sql = getJooq()
|
||||
// @formatter:off
|
||||
.select(T_FAVORITE.PK_FAVORITE,
|
||||
V_PROJECT.NAME,
|
||||
V_MODULE.NAME,
|
||||
V_JOB.NAME,
|
||||
V_BILLING.NAME)
|
||||
.from(T_FAVORITE)
|
||||
.leftJoin(V_PROJECT).on(V_PROJECT.PK.eq(T_FAVORITE.FK_PROJECT))
|
||||
.leftJoin(V_MODULE).on(V_MODULE.PK.eq(T_FAVORITE.FK_MODULE))
|
||||
.leftJoin(V_JOB).on(V_JOB.PK.eq(T_FAVORITE.FK_JOB))
|
||||
.leftJoin(V_BILLING).on(V_BILLING.PK.eq(T_FAVORITE.FK_BILLING))
|
||||
.where(T_FAVORITE.FK_LOGIN.eq(login));
|
||||
// @formatter:on
|
||||
LOGGER.trace(sql);
|
||||
List<FavoriteBean> list = new ArrayList<>();
|
||||
for (Record5<Integer, String, String, String, String> r : sql.fetch()) {
|
||||
FavoriteBean bean = new FavoriteBean();
|
||||
bean.setFkFavorite(r.get(T_FAVORITE.PK_FAVORITE));
|
||||
bean.setProject(r.get(V_PROJECT.NAME));
|
||||
bean.setModule(r.get(V_MODULE.NAME));
|
||||
bean.setJob(r.get(V_JOB.NAME));
|
||||
bean.setBilling(r.get(V_BILLING.NAME));
|
||||
list.add(bean);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ 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;
|
||||
import de.jottyfan.timetrack.modules.done.model.FavoriteBean;
|
||||
import de.jottyfan.timetrack.modules.note.NoteService;
|
||||
|
||||
/**
|
||||
@ -181,7 +182,7 @@ public class DoneService {
|
||||
if (userId == null) {
|
||||
LOGGER.warn("userId of user {} is null", username);
|
||||
}
|
||||
return gw.getRecent( userId, recentCount);
|
||||
return gw.getRecent(userId, recentCount);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
@ -194,4 +195,28 @@ public class DoneService {
|
||||
bean.setTimeUntil(null);
|
||||
return this.doUpsert(bean, username);
|
||||
}
|
||||
|
||||
public void favorize(Integer id) {
|
||||
try {
|
||||
new DoneGateway(dsl).favorize(id);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void unfavorize(Integer id) {
|
||||
try {
|
||||
new DoneGateway(dsl).unfavorize(id);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public List<FavoriteBean> getFavorites(String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
Integer login = gw.getUserId(username);
|
||||
return gw.getFavorites(login);
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TJobRecord;
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package de.jottyfan.timetrack.modules.done;
|
||||
package de.jottyfan.timetrack.modules.done.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDate;
|
@ -0,0 +1,88 @@
|
||||
package de.jottyfan.timetrack.modules.done.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
public class FavoriteBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Integer fkFavorite;
|
||||
private String project;
|
||||
private String module;
|
||||
private String job;
|
||||
private String 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the billing
|
||||
*/
|
||||
public String getBilling() {
|
||||
return billing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param billing the billing to set
|
||||
*/
|
||||
public void setBilling(String billing) {
|
||||
this.billing = billing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fkFavorite
|
||||
*/
|
||||
public Integer getFkFavorite() {
|
||||
return fkFavorite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fkFavorite the fkFavorite to set
|
||||
*/
|
||||
public void setFkFavorite(Integer fkFavorite) {
|
||||
this.fkFavorite = fkFavorite;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package de.jottyfan.timetrack.modules.done;
|
||||
package de.jottyfan.timetrack.modules.done.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
@ -6,6 +6,8 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import de.jottyfan.timetrack.modules.done.DoneBean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
@ -13,7 +13,7 @@ import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TModuleRecord;
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
|
@ -13,7 +13,7 @@ import de.jottyfan.timetrack.component.OAuth2Provider;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
import de.jottyfan.timetrack.modules.CommonController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
||||
import de.jottyfan.timetrack.modules.done.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.done.model.DoneModel;
|
||||
import de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
|
||||
|
@ -391,3 +391,6 @@ body {
|
||||
background-image: linear-gradient(to right bottom, #99c1f1, #1a5f64);
|
||||
}
|
||||
|
||||
.golden {
|
||||
color: darkgoldenrod;
|
||||
}
|
@ -64,7 +64,16 @@
|
||||
<th>Modul</th>
|
||||
<th>Aufgabe</th>
|
||||
<th>Abrechnung</th>
|
||||
<th></th>
|
||||
<th>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Favoriten</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li th:each="f : ${favorites}">
|
||||
<a class="dropdown-item" href="#"><span th:text="${f.project} + ' ' + ${f.module} + ' ' + ${f.job}"></span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -83,7 +92,10 @@
|
||||
th:if="${done.billing != null}"></span></td>
|
||||
<td>
|
||||
<a class="btn-list" th:href="@{/done/copy/{id}(id=${done.pk})}" title="Aufgabe neu beginnen"><i class="fa fa-copy"></i></a>
|
||||
<a class="btn-list" th:href="@{/done/edit/{id}(id=${done.pk})}" title="Eintrag bearbeiten"><i class="fa fa-edit"></i></a></td>
|
||||
<a class="btn-list" th:href="@{/done/edit/{id}(id=${done.pk})}" title="Eintrag bearbeiten"><i class="fa fa-edit"></i></a>
|
||||
<a class="btn-list" th:href="@{/done/favorize/{id}(id=${done.pk})}" title="als Favorit speichern" th:if="${!done.isFavorite}"><i class="far fa-star golden"></i></a>
|
||||
<a class="btn-list" th:href="@{/done/unfavorize/{id}(id=${done.pk})}" title="Favoritenstatus entfernen" th:if="${done.isFavorite}"><i class="fas fa-star golden"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
|
Reference in New Issue
Block a user