preparing creation of successor document

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-08-30 17:19:51 +02:00
parent 7b5ea62bfd
commit 8d16a93b69
6 changed files with 86 additions and 76 deletions

View File

@@ -59,7 +59,6 @@
} else { } else {
onMount(load); onMount(load);
} }
</script> </script>
<style> <style>

View File

@@ -99,10 +99,10 @@
<span class="error">{error}</span> <span class="error">{error}</span>
{/if} {/if}
{#if docType} {#if docType}
<legend>{t('add_new',docType)}</legend> <legend>{t('add_object',{object:docType})}</legend>
{/if} {/if}
{#if company} {#if company}
Company: {company.name} {t('company')}: {company.name}
<fieldset> <fieldset>
<legend>{t('customer')}</legend> <legend>{t('customer')}</legend>
<ContactSelector caption={t('select_customer')} onselect={contactSelected} /> <ContactSelector caption={t('select_customer')} onselect={contactSelected} />
@@ -143,5 +143,5 @@
{t('sender_local_court')} {t('sender_local_court')}
</label> </label>
</fieldset> </fieldset>
<button onclick={submit}>{t('create_new_document')}</button> <button onclick={submit}>{t('create_new_object',{object:docType})}</button>
</fieldset> </fieldset>

View File

@@ -12,26 +12,24 @@
let router = useTinyRouter(); let router = useTinyRouter();
let company_id = +router.query.company_id; let company_id = +router.query.company_id;
let documents = null; let documents = null;
let docType = 0;
let selected_company = null; let selected_company = null;
async function loadCompanies(){ function createDoc(type){
const url = api('company/list'); router.navigate(`/document/add?company_id=${selected_company.id}&document_type=${type}`)
const resp = await fetch(url,{ credentials: 'include'}); }
async function deleteDoc(ev,doc){
if (confirm(t('really_delete',doc.number))){
const url = api(`document/${doc.id}`);
const resp = await fetch(url,{
credentials: 'include',
method: 'DELETE'
});
if (resp.ok){ if (resp.ok){
companies = await resp.json(); load(selected_company); // relaod docs
} else { } else {
error = await resp.text(); error = await resp.text();
} }
if (company_id) {
for (let comp of companies){
if (comp.id == company_id){
load(comp);
break;
}
}
} }
} }
@@ -51,28 +49,29 @@
} }
} }
function createDoc(){ async function loadCompanies(){
router.navigate(`/document/add?company_id=${selected_company.id}&document_type=${docType}`) const url = api('company/list');
} const resp = await fetch(url,{ credentials: 'include'});
function show(id){
router.navigate(`/document/${id}/view`);
}
async function deleteDoc(ev,doc){
if (confirm(t('really_delete',doc.number))){
const url = api(`document/${doc.id}`);
const resp = await fetch(url,{
credentials: 'include',
method: 'DELETE'
});
if (resp.ok){ if (resp.ok){
load(selected_company); // relaod docs companies = await resp.json();
} else { } else {
error = await resp.text(); error = await resp.text();
} }
if (company_id) {
for (let comp of companies){
if (comp.id == company_id){
load(comp);
break;
} }
} }
}
}
function show(id){
router.navigate(`/document/${id}/view`);
}
onMount(loadCompanies); onMount(loadCompanies);
</script> </script>
@@ -100,7 +99,7 @@
<th>{t('state')}</th> <th>{t('state')}</th>
<th> <th>
{t('actions')} {t('actions')}
<TypeSelector caption={t('create_new_document')} bind:value={docType} onchange={createDoc} /> <TypeSelector caption={t('create_new_object',{object:t('document')})} onSelect={createDoc} />
</th> </th>
</tr> </tr>
</thead> </thead>

View File

