prepared favorites
This commit is contained in:
@ -7,7 +7,7 @@ plugins {
|
|||||||
apply plugin: 'io.spring.dependency-management'
|
apply plugin: 'io.spring.dependency-management'
|
||||||
|
|
||||||
group = 'de.jottyfan'
|
group = 'de.jottyfan'
|
||||||
version = '1.3.9'
|
version = '1.4.0'
|
||||||
|
|
||||||
description = """timetrack"""
|
description = """timetrack"""
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-test'
|
implementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
|
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'
|
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.context.annotation.Configuration;
|
||||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
|
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.component.OAuth2Provider;
|
||||||
import de.jottyfan.timetrack.modules.done.DoneBean;
|
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.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 de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
|
@ -37,9 +37,11 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
|||||||
private Integer fkModule;
|
private Integer fkModule;
|
||||||
private Integer fkJob;
|
private Integer fkJob;
|
||||||
private Integer fkBilling;
|
private Integer fkBilling;
|
||||||
|
private Boolean isFavorite;
|
||||||
|
|
||||||
public DoneBean() {
|
public DoneBean() {
|
||||||
this.day = null;
|
this.day = null;
|
||||||
|
isFavorite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DoneBean(TDoneRecord r, Map<Integer, VProjectRecord> projectMap, Map<Integer, VModuleRecord> moduleMap,
|
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.fkModule = module.getPk();
|
||||||
this.fkJob = activity.getPk();
|
this.fkJob = activity.getPk();
|
||||||
this.fkBilling = billing.getPk();
|
this.fkBilling = billing.getPk();
|
||||||
|
isFavorite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String nullable(Object o, String format) {
|
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(",module=").append(module == null ? "" : module.getName());
|
||||||
buf.append(",activity=").append(activity == null ? "" : activity.getName());
|
buf.append(",activity=").append(activity == null ? "" : activity.getName());
|
||||||
buf.append(",billing=").append(billing == null ? "" : billing.getName());
|
buf.append(",billing=").append(billing == null ? "" : billing.getName());
|
||||||
|
buf.append(",isFavorite=").append(isFavorite);
|
||||||
buf.append("}");
|
buf.append("}");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
@ -383,4 +387,18 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
|||||||
public void setFkBilling(Integer fkBilling) {
|
public void setFkBilling(Integer fkBilling) {
|
||||||
this.fkBilling = 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.component.OAuth2Provider;
|
||||||
import de.jottyfan.timetrack.modules.CommonController;
|
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 de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
@ -62,6 +64,7 @@ public class DoneController extends CommonController {
|
|||||||
model.addAttribute("jobList", doneService.getJobs(false));
|
model.addAttribute("jobList", doneService.getJobs(false));
|
||||||
model.addAttribute("billingList", doneService.getBillings(false));
|
model.addAttribute("billingList", doneService.getBillings(false));
|
||||||
model.addAttribute("theme", profileService.getTheme(username));
|
model.addAttribute("theme", profileService.getTheme(username));
|
||||||
|
model.addAttribute("favorites", doneService.getFavorites(username));
|
||||||
return "done/list";
|
return "done/list";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,4 +160,18 @@ public class DoneController extends CommonController {
|
|||||||
Integer amount = doneService.doDelete(id);
|
Integer amount = doneService.doDelete(id);
|
||||||
return amount.equals(1) ? "redirect:/done/list" : "redirect:/" + toItem(id, model);
|
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;
|
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_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_BILLING;
|
||||||
import static de.jottyfan.timetrack.db.done.Tables.V_JOB;
|
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_MODULE;
|
||||||
@ -20,8 +21,11 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.jooq.DSLContext;
|
import org.jooq.DSLContext;
|
||||||
import org.jooq.DeleteConditionStep;
|
import org.jooq.DeleteConditionStep;
|
||||||
|
import org.jooq.InsertReturningStep;
|
||||||
import org.jooq.InsertValuesStep7;
|
import org.jooq.InsertValuesStep7;
|
||||||
|
import org.jooq.Record5;
|
||||||
import org.jooq.Record7;
|
import org.jooq.Record7;
|
||||||
|
import org.jooq.Record8;
|
||||||
import org.jooq.Result;
|
import org.jooq.Result;
|
||||||
import org.jooq.SelectConditionStep;
|
import org.jooq.SelectConditionStep;
|
||||||
import org.jooq.SelectLimitPercentStep;
|
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.TDone;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.TDoneRecord;
|
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.VBillingRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
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.VModuleRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||||
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
|
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
|
||||||
import de.jottyfan.timetrack.help.LocalDateHelper;
|
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)
|
private List<DoneBean> getAllOfInterval(LocalDateTime start, LocalDateTime end, Integer userId)
|
||||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
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
|
// @formatter:off
|
||||||
.select(T_DONE.PK,
|
.select(T_DONE.PK,
|
||||||
T_DONE.TIME_FROM,
|
T_DONE.TIME_FROM,
|
||||||
@ -240,8 +246,14 @@ public class DoneGateway {
|
|||||||
T_DONE.FK_PROJECT,
|
T_DONE.FK_PROJECT,
|
||||||
T_DONE.FK_MODULE,
|
T_DONE.FK_MODULE,
|
||||||
T_DONE.FK_JOB,
|
T_DONE.FK_JOB,
|
||||||
T_DONE.FK_BILLING)
|
T_DONE.FK_BILLING,
|
||||||
|
T_FAVORITE.PK_FAVORITE)
|
||||||
.from(T_DONE)
|
.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()))
|
.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.TIME_UNTIL.between(start, end).or(T_DONE.TIME_UNTIL.isNull()))
|
||||||
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
|
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
|
||||||
@ -252,7 +264,7 @@ public class DoneGateway {
|
|||||||
Map<Integer, VModuleRecord> moduleMap = getModuleMap();
|
Map<Integer, VModuleRecord> moduleMap = getModuleMap();
|
||||||
Map<Integer, VJobRecord> jobMap = getJobMap();
|
Map<Integer, VJobRecord> jobMap = getJobMap();
|
||||||
Map<Integer, VBillingRecord> billingMap = getBillingMap();
|
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();
|
DoneBean bean = new DoneBean();
|
||||||
bean.setPk(r.get(T_DONE.PK));
|
bean.setPk(r.get(T_DONE.PK));
|
||||||
bean.setTimeFrom(r.get(T_DONE.TIME_FROM));
|
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.setModule(moduleMap.get(r.get(T_DONE.FK_MODULE)));
|
||||||
bean.setActivity(jobMap.get(r.get(T_DONE.FK_JOB)));
|
bean.setActivity(jobMap.get(r.get(T_DONE.FK_JOB)));
|
||||||
bean.setBilling(billingMap.get(r.get(T_DONE.FK_BILLING)));
|
bean.setBilling(billingMap.get(r.get(T_DONE.FK_BILLING)));
|
||||||
|
bean.setIsFavorite(r.get(T_FAVORITE.PK_FAVORITE) != null);
|
||||||
list.add(bean);
|
list.add(bean);
|
||||||
}
|
}
|
||||||
list.sort((o1, o2) -> o1 == null ? 0 : o1.compareTo(o2));
|
list.sort((o1, o2) -> o1 == null ? 0 : o1.compareTo(o2));
|
||||||
@ -436,4 +449,72 @@ public class DoneGateway {
|
|||||||
LOGGER.debug(sql.toString());
|
LOGGER.debug(sql.toString());
|
||||||
return sql.execute();
|
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.VJobRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
||||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||||
|
import de.jottyfan.timetrack.modules.done.model.FavoriteBean;
|
||||||
import de.jottyfan.timetrack.modules.note.NoteService;
|
import de.jottyfan.timetrack.modules.note.NoteService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,4 +195,28 @@ public class DoneService {
|
|||||||
bean.setTimeUntil(null);
|
bean.setTimeUntil(null);
|
||||||
return this.doUpsert(bean, username);
|
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.db.done.tables.records.TJobRecord;
|
||||||
import de.jottyfan.timetrack.modules.CommonController;
|
import de.jottyfan.timetrack.modules.CommonController;
|
||||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
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 de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
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.io.Serializable;
|
||||||
import java.time.LocalDate;
|
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.io.Serializable;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -6,6 +6,8 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.timetrack.modules.done.DoneBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author henkej
|
* @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.db.done.tables.records.TModuleRecord;
|
||||||
import de.jottyfan.timetrack.modules.CommonController;
|
import de.jottyfan.timetrack.modules.CommonController;
|
||||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
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 de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
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.db.done.tables.records.TProjectRecord;
|
||||||
import de.jottyfan.timetrack.modules.CommonController;
|
import de.jottyfan.timetrack.modules.CommonController;
|
||||||
import de.jottyfan.timetrack.modules.done.DoneController;
|
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 de.jottyfan.timetrack.modules.profile.ProfileService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
|
@ -391,3 +391,6 @@ body {
|
|||||||
background-image: linear-gradient(to right bottom, #99c1f1, #1a5f64);
|
background-image: linear-gradient(to right bottom, #99c1f1, #1a5f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.golden {
|
||||||
|
color: darkgoldenrod;
|
||||||
|
}
|
@ -64,7 +64,16 @@
|
|||||||
<th>Modul</th>
|
<th>Modul</th>
|
||||||
<th>Aufgabe</th>
|
<th>Aufgabe</th>
|
||||||
<th>Abrechnung</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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -83,7 +92,10 @@
|
|||||||
th:if="${done.billing != null}"></span></td>
|
th:if="${done.billing != null}"></span></td>
|
||||||
<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/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>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
|
Reference in New Issue
Block a user