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:
parent
a2994218e4
commit
4601864f94
|
@ -266,11 +266,7 @@ export class AdminInterface extends Interface {
|
||||||
<ak-sidebar-item>
|
<ak-sidebar-item>
|
||||||
<span slot="label">${t`Directory`}</span>
|
<span slot="label">${t`Directory`}</span>
|
||||||
<ak-sidebar-item
|
<ak-sidebar-item
|
||||||
path=${`/identity/users;${encodeURIComponent(
|
path="/identity/users"
|
||||||
JSON.stringify({
|
|
||||||
path: "users",
|
|
||||||
}),
|
|
||||||
)}`}
|
|
||||||
.activeWhen=${[`^/identity/users/(?<id>${ID_REGEX})$`]}
|
.activeWhen=${[`^/identity/users/(?<id>${ID_REGEX})$`]}
|
||||||
>
|
>
|
||||||
<span slot="label">${t`Users`}</span>
|
<span slot="label">${t`Users`}</span>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||||
import { t } from "@lingui/macro";
|
import { t } from "@lingui/macro";
|
||||||
|
|
||||||
import { TemplateResult, html } from "lit";
|
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 { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
import { PropertyMapping, PropertymappingsApi } from "@goauthentik/api";
|
import { PropertyMapping, PropertymappingsApi } from "@goauthentik/api";
|
||||||
|
@ -43,7 +43,7 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||||
@property()
|
@property()
|
||||||
order = "name";
|
order = "name";
|
||||||
|
|
||||||
@property({ type: Boolean })
|
@state()
|
||||||
hideManaged = getURLParam<boolean>("hideManaged", true);
|
hideManaged = getURLParam<boolean>("hideManaged", true);
|
||||||
|
|
||||||
async apiEndpoint(page: number): Promise<PaginatedResponse<PropertyMapping>> {
|
async apiEndpoint(page: number): Promise<PaginatedResponse<PropertyMapping>> {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import "@goauthentik/admin/users/UserPasswordForm";
|
||||||
import "@goauthentik/admin/users/UserResetEmailForm";
|
import "@goauthentik/admin/users/UserResetEmailForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
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 { first } from "@goauthentik/common/utils";
|
||||||
import { rootInterface } from "@goauthentik/elements/Base";
|
import { rootInterface } from "@goauthentik/elements/Base";
|
||||||
import { PFColor } from "@goauthentik/elements/Label";
|
import { PFColor } from "@goauthentik/elements/Label";
|
||||||
|
@ -16,7 +16,7 @@ import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
import "@goauthentik/elements/forms/ModalForm";
|
import "@goauthentik/elements/forms/ModalForm";
|
||||||
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
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 { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
import { TablePage } from "@goauthentik/elements/table/TablePage";
|
||||||
|
@ -54,7 +54,10 @@ export class UserListPage extends TablePage<User> {
|
||||||
order = "last_login";
|
order = "last_login";
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
activePath = getURLParam<string>("path", "/");
|
activePath;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
hideDeactivated = getURLParam<boolean>("hideDeactivated", false);
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
userPaths?: UserPath;
|
userPaths?: UserPath;
|
||||||
|
@ -63,6 +66,16 @@ export class UserListPage extends TablePage<User> {
|
||||||
return super.styles.concat(PFDescriptionList, PFCard, PFAlert);
|
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>> {
|
async apiEndpoint(page: number): Promise<PaginatedResponse<User>> {
|
||||||
const users = await new CoreApi(DEFAULT_CONFIG).coreUsersList({
|
const users = await new CoreApi(DEFAULT_CONFIG).coreUsersList({
|
||||||
ordering: this.order,
|
ordering: this.order,
|
||||||
|
@ -70,6 +83,7 @@ export class UserListPage extends TablePage<User> {
|
||||||
pageSize: (await uiConfig()).pagination.perPage,
|
pageSize: (await uiConfig()).pagination.perPage,
|
||||||
search: this.search || "",
|
search: this.search || "",
|
||||||
pathStartswith: getURLParam("path", ""),
|
pathStartswith: getURLParam("path", ""),
|
||||||
|
isActive: this.hideDeactivated ? true : undefined,
|
||||||
});
|
});
|
||||||
this.userPaths = await new CoreApi(DEFAULT_CONFIG).coreUsersPathsRetrieve({
|
this.userPaths = await new CoreApi(DEFAULT_CONFIG).coreUsersPathsRetrieve({
|
||||||
search: this.search,
|
search: this.search,
|
||||||
|
@ -131,6 +145,37 @@ export class UserListPage extends TablePage<User> {
|
||||||
</ak-forms-delete-bulk>`;
|
</ak-forms-delete-bulk>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderToolbarAfter(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<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[] {
|
row(item: User): TemplateResult[] {
|
||||||
return [
|
return [
|
||||||
html`<a href="#/identity/users/${item.pk}">
|
html`<a href="#/identity/users/${item.pk}">
|
||||||
|
|
|
@ -9,6 +9,8 @@ import {
|
||||||
ResponseContext,
|
ResponseContext,
|
||||||
} from "@goauthentik/api";
|
} from "@goauthentik/api";
|
||||||
|
|
||||||
|
export const CSRFHeaderName = "X-authentik-CSRF";
|
||||||
|
|
||||||
export interface RequestInfo {
|
export interface RequestInfo {
|
||||||
method: string;
|
method: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -32,7 +34,7 @@ export class LoggingMiddleware implements Middleware {
|
||||||
export class CSRFMiddleware implements Middleware {
|
export class CSRFMiddleware implements Middleware {
|
||||||
pre?(context: RequestContext): Promise<FetchParams | void> {
|
pre?(context: RequestContext): Promise<FetchParams | void> {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
context.init.headers["X-authentik-CSRF"] = getCookie("authentik_csrf");
|
context.init.headers[CSRFHeaderName] = getCookie("authentik_csrf");
|
||||||
return Promise.resolve(context);
|
return Promise.resolve(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ export interface UIConfig {
|
||||||
type: LayoutType;
|
type: LayoutType;
|
||||||
};
|
};
|
||||||
locale: string;
|
locale: string;
|
||||||
|
defaults: {
|
||||||
|
userPath: string,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DefaultUIConfig implements UIConfig {
|
export class DefaultUIConfig implements UIConfig {
|
||||||
|
@ -68,6 +71,9 @@ export class DefaultUIConfig implements UIConfig {
|
||||||
perPage: 20,
|
perPage: 20,
|
||||||
};
|
};
|
||||||
locale = "";
|
locale = "";
|
||||||
|
defaults = {
|
||||||
|
userPath: "users",
|
||||||
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (currentInterface() === "user") {
|
if (currentInterface() === "user") {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { CSRFHeaderName } from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { first, getCookie } from "@goauthentik/common/utils";
|
import { first, getCookie } from "@goauthentik/common/utils";
|
||||||
|
@ -90,10 +91,7 @@ export class APIBrowser extends Interface {
|
||||||
};
|
};
|
||||||
}>,
|
}>,
|
||||||
) => {
|
) => {
|
||||||
e.detail.request.headers.append(
|
e.detail.request.headers.append(CSRFHeaderName, getCookie("authentik_csrf"));
|
||||||
"X-authentik-CSRF",
|
|
||||||
getCookie("authentik_csrf"),
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div slot="nav-logo">
|
<div slot="nav-logo">
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
How many items should be retrieved per page. Defaults to 20.
|
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`
|
### `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`.
|
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`.
|
||||||
|
|
Reference in New Issue