implemented selection of timetrack entries and display of sum of durations of selected records
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -14,6 +14,10 @@
|
|||||||
<form {onsubmit}>
|
<form {onsubmit}>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{t('edit_object',{object:t('record')})}</legend>
|
<legend>{t('edit_object',{object:t('record')})}</legend>
|
||||||
|
<label>
|
||||||
|
{t('subject')}
|
||||||
|
<input type="text" bind:value={record.subject} />
|
||||||
|
</label>
|
||||||
<label>
|
<label>
|
||||||
{t('start')}
|
{t('start')}
|
||||||
<input type="datetime-local" bind:value={record.start_time} />
|
<input type="datetime-local" bind:value={record.start_time} />
|
||||||
@@ -22,10 +26,6 @@
|
|||||||
{t('end')}
|
{t('end')}
|
||||||
<input type="datetime-local" bind:value={record.end_time} />
|
<input type="datetime-local" bind:value={record.end_time} />
|
||||||
</label>
|
</label>
|
||||||
<label>
|
|
||||||
{t('subject')}
|
|
||||||
<input type="text" bind:value={record.subject} />
|
|
||||||
</label>
|
|
||||||
<label>
|
<label>
|
||||||
{t('description')}
|
{t('description')}
|
||||||
<MarkdownEditor simple={true} bind:value={record.description} />
|
<MarkdownEditor simple={true} bind:value={record.description} />
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
let sortedTimes = $derived.by(() => Object.values(times).sort((b, a) => a.start_time.localeCompare(b.start_time)));
|
let sortedTimes = $derived.by(() => Object.values(times).sort((b, a) => a.start_time.localeCompare(b.start_time)));
|
||||||
let selected = $state({});
|
let selected = $state({});
|
||||||
let ranges = {};
|
let ranges = {};
|
||||||
let timeMap = $derived.by(() => {
|
let timeMap = $derived.by(calcYearMap);
|
||||||
|
let selectionSum = $derived(sortedTimes.filter(time => selected[time.id]).map(time => time.duration).reduce((acc, a) => acc + a, 0));
|
||||||
|
|
||||||
|
function calcYearMap(){
|
||||||
let result = {
|
let result = {
|
||||||
months : {},
|
months : {},
|
||||||
years : {}
|
years : {}
|
||||||
@@ -42,17 +45,10 @@
|
|||||||
monthCount = 0;
|
monthCount = 0;
|
||||||
monthIndex = idx;
|
monthIndex = idx;
|
||||||
}
|
}
|
||||||
monthCount +=1;
|
monthCount +=1;
|
||||||
}
|
}
|
||||||
if (yearCount) result.years[yearIndex] = yearCount;
|
if (yearCount) result.years[yearIndex] = yearCount;
|
||||||
if (monthCount) result.months[monthIndex] = monthCount;
|
if (monthCount) result.months[monthIndex] = monthCount;
|
||||||
console.log(result);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
function calcYearMap(){
|
|
||||||
let result = Object.values(times).length;
|
|
||||||
console.log({result:result});
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,27 +111,22 @@
|
|||||||
onMount(loadTimes);
|
onMount(loadTimes);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
td { vertical-align: top; }
|
|
||||||
.year, .month{
|
|
||||||
border: 1px solid;
|
|
||||||
}
|
|
||||||
.selected td:not(.year):not(.month){
|
|
||||||
background: navy;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1>{t('timetracking')}</h1>
|
<h1>{t('timetracking')}</h1>
|
||||||
{#if error}
|
{#if error}
|
||||||
<span class="error">{error}</span>
|
<span class="error">{error}</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if times}
|
{#if times}
|
||||||
|
{#if selectionSum}
|
||||||
|
<div class="timetracks sum">
|
||||||
|
{t('sum_of_records')}: <span>{selectionSum.toFixed(3)} {t('hours')}</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<table class="timetracks">
|
<table class="timetracks">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('year')}</th>
|
<th>{t('year')}</th>
|
||||||
<th>{t('month')}</th>
|
<th>{t('month')}</th>
|
||||||
<th>{t('start_end')}</th>
|
<th>{t('start')}…{t('end')}</th>
|
||||||
<th>{t('duration')}</th>
|
<th>{t('duration')}</th>
|
||||||
<th>{t('subject')}</th>
|
<th>{t('subject')}</th>
|
||||||
<th>{t('tasks')}</th>
|
<th>{t('tasks')}</th>
|
||||||
@@ -184,4 +175,4 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
"do_open" : "öffnen",
|
"do_open" : "öffnen",
|
||||||
"do_send" : "versenden",
|
"do_send" : "versenden",
|
||||||
"due_date": "Fälligkeitsdatum",
|
"due_date": "Fälligkeitsdatum",
|
||||||
|
"duration": "Dauer",
|
||||||
|
|
||||||
"edit": "Bearbeiten",
|
"edit": "Bearbeiten",
|
||||||
"edit_object" : "{object} bearbeiten",
|
"edit_object" : "{object} bearbeiten",
|
||||||
@@ -67,6 +68,7 @@
|
|||||||
"edit_service": "Login-Service \"{0}\" bearbeiten",
|
"edit_service": "Login-Service \"{0}\" bearbeiten",
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
"email_or_username": "Email oder Nutzername",
|
"email_or_username": "Email oder Nutzername",
|
||||||
|
"end": "Ende",
|
||||||
"estimated_time": "geschätzte Zeit",
|
"estimated_time": "geschätzte Zeit",
|
||||||
"estimated_times": "geschätzte Zeiten",
|
"estimated_times": "geschätzte Zeiten",
|
||||||
"extended_settings": "erweiterte Einstellungen",
|
"extended_settings": "erweiterte Einstellungen",
|
||||||
@@ -137,6 +139,7 @@
|
|||||||
"wiki": "Wiki"
|
"wiki": "Wiki"
|
||||||
},
|
},
|
||||||
"mismatch": "ungleich",
|
"mismatch": "ungleich",
|
||||||
|
"month": "Monat",
|
||||||
"must_not_be_empty": "darf nicht leer sein",
|
"must_not_be_empty": "darf nicht leer sein",
|
||||||
|
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
@@ -197,6 +200,7 @@
|
|||||||
"show": "anzeigen",
|
"show": "anzeigen",
|
||||||
"show_closed": "geschlossene anzeigen",
|
"show_closed": "geschlossene anzeigen",
|
||||||
"show_kanban": "Kanban-Ansicht",
|
"show_kanban": "Kanban-Ansicht",
|
||||||
|
"start": "Start",
|
||||||
"start_date": "Startdatum",
|
"start_date": "Startdatum",
|
||||||
"started": "angefangen",
|
"started": "angefangen",
|
||||||
"state": "Status",
|
"state": "Status",
|
||||||
@@ -220,7 +224,7 @@
|
|||||||
"subject": "Betreff",
|
"subject": "Betreff",
|
||||||
"subtask": "Unteraufgabe",
|
"subtask": "Unteraufgabe",
|
||||||
"subtasks": "Unteraufgaben",
|
"subtasks": "Unteraufgaben",
|
||||||
|
"sum_of_records": "Summe der ausgewählten Einträge",
|
||||||
"tag_uses": "Verwendung des Tags „{tag}“",
|
"tag_uses": "Verwendung des Tags „{tag}“",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"task": "Aufgabe",
|
"task": "Aufgabe",
|
||||||
@@ -254,6 +258,7 @@
|
|||||||
"welcome" : "Willkommen, {0}",
|
"welcome" : "Willkommen, {0}",
|
||||||
"wiki": "Wiki",
|
"wiki": "Wiki",
|
||||||
|
|
||||||
|
"year": "Jahr",
|
||||||
"your_password_reset_token" : "Ihr Token zum Erstellen eines neuen Passworts",
|
"your_password_reset_token" : "Ihr Token zum Erstellen eines neuen Passworts",
|
||||||
"your_profile": "dein Profil"
|
"your_profile": "dein Profil"
|
||||||
}
|
}
|
||||||
@@ -300,4 +300,16 @@ li > a > p:nth-child(1){
|
|||||||
background: #734a00;
|
background: #734a00;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 12px 5px 3px 5px;
|
padding: 12px 5px 3px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetracks .year, .month{
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetracks .selected td:not(.year):not(.month){
|
||||||
|
background: navy;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetracks.sum span{
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user