implemented task creation right from the canban

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-07-27 14:55:10 +02:00
parent 65102df091
commit 3b163a0d77
6 changed files with 64 additions and 20 deletions

View File

@@ -25,6 +25,7 @@
import ViewTask from "./routes/task/View.svelte";
let translations_ready = $state(false);
onMount(async () => {
await loadTranslation('de','Login');
translations_ready = true;

View File

@@ -4,7 +4,7 @@
let {
editable = false,
onclick = evt => {},
onclick = evt => { startEdit() },
onSet = newVal => {return true;},
type = 'div',
value = $bindable(null)
@@ -84,5 +84,5 @@
{#if editable && editing}
<input bind:value={editValue} onkeyup={typed} autofocus />
{:else}
<svelte:element this={type} {onmousedown} {onmouseup} {ontouchstart} {ontouchend} class={{editable}} title={t('double_click_to_edit')} >{value}</svelte:element>
<svelte:element this={type} {onclick} {onmousedown} {onmouseup} {ontouchstart} {ontouchend} class={{editable}} title={t('double_click_to_edit')} >{value}</svelte:element>
{/if}

View File

@@ -4,8 +4,10 @@
import { api } from '../../urls.svelte.js';
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
import Card from './KanbanCard.svelte';
import LineEditor from '../../Components/LineEditor.svelte';
let { id } = $props();
@@ -21,6 +23,34 @@
let users = {};
let ready = $state(false);
async function create(name,user_id,state){
var url = api('task/add');
let task = {
description: '',
members : {},
name: name,
project_id: +id,
status : { code : +state}
}
task.members[user_id] = { permission: { name : 'ASSIGNEE' }};
task.members[user.id] = { permission: { name : 'OWNER' }};
const resp = await fetch(url,{
credentials:'include',
method:'POST',
body: JSON.stringify(task)
});
if (resp.ok) {
task = await resp.json();
task.assignee = user_id;
if (!tasks[user_id]) tasks[user_id] = {};
if (!tasks[user_id][state]) tasks[user_id][state] = {};
tasks[user_id][state][task.id] = task;
error = null;
} else {
error = await resp.text();
}
}
async function load(){
await loadProject();
await loadStates();
@@ -88,13 +118,13 @@
}
}
async function drop(user,state){
async function drop(user_id,state){
let task = dragged;
dragged = null;
highlight = {};
if (task.assignee == user && task.status.code == state) return; // no change
if (task.assignee == user_id && task.status.code == state) return; // no change
let patch = {members:{},status:+state}
patch.members[user] = 'ASSIGNEE';
patch.members[user_id] = 'ASSIGNEE';
const url = api(`task/${task.id}`);
const resp = await fetch(url,{
@@ -104,10 +134,10 @@
});
if (resp.ok){
delete tasks[task.assignee][task.status.code][task.id]
if (!tasks[user]) tasks[user] = {}
if (!tasks[user][state]) tasks[user][state] = {}
tasks[user][state][task.id] = task;
task.assignee = user;
if (!tasks[user_id]) tasks[user_id] = {}
if (!tasks[user_id][state]) tasks[user_id][state] = {}
tasks[user_id][state][task.id] = task;
task.assignee = user_id;
task.status = {code:state,name:states[state]};
error = null;
} else {
@@ -115,9 +145,9 @@
}
}
function hover(ev,user,state){
function hover(ev,user_id,state){
ev.preventDefault();
highlight = {user:user,state:state};
highlight = {user:user_id,state:state};
}
onMount(load);
@@ -142,11 +172,14 @@
<div class="user">{users[uid]}</div>
{#each Object.entries(states) as [state,name]}
<div class={[state, highlight.user == uid && highlight.state == state ? 'highlight':'']} ondragover={ev => hover(ev,uid,state)} ondrop={ev => drop(uid,state)} >
{#if stateList[state]}
{#each Object.values(stateList[state]).sort((a,b) => a.name.localeCompare(b.name)) as task}
<Card onclick={() => router.navigate(`/task/${task.id}/view`)} ondragstart={ev => dragged=task} {task} />
{/each}
{/if}
{#if stateList[state]}
{#each Object.values(stateList[state]).sort((a,b) => a.name.localeCompare(b.name)) as task}
<Card onclick={() => router.navigate(`/task/${task.id}/view`)} ondragstart={ev => dragged=task} {task} />
{/each}
{/if}
<div class="add_task">
<LineEditor value={t('add_task')} editable={true} onSet={(name) => create(name,uid,state)}/>
</div>
</div>
{/each}
{/each}