From ecb8e0b1c3510d4f96985fb19fc1a3a8e2aebfaa Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 18 Apr 2024 12:52:30 +0200 Subject: [PATCH] render orderBy filter --- .../user-collection-header.element.ts | 120 +++++++++++------- .../collection/user-collection.context.ts | 92 +++++++++++++- 2 files changed, 160 insertions(+), 52 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection-header.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection-header.element.ts index d39f83537c..ab4f7a4b66 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection-header.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection-header.element.ts @@ -1,29 +1,21 @@ import type { UmbUserCollectionContext } from './user-collection.context.js'; -import type { - UUIBooleanInputEvent, - UUICheckboxElement, - UUIRadioGroupElement, - UUIRadioGroupEvent, -} from '@umbraco-cms/backoffice/external/uui'; +import type { UmbUserOrderByOption } from './types.js'; +import { UmbUserStateFilterModel } from './types.js'; +import type { UUIBooleanInputEvent, UUICheckboxElement } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, state, repeat, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_DEFAULT_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; -import type { UmbModalManagerContext } from '@umbraco-cms/backoffice/modal'; -import type { UserOrderModel } from '@umbraco-cms/backoffice/external/backend-api'; -import { UserStateModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbUserGroupDetailModel } from '@umbraco-cms/backoffice/user-group'; import { UmbUserGroupCollectionRepository } from '@umbraco-cms/backoffice/user-group'; +import { observeMultiple } from '@umbraco-cms/backoffice/observable-api'; @customElement('umb-user-collection-header') export class UmbUserCollectionHeaderElement extends UmbLitElement { @state() - private _stateFilterOptions: Array = Object.values(UserStateModel); + private _stateFilterOptions: Array = Object.values(UmbUserStateFilterModel); @state() - private _stateFilterSelection: Array = []; - - @state() - private _orderBy?: UserOrderModel; + private _stateFilterSelection: Array = []; @state() private _userGroups: Array = []; @@ -31,7 +23,12 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { @state() private _userGroupFilterSelection: Array = []; - #modalContext?: UmbModalManagerContext; + @state() + private _orderByOptions: Array = []; + + @state() + _activeOrderByOption?: UmbUserOrderByOption; + #collectionContext?: UmbUserCollectionContext; #inputTimer?: NodeJS.Timeout; #inputTimerAmount = 500; @@ -43,9 +40,26 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { this.consumeContext(UMB_DEFAULT_COLLECTION_CONTEXT, (instance) => { this.#collectionContext = instance as UmbUserCollectionContext; + this.#observeOrderByOptions(); }); } + #observeOrderByOptions() { + if (!this.#collectionContext) return; + this.observe( + observeMultiple([this.#collectionContext.orderByOptions, this.#collectionContext.activeOrderByOption]), + ([options, activeOption]) => { + debugger; + this._orderByOptions = options; + + if (activeOption) { + this._activeOrderByOption = this._orderByOptions.find((option) => option.unique === activeOption); + } + }, + '_umbObserveUserOrderByOptions', + ); + } + protected firstUpdated() { this.#requestUserGroups(); } @@ -68,7 +82,7 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { #onStateFilterChange(event: UUIBooleanInputEvent) { event.stopPropagation(); const target = event.currentTarget as UUICheckboxElement; - const value = target.value as UserStateModel; + const value = target.value as UmbUserStateFilterModel; const isChecked = target.checked; this._stateFilterSelection = isChecked @@ -78,34 +92,6 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { this.#collectionContext?.setStateFilter(this._stateFilterSelection); } - #onOrderByChange(event: UUIRadioGroupEvent) { - event.stopPropagation(); - const target = event.currentTarget as UUIRadioGroupElement | null; - - if (target) { - this._orderBy = target.value as UserOrderModel; - this.#collectionContext?.setOrderByFilter(this._orderBy); - } - } - - render() { - return html` - - ${this.#renderSearch()} -
${this.#renderFilters()} ${this.#renderCollectionViews()}
- `; - } - - #renderSearch() { - return html` - - `; - } - #onUserGroupFilterChange(event: UUIBooleanInputEvent) { const target = event.currentTarget as UUICheckboxElement; const item = this._userGroups.find((group) => group.unique === target.value); @@ -122,6 +108,10 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { this.#collectionContext?.setUserGroupFilter(uniques); } + #onOrderByChange(option: UmbUserOrderByOption) { + this.#collectionContext?.setActiveOrderByOption(option.unique); + } + #getUserGroupFilterLabel() { const length = this._userGroupFilterSelection.length; const max = 2; @@ -146,8 +136,26 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { .join(', ') + (length > max ? ' + ' + (length - max) : ''); } + render() { + return html` + + ${this.#renderSearch()} +
${this.#renderFilters()} ${this.#renderCollectionViews()}
+ `; + } + + #renderSearch() { + return html` + + `; + } + #renderFilters() { - return html` ${this.#renderStatusFilter()} ${this.#renderUserGroupFilter()} `; + return html` ${this.#renderStatusFilter()} ${this.#renderUserGroupFilter()} ${this.#renderOrderBy()} `; } #renderStatusFilter() { @@ -196,6 +204,28 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement { `; } + #renderOrderBy() { + return html` + + : + ${this._activeOrderByOption ? this.localize.string(this._activeOrderByOption.label) : ''} + + + +
+ ${this._orderByOptions.map( + (option) => html` + this.#onOrderByChange(option)}> + `, + )} +
+
+
+ `; + } + #renderCollectionViews() { return html` `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts index 2c0d4566ab..3b454ca29b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/user-collection.context.ts @@ -1,33 +1,102 @@ import type { UmbUserDetailModel } from '../types.js'; import { UMB_COLLECTION_VIEW_USER_GRID } from './views/index.js'; -import type { UmbUserCollectionFilterModel } from './types.js'; +import type { UmbUserCollectionFilterModel, UmbUserOrderByOption, UmbUserStateFilterModel } from './types.js'; +import { UmbUserOrderByModel } from './types.js'; import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; -import type { UserOrderModel, UserStateModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbDirectionModel } from '@umbraco-cms/backoffice/models'; +import { UmbArrayState, UmbStringState } from '@umbraco-cms/backoffice/observable-api'; export class UmbUserCollectionContext extends UmbDefaultCollectionContext< UmbUserDetailModel, UmbUserCollectionFilterModel > { + #orderByOptions = new UmbArrayState( + [ + { + unique: 'nameAscending', + label: '#user_sortNameAscending', + config: { + orderBy: UmbUserOrderByModel.NAME, + orderDirection: UmbDirectionModel.ASCENDING, + }, + }, + { + unique: 'nameDescending', + label: '#user_sortNameDescending', + config: { + orderBy: UmbUserOrderByModel.NAME, + orderDirection: UmbDirectionModel.DESCENDING, + }, + }, + { + unique: 'createDateDescending', + label: '#user_sortCreateDateDescending', + config: { + orderBy: UmbUserOrderByModel.CREATE_DATE, + orderDirection: UmbDirectionModel.DESCENDING, + }, + }, + { + unique: 'createDateAscending', + label: '#user_sortCreateDateAscending', + config: { + orderBy: UmbUserOrderByModel.CREATE_DATE, + orderDirection: UmbDirectionModel.ASCENDING, + }, + }, + { + unique: 'lastLoginDateDescending', + label: '#user_sortLastLoginDateDescending', + config: { + orderBy: UmbUserOrderByModel.LAST_LOGIN_DATE, + orderDirection: UmbDirectionModel.DESCENDING, + }, + }, + ], + (x) => x.label, + ); + orderByOptions = this.#orderByOptions.asObservable(); + + #activeOrderByOption = new UmbStringState(undefined); + activeOrderByOption = this.#activeOrderByOption.asObservable(); + constructor(host: UmbControllerHost) { super(host, UMB_COLLECTION_VIEW_USER_GRID); + // init default orderBy option + const defaultOrderByOption = this.#orderByOptions.getValue()[0]; + this.setActiveOrderByOption(defaultOrderByOption.unique); } /** - * Sets the state filter for the collection and refreshes the collection. - * @param {Array} selection + * Sets the active order by for the collection and refreshes the collection. + * @param {UmbUserOrderByModel} orderBy + * @param {UmbDirectionModel} orderDirection * @memberof UmbUserCollectionContext */ - setStateFilter(selection: Array) { + setActiveOrderByOption(unique: string) { + const option = this.#orderByOptions.getValue().find((x) => x.unique === unique); + this.#activeOrderByOption.setValue(unique); + this.setFilter({ orderBy: option?.config.orderBy, orderDirection: option?.config.orderDirection }); + } + + getActiveOrderByOption() {} + + /** + * Sets the state filter for the collection and refreshes the collection. + * @param {Array} selection + * @memberof UmbUserCollectionContext + */ + setStateFilter(selection: Array) { this.setFilter({ userStates: selection }); } /** * Sets the order by filter for the collection and refreshes the collection. - * @param {UserOrderModel} orderBy + * @param {UmbUserOrderByModel} orderBy * @memberof UmbUserCollectionContext */ - setOrderByFilter(orderBy: UserOrderModel) { + setOrderByFilter(orderBy: UmbUserOrderByModel) { this.setFilter({ orderBy }); } @@ -39,6 +108,15 @@ export class UmbUserCollectionContext extends UmbDefaultCollectionContext< setUserGroupFilter(selection: Array) { this.setFilter({ userGroupIds: selection }); } + + /** + * Sets the order direction filter for the collection and refreshes the collection. + * @param {UmbDirectionModel} orderDirection + * @memberof UmbUserCollectionContext + */ + setOrderDirectionFilter(orderDirection: UmbDirectionModel) { + this.setFilter({ orderDirection }); + } } export default UmbUserCollectionContext;