Merge branch 'main' into dev
This commit is contained in:
@@ -98,7 +98,7 @@ public class Project implements Mappable {
|
|||||||
case DESCRIPTION: description = json.getString(key); break;
|
case DESCRIPTION: description = json.getString(key); break;
|
||||||
case NAME: name = json.getString(key); break;
|
case NAME: name = json.getString(key); break;
|
||||||
case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break;
|
case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break;
|
||||||
case STATUS: status = json.getInt(key); break;
|
case STATUS: status = json.get(key) instanceof Number state ? json.getInt(key) : Status.matching(json.getString(key)).code(); break;
|
||||||
case TAG_COLORS:
|
case TAG_COLORS:
|
||||||
tagColors.clear();
|
tagColors.clear();
|
||||||
json.getJSONObject(TAG_COLORS).toMap().forEach((k,v) -> tagColors.put(k,v.toString()));
|
json.getJSONObject(TAG_COLORS).toMap().forEach((k,v) -> tagColors.put(k,v.toString()));
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.core.model;
|
package de.srsoftware.umbrella.core.model;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.core.Constants.CODE;
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
import static de.srsoftware.umbrella.core.Constants.NAME;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.invalidFieldException;
|
||||||
|
|
||||||
import de.srsoftware.tools.Mappable;
|
import de.srsoftware.tools.Mappable;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public record Status(String name, int code) implements Mappable {
|
public record Status(String name, int code) implements Mappable {
|
||||||
public static final Status PENDING = new Status("PENDING", 10); // was 40
|
public static final Status PENDING = new Status("PENDING", 10); // was 40
|
||||||
@@ -18,6 +19,17 @@ public record Status(String name, int code) implements Mappable {
|
|||||||
public static final Status CANCELLED = new Status("CANCELLED", 100);
|
public static final Status CANCELLED = new Status("CANCELLED", 100);
|
||||||
public static final List<Status> PREDEFINED = List.of(OPEN, STARTED, PENDING, COMPLETE, CANCELLED);
|
public static final List<Status> PREDEFINED = List.of(OPEN, STARTED, PENDING, COMPLETE, CANCELLED);
|
||||||
|
|
||||||
|
public static Status matching(String name){
|
||||||
|
return switch (name.toLowerCase()){
|
||||||
|
case "pending" -> PENDING;
|
||||||
|
case "open" -> OPEN;
|
||||||
|
case "started" -> STARTED;
|
||||||
|
case "complete" -> COMPLETE;
|
||||||
|
case "cancelled" -> CANCELLED;
|
||||||
|
case null, default -> throw invalidFieldException(STATUS,"one of: "+PREDEFINED.stream().map(Status::name).collect(Collectors.joining(", ")));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Status of(int code){
|
public static Status of(int code){
|
||||||
return switch (code){
|
return switch (code){
|
||||||
case 10 -> PENDING;
|
case 10 -> PENDING;
|
||||||
|
|||||||
@@ -53,7 +53,8 @@
|
|||||||
|
|
||||||
function show(e){
|
function show(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let href = e.target.getAttribute('href');
|
let target = e.currentTarget;
|
||||||
|
let href = target.getAttribute('href');
|
||||||
if (href) router.navigate(href);
|
if (href) router.navigate(href);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -91,18 +92,18 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{#each sortedProjects as project}
|
{#each sortedProjects as project}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name">
|
<td class="name" onclick={show} href={`/project/${project.id}/view`} >
|
||||||
<a href={`/project/${project.id}/view`} onclick={show}>{project.name}</a>
|
<a href={`/project/${project.id}/view`} onclick={show}>{project.name}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="company">
|
<td class="company" onclick={show} href={`/project/${project.id}/view`} >
|
||||||
{#if project.company_id && companies[project.company_id]}
|
{#if project.company_id && companies[project.company_id]}
|
||||||
<a href={`/company/${companies[project.company_id]}/view`} onclick={show}>{companies[project.company_id].name}</a>
|
{companies[project.company_id].name}
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="state">
|
<td class="state" onclick={show} href={`/project/${project.id}/view`} >
|
||||||
<a href={`/project/${project.id}/view`} onclick={show}>{t("state_"+project.allowed_states[project.status]?.toLowerCase())}</a>
|
<a href={`/project/${project.id}/view`} onclick={show}>{t("state_"+project.allowed_states[project.status]?.toLowerCase())}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="members" >
|
<td class="members" onclick={show} href={`/project/${project.id}/view`} >
|
||||||
<a href={`/project/${project.id}/view`} onclick={show}>
|
<a href={`/project/${project.id}/view`} onclick={show}>
|
||||||
{#each Object.entries(project.members) as [uid,member]}
|
{#each Object.entries(project.members) as [uid,member]}
|
||||||
<div>{member.user.name}</div>
|
<div>{member.user.name}</div>
|
||||||
@@ -110,7 +111,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="actions">
|
<td class="actions">
|
||||||
<button class="edit symbol" title={t('edit')}></button>
|
<!-- <button class="edit symbol" title={t('edit')}></button> -->
|
||||||
{#if project.status < 60}
|
{#if project.status < 60}
|
||||||
<button class="complete symbol" title={t('complete')} onclick={() => setState(project.id,'COMPLETE')} ></button>
|
<button class="complete symbol" title={t('complete')} onclick={() => setState(project.id,'COMPLETE')} ></button>
|
||||||
<button class="abort symbol" title={t('abort')} onclick={() => setState(project.id,'CANCELLED')} ></button>
|
<button class="abort symbol" title={t('abort')} onclick={() => setState(project.id,'CANCELLED')} ></button>
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ td, tr{
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project.list td:not(.actions){
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.project:not(.list) .name,
|
.project:not(.list) .name,
|
||||||
.task .name{
|
.task .name{
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ td, tr{
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project.list td:not(.actions){
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.project:not(.list) .name,
|
.project:not(.list) .name,
|
||||||
.task .name{
|
.task .name{
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ td, tr{
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project.list td:not(.actions){
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.project:not(.list) .name,
|
.project:not(.list) .name,
|
||||||
.task .name{
|
.task .name{
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
|
|||||||
Reference in New Issue
Block a user