web: improve notification and API drawers (#12659)
* web: move clear all notification button to header, add empty state Signed-off-by: Jens Langhammer <jens@goauthentik.io> * improve sorting for API requests Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -12,6 +12,7 @@ import {
|
|||||||
export const CSRFHeaderName = "X-authentik-CSRF";
|
export const CSRFHeaderName = "X-authentik-CSRF";
|
||||||
|
|
||||||
export interface RequestInfo {
|
export interface RequestInfo {
|
||||||
|
time: number;
|
||||||
method: string;
|
method: string;
|
||||||
path: string;
|
path: string;
|
||||||
status: number;
|
status: number;
|
||||||
@ -47,6 +48,7 @@ export class CSRFMiddleware implements Middleware {
|
|||||||
export class EventMiddleware implements Middleware {
|
export class EventMiddleware implements Middleware {
|
||||||
post?(context: ResponseContext): Promise<Response | void> {
|
post?(context: ResponseContext): Promise<Response | void> {
|
||||||
const request: RequestInfo = {
|
const request: RequestInfo = {
|
||||||
|
time: new Date().getTime(),
|
||||||
method: (context.init.method || "GET").toUpperCase(),
|
method: (context.init.method || "GET").toUpperCase(),
|
||||||
path: context.url,
|
path: context.url,
|
||||||
status: context.response.status,
|
status: context.response.status,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
|
import { getRelativeTime } from "@goauthentik/common/utils";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -55,7 +56,8 @@ export class APIDrawer extends AKElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
window.addEventListener(EVENT_REQUEST_POST, ((e: CustomEvent<RequestInfo>) => {
|
window.addEventListener(EVENT_REQUEST_POST, ((e: CustomEvent<RequestInfo>) => {
|
||||||
this.requests.splice(0, 0, e.detail);
|
this.requests.push(e.detail);
|
||||||
|
this.requests.sort((a, b) => a.time - b.time).reverse();
|
||||||
if (this.requests.length > 50) {
|
if (this.requests.length > 50) {
|
||||||
this.requests.shift();
|
this.requests.shift();
|
||||||
}
|
}
|
||||||
@ -76,6 +78,9 @@ export class APIDrawer extends AKElement {
|
|||||||
href=${item.path}
|
href=${item.path}
|
||||||
>${item.path}</a
|
>${item.path}</a
|
||||||
>
|
>
|
||||||
|
<div class="pf-c-notification-drawer__list-item-timestamp">
|
||||||
|
${getRelativeTime(new Date(item.time))}
|
||||||
|
</div>
|
||||||
</li>`;
|
</li>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { MessageLevel } from "@goauthentik/common/messages";
|
|||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { getRelativeTime } from "@goauthentik/common/utils";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||||
@ -51,9 +52,6 @@ export class NotificationDrawer extends AKElement {
|
|||||||
.pf-c-notification-drawer__list-item-description {
|
.pf-c-notification-drawer__list-item-description {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
.pf-c-notification-drawer__footer {
|
|
||||||
margin: 1rem;
|
|
||||||
}
|
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +140,34 @@ export class NotificationDrawer extends AKElement {
|
|||||||
</li>`;
|
</li>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearNotifications() {
|
||||||
|
new EventsApi(DEFAULT_CONFIG).eventsNotificationsMarkAllSeenCreate().then(() => {
|
||||||
|
showMessage({
|
||||||
|
level: MessageLevel.success,
|
||||||
|
message: msg("Successfully cleared notifications"),
|
||||||
|
});
|
||||||
|
this.firstUpdated();
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent(EVENT_REFRESH, {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent(EVENT_NOTIFICATION_DRAWER_TOGGLE, {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEmpty() {
|
||||||
|
return html`<ak-empty-state header=${msg("No notifications found.")}>
|
||||||
|
<div slot="body">${msg("You don't have any notifications currently.")}</div>
|
||||||
|
</ak-empty-state>`;
|
||||||
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
if (!this.notifications) {
|
if (!this.notifications) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -156,6 +182,18 @@ export class NotificationDrawer extends AKElement {
|
|||||||
<span> ${msg(str`${this.unread} unread`)} </span>
|
<span> ${msg(str`${this.unread} unread`)} </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-c-notification-drawer__header-action">
|
<div class="pf-c-notification-drawer__header-action">
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
@click=${() => {
|
||||||
|
this.clearNotifications();
|
||||||
|
}}
|
||||||
|
class="pf-c-button pf-m-plain"
|
||||||
|
type="button"
|
||||||
|
aria-label=${msg("Clear all")}
|
||||||
|
>
|
||||||
|
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="pf-c-notification-drawer__header-action-close">
|
<div class="pf-c-notification-drawer__header-action-close">
|
||||||
<button
|
<button
|
||||||
@click=${() => {
|
@click=${() => {
|
||||||
@ -177,41 +215,11 @@ export class NotificationDrawer extends AKElement {
|
|||||||
</div>
|
</div>
|
||||||
<div class="pf-c-notification-drawer__body">
|
<div class="pf-c-notification-drawer__body">
|
||||||
<ul class="pf-c-notification-drawer__list">
|
<ul class="pf-c-notification-drawer__list">
|
||||||
${this.notifications.results.map((n) => this.renderItem(n))}
|
${this.notifications.pagination.count < 1
|
||||||
|
? this.renderEmpty()
|
||||||
|
: this.notifications.results.map((n) => this.renderItem(n))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="pf-c-notification-drawer__footer">
|
|
||||||
<button
|
|
||||||
@click=${() => {
|
|
||||||
new EventsApi(DEFAULT_CONFIG)
|
|
||||||
.eventsNotificationsMarkAllSeenCreate()
|
|
||||||
.then(() => {
|
|
||||||
showMessage({
|
|
||||||
level: MessageLevel.success,
|
|
||||||
message: msg("Successfully cleared notifications"),
|
|
||||||
});
|
|
||||||
this.firstUpdated();
|
|
||||||
this.dispatchEvent(
|
|
||||||
new CustomEvent(EVENT_REFRESH, {
|
|
||||||
bubbles: true,
|
|
||||||
composed: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
this.dispatchEvent(
|
|
||||||
new CustomEvent(EVENT_NOTIFICATION_DRAWER_TOGGLE, {
|
|
||||||
bubbles: true,
|
|
||||||
composed: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
class="pf-c-button pf-m-primary pf-m-block"
|
|
||||||
type="button"
|
|
||||||
aria-label=${msg("Clear all")}
|
|
||||||
>
|
|
||||||
${msg("Clear all")}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user