Merge branch 'main' into module/files

This commit is contained in:
2025-09-29 19:58:06 +02:00
4 changed files with 18 additions and 3 deletions

View File

@@ -62,7 +62,9 @@ onMount(fetchModules);
<a href="/files" {onclick}>{t('files')}</a> <a href="/files" {onclick}>{t('files')}</a>
<a href="/time" {onclick}>{t('timetracking')}</a> <a href="/time" {onclick}>{t('timetracking')}</a>
<a href="/wiki" {onclick}>{t('wiki')}</a> <a href="/wiki" {onclick}>{t('wiki')}</a>
{#if user.id == 2}
<a href="https://svelte.dev/tutorial/svelte/state" target="_blank">{t('tutorial')}</a> <a href="https://svelte.dev/tutorial/svelte/state" target="_blank">{t('tutorial')}</a>
{/if}
{#each modules as module,i} {#each modules as module,i}
{#if module.name.trim()}<a href={module.url}>{module.name}</a>{/if} {#if module.name.trim()}<a href={module.url}>{module.name}</a>{/if}
{/each} {/each}

View File

@@ -26,6 +26,7 @@
let ranges = {}; let ranges = {};
let timeMap = $derived.by(calcYearMap); let timeMap = $derived.by(calcYearMap);
let selectionSum = $derived(sortedTimes.filter(time => selected[time.id]).map(time => time.duration).reduce((acc, a) => acc + a, 0)); let selectionSum = $derived(sortedTimes.filter(time => selected[time.id]).map(time => time.duration).reduce((acc, a) => acc + a, 0));
let users = null;
async function addTime(task_id){ async function addTime(task_id){
const url = api(`time/track_task/${task_id}`); const url = api(`time/track_task/${task_id}`);
@@ -107,6 +108,7 @@
tasks = json.tasks; tasks = json.tasks;
projects = json.projects; projects = json.projects;
docLinks = json.documents; docLinks = json.documents;
users = json.users;
} else { } else {
error(resp); error(resp);
} }
@@ -207,6 +209,7 @@
<th>{t('month')}</th> <th>{t('month')}</th>
<th>{t('start')}<wbr><wbr>{t('end')}</th> <th>{t('start')}<wbr><wbr>{t('end')}</th>
<th>{t('duration')}</th> <th>{t('duration')}</th>
<th>{t('user')}</th>
<th>{t('subject')}</th> <th>{t('subject')}</th>
<th>{t('projects')} / {t('tasks')}</th> <th>{t('projects')} / {t('tasks')}</th>
<th>{t('state')}</th> <th>{t('state')}</th>
@@ -232,7 +235,7 @@
{:else} {:else}
<td class="start_end" onclick={e => toggleSelect(time.id)}> <td class="start_end" onclick={e => toggleSelect(time.id)}>
{time.start}{#if time.end_time}<wbr><wbr>{time.start.startsWith(time.end_date)?time.end.substring(11):time.end}{/if} {time.start}{#if time.end_time}<wbr><wbr>{time.start.startsWith(time.end_date)?time.end.substring(11):time.end}{/if}
{#if line>0 && Math.abs(sortedTimes[line-1].start_time - time.end_time)<100} {#if line>0 && (sortedTimes[line-1].user_id == time.user_id) && (Math.abs(sortedTimes[line-1].start_time - time.end_time)<100)}
<button class="symbol join" title={t('join_objects',{objects:t('times')})} onclick={e => joinTimes(e, time.id, sortedTimes[line-1].id)} ></button> <button class="symbol join" title={t('join_objects',{objects:t('times')})} onclick={e => joinTimes(e, time.id, sortedTimes[line-1].id)} ></button>
{/if} {/if}
</td> </td>
@@ -241,6 +244,9 @@
{time.duration.toFixed(3)}&nbsp;h {time.duration.toFixed(3)}&nbsp;h
{/if} {/if}
</td> </td>
<td class="user">
{users[time.user_id].name}
</td>
<td class="subject" onclick={e => {detail = time.id}}> <td class="subject" onclick={e => {detail = time.id}}>
{time.subject} {time.subject}
</td> </td>

View File

@@ -117,7 +117,7 @@ public class NoteModule extends BaseHandler implements NoteService {
addCors(ex); addCors(ex);
try { try {
Optional<Token> token = SessionToken.from(ex).map(Token::of); Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = userService().loadUser(token); var user = userService().refreshSession(ex);
if (user.isEmpty()) return unauthorized(ex); if (user.isEmpty()) return unauthorized(ex);
var head = path.pop(); var head = path.pop();
long noteId = Long.parseLong(head); long noteId = Long.parseLong(head);

View File

@@ -196,14 +196,21 @@ public class TimeModule extends BaseHandler implements TimeService {
boolean showClosed = false; boolean showClosed = false;
var times = timeDb.listTimes(taskIds, showClosed); var times = timeDb.listTimes(taskIds, showClosed);
times.putAll(timeDb.listUserTimes(user.id(), showClosed)); times.putAll(timeDb.listUserTimes(user.id(), showClosed));
taskIds = times.values().stream().map(Time::taskIds).flatMap(Collection::stream).collect(toSet()); taskIds.clear();
var userIds = new HashSet<Long>();
times.values().forEach(time -> {
taskIds.addAll(time.taskIds());
userIds.add(time.userId());
});
var tasks = taskService().load(taskIds); var tasks = taskService().load(taskIds);
var users = userService().list(null,null,userIds);
var result = new HashMap<String,Object>(); var result = new HashMap<String,Object>();
var docList = documentService().docsReferencedByTimes(times.keySet()); var docList = documentService().docsReferencedByTimes(times.keySet());
result.put(DOCUMENTS,docList); result.put(DOCUMENTS,docList);
result.put(TIMES,mapValues(times)); result.put(TIMES,mapValues(times));
result.put(TASKS,mapValues(tasks)); result.put(TASKS,mapValues(tasks));
result.put(PROJECTS,mapValues(projects)); result.put(PROJECTS,mapValues(projects));
result.put(USERS,mapValues(users));
return sendContent(ex,result); return sendContent(ex,result);
} }