(() => { const $ = id => document.getElementById(`cta-${id}`); const esc = v => String(v ?? '').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); let rows = [], tags = [], selected = []; async function api(path, options) { const r = await fetch(`/api/v1/${path}`, {credentials:'include',...options}); const data = await r.json(); if (!r.ok) throw new Error(typeof data.detail === 'string' ? data.detail : 'Kontrollér skabelonens felter'); return data; } function message(text, error=false) { $('message').textContent=text; $('message').className=error?'alert alert-danger':'alert alert-success'; } function renderTags() { $('tags').innerHTML=selected.map(id=>``).join(''); } function edit(row) { $('form').reset(); const v=row?.values || {}; for (const [key,value] of Object.entries({id:row?.id || '',name:row?.name || '',icon:row?.icon || 'bi-lightning',sort:row?.sort_order || 0,type:v.type || 'ticket',status:v.status || 'åben',group:v.assigned_group_id || '',title:v.titel || '',description:v.beskrivelse || '',stage:v.pipeline?.stage_id || '',amount:v.pipeline?.amount ?? '',probability:v.pipeline?.probability ?? '', 'pipeline-description':v.pipeline?.description || ''})) $(key).value=value; $('active').checked=row?.is_active ?? true; selected=[...(v.tag_ids || [])]; renderTags(); } async function load() { rows=await api('case-create/templates/admin'); $('list').innerHTML=rows.map(r=>`
`).join('') || '

Ingen skabeloner endnu.

'; } async function init() { try { const [types, groups, stages, tagRows] = await Promise.all([api('settings/case_types'),api('case-create/template-options'),api('pipeline/stages'),api('tags?is_active=true')]); let typeKeys; try { typeKeys=JSON.parse(types.value || '[]'); } catch { typeKeys=[]; } if (!Array.isArray(typeKeys) || !typeKeys.length) typeKeys=['ticket','pipeline','ordre','opgave','projekt','service','abonnement']; $('type').innerHTML=[...new Set([...typeKeys,'pipeline','abonnement'])].map(t=>``).join(''); $('group').insertAdjacentHTML('beforeend',groups.map(g=>``).join('')); $('stage').insertAdjacentHTML('beforeend',stages.map(s=>``).join('')); tags=tagRows; await load(); edit(null); const setting = await api('settings/case_statuses'); const statuses = JSON.parse(setting.value || '[]'); if (Array.isArray(statuses)) statuses.forEach(s => { const value=typeof s==='string'?s:s.value; if(value && !Array.from($('status').options).some(o=>o.value===value)) $('status').add(new Option(typeof s==='string'?s:(s.label || value),value)); }); } catch(e) { message(e.message,true); } $('new').onclick=()=>edit(null); $('tags').onclick=e=>{ const b=e.target.closest('[data-tag]'); if(b){selected=selected.filter(id=>id!==Number(b.dataset.tag));renderTags();} }; $('add-tag').onclick=()=>window.tagPicker.showSelection(t=>{if(!selected.includes(t.id))selected.push(t.id);renderTags();}); $('list').onclick=async e=>{try{const b=e.target.closest('[data-edit],[data-delete]');if(!b)return;if(b.dataset.edit)edit(rows.find(r=>r.id===Number(b.dataset.edit)));else if(confirm('Slet denne fælles skabelon?')){await api(`case-create/templates/${b.dataset.delete}`,{method:'DELETE'});await load();edit(null);}}catch(err){message(err.message,true);}}; $('form').onsubmit=async e=>{e.preventDefault();const button=$('form').querySelector('[type=submit]');button.disabled=true;try{ const number=k=>$(k).value===''?null:Number($(k).value); const pipeline={stage_id:number('stage'),amount:number('amount'),probability:number('probability'),description:$('pipeline-description').value || null}; const body={name:$('name').value.trim(),icon:$('icon').value,sort_order:number('sort') || 0,is_active:$('active').checked,values:{type:$('type').value,titel:$('title').value,beskrivelse:$('description').value,status:$('status').value,assigned_group_id:number('group'),tag_ids:selected,pipeline:Object.values(pipeline).some(v=>v!==null)?pipeline:null}}; const id=$('id').value;const saved=await api(`case-create/templates${id?`/${id}`:''}`,{method:id?'PUT':'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)});await load();edit(saved);message('Skabelon gemt'); }catch(err){message(err.message,true);}finally{button.disabled=false;}}; } document.addEventListener('DOMContentLoaded',init); })();