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:
		| @ -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> | ||||
|  | ||||
| @ -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>> { | ||||
|  | ||||
| @ -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`  | ||||
|             <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}"> | ||||
|  | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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") { | ||||
|  | ||||
| @ -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"> | ||||
|  | ||||
| @ -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`. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens L
					Jens L