Merge branch 'feature/translation' into module/messagebus
This commit is contained in:
@@ -9,9 +9,9 @@
|
||||
|
||||
<div>
|
||||
<div title={'task_'+task.id}>
|
||||
{#if task.estimated_time}
|
||||
{#if task.est_time}
|
||||
<span class="estimate" onclick={() => onSelect(task)}>
|
||||
{task.estimated_time} {t(task.estimated_time != 1 ? 'hours' : 'hour')}
|
||||
{task.est_time} {t(task.est_time != 1 ? 'hours' : 'hour')}
|
||||
</span>
|
||||
{/if}
|
||||
{task.name}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
item_code : t('estimated_time'),
|
||||
title : estimate.name,
|
||||
description : estimate.description.source,
|
||||
amount : estimate.estimated_time,
|
||||
amount : estimate.est_time,
|
||||
unit : t('hours')
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { useTinyRouter } from 'svelte-tiny-router';
|
||||
import { api } from '../../urls.svelte';
|
||||
import { error, yikes } from '../../warn.svelte';
|
||||
import { error, warn, yikes } from '../../warn.svelte';
|
||||
import { t } from '../../translations.svelte';
|
||||
import { user } from '../../user.svelte';
|
||||
|
||||
const image_extensions = ['jpg','jpeg','gif','png','svg','webp'];
|
||||
const router = useTinyRouter();
|
||||
let children = $state({});
|
||||
|
||||
let new_dir = $state(null);
|
||||
let files = $state();
|
||||
let parent = $state(false);
|
||||
@@ -17,23 +18,6 @@
|
||||
let delete_allowed = $state(false);
|
||||
let available = $derived.by(isAvailable);
|
||||
|
||||
function isAvailable(){
|
||||
if (!new_dir) return false;
|
||||
if (children){
|
||||
if (children.dirs) {
|
||||
for (let key of Object.values(children.dirs)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
if (children.files) {
|
||||
for (let key of Object.values(children.files)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function create_dir(ev){
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
@@ -74,13 +58,30 @@
|
||||
|
||||
async function handleDirectory(res){
|
||||
let json = await res.json();
|
||||
children.dirs = json.dirs ? json.dirs : {};
|
||||
children.files = json.files ? json.files : {};
|
||||
children.dirs = json.dirs ? val_sort(json.dirs) : {};
|
||||
children.files = json.files ? val_sort(json.files) : {};
|
||||
children.title = json.title ? json.title : path;
|
||||
delete_allowed = json.delete;
|
||||
yikes();
|
||||
}
|
||||
|
||||
function isAvailable(){
|
||||
if (!new_dir) return false;
|
||||
if (children){
|
||||
if (children.dirs) {
|
||||
for (let key of Object.values(children.dirs)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
if (children.files) {
|
||||
for (let key of Object.values(children.files)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function is_image(file){
|
||||
let parts = file.toLowerCase().split('.');
|
||||
let ext = parts.pop();
|
||||
@@ -90,12 +91,15 @@
|
||||
async function loadChildren(p){
|
||||
p = p.substring(6);
|
||||
if (p == '') p = '/';
|
||||
children = { dirs : {}, files : {}, title : p};
|
||||
children = { dirs : [], files : [], title : p};
|
||||
path = p;
|
||||
if (p == '/'){
|
||||
children.dirs[`/user/${user.id}`] = t('my_files');
|
||||
children.dirs['/project'] = t('projects')
|
||||
children.dirs['/company'] = t('companies');
|
||||
children.dirs = [
|
||||
{ path : `/user/${user.id}`, name : t('my files') },
|
||||
{ path : '/project', name : t('projects')},
|
||||
{ path : '/company', name : t('companies')},
|
||||
]
|
||||
|
||||
parent = false;
|
||||
form = false;
|
||||
} else {
|
||||
@@ -114,8 +118,12 @@
|
||||
|
||||
function markdown(file){
|
||||
let parts = file.split('/');
|
||||
let md = ``;
|
||||
let path = `/api/files${file}`;
|
||||
path = encodeURI(path);
|
||||
let md = ``;
|
||||
navigator.clipboard.writeText(md);
|
||||
warn(t('Markdown has been copied to clipboard!'));
|
||||
setTimeout(yikes, 2500);
|
||||
}
|
||||
|
||||
function onclick(ev){
|
||||
@@ -153,6 +161,12 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
function val_sort(map){
|
||||
return Object.entries(map)
|
||||
.map(item => ({name:item[1],path:item[0]}))
|
||||
.sort((a,b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
onMount(() => loadChildren(window.location.pathname));
|
||||
</script>
|
||||
|
||||
@@ -166,12 +180,12 @@
|
||||
</li>
|
||||
{/if}
|
||||
{#if children?.dirs}
|
||||
{#each Object.entries(children.dirs) as [k,v]}
|
||||
{#each children.dirs as dir}
|
||||
<li class="dir">
|
||||
<span class="symbol"></span>
|
||||
<a href={'/files'+k} {onclick}>{v}</a>
|
||||
<a href={'/files'+dir.path} {onclick}>{dir.name}</a>
|
||||
{#if delete_allowed}
|
||||
<button class="symbol" onclick={e => dropDir(`/api/files${k}`,v)}></button>
|
||||
<button class="symbol" onclick={e => dropDir(`/api/files${dir.path}`,dir.name)}></button>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
@@ -186,15 +200,15 @@
|
||||
</li>
|
||||
{/if}
|
||||
{#if children.files}
|
||||
{#each Object.entries(children.files) as [k,v]}
|
||||
{#each children.files as file}
|
||||
<li class="file">
|
||||
<span class="symbol"></span>
|
||||
<a href={`/api/files${k}`} target="_blank">{v}</a>
|
||||
{#if is_image(k)}
|
||||
<button class="symbol" title={'markdown_code'} onclick={e => markdown(k)}></button>
|
||||
<a href={`/api/files${file.path}`} target="_blank">{file.name}</a>
|
||||
{#if is_image(file.path)}
|
||||
<button class="symbol" title={'markdown_code'} onclick={e => markdown(file.path)}></button>
|
||||
{/if}
|
||||
{#if delete_allowed}
|
||||
<button class="symbol" title={t('delete_object',{'object':t('file')})} onclick={e => dropFile(`/api/files${k}`,v)}></button>
|
||||
<button class="symbol" title={t('delete_object',{'object':t('file')})} onclick={e => dropFile(`/api/files${file.path}`,file.name)}></button>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
title={task.description.source}
|
||||
>
|
||||
<span class="title">{task.name}</span>
|
||||
{#if task.estimated_time}
|
||||
{#if task.est_time}
|
||||
<span class="estimate">
|
||||
({task.estimated_time} h)
|
||||
({task.est_time} h)
|
||||
</span>
|
||||
{/if}
|
||||
{#if task.tags}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
let eventSource = $state(null);
|
||||
let { id } = $props();
|
||||
let lastEvent = $state(null);
|
||||
let estimated_time = $state({sum:0});
|
||||
let est_time = $state({sum:0});
|
||||
let project = $state(null);
|
||||
let router = useTinyRouter();
|
||||
let showSettings = $state(false);
|
||||
@@ -135,7 +135,7 @@
|
||||
});
|
||||
if (resp.ok){
|
||||
tasks = {};
|
||||
estimated_time.sum = 0;
|
||||
est_time.sum = 0;
|
||||
tasks = await resp.json();
|
||||
yikes();
|
||||
} else {
|
||||
@@ -283,9 +283,9 @@
|
||||
{/each}
|
||||
{/if} <!-- settings -->
|
||||
|
||||
{#if estimated_time.sum}
|
||||
{#if est_time.sum}
|
||||
<div>{t('estimated_time')}</div>
|
||||
<div class="estimated_time">{estimated_time.sum} h</div>
|
||||
<div class="estimated_time">{est_time.sum} h</div>
|
||||
{/if}
|
||||
|
||||
<div>{t('description')}</div>
|
||||
@@ -304,7 +304,7 @@
|
||||
</div>
|
||||
<div class="tasks">
|
||||
{#if tasks}
|
||||
<TaskList {tasks} {estimated_time} {lastEvent} {eventSource} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
||||
<TaskList {tasks} {est_time} {lastEvent} {eventSource} states={project?.allowed_states} show_closed={show_closed || project.show_closed} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
name : '',
|
||||
description : { source : '', rendered : '' },
|
||||
due_date : null,
|
||||
estimated_time : null,
|
||||
est_time : null,
|
||||
no_index : false,
|
||||
show_closed : false,
|
||||
start_date : null,
|
||||
@@ -191,7 +191,7 @@
|
||||
{t('estimated_time')}
|
||||
</th>
|
||||
<td>
|
||||
<input type="number" bind:value={task.estimated_time} /> {t('hours')}
|
||||
<input type="number" bind:value={task.est_time} /> {t('hours')}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
|
||||
let {
|
||||
estimated_time,
|
||||
est_time,
|
||||
lastEvent,
|
||||
show_closed,
|
||||
siblings,
|
||||
@@ -137,8 +137,8 @@
|
||||
return {state:0};
|
||||
}
|
||||
|
||||
if (task.estimated_time){
|
||||
estimated_time.sum += task.estimated_time;
|
||||
if (task.est_time){
|
||||
est_time.sum += task.est_time;
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
@@ -157,8 +157,8 @@
|
||||
{#if !deleted}
|
||||
<li draggable="true" {ondrop} ondragover={e => e.preventDefault()} {ondragstart} class="task {states[task.status]?.toLowerCase()}">
|
||||
<LineEditor bind:value={task.name} onclick={openTask} editable={true} onSet={setName} type="a" href={`/task/${task.id}/view`} />
|
||||
{#if task.estimated_time}
|
||||
<span class="estimated_time">({+task.estimated_time} h)</span>
|
||||
{#if task.est_time}
|
||||
<span class="estimated_time">({+task.est_time} h)</span>
|
||||
{/if}
|
||||
<button class="symbol" title={t('drag_n_drop')}></button>
|
||||
{#if states[task.status] != 'PENDING'}
|
||||
@@ -180,7 +180,7 @@
|
||||
<button class="symbol" title={t('add_object',{object:t('subtask')})} onclick={addSubtask}></button>
|
||||
<button class="symbol" title={t('timetracking')} onclick={addTime}></button>
|
||||
{#if children}
|
||||
<TaskList {states} {lastEvent} tasks={children} {estimated_time} {show_closed} />
|
||||
<TaskList {states} {lastEvent} tasks={children} {est_time} {show_closed} />
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
import { t } from '../../translations.svelte.js';
|
||||
import ListTask from './ListTask.svelte';
|
||||
|
||||
let { estimated_time, lastEvent, show_closed, states = {}, tasks } = $props();
|
||||
let { est_time, lastEvent, show_closed, states = {}, tasks } = $props();
|
||||
|
||||
let sortedTasks = $derived.by(() => Object.values(tasks).sort((a, b) => a.name.localeCompare(b.name)));
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
{#each sortedTasks as task}
|
||||
<ListTask {states} {task} {lastEvent} siblings={tasks} {estimated_time} show_closed={show_closed || task.show_closed} />
|
||||
<ListTask {states} {task} {lastEvent} siblings={tasks} {est_time} show_closed={show_closed || task.show_closed} />
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
let { id } = $props();
|
||||
let children = $state(null);
|
||||
let dummy = $derived(updateOn(id));
|
||||
let estimated_time = $state({sum:0});
|
||||
let est_time = $state({sum:0});
|
||||
let project = $state(null);
|
||||
const router = useTinyRouter();
|
||||
let showSettings = $state(router.fullPath.endsWith('/edit'));
|
||||
@@ -251,9 +251,9 @@
|
||||
<div>{t('due_date')}</div>
|
||||
<div class="due date">{task.due_date}</div>
|
||||
{/if}
|
||||
{#if task.estimated_time}
|
||||
{#if task.est_time}
|
||||
<div>{t('estimated_time')}</div>
|
||||
<div class="estimated time">{task.estimated_time} h</div>
|
||||
<div class="estimated time">{task.est_time} h</div>
|
||||
{/if}
|
||||
{#if showSettings}
|
||||
<div>{t('extended_settings')}</div>
|
||||
@@ -284,7 +284,7 @@
|
||||
|
||||
<div>{t('estimated_time')}</div>
|
||||
<div>
|
||||
<input type="number" bind:value={task.estimated_time} onchange={() => update({estimated_time:task.estimated_time})} /> h
|
||||
<input type="number" bind:value={task.est_time} onchange={() => update({est_time:task.est_time})} /> h
|
||||
</div>
|
||||
|
||||
<div>{t('priority')}</div>
|
||||
@@ -320,7 +320,7 @@
|
||||
</div>
|
||||
<div class="children">
|
||||
{#if children}
|
||||
<TaskList {eventSource} states={project?.allowed_states} tasks={children} {estimated_time} show_closed={task.show_closed} />
|
||||
<TaskList {eventSource} states={project?.allowed_states} tasks={children} {est_time} show_closed={task.show_closed} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -15,5 +15,5 @@ export async function warn(msg){
|
||||
|
||||
export function yikes(){
|
||||
messages.error = null;
|
||||
messages.warn = null;
|
||||
messages.warning = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user