working on project tree update upon task creation/deletion/update
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
|
|
||||||
import { api, eventStream, target } from '../../urls.svelte.js';
|
import { api, eventStream, target } from '../../urls.svelte.js';
|
||||||
import { error, messages, yikes } from '../../warn.svelte';
|
import { error, messages, yikes } from '../../warn.svelte';
|
||||||
import { t } from '../../translations.svelte.js';
|
import { t } from '../../translations.svelte.js';
|
||||||
import { user } from '../../user.svelte.js';
|
import { user } from '../../user.svelte.js';
|
||||||
@@ -11,12 +11,12 @@
|
|||||||
import LineEditor from '../../Components/LineEditor.svelte';
|
import LineEditor from '../../Components/LineEditor.svelte';
|
||||||
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
||||||
|
|
||||||
let eventSource = null;
|
let eventSource = null;
|
||||||
let connectionStatus = 'disconnected';
|
let connectionStatus = 'disconnected';
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
let descr = $state(false);
|
let descr = $state(false);
|
||||||
let filter_input = $state('');
|
let filter_input = $state('');
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
if (router.hasQueryParam('filter')) filter_input = router.getQueryParam('filter');
|
if (router.hasQueryParam('filter')) filter_input = router.getQueryParam('filter');
|
||||||
let dragged = null;
|
let dragged = null;
|
||||||
let highlight = $state({});
|
let highlight = $state({});
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
|
|
||||||
import { api } 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';
|
||||||
|
|
||||||
@@ -14,7 +14,9 @@
|
|||||||
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 { id } = $props();
|
let { id } = $props();
|
||||||
|
let lastEvent = $state(null);
|
||||||
let estimated_time = $state({sum:0});
|
let estimated_time = $state({sum:0});
|
||||||
let project = $state(null);
|
let project = $state(null);
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
@@ -80,10 +82,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCreate(evt){
|
||||||
|
let json = JSON.parse(evt.data);
|
||||||
|
json.event = 'create';
|
||||||
|
lastEvent = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(evt){
|
||||||
|
let json = JSON.parse(evt.data);
|
||||||
|
json.event = 'delete';
|
||||||
|
lastEvent = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdate(evt){
|
||||||
|
let json = JSON.parse(evt.data);
|
||||||
|
json.event = 'update';
|
||||||
|
lastEvent = json;
|
||||||
|
}
|
||||||
|
|
||||||
function kanban(){
|
function kanban(){
|
||||||
router.navigate(`/project/${id}/kanban`);
|
router.navigate(`/project/${id}/kanban`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function load(){
|
||||||
|
eventSource = eventStream(handleCreate,handleUpdate,handleDelete);
|
||||||
|
loadProject();
|
||||||
|
}
|
||||||
|
|
||||||
async function loadProject(){
|
async function loadProject(){
|
||||||
const url = api(`project/${id}`);
|
const url = api(`project/${id}`);
|
||||||
const resp = await fetch(url,{credentials:'include'});
|
const resp = await fetch(url,{credentials:'include'});
|
||||||
@@ -162,7 +187,10 @@
|
|||||||
window.open(`/time?project=${id}`, '_blank').focus();
|
window.open(`/time?project=${id}`, '_blank').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(loadProject);
|
onMount(load);
|
||||||
|
onDestroy(() => {
|
||||||
|
if (eventSource) eventSource.close();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -265,7 +293,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tasks">
|
<div class="tasks">
|
||||||
{#if tasks}
|
{#if tasks}
|
||||||
<TaskList {tasks} {estimated_time} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
<TaskList {tasks} {estimated_time} {lastEvent} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
let {
|
let {
|
||||||
estimated_time,
|
estimated_time,
|
||||||
|
lastEvent,
|
||||||
show_closed,
|
show_closed,
|
||||||
siblings,
|
siblings,
|
||||||
states = {},
|
states = {},
|
||||||
@@ -141,6 +142,18 @@
|
|||||||
estimated_time.sum += task.estimated_time;
|
estimated_time.sum += task.estimated_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (lastEvent && lastEvent.task) {
|
||||||
|
if (children && lastEvent.task.parent_task_id == task.id) {
|
||||||
|
if (lastEvent.event == 'delete'){
|
||||||
|
delete children[lastEvent.task.id];
|
||||||
|
} else {
|
||||||
|
children[lastEvent.task.id] = lastEvent.task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
onMount(loadChildren);
|
onMount(loadChildren);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -170,7 +183,7 @@
|
|||||||
<button class="symbol" title={t('add_object',{object:t('subtask')})} onclick={addSubtask}></button>
|
<button class="symbol" title={t('add_object',{object:t('subtask')})} onclick={addSubtask}></button>
|
||||||
<button class="symbol" title={t('timetracking')} onclick={addTime}></button>
|
<button class="symbol" title={t('timetracking')} onclick={addTime}></button>
|
||||||
{#if children}
|
{#if children}
|
||||||
<TaskList {states} tasks={children} {estimated_time} {show_closed} />
|
<TaskList {states} {lastEvent} tasks={children} {estimated_time} {show_closed} />
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -2,14 +2,13 @@
|
|||||||
import { t } from '../../translations.svelte.js';
|
import { t } from '../../translations.svelte.js';
|
||||||
import ListTask from './ListTask.svelte';
|
import ListTask from './ListTask.svelte';
|
||||||
|
|
||||||
let { estimated_time, show_closed, states = {}, tasks } = $props();
|
let { estimated_time, lastEvent, show_closed, states = {}, tasks } = $props();
|
||||||
|
|
||||||
let sortedTasks = $derived.by(() => Object.values(tasks).sort((a, b) => a.name.localeCompare(b.name)));
|
let sortedTasks = $derived.by(() => Object.values(tasks).sort((a, b) => a.name.localeCompare(b.name)));
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
{#each sortedTasks as task}
|
{#each sortedTasks as task}
|
||||||
<ListTask {states} {task} siblings={tasks} {estimated_time} show_closed={show_closed || task.show_closed} />
|
<ListTask {states} {task} {lastEvent} siblings={tasks} {estimated_time} show_closed={show_closed || task.show_closed} />
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user