Files
Umbrella/frontend/src/routes/search/Search.svelte
T

367 lines
9.4 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script>
import { onMount } from 'svelte';
import { useTinyRouter } from 'svelte-tiny-router';
import { api, get, post, search, target } from '../../urls.svelte.js';
import { error, warn, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte.js';
import { display } from '../../time.svelte';
import Bookmark from '../bookmark/Template.svelte';
const router = useTinyRouter();
let counter = 9;
let bookmarks = $state(null);
let companies = $state(null);
let documents = $state(null);
let fulltext = false;
let notes = $state(null);
let pages = $state(null);
let projects = $state(null);
let stock = $state(null);
let tasks = $state(null);
let times = $state(null);
function doSearch(key){
warn(t('searching…'));
const data = { key : key, fulltext : fulltext };
post(api('bookmark/search'),data).then(handleBookmarks);
post(api('company/search '),data).then(handleCompanies);
post(api('document/search'),data).then(handleDocuments);
post(api('notes/search' ),data).then(handleNotes);
post(api('project/search' ),data).then(handleProjects);
post(api('task/search' ),data).then(handleTasks);
post(api('stock/search' ),data).then(handleStock);
post(api('time/search' ),data).then(handleTimes);
post(api('wiki/search' ),data).then(handleWikiPages);
}
async function getTitle(key,module,entity_id){
get(api(module+'/'+entity_id)).then(res => setTitle(res,key,module))
}
async function handleBookmarks(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
bookmarks = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
async function handleCompanies(resp){
quitOne();
if (resp.ok){
const json = await resp.json();
companies = Object.keys(json).length ? json : null;
} else {
error(resp);
}
}
async function handleDocuments(resp){
quitOne();
if (resp.ok){
const json = await resp.json();
documents = Object.keys(json).length ? json : null;
} else {
error(resp);
}
}
async function handleNotes(resp){
quitOne();
if (resp.ok){
const json = await resp.json();
if ( Object.keys(json).length ) {
for (let key of Object.keys(json)){
let module = json[key].module;
let entity_id = json[key].entity_id;
json[key].title = t(module)+' '+entity_id;
getTitle(key,module,entity_id);
}
notes = json;
} else notes = null;
} else {
error(resp);
}
}
async function handleProjects(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
projects = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
async function handleStock(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
stock = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
async function handleTasks(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
tasks = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
async function handleTimes(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
times = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
async function handleWikiPages(resp){
quitOne();
if (resp.ok){
const res = await resp.json();
pages = Object.keys(res).length ? res : null;
} else {
error(resp);
}
}
function onclick(e){
e.preventDefault();
var target = e.target;
while (target && !target.href) target=target.parentNode;
let href = target.getAttribute('href');
if (href) router.navigate(href);
return false;
}
async function setKey(ev){
if (ev) ev.preventDefault();
doSearch(search.key);
}
async function setTitle(resp,key,module){
if (resp.ok){
const json = await resp.json();
if (json.name) notes[key].title = t(module)+": "+json.name;
if (json.title) notes[key].title = t(module)+": "+json.title;
if (module == 'document'){
notes[key].title = t(json.type)+" "+json.number;
}
}
}
function quitOne(){
counter--;
if (counter > 0) {
warn(t('searching…')+" "+counter);
} else yikes();
}
function updateUrl(ev){
ev.preventDefault();
let url = window.location.origin + window.location.pathname;
if (search.key) {
url += '?key=' + encodeURI(search.key);
window.history.replaceState(history.state, '', url);
doSearch(search.key);
}
}
$effect(() => {
doSearch(router.getQueryParam('key'));
});
</script>
<svelte:head>
<title>Umbrella {t('search')}{search.key?': '+search.key:''}</title>
</svelte:head>
<fieldset class="search">
<legend>{t('search')} - {search.key}</legend>
<form onsubmit={updateUrl}>
<label>
{t('key')}
<input type="text" bind:value={search.key} />
</label>
<label>
<input type="checkbox" bind:checked={fulltext} />
{t('fulltext')}
</label>
<button type="submit">{t('go')}</button>
</form>
</fieldset>
{#if projects}
<fieldset>
<legend>
{t('projects')}
</legend>
<ul>
{#each Object.values(projects) as project}
<li>
<a href="/project/{project.id}/view" {onclick} >{project.name}</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if tasks}
<fieldset>
<legend>
{t('tasks')}
</legend>
<ul>
{#each Object.values(tasks) as task}
<li>
<a href="/task/{task.id}/view" {onclick} class={task.status.name}>{task.name}</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if bookmarks}
<fieldset>
<legend>
{t('bookmarks')}
</legend>
<ul>
{#each Object.values(bookmarks) as bookmark}
<li>
<a href={bookmark.url} target="_blank">{@html target(bookmark.comment.rendered)}</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if companies}
<fieldset>
<legend>
{t('companies')}
</legend>
<ul>
{#each Object.values(companies) as company}
<li>
<a href="/company/{company.id}/view" {onclick} >{company.name}</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if stock}
<fieldset>
<legend>
{t('stock')}
</legend>
{#if Object.keys(stock.items).length }
{t('items')}
<ul>
{#each Object.values(stock.items) as item}
<li>
<a href="/stock/{item.owner.type}/{item.owner.id}/item/{item.owner_number}" {onclick} >
{item.name} [{t('code')}: <span class="code">{item.code}</span>]
</a>
{@html item.description.rendered}
</li>
{/each}
</ul>
{/if}
{#if Object.keys(stock.locations).length}
{t('locations')}
<ul>
{#each Object.values(stock.locations) as loc (loc.id)}
<li>
<a href="/stock/location/{loc.id}">{loc.name}</a>
<br/> {@html loc.description.rendered}
</li>
{/each}
</ul>
{/if}
</fieldset>
{/if}
{#if times}
<fieldset>
<legend>
{t('timetracking')}
</legend>
<ul>
{#each Object.values(times) as time}
<li>
<a href="/time/{time.id}/view" {onclick} >
{display(time.start_time)}{#if time.end_time}{display(time.end_time)}{/if}
{time.subject}
</a>
<br/>
{@html target(time.description.rendered)}
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if documents}
<fieldset>
<legend>
{t('documents')}
</legend>
<ul>
{#each Object.values(documents) as document}
<li>
<a href="/document/{document.id}/view" {onclick} >
{document.number}
({document.date})
{document.sender.name.split('\n')[0]}
{document.customer.name.split('\n')[0]}
</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if pages}
<fieldset>
<legend>
{t('wiki_pages')}
</legend>
<ul>
{#each Object.values(pages) as page}
<li>
<a href="/wiki/{page.id}/view" {onclick} >
{page.title}
</a>
</li>
{/each}
</ul>
</fieldset>
{/if}
{#if notes}
<fieldset>
<legend>
{t('notes')}
</legend>
<ul>
{#each Object.values(notes) as note}
<li>
<b>
<a href="/{note.module}/{note.entity_id}/view" {onclick} >{note.title}</a>
</b>
{@html target(note.text.rendered)}
</li>
{/each}
</ul>
</fieldset>
{/if}