implemented editing of 'show closed tasks' setting in project

This commit is contained in:
2025-07-22 20:33:28 +02:00
parent 1e439b87ac
commit b03b0683bc
7 changed files with 45 additions and 20 deletions

View File

@@ -13,7 +13,7 @@ import org.json.JSONObject;
public class Project implements Mappable { public class Project implements Mappable {
private final Map<Long,Member> members; private final Map<Long,Member> members;
private final boolean showClosed; private boolean showClosed;
private final Long companyId; private final Long companyId;
private Status status; private Status status;
private String name; private String name;
@@ -67,9 +67,10 @@ public class Project implements Mappable {
public Project patch(JSONObject json) { public Project patch(JSONObject json) {
for (var key : json.keySet()){ for (var key : json.keySet()){
switch (key){ switch (key){
case DESCRIPTION: description = json.getString(key); break; case DESCRIPTION: description = json.getString(key); break;
case NAME: name = json.getString(key); break; case NAME: name = json.getString(key); break;
case STATUS: status = json.get(key) instanceof Number number ? Status.of(number.intValue()) : Status.valueOf(json.getString(key)); break; case SHOW_CLOSED: showClosed = json.getBoolean(SHOW_CLOSED); break;
case STATUS: status = json.get(key) instanceof Number number ? Status.of(number.intValue()) : Status.valueOf(json.getString(key)); break;
default: key = null; default: key = null;
} }
if (key != null) dirtyFields.add(key); if (key != null) dirtyFields.add(key);

View File

@@ -6,13 +6,16 @@
import TaskList from './TaskList.svelte'; import TaskList from './TaskList.svelte';
const router = useTinyRouter(); const router = useTinyRouter();
let { estimated_time, task } = $props(); let { estimated_time, show_closed, task } = $props();
let children = $state(null); let children = $state(null);
let error = $state(null); let error = $state(null);
async function loadChildren(){ async function loadChildren(){
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/task/list`; const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/task/list`;
var data = {parent_task_id:+task.id}; var data = {
parent_task_id:+task.id,
show_closed: show_closed
};
if (task.show_closed) data.show_closed = true; if (task.show_closed) data.show_closed = true;
const resp = await fetch(url,{ const resp = await fetch(url,{
credentials:'include', credentials:'include',
@@ -52,6 +55,6 @@
<span class="error">{error}</span> <span class="error">{error}</span>
{/if} {/if}
{#if children} {#if children}
<TaskList tasks={children} {estimated_time} /> <TaskList tasks={children} {estimated_time} {show_closed} />
{/if} {/if}
</li> </li>

View File

@@ -50,13 +50,12 @@
{#if error} {#if error}
<span class="error">{error}</span> <span class="error">{error}</span>
{/if} {/if}
<table> <fieldset>
<tbody> <legend>{t('members')}</legend>
<table>
<tbody>
{#each sortedMembers as member,i} {#each sortedMembers as member,i}
<tr> <tr>
{#if !i}
<th rowspan={sortedMembers.length}>{t('members')}</th>
{/if}
<td>{member.user.name}</td> <td>{member.user.name}</td>
<td> <td>
<PermissionSelector {permissions} selected={member.permission.code} onchange={(perm) => updatePermission(member.user.id,perm)} /> <PermissionSelector {permissions} selected={member.permission.code} onchange={(perm) => updatePermission(member.user.id,perm)} />
@@ -67,11 +66,10 @@
</tr> </tr>
{/each} {/each}
<tr> <tr>
<td></td>
<td>{t('add_member')}</td> <td>{t('add_member')}</td>
<td> <td>
<Autocomplete {getOptionsFor} {onSelect} /> <Autocomplete {getOptionsFor} {onSelect} />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table></fieldset>

View File

@@ -2,7 +2,7 @@
import { t } from '../translations.svelte.js'; import { t } from '../translations.svelte.js';
import ListTask from './ListTask.svelte'; import ListTask from './ListTask.svelte';
let { estimated_time, tasks } = $props(); let { estimated_time, show_closed, tasks } = $props();
let sortedTasks = $derived.by(() => Object.values(tasks).sort((a, b) => a.name.localeCompare(b.name))); let sortedTasks = $derived.by(() => Object.values(tasks).sort((a, b) => a.name.localeCompare(b.name)));
@@ -11,6 +11,6 @@
<ul> <ul>
{#each sortedTasks as task} {#each sortedTasks as task}
<ListTask {task} {estimated_time} /> <ListTask {task} {estimated_time} show_closed={show_closed || task.show_closed} />
{/each} {/each}
</ul> </ul>

View File

@@ -20,6 +20,11 @@
if (ids) update({new_member:+ids.pop()}); if (ids) update({new_member:+ids.pop()});
} }
function changeClosed(){
update({show_closed:project.show_closed});
loadTasks();
}
async function dropMember(member){ async function dropMember(member){
update({drop_member:member.user.id}); update({drop_member:member.user.id});
} }
@@ -38,12 +43,18 @@
async function loadTasks(){ async function loadTasks(){
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/task/list`; const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/task/list`;
const data = {
project_id:+id,
show_closed:project.show_closed
}
const resp = await fetch(url,{ const resp = await fetch(url,{
credentials:'include', credentials:'include',
method:'POST', method:'POST',
body:JSON.stringify({project_id:+id}) body:JSON.stringify(data)
}); });
if (resp.ok){ if (resp.ok){
tasks = {};
estimated_time.sum = 0;
tasks = await resp.json(); tasks = await resp.json();
error = null; error = null;
} else { } else {
@@ -125,7 +136,7 @@
<th>{t('tasks')}</th> <th>{t('tasks')}</th>
<td class="tasks"> <td class="tasks">
{#if tasks} {#if tasks}
<TaskList {tasks} {estimated_time} /> <TaskList {tasks} {estimated_time} show_closed={project.show_closed} />
{/if} {/if}
</td> </td>
</tr> </tr>
@@ -136,5 +147,13 @@
<fieldset class="project settings"> <fieldset class="project settings">
<legend>{t('settings')}</legend> <legend>{t('settings')}</legend>
<MemberEditor members={project.members} {updatePermission} {addMember} {dropMember} /> <MemberEditor members={project.members} {updatePermission} {addMember} {dropMember} />
<fieldset>
<legend>{t('miscellaneous_settings')}</legend>
<label>
<input type="checkbox" bind:checked={project.show_closed} onchange={changeClosed} />
{t('display_closed_tasks')}
</label>
</fieldset>
<button onclick={() => showSettings = false}>{t('close_settings')}</button>
</fieldset> </fieldset>
{/if} {/if}

View File

@@ -100,6 +100,7 @@
"members": "Mitarbeiter", "members": "Mitarbeiter",
"message": "Nachricht", "message": "Nachricht",
"messages": "Benachrichtigungen", "messages": "Benachrichtigungen",
"miscellaneous_settings": "sonstige Einstellungen",
"model": "Modell", "model": "Modell",
"models": "Modelle", "models": "Modelle",
"module": { "module": {

View File

@@ -81,7 +81,10 @@ td, tr{
background: rgba(0,0,0,0.7); background: rgba(0,0,0,0.7);
backdrop-filter: blur(3px); backdrop-filter: blur(3px);
} }
.task.cancelled > .name {
text-decoration: line-through;
color: gray;
}
.task.started > .name { .task.started > .name {
color: green; color: green;
} }