updating kanban on
* task creation * task update * task deletion
This commit is contained in:
@@ -103,20 +103,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdateEvent(evt){
|
function handleCreateEvent(evt){
|
||||||
|
handleEvent(evt,'create');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEvent(evt,method){
|
||||||
let json = JSON.parse(evt.data);
|
let json = JSON.parse(evt.data);
|
||||||
if (json.task && json.user){
|
if (json.task && json.user){
|
||||||
|
// drop from kanban
|
||||||
for (let uid in tasks){
|
for (let uid in tasks){
|
||||||
if (!uid) continue;
|
if (!uid) continue;
|
||||||
for (let state in tasks[uid]) delete tasks[uid][state][json.task.id];
|
for (let state in tasks[uid]) delete tasks[uid][state][json.task.id];
|
||||||
}
|
}
|
||||||
processTask(json.task);
|
|
||||||
|
// (re) add to kanban
|
||||||
|
if (method != 'delete') processTask(json.task);
|
||||||
|
|
||||||
|
// show notification
|
||||||
if (json.user.id != user.id) {
|
if (json.user.id != user.id) {
|
||||||
info = t("user_updated_entity",{user:json.user.name,entity:json.task.name});
|
let term = "user_updated_entity";
|
||||||
|
if (method == 'create') term = "user_created_entity";
|
||||||
|
if (method == 'delete') term = "user_deleted_entity";
|
||||||
|
info = t(term,{user:json.user.name,entity:json.task.name});
|
||||||
setTimeout(() => { info = null; },2500);
|
setTimeout(() => { info = null; },2500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDeleteEvent(evt){
|
||||||
|
console.log('delete task');
|
||||||
|
handleEvent(evt,'delete');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdateEvent(evt){
|
||||||
|
handleEvent(evt,'update');
|
||||||
}
|
}
|
||||||
|
|
||||||
function hover(ev,user_id,state){
|
function hover(ev,user_id,state){
|
||||||
@@ -135,7 +155,7 @@
|
|||||||
|
|
||||||
async function load(){
|
async function load(){
|
||||||
try {
|
try {
|
||||||
eventSource = eventStream(handleUpdateEvent);
|
eventSource = eventStream(handleCreateEvent,handleUpdateEvent,handleDeleteEvent);
|
||||||
await loadProject();
|
await loadProject();
|
||||||
loadTasks({project_id:+id,parent_task_id:0});
|
loadTasks({project_id:+id,parent_task_id:0});
|
||||||
} catch (ignored) {}
|
} catch (ignored) {}
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ export function drop(url){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function eventStream(updateHandler){
|
export function eventStream(createHandler,updateHandler,deleteHandler){
|
||||||
const es = new EventSource(api('bus'), {withCredentials: true});
|
const es = new EventSource(api('bus'), {withCredentials: true});
|
||||||
|
if (createHandler) es.addEventListener('CREATE', createHandler);
|
||||||
if (updateHandler) es.addEventListener('UPDATE', updateHandler);
|
if (updateHandler) es.addEventListener('UPDATE', updateHandler);
|
||||||
|
if (deleteHandler) es.addEventListener('DELETE', deleteHandler);
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import static de.srsoftware.umbrella.core.Util.mapValues;
|
|||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||||
import static de.srsoftware.umbrella.core.model.Permission.*;
|
import static de.srsoftware.umbrella.core.model.Permission.*;
|
||||||
import static de.srsoftware.umbrella.core.model.Permission.OWNER;
|
import static de.srsoftware.umbrella.core.model.Permission.OWNER;
|
||||||
|
import static de.srsoftware.umbrella.messagebus.Event.EventType.CREATE;
|
||||||
import static de.srsoftware.umbrella.messagebus.Event.EventType.UPDATE;
|
import static de.srsoftware.umbrella.messagebus.Event.EventType.UPDATE;
|
||||||
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
||||||
import static de.srsoftware.umbrella.project.Constants.PERMISSIONS;
|
import static de.srsoftware.umbrella.project.Constants.PERMISSIONS;
|
||||||
@@ -31,6 +32,7 @@ import de.srsoftware.umbrella.core.model.*;
|
|||||||
import de.srsoftware.umbrella.core.model.Task;
|
import de.srsoftware.umbrella.core.model.Task;
|
||||||
import de.srsoftware.umbrella.core.model.Token;
|
import de.srsoftware.umbrella.core.model.Token;
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||||
|
import de.srsoftware.umbrella.messagebus.Event;
|
||||||
import de.srsoftware.umbrella.messagebus.TaskEvent;
|
import de.srsoftware.umbrella.messagebus.TaskEvent;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -40,6 +42,22 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
public class TaskModule extends BaseHandler implements TaskService {
|
public class TaskModule extends BaseHandler implements TaskService {
|
||||||
|
|
||||||
|
private static class TaggedTask extends Task{
|
||||||
|
private final Collection<String> tags;
|
||||||
|
|
||||||
|
public TaggedTask(Task task, Collection<String> 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<String, Object> toMap() {
|
||||||
|
var map = super.toMap();
|
||||||
|
map.put(TAGS,tags);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final TaskDb taskDb;
|
private final TaskDb taskDb;
|
||||||
|
|
||||||
public TaskModule(Configuration config) throws UmbrellaException {
|
public TaskModule(Configuration config) throws UmbrellaException {
|
||||||
@@ -63,6 +81,7 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
taskDb.delete(task);
|
taskDb.delete(task);
|
||||||
noteService().deleteEntity(TASK, "" + taskId);
|
noteService().deleteEntity(TASK, "" + taskId);
|
||||||
tagService().deleteEntity(TASK, taskId);
|
tagService().deleteEntity(TASK, taskId);
|
||||||
|
messageBus().dispatch(new TaskEvent(user,task,Event.EventType.DELETE));
|
||||||
return sendContent(ex, Map.of(DELETED, taskId));
|
return sendContent(ex, Map.of(DELETED, taskId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,6 +280,16 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
return taskList;
|
return taskList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean newParentIsSubtask(Task task, long newParent) {
|
||||||
|
var parent = taskDb.load(newParent);
|
||||||
|
while (parent != null) {
|
||||||
|
if (task.id() == parent.id()) return true;
|
||||||
|
if (parent.parentTaskId() == null) break;
|
||||||
|
parent = taskDb.load(parent.parentTaskId());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> placeInTree(Task task, HashMap<Long, Map<String, Object>> taskTree, Map<Long, Task> taskMap) {
|
private Map<String, Object> placeInTree(Task task, HashMap<Long, Map<String, Object>> taskTree, Map<Long, Task> taskMap) {
|
||||||
var mappedTask = task.toMap();
|
var mappedTask = task.toMap();
|
||||||
if (task.parentTaskId() != null) {
|
if (task.parentTaskId() != null) {
|
||||||
@@ -319,16 +348,6 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
return sendContent(ex, task);
|
return sendContent(ex, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean newParentIsSubtask(Task task, long newParent) {
|
|
||||||
var parent = taskDb.load(newParent);
|
|
||||||
while (parent != null) {
|
|
||||||
if (task.id() == parent.id()) return true;
|
|
||||||
if (parent.parentTaskId() == null) break;
|
|
||||||
parent = taskDb.load(parent.parentTaskId());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@@ -385,7 +404,10 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
if ((tagList == null || tagList.isEmpty()) && parentTask != null) tagList = tagService().getTags(TASK, parentTask.id(), user);
|
if ((tagList == null || tagList.isEmpty()) && parentTask != null) tagList = tagService().getTags(TASK, parentTask.id(), user);
|
||||||
if ((tagList == null || tagList.isEmpty())) tagList = tagService().getTags(PROJECT, projectId, user);
|
if ((tagList == null || tagList.isEmpty())) tagList = tagService().getTags(PROJECT, projectId, user);
|
||||||
if (tagList != null && !tagList.isEmpty()) tagService().save(TASK, task.id(), null, tagList);
|
if (tagList != null && !tagList.isEmpty()) tagService().save(TASK, task.id(), null, tagList);
|
||||||
return sendContent(ex, loadMembers(task));
|
task = loadMembers(task);
|
||||||
|
|
||||||
|
messageBus().dispatch(new TaskEvent(user,new TaggedTask(task,tagList), CREATE));
|
||||||
|
return sendContent(ex, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean postSearch(UmbrellaUser user, HttpExchange ex) throws IOException {
|
private boolean postSearch(UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||||
@@ -424,23 +446,6 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
return sendEmptyResponse(HTTP_NOT_IMPLEMENTED, ex);
|
return sendEmptyResponse(HTTP_NOT_IMPLEMENTED, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TaggedTask extends Task{
|
|
||||||
|
|
||||||
private final Collection<String> tags;
|
|
||||||
|
|
||||||
public TaggedTask(Task task, Collection<String> 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<String, Object> toMap() {
|
|
||||||
var map = super.toMap();
|
|
||||||
map.put(TAGS,tags);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Long, Task> addTags(Map<Long, Task> taskList, Map<Long, ? extends Collection<String>> tags) {
|
private Map<Long, Task> addTags(Map<Long, Task> taskList, Map<Long, ? extends Collection<String>> tags) {
|
||||||
return taskList.values().stream().map(task -> new TaggedTask(task, tags.get(task.id()))).collect(Collectors.toMap(Task::id, t -> t));
|
return taskList.values().stream().map(task -> new TaggedTask(task, tags.get(task.id()))).collect(Collectors.toMap(Task::id, t -> t));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,6 +343,8 @@
|
|||||||
"user_list": "Benutzer-Liste",
|
"user_list": "Benutzer-Liste",
|
||||||
"user_module" : "Umbrella User-Verwaltung",
|
"user_module" : "Umbrella User-Verwaltung",
|
||||||
"users": "Benutzer",
|
"users": "Benutzer",
|
||||||
|
"user_created_entity": "{user} hat \"{entity}\" angelegt",
|
||||||
|
"user_deleted_entity": "{user} hat \"{entity}\" gelöscht",
|
||||||
"user_updated_entity": "{user} hat \"{entity}\" bearbeitet",
|
"user_updated_entity": "{user} hat \"{entity}\" bearbeitet",
|
||||||
|
|
||||||
"website": "Website",
|
"website": "Website",
|
||||||
|
|||||||
Reference in New Issue
Block a user