From 2bd7270f83a1e94eb763d439996784d4d59c284b Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 28 Jul 2025 00:13:41 +0200 Subject: [PATCH] implemented deletion of tags upon deletion of task --- .../umbrella/backend/Application.java | 2 +- .../umbrella/core/api/TagService.java | 13 +++++++++ .../de/srsoftware/umbrella/tags/SqliteDb.java | 22 +++++++++++---- .../de/srsoftware/umbrella/tags/TagDB.java | 6 ++-- .../srsoftware/umbrella/tags/TagModule.java | 28 +++++++++++++++---- .../srsoftware/umbrella/task/Constants.java | 2 ++ .../srsoftware/umbrella/task/TaskModule.java | 16 +++++++---- web/src/main/resources/web/css/default.css | 2 +- 8 files changed, 71 insertions(+), 20 deletions(-) diff --git a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java index 84f37c0..af9e10c 100644 --- a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java +++ b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java @@ -68,7 +68,7 @@ public class Application { var messageApi = new MessageApi(messageSystem); var projectModule = new ProjectModule(config,companyModule); var tagModule = new TagModule(config,userModule); - var taskModule = new TaskModule(config,projectModule); + var taskModule = new TaskModule(config,projectModule,tagModule); var timeModule = new TimeModule(config,taskModule); var webHandler = new WebHandler(); diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java index 05e1e3c..6d3128f 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/TagService.java @@ -1,5 +1,18 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.core.api; +import de.srsoftware.umbrella.core.exceptions.UmbrellaException; +import de.srsoftware.umbrella.core.model.UmbrellaUser; + +import java.util.Collection; +import java.util.Set; + public interface TagService { + void deleteEntity(String task, long taskId); + + Collection getTags(String module, long entityId, UmbrellaUser user) throws UmbrellaException; + + void save(String module, long entityId, Collection userIds, Collection tags); + + String save(String module, long entityId, Collection userIds, String tag); } 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 0f5879c..9084b3f 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java @@ -93,7 +93,18 @@ CREATE TABLE IF NOT EXISTS "{0}" ( .execute(db); return tag; } catch (SQLException e){ - throw new UmbrellaException("Failed to save tag {0}",tag); + throw new UmbrellaException("Failed to delete tag {0}",tag); + } + } + + @Override + public void deleteEntity(String module, long entityId) { + try { + Query.delete().from(TABLE_TAGS) + .where(MODULE,equal(module)).where(ID,equal(entityId)) + .execute(db); + } catch (SQLException e){ + throw new UmbrellaException("Failed to save tags ({0} {1})",module,entityId); } } @@ -116,14 +127,15 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public String save(Collection userIds, String module, long entityId, String tag) { + public void save(Collection userIds, String module, long entityId, Collection tags) { try { var query = replaceInto(TABLE_TAGS,USER_ID,MODULE,ID,TAG); - for (var userId : userIds) query.values(userId,module,entityId,tag); + for (var userId : userIds) { + for (var tag : tags) query.values(userId,module,entityId,tag); + } query.execute(db).close(); - return tag; } catch (SQLException e){ - throw new UmbrellaException("Failed to save tag {0}",tag); + throw new UmbrellaException("Failed to save tags: {0}",String.join(", ",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 11d2f1a..d7f4f52 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/TagDB.java @@ -5,9 +5,11 @@ import java.util.Collection; import java.util.Set; public interface TagDB { - Object delete(long userId, String module, long entityId, String tag); + String delete(long userId, String module, long entityId, String tag); + + void deleteEntity(String module, long entityId); Set list(long id, String module, long entityId); - String save(Collection userIds, String module, long entityId, String tag); + void save(Collection userIds, String module, long entityId, Collection tags); } diff --git a/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java b/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java index 14c38cf..051e74a 100644 --- a/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java +++ b/tags/src/main/java/de/srsoftware/umbrella/tags/TagModule.java @@ -19,12 +19,11 @@ import de.srsoftware.umbrella.core.api.TagService; import de.srsoftware.umbrella.core.api.UserService; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Token; +import de.srsoftware.umbrella.core.model.UmbrellaUser; import org.json.JSONArray; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; public class TagModule extends BaseHandler implements TagService { private final SqliteDb tagDb; @@ -36,6 +35,11 @@ public class TagModule extends BaseHandler implements TagService { users = userService; } + @Override + public void deleteEntity(String module, long entityId) { + tagDb.deleteEntity(module,entityId); + } + @Override public boolean doDelete(Path path, HttpExchange ex) throws IOException { addCors(ex); @@ -67,8 +71,7 @@ public class TagModule extends BaseHandler implements TagService { if (module == null) throw unprocessable("Module missing in path."); var head = path.pop(); long entityId = Long.parseLong(head); - var tags = tagDb.list(user.get().id(),module,entityId); - return sendContent(ex, tags); + return sendContent(ex, getTags(module,entityId,user.get())); } catch (NumberFormatException e){ return sendContent(ex,HTTP_UNPROCESSABLE,"Entity id missing in path."); } catch (UmbrellaException e){ @@ -99,7 +102,7 @@ public class TagModule extends BaseHandler implements TagService { arr.toList().stream().filter(elem -> elem instanceof Number).map(elem -> (Number) elem).map(Number::longValue).toList() : List.of(user.get().id()); if (userList.isEmpty()) throw missingFieldException(USER_LIST); - tag = tagDb.save(userList, module, entityId, tag); + tag = save(module, entityId, userList, tag); return sendContent(ex, tag); } catch (NumberFormatException e) { return sendContent(ex, HTTP_UNPROCESSABLE, "Entity id missing in path."); @@ -108,5 +111,18 @@ public class TagModule extends BaseHandler implements TagService { } } + public Collection getTags(String module, long entityId, UmbrellaUser user) throws UmbrellaException{ + return tagDb.list(user.id(),module,entityId); + } + @Override + public void save(String module, long entityId, Collection userIds, Collection tags) { + tagDb.save(userIds,module,entityId,tags); + } + + @Override + public String save(String module, long entityId, Collection userIds, String tag) { + save(module,entityId,userIds,List.of(tag)); + return tag; + } } diff --git a/task/src/main/java/de/srsoftware/umbrella/task/Constants.java b/task/src/main/java/de/srsoftware/umbrella/task/Constants.java index 5c5ab84..7797a1c 100644 --- a/task/src/main/java/de/srsoftware/umbrella/task/Constants.java +++ b/task/src/main/java/de/srsoftware/umbrella/task/Constants.java @@ -4,11 +4,13 @@ package de.srsoftware.umbrella.task; public class Constants { private Constants(){} + public static final String CONFIG_DATABASE = "umbrella.modules.task.database"; public static final String CHILDREN = "children"; public static final String ESTIMATED_TIMES = "estimated_times"; public static final String TABLE_TASKS = "tasks"; public static final String TABLE_TASKS_USERS = "tasks_users"; + public static final String TASK = "task"; public static final String TASKS = "tasks"; public static final String TASK_ID = "task_id"; } 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 1552077..7d41af7 100644 --- a/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java +++ b/task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java @@ -21,10 +21,7 @@ import de.srsoftware.configuration.Configuration; import de.srsoftware.tools.Path; import de.srsoftware.tools.SessionToken; import de.srsoftware.umbrella.core.BaseHandler; -import de.srsoftware.umbrella.core.api.CompanyService; -import de.srsoftware.umbrella.core.api.ProjectService; -import de.srsoftware.umbrella.core.api.TaskService; -import de.srsoftware.umbrella.core.api.UserService; +import de.srsoftware.umbrella.core.api.*; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.*; import de.srsoftware.umbrella.core.model.Task; @@ -40,12 +37,14 @@ public class TaskModule extends BaseHandler implements TaskService { private final ProjectService projects; private final UserService users; private final CompanyService companies; + private final TagService tags; - public TaskModule(Configuration config, ProjectService projectService) throws UmbrellaException { + public TaskModule(Configuration config, ProjectService projectService, TagService tagService) throws UmbrellaException { var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE)); taskDb = new SqliteDb(connect(dbFile)); projects = projectService; companies = projectService.companyService(); + tags = tagService; users = companies.userService(); } @@ -66,6 +65,7 @@ public class TaskModule extends BaseHandler implements TaskService { var member = task.members().get(user.id()); if (member == null || !member.mayWrite()) throw forbidden("You are not allowed to delete {0}",task.name()); taskDb.delete(task); + tags.deleteEntity(TASK,taskId); return sendContent(ex,Map.of(DELETED,taskId)); } @@ -304,12 +304,18 @@ public class TaskModule extends BaseHandler implements TaskService { Task task = Task.of(json); task = taskDb.save(task); + var memberIds = new HashSet(); for (var key : memberData.keySet()){ long userId = Long.parseLong(key); + memberIds.add(userId); var nested = memberData.getJSONObject(key).getJSONObject(PERMISSION); var permission = nested.has(CODE) ? Permission.of(nested.getInt(CODE)) : Permission.valueOf(nested.getString(NAME)); taskDb.setMember(task.id(),userId,permission); } + if (isSet(task.parentTaskId())){ + var tagList = tags.getTags(TASK,task.parentTaskId(),user); + tags.save(TASK,task.id(),memberIds,tagList); + } return sendContent(ex,loadMembers(task)); } diff --git a/web/src/main/resources/web/css/default.css b/web/src/main/resources/web/css/default.css index 9e2254b..f33d3bb 100644 --- a/web/src/main/resources/web/css/default.css +++ b/web/src/main/resources/web/css/default.css @@ -189,7 +189,7 @@ textarea{ position: absolute; left: 0; bottom: 0; - font-size: 0.5em; + font-size: 0.6em; } .kanban .user, .kanban .head {