diff --git a/ui/package-lock.json b/ui/package-lock.json index 119e58ffa..a0f5956cb 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -2332,6 +2332,15 @@ "object-assign": "4.1.1" } }, + "create-react-context": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz", + "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==", + "requires": { + "fbjs": "0.8.17", + "gud": "1.0.0" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -4789,6 +4798,11 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "gzip-size": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", @@ -8106,6 +8120,11 @@ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" }, + "popper.js": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.3.tgz", + "integrity": "sha1-FDj5jQRqz3tNeM1QK/QYrGTU8JU=" + }, "portfinder": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", @@ -9652,6 +9671,19 @@ "resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.7.9.tgz", "integrity": "sha512-JpHQgpB+p3oqZv583xlJakPXgqdIjGBZvngHYcFhlYxTYs0NDZSdoM1FCpU9T2QmqKOEFBVuhhJBMvJzTkF/wQ==" }, + "react-popper": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0.tgz", + "integrity": "sha1-uZRSFE6P5KzHf6PZWajHngemUIQ=", + "requires": { + "babel-runtime": "6.26.0", + "create-react-context": "0.2.2", + "popper.js": "1.14.3", + "prop-types": "15.6.2", + "typed-styles": "0.0.5", + "warning": "3.0.0" + } + }, "react-resize-detector": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-3.1.0.tgz", @@ -11414,6 +11446,11 @@ "mime-types": "2.1.18" } }, + "typed-styles": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.5.tgz", + "integrity": "sha512-ht+rEe5UsdEBAa3gr64+QjUOqjOLJfWLvl5HZR5Ev9uo/OnD3p43wPeFSB1hNFc13GXQF/JU1Bn0YHLUqBRIlw==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -11764,6 +11801,14 @@ "makeerror": "1.0.11" } }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "1.3.1" + } + }, "watch": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", diff --git a/ui/package.json b/ui/package.json index db2bd93c1..c9b3f7131 100644 --- a/ui/package.json +++ b/ui/package.json @@ -27,6 +27,7 @@ "react-linkify": "^0.2.2", "react-masonry-infinite": "^1.2.2", "react-moment": "^0.7.9", + "react-popper": "^1.0.0", "react-resize-detector": "^3.0.1", "react-scripts": "1.1.4", "react-transition-group": "^2.4.0", diff --git a/ui/src/Components/Labels/HistoryLabel/index.css b/ui/src/Components/Labels/HistoryLabel/index.css new file mode 100644 index 000000000..0e258c6bb --- /dev/null +++ b/ui/src/Components/Labels/HistoryLabel/index.css @@ -0,0 +1,4 @@ +.badge.components-label-history { + /* fix align after text-truncate */ + vertical-align: middle; +} diff --git a/ui/src/Components/Labels/HistoryLabel/index.js b/ui/src/Components/Labels/HistoryLabel/index.js new file mode 100644 index 000000000..5b0c52cba --- /dev/null +++ b/ui/src/Components/Labels/HistoryLabel/index.js @@ -0,0 +1,28 @@ +import React from "react"; + +import { observer } from "mobx-react"; + +import { BaseLabel } from "Components/Labels/BaseLabel"; + +import "./index.css"; + +const HistoryLabel = observer( + class HistoryLabel extends BaseLabel { + render() { + const { name, value } = this.props; + return ( + + {name}: {value} + + ); + } + } +); + +export { HistoryLabel }; diff --git a/ui/src/Components/NavBar/FilterInput/History.js b/ui/src/Components/NavBar/FilterInput/History.js new file mode 100644 index 000000000..98135c87d --- /dev/null +++ b/ui/src/Components/NavBar/FilterInput/History.js @@ -0,0 +1,197 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; + +import { action, observable, toJS } from "mobx"; +import { observer } from "mobx-react"; +import { localStored } from "mobx-stored"; + +import { Manager, Reference, Popper } from "react-popper"; + +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCaretDown } from "@fortawesome/free-solid-svg-icons/faCaretDown"; + +import { AlertStore } from "Stores/AlertStore"; +import { HistoryLabel } from "Components/Labels/HistoryLabel"; + +const defaultHistory = { + filters: [] +}; + +// takes a filter object out of alertStore.history.values and creates a new +// object with only those keys that will be stored in history +function reduceFilter(filter) { + return { + raw: filter.raw, + name: filter.name, + matcher: filter.matcher, + value: filter.value + }; +} + +const HistoryMenu = ({ + popperPlacement, + popperRef, + popperStyle, + filters, + alertStore, + afterClick +}) => { + return ( +