web/admin: add toggle to hide deactivated users (#5419)

* web/admin: add toggle to hide deactivated users

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make default user path configurable

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-05-03 15:09:10 +03:00 committed by GitHub
parent a2994218e4
commit 4601864f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 15 deletions

View file

@ -266,11 +266,7 @@ export class AdminInterface extends Interface {
<ak-sidebar-item>
<span slot="label">${t`Directory`}</span>
<ak-sidebar-item
path=${`/identity/users;${encodeURIComponent(
JSON.stringify({
path: "users",
}),
)}`}
path="/identity/users"
.activeWhen=${[`^/identity/users/(?<id>${ID_REGEX})$`]}
>
<span slot="label">${t`Users`}</span>

View file

@ -18,7 +18,7 @@ import { TablePage } from "@goauthentik/elements/table/TablePage";
import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import { PropertyMapping, PropertymappingsApi } from "@goauthentik/api";
@ -43,7 +43,7 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
@property()
order = "name";
@property({ type: Boolean })
@state()
hideManaged = getURLParam<boolean>("hideManaged", true);
async apiEndpoint(page: number): Promise<PaginatedResponse<PropertyMapping>> {

View file

@ -6,7 +6,7 @@ import "@goauthentik/admin/users/UserPasswordForm";
import "@goauthentik/admin/users/UserResetEmailForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { MessageLevel } from "@goauthentik/common/messages";
import { uiConfig } from "@goauthentik/common/ui/config";
import { DefaultUIConfig, uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils";
import { rootInterface } from "@goauthentik/elements/Base";
import { PFColor } from "@goauthentik/elements/Label";
@ -16,7 +16,7 @@ import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/forms/DeleteBulkForm";
import "@goauthentik/elements/forms/ModalForm";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { getURLParam } from "@goauthentik/elements/router/RouteMatch";
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { TableColumn } from "@goauthentik/elements/table/Table";
import { TablePage } from "@goauthentik/elements/table/TablePage";
@ -54,7 +54,10 @@ export class UserListPage extends TablePage<User> {
order = "last_login";
@property()
activePath = getURLParam<string>("path", "/");
activePath;
@state()
hideDeactivated = getURLParam<boolean>("hideDeactivated", false);
@state()
userPaths?: UserPath;
@ -63,6 +66,16 @@ export class UserListPage extends TablePage<User> {
return super.styles.concat(PFDescriptionList, PFCard, PFAlert);
}
constructor() {
super();
this.activePath = getURLParam<string>("path", "/");
uiConfig().then((c) => {
if (c.defaults.userPath !== new DefaultUIConfig().defaults.userPath) {
this.activePath = c.defaults.userPath;
}
});
}
async apiEndpoint(page: number): Promise<PaginatedResponse<User>> {
const users = await new CoreApi(DEFAULT_CONFIG).coreUsersList({
ordering: this.order,
@ -70,6 +83,7 @@ export class UserListPage extends TablePage<User> {
pageSize: (await uiConfig()).pagination.perPage,
search: this.search || "",
pathStartswith: getURLParam("path", ""),
isActive: this.hideDeactivated ? true : undefined,
});
this.userPaths = await new CoreApi(DEFAULT_CONFIG).coreUsersPathsRetrieve({
search: this.search,
@ -131,6 +145,37 @@ export class UserListPage extends TablePage<User> {
</ak-forms-delete-bulk>`;
}
renderToolbarAfter(): TemplateResult {
return html`&nbsp;
<div class="pf-c-toolbar__group pf-m-filter-group">
<div class="pf-c-toolbar__item pf-m-search-filter">
<div class="pf-c-input-group">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${this.hideDeactivated}
@change=${() => {
this.hideDeactivated = !this.hideDeactivated;
this.page = 1;
this.fetch();
updateURLParams({
hideDeactivated: this.hideDeactivated,
});
}}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Hide deactivated user`}</span>
</label>
</div>
</div>
</div>`;
}
row(item: User): TemplateResult[] {
return [
html`<a href="#/identity/users/${item.pk}">

View file

@ -9,6 +9,8 @@ import {
ResponseContext,
} from "@goauthentik/api";
export const CSRFHeaderName = "X-authentik-CSRF";
export interface RequestInfo {
method: string;
path: string;
@ -32,7 +34,7 @@ export class LoggingMiddleware implements Middleware {
export class CSRFMiddleware implements Middleware {
pre?(context: RequestContext): Promise<FetchParams | void> {
// @ts-ignore
context.init.headers["X-authentik-CSRF"] = getCookie("authentik_csrf");
context.init.headers[CSRFHeaderName] = getCookie("authentik_csrf");
return Promise.resolve(context);
}
}

View file

@ -43,6 +43,9 @@ export interface UIConfig {
type: LayoutType;
};
locale: string;
defaults: {
userPath: string,
},
}
export class DefaultUIConfig implements UIConfig {
@ -68,6 +71,9 @@ export class DefaultUIConfig implements UIConfig {
perPage: 20,
};
locale = "";
defaults = {
userPath: "users",
};
constructor() {
if (currentInterface() === "user") {

View file

@ -1,3 +1,4 @@
import { CSRFHeaderName } from "@goauthentik/common/api/middleware";
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { first, getCookie } from "@goauthentik/common/utils";
@ -90,10 +91,7 @@ export class APIBrowser extends Interface {
};
}>,
) => {
e.detail.request.headers.append(
"X-authentik-CSRF",
getCookie("authentik_csrf"),
);
e.detail.request.headers.append(CSRFHeaderName, getCookie("authentik_csrf"));
}}
>
<div slot="nav-logo">

View file

@ -4,6 +4,10 @@
How many items should be retrieved per page. Defaults to 20.
### `settings.defaults.userPath`
Default user path which is opened when opening the user list. Defaults to `users`.
### `settings.theme.base`
Configure the base color scheme. Defaults to `automatic`, which switches between dark and light mode based on the users' browsers' preference. Choices: `automatic`, `dark`, `light`.