layout optimization

This commit is contained in:
Jörg Henke
2022-05-04 17:19:31 +02:00
parent 2f51c93cfe
commit 8f29a6c788
14 changed files with 331 additions and 543 deletions

View File

@ -1,27 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0"> <?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="timetrack"> <wb-module deploy-name="timetrack">
<property name="context-root" value="timetrack"/> <property name="context-root" value="timetrack"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/resources"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/webapp"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/webapp"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="src/main/java"/>
<wb-resource deploy-path="/" source-path="src/main/webapp"/> <wb-resource deploy-path="/" source-path="src/main/webapp"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
</wb-module> </wb-module>
</project-modules> </project-modules>

View File

@ -0,0 +1,20 @@
package de.jottyfan.timetrack.spring.done;
import java.io.Serializable;
/**
*
* @author henkej
*
*/
public class DoneBean implements Serializable, Comparable<DoneBean>{
private static final long serialVersionUID = 1L;
@Override
public int compareTo(DoneBean bean) {
// TODO: implement
return 0;
}
}

View File

@ -0,0 +1,63 @@
package de.jottyfan.timetrack.spring.done;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
*
* @author henkej
*
*/
@Controller
public class DoneController {
private static final Logger LOGGER = LogManager.getLogger(DoneController.class);
private final HttpServletRequest request;
@Autowired
private IDoneService doneService;
@Autowired
public DoneController(HttpServletRequest request) {
this.request = request;
}
@RolesAllowed("timetrack_user")
@RequestMapping(value = "/done/list")
public String getList(Model model) {
List<DoneBean> list = doneService.getList();
model.addAttribute("doneList", list);
return "done/list";
}
@RolesAllowed("timetrack_user")
@RequestMapping(value = "/done/add", method = RequestMethod.GET)
public String toAdd(Model model) {
return toItem(null, model);
}
@RolesAllowed("timetrack_user")
@GetMapping("/done/edit/{id}")
public String toItem(@PathVariable Integer id, Model model) {
DoneBean bean = doneService.getBean(id);
if (bean == null) {
bean = new DoneBean(); // the add case
}
model.addAttribute("doneBean", bean);
// model.addAttribute("types", Arrays.asList(EnumNotetype.values()));
// model.addAttribute("categories", Arrays.asList(EnumCategory.values()));
return "done/item";
}
}

View File

@ -0,0 +1,18 @@
package de.jottyfan.timetrack.spring.done;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
/**
*
* @author henkej
*
*/
public interface IDoneService {
public List<DoneBean> getList();
public DoneBean getBean(Integer id);
public String getCurrentUser(HttpServletRequest request);
}

View File

