Files

100 lines
5.1 KiB
HTML
Raw Permalink Normal View History

2026-09-13 20:03:24 +01:00
{% extends "base.html" %}
{% block title %}{{ 'Edit' if wf else 'New' }} workflow — MartinhalApprovalFlow{% endblock %}
{% block content %}
<p><a href="{{ url_for('admin') }}">&larr; All workflows</a></p>
<h1>{{ 'Edit workflow' if wf else 'New workflow' }}</h1>
<p class="sub">Each workflow has its own allowed sender domain, its own approver, and its own email wording.</p>
<form method="post">
<div class="card">
<h2 style="margin-top:0">Basics</h2>
<div class="grid2">
<div>
<label for="n">Name</label>
<input id="n" type="text" name="name" value="{{ wf.name if wf else '' }}" required>
</div>
<div>
<label for="de">Description <small>(shown to users on the main page)</small></label>
<input id="de" type="text" name="description" value="{{ wf.description if wf else '' }}">
</div>
</div>
<div class="grid2">
<div>
<label for="ap">Approval chain <small>(one email per line, in order — the request goes to the first person; each approval sends it to the next; any denial stops the workflow)</small></label>
<textarea id="ap" name="approvers" class="tpl" required
placeholder="team-lead@example.com&#10;manager@example.com&#10;director@example.com">{% if wf %}{{ '\n'.join(wf.approvers | fromjson) }}{% endif %}</textarea>
</div>
<div>
<label for="kn">Knowledge chain <small>(one email per line — these people never approve, but are informed by e-mail when a request is created and every time an approval, denial or final decision happens)</small></label>
<textarea id="kn" name="knowledge" class="tpl"
placeholder="team-inbox@example.com&#10;finance@example.com">{% if wf %}{{ '\n'.join(wf.knowledge | fromjson) }}{% endif %}</textarea>
</div>
</div>
<label class="check"><input type="checkbox" name="active" {% if not wf or wf.active %}checked{% endif %}> Active — accept new requests</label>
</div>
<div class="card">
<h2 style="margin-top:0">Email wording</h2>
<p class="muted">Placeholders: <span class="mono">{workflow} {requester} {subject} {body} {request_id} {step} {total_steps} {decided_by} {created_at} {summary} {deny_reason} {approve_url} {deny_url}</span>. Leave a field empty to use the default.</p>
<label>Approval request — subject</label>
<input type="text" name="approval_subject" value="{{ wf.approval_subject if wf else defaults.approval_subject }}">
<label>Approval request — body <small>(must include {approve_url} and {deny_url})</small></label>
<textarea class="tpl" name="approval_body">{{ wf.approval_body if wf else defaults.approval_body }}</textarea>
<div class="grid2">
<div>
<label>Approved notice — subject</label>
<input type="text" name="approved_subject" value="{{ wf.approved_subject if wf else defaults.approved_subject }}">
<label>Approved notice — body</label>
<textarea class="tpl" name="approved_body">{{ wf.approved_body if wf else defaults.approved_body }}</textarea>
</div>
<div>
<label>Denied notice — subject</label>
<input type="text" name="denied_subject" value="{{ wf.denied_subject if wf else defaults.denied_subject }}">
<label>Denied notice — body</label>
<textarea class="tpl" name="denied_body">{{ wf.denied_body if wf else defaults.denied_body }}</textarea>
</div>
</div>
</div>
<button type="submit">{{ 'Save changes' if wf else 'Create workflow' }}</button>
</form>
<div class="card">
<h2 style="margin-top:0">Images for email bodies</h2>
<p class="muted">These images can be used in the <b>approval request body</b>, <b>approved notice body</b> and
<b>denied notice body</b> above. Copy an image's tag into the text where the image should appear —
it is embedded in the email at that spot. PNG, JPG or GIF, up to 2 MB each. The library is shared by all workflows.</p>
{% if images %}
<div class="imggrid">
{% for name in images %}
<div class="imgcard">
<img src="{{ url_for('email_image', name=name) }}" alt="{{ name }}">
<div class="imgmeta">
<span class="mono" title="{{ name }}">{{ name }}</span>
<code class="mono tag" onclick="navigator.clipboard && navigator.clipboard.writeText(this.textContent)"
title="Click to copy">{{ '{image:' + name + '}' }}</code>
<form method="post" action="{{ url_for('email_image_delete') }}"
onsubmit="return confirm('Delete {{ name }}? Emails using its tag will show plain text instead.')">
<input type="hidden" name="name" value="{{ name }}">
<input type="hidden" name="next" value="{{ request.path }}">
<button class="btn ghost small" type="submit">Delete</button>
</form>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="muted">No images uploaded yet.</p>
{% endif %}
<form method="post" action="{{ url_for('email_image_upload') }}" enctype="multipart/form-data" class="rowline" style="margin-top:1rem">
<input type="hidden" name="next" value="{{ request.path }}">
<input type="file" name="image" accept=".png,.jpg,.jpeg,.gif" required>
<button class="small" type="submit">Upload image</button>
</form>
</div>
{% endblock %}