@@ -6,12 +6,12 @@
let { let {
caption, caption,
onchange = () => console.log('changed'), onSelect = (type) => console.log('changed'),
value = $bindable(0)
} = $props(); } = $props();
let message = t('loading'); let message = t('loading');
let types = $state(null); let types = $state(null);
let value = $state(0);
async function loadTypes(){ async function loadTypes(){
const url = api('document/types'); const url = api('document/types');
@@ -27,7 +27,7 @@
</script> </script>
{#if types} {#if types}
<select bind:value onchange={onchange}> <select bind:value onchange={e => onSelect(value)}>
<option value={0}>{caption}</option> <option value={0}>{caption}</option>
{#each Object.entries(types) as [id,type]} {#each Object.entries(types) as [id,type]}
<option value={id}>{t('type_'+type)}</option> <option value={id}>{t('type_'+type)}</option>

View File

@@ -15,6 +15,7 @@
import StateSelector from './StateSelector.svelte'; import StateSelector from './StateSelector.svelte';
import Tags from '../tags/TagList.svelte'; import Tags from '../tags/TagList.svelte';
import TemplateSelector from './TemplateSelector.svelte'; import TemplateSelector from './TemplateSelector.svelte';
import TypeSelector from './TypeSelector.svelte';
let doc = $state(null); let doc = $state(null);
@@ -26,12 +27,15 @@
const router = useTinyRouter(); const router = useTinyRouter();
let sndDisabled = $state(false); let sndDisabled = $state(false);
async function addPosition(selected){
async function loadDoc(){ const url = api(`document/${doc.id}/position`);
const url = api(`document/${id}`); const resp = await fetch(url,{
const resp = await fetch(url,{credentials:'include'}); method : 'POST',
credentials : 'include',
body : JSON.stringify(selected)
});
if (resp.ok){ if (resp.ok){
doc = await resp.json(); doc.positions = await resp.json();
error = null; error = null;
} else { } else {
error = await resp.text(); error = await resp.text();
@@ -52,37 +56,15 @@
} }
} }
async function update(path,newValue){ function createSuccessorDoc(type){
const parts = path.split('.'); console.log(type);
if (parts.length<1) return false;
let data = newValue;
while (parts.length > 0){
const inner = data;
data = {};
data[parts.pop()] = inner;
}
try {
const url = api(`document/${doc.id}`);
const resp = await fetch(url,{
credentials : 'include',
method : 'PATCH',
body : JSON.stringify(data)
});
return resp.ok;
} catch (err){
return false;
}
} }
async function addPosition(selected){ async function loadDoc(){
const url = api(`document/${doc.id}/position`); const url = api(`document/${id}`);
const resp = await fetch(url,{ const resp = await fetch(url,{credentials:'include'});
method : 'POST',
credentials : 'include',
body : JSON.stringify(selected)
});
if (resp.ok){ if (resp.ok){
doc.positions = await resp.json(); doc = await resp.json();
error = null; error = null;
} else { } else {
error = await resp.text(); error = await resp.text();
@@ -109,6 +91,28 @@
pdfDisabled = false; pdfDisabled = false;
} }
async function update(path,newValue){
const parts = path.split('.');
if (parts.length<1) return false;
let data = newValue;
while (parts.length > 0){
const inner = data;
data = {};
data[parts.pop()] = inner;
}
try {
const url = api(`document/${doc.id}`);
const resp = await fetch(url,{
credentials : 'include',
method : 'PATCH',
body : JSON.stringify(data)
});
return resp.ok;
} catch (err){
return false;
}
}
onMount(loadDoc); onMount(loadDoc);
</script> </script>
@@ -207,6 +211,12 @@
{/if} {/if}
</td> </td>
</tr> </tr>
<tr>
<th>{t('create_new_object',{object:t('succeeding_document')})}:</th>
<td>
<TypeSelector caption={t('choose_type')} onSelect={createSuccessorDoc} />
</td>
</tr>
</tbody> </tbody>
</table> </table>
</fieldset> </fieldset>

View File

@@ -16,6 +16,7 @@
"by": "von", "by": "von",
"cancel": "abbrechen", "cancel": "abbrechen",
"choose_type": "Typ wählen",
"client_id": "Client-ID", "client_id": "Client-ID",
"client_secret": "Client-Geheimnis", "client_secret": "Client-Geheimnis",
"close_settings": "Einstellungen schließen", "close_settings": "Einstellungen schließen",
@@ -225,6 +226,7 @@
"subject": "Betreff", "subject": "Betreff",
"subtask": "Unteraufgabe", "subtask": "Unteraufgabe",
"subtasks": "Unteraufgaben", "subtasks": "Unteraufgaben",
"succeeding_document": "Nachfolge-Dokument",
"sum_of_records": "Summe der ausgewählten Einträge", "sum_of_records": "Summe der ausgewählten Einträge",
"tag_uses": "Verwendung des Tags „{tag}“", "tag_uses": "Verwendung des Tags „{tag}“",
"tags": "Tags", "tags": "Tags",