working on drag an drop of tasks. this is tricky.

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-07-31 00:52:19 +02:00
parent 99fa2ab1ce
commit bad323b7cc
4 changed files with 45 additions and 4 deletions

View File

@@ -18,7 +18,7 @@ import org.json.JSONObject;
public class Task implements Mappable { public class Task implements Mappable {
public static final System.Logger LOG = System.getLogger(Task.class.getSimpleName()); public static final System.Logger LOG = System.getLogger(Task.class.getSimpleName());
private final long id, projectId; private final long id, projectId;
private final Long parentTaskId; private Long parentTaskId;
private String description, name; private String description, name;
private Status status; private Status status;
private Double estimatedTime; private Double estimatedTime;
@@ -158,6 +158,7 @@ public class Task implements Mappable {
case MEMBERS: continue; case MEMBERS: continue;
case NAME: name = json.getString(key); break; case NAME: name = json.getString(key); break;
case NO_INDEX: noIndex = json.getBoolean(NO_INDEX); break; case NO_INDEX: noIndex = json.getBoolean(NO_INDEX); break;
case PARENT_TASK_ID: parentTaskId = json.getLong(PARENT_TASK_ID); break;
case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break; case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break;
case START_DATE: start = json.isNull(START_DATE) || json.getString(START_DATE).isBlank() ? null : LocalDate.parse(json.getString(START_DATE)); break; case START_DATE: start = json.isNull(START_DATE) || json.getString(START_DATE).isBlank() ? null : LocalDate.parse(json.getString(START_DATE)); break;
case STATUS: status = json.get(key) instanceof Number number ? Status.of(number.intValue()) : Status.valueOf(json.getString(key)); break; case STATUS: status = json.get(key) instanceof Number number ? Status.of(number.intValue()) : Status.valueOf(json.getString(key)); break;

View File

@@ -2,13 +2,18 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { useTinyRouter } from 'svelte-tiny-router'; import { useTinyRouter } from 'svelte-tiny-router';
import { dragged } from './dragndrop.svelte.js';
import { api } from '../../urls.svelte.js'; import { api } from '../../urls.svelte.js';
import { t } from '../../translations.svelte.js'; import { t } from '../../translations.svelte.js';
import TaskList from './TaskList.svelte'; import TaskList from './TaskList.svelte';
import LineEditor from '../../Components/LineEditor.svelte'; import LineEditor from '../../Components/LineEditor.svelte';
let { estimated_time, show_closed, task } = $props(); let {
estimated_time,
show_closed,
task
} = $props();
let children = $state(null); let children = $state(null);
let deleted = $state(false); let deleted = $state(false);
let error = $state(null); let error = $state(null);
@@ -34,6 +39,40 @@
} }
} }
function drag(ev,task){
ev.stopPropagation();
task.new_parent = false;
dragged.element = task;
}
function dragend(ev,task){
ev.stopPropagation();
setTimeout(() => {
if (dragged.moved){
console.log("removing",ev.target);
ev.target.remove();
}
},500);
}
async function dropAt(ev,target){
ev.stopPropagation();
if (dragged.element.id == target.id) return;
const url = api(`task/${dragged.element.id}`);
const resp = await fetch(url,{
credentials : 'include',
method : 'PATCH',
body : JSON.stringify({ parent_task_id : target.id})
});
if (resp.ok) {
dragged.moved = true;
children[dragged.element.id]=dragged.element;
} else {
error = await resp.text();
}
return false;
}
async function loadChildren(){ async function loadChildren(){
const url = api('task/list'); const url = api('task/list');
const data = { const data = {
@@ -80,14 +119,13 @@
if (task.estimated_time){ if (task.estimated_time){
estimated_time.sum += task.estimated_time; estimated_time.sum += task.estimated_time;
console.log(estimated_time)
} }
onMount(loadChildren); onMount(loadChildren);
</script> </script>
{#if !deleted} {#if !deleted}
<li class="task {task.status.name.toLowerCase()}"> <li draggable="true" ondrop={ev => dropAt(ev, task)} ondragover={e => e.preventDefault()} ondragend={e => dragend(e,task)} ondragstart={e => drag(e,task)} class="task {task.status.name.toLowerCase()}">
<LineEditor bind:value={task.name} onclick={openTask} editable={true} onSet={setName} type="a" /> <LineEditor bind:value={task.name} onclick={openTask} editable={true} onSet={setName} type="a" />
{#if task.estimated_time} {#if task.estimated_time}
<span class="estimated_time">({+task.estimated_time}&nbsp;h)</span> <span class="estimated_time">({+task.estimated_time}&nbsp;h)</span>

View File

@@ -5,6 +5,7 @@
let { estimated_time, show_closed, tasks } = $props(); let { estimated_time, show_closed, 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>

View File

@@ -0,0 +1 @@
export const dragged = $state({element:null,moved:false});