From be5b19c8d885df31044341991a2e3aa5f39b605d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Wed, 14 Aug 2019 18:51:52 +0100 Subject: [PATCH 1/2] fix(ui): deduplicate filter in query args If we get same filter value multiple times we should only use it once --- ui/src/Stores/AlertStore.js | 7 +++++-- ui/src/Stores/AlertStore.test.js | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ui/src/Stores/AlertStore.js b/ui/src/Stores/AlertStore.js index eb0b1a972..e6025abb5 100644 --- a/ui/src/Stores/AlertStore.js +++ b/ui/src/Stores/AlertStore.js @@ -46,8 +46,11 @@ function DecodeLocationSearch(searchString) { if (parsed.q === "") { params.q = []; } else if (Array.isArray(parsed.q)) { - // filter out empty strings, so 'q=' doesn't end up [""] but rather [] - params.q = parsed.q.filter(v => v !== ""); + // first filter out duplicates + // then filter out empty strings, so 'q=' doesn't end up [""] but rather [] + params.q = parsed.q + .filter((v, i) => parsed.q.indexOf(v) === i) + .filter(v => v !== ""); } else { params.q = [parsed.q]; } diff --git a/ui/src/Stores/AlertStore.test.js b/ui/src/Stores/AlertStore.test.js index 3f82a11a1..210ccba93 100644 --- a/ui/src/Stores/AlertStore.test.js +++ b/ui/src/Stores/AlertStore.test.js @@ -181,6 +181,13 @@ describe("DecodeLocationSearch", () => { }); }); + it("no value q[]=&q[]= search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q=")).toMatchObject({ + defaultsUsed: false, + params: { q: [] } + }); + }); + it("single value q=foo search param is decoded correctly", () => { expect(DecodeLocationSearch("?q=foo")).toMatchObject({ defaultsUsed: false, @@ -201,6 +208,20 @@ describe("DecodeLocationSearch", () => { params: { q: ["foo", "bar"] } }); }); + + it("multi value q[]=foo&q[]=bar&q[]=foo search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q[]=foo&q[]=bar&q[]=foo")).toMatchObject({ + defaultsUsed: false, + params: { q: ["foo", "bar"] } + }); + }); + + it("multi value q[]=foo&q[]=&q[]=foo search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q[]=foo&q[]=&q[]=foo")).toMatchObject({ + defaultsUsed: false, + params: { q: ["foo"] } + }); + }); }); describe("UpdateLocationSearch", () => { From a36fd5562797a5d3b735180ee39b903e7cc38ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Wed, 14 Aug 2019 19:18:12 +0100 Subject: [PATCH 2/2] fix(ui): generate correct group URL current filters got appended to the group url, fix it by stripping query args away --- .../AlertGroup/GroupHeader/GroupMenu.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js index 8ccba09d3..355deaadd 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.js @@ -15,7 +15,7 @@ import { faShareSquare } from "@fortawesome/free-solid-svg-icons/faShareSquare"; import { faBellSlash } from "@fortawesome/free-solid-svg-icons/faBellSlash"; import { APIGroup } from "Models/API"; -import { FormatAPIFilterQuery } from "Stores/AlertStore"; +import { FormatAlertsQ } from "Stores/AlertStore"; import { AlertStore } from "Stores/AlertStore"; import { SilenceFormStore } from "Stores/SilenceFormStore"; import { QueryOperators, StaticLabels, FormatQuery } from "Common/Query"; @@ -47,9 +47,13 @@ const MenuContent = onClickOutside( groupFilters.push( FormatQuery(StaticLabels.Receiver, QueryOperators.Equal, group.receiver) ); - const groupLink = `${window.location.href}?${FormatAPIFilterQuery( - groupFilters - )}`; + const baseURL = [ + window.location.protocol, + "//", + window.location.host, + window.location.pathname + ].join(""); + const groupLink = `${baseURL}?${FormatAlertsQ(groupFilters)}`; return ( @@ -160,9 +164,7 @@ const GroupMenu = observer( silenceFormStore={silenceFormStore} afterClick={this.collapse.hide} handleClickOutside={this.collapse.hide} - outsideClickIgnoreClass={`components-grid-alertgroup-${ - group.id - }`} + outsideClickIgnoreClass={`components-grid-alertgroup-${group.id}`} /> )}