implemented listing users on task index page

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-11-28 08:49:51 +01:00
parent 21759d1b12
commit 146ea80e4e
2 changed files with 22 additions and 24 deletions

View File

@@ -2,7 +2,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { useTinyRouter } from 'svelte-tiny-router'; import { useTinyRouter } from 'svelte-tiny-router';
import { api } from '../../urls.svelte.js'; import { api, get, patch } from '../../urls.svelte.js';
import { error, yikes } from '../../warn.svelte'; import { error, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte.js'; import { t } from '../../translations.svelte.js';
@@ -23,16 +23,10 @@
const prj = projects[task.project_id]; const prj = projects[task.project_id];
const stat = Object.keys(prj.allowed_states).find(k => prj.allowed_states[k] === state); const stat = Object.keys(prj.allowed_states).find(k => prj.allowed_states[k] === state);
const url = api(`task/${tid}`); const url = api(`task/${tid}`);
const resp = await fetch(url,{ const resp = await patch(url,{status:stat});
credentials : 'include',
method : 'PATCH',
body : JSON.stringify({status:stat})
});
if (resp.ok){ if (resp.ok){
tasks[idx] = await resp.json(); tasks[idx] = await resp.json();
} else { } else error(resp);
error(resp);
}
} }
function abort(idx){ function abort(idx){
@@ -66,17 +60,15 @@
async function loadProject(pid){ async function loadProject(pid){
const url = api(`project/${pid}`); const url = api(`project/${pid}`);
const resp = await fetch(url,{credentials:'include'}); const resp = await get(url);
if (resp.ok){ if (resp.ok){
projects[pid] = await resp.json(); projects[pid] = await resp.json();
} else { } else error(resp);
error(resp);
}
} }
async function load(){ async function load(){
const url = api(`task?offset=${bounds.offset}&limit=${bounds.limit}`); const url = api(`task?offset=${bounds.offset}&limit=${bounds.limit}`);
const resp = await fetch(url,{credentials:'include'}); const resp = await get(url);
if (resp.ok){ if (resp.ok){
let newTasks = await resp.json(); let newTasks = await resp.json();
if (bounds.offset == 0) { if (bounds.offset == 0) {
@@ -93,9 +85,7 @@
bounds.offset += bounds.limit; bounds.offset += bounds.limit;
load(); load();
} }
} else { } else error(resp);
error(resp);
}
} }
function open(idx){ function open(idx){
@@ -139,13 +129,14 @@
<th>{t('state')}</th> <th>{t('state')}</th>
<th>{t('start_date')}</th> <th>{t('start_date')}</th>
<th>{t('due_date')}</th> <th>{t('due_date')}</th>
<th>{t('users')}</th>
<th>{t('actions')}</th> <th>{t('actions')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each tasks as task,idx} {#each tasks as task,idx}
{#if task.status > 10 && task.status < 60 && !task.no_index && projects[task.project_id]?.status < 60 && !hidden[task.id] && filterApplies(task)} {#if task.status > 10 && task.status < 60 && !task.no_index && projects[task.project_id]?.status < 60 && !hidden[task.id] && filterApplies(task)}
<tr> <tr title={task.description.source}>
<td onclick={() => go('task',task.id)}>{task.name}</td> <td onclick={() => go('task',task.id)}>{task.name}</td>
<td> <td>
<a href="#" onclick={() => go('project',task.project_id)}> {projects[task.project_id]?.name}</a> <a href="#" onclick={() => go('project',task.project_id)}> {projects[task.project_id]?.name}</a>
@@ -162,6 +153,16 @@
<td> <td>
{task.due_date} {task.due_date}
</td> </td>
<td>
<ul>
{#each Object.values(task.members) as member}
<li>
{member.user.name}:
{t('permission_'+member.permission.name.toLowerCase())}
</li>
{/each}
</ul>
</td>
<td> <td>
<button class="symbol" onclick={() => edit(task.id)} title={t('edit')} ></button> <button class="symbol" onclick={() => edit(task.id)} title={t('edit')} ></button>
<button class="symbol" onclick={() => postpone(idx)} title={t('postpone')} ></button> <button class="symbol" onclick={() => postpone(idx)} title={t('postpone')} ></button>

View File

@@ -199,12 +199,9 @@ public class TaskModule extends BaseHandler implements TaskService {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw invalidFieldException(LIMIT, "number"); throw invalidFieldException(LIMIT, "number");
} }
Set<Long> projectIds = projectService().listUserProjects(user.id(), true).keySet(); var tasks = taskDb.listUserTasks(user.id(), limit, offset, false);
var list = taskDb.listUserTasks(user.id(), limit, offset, false).stream() var mapped = loadMembers(tasks).stream().map(Task::toMap);
.filter(task -> projectIds.contains(task.projectId())) // drop tasks assigned to project we are not member of return sendContent(ex, mapped);
.map(Task::toMap)
.toList();
return sendContent(ex, list);
} }
@Override @Override