working on tagging system

This commit is contained in:
2025-07-27 23:37:23 +02:00
parent 4f54276e8f
commit e59e40b809
5 changed files with 75 additions and 34 deletions

View File

@@ -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 @@
}
}
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 @@
}
}
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 @@
}
}
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();

View File

@@ -9,6 +9,11 @@
({task.estimated_time} h)
</span>
{/if}
{#if task.tags}
<span class="tags">
{task.tags.join(' ')}
</span>
{/if}
{#if task.due_date}
<span class="due_date">
{#if task.start_date}

View File

@@ -44,8 +44,8 @@
return false;
}
async function loadTags(){
const url = api(`tags/${module}/${id}`);
async function loadTags(entityId){
const url = api(`tags/${module}/${entityId}`);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok) {
tags = await resp.json();
@@ -54,7 +54,7 @@
}
}
onMount(loadTags);
$effect(() => loadTags(id));
</script>
<style>

View File

@@ -290,7 +290,7 @@
{t('tags')}
</th>
<td class="tags">
<TagList module="task", {id} user_list={Object.keys(task.members).map(id => +id)} />
<TagList module="task" {id} user_list={Object.keys(task.members).map(id => +id)} />
</td>
</tr>
</tbody>

View File

@@ -45,6 +45,7 @@ footer {
}
nav {
position: sticky;
z-index: 100;
top: 0;
background: #26220c;
padding: 5px;
@@ -184,6 +185,19 @@ textarea{
right: 0;
}
.kanban .tags {
position: absolute;
left: 0;
bottom: 0;
font-size: 0.5em;
}
.kanban .user,
.kanban .head {
position: sticky;
top: 50px;
z-index: 20;
}
.project th,
.task th{
text-align: right;