Compare commits

..

1 Commits

Author SHA1 Message Date
3b6e84d1af improved easylist: now toggling task state between pending and open
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
2026-02-02 23:12:23 +01:00
7 changed files with 25 additions and 98 deletions

View File

@@ -10,7 +10,6 @@
import Card from './KanbanCard.svelte';
import LineEditor from '../../Components/LineEditor.svelte';
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
import TaskForm from '../task/Add.svelte';
let eventSource = null;
let connectionStatus = 'disconnected';
@@ -27,7 +26,7 @@
let users = [];
let columns = $derived(project.allowed_states?Object.keys(project.allowed_states).length+1:1);
let info = $state(null);
let task_form = $state(false);
let stateList = {};
$effect(() => updateUrl(filter_input));
@@ -121,9 +120,7 @@
if (method != 'delete') processTask(json.task);
// show notification
if (json.user.id == user.id) {
if (method == 'create') task_form = false; // task has been created by current user
} else {
if (json.user.id != user.id) {
let term = "user_updated_entity";
if (method == 'create') term = "user_created_entity";
if (method == 'delete') term = "user_deleted_entity";
@@ -252,9 +249,6 @@
}
}
function show_task_form(project_id,assignee,state_id){
task_form = {project_id,assignee,state_id};
}
function updateUrl(){
let url = window.location.origin + window.location.pathname;
@@ -273,12 +267,6 @@
</svelte:head>
{#if project}
{#if task_form}
<div class="overlay">
<TaskForm assignee={task_form.assignee} on_abort={ev => {task_form = false;}} project_id={task_form.project_id} state_id={task_form.state_id} />
</div>
{/if} <!-- task form -->
<h1 onclick={ev => router.navigate(`/project/${project.id}/view`)}>{project.name}</h1>
{/if}
{#if info}
@@ -312,8 +300,8 @@
<Card onclick={e => openTask(task.id)} ondragstart={ev => dragged=task} {task} tag_colors={project.tag_colors} />
{/if}
{/each}
<div class="add_task" onclick={ev => show_task_form(project.id,u.id,+state)}>
{t('add_object',{object:t('task')})}
<div class="add_task">
<LineEditor value={t('add_object',{object:t('task')})} editable={true} onSet={(name) => create(name,u.id,state)}/>
</div>
</div>
{/each}
@@ -322,4 +310,4 @@
<div class="archive {highlight.archive?'hover':''}" ondragover={hover_archive} ondragleave={e => delete highlight.archive} ondrop={do_archive} >
{t('hide')}
</div>
{/if} <!-- project -->
{/if}

View File

@@ -2,7 +2,7 @@
import { onMount } from 'svelte';
import { useTinyRouter } from 'svelte-tiny-router';
import { api, get } from '../../urls.svelte.js';
import { api } from '../../urls.svelte.js';
import { error, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte.js';
import { user } from '../../user.svelte.js';
@@ -11,7 +11,7 @@
import PermissionEditor from '../../Components/PermissionEditor.svelte';
import Tags from '../tags/TagList.svelte';
let { assignee = null, on_abort = null, project_id = null, parent_task_id = null, state_id = null } = $props();
let { project_id = null, parent_task_id } = $props();
let project = $state(null);
let extendedSettings = $state(false);
let parent_task = $state(null);
@@ -20,7 +20,6 @@
description : { source : '', rendered : '' },
due_date : null,
est_time : null,
members : {},
no_index : false,
show_closed : false,
start_date : null,
@@ -45,32 +44,29 @@
async function load(){
if (parent_task_id) await loadParent();
if (project_id) loadProject();
if (state_id) task.status = { code : +state_id };
loadTags();
}
async function loadParent(){
const url = api(`task/${parent_task_id}`);
const resp = await get(url);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
parent_task = await resp.json();
task.parent_task_id = +parent_task_id;
project_id = +parent_task.project_id;
project_id = parent_task.project_id;
yikes();
project = null; // TODO
} else error(resp);
} else {
error(resp);
}
}
async function loadProject(){
const url = api(`project/${project_id}`);
const resp = await get(url);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
project = await resp.json();
task.project_id = +project_id;
if (assignee && project.members[assignee]){
task.members[assignee] = project.members[assignee];
task.members[assignee].permission = { name : "ASSIGNEE", code : 3 }
}
yikes();
} else {
error(resp);
@@ -82,7 +78,7 @@
if (project_id) url = api(`tags/project/${project_id}`);
if (parent_task_id) url = api(`tags/task/${parent_task_id}`);
if (url) {
const resp = await get(url);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok) task.tags = await resp.json();
}
}
@@ -111,12 +107,10 @@
body : JSON.stringify(task)
});
if (resp.ok) {
if (!assignee) { // if assignee is set, this form was opened within an external context. hence we don`t want to navigate somewhere else!
task = await resp.json();
if (task.parent_task_id){
router.navigate(`/task/${task.parent_task_id}/view`);
} else router.navigate(`/task/${task.id}/view`);
}
task = await resp.json();
if (task.parent_task_id){
router.navigate(`/task/${task.parent_task_id}/view`);
} else router.navigate(`/task/${task.id}/view`);
yikes();
} else {
error(resp);
@@ -189,7 +183,7 @@
{t('members')}
</th>
<td>
<PermissionEditor members={task.members} {addMember} {dropMember} {getCandidates} />
<PermissionEditor members={task.members} {addMember} {getCandidates} {dropMember} />
</td>
</tr>
<tr>
@@ -251,7 +245,4 @@
</tbody>
</table>
<button onclick={saveTask}>{t('save_object',{object:t('task')})}</button>
{#if on_abort}
<button onclick={on_abort}>{t('abort')}</button>
{/if}
</fieldset>
</fieldset>

View File

@@ -88,8 +88,8 @@
function onclick(evt) {
ignore(evt);
let task = getTask(evt);
if (task.status <= 20) { // open
update(task,60);
if (task.status == 20) { // open
update(task,10);
} else update(task,20);
return false;
}
@@ -153,7 +153,7 @@
<legend>{t('state_complete')}</legend>
{#if sorted}
{#each sorted as task}
{#if task.status > 20 && match(task)}
{#if task.status < 20 && match(task)}
<div href={`/task/${task.id}/view`} title={task.description.source} task_id={task.id} {onclick} {oncontextmenu} {ontouchstart} {ontouchend} onmousedown={ontouchstart} onmouseup={ontouchend} >
{task.name}
</div>

View File

@@ -270,7 +270,7 @@
<div>{t('members')}</div>
<div>
<PermissionEditor members={task.members} {addMember} {dropMember} {getCandidates} {updatePermission} />
<PermissionEditor members={task.members} {updatePermission} {addMember} {dropMember} {getCandidates} />
</div>
<div>{t('start_date')}</div>
<div>

View File

@@ -45,7 +45,7 @@ fieldset[tabindex="0"]{
overflow: hidden;
}
fieldset[tabindex="0"]:hover{
fieldset[tabindex="0"]:focus-within{
max-height: unset;
}
@@ -91,26 +91,6 @@ td, tr{
border-radius: 6px;
}
.info {
position: absolute;
bottom: 0;
right: 0;
font-size: 14px;
z-index: 200;
padding: 3px;
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
padding: 40px 10px 10px;
background: rgba(0,0,0,0.9);
z-index: 50;
}
.warn {
padding: 5px;
border-radius: 6px;

View File

@@ -183,17 +183,6 @@ td, tr{
padding: 3px;
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
padding: 40px 10px 10px;
background: rgba(0,0,0,0.9);
z-index: 50;
}
.warn {
padding: 5px;
border-radius: 6px;

View File

@@ -91,26 +91,6 @@ td, tr{
border-radius: 6px;
}
.info {
position: absolute;
bottom: 0;
right: 0;
font-size: 14px;
z-index: 200;
padding: 3px;
}
.overlay {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
padding: 40px 10px 10px;
background: rgba(255,255,255,0.9);
z-index: 50;
}
.warn {
padding: 5px;
border-radius: 6px;
@@ -255,7 +235,6 @@ textarea{
.message.settings label{
display: block;
}
.message.settings td{
vertical-align: middle;
}