mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
Merge pull request #158 from cloudflare/history
Save filters usage history to local storage and provide a dropdown me…
This commit is contained in:
21
assets/static/__mocks__/localStorageMock.js
Normal file
21
assets/static/__mocks__/localStorageMock.js
Normal file
@@ -0,0 +1,21 @@
|
||||
class LocalStorageMock {
|
||||
|
||||
constructor() {
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
getItem(key) {
|
||||
return this.store[key] || null;
|
||||
}
|
||||
|
||||
setItem(key, value) {
|
||||
this.store[key] = value.toString();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = new LocalStorageMock();
|
||||
@@ -9,6 +9,7 @@ function loadTemplates() {
|
||||
"modal.html",
|
||||
"silence.html",
|
||||
"summary.html",
|
||||
"history.html",
|
||||
];
|
||||
templateFiles.forEach(function(filename){
|
||||
var templatePath = path.join(__dirname, "../../templates/", filename);
|
||||
|
||||
390
assets/static/__snapshots__/filters.test.js.snap
Normal file
390
assets/static/__snapshots__/filters.test.js.snap
Normal file
@@ -0,0 +1,390 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`appended filtes should be present in history 1`] = `
|
||||
"<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`appended filtes should be present in history 2`] = `
|
||||
"<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`appended filtes should be present in history 3`] = `
|
||||
"<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`appended filtes should be present in history 4`] = `
|
||||
"<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar,@state=active
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
@state=active
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`appended filtes should be present in history 5`] = `
|
||||
"<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar,@state=active
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
@state=active
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`appended filtes should be present in history 6`] = `
|
||||
"<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
@state=active
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
@state=active
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar,@state=active
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
@state=active
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default,bar
|
||||
</span>
|
||||
<i class=\\"fa fa-search\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
bar
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
|
||||
exports[`default filter should be in history after setting filter to foo 1`] = `
|
||||
"<li role=\\"separator\\" class=\\"divider\\"></li>
|
||||
|
||||
|
||||
<li class=\\"history-menu\\">
|
||||
<a class=\\"cursor-pointer history-menu-item\\">
|
||||
<span class=\\"rawFilter hidden\\">
|
||||
default
|
||||
</span>
|
||||
<i class=\\"fa fa-home\\"></i>
|
||||
|
||||
<span class=\\"label-list label label-info\\">
|
||||
default
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>"
|
||||
`;
|
||||
@@ -141,7 +141,7 @@ span.label-ts-span {
|
||||
|
||||
/* make filter input take all the space it can */
|
||||
div.filterbar {
|
||||
width: 950px;
|
||||
width: 905px;
|
||||
}
|
||||
div.filterbar > .input-group-addon.input-sm {
|
||||
width: 10px;
|
||||
@@ -186,12 +186,14 @@ div.bootstrap-tagsinput > .twitter-typeahead > input.tt-input {
|
||||
|
||||
/* menus uses links with icons instead of buttons, fix focus color
|
||||
so the link doesn't stay colored after clicking */
|
||||
#history:focus,
|
||||
#help:focus,
|
||||
#settings:focus,
|
||||
#refresh:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#history:hover,
|
||||
#help:hover,
|
||||
#settings:hover,
|
||||
#refresh:hover {
|
||||
@@ -498,3 +500,10 @@ a[aria-expanded=false] .fa-chevron-down {
|
||||
.alert-static-elements {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
li.history-menu > a.history-menu-item {
|
||||
padding-left: 10px;
|
||||
padding-right: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
@@ -13,11 +13,16 @@ require("./bootstrap-tagsinput.less");
|
||||
const autocomplete = require("./autocomplete");
|
||||
const unsee = require("./unsee");
|
||||
const querystring = require("./querystring");
|
||||
const templates = require("./templates");
|
||||
|
||||
var selectors = {
|
||||
filter: "#filter",
|
||||
icon: "#filter-icon"
|
||||
icon: "#filter-icon",
|
||||
historyMenu: "#historyMenu"
|
||||
};
|
||||
var appendsEnabled = true;
|
||||
var historyStorage;
|
||||
const historyKey = "filterHistory";
|
||||
|
||||
function addBadge(text) {
|
||||
$.each($("span.tag"), function(i, tag) {
|
||||
@@ -51,6 +56,27 @@ function addFilter(text) {
|
||||
$(selectors.filter).tagsinput("add", text);
|
||||
}
|
||||
|
||||
function applyFilterList(filterList) {
|
||||
// we need to add filters one by one, this would reload alerts on every
|
||||
// add() so let's pause reloads and resume once we're done with updating
|
||||
// filters
|
||||
unsee.pause();
|
||||
// disable history appends as it would record each new filter in the
|
||||
// history
|
||||
appendsEnabled = false;
|
||||
$(selectors.filter).tagsinput("removeAll");
|
||||
for (var i = 0; i < filterList.length; i++) {
|
||||
$(selectors.filter).tagsinput("add", filterList[i]);
|
||||
}
|
||||
// enable everything again
|
||||
appendsEnabled = true;
|
||||
unsee.resume();
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
$(selectors.filter).tagsinput("removeAll");
|
||||
}
|
||||
|
||||
function setUpdating() {
|
||||
// visual hint that alerts are reloaded due to filter change
|
||||
$(selectors.icon).removeClass("fa-search fa-pause").addClass("fa-circle-o-notch fa-spin");
|
||||
@@ -64,17 +90,64 @@ function setPause() {
|
||||
$(selectors.icon).removeClass("fa-circle-o-notch fa-spin fa-search").addClass("fa-pause");
|
||||
}
|
||||
|
||||
function renderHistory() {
|
||||
var historicFilters = [];
|
||||
|
||||
const currentFilterText = getFilters().join(",");
|
||||
|
||||
const history = historyStorage.getItem(historyKey);
|
||||
if (history) {
|
||||
historicFilters = history.split("\n");
|
||||
}
|
||||
|
||||
var historyMenuHTML = templates.renderTemplate("historyMenu", {
|
||||
activeFilter: currentFilterText,
|
||||
defaultFilter: $(selectors.filter).data("default-filter"),
|
||||
savedFilter: Cookies.get("defaultFilter.v2"),
|
||||
filters: historicFilters
|
||||
});
|
||||
$(selectors.historyMenu).html(historyMenuHTML);
|
||||
}
|
||||
|
||||
function appendFilterToHistory(text) {
|
||||
// require non empty text and enabled appends
|
||||
if (!text || !appendsEnabled) return false;
|
||||
|
||||
// final filter list we'll save to storage
|
||||
var filterList = new Set([ text ]);
|
||||
|
||||
// get current history list from storage and append it to our final list
|
||||
// of filters, but avoid duplicates
|
||||
const history = historyStorage.getItem(historyKey);
|
||||
if (history) {
|
||||
const historyArr = history.split("\n");
|
||||
for (var i = 0; i < historyArr.length; i++) {
|
||||
filterList.add(historyArr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// truncate the history to up to 11 elements
|
||||
const filterListTrunc = Array.from(filterList).slice(0, 10);
|
||||
|
||||
historyStorage.setItem(historyKey, filterListTrunc.join("\n"));
|
||||
}
|
||||
|
||||
function setFilters() {
|
||||
setUpdating();
|
||||
|
||||
// update location so it's easy to share it
|
||||
querystring.update("q", getFilters().join(","));
|
||||
|
||||
// append filter to the history and render it
|
||||
appendFilterToHistory(getFilters().join(","));
|
||||
renderHistory();
|
||||
|
||||
// reload alerts
|
||||
unsee.triggerReload();
|
||||
}
|
||||
|
||||
function init() {
|
||||
function init(historyStore) {
|
||||
historyStorage = historyStore;
|
||||
var initialFilter;
|
||||
|
||||
if ($(selectors.filter).data("default-used") == "false" || $(selectors.filter).data("default-used") === false) {
|
||||
@@ -141,10 +214,18 @@ function init() {
|
||||
$("body").css("padding-top", $(".navbar").height());
|
||||
});
|
||||
|
||||
renderHistory();
|
||||
$(selectors.historyMenu).on("click", "a.history-menu-item", function(event) {
|
||||
var elem = $(event.target).parents("li.history-menu");
|
||||
const filtersList = elem.find(".rawFilter").text().trim().split(",");
|
||||
applyFilterList(filtersList);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
exports.init = init;
|
||||
exports.addFilter = addFilter;
|
||||
exports.clearFilters = clearFilters;
|
||||
exports.setFilters = setFilters;
|
||||
exports.getFilters = getFilters;
|
||||
exports.addBadge = addBadge;
|
||||
@@ -152,3 +233,4 @@ exports.reloadBadges = reloadBadges;
|
||||
exports.updateDone = updateDone;
|
||||
exports.setUpdating = setUpdating;
|
||||
exports.setPause = setPause;
|
||||
exports.renderHistory = renderHistory;
|
||||
|
||||
@@ -1,7 +1,133 @@
|
||||
const $ = window.jQuery = require("jquery");
|
||||
const LocalStorageMock = require("./__mocks__/localStorageMock");
|
||||
|
||||
test("filters addBadge()", () => {
|
||||
// mock data attr with default filter
|
||||
//document.body.innerHTML = "<div id='filter' data-default-filter='foo=bar'></div>";
|
||||
window.jQuery = require("jquery");
|
||||
const filters = require("./filters");
|
||||
filters.addBadge("foo=bar");
|
||||
});
|
||||
|
||||
test("default filter should be in history after setting filter to foo", () => {
|
||||
LocalStorageMock.clear();
|
||||
document.body.innerHTML =
|
||||
"<div class='input-group filterbar'>" +
|
||||
" <div class='input-group-addon input-sm'>" +
|
||||
" <i class='fa fa-search' id='filter-icon'></i>" +
|
||||
" </div>" +
|
||||
" <input id='filter' type='text' value='foo' data-default-used='false' data-default-filter='default'>" +
|
||||
"</div>" +
|
||||
"<div id='historyMenu'></div>";
|
||||
|
||||
const templatesMock = require("./__mocks__/templatesMock");
|
||||
document.body.innerHTML += templatesMock.loadTemplates();
|
||||
const templates = require("./templates");
|
||||
templates.init();
|
||||
|
||||
const autocomplete = require("./autocomplete");
|
||||
const filters = require("./filters");
|
||||
|
||||
autocomplete.init();
|
||||
filters.init(LocalStorageMock);
|
||||
filters.setFilters();
|
||||
filters.renderHistory();
|
||||
|
||||
// use snapshot to check that generated HTML is what we expect
|
||||
const historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
|
||||
// we set foo, so that what should be in history
|
||||
expect(LocalStorageMock.getItem("filterHistory")).toBe("foo");
|
||||
});
|
||||
|
||||
test("appended filtes should be present in history", () => {
|
||||
LocalStorageMock.clear();
|
||||
document.body.innerHTML =
|
||||
"<div class='input-group filterbar'>" +
|
||||
" <div class='input-group-addon input-sm'>" +
|
||||
" <i class='fa fa-search' id='filter-icon'></i>" +
|
||||
" </div>" +
|
||||
" <input id='filter' type='text' value='default' data-default-used='true' data-default-filter='default'>" +
|
||||
"</div>" +
|
||||
"<div id='historyMenu'></div>";
|
||||
|
||||
const templatesMock = require("./__mocks__/templatesMock");
|
||||
document.body.innerHTML += templatesMock.loadTemplates();
|
||||
const templates = require("./templates");
|
||||
templates.init();
|
||||
|
||||
const autocomplete = require("./autocomplete");
|
||||
const filters = require("./filters");
|
||||
|
||||
autocomplete.init();
|
||||
filters.init(LocalStorageMock);
|
||||
filters.setFilters();
|
||||
filters.renderHistory();
|
||||
|
||||
// we only used default, so there should be a single (default) entry
|
||||
let historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
// and that's what history should have
|
||||
expect(LocalStorageMock.getItem("filterHistory")).toBe("default");
|
||||
|
||||
// now we append more filters, so q=default becomes q=default,bar
|
||||
filters.addFilter("bar");
|
||||
filters.setFilters();
|
||||
// now we got non-default filter as active, so we should have 2 entries
|
||||
// both for default (as recent and as global default)
|
||||
historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
expect(
|
||||
LocalStorageMock.getItem("filterHistory").split("\n")
|
||||
).toMatchObject(
|
||||
[ "default,bar", "default" ]
|
||||
);
|
||||
|
||||
// append another filter, so we now have: q=default,bar,@state=active
|
||||
filters.addFilter("@state=active");
|
||||
filters.setFilters();
|
||||
// now we should have 3 entries, 2x default + default,bar
|
||||
historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
expect(
|
||||
LocalStorageMock.getItem("filterHistory").split("\n")
|
||||
).toMatchObject(
|
||||
[ "default,bar,@state=active", "default,bar", "default" ]
|
||||
);
|
||||
|
||||
// clear filters, so now we have: q=
|
||||
filters.clearFilters();
|
||||
filters.setFilters();
|
||||
// now we should have 4 entries, 2x default + default,bar + default,bar,@state=active
|
||||
historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
expect(
|
||||
LocalStorageMock.getItem("filterHistory").split("\n")
|
||||
).toMatchObject(
|
||||
[ "default,bar,@state=active", "default,bar", "default" ]
|
||||
);
|
||||
|
||||
// now add a filter back, so now we have: q=@state=active
|
||||
filters.addFilter("@state=active");
|
||||
filters.setFilters();
|
||||
// we should have same filters as before
|
||||
historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
expect(
|
||||
LocalStorageMock.getItem("filterHistory").split("\n")
|
||||
).toMatchObject(
|
||||
[ "@state=active", "default,bar,@state=active", "default,bar", "default" ]
|
||||
);
|
||||
|
||||
// as a last test add default back to have @state=active rendered
|
||||
filters.clearFilters();
|
||||
filters.addFilter("default");
|
||||
filters.setFilters();
|
||||
// we should have same filters as before
|
||||
historyMenu = $("#historyMenu").html().trim();
|
||||
expect(historyMenu).toMatchSnapshot();
|
||||
// default should move from the bottom to to top of the list
|
||||
expect(
|
||||
LocalStorageMock.getItem("filterHistory").split("\n")
|
||||
).toMatchObject(
|
||||
[ "default", "@state=active", "default,bar,@state=active", "default,bar" ]
|
||||
);
|
||||
});
|
||||
|
||||
@@ -45,7 +45,11 @@ var templates = {},
|
||||
alertGroupLabels: "#alert-group-labels",
|
||||
alertGroupElements: "#alert-group-elements",
|
||||
alertGroupSilence: "#alert-group-silence",
|
||||
alertGroupLabelMap: "#alert-group-label-map"
|
||||
alertGroupLabelMap: "#alert-group-label-map",
|
||||
|
||||
// history dropdown
|
||||
historyMenu: "#history-menu",
|
||||
historyMenuItem: "#history-menu-item"
|
||||
};
|
||||
|
||||
function getConfig() {
|
||||
|
||||
@@ -304,7 +304,7 @@ function setupPageVisibilityHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
function init(localStore) {
|
||||
progress.init();
|
||||
|
||||
config.init({
|
||||
@@ -318,7 +318,7 @@ function init() {
|
||||
summary.init();
|
||||
grid.init();
|
||||
autocomplete.init();
|
||||
filters.init();
|
||||
filters.init(localStore);
|
||||
watchdog.init(30, 60*15); // set watchdog to 15 minutes
|
||||
|
||||
$(selectors.refreshButton).click(function() {
|
||||
@@ -331,7 +331,7 @@ function init() {
|
||||
setupPageVisibilityHandler();
|
||||
}
|
||||
|
||||
function onReady() {
|
||||
function onReady(localStore) {
|
||||
// wrap all inits so we can handle errors
|
||||
try {
|
||||
// init all elements using bootstrapSwitch
|
||||
@@ -347,7 +347,7 @@ function onReady() {
|
||||
ui.setupModal();
|
||||
silence.setupSilenceForm();
|
||||
unsilence.init();
|
||||
init();
|
||||
init(localStore);
|
||||
|
||||
// delay initial alert load to allow browser finish rendering
|
||||
setTimeout(function() {
|
||||
@@ -381,4 +381,6 @@ exports.flash = flash;
|
||||
exports.parseAJAXError = parseAJAXError;
|
||||
exports.onReady = onReady;
|
||||
|
||||
$(document).ready(onReady);
|
||||
$(document).ready(function() {
|
||||
onReady(window.localStorage);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const $ = require("jquery");
|
||||
const templatesMock = require("./__mocks__/templatesMock");
|
||||
const alertsMock = require("./__mocks__/alertsMock");
|
||||
const LocalStorageMock = require("./__mocks__/localStorageMock");
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
@@ -50,7 +51,7 @@ if (alertsServer) {
|
||||
require("bootstrap/js/popover.js");
|
||||
alertsServer.start();
|
||||
|
||||
unsee.onReady();
|
||||
unsee.onReady(LocalStorageMock);
|
||||
unsee.triggerReload();
|
||||
jest.runOnlyPendingTimers();
|
||||
// we should have 2 alerts
|
||||
|
||||
34
assets/templates/history.html
Normal file
34
assets/templates/history.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<script type="application/json" id="history-menu">
|
||||
<% if (filters.length) { %>
|
||||
<% _.each(filters, function(filter) { %>
|
||||
<% if (filter !== activeFilter) { %>
|
||||
<%= renderTemplate("historyMenuItem", {filter: filter, icon: "fa fa-search"}) %>
|
||||
<% } %>
|
||||
<% }) %>
|
||||
<% } %>
|
||||
<% if (defaultFilter || savedFilter) { %>
|
||||
<li role="separator" class="divider"></li>
|
||||
<% if (defaultFilter) { %>
|
||||
<%= renderTemplate("historyMenuItem", {filter: defaultFilter, icon: "fa fa-home"}) %>
|
||||
<% } %>
|
||||
<% if (savedFilter) { %>
|
||||
<%= renderTemplate("historyMenuItem", {filter: savedFilter, icon: "fa fa-floppy-o"}) %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</script>
|
||||
|
||||
<script type="application/json" id="history-menu-item">
|
||||
<li class="history-menu">
|
||||
<a class="cursor-pointer history-menu-item">
|
||||
<span class="rawFilter hidden">
|
||||
<%- filter %>
|
||||
</span>
|
||||
<i class="<%- icon %>"></i>
|
||||
<% _.each(filter.split(","), function(filterItem) { %>
|
||||
<span class="label-list label label-info">
|
||||
<%- filterItem %>
|
||||
</span>
|
||||
<% }) %>
|
||||
</a>
|
||||
</li>
|
||||
</script>
|
||||
@@ -47,6 +47,13 @@
|
||||
</div>
|
||||
</form>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" id="history" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
|
||||
title="Filter history" data-toggle="tooltip" data-placement="auto">
|
||||
<i id="historyList" class="fa fa-history"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu" id="historyMenu"></ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ .WebPrefix }}help" id="help" role="button" title="Filter documentation" data-toggle="tooltip" data-placement="auto">
|
||||
<i class="fa fa-question-circle"></i>
|
||||
@@ -177,3 +184,4 @@
|
||||
{{ template "templates/errors.html" }}
|
||||
{{ template "templates/modal.html" }}
|
||||
{{ template "templates/silence.html" }}
|
||||
{{ template "templates/history.html" }}
|
||||
|
||||
Reference in New Issue
Block a user