Refactored property-editor UI picker modal

Refactored the grouping code, to sort items alphabetically
and `fromCamelCase` the group labels.
This commit is contained in:
leekelleher
2024-08-07 16:42:08 +01:00
parent a2158a7ca3
commit 7a83c8e85f

View File

@@ -1,25 +1,22 @@
import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
import { css, customElement, html, repeat, state } from '@umbraco-cms/backoffice/external/lit';
import { fromCamelCase } from '@umbraco-cms/backoffice/utils';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry';
import type {
UmbPropertyEditorUIPickerModalData,
UmbPropertyEditorUIPickerModalValue,
} from '@umbraco-cms/backoffice/modal';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
interface GroupedPropertyEditorUIs {
[key: string]: Array<ManifestPropertyEditorUi>;
}
@customElement('umb-property-editor-ui-picker-modal')
export class UmbPropertyEditorUIPickerModalElement extends UmbModalBaseElement<
UmbPropertyEditorUIPickerModalData,
UmbPropertyEditorUIPickerModalValue
> {
@state()
private _groupedPropertyEditorUIs: GroupedPropertyEditorUIs = {};
private _groupedPropertyEditorUIs: Array<{ key: string; items: Array<ManifestPropertyEditorUi> }> = [];
@state()
private _propertyEditorUIs: Array<ManifestPropertyEditorUi> = [];
@@ -33,17 +30,11 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbModalBaseElement<
#usePropertyEditorUIs() {
this.observe(umbExtensionsRegistry.byType('propertyEditorUi'), (propertyEditorUIs) => {
// Only include Property Editor UIs which has Property Editor Schema Alias
this._propertyEditorUIs = propertyEditorUIs.filter(
(propertyEditorUi) => !!propertyEditorUi.meta.propertyEditorSchemaAlias,
);
this._propertyEditorUIs = propertyEditorUIs
.filter((propertyEditorUi) => !!propertyEditorUi.meta.propertyEditorSchemaAlias)
.sort((a, b) => a.meta.label.localeCompare(b.meta.label));
// TODO: groupBy is not known by TS yet
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
this._groupedPropertyEditorUIs = Object.groupBy(
this._propertyEditorUIs,
(propertyEditorUi: ManifestPropertyEditorUi) => propertyEditorUi.meta.group,
);
this.#groupPropertyEditorUIs(this._propertyEditorUIs);
});
}
@@ -53,30 +44,35 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbModalBaseElement<
}
#handleFilterInput(event: UUIInputEvent) {
let query = (event.target.value as string) || '';
query = query.toLowerCase();
const query = ((event.target.value as string) || '').toLowerCase();
const result = !query
? this._propertyEditorUIs
: this._propertyEditorUIs.filter((propertyEditorUI) => {
return (
propertyEditorUI.name.toLowerCase().includes(query) || propertyEditorUI.alias.toLowerCase().includes(query)
);
});
: this._propertyEditorUIs.filter(
(propertyEditorUI) =>
propertyEditorUI.name.toLowerCase().includes(query) || propertyEditorUI.alias.toLowerCase().includes(query),
);
this.#groupPropertyEditorUIs(result);
}
#groupPropertyEditorUIs(items: Array<ManifestPropertyEditorUi>) {
// TODO: groupBy is not known by TS yet
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
this._groupedPropertyEditorUIs = Object.groupBy(
result,
(propertyEditorUI: ManifestPropertyEditorUi) => propertyEditorUI.meta.group,
const grouped = Object.groupBy(items, (propertyEditorUi: ManifestPropertyEditorUi) =>
fromCamelCase(propertyEditorUi.meta.group),
);
this._groupedPropertyEditorUIs = Object.keys(grouped)
.sort()
.map((key) => ({ key, items: grouped[key] }));
}
override render() {
return html`
<umb-body-layout headline=${this.localize.term('propertyEditorPicker_openPropertyEditorPicker')}>
<uui-box> ${this._renderFilter()} ${this._renderGrid()} </uui-box>
<uui-box>${this.#renderFilter()} ${this.#renderGrid()}</uui-box>
<div slot="actions">
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
</div>
@@ -84,44 +80,53 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbModalBaseElement<
`;
}
private _renderFilter() {
return html` <uui-input
type="search"
id="filter"
@input="${this.#handleFilterInput}"
placeholder="Type to filter..."
label="Type to filter icons"
${umbFocus()}>
<uui-icon name="search" slot="prepend" id="filter-icon"></uui-icon>
</uui-input>`;
#renderFilter() {
return html`
<uui-input
type="search"
id="filter"
@input=${this.#handleFilterInput}
placeholder=${this.localize.term('placeholders_filter')}
label=${this.localize.term('placeholders_filter')}
${umbFocus()}>
<uui-icon name="search" slot="prepend" id="filter-icon"></uui-icon>
</uui-input>
`;
}
private _renderGrid() {
return html` ${Object.entries(this._groupedPropertyEditorUIs).map(
([key, value]) =>
html` <h4>${key}</h4>
${this._renderGroupItems(value)}`,
)}`;
}
private _renderGroupItems(groupItems: Array<ManifestPropertyEditorUi>) {
return html` <ul id="item-grid">
#renderGrid() {
return html`
${repeat(
groupItems,
(propertyEditorUI) => propertyEditorUI.alias,
(propertyEditorUI) =>
html` <li class="item" ?selected=${this.value.selection.includes(propertyEditorUI.alias)}>
<button type="button" @click="${() => this.#handleClick(propertyEditorUI)}">
<umb-icon name="${propertyEditorUI.meta.icon}" class="icon"></umb-icon>
${propertyEditorUI.meta.label || propertyEditorUI.name}
</button>
</li>`,
this._groupedPropertyEditorUIs,
(group) => group.key,
(group) => html`
<h4>${group.key}</h4>
${this.#renderGroupItems(group.items)}
`,
)}
</ul>`;
`;
}
#renderGroupItems(groupItems: Array<ManifestPropertyEditorUi>) {
return html`
<ul id="item-grid">
${repeat(
groupItems,
(propertyEditorUI) => propertyEditorUI.alias,
(propertyEditorUI) => html`
<li class="item" ?selected=${this.value.selection.includes(propertyEditorUI.alias)}>
<button type="button" @click=${() => this.#handleClick(propertyEditorUI)}>
<umb-icon name=${propertyEditorUI.meta.icon} class="icon"></umb-icon>
${propertyEditorUI.meta.label || propertyEditorUI.name}
</button>
</li>
`,
)}
</ul>
`;
}
static override styles = [
UmbTextStyles,
css`
#filter {
width: 100%;