@ -0,0 +1,57 @@
package de.jottyfan.timetrack.spring.done.impl;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.DSLContext;
import org.keycloak.KeycloakSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import de.jottyfan.timetrack.spring.done.DoneBean;
import de.jottyfan.timetrack.spring.done.IDoneService;
import de.jottyfan.timetrack.spring.note.NoteBean;
import de.jottyfan.timetrack.spring.note.impl.NoteGateway;
import de.jottyfan.timetrack.spring.note.impl.NoteService;
/**
*
* @author henkej
*
*/
@Service
@Transactional(transactionManager = "transactionManager")
public class DoneService implements IDoneService {
private static final Logger LOGGER = LogManager.getLogger(NoteService.class);
@Autowired
private DSLContext dsl;
@Override
public String getCurrentUser(HttpServletRequest request) {
KeycloakSecurityContext ksc = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
return ksc == null ? "" : ksc.getIdToken().getPreferredUsername();
}
@Override
public List<DoneBean> getList() {
// try {
// return new DoneGateway(dsl).getAll();
// } catch (Exception e) {
// LOGGER.error(e);
return new ArrayList<>();
// }
}
@Override
public DoneBean getBean(Integer id) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,91 +0,0 @@
package de.jottyfan.timetrack.modules.note;
import java.io.Serializable;
import java.time.LocalDateTime;
import de.jottyfan.timetrack.db.note.enums.EnumCategory;
import de.jottyfan.timetrack.db.note.enums.EnumNotetype;
import de.jottyfan.timetrack.modules.Bean;
/**
*
* @author henkej
*
*/
public class NoteBean implements Bean, Serializable
{
private static final long serialVersionUID = 1L;
private final Integer pk;
private String title;
private EnumCategory category;
private EnumNotetype type;
private String content;
private LocalDateTime lastchange;
public NoteBean(Integer pk)
{
super();
this.pk = pk;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public EnumCategory getCategory()
{
return category;
}
public void setCategory(EnumCategory category)
{
this.category = category;
}
public EnumNotetype getType()
{
return type;
}
public void setType(EnumNotetype type)
{
this.type = type;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
public LocalDateTime getLastchange()
{
return lastchange;
}
public void setLastchange(LocalDateTime lastchange)
{
this.lastchange = lastchange;
}
public static long getSerialversionuid()
{
return serialVersionUID;
}
public Integer getPk()
{
return pk;
}
}

View File

@ -1,104 +0,0 @@
package de.jottyfan.timetrack.modules.note;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import de.jooqfaces.JooqFacesContext;
import de.jottyfan.timetrack.help.Navigation;
import de.jottyfan.timetrack.help.Pages;
import de.jottyfan.timetrack.modules.ControlInterface;
/**
*
* @author henkej
*
*/
@Named
@RequestScoped
public class NoteControl extends Navigation implements ControlInterface, Serializable
{
private static final long serialVersionUID = 1L;
@Inject
@Named("noteModel")
private NoteModel model;
public String toStart()
{
return navigateTo(Pages.START);
}
public String toList()
{
boolean ready = model.init((JooqFacesContext) FacesContext.getCurrentInstance());
return ready ? navigateTo(Pages.NOTE_LIST) : "";
}
public String toItem(NoteBean bean)
{
model.setBean(bean);
return navigateTo(Pages.NOTE_ITEM);
}
public String toAdd()
{
return toItem(new NoteBean(null));
}
public String doAdd()
{
boolean ready = model.add((JooqFacesContext) FacesContext.getCurrentInstance());
return ready ? toList() : toItem(model.getBean());
}
public String doUpdate()
{
boolean ready = model.update((JooqFacesContext) FacesContext.getCurrentInstance());
return ready ? toList() : toItem(model.getBean());
}
public String doDelete()
{
boolean ready = model.delete((JooqFacesContext) FacesContext.getCurrentInstance());
return ready ? toList() : toItem(model.getBean());
}
/**
* trim s to maxLength; if s > maxLength, append ...
*
* @param s
* @param maxLength
* @return
*/
public String trimTo(String s, Integer maxLength)
{
if (s == null)
{
return s;
}
else
{
String firstLine = s.contains("\n") ? s.substring(0, s.indexOf("\n")) : s;
if (firstLine.length() > maxLength)
{
return firstLine.substring(0, maxLength).concat("...");
}
else if (s.contains("\n"))
{
return firstLine.concat("...");
}
else
{
return firstLine;
}
}
}
public Long getAmount() {
return model.getAmount((JooqFacesContext) FacesContext.getCurrentInstance());
}
}

View File

@ -1,125 +0,0 @@
package de.jottyfan.timetrack.modules.note;
import static de.jottyfan.timetrack.db.note.Tables.T_NOTE;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.CloseableDSLContext;
import org.jooq.DeleteConditionStep;
import org.jooq.InsertValuesStep4;
import org.jooq.Record;
import org.jooq.SelectJoinStep;
import org.jooq.UpdateConditionStep;
import org.jooq.exception.DataAccessException;
import de.jooqfaces.JooqFacesContext;
import de.jottyfan.timetrack.db.note.enums.EnumCategory;
import de.jottyfan.timetrack.db.note.enums.EnumNotetype;
import de.jottyfan.timetrack.db.note.tables.records.TNoteRecord;
import de.jottyfan.timetrack.modules.JooqGateway;
/**
*
* @author henkej
*
*/
public class NoteGateway extends JooqGateway {
private static final Logger LOGGER = LogManager.getLogger(NoteGateway.class);
public NoteGateway(JooqFacesContext facesContext) {
super(facesContext);
}
/**
* insert into t_note
*
* @param noteBean
* @throws DataAccessException
* @throws SQLException
* @throws ClassNotFoundException
* @returns amount of affected rows in db
*/
public void insert(NoteBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
try (CloseableDSLContext jooq = getJooq()) {
InsertValuesStep4<TNoteRecord, String, EnumCategory, EnumNotetype, String> sql = jooq
// @formatter:off
.insertInto(T_NOTE,
T_NOTE.TITLE,
T_NOTE.CATEGORY,
T_NOTE.NOTETYPE,
T_NOTE.CONTENT)
.values(bean.getTitle(), bean.getCategory(), bean.getType(), bean.getContent());
// @formatter:on
LOGGER.debug(sql.toString());
sql.execute();
}
}
/**
* update content of bean
*
* @param bean
* @throws DataAccessException
* @throws SQLException
* @throws ClassNotFoundException
*/
public void update(NoteBean bean) throws DataAccessException, ClassNotFoundException, SQLException {
try (CloseableDSLContext jooq = getJooq()) {
UpdateConditionStep<TNoteRecord> sql = jooq
// @formatter:off
.update(T_NOTE)
.set(T_NOTE.TITLE, bean.getTitle())
.set(T_NOTE.CONTENT, bean.getContent())
.where(T_NOTE.PK.eq(bean.getPk()));
// @formatter:on
LOGGER.debug(sql.toString());
sql.execute();
}
}
/**
* delete from t_note
*
* @param pk
* @throws DataAccessException
* @throws SQLException
* @throws ClassNotFoundException
*/
public void delete(Integer pk) throws DataAccessException, ClassNotFoundException, SQLException {
try (CloseableDSLContext jooq = getJooq()) {
DeleteConditionStep<TNoteRecord> sql = jooq.deleteFrom(T_NOTE).where(T_NOTE.PK.eq(pk));
LOGGER.debug(sql.toString());
sql.execute();
}
}
/**
* get all from t_note
*
* @return
* @throws DataAccessException
* @throws SQLException
* @throws ClassNotFoundException
*/
public List<NoteBean> getAll() throws DataAccessException, ClassNotFoundException, SQLException {
try (CloseableDSLContext jooq = getJooq()) {
SelectJoinStep<Record> sql = jooq.select().from(T_NOTE);
LOGGER.debug(sql.toString());
List<NoteBean> list = new ArrayList<>();
for (Record r : sql.fetch()) {
NoteBean bean = new NoteBean(r.get(T_NOTE.PK));
bean.setTitle(r.get(T_NOTE.TITLE));
bean.setCategory(r.get(T_NOTE.CATEGORY));
bean.setContent(r.get(T_NOTE.CONTENT));
bean.setType(r.get(T_NOTE.NOTETYPE));
bean.setLastchange(r.get(T_NOTE.LASTCHANGE));
list.add(bean);
}
return list;
}
}
}

View File

@ -1,112 +0,0 @@
package de.jottyfan.timetrack.modules.note;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import org.jooq.exception.DataAccessException;
import de.jooqfaces.JooqFacesContext;
import de.jottyfan.timetrack.db.note.Tables;
import de.jottyfan.timetrack.modules.Model;
/**
*
* @author henkej
*
*/
@Named
@SessionScoped
public class NoteModel implements Model, Serializable
{
private static final long serialVersionUID = 1L;
private List<NoteBean> beans;
private NoteBean bean;
public boolean init(JooqFacesContext facesContext)
{
try
{
beans = new NoteGateway(facesContext).getAll();
return true;
}
catch (DataAccessException | ClassNotFoundException | SQLException e)
{
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
return false;
}
}
public boolean add(JooqFacesContext facesContext)
{
try
{
new NoteGateway(facesContext).insert(bean);
return true;
}
catch (DataAccessException | ClassNotFoundException | SQLException e)
{
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
return false;
}
}
public boolean update(JooqFacesContext facesContext)
{
try
{
new NoteGateway(facesContext).update(bean);
return true;
}
catch (DataAccessException | ClassNotFoundException | SQLException e)
{
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
return false;
}
}
public boolean delete(JooqFacesContext facesContext)
{
try
{
new NoteGateway(facesContext).delete(bean.getPk());
return true;
}
catch (DataAccessException | ClassNotFoundException | SQLException e)
{
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
return false;
}
}
public Long getAmount(JooqFacesContext facesContext)
{
try {
return new NoteGateway(facesContext).getAmount(Tables.T_NOTE);
} catch (ClassNotFoundException | SQLException e) {
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "error", e.getMessage()));
return -1l;
}
}
@Override
public NoteBean getBean()
{
return bean;
}
public void setBean(NoteBean bean)
{
this.bean = bean;
}
public List<NoteBean> getBeans()
{
return beans;
}
}

View File

@ -7,6 +7,31 @@ body {
height: calc(100% - 56px); height: calc(100% - 56px);
} }
.titlemod {
font-weight: bolder;
color: darkcyan !important;
font-variant: small-caps;
}
.navlinkstyle {
color: black;
}
.navlinkstyle:hover {
color: #1a5fb4;
}
.navback {
background-color: ghostwhite;
}
.tabdivblurred {
padding: 8px;
padding-bottom: 0px;
background-color: rgba(255, 255, 255, 0.5);
height: calc(100% - 42px);
}
.float-right { .float-right {
float: right; float: right;
} }
@ -16,7 +41,7 @@ body {
} }
.glassy { .glassy {
background-color: rgba(1,1,1,0.1); background-color: rgba(0, 0, 0s, 0.1);
} }
.formpane { .formpane {
@ -47,7 +72,6 @@ body {
.page { .page {
width: 100%; width: 100%;
padding-bottom: 12px;
background-image: linear-gradient(to bottom, #99c1f1, #1a5f64) !important; background-image: linear-gradient(to bottom, #99c1f1, #1a5f64) !important;
} }

View File

@ -5,65 +5,60 @@
<title>Kontakte</title> <title>Kontakte</title>
</head> </head>
<body> <body>
<ul layout:fragment="title">
<li class="nav-item"><a class="nav-link titlemod">Kontakte</a></li>
</ul>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/contact/add}">Neuen <li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/contact/add}">Neuen
Kontakt anlegen</a></li> Kontakt anlegen</a></li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
<div class="accordion" id="acdiv"> <ul class="nav nav-tabs navback" role="tablist">
<div class="accordion-item glassy"> <li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_dashboard">Dashboard</a></li>
<h2 class="accordion-header" id="headingDashboard"> <li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_list">Liste</a></li>
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#dashboard" aria-expanded="true" </ul>
aria-controls="dashboard">Dashboard</button> <div class="tabdivblurred tab-content">
</h2> <div id="div_dashboard" class="tab-pane active">
<div id="dashboard" class="accordion-collapse collapse show" aria-labelledby="headingDashboard" data-bs-parent="#acdiv"> <div class="accordion-body">
<div class="accordion-body"> <div class="row row-cols-12 ro-cols-lg-4 ro-cols-md-3 ro-cols-sd-2 g-4" style="margin: 8px">
<div class="row row-cols-12 ro-cols-lg-4 ro-cols-md-3 ro-cols-sd-2 g-4" style="margin: 8px"> <div class="col" th:each="contact : ${contactList}">
<div class="col" th:each="contact : ${contactList}"> <div class="card text-dark bg-light shadow" style="width: 18rem">
<div class="card text-dark bg-light shadow" style="width: 18rem"> <div class="card-header text-center">
<div class="card-header text-center"> <font th:text="${contact.forename} + ' ' + ${contact.surname}" style="font-size: larger"></font>
<font th:text="${contact.forename} + ' ' + ${contact.surname}" style="font-size: larger"></font> </div>
</div> <div class="card-body">
<div class="card-body"> <div class="d-flex justify-content-center align-items-center">
<div class="d-flex justify-content-center align-items-center"> <span th:text="${contact.type} + ': ' + ${contact.contact}"></span> <a
<span th:text="${contact.type} + ': ' + ${contact.contact}"></span> <a th:href="@{/contact/edit/{id}(id=${contact.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;">
th:href="@{/contact/edit/{id}(id=${contact.pk})}" sec:authorize="hasRole('timetrack_user')" <i class="fa fa-edit"></i>
style="margin-left: 8px;"> <i class="fa fa-edit"></i> </a>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="accordion-item glassy"> </div>
<h2 class="accordion-header" id="headingTable"> <div id="div_list" class="tab-pane fade">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#list" <div class="accordion-body" style="background-color: white">
aria-expanded="false" aria-controls="list">Liste</button> <table class="table table-striped table-condensed">
</h2> <thead>
<div id="list" class="accordion-collapse collapse" aria-labelledby="headingTable" data-bs-parent="#acdiv"> <tr>
<div class="accordion-body" style="background-color: white"> <th>Vorname</th>
<table class="table table-striped table-condensed"> <th>Nachname</th>
<thead> <th>Kontakt</th>
<tr> <th>Typ</th>
<th>Vorname</th> </tr>
<th>Nachname</th> </thead>
<th>Kontakt</th> <tbody>
<th>Typ</th> <tr th:each="contact : ${contactList}">
</tr> <td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.forename}"></span></a></td>
</thead> <td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.surname}"></span></a></td>
<tbody> <td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.contact}"></span></a></td>
<tr th:each="contact : ${contactList}"> <td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.type}"></span></a></td>
<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.forename}"></span></a></td> </tr>
<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.surname}"></span></a></td> </tbody>
<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.contact}"></span></a></td> </table>
<td><a th:href="@{/contact/edit/{id}(id=${contact.pk})}"><span th:text="${contact.type}"></span></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{layout/main.html}">
<head>
<title>Notizen</title>
</head>
<body>
<ul layout:fragment="title">
<li class="nav-item"><a class="nav-link titlemod">Arbeitszeit</a></li>
</ul>
<ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/done/add}">Neuer
Eintrag</a></li>
</ul>
<main layout:fragment="content">
<ul class="nav nav-tabs navback" role="tablist">
<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_summary">Zusammenfassung</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_attachment">Anhang</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_calendar">Kalender</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Tätigkeit</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_budget">Abrechnung</a></li>
</ul>
<div class="tabdivblurred tab-content">
<div id="div_list" class="tab-pane active">Liste</div>
<div id="div_summary" class="tab-pane fade">Zusammenfassung</div>
<div id="div_attachment" class="tab-pane fade">Anhang</div>
<div id="div_calendar" class="tab-pane fade">Kalender</div>
<div id="div_project" class="tab-pane fade">Projekt</div>
<div id="div_module" class="tab-pane fade">Modul</div>
<div id="div_job" class="tab-pane fade">Tätigkeit</div>
<div id="div_budget" class="tab-pane fade">Abrechnung</div>
</div>
</main>
</body>
</html>

