From 4eacd18cf6255d433603c65795a8ebcc06e7bef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Wed, 13 May 2020 17:07:37 +0100 Subject: [PATCH] fix(ui): drop react-onclickoutside use a custom hook instad --- ui/package.json | 1 - .../AlertGrid/AlertGroup/Alert/AlertMenu.js | 119 +++++++++-------- .../AlertGroup/Alert/AlertMenu.test.js | 2 +- .../Alert/__snapshots__/index.test.js.snap | 4 +- .../AlertGroup/GroupHeader/GroupMenu.js | 120 +++++++++--------- .../AlertGroup/GroupHeader/GroupMenu.test.js | 2 +- .../Components/NavBar/FilterInput/History.js | 21 +-- ui/src/Components/NavBar/index.stories.js | 4 +- ui/src/__mocks__/react-onclickoutside.js | 6 - 9 files changed, 139 insertions(+), 140 deletions(-) delete mode 100644 ui/src/__mocks__/react-onclickoutside.js diff --git a/ui/package.json b/ui/package.json index 3abdee8cb..09f97afdf 100644 --- a/ui/package.json +++ b/ui/package.json @@ -50,7 +50,6 @@ "react-masonry-infinite": "1.2.2", "react-media": "1.10.0", "react-moment": "0.9.7", - "react-onclickoutside": "6.9.0", "react-popper": "2.2.3", "react-resize-detector": "4.2.3", "react-reveal": "1.2.2", diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js index e5478689b..58665f272 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.js @@ -1,12 +1,9 @@ -import React from "react"; +import React, { useRef, useEffect } from "react"; import PropTypes from "prop-types"; import { useObserver, useLocalStore } from "mobx-react"; -import hash from "object-hash"; - import { Manager, Reference, Popper } from "react-popper"; -import onClickOutside from "react-onclickoutside"; import Moment from "react-moment"; @@ -20,6 +17,7 @@ import { AlertStore } from "Stores/AlertStore"; import { SilenceFormStore, SilenceTabNames } from "Stores/SilenceFormStore"; import { FetchPauser } from "Components/FetchPauser"; import { DropdownSlide } from "Components/Animations/DropdownSlide"; +import { useOnClickOutside } from "Hooks/useOnClickOutside"; const onSilenceClick = (alertStore, silenceFormStore, group, alert) => { silenceFormStore.data.resetProgress(); @@ -32,60 +30,65 @@ const onSilenceClick = (alertStore, silenceFormStore, group, alert) => { silenceFormStore.toggle.show(); }; -const MenuContent = onClickOutside( - ({ - popperPlacement, - popperRef, - popperStyle, - group, - alert, - afterClick, - alertStore, - silenceFormStore, - }) => { - const isReadOnly = - Object.keys(alertStore.data.clustersWithoutReadOnly).length === 0; +const MenuContent = ({ + popperPlacement, + popperRef, + popperStyle, + group, + alert, + afterClick, + alertStore, + silenceFormStore, +}) => { + const ref = useRef(null); + useOnClickOutside(ref, afterClick); - return ( - -
-
Alert source links:
- {alert.alertmanager.map((am) => ( - - - {am.name} - - ))} -
-
- isReadOnly || - onSilenceClick(alertStore, silenceFormStore, group, alert) - } + useEffect(() => { + popperRef(ref.current); + }, [popperRef]); + + return ( + +
+
Alert source links:
+ {alert.alertmanager.map((am) => ( + - - Silence this alert -
+ + {am.name} + + ))} +
+
{ + if (Object.keys(alertStore.data.clustersWithoutReadOnly).length) { + onSilenceClick(alertStore, silenceFormStore, group, alert); + afterClick(); + } + }} + > + + Silence this alert
- - ); - } -); +
+
+ ); +}; MenuContent.propTypes = { popperPlacement: PropTypes.string, popperRef: PropTypes.func, @@ -114,14 +117,12 @@ const AlertMenu = ({ }, })); - const uniqueClass = `components-grid-alert-${group.id}-${hash(alert.labels)}`; - return useObserver(() => ( {({ ref }) => ( )} diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js index d35a8e9f5..389b962ab 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/AlertMenu.test.js @@ -118,7 +118,7 @@ const MountedMenuContent = (group) => { return mount( matches snapshot when inhibited 1`] = `
- matches snapshot with showAlertmanagers=false showReceiver=fa - { silenceFormStore.data.resetProgress(); @@ -31,65 +31,71 @@ const onSilenceClick = (alertStore, silenceFormStore, group) => { silenceFormStore.toggle.show(); }; -const MenuContent = onClickOutside( - ({ - popperPlacement, - popperRef, - popperStyle, - group, - afterClick, - alertStore, - silenceFormStore, - }) => { - let groupFilters = Object.keys(group.labels).map((name) => - FormatQuery(name, QueryOperators.Equal, group.labels[name]) - ); - groupFilters.push( - FormatQuery(StaticLabels.Receiver, QueryOperators.Equal, group.receiver) - ); - const baseURL = [ - window.location.protocol, - "//", - window.location.host, - window.location.pathname, - ].join(""); - const groupLink = `${baseURL}?${FormatAlertsQ(groupFilters)}`; +const MenuContent = ({ + popperPlacement, + popperRef, + popperStyle, + group, + afterClick, + alertStore, + silenceFormStore, +}) => { + const ref = useRef(null); + useOnClickOutside(ref, afterClick); - const isReadOnly = - Object.keys(alertStore.data.clustersWithoutReadOnly).length === 0; + useEffect(() => { + popperRef(ref.current); + }, [popperRef]); - return ( - + let groupFilters = Object.keys(group.labels).map((name) => + FormatQuery(name, QueryOperators.Equal, group.labels[name]) + ); + groupFilters.push( + FormatQuery(StaticLabels.Receiver, QueryOperators.Equal, group.receiver) + ); + const baseURL = [ + window.location.protocol, + "//", + window.location.host, + window.location.pathname, + ].join(""); + const groupLink = `${baseURL}?${FormatAlertsQ(groupFilters)}`; + + return ( + +
{ + copy(groupLink); + afterClick(); + }} > -
{ - copy(groupLink); - afterClick(); - }} - > - Copy link to this group -
-
- isReadOnly || onSilenceClick(alertStore, silenceFormStore, group) - } - > - Silence this group -
+ Copy link to this group
- - ); - } -); +
{ + if (Object.keys(alertStore.data.clustersWithoutReadOnly).length) { + onSilenceClick(alertStore, silenceFormStore, group); + afterClick(); + } + }} + > + Silence this group +
+
+
+ ); +}; MenuContent.propTypes = { popperPlacement: PropTypes.string, popperRef: PropTypes.func, @@ -152,8 +158,6 @@ const GroupMenu = ({ alertStore={alertStore} silenceFormStore={silenceFormStore} afterClick={collapse.hide} - handleClickOutside={collapse.hide} - outsideClickIgnoreClass={`components-grid-alertgroup-${group.id}`} /> )} diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js index 05d5450da..6c6635b27 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/GroupHeader/GroupMenu.test.js @@ -120,7 +120,7 @@ const MountedMenuContent = (group) => { return mount( { + const ref = useRef(null); + useOnClickOutside(ref, afterClick); + + useEffect(() => { + popperRef(ref.current); + }, [popperRef]); + return (
@@ -130,7 +137,7 @@ const HistoryMenuContent = ({
); }; -HistoryMenuContent.propTypes = { +HistoryMenu.propTypes = { popperPlacement: PropTypes.string, popperRef: PropTypes.func, popperStyle: PropTypes.object, @@ -141,8 +148,6 @@ HistoryMenuContent.propTypes = { onClear: PropTypes.func.isRequired, }; -const HistoryMenu = onClickOutside(HistoryMenuContent); - const History = ({ alertStore, settingsStore }) => { // this will be dumped to local storage via mobx-stored const history = localStored( @@ -236,8 +241,6 @@ const History = ({ alertStore, settingsStore }) => { alertStore={alertStore} settingsStore={settingsStore} afterClick={collapse.hide} - handleClickOutside={collapse.hide} - outsideClickIgnoreClass="components-navbar-history" /> )} @@ -250,4 +253,4 @@ History.propTypes = { settingsStore: PropTypes.instanceOf(Settings).isRequired, }; -export { History, HistoryMenu, HistoryMenuContent, ReduceFilter }; +export { History, HistoryMenu, ReduceFilter }; diff --git a/ui/src/Components/NavBar/index.stories.js b/ui/src/Components/NavBar/index.stories.js index 540c1a300..87713fa28 100644 --- a/ui/src/Components/NavBar/index.stories.js +++ b/ui/src/Components/NavBar/index.stories.js @@ -5,7 +5,7 @@ import { storiesOf } from "@storybook/react"; import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore"; import { Settings } from "Stores/Settings"; import { SilenceFormStore } from "Stores/SilenceFormStore"; -import { HistoryMenuContent } from "./FilterInput/History"; +import { HistoryMenu } from "./FilterInput/History"; import { NavBar } from "."; import "Styles/Percy.scss"; @@ -91,7 +91,7 @@ storiesOf("NavBar", module).add("NavBar", () => { silenceFormStore={silenceFormStore} fixedTop={false} /> - {}} popperStyle={{}} diff --git a/ui/src/__mocks__/react-onclickoutside.js b/ui/src/__mocks__/react-onclickoutside.js deleted file mode 100644 index e6131a53b..000000000 --- a/ui/src/__mocks__/react-onclickoutside.js +++ /dev/null @@ -1,6 +0,0 @@ -// mock react-onclickoutside so we bypass it due to: -// TypeError: Cannot read property 'isReactComponent' of undefined - -export default function onClickOutsideHOC(WrappedComponent, config) { - return WrappedComponent; -}