refactored member assignment for new tasks

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-09-23 11:58:29 +02:00
parent f549269326
commit 52b41b8d28
3 changed files with 41 additions and 44 deletions

View File

@@ -13,8 +13,9 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import org.json.JSONObject; import org.json.JSONObject;
public class User { public class User {
private String lang, name; private final String lang;
private EmailAddress email; private final String name;
private final EmailAddress email;
public User(String name, EmailAddress email, String languageCode){ public User(String name, EmailAddress email, String languageCode){
lang = languageCode; lang = languageCode;
@@ -51,6 +52,6 @@ public class User {
@Override @Override
public String toString() { public String toString() {
return format("{0} ({1})",name,email); return email == null ? name : format("{0} ({1})",name,email);
} }
} }

View File

@@ -21,7 +21,6 @@
due_date : null, due_date : null,
estimated_time : null, estimated_time : null,
no_index : false, no_index : false,
members : {},
show_closed : false, show_closed : false,
start_date : null, start_date : null,
tags : [] tags : []
@@ -36,22 +35,6 @@
return JSON.parse(JSON.stringify(json)); return JSON.parse(JSON.stringify(json));
} }
function copyMembers(source){
task.members = {};
let owner = null;
let me = null;
for (let [uid, member] of Object.entries(source)){
task.members[uid] = member;
if (member.permission.name == 'OWNER') owner = flat(member);
if (uid == user.id) me = flat(member);
}
if (owner && me) {
// of someone else is owner of the parent task or project, make current user the owner
task.members[me.user.id].permission = owner.permission;
task.members[owner.user.id].permission = me.permission;
}
}
function dropMember(member){ function dropMember(member){
delete task.members[member.user.id]; delete task.members[member.user.id];
console.log({drop:member.user.id}); console.log({drop:member.user.id});
@@ -84,8 +67,6 @@
if (resp.ok){ if (resp.ok){
project = await resp.json(); project = await resp.json();
task.project_id = +project_id; task.project_id = +project_id;
let member_source = parent_task?parent_task.members:project.members;
copyMembers(member_source);
error = null; error = null;
} else { } else {
error = await resp.text(); error = await resp.text();

View File

@@ -316,36 +316,51 @@ public class TaskModule extends BaseHandler implements TaskService {
private boolean postNewTask(UmbrellaUser user, HttpExchange ex) throws IOException { private boolean postNewTask(UmbrellaUser user, HttpExchange ex) throws IOException {
var json = json(ex); var json = json(ex);
if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingFieldException(PROJECT_ID); if (!(json.has(PROJECT_ID) && json.get(PROJECT_ID) instanceof Number pid)) throw missingFieldException(PROJECT_ID);
if (!(json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberData)) throw missingFieldException(MEMBERS);
long projectId = pid.longValue(); long projectId = pid.longValue();
var project = projectService().load(projectId); var project = projectService().load(projectId);
projectService().loadMembers(List.of(project)); projectService().loadMembers(List.of(project));
var member = project.members().get(user.id()); var members = project.members();
var member = members.get(user.id());
if (member == null || member.permission() == READ_ONLY) throw forbidden("You are not allowed to create new tasks in this project"); if (member == null || member.permission() == READ_ONLY) throw forbidden("You are not allowed to create new tasks in this project");
for (var key : memberData.keySet()){
long userId = Long.parseLong(key); var parentTask = json.has(PARENT_TASK_ID) && json.get(PARENT_TASK_ID) instanceof Number par ? taskService().load(Set.of(par.longValue())).get(par.longValue()) : null;
if (!(memberData.get(key) instanceof JSONObject nested)) throw invalidFieldException("members."+userId,"JSON"); if (parentTask != null){
if (!(nested.has(PERMISSION) && nested.get(PERMISSION) instanceof JSONObject permission)) throw invalidFieldException("members."+userId+".permission","JSON"); taskService().loadMembers(parentTask);
Permission perm = null; members = parentTask.members();
if (permission.has(CODE) && permission.get(CODE) instanceof Number code) perm = Permission.of(code.intValue()); member = members.get(user.id());
if (permission.has(NAME) && permission.get(NAME) instanceof String name) perm = Permission.valueOf(name); if (member == null || member.permission() == READ_ONLY) throw forbidden("You are not allowed to add sub-stasks to {0}",parentTask.name());
if (perm == null) throw invalidFieldException("members."+userId+".permission.code","int");
if (!project.members().containsKey(userId)) {
String username = nested.has(USER) && nested.get(USER) instanceof JSONObject userData && userData.get(NAME) instanceof String n ? n : key;
throw new UmbrellaException(HTTP_BAD_REQUEST,"User {0} is no member of the leading project and cannot be assigned to this task",username);
}
} }
var newMembers = new HashMap<Long,Permission>();
for (var mem : members.values()){ // Assign members from project or parent task
var permission = mem.permission() == OWNER ? EDIT : mem.permission();
newMembers.put(mem.user().id(),permission);
}
if (json.has(MEMBERS) &&json.get(MEMBERS) instanceof JSONObject mems){
// check of assignee has been set by client
for (var k : mems.keySet()){
try {
var userId = Long.parseLong(k);
var permName = mems.getJSONObject(k).getJSONObject(PERMISSION).getString(NAME);
if (Permission.valueOf(permName) == ASSIGNEE) newMembers.put(userId, ASSIGNEE);
} catch (Exception ignored){
LOG.log(WARNING,"Failed to parse {0}",mems.get(k));
}
}
}
// set ownership to current user
newMembers.put(user.id(),OWNER);
json.put(MEMBERS,Map.of()); // reset member map for task-to-be-created
Task task = Task.of(json); Task task = Task.of(json);
task = taskDb.save(task); task = taskDb.save(task);
var memberIds = new HashSet<Long>();
for (var key : memberData.keySet()){ // do actual member assignment
long userId = Long.parseLong(key); for (var entry : newMembers.entrySet()) taskDb.setMember(task.id(),entry.getKey(),entry.getValue());
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 (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){ if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){
var tagList = arr.toList().stream().filter(e -> e instanceof String).map(String.class::cast).toList(); var tagList = arr.toList().stream().filter(e -> e instanceof String).map(String.class::cast).toList();
tagService().save(TASK,task.id(),null,tagList); tagService().save(TASK,task.id(),null,tagList);