diff --git a/apprise_api/api/templates/config.html b/apprise_api/api/templates/config.html index 7b56991..b95b0c8 100644 --- a/apprise_api/api/templates/config.html +++ b/apprise_api/api/templates/config.html @@ -8,9 +8,9 @@
{{ key }}
info
{% trans "Overview" %}
- {% if not CONFIG_LOCK %}settings{% else %}lock{% endif %} {%trans "Configuration" %}
+ {% if not CONFIG_LOCK %}settings{% else %}lock{% endif %} {%trans "Configuration" %}
- {% if not CONFIG_LOCK %}web{% else %}lock{% endif %} {%trans "Review" %}
+ {% if not CONFIG_LOCK %}web{% else %}lock{% endif %} {%trans "Review" %}
announcement {%trans "Notifications" %}
@@ -47,6 +47,11 @@ {% trans "Getting Started" %}
+
+ {% blocktrans %}
+ Use the web Review section to review what was parsed/detected from your defined configuration.
+ {% endblocktrans %}
+
{% blocktrans %}
Use the announcement Notifications section to test out your saved configuration.
@@ -54,15 +59,6 @@ {% trans "Getting Started" %}
-
-
-
- info
- {% blocktrans %}Once you have successfully load at least one Apprise URL on the settings Configuration section, your loaded entries will display here.
- {% endblocktrans %}
-
-
-
{% else %}
{% trans "Apprise Configuration is Locked" %}
@@ -147,11 +143,18 @@ {% trans "Your Configuration Is Locked" %}
{% if not CONFIG_LOCK %}
-
- {% blocktrans %}The following URLs have been detected:{% endblocktrans %}
-
-
+
+
+
+ info
+ {% blocktrans %}Once you have successfully loaded at least one Apprise URL on the settings Configuration section, your loaded entries will display here.
+ {% endblocktrans %}
+
+
+
+
{% trans "Loaded Configuration" %}
+ {% blocktrans %}Tip: Click on a tag (🏷️) to pre-select in the announcementNotifications section with the tag already pre-selected.{% endblocktrans %}
@@ -189,24 +192,35 @@ {% trans "Persistent Store Endpoints" %}
{% if STATEFUL_MODE != 'disabled' %}
async function main_init(){
+ const params = new Proxy(new URLSearchParams(window.location.search), {
+ get: (searchParams, prop) => searchParams.get(prop),
+ });
+
+ if (params.title) {
+ document.querySelector('#id_title').value = params.title;
+ }
+ if (params.body) {
+ document.querySelector('#id_body').value = params.body;
+ }
+
+{% if not CONFIG_LOCK %}
// 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');
+ .parentNode.classList.add('disabled');
// Disable any has-config entries
- document.querySelector('.has-config')
- .style.display = 'none';
-
+ document.querySelectorAll('.has-config').forEach(function(e){
+ e.style.display = 'none'
+ });
// Ensure we show our progress loader and reset our url list
document.querySelector('#url-list').textContent = ''
document.querySelector('#url-list-progress').style.display = null;
-{% if not CONFIG_LOCK %}
// Ensure no-config sections are visible
- document.querySelector('.no-config')
- .style.display = null;
-{% endif %}
+ document.querySelectorAll('.no-config').forEach(function(e){
+ e.style.display = null;
+ });
// perform a tag retrieval; start with 'all'
let tags = ['all'];
@@ -217,7 +231,7 @@ {% trans "Persistent Store Endpoints" %}
if(jsonResponse.status == 204) {
// Take an early exit
document.querySelector('#url-list-progress').style.display = 'none';
- document.querySelector('#url-list').textContent = '{% trans "There are no URLs defined. Click on the ⚙️ Configuration tab and define some." %}'
+ document.querySelector('#url-list').textContent = ''
return;
} else if(jsonResponse.status != 200) {
@@ -234,42 +248,71 @@ {% trans "Persistent Store Endpoints" %}
const external_data = tags.concat(data.tags).reduce(function(result, item) {
result[item] = null;
return result;
- }, {})
+}, {})
const chipElement = document.querySelector('.chips');
M.Chips.init(chipElement, {
- placeholder: 'Optional Tag',
- secondaryPlaceholder: 'Another Tag',
+ placeholder: '{% trans "Optional Tag" %}',
+ secondaryPlaceholder: '{% trans "Another Tag" %}',
autocompleteOptions: {
data: external_data,
minLength: 0
},
- onChipAdd: function(e, chip) {
+ onChipAdd: function(e, data) {
var $this = this;
+ const chip = data.childNodes[0].textContent;
+ document.querySelectorAll(`#url-list .chip[name=${chip}]`).forEach(function(e){
+ if (!e.classList.contains('selected')) {
+ e.classList.add('selected');
+ }
+ })
+ document.querySelectorAll(`#url-list .chip.chip-notag`).forEach(function(e){
+ if (e.classList.contains('selected')) {
+ e.classList.remove('selected');
+ }
+ })
$this.chipsData.forEach(function(e, index) {
if(!(e.tag in external_data))
$this.deleteChip(index);
})
+ },
+ onChipDelete: function(e, data) {
+ var $this = this;
+ const chip = data.childNodes[0].textContent;
+ document.querySelectorAll(`#url-list .chip[name=${chip}]`).forEach(function(e){
+ if (e.classList.contains('selected')) {
+ e.classList.remove('selected');
+ }
+ })
+ if ($this.chipsData.length == 0){
+ // last item
+ document.querySelectorAll(`#url-list .chip.chip-notag`).forEach(function(e){
+ if (!e.classList.contains('selected')) {
+ e.classList.add('selected');
+ }
+ })
+ }
}
});
-
- // our GET parameters to be treated as template values
- var tagRe = new RegExp('[^[A-Za-z0-9_-]+');
- const params = new Proxy(new URLSearchParams(window.location.search), {
- get: (searchParams, prop) => searchParams.get(prop),
+{% else %}
+ {# Empty external data set #}
+ const data = {
+ urls: []
+ };
+ M.Chips.init(chipElement, {
+ placeholder: '{% trans "Optional Tag" %}',
+ secondaryPlaceholder: '{% trans "Another Tag" %}'
});
+{% endif %}
+ const chipInstance = M.Chips.getInstance(chipElement);
if (params.tag) {
+ // our GET parameters to be treated as template values
+ var tagRe = new RegExp('[^[A-Za-z0-9_-]+');
params.tag.split(tagRe).forEach(function (tag, index) {
- M.Chips.getInstance(chipElement).addChip({tag: tag, image: ''});
+ chipInstance.addChip({tag: tag, image: ''});
});
}
- if (params.title) {
- document.querySelector('#id_title').value = params.title;
- }
- if (params.body) {
- document.querySelector('#id_body').value = params.body;
- }
-
+{% if not CONFIG_LOCK %}
// Now build our our loaded list of configuration for our welcome page
let urlList = document.createElement('ul');
@@ -281,51 +324,86 @@ {% trans "Persistent Store Endpoints" %}
li.setAttribute('class', 'card-panel');
li.appendChild(code);
+ urlList.appendChild(li);
+ // Store `all` tag
+ entry.tags.unshift('all')
+
+ if (entry.tags.length === 1){
+ // This entry triggers when no tags are defined
+ // Store '' (empty) tag for notice generation
+ entry.tags.unshift('')
+
+ }
// Get our tags associate with the URL
entry.tags.forEach(function (tag) {
let chip = document.createElement('div');
- chip.setAttribute('class', 'chip');
- chip.setAttribute('name', tag);
- chip.setAttribute('href', `?tag=${tag}#notify`);
- chip.textContent = `🏷️ ${tag}`;
- li.appendChild(chip);
-
- chip.addEventListener('click', function(e) {
- e.preventDefault();
- window.history.pushState(null, null, this.getAttribute('href'));
- document.querySelector('.config-overview li a[href="#notify"]').click()
-
- const chipElement = document.querySelector('.chips');
- M.Chips.getInstance(chipElement).addChip({tag: this.getAttribute('name'), image: ''});
- }, false);
+ chip.setAttribute('class', `chip`);
+ if(tag.length > 0) {
+ // we're dealing with a valid tag
+ chip.setAttribute('name', tag);
+ chip.textContent = `🏷️ ${tag}`;
+
+ const index = chipInstance.chipsData.findIndex(function (e) {
+ return e.tag === tag;})
+ if (index >= 0) {
+ chip.classList.add('selected');
+ }
+ li.appendChild(chip);
+
+ chip.addEventListener('click', function(e) {
+ e.preventDefault();
+ const index = chipInstance.chipsData.findIndex(function (e) {
+ return e.tag === tag;
+ });
+ if(index < 0) {
+ chipInstance.addChip({tag: this.getAttribute('name'), image: ''});
+ } else {
+ chipInstance.deleteChip(index);
+ }
+ }, false);
+ } else {
+ // no tags were defined for this element
+ chip.classList.add('chip-notag');
+ chip.textContent = '🔖 ' + 'no-tag';
+ if (chipInstance.chipsData.length === 0) {
+ chip.classList.add('selected');
+ }
+ li.appendChild(chip);
+ chip.addEventListener('click', function(e) {
+ e.preventDefault();
+ while(chipInstance.chipsData.length > 0){
+ chipInstance.deleteChip(0);
+ }
+ chip.classList.add('selected');
+ }, false);
+ }
});
-
- urlList.appendChild(li);
});
+{% endif %}
+{% if not CONFIG_LOCK %}
// Store our new list
document.querySelector('#url-list-progress').style.display = 'none';
document.querySelector('#url-list').textContent = ''
if(urlList.childNodes.length > 0) {
// Ensure has-config sections are visible
- document.querySelector('.has-config')
- .style.display = null;
+ document.querySelectorAll('.has-config').forEach(function(e){
+ e.style.display = null;
+ });
// Remove our restrictions on sending notifications
document.querySelector('.config-overview li a[href="#notify"]')
.parentNode.classList.remove('disabled');
- {% if not CONFIG_LOCK %}
// Disable any no-config entries
- document.querySelector('.no-config')
- .style.display = 'none';
- {% endif %}
+ document.querySelectorAll('.no-config').forEach(function(e){
+ e.style.display = 'none';
+ });
// Save our list to the screen
document.querySelector('#url-list').appendChild(urlList);
- {% if not CONFIG_LOCK %}
//
// Load our configuration now into the configuration tab
//
@@ -362,14 +440,15 @@ {% trans "Persistent Store Endpoints" %}
}
document.querySelector('#id_format').dispatchEvent(event);
}
- {% endif %}
} else {
document.querySelector('#url-list').textContent = '{% trans "There are no Apprise URL(s) loaded." %}'
}
+ {% endif %}
return null;
}
+{% if not CONFIG_LOCK %}
function config_init() {
// over-ride manual submit for a nicer user experience
document.querySelector('#addconfig').onsubmit = function(event) {
@@ -443,6 +522,7 @@ {% trans "Persistent Store Endpoints" %}
return false;
}
}
+{% endif %}
function form_file_input_hack() {
/*
@@ -478,7 +558,8 @@ {% trans "Persistent Store Endpoints" %}
selected.textContent = file.name;
});
});
- }
+}
+
function notify_init() {
// over-ride manual submit for a nicer user experience
document.querySelector('#donotify').onsubmit = function(event) {
@@ -571,16 +652,6 @@ {% trans "Persistent Store Endpoints" %}
return false;
}
}
-
-/* Initialize our page */
-main_init();
-{% if not CONFIG_LOCK %}
-/* Initialze our configuration */
-config_init();
-
-{% endif %}
-notify_init();
-form_file_input_hack();
{% endif %}
{% endblock %}
@@ -599,5 +670,14 @@ {% trans "Persistent Store Endpoints" %}
// Hide tag field since we use the pretty Materialize Chip setup instead
document.querySelector('#id_tag').style.display = 'none';
+/* Initialize our page */
+main_init();
+
+{% if not CONFIG_LOCK %}
+/* Initialze our configuration */
+config_init();
+{% endif %}
+notify_init();
+form_file_input_hack();
{% endif %}
{% endblock %}
diff --git a/apprise_api/static/css/base.css b/apprise_api/static/css/base.css
index ce69914..999a180 100644
--- a/apprise_api/static/css/base.css
+++ b/apprise_api/static/css/base.css
@@ -125,10 +125,11 @@ textarea {
float: left;
}
-#url-list .chip {
+.chip {
margin: 0.3rem;
background-color: inherit;
- border: 1px solid #e4e4e4;
+ border: 1px solid #464646;
+ color: #464646;
cursor: pointer;
}
@@ -232,3 +233,7 @@ code.config-id {
padding: 0 1em;
overflow: hidden;
}
+
+.chip.selected {
+ font-weight: 600;
+}
diff --git a/apprise_api/static/css/theme-dark.min.css b/apprise_api/static/css/theme-dark.min.css
index cbed69f..4f125af 100644
--- a/apprise_api/static/css/theme-dark.min.css
+++ b/apprise_api/static/css/theme-dark.min.css
@@ -1324,3 +1324,8 @@ input[type=range]::-ms-thumb {
color: #ebcb8b;
background-color: #2e3440;
}
+
+.chip.selected {
+ color: #fff;
+ background-color: #258528!important;
+}
diff --git a/apprise_api/static/css/theme-light.min.css b/apprise_api/static/css/theme-light.min.css
index e98a73c..77c6353 100644
--- a/apprise_api/static/css/theme-light.min.css
+++ b/apprise_api/static/css/theme-light.min.css
@@ -1,7 +1,21 @@
.tabs .tab a {background-color: #f3f3f3;}
-.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover, .tab.disabled i.material-icons{color:#a7a7a7}
-.tabs .tab.disabled a,.tabs .tab.disabled a:hover{background-color: #f3f3f3; color:#a7a7a7}
+.tabs.tabs-transparent .tab a,
+.tabs.tabs-transparent .tab.disabled a,
+.tabs.tabs-transparent .tab.disabled a:hover,
+.tab.disabled i.material-icons{
+ color:#a7a7a7
+}
+.tabs .tab.disabled a,
+.tabs .tab.disabled a:hover {
+ background-color: #f3f3f3;
+ color:#a7a7a7
+}
.file-selected {
color: #039be5;
background-color: #f3f3f3;
}
+
+.chip.selected {
+ color: #fff;
+ background-color: #258528!important;
+}