mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-05 15:02:26 +01:00
Added a /query page
What currently works: - Adding filters dynamically
This commit is contained in:
parent
8f5db846af
commit
6ff2d68b99
@ -222,4 +222,11 @@ public class PageFactory {
|
||||
public Page registerPage() throws IOException {
|
||||
return new LoginPage(getResource("register.html"), serverInfo.get());
|
||||
}
|
||||
|
||||
public Page queryPage() throws IOException {
|
||||
return new QueryPage(
|
||||
getResource("query.html"),
|
||||
locale.get(), theme.get(), versionChecker.get()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.rendering.pages;
|
||||
|
||||
import com.djrapitops.plan.delivery.formatting.PlaceholderReplacer;
|
||||
import com.djrapitops.plan.delivery.rendering.html.Contributors;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.theme.Theme;
|
||||
import com.djrapitops.plan.utilities.java.UnaryChain;
|
||||
import com.djrapitops.plan.version.VersionChecker;
|
||||
|
||||
/**
|
||||
* Page to display error stacktrace.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class QueryPage implements Page {
|
||||
|
||||
private final String template;
|
||||
|
||||
private final Locale locale;
|
||||
private final Theme theme;
|
||||
private final VersionChecker versionChecker;
|
||||
|
||||
public QueryPage(
|
||||
String template,
|
||||
Locale locale, Theme theme, VersionChecker versionChecker
|
||||
) {
|
||||
this.template = template;
|
||||
this.locale = locale;
|
||||
this.theme = theme;
|
||||
this.versionChecker = versionChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHtml() {
|
||||
PlaceholderReplacer placeholders = new PlaceholderReplacer();
|
||||
placeholders.put("version", versionChecker.getUpdateButton().orElse(versionChecker.getCurrentVersionButton()));
|
||||
placeholders.put("updateModal", versionChecker.getUpdateModal());
|
||||
placeholders.put("contributors", Contributors.generateContributorHtml());
|
||||
return UnaryChain.of(template)
|
||||
.chain(theme::replaceThemeColors)
|
||||
.chain(placeholders::apply)
|
||||
.chain(locale::replaceLanguageInHtml)
|
||||
.apply();
|
||||
}
|
||||
}
|
@ -423,4 +423,12 @@ public class ResponseFactory {
|
||||
return forInternalError(e, "Failed to generate player page");
|
||||
}
|
||||
}
|
||||
|
||||
public Response queryPageResponse() {
|
||||
try {
|
||||
return forPage(pageFactory.queryPage());
|
||||
} catch (IOException e) {
|
||||
return forInternalError(e, "Failed to generate query page");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ import java.util.regex.Pattern;
|
||||
public class ResponseResolver {
|
||||
|
||||
private final DebugPageResolver debugPageResolver;
|
||||
private QueryPageResolver queryPageResolver;
|
||||
private final PlayersPageResolver playersPageResolver;
|
||||
private final PlayerPageResolver playerPageResolver;
|
||||
private final ServerPageResolver serverPageResolver;
|
||||
@ -78,6 +79,7 @@ public class ResponseResolver {
|
||||
Lazy<WebServer> webServer,
|
||||
|
||||
DebugPageResolver debugPageResolver,
|
||||
QueryPageResolver queryPageResolver,
|
||||
PlayersPageResolver playersPageResolver,
|
||||
PlayerPageResolver playerPageResolver,
|
||||
ServerPageResolver serverPageResolver,
|
||||
@ -97,6 +99,7 @@ public class ResponseResolver {
|
||||
this.responseFactory = responseFactory;
|
||||
this.webServer = webServer;
|
||||
this.debugPageResolver = debugPageResolver;
|
||||
this.queryPageResolver = queryPageResolver;
|
||||
this.playersPageResolver = playersPageResolver;
|
||||
this.playerPageResolver = playerPageResolver;
|
||||
this.serverPageResolver = serverPageResolver;
|
||||
@ -115,6 +118,7 @@ public class ResponseResolver {
|
||||
String plugin = "Plan";
|
||||
resolverService.registerResolver(plugin, "/robots.txt", (NoAuthResolver) request -> Optional.of(responseFactory.robotsResponse()));
|
||||
resolverService.registerResolver(plugin, "/debug", debugPageResolver);
|
||||
resolverService.registerResolver(plugin, "/query", queryPageResolver);
|
||||
resolverService.registerResolver(plugin, "/players", playersPageResolver);
|
||||
resolverService.registerResolver(plugin, "/player", playerPageResolver);
|
||||
resolverService.registerResolver(plugin, "/favicon.ico", (NoAuthResolver) request -> Optional.of(responseFactory.faviconResponse()));
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.webserver.resolver;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resolver.Resolver;
|
||||
import com.djrapitops.plan.delivery.web.resolver.Response;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||
import com.djrapitops.plan.delivery.webserver.ResponseFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Optional;
|
||||
|
||||
public class QueryPageResolver implements Resolver {
|
||||
|
||||
private final ResponseFactory responseFactory;
|
||||
|
||||
@Inject
|
||||
public QueryPageResolver(
|
||||
ResponseFactory responseFactory
|
||||
) {
|
||||
this.responseFactory = responseFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccess(Request request) {
|
||||
return request.getUser().map(user -> user.hasPermission("page.players")).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Response> resolve(Request request) {
|
||||
return Optional.of(responseFactory.queryPageResponse());
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.storage.database.queries.filter.filters;
|
||||
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.FilterQuery;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -42,12 +43,15 @@ public class PluginGroupsFilter extends MultiOptionFilter {
|
||||
|
||||
@Override
|
||||
public String getKind() {
|
||||
return null;
|
||||
return "pluginGroups";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getOptions() {
|
||||
return null;
|
||||
return Maps.builder(String.class, Object.class)
|
||||
.put("plugin", pluginName)
|
||||
.put("options", groups)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
73
Plan/common/src/main/resources/assets/plan/web/js/query.js
Normal file
73
Plan/common/src/main/resources/assets/plan/web/js/query.js
Normal file
@ -0,0 +1,73 @@
|
||||
var filterCount = 0;
|
||||
|
||||
function addFilter(parentSelector, filterIndex) {
|
||||
$(parentSelector).append(createElement(filters[filterIndex]));
|
||||
filterCount++;
|
||||
}
|
||||
|
||||
function createElement(filter) {
|
||||
switch (filter.kind) {
|
||||
case "activityIndexNow":
|
||||
return createMultipleChoiceSelector(`are in Activity Groups`, filter.options);
|
||||
case "banned":
|
||||
return createMultipleChoiceSelector(`are`, filter.options);
|
||||
case "operators":
|
||||
return createMultipleChoiceSelector(`are`, filter.options);
|
||||
case "pluginGroups":
|
||||
return createMultipleChoiceSelector(`are in ${filter.options.plugin} Groups`, filter.options);
|
||||
case "playedBetween":
|
||||
return createBetweenSelector("Played between", filter.options);
|
||||
case "registeredBetween":
|
||||
return createBetweenSelector("Registered between", filter.options);
|
||||
default:
|
||||
throw new Error("Unsupported filter kind: '" + filter.kind + "'")
|
||||
}
|
||||
}
|
||||
|
||||
function createFilterSelector(parent, index, filter) {
|
||||
return `<a class="dropdown-item" href="#" onclick="addFilter('${parent}', ${index})">${filter.kind}</a>`;
|
||||
}
|
||||
|
||||
function createBetweenSelector(label, options) {
|
||||
var select = filterCount === 0 ? "of Players who " : "and ";
|
||||
return `<label class="ml-2 mt-0 mb-0">${select}${label}:</label>` +
|
||||
`<div class="mt-2 input-group input-row">` +
|
||||
|
||||
`<div class="col-3"><div class="input-group mb-2">` +
|
||||
`<div class="input-group-prepend"><div class="input-group-text"><i class="far fa-calendar"></i></div></div>` +
|
||||
`<input class="form-control" placeholder="${options.after[0]}" type="text">` +
|
||||
`</div></div>` +
|
||||
|
||||
`<div class="col-2"><div class="input-group mb-2">` +
|
||||
`<div class="input-group-prepend"><div class="input-group-text"><i class="far fa-clock"></i></div></div>` +
|
||||
`<input class="form-control" placeholder="${options.after[1]}" type="text">` +
|
||||
`</div></div>` +
|
||||
|
||||
`<div class="col-auto"><label class="mt-2 mb-0" for="inlineFormCustomSelectPref">&</label></div>` +
|
||||
|
||||
`<div class="col-3"><div class="input-group mb-2">` +
|
||||
`<div class="input-group-prepend"><div class="input-group-text"><i class="far fa-calendar"></i></div></div>` +
|
||||
`<input class="form-control" placeholder="${options.before[0]}" type="text">` +
|
||||
`</div></div>` +
|
||||
|
||||
`<div class="col-2"><div class="input-group mb-2">` +
|
||||
`<div class="input-group-prepend"><div class="input-group-text"><i class="far fa-clock"></i></div></div>` +
|
||||
`<input class="form-control" placeholder="${options.before[1]}" type="text">` +
|
||||
`</div></div>` +
|
||||
`</div>`;
|
||||
}
|
||||
|
||||
function createMultipleChoiceSelector(label, options) {
|
||||
var select = filterCount === 0 ? "of Players who " : "and ";
|
||||
var html = `<div class="mt-2 input-group input-row">` +
|
||||
`<div class="col-12">
|
||||
<label for="exampleFormControlSelect2">${select}${label}:</label>` +
|
||||
`<select class="form-control" multiple>`;
|
||||
|
||||
for (var option of options.options) {
|
||||
html += `<option>${option}</option>`
|
||||
}
|
||||
|
||||
html += `</select></div> </div>`;
|
||||
return html;
|
||||
}
|
337
Plan/common/src/main/resources/assets/plan/web/query.html
Normal file
337
Plan/common/src/main/resources/assets/plan/web/query.html
Normal file
@ -0,0 +1,337 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport">
|
||||
<meta content="Player Analytics, generic error/debug page" name="description">
|
||||
<meta content="Rsl1122" name="author">
|
||||
|
||||
<title>Plan | Query</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet">
|
||||
<link crossorigin="anonymous" href="https://fonts.googleapis.com/css?family=Nunito:300,400,600,700,800,900"
|
||||
rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-plan sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center">
|
||||
<img class="w-22" src="img/Flaticon_circle.png">
|
||||
</a>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider my-0">
|
||||
|
||||
<li class="nav-item nav-button active">
|
||||
<a class="nav-link" href="/">
|
||||
<i class="far fa-fw fa-hand-point-left"></i>
|
||||
<span>to main page</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider">
|
||||
|
||||
<div class="ml-3 align-items-center justify-content-between">
|
||||
<button class="btn bg-plan" data-target="#colorChooserModal" data-toggle="modal" type="button">
|
||||
<i class="fa fa-palette"></i>
|
||||
</button>
|
||||
<button class="btn bg-plan" data-target="#informationModal" data-toggle="modal" type="button">
|
||||
<i class="fa fa-fw fa-question-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="ml-3 align-items-center justify-content-between">
|
||||
${version}
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div class="d-flex flex-column" id="content-wrapper">
|
||||
<div class="sidebar-close-modal hidden"></div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content" style="display: flex;">
|
||||
<!-- Begin Player Overview Tab -->
|
||||
<div class="tab" style="width: 100%;">
|
||||
<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>Plan ·
|
||||
Query</h1>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Card -->
|
||||
<div class="col-xs-12 col-sm-12 col-lg-11">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-body" id="data_player_info">
|
||||
<label class="mt-2 mb-0" for="inlineFormCustomSelectPref">Show a view</label>
|
||||
<div class="mt-2 input-group input-row">
|
||||
<div class="col-auto">
|
||||
<label class="mt-2 mb-0" for="inlineFormCustomSelectPref">from</label>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<label class="sr-only" for="inlineFormInputGroup">Date: DD/MM/YYYY</label>
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text"><i class="far fa-calendar"></i></div>
|
||||
</div>
|
||||
<input class="form-control" id="inlineFormInputGroup"
|
||||
placeholder="31/12/2016" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<label class="sr-only" for="inlineFormInputGroup">Time: H H : M M</label>
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text"><i class="far fa-clock"></i></div>
|
||||
</div>
|
||||
<input class="form-control" id="inlineFormInputGroup"
|
||||
placeholder="23:59" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="mt-2 mb-0" for="inlineFormCustomSelectPref">to</label>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text"><i class="far fa-calendar"></i></div>
|
||||
</div>
|
||||
<input class="form-control" id="inlineFormInputGroup"
|
||||
placeholder="23/03/2020" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text"><i class="far fa-clock"></i></div>
|
||||
</div>
|
||||
<input class="form-control" id="inlineFormInputGroup"
|
||||
placeholder="21:26" type="text">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div id="filters"></div>
|
||||
|
||||
<div class="mt-2 dropdown" id="addFilter">
|
||||
<button aria-expanded="false" aria-haspopup="true" class="btn dropdown-toggle"
|
||||
data-toggle="dropdown" id="filterDropdown" type="button">
|
||||
<i class="fa fa-plus"></i> Add a filter..
|
||||
</button>
|
||||
<div aria-labelledby="filterDropdown" class="dropdown-menu">
|
||||
<a class="dropdown-item" id="dropdown-loading">Loading filters..</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="mt-2 mb-2 btn col-plan"><i class="fa fa-search"></i> Perform Query!
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- /.container-fluid -->
|
||||
</div> <!-- End of tab -->
|
||||
</div> <!-- End of Main Content -->
|
||||
</div><!-- End of Content Wrapper -->
|
||||
|
||||
<!-- Color Chooser Modal -->
|
||||
<div aria-hidden="true" aria-labelledby="colorChooserModalLabel" class="modal fade" id="colorChooserModal"
|
||||
role="dialog" tabindex="-1">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="colorChooserModalLabel"><i class="fa fa-palette"></i> Theme Select
|
||||
</h5>
|
||||
<button aria-label="Close" class="close" data-dismiss="modal" type="button">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<button class="btn color-chooser" id="choose-plan" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-red" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-pink" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-purple" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-deep-purple" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-indigo" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-blue" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-light-blue" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-cyan" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-teal" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-green" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-light-green" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-lime" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-yellow" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-amber" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-orange" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-deep-orange" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-brown" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-grey" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
<button class="btn color-chooser" id="choose-blue-grey" type="button"><i
|
||||
class="fa fa-palette"></i></button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" id="night-mode-toggle" type="button"><i class="fa fa-fw fa-cloud-moon"></i>
|
||||
Night
|
||||
Mode
|
||||
</button>
|
||||
<button class="btn bg-plan" data-dismiss="modal" type="button">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Information Modal -->
|
||||
<div aria-hidden="true" aria-labelledby="informationModalLabel" class="modal fade" id="informationModal"
|
||||
role="dialog" tabindex="-1">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="informationModalLabel"><i class="fa fa-fw fa-question-circle"></i>
|
||||
Information about the plugin
|
||||
</h5>
|
||||
<button aria-label="Close" class="close" data-dismiss="modal" type="button">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Player Analytics is developed and licensed under <a
|
||||
href="https://opensource.org/licenses/LGPL-3.0" rel="noopener noreferrer"
|
||||
target="_blank">Lesser General Public License
|
||||
v3.0</a></p>
|
||||
<hr>
|
||||
<a class="btn col-plan" href="https://github.com/Rsl1122/Plan-PlayerAnalytics/wiki"
|
||||
rel="noopener noreferrer" target="_blank"><i class="fa fa-fw fa-graduation-cap"></i> Plan
|
||||
Wiki,
|
||||
Tutorials & Documentation</a>
|
||||
<a class="btn col-plan" href="https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"
|
||||
rel="noopener noreferrer" target="_blank"><i class="fa fa-fw fa-bug"></i> Report Issues</a>
|
||||
<a class="btn col-plan" href="https://discord.gg/yXKmjzT" rel="noopener noreferrer"
|
||||
target="_blank"><i class="fab fa-fw fa-discord"></i> General Support on Discord</a>
|
||||
<hr>
|
||||
<p>Player Analytics is developed by Rsl1122.</p>
|
||||
<p>In addition following <span class="col-plan">awesome people</span> have contributed:</p>
|
||||
<ul>
|
||||
${contributors}
|
||||
<li>& Bug reporters!</li>
|
||||
</ul>
|
||||
<small><i class="fa fa-fw fa-code"></i> code contributor <i class="fa fa-fw fa-language"></i>
|
||||
translator
|
||||
</small>
|
||||
<hr>
|
||||
<p class="col-plan">Extra special thanks to those who have monetarily supported the development.
|
||||
<i class="fa fa-fw fa-star col-amber"></i></p>
|
||||
<hr>
|
||||
<h6>bStats Metrics</h6>
|
||||
<a class="btn col-plan" href="https://bstats.org/plugin/bukkit/Plan" rel="noopener noreferrer"
|
||||
target="_blank"><i class="fa fa-fw fa-chart-area"></i> Bukkit</a>
|
||||
<a class="btn col-plan" href="https://bstats.org/plugin/bungeecord/Plan"
|
||||
rel="noopener noreferrer" target="_blank"><i class="fa fa-fw fa-chart-area"></i>
|
||||
BungeeCord</a>
|
||||
<a class="btn col-plan" href="https://bstats.org/plugin/sponge/plan" rel="noopener noreferrer"
|
||||
target="_blank"><i class="fa fa-fw fa-chart-area"></i> Sponge</a>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn bg-plan" data-dismiss="modal" type="button">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Update Modal -->
|
||||
<div aria-hidden="true" aria-labelledby="updateModalLabel" class="modal fade" id="updateModal" role="dialog"
|
||||
tabindex="-1">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
${updateModal}
|
||||
<div class="modal-footer">
|
||||
<button class="btn bg-plan" data-dismiss="modal" type="button">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-fw fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="./vendor/jquery/jquery.min.js"></script>
|
||||
<script src="./vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="./vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<script src="./vendor/datatables/jquery.dataTables.min.js"></script>
|
||||
<script src="./vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||
<script src='./vendor/momentjs/moment.js'></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="./js/sb-admin-2.js"></script>
|
||||
<script src="./js/xmlhttprequests.js"></script>
|
||||
<script src="./js/color-selector.js"></script>
|
||||
|
||||
<!-- Page level custom scripts -->
|
||||
<script src='./js/query.js'></script>
|
||||
|
||||
<script id="mainScript">
|
||||
var filters = [];
|
||||
jsonRequest("./v1/filters", function (json, error) {
|
||||
var dropdown = $('#addFilter .dropdown-menu');
|
||||
|
||||
filters.push(...json.filters);
|
||||
console.log(filters);
|
||||
|
||||
var filterElements = [];
|
||||
for (var i = 0; i < filters.length; i++) {
|
||||
filterElements.push(createFilterSelector('#filters', i, filters[i]));
|
||||
}
|
||||
$('#dropdown-loading').replaceWith(filterElements);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user