Browse Source

implemented selecting tasks by estimated time

feature/document
Stephan Richter 4 months ago
parent
commit
b600a3613f
  1. 27
      frontend/src/Components/EstimatedTask.svelte
  2. 31
      frontend/src/routes/document/EstimateList.svelte
  3. 6
      frontend/src/routes/document/PositionSelector.svelte
  4. 2
      frontend/src/routes/document/View.svelte
  5. 3
      task/src/main/java/de/srsoftware/umbrella/task/Task.java
  6. 6
      task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java

27
frontend/src/Components/EstimatedTask.svelte

@ -0,0 +1,27 @@
<script>
import {t} from '../translations.svelte.js';
let { task, onSelect = (task) => {} } = $props();
</script>
<div>
<div title={'task_'+task.id}>
{#if task.estimated_time}
<span class="estimate" onclick={() => onSelect(task)}>
{task.estimated_time}&nbsp;{t(task.estimated_time != 1 ? 'task.hours' : 'task.hour')}
</span>
{/if}
{task.name}
</div>
<div>
{@html task.description.rendered}
</div>
{#if task.children}
<ul>
{#each task.children as child,tid}
<svelte:self task={child} />
{/each}
</ul>
{/if}
</div>

31
frontend/src/routes/document/EstimateList.svelte

@ -1,10 +1,10 @@
<script> <script>
import { t } from '../../translations.svelte.js'; import { t } from '../../translations.svelte.js';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import EstimatedTime from '../../Components/Item.svelte'; import EstimatedTask from '../../Components/EstimatedTask.svelte';
let { company_id, onSelect = (item) => {} } = $props(); let { company_id, onSelect = (task) => {} } = $props();
let items = $state(null); let projects = $state(null);
let error = $state(null); let error = $state(null);
async function loadItems(){ async function loadItems(){
@ -16,7 +16,7 @@
body: JSON.stringify(data) body: JSON.stringify(data)
}); });
if (resp.ok){ if (resp.ok){
items = await resp.json(); projects = await resp.json();
} else { } else {
error = await resp.body(); error = await resp.body();
} }
@ -26,14 +26,31 @@
</script> </script>
<style>
:global(.estimate){
border: 1px solid;
padding: 4px;
border-radius: 4px;
}
</style>
<div> <div>
<h1>{t('task.estimated_times')}</h1> <h1>{t('task.estimated_times')}</h1>
{#if error} {#if error}
<span class="error">{error}</span> <span class="error">{error}</span>
{/if} {/if}
{#if items} {#if projects}
{#each items as item,id} {#each projects as project,pid}
<EstimatedTime item={item} onclick={() => onSelect(item)} /> <fieldset>
<legend>{project.name}</legend>
{#each project.tasks as task,tid}
<ul>
<li>
<EstimatedTask {task} {onSelect} />
</li>
</ul>
{/each}
</fieldset>
{/each} {/each}
{/if} {/if}
</div> </div>

6
frontend/src/routes/document/PositionSelector.svelte

@ -9,7 +9,7 @@
let select = $state(0); let select = $state(0);
function estimateSelected(estimate){ function estimateSelected(estimate){
onSelect({estimate:estimate}); onSelect({task:estimate});
close(); close();
} }
@ -40,8 +40,8 @@
<div> <div>
<span class="tabs"> <span class="tabs">
<button onclick={() => select=0}>{t('document.items')}</button> <button onclick={() => select=0}>{t('document.items')}</button>
<button onclick={() => select=1}>{t('document.timetrack')}</button> <button onclick={() => select=1}>{t('document.estimated_times')}</button>
<button onclick={() => select=2}>{t('document.estimated_times')}</button> <button onclick={() => select=2}>{t('document.timetrack')}</button>
<button onclick={close}>{t('document.abort')}</button> <button onclick={close}>{t('document.abort')}</button>
</span> </span>
{#if select == 0} {#if select == 0}

2
frontend/src/routes/document/View.svelte

@ -64,8 +64,10 @@
} }
function addPosition(selected){ function addPosition(selected){
console.log(selected);
let newPos = {}; let newPos = {};
if (selected.item) newPos['item']=selected.item.id; if (selected.item) newPos['item']=selected.item.id;
if (selected.task) newPos['task']=selected.task.id;
console.log(JSON.stringify({newPos:newPos})); console.log(JSON.stringify({newPos:newPos}));
} }

3
task/src/main/java/de/srsoftware/umbrella/task/Task.java

@ -5,6 +5,7 @@ import static de.srsoftware.tools.Optionals.nullIfEmpty;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.SHOW_CLOSED; import static de.srsoftware.umbrella.core.Constants.SHOW_CLOSED;
import static de.srsoftware.umbrella.core.Constants.STATUS; import static de.srsoftware.umbrella.core.Constants.STATUS;
import static de.srsoftware.umbrella.core.Util.markdown;
import static de.srsoftware.umbrella.task.Constants.*; import static de.srsoftware.umbrella.task.Constants.*;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
@ -42,7 +43,7 @@ public record Task(long id, long projectId, Long parentTaskId, String name, Stri
map.put(PROJECT_ID, projectId); map.put(PROJECT_ID, projectId);
map.put(PARENT_TASK_ID, parentTaskId); map.put(PARENT_TASK_ID, parentTaskId);
map.put(NAME, name); map.put(NAME, name);
map.put(DESCRIPTION, description); map.put(DESCRIPTION, Map.of(SOURCE,description,RENDERED,markdown(description)));
map.put(STATUS, status); map.put(STATUS, status);
map.put(ESTIMATED_TIME, estimatedTime); map.put(ESTIMATED_TIME, estimatedTime);
map.put(START_DATE,start); map.put(START_DATE,start);

6
task/src/main/java/de/srsoftware/umbrella/task/TaskModule.java

@ -73,8 +73,10 @@ public class TaskModule extends BaseHandler {
projects.forEach(project -> { projects.forEach(project -> {
var projectMap = new HashMap<>(project.toMap()); var projectMap = new HashMap<>(project.toMap());
var children = tree.values().stream().filter(root -> project.id() == (Long)root.get(PROJECT_ID)).toList(); var children = tree.values().stream().filter(root -> project.id() == (Long)root.get(PROJECT_ID)).toList();
projectMap.put(FIELD_TASKS,children); if (!children.isEmpty()) {
result.add(projectMap); projectMap.put(FIELD_TASKS, children);
result.add(projectMap);
}
}); });
return sendContent(ex,result); return sendContent(ex,result);
} }

Loading…
Cancel
Save