diff --git a/frontend/src/routes/project/Kanban.svelte b/frontend/src/routes/project/Kanban.svelte
index f3726d5..7f0cd14 100644
--- a/frontend/src/routes/project/Kanban.svelte
+++ b/frontend/src/routes/project/Kanban.svelte
@@ -18,7 +18,6 @@
let highlight = $state({});
let filter = $derived(filter_input.toLowerCase());
let project = $state(null);
- let ready = $state(false);
let tasks = $state({});
let users = {};
let columns = $derived(project.allowed_states?Object.keys(project.allowed_states).length+1:1);
@@ -96,8 +95,6 @@
try {
await loadProject();
await loadTasks({project_id:+id,parent_task_id:0});
- ready = true;
- loadTags();
} catch (ignored) {}
}
@@ -120,31 +117,6 @@
}
}
- async function loadTag(task){
- try {
- const url = api(`tags/task/${task.id}`);
- const resp = await fetch(url,{
- credentials:'include',
- signal: signal
- });
- if (resp.ok) {
- const tags = await resp.json();
- if (tags.length) task.tags = tags.sort();
- }
- } catch (ignored) {}
- }
-
- function loadTags(){
- for (let uid of Object.keys(tasks)){
- for (let state of Object.keys(tasks[uid])){
- for (let tid of Object.keys(tasks[uid][state])){
- const task = tasks[uid][state][tid];
- loadTag(task);
- }
- }
- }
- }
-
async function loadTasks(selector){
const url = api('task/list');
selector.show_closed = true;
@@ -205,7 +177,7 @@
{error}
{/if}
-{#if ready}
+{#if project}
diff --git a/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java b/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java
index 8d1224e..6dcaedd 100644
--- a/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java
+++ b/project/src/main/java/de/srsoftware/umbrella/project/SqliteDb.java
@@ -16,13 +16,12 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Permission;
import de.srsoftware.umbrella.core.model.Project;
import de.srsoftware.umbrella.core.model.Status;
-import org.json.JSONObject;
-
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import org.json.JSONObject;
public class SqliteDb extends BaseDb implements ProjectDb {
private static final System.Logger LOG = System.getLogger("ProjectDb");
diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java b/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java
index a2a0651..119b1da 100644
--- a/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java
+++ b/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java
@@ -280,7 +280,7 @@ CREATE TABLE IF NOT EXISTS {0} (
rs.close();
// load tags assigned to no user
- rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,isNull()).exec(db);
+ rs = select(ENTITY_ID,TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,isNull()).exec(db);
while (rs.next()) tags.computeIfAbsent(rs.getLong(ENTITY_ID), k -> new HashSet<>()).add(rs.getString(TAG));
rs.close();
return tags;
diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java b/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java
index a04f89c..57effd3 100644
--- a/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java
+++ b/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java
@@ -1,7 +1,6 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.tags;
-import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import java.util.Collection;
import java.util.List;
diff --git a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java
index fc42b79..c53f0c8 100644
--- a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java
+++ b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java
@@ -15,7 +15,6 @@ import static de.srsoftware.umbrella.project.Constants.PERMISSIONS;
import static de.srsoftware.umbrella.task.Constants.*;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.WARNING;
-import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration;
@@ -398,10 +397,8 @@ public class TaskModule extends BaseHandler implements TaskService {
var projectTasks = taskDb.listProjectTasks(projectId, parentTaskId, noIndex);
loadMembers(projectTasks.values());
var tags = tagService().getTags(TASK,projectTasks.keySet(),user);
- LOG.log(DEBUG,"tags: {0}",tags);
-
- // TODO: add tags to result map
+ projectTasks = addTags(projectTasks, tags);
return sendContent(ex, mapValues(projectTasks));
}
if (isSet(parentTaskId)) return sendContent(ex, mapValues(taskDb.listChildrenOf(parentTaskId, user, showClosed)));
@@ -409,4 +406,25 @@ public class TaskModule extends BaseHandler implements TaskService {
if (isSet(taskIds)) return sendContent(ex, mapValues(taskDb.load(taskIds)));
return sendEmptyResponse(HTTP_NOT_IMPLEMENTED, ex);
}
+
+ private static class TaggedTask extends Task{
+
+ private final Collection tags;
+
+ public TaggedTask(Task task, Collection tags) {
+ super(task.id(), task.projectId(), task.parentTaskId(), task.name(), task.description(), task.status(), task.estimatedTime(), task.start(), task.dueDate(), task.showClosed(), task.noIndex(), task.members(), task.priority());
+ this.tags = tags;
+ }
+
+ @Override
+ public Map toMap() {
+ var map = super.toMap();
+ map.put(TAGS,tags);
+ return map;
+ }
+ }
+
+ private Map addTags(Map taskList, Map> tags) {
+ return taskList.values().stream().map(task -> new TaggedTask(task, tags.get(task.id()))).collect(Collectors.toMap(Task::id, t -> t));
+ }
}