bmc_hub/app/modules/sag/templates/reminder_rules.html
Christian 9ca562745a feat(subscriptions): enhance subscription update logic to allow direct edits for drafts and add new endpoint for manual invoice processing
feat(ticket): update email integration to use new priority constants for ticket classification

feat(procurement): add procurement overview page with dynamic data loading and display

test(subscriptions): add tests for billing calendar to ensure correct invoice dates

feat(reminder): implement automated task lists with user-defined rules for reminders

feat(migrations): create tables for managing delefiber product prices and mobile recorder provisioning history

test(mobile_recorder): add tests for provisioning mobile recorders to ensure correct asset creation and updates
2026-09-07 19:05:58 +02:00

20 lines
6.4 KiB
HTML
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.

{% extends "shared/frontend/base.html" %}
{% block title %}Automatiske opgavelister{% endblock %}
{% block content %}
<div class="container py-4 py-lg-5 reminder-rules-page">
<section class="rule-hero mb-4"><div><div class="eyebrow hero-eyebrow">SUPPORT · AUTOMATISERING</div><h1>Automatiske opgavelister</h1><p>Få dine åbne sager og valgfrit gruppens samlet i en kort, klikbar besked på de tidspunkter, der passer din arbejdsdag.</p></div><div class="hero-icon"></div></section>
<div class="card rule-card border-0 shadow-sm"><div class="card-body p-4 p-lg-5"><div class="d-flex align-items-start gap-3 mb-4"><div class="section-icon"></div><div><h2 class="h4 mb-1">Ny regel</h2><p class="text-muted mb-0">Reglen kører automatisk; brug <strong>Send nu</strong> for at teste den med det samme.</p></div></div><div class="row g-4"><div class="col-lg-6"><label class="form-label fw-semibold" for="ruleTitle">Navn på listen</label><input id="ruleTitle" class="form-control form-control-lg" value="Min opgaveliste"><div class="form-text">Kun til din egen oversigt.</div></div><div class="col-lg-6"><label class="form-label fw-semibold" for="ruleTimes">Tidspunkter</label><input id="ruleTimes" class="form-control form-control-lg" value="09:00, 12:00, 14:00" placeholder="09:00, 12:00"><div class="form-text">Skriv flere tider adskilt med komma, fx 09:00, 12:00, 14:00.</div></div><div class="col-12"><div class="rule-options"><label class="form-check option"><input id="ruleGroups" class="form-check-input" type="checkbox" checked><span><strong>Medtag mine gruppers sager</strong><small>Viser også åbne sager, som er tildelt dine grupper.</small></span></label><label class="form-check option"><input id="ruleMattermost" class="form-check-input" type="checkbox" checked><span><strong>Send til Mattermost</strong><small>Hver sag i beskeden får et direkte link til Hub.</small></span></label></div></div><div class="col-12 d-flex justify-content-end"><button id="saveButton" class="btn btn-primary px-4 py-2" onclick="saveRule()">Gem regel</button></div></div></div></div>
<section class="mt-5"><div class="mb-3"><div class="eyebrow">DINE REGLER</div><h2 class="h4 mb-0">Planlagte opgavelister</h2></div><div id="rules"></div></section>
</div>
<style>.reminder-rules-page{max-width:1180px}.rule-hero{background:linear-gradient(120deg,#0b3e68,#126d91 65%,#18a6a6);color:#fff;border-radius:24px;padding:34px 40px;display:flex;justify-content:space-between;align-items:center}.rule-hero h1{font-size:clamp(1.7rem,3vw,2.4rem);margin:.35rem 0 .6rem;font-weight:750}.rule-hero p{margin:0;max-width:680px;color:#d8edf5;font-size:1.05rem}.eyebrow{font-size:.73rem;letter-spacing:.11em;font-weight:800;color:#5a7890}.hero-eyebrow{color:#a9edf0}.hero-icon{width:74px;height:74px;border-radius:50%;display:grid;place-items:center;font-size:2.4rem;font-weight:700;background:#ffffff22;border:1px solid #ffffff40}.rule-card{border-radius:22px}.section-icon{width:42px;height:42px;border-radius:12px;display:grid;place-items:center;background:#e6f4fa;color:#0c6895;font-size:1.35rem}.rule-options{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.option{margin:0;border:1px solid #dce8ef;border-radius:14px;padding:16px 17px 16px 40px;background:#fbfdff}.option .form-check-input{margin-left:-24px;margin-top:.35rem}.option small{display:block;color:#6a7c89;margin-top:3px}.rule-entry{border:1px solid #dde8ef;border-radius:17px;background:#fff;padding:18px 20px;display:flex;align-items:center;justify-content:space-between;gap:16px}.rule-time{display:inline-flex;border-radius:999px;padding:5px 10px;background:#edf6fa;color:#155c82;font-size:.86rem;font-weight:650}.empty-rules{border:1px dashed #bfd2df;border-radius:16px;padding:28px;color:#647684;text-align:center;background:#fcfeff}@media(max-width:700px){.rule-hero{padding:27px}.hero-icon{display:none}.rule-options{grid-template-columns:1fr}.rule-entry{align-items:flex-start;flex-direction:column}}</style>
<script>
const rulesEl=document.getElementById('rules');
const escapeHtml=value=>String(value||'').replace(/[&<>'"]/g,char=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[char]));
async function responseMessage(response,fallback){const body=await response.json().catch(()=>({}));return body.detail||body.message||fallback}
async function load(){const response=await fetch('/api/v1/reminder-task-rules');if(!response.ok){rulesEl.innerHTML=`<div class="alert alert-danger">${escapeHtml(await responseMessage(response,'Kunne ikke hente regler'))}</div>`;return}const list=await response.json();rulesEl.innerHTML=list.map(rule=>`<article class="rule-entry"><div><div class="fw-bold fs-5">${escapeHtml(rule.title)}</div><div class="mt-2">${(rule.times_json||[]).map(time=>`<span class="rule-time me-1">${escapeHtml(time)}</span>`).join('')} ${rule.include_groups?'<span class="text-muted small ms-1">· Mine grupper er med</span>':''}</div></div><button class="btn btn-outline-primary" onclick="sendRule(${rule.id},this)">Send nu ↗</button></article>`).join('')||'<div class="empty-rules">Ingen regler endnu. Opret den første ovenfor, og test den derefter med <strong>Send nu</strong>.</div>'}
async function saveRule(){const button=document.getElementById('saveButton');const times=document.getElementById('ruleTimes').value.split(',').map(value=>value.trim()).filter(Boolean);if(!times.length)return alert('Vælg mindst ét tidspunkt');button.disabled=true;button.textContent='Gemmer…';try{const response=await fetch('/api/v1/reminder-task-rules',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({title:document.getElementById('ruleTitle').value,times,include_groups:document.getElementById('ruleGroups').checked,notify_mattermost:document.getElementById('ruleMattermost').checked})});if(!response.ok)throw new Error(await responseMessage(response,'Kunne ikke gemme'));await load()}catch(error){alert(error.message)}finally{button.disabled=false;button.textContent='Gem regel'}}
async function sendRule(id,button){const original=button.innerHTML;button.disabled=true;button.textContent='Sender…';try{const response=await fetch(`/api/v1/reminder-task-rules/${id}/send-now`,{method:'POST'});const result=await response.json().catch(()=>({}));if(!response.ok||!result.sent)throw new Error(result.detail||result.message||'Kunne ikke sende');alert(`Opgavelisten er sendt med ${result.count} sager.`)}catch(error){alert(error.message)}finally{button.disabled=false;button.innerHTML=original}}
load();
</script>
{% endblock %}