|
|
|
|
@ -11,17 +11,17 @@
@@ -11,17 +11,17 @@
|
|
|
|
|
|
|
|
|
|
let { id } = $props(); |
|
|
|
|
|
|
|
|
|
let dragged = null; |
|
|
|
|
let error = $state(null); |
|
|
|
|
let highlight = $state({}); |
|
|
|
|
let project = $state(null); |
|
|
|
|
let ready = $state(false); |
|
|
|
|
let router = useTinyRouter(); |
|
|
|
|
let states = $state(null); |
|
|
|
|
let tasks = $state({}); |
|
|
|
|
let highlight = $state({}); |
|
|
|
|
let users = {}; |
|
|
|
|
|
|
|
|
|
let columns = $derived(states?Object.keys(states).length+1:1); |
|
|
|
|
let dragged = null; |
|
|
|
|
let users = {}; |
|
|
|
|
let ready = $state(false); |
|
|
|
|
|
|
|
|
|
async function create(name,user_id,state){ |
|
|
|
|
var url = api('task/add'); |
|
|
|
|
@ -51,11 +51,39 @@
@@ -51,11 +51,39 @@
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function drop(user_id,state){ |
|
|
|
|
let task = dragged; |
|
|
|
|
dragged = null; |
|
|
|
|
highlight = {}; |
|
|
|
|
if (task.assignee == user_id && task.status.code == state) return; // no change |
|
|
|
|
let patch = {members:{},status:+state} |
|
|
|
|
patch.members[user_id] = 'ASSIGNEE'; |
|
|
|
|
|
|
|
|
|
const url = api(`task/${task.id}`); |
|
|
|
|
const resp = await fetch(url,{ |
|
|
|
|
credentials: 'include', |
|
|
|
|
method: 'PATCH', |
|
|
|
|
body: JSON.stringify(patch) |
|
|
|
|
}); |
|
|
|
|
if (resp.ok){ |
|
|
|
|
delete tasks[task.assignee][task.status.code][task.id] |
|
|
|
|
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 { |
|
|
|
|
error = await resp.text(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function load(){ |
|
|
|
|
await loadProject(); |
|
|
|
|
await loadStates(); |
|
|
|
|
await loadTasks({project_id:+id,parent_task_id:0}); |
|
|
|
|
ready = true; |
|
|
|
|
loadTags(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function loadProject(){ |
|
|
|
|
@ -85,6 +113,26 @@
@@ -85,6 +113,26 @@
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function loadTag(task){ |
|
|
|
|
const url = api(`tags/task/${task.id}`); |
|
|
|
|
const resp = await fetch(url,{credentials:'include'}); |
|
|
|
|
if (resp.ok) { |
|
|
|
|
const tags = await resp.json(); |
|
|
|
|
if (tags.length) task.tags = tags.sort(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function loadTags(){ |
|
|
|
|
for (let uid of Object.keys(tasks)){ |
|
|
|
|
for (let state of Object.keys(tasks[uid])){ |
|
|
|
|
for (let tid of Object.keys(tasks[uid][state])){ |
|
|
|
|
const task = tasks[uid][state][tid]; |
|
|
|
|
loadTag(task); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function loadTasks(selector){ |
|
|
|
|
const url = api('task/list'); |
|
|
|
|
selector.show_closed = true; |
|
|
|
|
@ -118,32 +166,6 @@
@@ -118,32 +166,6 @@
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function drop(user_id,state){ |
|
|
|
|
let task = dragged; |
|
|
|
|
dragged = null; |
|
|
|
|
highlight = {}; |
|
|
|
|
if (task.assignee == user_id && task.status.code == state) return; // no change |
|
|
|
|
let patch = {members:{},status:+state} |
|
|
|
|
patch.members[user_id] = 'ASSIGNEE'; |
|
|
|
|
|
|
|
|
|
const url = api(`task/${task.id}`); |
|
|
|
|
const resp = await fetch(url,{ |
|
|
|
|
credentials: 'include', |
|
|
|
|
method: 'PATCH', |
|
|
|
|
body: JSON.stringify(patch) |
|
|
|
|
}); |
|
|
|
|
if (resp.ok){ |
|
|
|
|
delete tasks[task.assignee][task.status.code][task.id] |
|
|
|
|
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 { |
|
|
|
|
error = await resp.text(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function hover(ev,user_id,state){ |
|
|
|
|
ev.preventDefault(); |
|
|
|
|
|