working on tagging system
This commit is contained in:
@@ -11,17 +11,17 @@
|
|||||||
|
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
|
|
||||||
|
let dragged = null;
|
||||||
let error = $state(null);
|
let error = $state(null);
|
||||||
|
let highlight = $state({});
|
||||||
let project = $state(null);
|
let project = $state(null);
|
||||||
|
let ready = $state(false);
|
||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
let states = $state(null);
|
let states = $state(null);
|
||||||
let tasks = $state({});
|
let tasks = $state({});
|
||||||
let highlight = $state({});
|
let users = {};
|
||||||
|
|
||||||
let columns = $derived(states?Object.keys(states).length+1:1);
|
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){
|
async function create(name,user_id,state){
|
||||||
var url = api('task/add');
|
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(){
|
async function load(){
|
||||||
await loadProject();
|
await loadProject();
|
||||||
await loadStates();
|
await loadStates();
|
||||||
await loadTasks({project_id:+id,parent_task_id:0});
|
await loadTasks({project_id:+id,parent_task_id:0});
|
||||||
ready = true;
|
ready = true;
|
||||||
|
loadTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadProject(){
|
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){
|
async function loadTasks(selector){
|
||||||
const url = api('task/list');
|
const url = api('task/list');
|
||||||
selector.show_closed = true;
|
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){
|
function hover(ev,user_id,state){
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
({task.estimated_time} h)
|
({task.estimated_time} h)
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if task.tags}
|
||||||
|
<span class="tags">
|
||||||
|
{task.tags.join(' ')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
{#if task.due_date}
|
{#if task.due_date}
|
||||||
<span class="due_date">
|
<span class="due_date">
|
||||||
{#if task.start_date}
|
{#if task.start_date}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTags(){
|
async function loadTags(entityId){
|
||||||
const url = api(`tags/${module}/${id}`);
|
const url = api(`tags/${module}/${entityId}`);
|
||||||
const resp = await fetch(url,{credentials:'include'});
|
const resp = await fetch(url,{credentials:'include'});
|
||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
tags = await resp.json();
|
tags = await resp.json();
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(loadTags);
|
$effect(() => loadTags(id));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -290,7 +290,7 @@
|
|||||||
{t('tags')}
|
{t('tags')}
|
||||||
</th>
|
</th>
|
||||||
<td class="tags">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ footer {
|
|||||||
}
|
}
|
||||||
nav {
|
nav {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
|
z-index: 100;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: #26220c;
|
background: #26220c;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@@ -184,6 +185,19 @@ textarea{
|
|||||||
right: 0;
|
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,
|
.project th,
|
||||||
.task th{
|
.task th{
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|||||||
Reference in New Issue
Block a user