{% extends 'base.html' %} {% load i18n %} {% block body %}

{% trans "Management for:" %} {{ key }}

{% blocktrans %} Here is where you can store your configuration so that it can be accessed by Apprise. You can always refer to the Apprise Wiki if you're having troubles assembling your URL(s). You have chosen to associate your configuration with the key {{key}}. If anything was previously associated with this key, it will be replaced if you continue. {% endblocktrans %}

{% blocktrans %} In the future you can return to this configuration screen at any time by placing the following into your browser:{% endblocktrans %}
{{request.scheme}}://{{request.META.HTTP_HOST}}{{request.path}}

{% blocktrans %}For example, the following command would cause apprise to retrieve the configuration loaded and send a test notification to all of your added services:{% endblocktrans %}
apprise --body="Test Message" --tag=all --config={{request.scheme}}://{{request.META.HTTP_HOST}}{% url "get" key %}
{% trans "Option 1: Set By URL(s)" %}

{% blocktrans %} Use a comma and/or space to separate one Apprise URL from another. {% endblocktrans %}

{{ form_url }}

{% trans "Option 2: Set By Config" %}

{% blocktrans %} This option grants you a bit more flexability because you can additionally associate tags with your URLs. Those using YAML configuration can also alter the Apprise Asset object as well for a more customized look and feel. {% endblocktrans %}

{{ form_cfg }}

{% blocktrans %} You can send a notification using the loaded configuration: {% endblocktrans %}

{{ form_notify }}

{% endblock %} {% block jsfooter %} async function update() { // disable the notification tab until we know for certain // a notification is possible document.querySelector('.config-overview li a[href="#notify"]') .parentNode.classList.add('disabled'); // perform our status check let response = await fetch('{% url "get" key %}', { method: 'POST', }); let result = await response; if(response.status == 204) { // no problem; we simply have no content to retrieve return ''; } else if(response.status == 200) { // configuration found // Remove our restrictions on sending notifications document.querySelector('.config-overview li a[href="#notify"]') .parentNode.classList.remove('disabled'); // Set our configuration so it's visible response.text().then(function (text) { document.querySelector('#id_config').value = text; }); // perform a tag retrieval; start with 'all' let tags = ['all']; let jsonResponse = fetch('{% url "json_urls" key %}', { method: 'GET', }).then(function(jsonResponse) { return jsonResponse.json(); }).then(function (data) { // Initialize our tags making it easy for an end user to // choose from. Tags are based off ones found in the saved // configuration. M.Chips.init(document.querySelectorAll('.chips'), { placeholder: 'Optional Tag', secondaryPlaceholder: 'Another Tag', autocompleteOptions: { data: tags.concat(data.tags).reduce(function(result, item) { result[item] = null; return result; }, {}), limit: Infinity, minLength: 1 } }); }).catch(function (err) { // There was an error }); return response; } // if we reach here, we failed return null; } update(); // over-ride manual submit for a nicer user experience document.querySelector('#addurl').onsubmit = function(event) { event.preventDefault(); const form = this; const body = new URLSearchParams(new FormData(form)); // perform our status check let response = fetch('{% url "add" key %}', { method: 'POST', body: body, }).then(function(response) { if(response.status == 200) { // update our settings update(); // reset our form form.reset(); Swal.fire( 'Save', 'Successfully saved the specified URL(s).', 'success' ); } else { Swal.fire( 'Save', 'Failed to save the specified URL(s).', 'error' ); } }); return false; } // over-ride manual submit for a nicer user experience document.querySelector('#addconfig').onsubmit = function(event) { event.preventDefault(); const form = this; const body = new URLSearchParams(new FormData(form)); // perform our status check let response = fetch('{% url "add" key %}', { method: 'POST', body: body, }).then(function(response) { if(response.status == 200) { // update our settings update(); // user notification Swal.fire( 'Save', 'Successfully saved the specified URL(s).', 'success' ); } else { // user notification Swal.fire( 'Save', 'Failed to save the specified URL(s).', 'error' ); } }); return false; } // over-ride manual submit for a nicer user experience document.querySelector('#donotify').onsubmit = function(event) { event.preventDefault(); const chipElement = document.querySelector('.chips'); chipElement.querySelector('.chips'); const chipInput = document.querySelector('.chips > input'); if(chipInput.value) { // This code just handles text typed in the tag section that was // not submitted. This forces any lingering un-commited text // into a tag just prior to it's submission const ev = new KeyboardEvent('keydown', { altKey:false, bubbles: true, cancelBubble: false, cancelable: true, charCode: 0, code: "Enter", composed: true, ctrlKey: false, currentTarget: null, defaultPrevented: true, detail: 0, eventPhase: 0, isComposing: false, isTrusted: true, key: "Enter", keyCode: 13, location: 0, metaKey: false, repeat: false, returnValue: false, shiftKey: false, type: "keydown", which: 13 }); chipInput.dispatchEvent(ev); } // store tags (as comma separated string) from materialize chip type into form document.querySelector('#id_tag').value = M.Chips.getInstance(chipElement).chipsData.reduce( function(s, a){ s.push(a.tag) return s; }, []).join(",") const form = this; const body = new URLSearchParams(new FormData(form)); // perform our status check let response = fetch('{% url "notify" key %}', { method: 'POST', body: body, }).then(function(response) { if(response.status == 200) { // user notification Swal.fire( 'Notification', 'Successfully sent the notification(s).', 'success' ); } else { // user notification Swal.fire( 'Notification', 'Failed to send the notification(s).', 'error' ); } }); return false; } {% endblock %} {% block onload %} {{ block.super }} document.querySelector('label [for="id_tag"]') { // create a new div with the class 'chips' assigned to it const element = document.createElement('div') let refNode = document.querySelector('label[for="id_tag"]') element.classList.add("chips") element.style.margin = '0' refNode.parentNode.insertBefore(element, refNode.nextSibling) } // Hide tag field since we use the pretty Materialize Chip setup instead document.querySelector('#id_tag').style.display = 'none'; {% endblock %}