Display more informations on the dashboard

This commit is contained in:
Kerollmops 2020-07-11 11:48:27 +02:00
parent 11c7fef80a
commit d44428fa90
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4
4 changed files with 218 additions and 187 deletions

View File

@ -1,200 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/bulma.min.css">
<script type="text/javascript" src="/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="/papaparse.min.js"></script>
<title>The mega-mini-indexer</title>
<style>
em {
color: hsl(204, 86%, 25%);
font-style: inherit;
background-color: hsl(204, 86%, 88%);
}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/bulma.min.css">
<link rel="stylesheet" href="/style.css">
<script type="text/javascript" src="/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="/papaparse.min.js"></script>
<title>The milli engine</title>
</head>
<body>
#results {
max-width: 900px;
margin: 20px auto 0 auto;
padding: 0;
}
.notification {
display: flex;
justify-content: center;
}
.level-left {
margin-right: 50px;
}
.document {
padding: 20px 20px;
background-color: #f5f5f5;
border-radius: 4px;
margin-bottom: 20px;
display: flex;
}
.document ol {
flex: 0 0 75%;
max-width: 75%;
padding: 0;
margin: 0;
}
.document .image {
max-width: 25%;
flex: 0 0 25%;
padding-left: 30px;
box-sizing: border-box;
}
.document .image img {
width: 100%;
}
.field {
list-style-type: none;
display: flex;
flex-wrap: wrap;
}
.field:not(:last-child) {
margin-bottom: 7px;
}
.attribute {
flex: 0 0 35%;
max-width: 35%;
text-align: right;
padding-right: 10px;
box-sizing: border-box;
text-transform: uppercase;
color: rgba(0,0,0,.7);
}
.content {
max-width: 65%;
flex: 0 0 65%;
box-sizing: border-box;
padding-left: 10px;
color: rgba(0,0,0,.9);
}
</style>
</head>
<body>
<section class="hero is-light">
<div class="hero-body">
<div class="container">
<h1 class="title">
Welcome to the mega-mini-indexer also known as the MMI
</h1>
<h2 class="subtitle">
This dashboard will help you check the search results with ease.
</h2>
<p>Quoted query strings are available and forces the engine to search without typo tolerance or prefixes (e.g. <code>big "black" boat</code>).</p>
</div>
</div>
</section>
<section class="hero container">
<div class="notification" style="border-radius: 0 0 4px 4px;">
<nav class="level">
<!-- Left side -->
<div class="level-left">
<div class="level-item">
<div class="field has-addons has-addons-right">
<input id="search" class="input" type="text" autofocus placeholder="e.g. George Clooney">
</div>
</div>
<section class="hero is-light">
<div class="hero-body">
<div class="container">
<h1 class="title has-text-centered">
Welcome to milli
</h1>
<nav class="level">
<div class="level-item has-text-centered">
<div>
<p class="heading">Database Name</p>
<p class="title">songs-2.mmdb</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Database Size</p>
<p class="title">123 MB</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Number of Documents</p>
<p class="title">456 K</p>
</div>
</div>
</nav>
</div>
</div>
</section>
<!-- Right side -->
<nav class="level-right">
<div class="level-item has-text-centered">
<div>
<p class="heading">Documents</p>
<p id="count" class="title">20</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Time Spent</p>
<p id="time" class="title">4ms</p>
</div>
</div>
</nav>
</nav>
<section class="hero container">
<div class="notification" style="border-radius: 0 0 4px 4px;">
<nav class="level">
<!-- Left side -->
<div class="level-left">
<div class="level-item">
<div class="field has-addons has-addons-right">
<input id="search" class="input" type="text" autofocus placeholder="e.g. George Clooney">
</div>
</div>
</div>
</section>
<section>
<ol id="results" class="content">
<!-- documents matching requests -->
</ol>
</section>
</body>
<!-- Right side -->
<nav class="level-right">
<div class="level-item has-text-centered">
<div>
<p class="heading">Documents</p>
<p id="count" class="title">0</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Time Spent</p>
<p id="time" class="title">0ms</p>
</div>
</div>
</nav>
</nav>
<script>
var request = null;
</div>
</section>
$('#search').on('input', function () {
var query = $(this).val();
request = $.ajax({
type: "POST",
url: "query",
contentType: 'application/json',
data: JSON.stringify({ 'query': query }),
contentType: 'application/json',
success: function (data, textStatus, request) {
let httpResults = Papa.parse(data, { header: true, skipEmptyLines: true });
results.innerHTML = '';
<section>
<ol id="results" class="content">
<!-- documents matching requests -->
</ol>
</section>
</body>
let timeSpent = request.getResponseHeader('Time-Ms');
let numberOfDocuments = httpResults.data.length;
count.innerHTML = `${numberOfDocuments}`;
time.innerHTML = `${timeSpent}ms`;
<script type="text/javascript" src="/script.js"></script>
for (element of httpResults.data) {
const elem = document.createElement('li');
elem.classList.add("document");
const ol = document.createElement('ol');
for (const prop in element) {
const field = document.createElement('li');
field.classList.add("field");
const attribute = document.createElement('div');
attribute.classList.add("attribute");
attribute.innerHTML = prop;
const content = document.createElement('div');
content.classList.add("content");
content.innerHTML = element[prop];
field.appendChild(attribute);
field.appendChild(content);
ol.appendChild(field);
}
elem.appendChild(ol);
results.appendChild(elem)
}
},
beforeSend: function () {
if (request !== null) {
request.abort();
}
},
});
});
</script>
</html>

