mirror of
https://github.com/caronc/apprise-api.git
synced 2024-11-07 16:54:10 +01:00
Refactored dark/light CSS + New Review Tab (#178)
This commit is contained in:
parent
4bf5093d8f
commit
2c7f7b36fe
@ -7,21 +7,23 @@
|
||||
<meta charset="utf-8">
|
||||
<!--Let browser know website is optimized for mobile-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}" />
|
||||
<!--materialize-->
|
||||
<link rel="stylesheet" href="{% get_static_prefix %}css/{{request.theme|safe}}/materialize.min.css" />
|
||||
<link rel="stylesheet" href="{% get_static_prefix %}css/materialize.min.css" />
|
||||
<!--material-design-icons-->
|
||||
<link rel="stylesheet" href="{% static 'iconfont/material-icons.css' %}">
|
||||
<!--highlightjs-->
|
||||
<link rel="stylesheet" href="{% get_static_prefix %}css/highlight.min.css">
|
||||
<!--common-->
|
||||
<link rel="stylesheet" href="{% static 'css/base.css' %}" />
|
||||
<!--highlightjs-->
|
||||
<link rel="stylesheet" href="{% get_static_prefix %}css/{{request.theme|safe}}/highlight.min.css">
|
||||
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}" />
|
||||
<!--materialize-->
|
||||
<script src="{% static 'js/materialize.min.js' %}"></script>
|
||||
<!--sweetalert2-->
|
||||
<script src="{% static 'js/sweetalert2.all.min.js' %}"></script>
|
||||
<!--highlightjs-->
|
||||
<script src="{% static 'js/highlight.pack.js' %}"></script>
|
||||
<!--theme-->
|
||||
<link rel="stylesheet" href="{% get_static_prefix %}css/theme-{{request.theme|safe}}.min.css">
|
||||
<title>{% block title %}{% trans "Apprise API" %}{% endblock %}</title>
|
||||
</head>
|
||||
|
||||
|
@ -2,15 +2,17 @@
|
||||
{% load i18n %}
|
||||
{% block body %}
|
||||
{% if STATEFUL_MODE != 'disabled' %}
|
||||
<h4>{% trans "Management for Config ID:" %} <em>{{ key }}</em></h4>
|
||||
<h4>{% trans "Management for Config ID:" %} <code class="config-id">{{ key }}</code></h4>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<ul class="tabs config-overview">
|
||||
<li class="tab col s4"><a class="active" href="#overview"><i class="material-icons">info</i>
|
||||
<li class="tab col s3"><a class="active" href="#overview"><i class="material-icons">info</i>
|
||||
{% trans "Overview" %}</a></li>
|
||||
<li class="tab {% if CONFIG_LOCK %}tab-locked {% endif %}col s4"><a href="#config"><i class="material-icons">{% if not CONFIG_LOCK %}settings{% else %}lock{% endif %}</i> {%trans "Configuration" %}</a>
|
||||
<li class="tab {% if CONFIG_LOCK %}tab-locked {% endif %}col s3"><a href="#config"><i class="material-icons">{% if not CONFIG_LOCK %}settings{% else %}lock{% endif %}</i> {%trans "Configuration" %}</a>
|
||||
</li>
|
||||
<li class="tab col s4"><a href="#notify"><i class="material-icons">announcement</i> {%trans "Notifications" %}</a>
|
||||
<li class="tab {% if CONFIG_LOCK %}tab-locked {% endif %}col s3"><a href="#review"><i class="material-icons">{% if not CONFIG_LOCK %}web{% else %}lock{% endif %}</i> {%trans "Review" %}</a>
|
||||
</li>
|
||||
<li class="tab col s3"><a href="#notify"><i class="material-icons">announcement</i> {%trans "Notifications" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -123,13 +125,6 @@
|
||||
"{{request.scheme}}://{{request.META.HTTP_HOST}}{{BASE_URL}}/notify/<em>{{key}}</em>"</code></pre>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h5>{% trans "Loaded Configuration" %}</h5>
|
||||
<div id="url-list"></div>
|
||||
<div id="url-list-progress" class="progress" style="width:70%">
|
||||
<div class="indeterminate"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="config" class="col s12">
|
||||
@ -150,6 +145,24 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="review" class="col s12">
|
||||
{% if not CONFIG_LOCK %}
|
||||
<p>
|
||||
{% blocktrans %}The following URLs have been detected:{% endblocktrans %}
|
||||
</p>
|
||||
<div class="section">
|
||||
<h5>{% trans "Loaded Configuration" %}</h5>
|
||||
<div id="url-list"></div>
|
||||
<div id="url-list-progress" class="progress" style="width:70%">
|
||||
<div class="indeterminate"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<h5>{% trans "Your Configuration Is Locked" %}</h5>
|
||||
<p>{% blocktrans %}Access to your configuration has been disabled by your administrator.{% endblocktrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="notify" class="col s12">
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
@ -201,10 +214,16 @@ async function main_init(){
|
||||
let jsonResponse = await fetch('{% url "json_urls" key %}/?privacy=1', {
|
||||
method: 'GET',
|
||||
})
|
||||
if(jsonResponse.status != 200) {
|
||||
if(jsonResponse.status == 204) {
|
||||
// Take an early exit
|
||||
document.querySelector('#url-list-progress').style.display = 'none';
|
||||
document.querySelector('#url-list').textContent = '{% trans "An error occurred retrieving the list of loaded Apprise URL(s)" %}'
|
||||
document.querySelector('#url-list').textContent = '{% trans "There are no URLs defined. Click on the ⚙️ Configuration tab and define some." %}'
|
||||
return;
|
||||
|
||||
} else if(jsonResponse.status != 200) {
|
||||
// Take an early exit
|
||||
document.querySelector('#url-list-progress').style.display = 'none';
|
||||
document.querySelector('#url-list').textContent = '{% trans "💣 An error occurred retrieving the list of loaded Apprise URL(s)" %}'
|
||||
return;
|
||||
}
|
||||
|
||||
@ -212,12 +231,13 @@ async function main_init(){
|
||||
// choose from. Tags are based off ones found in the saved
|
||||
// configuration.
|
||||
const data = await jsonResponse.json();
|
||||
let external_data = tags.concat(data.tags).reduce(function(result, item) {
|
||||
const external_data = tags.concat(data.tags).reduce(function(result, item) {
|
||||
result[item] = null;
|
||||
return result;
|
||||
}, {})
|
||||
|
||||
M.Chips.init(document.querySelectorAll('.chips'), {
|
||||
const chipElement = document.querySelector('.chips');
|
||||
M.Chips.init(chipElement, {
|
||||
placeholder: 'Optional Tag',
|
||||
secondaryPlaceholder: 'Another Tag',
|
||||
autocompleteOptions: {
|
||||
@ -233,6 +253,23 @@ async function main_init(){
|
||||
}
|
||||
});
|
||||
|
||||
// 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),
|
||||
});
|
||||
if (params.tag) {
|
||||
params.tag.split(tagRe).forEach(function (tag, index) {
|
||||
M.Chips.getInstance(chipElement).addChip({tag: tag, image: ''});
|
||||
});
|
||||
}
|
||||
if (params.title) {
|
||||
document.querySelector('#id_title').value = params.title;
|
||||
}
|
||||
if (params.body) {
|
||||
document.querySelector('#id_body').value = params.body;
|
||||
}
|
||||
|
||||
// Now build our our loaded list of configuration for our welcome page
|
||||
let urlList = document.createElement('ul');
|
||||
|
||||
@ -248,8 +285,19 @@ async function main_init(){
|
||||
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);
|
||||
});
|
||||
|
||||
urlList.appendChild(li);
|
||||
@ -396,14 +444,47 @@ function config_init() {
|
||||
}
|
||||
}
|
||||
|
||||
function form_file_input_hack() {
|
||||
/*
|
||||
A small hack to remformat all `<input file>` upload options to a more cleaner
|
||||
and presentable look by wrapping it like this:
|
||||
|
||||
<span class="btn btn-file">
|
||||
<i class="material-icons left">cloud_upload</i>
|
||||
Browse<input type="file">
|
||||
</span>
|
||||
*/
|
||||
document.querySelectorAll('input[type=file]').forEach(function (entry) {
|
||||
const div = document.createElement('div');
|
||||
const selected = document.createElement('div');
|
||||
selected.style.display = 'none';
|
||||
selected.setAttribute('class', 'file-selected');
|
||||
const span = document.createElement('span')
|
||||
span.setAttribute('class', 'btn btn-file waves-effect waves-light');
|
||||
const i = document.createElement('i')
|
||||
span.textContent = '{% trans "Browse" %}';
|
||||
i.setAttribute('class', 'material-icons right');
|
||||
i.textContent = 'folder';
|
||||
div.appendChild(span);
|
||||
span.appendChild(i);
|
||||
entry.before(div)
|
||||
span.appendChild(entry);
|
||||
span.after(selected);
|
||||
|
||||
entry.addEventListener('change', function(e){
|
||||
const selected = this.parentNode.nextElementSibling;
|
||||
const file = e.target.files[0];
|
||||
selected.style.display = 'block'
|
||||
selected.textContent = file.name;
|
||||
});
|
||||
});
|
||||
}
|
||||
function notify_init() {
|
||||
// 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
|
||||
@ -496,8 +577,10 @@ main_init();
|
||||
{% if not CONFIG_LOCK %}
|
||||
/* Initialze our configuration */
|
||||
config_init();
|
||||
|
||||
{% endif %}
|
||||
notify_init();
|
||||
form_file_input_hack();
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -40,12 +40,12 @@
|
||||
<hr/>
|
||||
|
||||
<ul class="detail-buttons">
|
||||
<li><strong>{% blocktrans %}Category{% endblocktrans %}:</strong> {{entry.category}}</li>
|
||||
<li><strong>{% blocktrans %}Category{% endblocktrans %}:</strong> <code>{{entry.category}}</code></li>
|
||||
{% if entry.protocols %}
|
||||
<li><strong>{% blocktrans %}Insecure Schema(s){% endblocktrans %}:</strong> {{ entry.protocols|join:", " }}</li>
|
||||
<li><strong>{% blocktrans %}Insecure Schema(s){% endblocktrans %}:</strong> <code>{{ entry.protocols|join:", " }}</code></li>
|
||||
{% endif %}
|
||||
{% if entry.secure_protocols %}
|
||||
<li><strong>{% blocktrans %}Secure Schema(s){% endblocktrans %}:</strong> {{ entry.secure_protocols|join:", " }}</li>
|
||||
<li><strong>{% blocktrans %}Secure Schema(s){% endblocktrans %}:</strong> <code>{{ entry.secure_protocols|join:", " }}</code></li>
|
||||
{% endif %}
|
||||
<li><pre><code class="bash">
|
||||
# {% blocktrans %}Apprise URL Formatting{% endblocktrans %}</br>
|
||||
|
@ -22,17 +22,14 @@ input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tabs .tab.disabled a,.tabs .tab.disabled a:hover{font-weight: inherit}
|
||||
|
||||
code {
|
||||
background-color: #eee;
|
||||
font-family: monospace;
|
||||
white-space: normal;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
table code {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin-top: 0;
|
||||
}
|
||||
@ -46,6 +43,10 @@ td, th {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul.detail-buttons strong {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
h4 em {
|
||||
font-size: 2.0rem;
|
||||
display: inline-block;
|
||||
@ -114,13 +115,31 @@ textarea {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#url-list code {
|
||||
display: block;
|
||||
background-color: inherit;
|
||||
|
||||
#url-list .card-panel {
|
||||
padding: 0.5rem;
|
||||
margin: 0.1rem 0;
|
||||
border-radius: 12px;
|
||||
width: 50%;
|
||||
min-width: 35rem;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#url-list .chip {
|
||||
margin: 0.3rem;
|
||||
background-color: inherit;
|
||||
border: 1px solid #e4e4e4;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#url-list code {
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
white-space: wrap;
|
||||
text-wrap: wrap;
|
||||
overflow-wrap: break-word;
|
||||
border-radius: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Notification Details */
|
||||
@ -179,3 +198,37 @@ h6 {
|
||||
#overview pre {
|
||||
margin-left: 2.0rem
|
||||
}
|
||||
|
||||
code.config-id {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
/* file button styled */
|
||||
.btn-file {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.btn-file input[type=file] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
font-size: 100px;
|
||||
text-align: right;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
outline: none;
|
||||
background: white;
|
||||
cursor: inherit;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.file-selected {
|
||||
line-height: 2.0em;
|
||||
font-size: 1.2rem;
|
||||
border-radius: 5px;
|
||||
padding: 0 1em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
.nav.nav-color{background:#4c566a!important}.hljs{display:block;overflow-x:auto;padding:.5em;color:#d8dee9;background:#4c566a;transition:box-shadow .25s,-webkit-box-shadow .25s!important;border-radius:2px!important}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#4fa1ba;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#7091aa}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#a3be8c}.hljs-bullet,.hljs-symbol{color:#b48ead}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.no-config .info{color: #4c566a}.tabs .tab a:hover, .tabs .tab a.active {color: #4c566a}.theme a {color: #d8dee9}.url-enabled{color: #02c7a6}.url-disabled{color:#e00202}.btn, .btn-large,.btn-small {background-color:#333}.btn-large:hover, .btn-small:hover, .btn:hover {background-color:#222}i.material-icons{color:#6e7d9c}i.material-icons:hover{color:#57637a}.nav h1{color:#d8dee9!important}
|
File diff suppressed because one or more lines are too long
1326
apprise_api/static/css/theme-dark.min.css
vendored
Normal file
1326
apprise_api/static/css/theme-dark.min.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
apprise_api/static/css/theme-light.min.css
vendored
Normal file
7
apprise_api/static/css/theme-light.min.css
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.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}
|
||||
.file-selected {
|
||||
color: #039be5;
|
||||
background-color: #f3f3f3;
|
||||
}
|
Loading…
Reference in New Issue
Block a user