fine-tuning kanban
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -19,11 +19,13 @@
|
|||||||
let columns = $derived(states?Object.keys(states).length+1:1);
|
let columns = $derived(states?Object.keys(states).length+1:1);
|
||||||
let dragged = null;
|
let dragged = null;
|
||||||
let users = {};
|
let users = {};
|
||||||
|
let ready = $state(false);
|
||||||
|
|
||||||
async function load(){
|
async function load(){
|
||||||
loadProject();
|
await loadProject();
|
||||||
loadStates();
|
await loadStates();
|
||||||
await loadTasks({project_id:+id,parent_task_id:0});
|
await loadTasks({project_id:+id,parent_task_id:0});
|
||||||
|
ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadProject(){
|
async function loadProject(){
|
||||||
@@ -31,6 +33,11 @@
|
|||||||
const resp = await fetch(url,{credentials:'include'});
|
const resp = await fetch(url,{credentials:'include'});
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
project = await resp.json();
|
project = await resp.json();
|
||||||
|
for (var uid of Object.keys(project.members)){
|
||||||
|
let member = project.members[uid];
|
||||||
|
users[uid] = member.user.name;
|
||||||
|
if (!tasks[uid]) tasks[uid] = {};
|
||||||
|
}
|
||||||
error = null;
|
error = null;
|
||||||
} else {
|
} else {
|
||||||
error = await resp.text();
|
error = await resp.text();
|
||||||
@@ -68,7 +75,7 @@
|
|||||||
var member = task.members[user_id];
|
var member = task.members[user_id];
|
||||||
if (member.permission.name == 'OWNER') owner = user_id;
|
if (member.permission.name == 'OWNER') owner = user_id;
|
||||||
if (member.permission.name == 'ASSIGNEE') assignee = user_id;
|
if (member.permission.name == 'ASSIGNEE') assignee = user_id;
|
||||||
users[user_id] = member.user.name;
|
|
||||||
}
|
}
|
||||||
if (!assignee) assignee = owner;
|
if (!assignee) assignee = owner;
|
||||||
task.assignee = assignee;
|
task.assignee = assignee;
|
||||||
@@ -116,31 +123,6 @@
|
|||||||
onMount(load);
|
onMount(load);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.box,
|
|
||||||
.head,
|
|
||||||
.user{
|
|
||||||
border-radius: 5px;
|
|
||||||
margin: 2px;
|
|
||||||
min-height: 50px;
|
|
||||||
color: black;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
.box{
|
|
||||||
background: orange;
|
|
||||||
}
|
|
||||||
.head,
|
|
||||||
.user{
|
|
||||||
background: black;
|
|
||||||
border: 1px solid orange;
|
|
||||||
color: orange;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.highlight{
|
|
||||||
background: #4b3000;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{#if project}
|
{#if project}
|
||||||
<h1 onclick={ev => router.navigate(`/project/${project.id}/view`)}>{project.name}</h1>
|
<h1 onclick={ev => router.navigate(`/project/${project.id}/view`)}>{project.name}</h1>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -148,6 +130,7 @@
|
|||||||
<span class="error">{error}</span>
|
<span class="error">{error}</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if ready}
|
||||||
<div class="kanban" style="display: grid; grid-template-columns: {`repeat(${columns}, auto)`}">
|
<div class="kanban" style="display: grid; grid-template-columns: {`repeat(${columns}, auto)`}">
|
||||||
<div class="head">{t('user')}</div>
|
<div class="head">{t('user')}</div>
|
||||||
{#if states}
|
{#if states}
|
||||||
@@ -155,10 +138,10 @@
|
|||||||
<div class="head">{t('state_'+state.toLowerCase())}</div>
|
<div class="head">{t('state_'+state.toLowerCase())}</div>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
{#each Object.entries(tasks) as [user,stateList]}
|
{#each Object.entries(tasks) as [uid,stateList]}
|
||||||
<div class="user">{users[user]}</div>
|
<div class="user">{users[uid]}</div>
|
||||||
{#each Object.entries(states) as [state,name]}
|
{#each Object.entries(states) as [state,name]}
|
||||||
<div class={[state, highlight.user == user && highlight.state == state ? 'highlight':'']} ondragover={ev => hover(ev,user,state)} ondrop={ev => drop(user,state)} >
|
<div class={[state, highlight.user == uid && highlight.state == state ? 'highlight':'']} ondragover={ev => hover(ev,uid,state)} ondrop={ev => drop(uid,state)} >
|
||||||
{#if stateList[state]}
|
{#if stateList[state]}
|
||||||
{#each Object.values(stateList[state]).sort((a,b) => a.name.localeCompare(b.name)) as task}
|
{#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} />
|
<Card onclick={() => router.navigate(`/task/${task.id}/view`)} ondragstart={ev => dragged=task} {task} />
|
||||||
@@ -168,3 +151,4 @@
|
|||||||
{/each}
|
{/each}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
@@ -1,7 +1,21 @@
|
|||||||
<script>
|
<script>
|
||||||
let { ondragstart, task } = $props();
|
let { onclick, ondragstart, task } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div draggable="true" class="box" {ondragstart} >
|
<div draggable="true" class="box" {onclick} {ondragstart} >
|
||||||
{task.name}
|
<span class="title">{task.name}</span>
|
||||||
|
{#if task.estimated_time}
|
||||||
|
<span class="estimate">
|
||||||
|
({task.estimated_time} h)
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if task.due_date}
|
||||||
|
<span class="due_date">
|
||||||
|
{#if task.start_date}
|
||||||
|
{task.start_date}
|
||||||
|
{/if}
|
||||||
|
→ {task.due_date}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -154,6 +154,7 @@ textarea{
|
|||||||
}
|
}
|
||||||
.kanban .box{
|
.kanban .box{
|
||||||
background: orange;
|
background: orange;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.kanban .head,
|
.kanban .head,
|
||||||
.kanban .user{
|
.kanban .user{
|
||||||
@@ -165,3 +166,18 @@ textarea{
|
|||||||
.kanban .highlight{
|
.kanban .highlight{
|
||||||
background: #4b3000;
|
background: #4b3000;
|
||||||
}
|
}
|
||||||
|
.kanban .estimate{
|
||||||
|
border: 0 none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
.kanban .due_date{
|
||||||
|
position: absolute;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 0.6em;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user