View File

@ -31,11 +31,13 @@
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarScrollingDropdown" role="button" <li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarScrollingDropdown" role="button"
data-bs-toggle="dropdown" aria-expanded="false"> Module </a> data-bs-toggle="dropdown" aria-expanded="false"> Module </a>
<ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown"> <ul class="dropdown-menu dropdown-menu-light" aria-labelledby="navbarScrollingDropdown">
<li><a class="dropdown-item" th:href="@{/done/list}">Arbeitszeit</a></li>
<li><a class="dropdown-item" th:href="@{/contact/list}">Kontakte</a></li> <li><a class="dropdown-item" th:href="@{/contact/list}">Kontakte</a></li>
<li><a class="dropdown-item" th:href="@{/note/list}">Notizen</a></li> <li><a class="dropdown-item" th:href="@{/note/list}">Notizen</a></li>
<li><hr /></li> <li><hr /></li>
<li><a class="dropdown-item" th:href="@{/logout}">[[${currentUser}]] abmelden</a></li> <li><a class="dropdown-item" th:href="@{/logout}">[[${currentUser}]] abmelden</a></li>
</ul></li> </ul></li>
<li layout:fragment="title" style="list-style-type: none"></li>
<li layout:fragment="menu" style="list-style-type: none"></li> <li layout:fragment="menu" style="list-style-type: none"></li>
</ul> </ul>
</div> </div>

