feat: search dashboard time range

isekai-main
Barış Soner Uşaklı 2 years ago
parent 53fbe2a7a1
commit ebb5d2d25c

@ -83,8 +83,11 @@
"back-to-dashboard": "Back to Dashboard",
"details.no-users": "No users have joined within the selected timeframe",
"details.no-topics": "No topics have been posted within the selected timeframe",
"details.no-searches": "No searches have been made yet",
"details.no-searches": "No searches have been made within the selected timeframe",
"details.no-logins": "No logins have been recorded within the selected timeframe",
"details.logins-static": "NodeBB only saves session data for %1 days, and so this table below will only show the most recently active sessions",
"details.logins-login-time": "Login Time"
"details.logins-login-time": "Login Time",
"start": "Start",
"end": "End",
"filter": "Filter"
}

@ -337,8 +337,54 @@ dashboardController.getTopics = async (req, res) => {
};
dashboardController.getSearches = async (req, res) => {
const searches = await db.getSortedSetRevRangeWithScores('searches:all', 0, 99);
let start = 0;
let end = 0;
if (req.query.start) {
start = new Date(req.query.start);
start.setHours(24, 0, 0, 0);
end = new Date();
end.setHours(24, 0, 0, 0);
}
if (req.query.end) {
end = new Date(req.query.end);
end.setHours(24, 0, 0, 0);
}
let searches;
if (start && end && start <= end) {
const daysArr = [start];
const nextDay = new Date(start.getTime());
while (nextDay < end) {
nextDay.setDate(nextDay.getDate() + 1);
nextDay.setHours(0, 0, 0, 0);
daysArr.push(new Date(nextDay.getTime()));
}
const daysData = await Promise.all(
daysArr.map(async d => db.getSortedSetRevRangeWithScores(`searches:${d.getTime()}`, 0, -1))
);
const map = {};
daysData.forEach((d) => {
d.forEach((search) => {
if (!map[search.value]) {
map[search.value] = search.score;
} else {
map[search.value] += search.score;
}
});
});
searches = Object.keys(map)
.map(key => ({ value: key, score: map[key] }))
.sort((a, b) => b.score - a.score);
} else {
searches = await db.getSortedSetRevRangeWithScores('searches:all', 0, 99);
}
res.render('admin/dashboard/searches', {
searches: searches.map(s => ({ value: validator.escape(String(s.value)), score: s.score })),
startDate: validator.escape(String(req.query.start)),
endDate: validator.escape(String(req.query.end)),
});
};

@ -2,6 +2,7 @@
'use strict';
const validator = require('validator');
const _ = require('lodash');
const db = require('../database');
const meta = require('../meta');
@ -120,7 +121,12 @@ async function recordSearch(data) {
q => !copy.find(query => query.startsWith(q) && query.length > q.length)
);
delete searches[data.uid];
await Promise.all(filtered.map(query => db.sortedSetIncrBy('searches:all', 1, query)));
const dayTimestamp = (new Date());
dayTimestamp.setHours(0, 0, 0, 0);
await Promise.all(_.uniq(filtered).map(async (query) => {
await db.sortedSetIncrBy('searches:all', 1, query);
await db.sortedSetIncrBy(`searches:${dayTimestamp.getTime()}`, 1, query);
}));
}
}, 5000);
}

@ -1,10 +1,23 @@
<div class="row dashboard">
<div class="col-xs-12">
<a class="btn btn-link" href="{config.relative_path}/admin/dashboard">
<i class="fa fa-chevron-left"></i>
[[admin/dashboard:back-to-dashboard]]
</a>
<div class="clearfix">
<a class="btn btn-link" href="{config.relative_path}/admin/dashboard">
<i class="fa fa-chevron-left"></i>
[[admin/dashboard:back-to-dashboard]]
</a>
<form class="form-inline pull-right" method="GET">
<div class="form-group">
<label>[[admin/dashboard:start]]</label>
<input type="date" class="form-control" name="start" value="{startDate}">
</div>
<div class="form-group">
<label>[[admin/dashboard:end]]</label>
<input type="date" class="form-control" name="end" value="{endDate}">
</div>
<button onclick="$('form').submit();return false;"class="btn btn-primary" type="submit">Filter</button>
</form>
</div>
<hr/>
<table class="table table-striped search-list">
<tbody>

Loading…
Cancel
Save