OpenSource Projekt-Management-Software
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

123 lines
3.7 KiB

<script>
import { onMount } from 'svelte';
import { api } from '../../urls.svelte.js';
import { t } from '../../translations.svelte.js';
import Editor from '../../Components/MarkdownEditor.svelte';
import Users from '../../Components/UserSelector.svelte';
import Tags from '../tags/TagList.svelte';
import Template from './Template.svelte';
let bookmarks = $state(null);
let loader = {
offset : 0,
limit : 16,
active : true
}
let new_bookmark = $state({
comment:{
source:null,
rendered:null
},
tags:[],
url:null,
users:{}
});
let error = $state(null);
async function getCandidates(text){
const url = api('user/search');
const resp = await fetch(url,{
credentials : 'include',
method : 'POST',
body : text
});
if (resp.ok){
error = null;
const input = await resp.json();
return Object.fromEntries(
Object.entries(input).map(([key, value]) => [key, value.name])
);
} else {
error = await resp.text();
return {};
}
}
async function loadBookmarks(){
const url = api(`bookmark/list?offset=${loader.offset}&limit=${loader.limit}`);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok){
const raw = await resp.json();
let merged = bookmarks ? bookmarks : {}
merged = { ...bookmarks , ...raw };
bookmarks = Object.values(merged).sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
loader.offset += loader.limit;
loader.active = false;
error = null;
if (Object.keys(raw).length) onscroll(null); // when bookmarks were received, check whether they fill up the page
} else {
error = await resp.html();
}
}
async function onclick(ev){
delete new_bookmark.comment.rendered;
const url = api('bookmark');
const data = {
comment : new_bookmark.comment.source,
url : new_bookmark.url,
tags : new_bookmark.tags
}
const share = Object.keys(new_bookmark.users).map(id => +id);
if (share.length>0) data.share = share;
const resp = await fetch(url,{
credentials : 'include',
method : 'POST',
body : JSON.stringify(data)
});
if (resp.ok) {
const bookmark = await resp.json();
bookmarks.unshift(bookmark);
} else {
error = await resp.text();
}
}
function onscroll(ev){
if (window.innerHeight + window.scrollY >= document.body.offsetHeight && !loader.active) {
loader.active = true;
loadBookmarks();
}
}
onMount(loadBookmarks);
</script>
<svelte:window {onscroll} />
<fieldset>
<legend>{t('Bookmarks')}</legend>
{#if error}
<span class="error">{error}</span>
{/if}
<label>
{t('URL')}
<input bind:value={new_bookmark.url} autofocus />
</label>
<label>
{t('Comment')}
<Editor simple={true} bind:value={new_bookmark.comment} />
</label>
<label>
{t('share_with')}
<Users {getCandidates} users={new_bookmark.users} />
</label>
<Tags module="bookmark" bind:tags={new_bookmark.tags} />
<button {onclick}>{t('save')}</button>
{#if bookmarks}
{#each bookmarks as bookmark}
<Template {bookmark} />
{/each}
{/if}
</fieldset>