render orderBy filter

This commit is contained in:
Mads Rasmussen
2024-04-18 12:52:30 +02:00
parent d5072062d7
commit ecb8e0b1c3
2 changed files with 160 additions and 52 deletions

View File

@@ -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<UserStateModel> = Object.values(UserStateModel);
private _stateFilterOptions: Array<UmbUserStateFilterModel> = Object.values(UmbUserStateFilterModel);
@state()
private _stateFilterSelection: Array<UserStateModel> = [];
@state()
private _orderBy?: UserOrderModel;
private _stateFilterSelection: Array<UmbUserStateFilterModel> = [];
@state()
private _userGroups: Array<UmbUserGroupDetailModel> = [];
@@ -31,7 +23,12 @@ export class UmbUserCollectionHeaderElement extends UmbLitElement {
@state()
private _userGroupFilterSelection: Array<UmbUserGroupDetailModel> = [];
#modalContext?: UmbModalManagerContext;
@state()
private _orderByOptions: Array<UmbUserOrderByOption> = [];
@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`
<umb-collection-action-bundle></umb-collection-action-bundle>
${this.#renderSearch()}
<div>${this.#renderFilters()} ${this.#renderCollectionViews()}</div>
`;
}
#renderSearch() {
return html`
<uui-input
@input=${this._updateSearch}
label=${this.localize.term('visuallyHiddenTexts_userSearchLabel')}
placeholder=${this.localize.term('visuallyHiddenTexts_userSearchLabel')}
id="input-search"></uui-input>
`;
}
#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`
<umb-collection-action-bundle></umb-collection-action-bundle>
${this.#renderSearch()}
<div>${this.#renderFilters()} ${this.#renderCollectionViews()}</div>
`;
}
#renderSearch() {
return html`
<uui-input
@input=${this._updateSearch}
label=${this.localize.term('visuallyHiddenTexts_userSearchLabel')}
placeholder=${this.localize.term('visuallyHiddenTexts_userSearchLabel')}
id="input-search"></uui-input>
`;
}
#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`
<uui-button popovertarget="popover-order-by-filter" label="order by">
<umb-localize key="general_orderBy"></umb-localize>:
<b> ${this._activeOrderByOption ? this.localize.string(this._activeOrderByOption.label) : ''}</b>
</uui-button>
<uui-popover-container id="popover-order-by-filter" placement="bottom">
<umb-popover-layout>
<div class="filter-dropdown">
${this._orderByOptions.map(
(option) => html`
<uui-menu-item
label=${this.localize.string(option.label)}
@click-label=${() => this.#onOrderByChange(option)}></uui-menu-item>
`,
)}
</div>
</umb-popover-layout>
</uui-popover-container>
`;
}
#renderCollectionViews() {
return html` <umb-collection-view-bundle></umb-collection-view-bundle> `;
}

View File

@@ -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<UmbUserOrderByOption>(
[
{
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<string | undefined>(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<UserStateModel>} selection
* Sets the active order by for the collection and refreshes the collection.
* @param {UmbUserOrderByModel} orderBy
* @param {UmbDirectionModel} orderDirection
* @memberof UmbUserCollectionContext
*/
setStateFilter(selection: Array<UserStateModel>) {
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<UmbUserStateFilterModel>} selection
* @memberof UmbUserCollectionContext
*/
setStateFilter(selection: Array<UmbUserStateFilterModel>) {
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<string>) {
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;