working on task update by event
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.messagebus;
|
package de.srsoftware.umbrella.messagebus;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
||||||
|
|
||||||
public interface EventListener {
|
public interface EventListener {
|
||||||
void onEvent(Event event);
|
void onEvent(Event event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.messagebus;
|
package de.srsoftware.umbrella.messagebus;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import de.srsoftware.tools.SessionToken;
|
|||||||
import de.srsoftware.umbrella.core.BaseHandler;
|
import de.srsoftware.umbrella.core.BaseHandler;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.core.model.Token;
|
import de.srsoftware.umbrella.core.model.Token;
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.messagebus;
|
package de.srsoftware.umbrella.messagebus;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.messagebus;
|
package de.srsoftware.umbrella.messagebus.events;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.core.Constants.USER;
|
import static de.srsoftware.umbrella.core.Constants.USER;
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/* © SRSoftware 2025 */
|
||||||
|
package de.srsoftware.umbrella.messagebus.events;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.core.model.Project;
|
||||||
|
import de.srsoftware.umbrella.core.model.Task;
|
||||||
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||||
|
|
||||||
|
import static de.srsoftware.umbrella.core.Constants.PROJECT;
|
||||||
|
import static de.srsoftware.umbrella.core.Constants.TASK;
|
||||||
|
|
||||||
|
|
||||||
|
public class ProjectEvent extends Event<Project>{
|
||||||
|
public ProjectEvent(UmbrellaUser initiator, Project project, EventType type){
|
||||||
|
super(initiator, PROJECT, project, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIntendedFor(UmbrellaUser user) {
|
||||||
|
for (var member : payload().members().values()){
|
||||||
|
if (member.user().equals(user)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* © SRSoftware 2025 */
|
/* © SRSoftware 2025 */
|
||||||
package de.srsoftware.umbrella.messagebus;
|
package de.srsoftware.umbrella.messagebus.events;
|
||||||
|
|
||||||
import static de.srsoftware.umbrella.core.Constants.TASK;
|
import static de.srsoftware.umbrella.core.Constants.TASK;
|
||||||
|
|
||||||
@@ -116,6 +116,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
<svelte:element this={type} {onclick} {oncontextmenu} class={{editable}} title={t('right_click_to_edit')} >{@html target(editValue.rendered)}</svelte:element>
|
<svelte:element this={type} {onclick} {oncontextmenu} class={{editable}} title={t('right_click_to_edit')} >{@html target(value.rendered)}</svelte:element>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
import Tags from '../tags/TagList.svelte';
|
import Tags from '../tags/TagList.svelte';
|
||||||
import TaskList from '../task/TaskList.svelte';
|
import TaskList from '../task/TaskList.svelte';
|
||||||
|
|
||||||
let eventSource = null;
|
let eventSource = $state(null);
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
let lastEvent = $state(null);
|
let lastEvent = $state(null);
|
||||||
let estimated_time = $state({sum:0});
|
let estimated_time = $state({sum:0});
|
||||||
@@ -98,6 +98,7 @@
|
|||||||
let json = JSON.parse(evt.data);
|
let json = JSON.parse(evt.data);
|
||||||
json.event = 'update';
|
json.event = 'update';
|
||||||
lastEvent = json;
|
lastEvent = json;
|
||||||
|
if (json.project && json.project.id == project.id) project = json.project;
|
||||||
}
|
}
|
||||||
|
|
||||||
function kanban(){
|
function kanban(){
|
||||||
@@ -303,7 +304,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tasks">
|
<div class="tasks">
|
||||||
{#if tasks}
|
{#if tasks}
|
||||||
<TaskList {tasks} {estimated_time} {lastEvent} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
<TaskList {tasks} {estimated_time} {lastEvent} {eventSource} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
|
|
||||||
import { api, eventStream } from '../../urls.svelte';
|
import { api, eventStream } from '../../urls.svelte';
|
||||||
import { error, yikes } from '../../warn.svelte';
|
import { error, yikes } from '../../warn.svelte';
|
||||||
import { t } from '../../translations.svelte';
|
import { t } from '../../translations.svelte';
|
||||||
import { timetrack } from '../../user.svelte.js';
|
import { timetrack } from '../../user.svelte.js';
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
import TagList from '../tags/TagList.svelte';
|
import TagList from '../tags/TagList.svelte';
|
||||||
import TaskList from './TaskList.svelte';
|
import TaskList from './TaskList.svelte';
|
||||||
|
|
||||||
let eventSource = null;
|
let eventSource = $state(null);
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
let children = $state(null);
|
let children = $state(null);
|
||||||
let dummy = $derived(updateOn(id));
|
let dummy = $derived(updateOn(id));
|
||||||
@@ -28,7 +28,10 @@
|
|||||||
let show_closed = $state(false);
|
let show_closed = $state(false);
|
||||||
let task = $state(null);
|
let task = $state(null);
|
||||||
|
|
||||||
$effect(() => updateOn(id));
|
$effect(() => {
|
||||||
|
if (!eventSource) eventSource = eventStream(null,handleUpdateEvent,null);
|
||||||
|
updateOn(id)
|
||||||
|
});
|
||||||
|
|
||||||
function addChild(){
|
function addChild(){
|
||||||
router.navigate(`/task/${id}/add_subtask`);
|
router.navigate(`/task/${id}/add_subtask`);
|
||||||
@@ -83,16 +86,15 @@
|
|||||||
router.navigate(`/project/${project.id}/view`)
|
router.navigate(`/project/${project.id}/view`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdateEvent(evt){
|
function handleUpdateEvent(evt){
|
||||||
let json = JSON.parse(evt.data);
|
let json = JSON.parse(evt.data);
|
||||||
if (json.task && json.task.id == id) updateOn(id);
|
if (json.task) {
|
||||||
}
|
if (json.task.id == id) updateOn(id);
|
||||||
|
if (json.task.parent_task_id == id) children[json.task.id] = json.task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function load(){
|
async function loadChildren(){
|
||||||
eventSource = eventStream(null,handleUpdateEvent,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadChildren(){
|
|
||||||
const url = api('task/list');
|
const url = api('task/list');
|
||||||
const data = {
|
const data = {
|
||||||
parent_task_id : +task.id,
|
parent_task_id : +task.id,
|
||||||
@@ -204,7 +206,6 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (eventSource) eventSource.close();
|
if (eventSource) eventSource.close();
|
||||||
});
|
});
|
||||||
onMount(load);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -319,7 +320,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="children">
|
<div class="children">
|
||||||
{#if children}
|
{#if children}
|
||||||
<TaskList states={project?.allowed_states} tasks={children} {estimated_time} show_closed={task.show_closed} />
|
<TaskList {eventSource} states={project?.allowed_states} tasks={children} {estimated_time} show_closed={task.show_closed} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
description = "Umbrella : Projects"
|
description = "Umbrella : Projects"
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
|
implementation(project(":bus"))
|
||||||
implementation(project(":core"))
|
implementation(project(":core"))
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,8 @@ 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.core.model.Status.OPEN;
|
import static de.srsoftware.umbrella.core.model.Status.OPEN;
|
||||||
import static de.srsoftware.umbrella.core.model.Status.PREDEFINED;
|
import static de.srsoftware.umbrella.core.model.Status.PREDEFINED;
|
||||||
|
import static de.srsoftware.umbrella.messagebus.MessageBus.messageBus;
|
||||||
|
import static de.srsoftware.umbrella.messagebus.events.Event.EventType.UPDATE;
|
||||||
import static de.srsoftware.umbrella.project.Constants.CONFIG_DATABASE;
|
import static de.srsoftware.umbrella.project.Constants.CONFIG_DATABASE;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
|
||||||
@@ -27,6 +29,10 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
|||||||
import de.srsoftware.umbrella.core.model.*;
|
import de.srsoftware.umbrella.core.model.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.Event;
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.ProjectEvent;
|
||||||
|
import de.srsoftware.umbrella.messagebus.events.TaskEvent;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@@ -211,7 +217,8 @@ public class ProjectModule extends BaseHandler implements ProjectService {
|
|||||||
if (json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberJson) patchMembers(project,memberJson);
|
if (json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberJson) patchMembers(project,memberJson);
|
||||||
if (json.has(NEW_MEMBER) && json.get(NEW_MEMBER) instanceof Number num) addMember(project,num.longValue());
|
if (json.has(NEW_MEMBER) && json.get(NEW_MEMBER) instanceof Number num) addMember(project,num.longValue());
|
||||||
|
|
||||||
projectDb.save(project.patch(json), user);
|
project = projectDb.save(project.patch(json), user);
|
||||||
|
messageBus().dispatch(new ProjectEvent(user,project, UPDATE));
|
||||||
return sendContent(ex,project.toMap());
|
return sendContent(ex,project.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ 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.events.Event.EventType.CREATE;
|
||||||
import static de.srsoftware.umbrella.messagebus.Event.EventType.UPDATE;
|
import static de.srsoftware.umbrella.messagebus.events.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;
|
||||||
import static de.srsoftware.umbrella.task.Constants.*;
|
import static de.srsoftware.umbrella.task.Constants.*;
|
||||||
@@ -32,8 +32,8 @@ 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.events.Event;
|
||||||
import de.srsoftware.umbrella.messagebus.TaskEvent;
|
import de.srsoftware.umbrella.messagebus.events.TaskEvent;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|||||||
Reference in New Issue
Block a user