Implemented toast manager, moved job panel to the top, removed footer.

This commit is contained in:
Tiberiu Chibici 2020-04-24 00:21:44 +03:00
parent 6afca61dd9
commit 5175846310
9 changed files with 180 additions and 78 deletions

View File

@ -137,6 +137,39 @@
overflow-y: auto;
flex: 1; }
#toast-wrapper {
position: fixed;
right: 2rem;
top: 2rem;
z-index: 1000; }
.toast {
min-width: 15rem;
line-height: 1.5rem; }
.toast .typcn {
font-size: 1.5rem; }
.toast.bg-success {
background-color: rgba(134, 226, 155, 0.98) !important; }
.toast.bg-success .toast-header {
background-color: rgba(40, 167, 69, 0.75);
color: #f8f9fa; }
.toast.bg-success .toast-header > * {
color: #f8f9fa; }
.toast.bg-warning {
background-color: rgba(255, 231, 160, 0.98) !important; }
.toast.bg-warning .toast-header {
background-color: rgba(211, 158, 0, 0.75);
color: #f8f9fa; }
.toast.bg-warning .toast-header > * {
color: #f8f9fa; }
.toast.bg-danger {
background-color: rgba(243, 183, 189, 0.98) !important; }
.toast.bg-danger .toast-header {
background-color: rgba(220, 53, 69, 0.75);
color: #f8f9fa; }
.toast.bg-danger .toast-header > * {
color: #f8f9fa; }
#main_navbar {
position: fixed;
top: 0;

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,8 @@
@import "lib/theme";
@import "lib/loading";
@import "lib/hamburger";
$accent-color: #007bff;
$success-color: #28a745;
@import "lib/toast";
@import "lib/variables";
#main_navbar {
position: fixed;

View File

@ -1,5 +1,6 @@
import {JobPanel} from "./components/JobPanel.js";
import {AjaxModal} from "./components/AjaxModal.js";
import {ToastManager} from "./components/ToastManager.js";
// Document loaded
jQuery(function() {
@ -24,5 +25,8 @@ jQuery(function() {
}
modal.loadAndShow();
});
// Initialize toasts
window.ytsm_ToastManager = new ToastManager($('#toast-wrapper'));
});

View File

@ -101,7 +101,6 @@ export class JobPanel
_updateInternal(data)
{
this._updateJobs(data);
this._updateStatusBar();
this._updateProgressBar();
this._updateTitle();
@ -164,19 +163,6 @@ export class JobPanel
}
}
_updateStatusBar()
{
let text = "";
if (this.jobs.length === 1) {
text = `${this.jobs[0].description} | ${this.jobs[0].message}`;
}
else if (this.jobs.length > 1) {
text = `Running ${this.jobs.length} jobs...`;
}
$('#status-message').text(text);
}
_updateProgressBar()
{
if (this.jobs.length > 0) {

View File

@ -0,0 +1,93 @@
export class ToastManager {
toastWrapper = null;
constructor(toastWrapper) {
this.toastWrapper = toastWrapper;
}
/**
* Displays a toast message
* @param caption Title of the toast
* @param options An object containing the following attributes. Title and message are mandatory:
* - body: the main content
* - icon: a typcn class which will be used as an icon
* - cssClass: additional css classes to apply to the toast (i.e. toast-success, toast-fail)
* - duration: duration in milliseconds, defaults to 4000
*/
toast(caption, options) {
let body = '';
if (options.hasOwnProperty('body')) {
body = `<div class="toast-body">${options.body}</div>`;
}
let icon = '';
if (options.hasOwnProperty('icon')) {
icon = `<span class="typcn ${options.icon} mr-2"></span>`;
}
let cssClass = '';
if (options.hasOwnProperty('cssClass')) {
cssClass = options.cssClass;
}
let duration = 4000;
if (options.hasOwnProperty('duration')) {
duration = options.duration;
}
// Generate DOM
let elem = $(`
<div class="toast ${cssClass}" role="alert"
aria-live="assertive" aria-atomic="true">
<div class="toast-header">
${icon}
<strong class="mr-auto">${caption}</strong>
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
${body}
</div>`);
elem.appendTo(this.toastWrapper);
elem.toast({
animation: true,
autoHide: true,
delay: duration
});
elem.on('hidden.bs.toast', function () {
elem.remove();
});
elem.toast('show');
}
success(caption, options = {}) {
if (!options.hasOwnProperty('icon')) {
options.icon = 'typcn-tick';
}
if (!options.hasOwnProperty('cssClass')) {
options.cssClass = 'bg-success'
}
this.toast(caption, options);
}
warning(caption, options = {}) {
if (!options.hasOwnProperty('icon')) {
options.icon = 'typcn-warning';
}
if (!options.hasOwnProperty('cssClass')) {
options.cssClass = 'bg-warning'
}
this.toast(caption, options);
}
error(caption, options = {}) {
if (!options.hasOwnProperty('icon')) {
options.icon = 'typcn-cancel';
}
if (!options.hasOwnProperty('cssClass')) {
options.cssClass = 'bg-danger'
}
this.toast(caption, options);
}
}

View File

@ -15,15 +15,6 @@
{% block body %}
<div id="modal-wrapper">
<div id="modal-loading" class="black-overlay">
<div class="loading-dual-ring loading-dual-ring-center-screen"></div>
</div>
<div id="modal-wrapper">
</div>
</div>
{% include 'YtManagerApp/controls/setup_errors_banner.html' %}
<div class="row">

View File

@ -1,11 +1,3 @@
function zeroFill(number, width) {
width -= number.toString().length;
if ( width > 0 ) {
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
function syncNow() {
$.post("{% url 'ajax_action_sync_now' %}", {
csrfmiddlewaretoken: '{{ csrf_token }}'

View File

@ -44,6 +44,41 @@
<a class="nav-link" href="{% url 'register' %}">Register</a>
</li>
{% endif %}
{% else %}
{# The job panel #}
<li class="nav-item">
<div class="btn-group">
<button id="btn_toggle_job_panel"
class="btn btn-sm btn-light dropdown-toggle"
title="Show/hide job details"
data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="typcn typcn-th-list" aria-hidden="true"></span>
</button>
<div id="job_panel" class="dropdown-menu dropdown-menu-right dropdown-jobs" aria-labelledby="btn_toggle_job_panel">
<h6 id="job_panel_title" class="dropdown-header collapse">Running jobs</h6>
<h6 id="job_panel_no_jobs_title" class="dropdown-header">No jobs are currently running</h6>
<div id="job_panel_item_template" class="dropdown-item collapse">
<div class="row">
<div class="col-8">
<p id="job_panel_item_title">Title</p>
<p><small id="job_panel_item_subtitle" class="text-muted">Subtitle</small></p>
</div>
<div class="col-4">
<div class="progress">
<div id="job_panel_item_progress"
class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" style="width: 25%" aria-valuenow="25"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
{% endif %}
</ul>
@ -72,53 +107,22 @@
</div>
{% endif %}
<div id="toast-wrapper" aria-live="polite" aria-atomic="true"></div>
<div id="modal-wrapper">
<div id="modal-loading" class="black-overlay">
<div class="loading-dual-ring loading-dual-ring-center-screen"></div>
</div>
<div id="modal-wrapper">
</div>
</div>
<div id="main_body" class="container-fluid">
{% block body %}
{% endblock %}
</div>
<footer id="main_footer" class="footer bg-light row">
<button id="btn_sync_now" class="btn btn-sm btn-light" title="Synchronize now!">
<span class="typcn typcn-arrow-sync" aria-hidden="true"></span>
</button>
<span id="status-message" class="text-muted"></span>
<div id="status-progress" class="progress my-2 ml-auto invisible" style="width: 15rem">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="btn-group">
<button id="btn_toggle_job_panel"
class="btn btn-sm btn-light dropdown-toggle"
title="Show/hide job details"
data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="typcn typcn-th-list" aria-hidden="true"></span>
</button>
<div id="job_panel" class="dropdown-menu dropdown-jobs" aria-labelledby="btn_toggle_job_panel">
<h6 id="job_panel_title" class="dropdown-header collapse">Running jobs</h6>
<h6 id="job_panel_no_jobs_title" class="dropdown-header">No jobs are currently running</h6>
<div id="job_panel_item_template" class="dropdown-item collapse">
<div class="row">
<div class="col-8">
<p id="job_panel_item_title">Title</p>
<p><small id="job_panel_item_subtitle" class="text-muted">Subtitle</small></p>
</div>
<div class="col-4">
<div class="progress">
<div id="job_panel_item_progress"
class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</footer>
<script src="{% static 'YtManagerApp/import/jquery/jquery-3.3.1.min.js' %}"></script>
<script src="{% static 'YtManagerApp/import/popper/popper.min.js' %}"></script>
<script src="{% static 'YtManagerApp/import/bootstrap/js/bootstrap.min.js' %}"></script>