WIP: Add a ticketing app for Chill #21

Draft
julienfastre wants to merge 49 commits from ticket-app-master into main
Showing only changes of commit 99e1763332 - Show all commits

View File

@ -1,143 +0,0 @@
{% extends "@ChillMain/layout.html.twig" %}
{% block content %}
<div class="col-md-10 col-xxl error-page">
<h1 class="chill-red">{{ 'Oops, we came across an error!'|trans }}</h1>
<p>{{ 'Don\'t panick though, we\'ll fix it as soon as possible. To help us out, please send us the information below.'|trans }}</p>
<div id="error-details" class="flex-table alert alert-warning">
<dl>
<dt>{{ 'Date and time of error'|trans }}:</dt><dd>{{ "now"|date("d/m/Y H:i:s") }}</dd>
<dt>{{ 'Error message'|trans }}:</dt><dd>{{ exception.message }}</dd>
<dt>Stacktrace:</dt><dd>{{ exception.traceAsString }}</dd>
</dl>
</div>
<ul class="record_actions sticky-form-buttons">
<li>
<button data-copy="#error-details" data-done="Error details copied" class="btn btn-warning" id="copy">
<i class="fa fa-copy"></i>
{{ 'Copy'|trans }}
</button>
</li>
<li>
<a class="btn btn-success" href="mailto:?subject=Chill Error {{ exception.statusCode }}&amp;body=Datetime:%0D%0A{{ "now"|date("d/m/Y H:i:s") }}%0D%0A%0D%0AError message:%0D%0A{{ exception.message|escape('html_attr') }}%0D%0A%0D%0AStacktrace:%0D%0A{{ exception.traceAsString|escape('html_attr') }}">
{{ 'Send by email'|trans }}
</a>
</li>
</ul>
</div>
{% endblock %}
{% block js %}
<script>
const activeClass = { copy: 'copyactive', paste: 'pasteactive' }
const doneMessage = { copy: 'copied', paste: 'pasted' }
const doneClass = 'done';
window && window.addEventListener('DOMContentLoaded', init);
function init() {
const body = document && document.body;
// clipboard API available?
if (!body || !navigator.clipboard) return;
// text copy active
if (navigator.clipboard.writeText) body.classList.add(activeClass.copy);
// text paste active
if (navigator.clipboard.readText) body.classList.add(activeClass.paste);
// copy/paste handler
body.addEventListener('click', clipboardHandler);
}
async function clipboardHandler(e) {
// get clicked element
const
target = e.target,
type = (undefined === target.dataset.paste ? 'copy' : 'paste'),
content = target.dataset[type];
if (undefined === content) return;
// is CSS selector?
let select;
try {
select = content && document.querySelector(content);
}
catch (error) {}
// call copy or paste handler
const handler = { copy, paste };
if (!await handler[type]( select, content )) return;
// show success message
if (!target.dataset.done) target.dataset.done = doneMessage[type];
target.addEventListener('animationend', () => target.classList.remove(doneClass), { once: true });
target.classList.add(doneClass);
}
// copy to clipboard
async function copy(select, content) {
// get text
const copytext = select ? select.value || select.innerText : content;
try {
await navigator.clipboard.writeText(copytext);
document.getElementById("copy").innerText = "Copié";
return true;
}
catch (error) {
console.log('copy error', error);
}
}
// paste handler
async function paste(select) {
if (!select) return;
// paste from clipboard
try {
const pastetext = await navigator.clipboard.readText();
if (undefined === select.value) {
select.innerText += pastetext;
}
else {
select.value += pastetext;
}
return true;
}
catch (error) {
console.log('paste error', error);
}
}
</script>
{% endblock %}