View File

@ -5,69 +5,62 @@
<title>Notizen</title> <title>Notizen</title>
</head> </head>
<body> <body>
<ul layout:fragment="title">
<li class="nav-item"><a class="nav-link titlemod">Notizen</a></li>
</ul>
<ul layout:fragment="menu"> <ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/note/add}">Neue Notiz <li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/note/add}">Neue Notiz
anlegen</a></li> anlegen</a></li>
</ul> </ul>
<main layout:fragment="content"> <main layout:fragment="content">
<div class="accordion" id="acdiv"> <ul class="nav nav-tabs navback" role="tablist">
<div class="accordion-item noty"> <li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_dashboard">Dashboard</a></li>
<h2 class="accordion-header" id="headingDashboard"> <li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_list">Liste</a></li>
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#dashboard" aria-expanded="true" </ul>
aria-controls="dashboard">Dashboard</button> <div class="tabdivblurred tab-content">
</h2> <div id="div_dashboard" class="tab-pane active">
<div id="dashboard" class="accordion-collapse collapse show" aria-labelledby="headingDashboard" data-bs-parent="#acdiv"> <div class="row row-cols-12 ro-cols-lg-3 ro-cols-md-2 ro-cols-sd-1 g-4" style="margin: 8px">
<div class="accordion-body"> <div class="col" th:each="note : ${noteList}">
<div class="row row-cols-12 ro-cols-lg-3 ro-cols-md-2 ro-cols-sd-1 g-4" style="margin: 8px"> <div class="card text-dark bg-light shadow" style="width: 100%">
<div class="col" th:each="note : ${noteList}"> <div class="card-header text-center">
<div class="card text-dark bg-light shadow" style="width: 100%"> <font th:text="${note.category}" style="font-size: larger">:</font> <font th:text="${note.title}"
<div class="card-header text-center"> style="font-size: larger; font-weight: bolder"></font>
<font th:text="${note.category}" style="font-size: larger">:</font> <font th:text="${note.title}" </div>
style="font-size: larger; font-weight: bolder"></font> <div class="card-body">
</div> <div class="d-flex justify-content-center align-items-center">
<div class="card-body"> <pre th:text="${note.content}"></pre>
<div class="d-flex justify-content-center align-items-center"> <a th:href="@{/note/edit/{id}(id=${note.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;">
<pre th:text="${note.content}"></pre> <i class="fa fa-edit"></i>
<a th:href="@{/note/edit/{id}(id=${note.pk})}" sec:authorize="hasRole('timetrack_user')" style="margin-left: 8px;"> </a>
<i class="fa fa-edit"></i>
</a>
</div>
</div>
<div class="card-footer">
<span th:text="${note.type}"></span>
</div>
</div> </div>
</div> </div>
<div class="card-footer">
<span th:text="${note.type}"></span>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="accordion-item glassy"> </div>
<h2 class="accordion-header" id="headingTable"> <div id="div_list" class="tab-pane fade">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#list" <div class="accordion-body" style="background-color: white">
aria-expanded="false" aria-controls="list">Liste</button> <table class="table table-striped table-condensed">
</h2> <thead>
<div id="list" class="accordion-collapse collapse" aria-labelledby="headingTable" data-bs-parent="#acdiv"> <tr>
<div class="accordion-body" style="background-color: white"> <th>Titel</th>
<table class="table table-striped table-condensed"> <th>Kategorie</th>
<thead> <th>Inhalt</th>
<tr> <th>Typ</th>
<th>Titel</th> </tr>
<th>Kategorie</th> </thead>
<th>Inhalt</th> <tbody>
<th>Typ</th> <tr th:each="note : ${noteList}">
</tr> <td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.title}"></span></a></td>
</thead> <td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.category}"></span></a></td>
<tbody> <td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.content}"></span></a></td>
<tr th:each="note : ${noteList}"> <td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.type}"></span></a></td>
<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.title}"></span></a></td> </tr>
<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.category}"></span></a></td> </tbody>
<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.content}"></span></a></td> </table>
<td><a th:href="@{/note/edit/{id}(id=${note.pk})}"><span th:text="${note.type}"></span></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>