55
public/script.js Normal file
View File

@ -0,0 +1,55 @@
var request = null;
$('#search').on('input', function () {
var query = $(this).val();
request = $.ajax({
type: "POST",
url: "query",
contentType: 'application/json',
data: JSON.stringify({ 'query': query }),
contentType: 'application/json',
success: function (data, textStatus, request) {
let httpResults = Papa.parse(data, { header: true, skipEmptyLines: true });
results.innerHTML = '';
let timeSpent = request.getResponseHeader('Time-Ms');
let numberOfDocuments = httpResults.data.length;
count.innerHTML = `${numberOfDocuments}`;
time.innerHTML = `${timeSpent}ms`;
for (element of httpResults.data) {
const elem = document.createElement('li');
elem.classList.add("document");
const ol = document.createElement('ol');
for (const prop in element) {
const field = document.createElement('li');
field.classList.add("field");
const attribute = document.createElement('div');
attribute.classList.add("attribute");
attribute.innerHTML = prop;
const content = document.createElement('div');
content.classList.add("content");
content.innerHTML = element[prop];
field.appendChild(attribute);
field.appendChild(content);
ol.appendChild(field);
}
elem.appendChild(ol);
results.appendChild(elem)
}
},
beforeSend: function () {
if (request !== null) {
request.abort();
}
},
});
});

74
public/style.css Normal file
View File

@ -0,0 +1,74 @@
em {
color: hsl(204, 86%, 25%);
font-style: inherit;
background-color: hsl(204, 86%, 88%);
}
#results {
max-width: 900px;
margin: 20px auto 0 auto;
padding: 0;
}
.notification {
display: flex;
justify-content: center;
}
.level-left {
margin-right: 50px;
}
.document {
padding: 20px 20px;
background-color: #f5f5f5;
border-radius: 4px;
margin-bottom: 20px;
display: flex;
}
.document ol {
flex: 0 0 75%;
max-width: 75%;
padding: 0;
margin: 0;
}
.document .image {
max-width: 25%;
flex: 0 0 25%;
padding-left: 30px;
box-sizing: border-box;
}
.document .image img {
width: 100%;
}
.field {
list-style-type: none;
display: flex;
flex-wrap: wrap;
}
.field:not(:last-child) {
margin-bottom: 7px;
}
.attribute {
flex: 0 0 35%;
max-width: 35%;
text-align: right;
padding-right: 10px;
box-sizing: border-box;
text-transform: uppercase;
color: rgba(0,0,0,.7);
}
.content {
max-width: 65%;
flex: 0 0 65%;
box-sizing: border-box;
padding-left: 10px;
color: rgba(0,0,0,.9);
}

View File

@ -58,6 +58,13 @@ async fn main() -> anyhow::Result<()> {
.body(include_str!("../../public/bulma.min.css"))
);
let dash_style_route = warp::filters::method::get()
.and(warp::path!("style.css"))
.map(|| Response::builder()
.header("content-type", "text/css; charset=utf-8")
.body(include_str!("../../public/style.css"))
);
let dash_jquery_route = warp::filters::method::get()
.and(warp::path!("jquery-3.4.1.min.js"))
.map(|| Response::builder()
@ -72,6 +79,13 @@ async fn main() -> anyhow::Result<()> {
.body(include_str!("../../public/papaparse.min.js"))
);
let dash_script_route = warp::filters::method::get()
.and(warp::path!("script.js"))
.map(|| Response::builder()
.header("content-type", "application/javascript; charset=utf-8")
.body(include_str!("../../public/script.js"))
);
#[derive(Deserialize)]
struct QueryBody {
query: String,
@ -107,8 +121,10 @@ async fn main() -> anyhow::Result<()> {
let routes = dash_html_route
.or(dash_bulma_route)
.or(dash_style_route)
.or(dash_jquery_route)
.or(dash_papaparse_route)
.or(dash_script_route)
.or(query_route);
let addr = SocketAddr::from_str(&opt.http_listen_addr).unwrap();