Merge pull request #1659 from umbraco/bugfix/input-member-group-picker

Bugfix: Member Group Picker sorting
This commit is contained in:
Lee Kelleher
2024-04-18 14:26:01 +01:00
committed by GitHub
2 changed files with 56 additions and 100 deletions

View File

@@ -1,66 +1,46 @@
import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';
import type { NumberRangeValueType } from '@umbraco-cms/backoffice/models';
import type { UmbInputMemberGroupElement } from '@umbraco-cms/backoffice/member-group';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
/**
* @element umb-property-editor-ui-member-group-picker
*/
@customElement('umb-property-editor-ui-member-group-picker')
export class UmbPropertyEditorUIMemberGroupPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
// private _value: Array<string> = [];
// @property({ type: Array })
// public set value(value: Array<string>) {
// this._value = Array.isArray(value) ? value : value ? [value] : [];
// }
// public get value(): Array<string> {
// return this._value;
// }
@property({ type: String })
public value: string = '';
@property()
public value?: string;
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
const validationLimit = config?.find((x) => x.alias === 'validationLimit');
if (!config) return;
this._limitMin = (validationLimit?.value as any)?.min;
this._limitMax = (validationLimit?.value as any)?.max;
const minMax = config?.getValueByAlias<NumberRangeValueType>('validationLimit');
this.min = minMax?.min ?? 0;
this.max = minMax?.max ?? Infinity;
}
@state()
_items: Array<string> = [];
min = 0;
@state()
private _limitMin?: number;
@state()
private _limitMax?: number;
max = Infinity;
protected updated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
super.updated(_changedProperties);
if (_changedProperties.has('value')) {
this._items = this.value ? this.value.split(',') : [];
}
}
private _onChange(event: CustomEvent) {
//TODO: This is a hack, something changed so now we need to convert the array to a comma separated string to make it work with the server.
const toCommaSeparatedString = (event.target as UmbInputMemberGroupElement).selection.join(',');
// this.value = (event.target as UmbInputMemberGroupElement).selection;
this.value = toCommaSeparatedString;
this.dispatchEvent(new CustomEvent('property-value-change'));
#onChange(event: CustomEvent & { target: UmbInputMemberGroupElement }) {
this.value = event.target.value;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`
<umb-input-member-group
@change=${this._onChange}
.selection=${this._items}
.min=${this._limitMin ?? 0}
.max=${this._limitMax ?? Infinity}>
</umb-input-member-group>
.min=${this.min}
.max=${this.max}
.value=${this.value ?? ''}
?showOpenButton=${true}
@change=${this.#onChange}></umb-input-member-group>
`;
}
}

View File

@@ -1,31 +1,28 @@
import type { UmbMemberGroupItemModel } from '../../repository/index.js';
import { UmbMemberPickerContext } from './input-member-group.context.js';
import { css, html, customElement, property, state, ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { MemberItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
import { type UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter';
const SORTER_CONFIG: UmbSorterConfig<string> = {
getUniqueOfElement: (element) => {
return element.getAttribute('detail');
},
getUniqueOfModel: (modelEntry) => {
return modelEntry;
},
identifier: 'Umb.SorterIdentifier.InputMemberGroup',
itemSelector: 'uui-ref-node',
containerSelector: 'uui-ref-list',
};
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
import { UmbModalRouteRegistrationController, UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal';
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-input-member-group')
export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElement, '') {
#sorter = new UmbSorterController(this, {
...SORTER_CONFIG,
#sorter = new UmbSorterController<string>(this, {
getUniqueOfElement: (element) => {
return element.id;
},
getUniqueOfModel: (modelEntry) => {
return modelEntry;
},
identifier: 'Umb.SorterIdentifier.InputMemberGroup',
itemSelector: 'uui-ref-node',
containerSelector: 'uui-ref-list',
onChange: ({ model }) => {
this.selection = model;
this.dispatchEvent(new UmbChangeEvent());
},
});
@@ -91,7 +88,6 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
@property()
public set value(idsString: string) {
// Its with full purpose we don't call super.value, as thats being handled by the observation of the context selection.
this.selection = splitStringToArray(idsString);
}
public get value(): string {
@@ -112,7 +108,6 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
constructor() {
super();
// TODO: This would have to be more specific if used in a property editor context... [NL]
new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL)
.addAdditionalPath('member-group')
.onSetup(() => {
@@ -122,10 +117,8 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
this._editMemberGroupPath = routeBuilder({});
});
this.observe(this.#pickerContext.selection, (selection) => (this.value = selection.join(',')));
this.observe(this.#pickerContext.selectedItems, (selectedItems) => {
this._items = selectedItems;
});
this.observe(this.#pickerContext.selection, (selection) => (this.value = selection.join(',')), '_observeSelection');
this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems), '_observeItems');
}
connectedCallback(): void {
@@ -144,16 +137,6 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
);
}
protected _openPicker() {
this.#pickerContext.openPicker({
hideTreeRoot: true,
});
}
protected _requestRemoveItem(item: UmbMemberGroupItemModel) {
this.#pickerContext.requestRemoveItem(item.unique!);
}
protected getFormElement() {
return undefined;
}
@@ -164,29 +147,31 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
});
}
#requestRemoveItem(item: MemberItemResponseModel) {
this.#pickerContext.requestRemoveItem(item.id!);
#removeItem(item: UmbMemberGroupItemModel) {
this.#pickerContext.requestRemoveItem(item.unique);
}
render() {
return html` ${this.#renderItems()} ${this.#renderAddButton()} `;
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
}
#renderItems() {
if (!this._items) return;
return html`<uui-ref-list>
${repeat(
this._items,
(item) => item.unique,
(item) => this.#renderItem(item),
)}
</uui-ref-list>`;
return html`
<uui-ref-list>
${repeat(
this._items,
(item) => item.unique,
(item) => this.#renderItem(item),
)}
</uui-ref-list>
`;
}
#renderAddButton() {
if (this.max === 1 && this.selection.length >= this.max) return;
return html`<uui-button
id="add-button"
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}></uui-button>`;
@@ -194,17 +179,11 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
#renderItem(item: UmbMemberGroupItemModel) {
if (!item.unique) return;
// TODO: get the correct variant name
const name = item.name;
return html`
<uui-ref-node name=${ifDefined(item.name)} detail=${ifDefined(item.unique)}>
<uui-ref-node name=${item.name} id=${item.unique}>
<uui-action-bar slot="actions">
${this.#renderOpenButton(item)}
<uui-button
@click=${() => this._requestRemoveItem(item)}
label="${this.localize.term('general_remove')} ${name}">
${this.localize.term('general_remove')}
</uui-button>
<uui-button @click=${() => this.#removeItem(item)} label=${this.localize.term('general_remove')}></uui-button>
</uui-action-bar>
</uui-ref-node>
`;
@@ -212,21 +191,18 @@ export class UmbInputMemberGroupElement extends UUIFormControlMixin(UmbLitElemen
#renderOpenButton(item: UmbMemberGroupItemModel) {
if (!this.showOpenButton) return;
// TODO: get the correct variant name
const name = item.name;
return html`
<uui-button
compact
href="${this._editMemberGroupPath}edit/${item.unique}"
label=${this.localize.term('general_edit') + ` ${name}`}>
<uui-icon name="icon-edit"></uui-icon>
label="${this.localize.term('general_open')} ${item.name}">
${this.localize.term('general_open')}
</uui-button>
`;
}
static styles = [
css`
#add-button {
#btn-add {
width: 100%;
}