web: add sentry, add spinner button as base for action button
This commit is contained in:
parent
2417d5a59e
commit
a8dad2e393
|
@ -30,3 +30,5 @@ values =
|
|||
[bumpversion:file:passbook/__init__.py]
|
||||
|
||||
[bumpversion:file:proxy/pkg/version.go]
|
||||
|
||||
[bumpversion:file:web/src/constants.ts]
|
||||
|
|
|
@ -15,6 +15,10 @@ class ConfigSerializer(Serializer):
|
|||
branding_logo = ReadOnlyField()
|
||||
branding_title = ReadOnlyField()
|
||||
|
||||
error_reporting_enabled = ReadOnlyField()
|
||||
error_reporting_environment = ReadOnlyField()
|
||||
error_reporting_send_pii = ReadOnlyField()
|
||||
|
||||
def create(self, request: Request) -> Response:
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -34,6 +38,9 @@ class ConfigsViewSet(ViewSet):
|
|||
{
|
||||
"branding_logo": CONFIG.y("passbook.branding.logo"),
|
||||
"branding_title": CONFIG.y("passbook.branding.title"),
|
||||
"error_reporting_enabled": CONFIG.y("error_reporting.enabled"),
|
||||
"error_reporting_environment": CONFIG.y("error_reporting.environment"),
|
||||
"error_reporting_send_pii": CONFIG.y("error_reporting.send_pii"),
|
||||
}
|
||||
)
|
||||
return Response(config.data)
|
||||
|
|
35
web/dist/main.js
vendored
35
web/dist/main.js
vendored
File diff suppressed because one or more lines are too long
2
web/dist/main.js.map
vendored
2
web/dist/main.js.map
vendored
File diff suppressed because one or more lines are too long
111
web/package-lock.json
generated
111
web/package-lock.json
generated
|
@ -96,6 +96,117 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@sentry/browser": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.27.6.tgz",
|
||||
"integrity": "sha512-pqrojE2ZmLUVz7l/ogtogK0+M2pK3bigYm0fja7vG7F7kXnCAwqAHDYfkFXEvFI8WvNwH+niy28lSoV95lnm0Q==",
|
||||
"requires": {
|
||||
"@sentry/core": "5.27.6",
|
||||
"@sentry/types": "5.27.6",
|
||||
"@sentry/utils": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/core": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.27.6.tgz",
|
||||
"integrity": "sha512-izCS5iyc6HAfpW1AsGXLAKetx82C1Sq1siAh97tOlSK58PVJAEH/WMiej9WuZJxCDTOtj94QtoLflssrZyAtFg==",
|
||||
"requires": {
|
||||
"@sentry/hub": "5.27.6",
|
||||
"@sentry/minimal": "5.27.6",
|
||||
"@sentry/types": "5.27.6",
|
||||
"@sentry/utils": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/hub": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.27.6.tgz",
|
||||
"integrity": "sha512-bOMky3iu7zEghSaWmTayfme5tCpUok841qDCGxGKuyAtOhBDsgGNS/ApNEEDF2fyX0oo4G1cHYPWhX90ZFf/xA==",
|
||||
"requires": {
|
||||
"@sentry/types": "5.27.6",
|
||||
"@sentry/utils": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/minimal": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.27.6.tgz",
|
||||
"integrity": "sha512-pKhzVQX9nL4m1dcnb2i2Y47IWVNs+K3wiYLgCB9hl9+ApxppfOc+fquiFoCloST3IuaD4yly2TtbOJgAMWcMxQ==",
|
||||
"requires": {
|
||||
"@sentry/hub": "5.27.6",
|
||||
"@sentry/types": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/tracing": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.27.6.tgz",
|
||||
"integrity": "sha512-ms3vprEId+hi8hcqtf8weqsNGASaDXAZzIOT4g2gASGpwLb5hLuScpM8z6Yhu5FGjb8DektlW5OrXJSsStIozw==",
|
||||
"requires": {
|
||||
"@sentry/hub": "5.27.6",
|
||||
"@sentry/minimal": "5.27.6",
|
||||
"@sentry/types": "5.27.6",
|
||||
"@sentry/utils": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sentry/types": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.27.6.tgz",
|
||||
"integrity": "sha512-XOW9W8DrMk++4Hk7gWi9o5VR0o/GrqGfTKyFsHSIjqt2hL6kiMPvKeb2Hhmp7Iq37N2bDmRdWpM5m+68S2Jk6w=="
|
||||
},
|
||||
"@sentry/utils": {
|
||||
"version": "5.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.27.6.tgz",
|
||||
"integrity": "sha512-/QMVLv+zrTfiIj2PU+SodSbSzD5MmamMOaljkDsRIVsj6gpkm1/VG1g2+40TZ0FbQ4hCW2F+iR7cnqzZBNmchA==",
|
||||
"requires": {
|
||||
"@sentry/types": "5.27.6",
|
||||
"tslib": "^1.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/chart.js": {
|
||||
"version": "2.9.28",
|
||||
"resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.28.tgz",
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||
"@patternfly/patternfly": "^4.65.6",
|
||||
"@sentry/browser": "^5.27.6",
|
||||
"@sentry/tracing": "^5.27.6",
|
||||
"@types/chart.js": "^2.9.28",
|
||||
"@types/codemirror": "0.0.100",
|
||||
"chart.js": "^2.9.4",
|
||||
|
|
|
@ -1,10 +1,31 @@
|
|||
import { DefaultClient } from "./client";
|
||||
import * as Sentry from "@sentry/browser";
|
||||
import { Integrations } from "@sentry/tracing";
|
||||
import { VERSION } from "../constants";
|
||||
|
||||
export class Config {
|
||||
branding_logo?: string;
|
||||
branding_title?: string;
|
||||
|
||||
error_reporting_enabled?: boolean;
|
||||
error_reporting_environment?: string;
|
||||
error_reporting_send_pii?: boolean;
|
||||
|
||||
static get(): Promise<Config> {
|
||||
return DefaultClient.fetch<Config>(["root", "config"]);
|
||||
return DefaultClient.fetch<Config>(["root", "config"])
|
||||
.then((config) => {
|
||||
if (config.error_reporting_enabled) {
|
||||
Sentry.init({
|
||||
dsn: "https://33cdbcb23f8b436dbe0ee06847410b67@sentry.beryju.org/3",
|
||||
release: `passbook@${VERSION}`,
|
||||
integrations: [new Integrations.BrowserTracing()],
|
||||
tracesSampleRate: 1.0,
|
||||
environment: config.error_reporting_environment,
|
||||
sendDefaultPii: config.error_reporting_send_pii,
|
||||
});
|
||||
console.debug(`passbook/config: Sentry enabled.`);
|
||||
}
|
||||
return config;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,3 +28,4 @@ export const ColorStyles = css`
|
|||
background-color: var(--pf-global--danger-color--100);
|
||||
}
|
||||
`;
|
||||
export const VERSION = "0.12.11-stable";
|
||||
|
|
|
@ -1,64 +1,13 @@
|
|||
import { getCookie } from "../utils";
|
||||
import { css, customElement, html, LitElement, property } from "lit-element";
|
||||
// @ts-ignore
|
||||
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
||||
// @ts-ignore
|
||||
import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
|
||||
// @ts-ignore
|
||||
import SpinnerStyle from "@patternfly/patternfly/components/Spinner/spinner.css";
|
||||
import {
|
||||
ColorStyles,
|
||||
ERROR_CLASS,
|
||||
PRIMARY_CLASS,
|
||||
PROGRESS_CLASS,
|
||||
SUCCESS_CLASS,
|
||||
} from "../constants";
|
||||
import { customElement, html, property } from "lit-element";
|
||||
import { ERROR_CLASS, SUCCESS_CLASS } from "../constants";
|
||||
import { SpinnerButton } from "./SpinnerButton";
|
||||
|
||||
@customElement("pb-action-button")
|
||||
export class ActionButton extends LitElement {
|
||||
export class ActionButton extends SpinnerButton {
|
||||
@property()
|
||||
url: string = "";
|
||||
|
||||
@property()
|
||||
isRunning = false;
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
GlobalsStyle,
|
||||
ButtonStyle,
|
||||
SpinnerStyle,
|
||||
ColorStyles,
|
||||
css`
|
||||
button {
|
||||
/* Have to use !important here, as buttons with pf-m-progress have transition already */
|
||||
transition: all var(--pf-c-button--m-progress--TransitionDuration) ease 0s !important;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.classList.add(PRIMARY_CLASS);
|
||||
}
|
||||
|
||||
setLoading() {
|
||||
this.isRunning = true;
|
||||
this.classList.add(PROGRESS_CLASS);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
setDone(statusClass: string) {
|
||||
this.isRunning = false;
|
||||
this.classList.remove(PROGRESS_CLASS);
|
||||
this.classList.replace(PRIMARY_CLASS, statusClass);
|
||||
this.requestUpdate();
|
||||
setTimeout(() => {
|
||||
this.classList.replace(statusClass, PRIMARY_CLASS);
|
||||
this.requestUpdate();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
callAction() {
|
||||
if (this.isRunning === true) {
|
||||
return;
|
||||
|
@ -80,26 +29,4 @@ export class ActionButton extends LitElement {
|
|||
this.setDone(ERROR_CLASS);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<button
|
||||
class="pf-c-button pf-m-progress ${this.classList.toString()}"
|
||||
@click=${() => this.callAction()}
|
||||
>
|
||||
${this.isRunning
|
||||
? html` <span class="pf-c-button__progress">
|
||||
<span
|
||||
class="pf-c-spinner pf-m-md"
|
||||
role="progressbar"
|
||||
aria-valuetext="Loading..."
|
||||
>
|
||||
<span class="pf-c-spinner__clipper"></span>
|
||||
<span class="pf-c-spinner__lead-ball"></span>
|
||||
<span class="pf-c-spinner__tail-ball"></span>
|
||||
</span>
|
||||
</span>`
|
||||
: ""}
|
||||
<slot></slot>
|
||||
</button>`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
|
|||
import fa from "@fortawesome/fontawesome-free/css/solid.css";
|
||||
|
||||
import { convertToSlug } from "../utils";
|
||||
import { SpinnerButton } from "./SpinnerButton";
|
||||
import { PRIMARY_CLASS } from "../constants";
|
||||
|
||||
@customElement("pb-modal-button")
|
||||
export class ModalButton extends LitElement {
|
||||
|
@ -119,6 +121,9 @@ export class ModalButton extends LitElement {
|
|||
this.querySelector("[slot=modal]")!.innerHTML = t;
|
||||
this.updateHandlers();
|
||||
this.open = true;
|
||||
this.querySelectorAll<SpinnerButton>("pb-spinner-button").forEach(sb => {
|
||||
sb.setDone(PRIMARY_CLASS);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
|
|
84
web/src/elements/SpinnerButton.ts
Normal file
84
web/src/elements/SpinnerButton.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { css, customElement, html, LitElement, property } from "lit-element";
|
||||
// @ts-ignore
|
||||
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
||||
// @ts-ignore
|
||||
import ButtonStyle from "@patternfly/patternfly/components/Button/button.css";
|
||||
// @ts-ignore
|
||||
import SpinnerStyle from "@patternfly/patternfly/components/Spinner/spinner.css";
|
||||
import {
|
||||
ColorStyles,
|
||||
PRIMARY_CLASS,
|
||||
PROGRESS_CLASS,
|
||||
} from "../constants";
|
||||
|
||||
@customElement("pb-spinner-button")
|
||||
export class SpinnerButton extends LitElement {
|
||||
@property()
|
||||
isRunning = false;
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
GlobalsStyle,
|
||||
ButtonStyle,
|
||||
SpinnerStyle,
|
||||
ColorStyles,
|
||||
css`
|
||||
button {
|
||||
/* Have to use !important here, as buttons with pf-m-progress have transition already */
|
||||
transition: all var(--pf-c-button--m-progress--TransitionDuration) ease 0s !important;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.classList.add(PRIMARY_CLASS);
|
||||
}
|
||||
|
||||
setLoading() {
|
||||
this.isRunning = true;
|
||||
this.classList.add(PROGRESS_CLASS);
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
setDone(statusClass: string) {
|
||||
this.isRunning = false;
|
||||
this.classList.remove(PROGRESS_CLASS);
|
||||
this.classList.replace(PRIMARY_CLASS, statusClass);
|
||||
this.requestUpdate();
|
||||
setTimeout(() => {
|
||||
this.classList.replace(statusClass, PRIMARY_CLASS);
|
||||
this.requestUpdate();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
callAction() {
|
||||
if (this.isRunning === true) {
|
||||
return;
|
||||
}
|
||||
this.setLoading();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<button
|
||||
class="pf-c-button pf-m-progress ${this.classList.toString()}"
|
||||
@click=${() => this.callAction()}
|
||||
>
|
||||
${this.isRunning
|
||||
? html` <span class="pf-c-button__progress">
|
||||
<span
|
||||
class="pf-c-spinner pf-m-md"
|
||||
role="progressbar"
|
||||
aria-valuetext="Loading..."
|
||||
>
|
||||
<span class="pf-c-spinner__clipper"></span>
|
||||
<span class="pf-c-spinner__lead-ball"></span>
|
||||
<span class="pf-c-spinner__tail-ball"></span>
|
||||
</span>
|
||||
</span>`
|
||||
: ""}
|
||||
<slot></slot>
|
||||
</button>`;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import "construct-style-sheets-polyfill";
|
||||
|
||||
import "./elements/ActionButton";
|
||||
import "./elements/SpinnerButton";
|
||||
import "./elements/AdminLoginsChart";
|
||||
import "./elements/CodeMirror";
|
||||
import "./elements/Dropdown";
|
||||
|
|
|
@ -22,24 +22,24 @@ export class BoundPoliciesList extends Table {
|
|||
|
||||
row(item: any): string[] {
|
||||
return [
|
||||
item.policy.name,
|
||||
item.policy_obj.name,
|
||||
item.enabled,
|
||||
item.order,
|
||||
item.timeout,
|
||||
`
|
||||
<pb-modal-button href="{% url 'passbook_admin:policy-binding-update' pk=binding.pk %}">
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
<pb-modal-button href="administration/policies/bindings/${item.pk}/update/">
|
||||
<pb-spinner-button slot="trigger" class="pf-m-secondary">
|
||||
Edit
|
||||
</button>
|
||||
</pb-spinner-button>
|
||||
<div slot="modal"></div>
|
||||
</pb-modal-button>
|
||||
<pb-modal-button href="{% url 'passbook_admin:policy-binding-delete' pk=binding.pk %}">
|
||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||
<pb-modal-button href="administration/policies/bindings/${item.pk}/delete/">
|
||||
<pb-spinner-button slot="trigger" class="pf-m-danger">
|
||||
Delete
|
||||
</button>
|
||||
</pb-spinner-button>
|
||||
<div slot="modal"></div>
|
||||
</pb-modal-button>
|
||||
`
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue