mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
feat(ui): read config from index.html and use it to setup Sentry & default filters
This commit is contained in:
@@ -161,7 +161,6 @@ func (ag *APIAlertGroup) DedupSharedMaps() {
|
||||
// Settings is used to export unsee configuration that is used by UI
|
||||
type Settings struct {
|
||||
StaticColorLabels []string `json:"staticColorLabels"`
|
||||
DefaultFilters []string `json:"defaultFilters"`
|
||||
}
|
||||
|
||||
// AlertsResponse is the structure of JSON response UI will use to get alert data
|
||||
|
||||
Generated
+5
@@ -9487,6 +9487,11 @@
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
|
||||
},
|
||||
"raven-js": {
|
||||
"version": "3.26.3",
|
||||
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.26.3.tgz",
|
||||
"integrity": "sha512-VPAsPfK73A9VPcJx5X/kt0GxOqUGpGDM8vdzsYNQXMhYemyZGiW1JX1AI+f4jxm37Apijj6VVtCyJcYFz3ocSQ=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"moment": "^2.22.2",
|
||||
"prop-types": "^15.6.2",
|
||||
"qs": "^6.5.2",
|
||||
"raven-js": "^3.26.3",
|
||||
"react": "^16.4.1",
|
||||
"react-autosuggest": "^9.3.4",
|
||||
"react-dom": "^16.4.1",
|
||||
|
||||
@@ -16,6 +16,15 @@
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<!--
|
||||
Settings span is used to pass config keys that needs to be accessible
|
||||
early, before the UI app is started.
|
||||
-->
|
||||
<span id="settings"
|
||||
data-raven-dsn="{{ .SentryDSN }}"
|
||||
data-version="{{ .Version }}"
|
||||
data-default-filters-base64="{{ .DefaultFilter }}">
|
||||
</span>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
|
||||
+21
-2
@@ -1,4 +1,5 @@
|
||||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
@@ -10,12 +11,30 @@ import { Fetcher } from "Components/Fetcher";
|
||||
import "./App.css";
|
||||
|
||||
class App extends Component {
|
||||
static propTypes = {
|
||||
defaultFilters: PropTypes.arrayOf(PropTypes.string).isRequired
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const params = DecodeLocationSearch();
|
||||
const { defaultFilters } = this.props;
|
||||
|
||||
this.alertStore = new AlertStore(params.q);
|
||||
let filters;
|
||||
|
||||
// parse and decode request query args
|
||||
const p = DecodeLocationSearch();
|
||||
|
||||
// p.defaultsUsed means that unsee URI didn't have ?q=foo query args
|
||||
if (p.defaultsUsed) {
|
||||
// no ?q=foo set, use defaults from backend config
|
||||
filters = defaultFilters;
|
||||
} else {
|
||||
// user passed ?q=foo, use it as initial filters
|
||||
filters = p.params.q;
|
||||
}
|
||||
|
||||
this.alertStore = new AlertStore(filters);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -8,10 +8,13 @@ import qs from "qs";
|
||||
|
||||
// generate URL for the UI with a set of filters
|
||||
function FormatAPIFilterQuery(filters) {
|
||||
return qs.stringify(Object.assign(DecodeLocationSearch(), { q: filters }), {
|
||||
encodeValuesOnly: true, // don't encode q[]
|
||||
indices: false // go-gin doesn't support parsing q[0]=foo&q[1]=bar
|
||||
});
|
||||
return qs.stringify(
|
||||
Object.assign(DecodeLocationSearch().params, { q: filters }),
|
||||
{
|
||||
encodeValuesOnly: true, // don't encode q[]
|
||||
indices: false // go-gin doesn't support parsing q[0]=foo&q[1]=bar
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// format URI for react UI -> Go backend requests
|
||||
@@ -21,18 +24,26 @@ function FormatUnseeBackendURI(path) {
|
||||
}
|
||||
|
||||
function DecodeLocationSearch() {
|
||||
let defaultsUsed = true;
|
||||
let params = { q: [] };
|
||||
|
||||
if (window.location.search !== "") {
|
||||
const parsed = qs.parse(window.location.search.split("?")[1]);
|
||||
if (Array.isArray(parsed.q)) {
|
||||
params.q = parsed.q;
|
||||
} else {
|
||||
params.q = [parsed.q];
|
||||
params = Object.assign(params, parsed);
|
||||
|
||||
if (parsed.q !== undefined) {
|
||||
defaultsUsed = false;
|
||||
if (parsed.q === "") {
|
||||
params.q = [];
|
||||
} else if (Array.isArray(parsed.q)) {
|
||||
params.q = parsed.q;
|
||||
} else {
|
||||
params.q = [parsed.q];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
return { params: params, defaultsUsed: defaultsUsed };
|
||||
}
|
||||
|
||||
function UpdateLocationSearch(newParams) {
|
||||
|
||||
+50
-1
@@ -1,10 +1,56 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
import Raven from "raven-js";
|
||||
|
||||
import Moment from "react-moment";
|
||||
|
||||
import { App } from "./App";
|
||||
|
||||
let defaultFilters = [];
|
||||
|
||||
// check if we have early settings
|
||||
const settings = document.getElementById("settings");
|
||||
if (settings !== null) {
|
||||
// sentry setup if sentry dsn is set
|
||||
if (
|
||||
settings.dataset.ravenDsn &&
|
||||
settings.dataset.ravenDsn !== "{{ .SentryDSN }}"
|
||||
) {
|
||||
let version = "unknown";
|
||||
if (
|
||||
settings.dataset.version &&
|
||||
settings.dataset.version !== "{{ .Version }}"
|
||||
) {
|
||||
version = settings.dataset.version;
|
||||
}
|
||||
|
||||
try {
|
||||
Raven.config(settings.dataset.ravenDsn, { release: version }).install();
|
||||
} catch (err) {
|
||||
console.error("Raven config failed: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
// default filters, JSON blob encoded with base64
|
||||
if (
|
||||
settings.dataset.defaultFiltersBase64 &&
|
||||
settings.dataset.defaultFiltersBase64 !== "{{ .DefaultFilter }}"
|
||||
) {
|
||||
// decode from base64 to a string
|
||||
const decoded = Buffer.from(
|
||||
settings.dataset.defaultFiltersBase64,
|
||||
"base64"
|
||||
).toString("ascii");
|
||||
// parse decoded string as JSON
|
||||
const json = JSON.parse(decoded);
|
||||
// if we got an array then use it as default filters
|
||||
if (Array.isArray(json)) {
|
||||
defaultFilters = json;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enable console warnings, but only for dev
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
const { whyDidYouUpdate } = require("why-did-you-update");
|
||||
@@ -18,4 +64,7 @@ if (process.env.NODE_ENV === "development") {
|
||||
// https://www.npmjs.com/package/react-moment#pooled-timer
|
||||
Moment.startPooledTimer();
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
ReactDOM.render(
|
||||
<App defaultFilters={defaultFilters} />,
|
||||
document.getElementById("root")
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user