Rewrote page navigation

Old: Used a number in window.localStorage to keep track of what page
     was being looked at
New: Uses page history with #tab-something

Benefits: Middle click works as expected, page history works as expected
Drawbacks: Comparing two players page might require few more clicks

Might need some history manipulation later if it turns out that the
history aspect is too much (No more one-click back arrow).
This commit is contained in:
Rsl1122 2019-09-24 18:28:25 +03:00
parent 2139067ac5
commit b956b71e96
7 changed files with 107 additions and 170 deletions

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.delivery.rendering.html.structure;
import com.djrapitops.plan.delivery.rendering.html.icon.Icon;
import com.djrapitops.plugin.utilities.Format;
/**
* Html utility for creating navigation link html.
@ -48,13 +49,14 @@ public class NavLink {
}
public String toHtml() {
String tabID = new Format(tabName).justLetters().lowerCase().toString();
if (collapsed) {
return "<a class=\"collapse-item nav-button\" href=\"javascript:void(0)\">" +
return "<a class=\"collapse-item nav-button\" href=\"#tab-" + tabID + "\">" +
icon.toHtml() + ' ' +
tabName + "</a>";
}
return "<li class=\"nav-item nav-button\">" +
"<a class=\"nav-link\" href=\"javascript:void(0)\">" +
"<a class=\"nav-link\" href=\"#tab-" + tabID + "\">" +
icon.toHtml() +
"<span>" + tabName + "</span></a>" +
"</li>";

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.extension.ElementOrder;
import com.djrapitops.plan.extension.FormatType;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.extension.implementation.results.*;
import com.djrapitops.plugin.utilities.Format;
import java.util.*;
@ -87,6 +88,7 @@ public class PlayerPluginTab implements Comparable<PlayerPluginTab> {
if (playerData.isEmpty()) {
nav = NavLink.collapsed(Icon.called("cubes").build(), serverName + " (No Data)").toHtml();
tab = wrapInTab(
serverName + " (No Data)",
"<div class=\"col-md-12\"><div class=\"card\"><div class=\"card-body\"><p>No Extension Data</p></div></div></div>"
);
} else {
@ -118,14 +120,14 @@ public class PlayerPluginTab implements Comparable<PlayerPluginTab> {
tabBuilder.append(wrapInContainer(extensionInformation, tabsElement));
}
return wrapInTab(tabBuilder.toString());
return wrapInTab(serverName, tabBuilder.toString());
}
private String wrapInTab(String content) {
return "<div class=\"tab\"><div class=\"container-fluid mt-4\">" +
private String wrapInTab(String tabName, String content) {
return "<div class=\"tab\" id=\"" + new Format(tabName).justLetters().lowerCase() + "\"><div class=\"container-fluid mt-4\">" +
// Page heading
"<div class=\"d-sm-flex align-items-center justify-content-between mb-4\">" +
"<h1 class=\"h3 mb-0 text-gray-800\"><i class=\"sidebar-toggler fa fa-fw fa-bars\"></i>${playerName} &middot; " + serverName + " Plugins</h1>${backButton}" +
"<h1 class=\"h3 mb-0 text-gray-800\"><i class=\"sidebar-toggler fa fa-fw fa-bars\"></i>" + serverName + " &middot; Plugins Overview</h1>${backButton}" +
"</div>" +
// End Page heading
"<div class=\"card-columns\">" + content + "</div></div></div>";

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.extension.ElementOrder;
import com.djrapitops.plan.extension.FormatType;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.extension.implementation.results.*;
import com.djrapitops.plugin.utilities.Format;
import java.util.*;
import java.util.stream.Collectors;
@ -87,8 +88,10 @@ public class ServerPluginTabs {
private void generate() {
if (serverData.isEmpty()) {
nav = new StringBuilder(new NavLink(Icon.called("cubes").build(), "Overview (No Data)").toHtml());
String tabName = "Overview (No Data)";
nav = new StringBuilder(new NavLink(Icon.called("cubes").build(), tabName).toHtml());
tab = wrapInTab(
tabName,
"<div class=\"col-md-12\"><div class=\"card\"><div class=\"card-body\"><p>No Extension Data</p></div></div></div>"
);
} else {
@ -124,7 +127,7 @@ public class ServerPluginTabs {
).toHtmlFull();
}
tabBuilder.append(wrapInTab(extensionInformation, wrapInContainer(extensionInformation, tabsElement)));
tabBuilder.append(wrapInTab(extensionInformation.getPluginName(), wrapInContainer(extensionInformation, tabsElement)));
nav.append(new NavLink(Icon.fromExtensionIcon(extensionInformation.getIcon()), extensionInformation.getPluginName()).toHtml());
}
return tabBuilder.toString();
@ -151,11 +154,11 @@ public class ServerPluginTabs {
tabBuilder.append(wrapInContainer(extensionInformation, tabsElement));
}
return wrapInTab(tabBuilder.toString());
return wrapInTab("Overview", tabBuilder.toString());
}
private String wrapInTab(String content) {
return "<div class=\"tab\"><div class=\"container-fluid mt-4\">" +
private String wrapInTab(String tabName, String content) {
return "<div class=\"tab\" id=\"" + new Format(tabName).justLetters().lowerCase() + "\"><div class=\"container-fluid mt-4\">" +
// Page heading
"<div class=\"d-sm-flex align-items-center justify-content-between mb-4\">" +
"<h1 class=\"h3 mb-0 text-gray-800\"><i class=\"sidebar-toggler fa fa-fw fa-bars\"></i><span class=\"server-name\"></span> &middot; Plugins Overview</h1>${backButton}" +
@ -164,16 +167,6 @@ public class ServerPluginTabs {
"<div class=\"card-columns\">" + content + "</div></div></div>";
}
private String wrapInTab(ExtensionInformation info, String content) {
return "<div class=\"tab\"><div class=\"container-fluid mt-4\">" +
// Page heading
"<div class=\"d-sm-flex align-items-center justify-content-between mb-4\">" +
"<h1 class=\"h3 mb-0 text-gray-800\"><i class=\"sidebar-toggler fa fa-fw fa-bars\"></i><span class=\"server-name\"></span> &middot; " + info.getPluginName() + "</h1>${backButton}" +
"</div>" +
// End Page heading
"<div class=\"row\"><div class=\"col-xl-12 col-sm-12\">" + content + "</div></div></div></div>";
}
private TabsElement.Tab wrapToTabElementTab(ExtensionTabData tabData) {
TabInformation tabInformation = tabData.getTabInformation();
String tabContentHtml = parseContentHtml(tabData);

View File

@ -1,6 +1,72 @@
function openTab(i) {
var x = document.getElementById("content");
var navButtons = document.getElementsByClassName("nav-button");
var max = navButtons.length;
for (var j = 0; j < max; j++) {
if (navButtons[j].classList.contains('active')) {
navButtons[j].classList.remove('active');
}
if (j === i) {
navButtons[j].classList.add('active');
}
}
var percent = -100 / navButtons.length;
slideIndex = i;
if (slideIndex > max) {
slideIndex = 0
}
if (slideIndex < 0) {
slideIndex = max
}
window.scrollTo(0, 0);
var value = slideIndex * percent;
x.style.transition = "0.5s";
x.style.transform = "translate3d(" + value + "%,0px,0)";
}
function openPage() {
var params = (window.location.hash.substr(5)).split("&");
if (!params.length) {
openTab(0);
return;
}
// window.sessionStorage.setItem("server_slide_index", slideIndex);
var tabID = params[0];
var button = $('.nav-button[href="#' + tabID + '"]');
var tabs = document.getElementsByClassName("tab");
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].id === tabID) openTab(i);
}
if (params.length <= 1) {
return;
}
var graphTabID = params[1];
$('a[href="#' + graphTabID + '"]').tab('show');
}
(function ($) {
"use strict"; // Start of use strict
var x = document.getElementById("content");
// Prepare tabs for display
var navButtons = document.getElementsByClassName("nav-button");
var tabs = document.getElementsByClassName("tab");
x.style.transform = "translate3d(0px,0px,0)";
x.style.width = "" + navButtons.length * 100 + "%";
for (var i = 0; i < navButtons.length; i++) {
tabs[i].style.width = "" + 100 / navButtons.length + "%";
}
x.style.opacity = "1";
window.addEventListener('hashchange', function (e) {
openPage();
});
var oldWidth = null;
function reduceSidebar() {

View File

@ -49,7 +49,7 @@
<!-- Nav Item - Dashboard -->
<li class="nav-item nav-button active">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-network-overview">
<i class="fas fa-fw fa-info-circle"></i>
<span>Network Overview</span></a>
</li>
@ -69,10 +69,10 @@
</a>
<div aria-labelledby="headingPages" class="collapse" data-parent="#accordionSidebar" id="serverPages">
<div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-servers"><i
class="fas fa-fw fa-network-wired"></i>
Overview</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-sessions-overview"><i
class="far fa-fw fa-calendar-alt"></i>
Sessions</a>
</div>
@ -89,12 +89,12 @@
<div aria-labelledby="headingPages" class="collapse" data-parent="#accordionSidebar"
id="playerbasePages">
<div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-playerbase-overview"><i
class="fas fa-fw fa-chart-line"></i>
Overview</a>
<a class="collapse-item" href="./players"><i class="fas fa-fw fa-users"></i>
Player List</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i class="fas fa-fw fa-globe"></i>
<a class="collapse-item nav-button" href="#tab-geolocations"><i class="fas fa-fw fa-globe"></i>
Geolocations</a>
</div>
</div>
@ -307,7 +307,7 @@
</div> <!-- /.container-fluid -->
</div> <!-- End of Network Overview tab -->
<!-- Begin Servers Overview Tab -->
<div class="tab" id="servers-tab">
<div class="tab" id="servers">
<div class="container-fluid mt-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
@ -960,22 +960,9 @@
});
setLoadingText('Almost done..');
var navButtons = document.getElementsByClassName("nav-button");
var tabs = document.getElementsByClassName("tab");
var slideIndex = window.sessionStorage.getItem("network_slide_index");
if (slideIndex === null) {
slideIndex = 0;
}
var x = document.getElementById("content");
x.style.transform = "translate3d(0px,0px,0)";
x.style.width = "" + navButtons.length * 100 + "%";
for (var i = 0; i < navButtons.length; i++) {
navButtons[i].onclick = openFunc(i);
tabs[i].style.width = "" + 100 / navButtons.length + "%";
}
x.style.opacity = "1";
openFunc(slideIndex)();
openPage();
setLoadingText('Done.');
setTimeout(function () {
$('.page-loader').fadeOut();
}, 50);
@ -987,33 +974,6 @@
throw loadingError;
}
function openFunc(i) {
return function () {
var max = navButtons.length;
for (var j = 0; j < max; j++) {
if (navButtons[j].classList.contains('active')) {
navButtons[j].classList.remove('active');
}
if (j == i) {
navButtons[j].classList.add('active');
}
}
var percent = -100 / navButtons.length;
slideIndex = i;
if (slideIndex > max) {
slideIndex = 0
}
if (slideIndex < 0) {
slideIndex = max
}
window.scrollTo(0, 0);
window.sessionStorage.setItem("network_slide_index", slideIndex);
var value = slideIndex * percent;
x.style.transition = "0.5s";
x.style.transform = "translate3d(" + value + "%,0px,0)";
};
}
function setLoadingText(text) {
$('.loader-text').text(text);
}

View File

@ -48,7 +48,7 @@
<hr class="sidebar-divider my-0">
<li class="nav-item nav-button active">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-player-overview">
<i class="fas fa-fw fa-info-circle"></i>
<span>Player Overview</span></a>
</li>
@ -61,13 +61,13 @@
</div>
<li class="nav-item nav-button">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-sessions-overview">
<i class="fas fa-fw fa-calendar"></i>
<span>Sessions</span></a>
</li>
<li class="nav-item nav-button">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-pvp-pve">
<i class="fas fa-fw fa-campground"></i>
<span>PvP & PvE</span></a>
</li>
@ -80,7 +80,7 @@
</div>
<li class="nav-item nav-button">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-server-overview">
<i class="fas fa-fw fa-network-wired"></i>
<span>Servers Overview</span></a>
</li>
@ -791,21 +791,7 @@
setLoadingText('Rendering graphs..');
setLoadingText('Sorting players table..');
setLoadingText('Almost done..');
var navButtons = document.getElementsByClassName("nav-button");
var tabs = document.getElementsByClassName("tab");
var slideIndex = window.sessionStorage.getItem("player_slide_index");
if (slideIndex === null) {
slideIndex = 0;
}
var x = document.getElementById("content");
x.style.transform = "translate3d(0px,0px,0)";
x.style.width = "" + navButtons.length * 100 + "%";
for (var i = 0; i < navButtons.length; i++) {
navButtons[i].onclick = openFunc(i);
tabs[i].style.width = "" + 100 / navButtons.length + "%";
}
x.style.opacity = "1";
openFunc(slideIndex)();
openPage();
setLoadingText('Done.');
setTimeout(function () {
$('.page-loader').fadeOut();
@ -818,33 +804,6 @@
throw loadingError;
}
function openFunc(i) {
return function () {
var max = navButtons.length;
for (var j = 0; j < max; j++) {
if (navButtons[j].classList.contains('active')) {
navButtons[j].classList.remove('active');
}
if (j == i) {
navButtons[j].classList.add('active');
}
}
var percent = -100 / navButtons.length;
slideIndex = i;
if (slideIndex > max) {
slideIndex = 0
}
if (slideIndex < 0) {
slideIndex = max
}
window.scrollTo(0, 0);
window.sessionStorage.setItem("player_slide_index", slideIndex);
var value = slideIndex * percent;
x.style.transition = "0.5s";
x.style.transform = "translate3d(" + value + "%,0px,0)";
};
}
function setLoadingText(text) {
$('.loader-text').text(text);
}

View File

@ -46,7 +46,7 @@
<hr class="sidebar-divider my-0">
<li class="nav-item nav-button active">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-server-overview">
<i class="fas fa-fw fa-info-circle"></i>
<span>Server Overview</span></a>
</li>
@ -68,13 +68,13 @@
<div aria-labelledby="headingPages" class="collapse" data-parent="#accordionSidebar"
id="onlineActivityPages">
<div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-online-activity-overview"><i
class="fas fa-fw fa-chart-area"></i>
Overview</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-sessions-overview"><i
class="far fa-fw fa-calendar-alt"></i>
Sessions</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-pvp-pve"><i
class="fa fa-fw fa-campground"></i>
PvP & PvE</a>
</div>
@ -91,19 +91,19 @@
<div aria-labelledby="headingPages" class="collapse" data-parent="#accordionSidebar"
id="playerbasePages">
<div class="bg-white py-2 collapse-inner rounded">
<a class="collapse-item nav-button" href="javascript:void(0)"><i
<a class="collapse-item nav-button" href="#tab-playerbase-overview"><i
class="fas fa-fw fa-chart-line"></i>
Overview</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i class="fas fa-fw fa-users"></i>
<a class="collapse-item nav-button" href="#tab-playerlist"><i class="fas fa-fw fa-users"></i>
Player List</a>
<a class="collapse-item nav-button" href="javascript:void(0)"><i class="fas fa-fw fa-globe"></i>
<a class="collapse-item nav-button" href="#tab-geolocations"><i class="fas fa-fw fa-globe"></i>
Geolocations</a>
</div>
</div>
</li>
<li class="nav-item nav-button">
<a class="nav-link" href="javascript:void(0)">
<a class="nav-link" href="#tab-performance">
<i class="fas fa-fw fa-cogs"></i>
<span>Performance</span></a>
</li>
@ -824,7 +824,7 @@
</div> <!-- /.container-fluid -->
</div> <!-- End of Playerbase Overview tab -->
<!-- Begin Player List Tab -->
<div class="tab">
<div class="tab" id="playerlist">
<div class="container-fluid mt-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
@ -1298,8 +1298,6 @@
<script>
try {
var x = document.getElementById("content");
setLoadingText('Calculating values..');
jsonRequest("../v1/serverOverview?server=${serverName}", loadServerOverviewValues);
jsonRequest("../v1/onlineOverview?server=${serverName}", loadOnlineActivityOverviewValues);
@ -1604,7 +1602,7 @@
});
setLoadingText('Almost done..');
openPageFunc();
openPage();
jsonRequest("../v1/sessions?server=${serverName}", loadSessionAccordion);
@ -1620,50 +1618,7 @@
throw loadingError;
}
function openPageFunc() {
var navButtons = document.getElementsByClassName("nav-button");
var tabs = document.getElementsByClassName("tab");
var slideIndex = window.sessionStorage.getItem("server_slide_index");
if (slideIndex === null) {
slideIndex = 0;
}
x.style.transform = "translate3d(0px,0px,0)";
x.style.width = "" + navButtons.length * 100 + "%";
for (var i = 0; i < navButtons.length; i++) {
navButtons[i].onclick = openFunc(i);
tabs[i].style.width = "" + 100 / navButtons.length + "%";
}
x.style.opacity = "1";
openFunc(slideIndex)();
}
function openFunc(i) {
return function () {
var navButtons = document.getElementsByClassName("nav-button");
var max = navButtons.length;
for (var j = 0; j < max; j++) {
if (navButtons[j].classList.contains('active')) {
navButtons[j].classList.remove('active');
}
if (j == i) {
navButtons[j].classList.add('active');
}
}
var percent = -100 / navButtons.length;
slideIndex = i;
if (slideIndex > max) {
slideIndex = 0
}
if (slideIndex < 0) {
slideIndex = max
}
window.scrollTo(0, 0);
window.sessionStorage.setItem("server_slide_index", slideIndex);
var value = slideIndex * percent;
x.style.transition = "0.5s";
x.style.transform = "translate3d(" + value + "%,0px,0)";
};
}
function setLoadingText(text) {
$('.loader-text').text(text);