Browse Source

implemented editor for times

feature/join_times
Stephan Richter 2 months ago
parent
commit
49461199cd
  1. 17
      core/src/main/java/de/srsoftware/umbrella/core/model/Time.java
  2. 24
      frontend/src/Components/DateTimeEditor.svelte
  3. 37
      frontend/src/Components/TimeRecordEditor.svelte
  4. 38
      frontend/src/routes/time/Index.svelte
  5. 1
      translations/src/main/resources/de.json

17
core/src/main/java/de/srsoftware/umbrella/core/model/Time.java

@ -108,12 +108,21 @@ public class Time implements Mappable{ @@ -108,12 +108,21 @@ public class Time implements Mappable{
);
}
private LocalDateTime parse(String time){
if (time.contains("T")) return LocalDateTime.parse(time);
return LocalDateTime.parse(time,DT);
}
public Time patch(JSONObject json) {
if (json.has(SUBJECT) && json.get(SUBJECT) instanceof String s) subject = s;
if (json.has(DESCRIPTION) && json.get(DESCRIPTION) instanceof String d) description = d;
if (json.has(START_TIME) && json.get(START_TIME) instanceof String st) start = LocalDateTime.parse(st, DT);
if (json.has(END_TIME) && json.get(END_TIME) instanceof String e) end = LocalDateTime.parse(e,DT);
if (end != null && !start.isBefore(end)) throw UmbrellaException.invalidFieldException(END_TIME,"after start_time");
if (json.has(DESCRIPTION)) {
var o = json.get(DESCRIPTION);
if (o instanceof JSONObject nested && nested.get(SOURCE) instanceof String src) o = src;
if (o instanceof String d) description = d;
}
if (json.has(START_TIME) && json.get(START_TIME) instanceof String st) start = parse(st);
if (json.has(END_TIME) && json.get(END_TIME) instanceof String e) end = parse(e);
if (end != null && end.isBefore(start)) throw UmbrellaException.invalidFieldException(END_TIME,"after start_time");
return this;
}

24
frontend/src/Components/DateTimeEditor.svelte

@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
<script>
let { onSet = (dateTime) => {}, value = ' ' } = $props();
let date = $state(value.split(' ')[0]);
let time = $state(value.split(' ')[1]);
console.log({date:date,time:time,value:value});
function handleSubmit(e){
e.preventDefault();
onSet(`${date} ${time}`);
}
</script>
<style>
button{ display: none }
</style>
<form onsubmit={handleSubmit} >
<input type="date" bind:value={date} />
<input type="time" bind:value={time} />
<button type="submit">ok</button>
</form>

37
frontend/src/Components/TimeRecordEditor.svelte

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
<script>
import { t } from '../translations.svelte.js';
import MarkdownEditor from './MarkdownEditor.svelte';
let { record = null, onSet = time => {} } = $props();
function onsubmit(e){
e.preventDefault();
onSet(record);
}
</script>
{#if record}
<form {onsubmit}>
<fieldset>
<legend>{t('edit_object',{object:t('record')})}</legend>
<label>
{t('start')}
<input type="datetime-local" bind:value={record.start_time} />
</label>
<label>
{t('end')}
<input type="datetime-local" bind:value={record.end_time} />
</label>
<label>
{t('subject')}
<input type="text" bind:value={record.subject} />
</label>
<label>
{t('description')}
<MarkdownEditor simple={true} bind:value={record.description} />
</label>
<button type="submit">{t('save')}</button>
</fieldset>
</form>
{record.description.source}
{/if}

38
frontend/src/routes/time/Index.svelte

@ -4,14 +4,13 @@ @@ -4,14 +4,13 @@
import { api } from '../../urls.svelte.js';
import { t } from '../../translations.svelte.js';
import DateTimeEditor from '../../Components/DateTimeEditor.svelte';
import LineEditor from '../../Components/LineEditor.svelte';
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
import TimeEditor from '../../Components/TimeRecordEditor.svelte';
let error = $state(null);
let router = useTinyRouter();
let times = $state(null);
let detail = $state(null);
let sortedTimes = $derived.by(() => Object.values(times).sort((b, a) => a.start_time.localeCompare(b.start_time)));
async function loadTimes(){
const url = api('time');
@ -27,17 +26,20 @@ @@ -27,17 +26,20 @@
router.navigate(`task/${tid}/view`);
}
async function update(tid,field,newVal){
times[tid][field] = newVal;
detail = null;
const url = api(`time/${tid}`);
async function update(time){
const url = api(`time/${time.id}`);
time.start_time = time.start_time.split(':').slice(0,2).join(':');
time.end_time = time.end_time.split(':').slice(0,2).join(':');
const res = await fetch(url,{
credentials:'include',
method:'PATCH',
body:JSON.stringify(times[tid])
body:JSON.stringify(time)
});
if (res.ok){
times[tid] = await res.json();
let json = await res.json();
let id = json.id;
for (let key of Object.keys(json)) times[id][key] = json[key];
detail = null;
error = null;
return true;
} else {
@ -69,23 +71,15 @@ @@ -69,23 +71,15 @@
</tr>
</thead>
<tbody>
{#each Object.entries(times) as [tid,time]}
{#if detail == tid}
{#each sortedTimes as time}
{#if detail == time.id}
<tr>
<td>
<div>
<DateTimeEditor value={time.start_time} onSet={dateTime => update(tid,'start_time',dateTime)} />
<DateTimeEditor value={time.end_time} onSet={dateTime => update(tid,'end_time',dateTime)} />
</div>
</td>
<td colspan="2">
<LineEditor simple={true} value={time.subject} onSet={subject => update(tid,'subject',subject)} />
<MarkdownEditor simple={true} value={time.description} onSet={desc => update(tid,'description',desc)} />
<td colspan="5">
<TimeEditor record={time} onSet={update} />
</td>
</tr>
{:else}
<tr onclick={e => {detail = tid}}>
<tr onclick={e => {detail = time.id}}>
<td class="start_end">
{time.start_time}{#if time.end_time}{time.end_time}{/if}
</td>

1
translations/src/main/resources/de.json

@ -173,6 +173,7 @@ @@ -173,6 +173,7 @@
"project": "Projekt",
"projects": "Projekte",
"record": "Eintrag",
"repeat_new_password": "Wiederholung",
"results": "Ergebnisse",

Loading…
Cancel
Save