Added sorting to picker inputs
- Data Type picker - Document Type picker - Entity picker - Language picker - Media Type picker - Stylesheet Rule picker - User picker + code tidy-up, consistency between picker code/markup
This commit is contained in:
@@ -1,14 +1,30 @@
|
||||
import { css, html, customElement, property, state, repeat, when } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { css, html, customElement, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input';
|
||||
import type { UmbUniqueItemModel } from '@umbraco-cms/backoffice/models';
|
||||
|
||||
@customElement('umb-input-entity')
|
||||
export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
// TODO: [LK] Add sort ordering.
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputEntity',
|
||||
itemSelector: 'uui-ref-node',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
@@ -41,14 +57,23 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
|
||||
#max: number = Infinity;
|
||||
|
||||
@property({ attribute: false })
|
||||
getIcon?: (item: any) => string;
|
||||
getIcon?: (item: UmbUniqueItemModel) => string;
|
||||
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
@property({ type: Array })
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext?.setSelection(uniques);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> | undefined {
|
||||
return this.#pickerContext?.getSelection();
|
||||
}
|
||||
|
||||
@property()
|
||||
public set value(value: string) {
|
||||
this.selection = splitStringToArray(value);
|
||||
public set value(uniques: string) {
|
||||
this.selection = splitStringToArray(uniques);
|
||||
}
|
||||
public get value(): string {
|
||||
return this.selection?.join(',') ?? '';
|
||||
@@ -60,18 +85,12 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
|
||||
this.#pickerContext = new ctor(this);
|
||||
this.#observePickerContext();
|
||||
}
|
||||
#pickerContext?: UmbPickerInputContext<any>;
|
||||
|
||||
public set selection(value: Array<string>) {
|
||||
this.#pickerContext?.setSelection(value);
|
||||
}
|
||||
public get selection(): Array<string> | undefined {
|
||||
return this.#pickerContext?.getSelection();
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items?: Array<UmbUniqueItemModel>;
|
||||
|
||||
#pickerContext?: UmbPickerInputContext<any>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
@@ -100,19 +119,8 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
|
||||
this.#pickerContext.min = this.min;
|
||||
this.#pickerContext.max = this.max;
|
||||
|
||||
this.observe(
|
||||
this.#pickerContext.selection,
|
||||
(selection) => (this.value = selection?.join(',') ?? ''),
|
||||
'observeSelection',
|
||||
);
|
||||
|
||||
this.observe(
|
||||
this.#pickerContext.selectedItems,
|
||||
(selectedItems) => {
|
||||
this._items = selectedItems;
|
||||
},
|
||||
'observeSelectedItems',
|
||||
);
|
||||
this.observe(this.#pickerContext.selection, (selection) => (this.value = selection.join(',')), '_observeSelection');
|
||||
this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems), '_observerItems');
|
||||
}
|
||||
|
||||
#openPicker() {
|
||||
@@ -121,6 +129,10 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
|
||||
});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbUniqueItemModel) {
|
||||
this.#pickerContext?.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
@@ -153,12 +165,10 @@ export class UmbInputEntityElement extends UUIFormControlMixin(UmbLitElement, ''
|
||||
if (!item.unique) return;
|
||||
const icon = this.getIcon?.(item) ?? item.icon ?? '';
|
||||
return html`
|
||||
<uui-ref-node name=${item.name}>
|
||||
<uui-ref-node name=${item.name} id=${item.unique}>
|
||||
${when(icon, () => html`<umb-icon slot="icon" name=${icon}></umb-icon>`)}
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext?.requestRemoveItem(item.unique)}
|
||||
label=${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>
|
||||
`;
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
import type { UmbDataTypeItemModel } from '../../repository/item/types.js';
|
||||
import { UmbDataTypePickerContext } from './data-type-input.context.js';
|
||||
import { css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { css, html, customElement, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
// TODO: Rename to 'umb-input-data-type'. [LK]
|
||||
@customElement('umb-data-type-input')
|
||||
export class UmbDataTypeInputElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputDataType',
|
||||
itemSelector: 'uui-ref-node-data-type',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
* @type {number}
|
||||
@@ -54,20 +73,20 @@ export class UmbDataTypeInputElement extends UUIFormControlMixin(UmbLitElement,
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
@property({ type: Array })
|
||||
public set selection(ids: Array<string> | undefined) {
|
||||
this.#pickerContext.setSelection(ids ?? []);
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext.setSelection(uniques ?? []);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> | undefined {
|
||||
public get selection(): Array<string> {
|
||||
return this.#pickerContext.getSelection();
|
||||
}
|
||||
|
||||
@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 set value(uniques: string) {
|
||||
this.selection = splitStringToArray(uniques);
|
||||
}
|
||||
public get value(): string {
|
||||
return this.selection?.join(',') ?? '';
|
||||
return this.selection.join(',');
|
||||
}
|
||||
|
||||
@state()
|
||||
@@ -90,33 +109,58 @@ export class UmbDataTypeInputElement extends UUIFormControlMixin(UmbLitElement,
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
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), '_observerItems');
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
#openPicker() {
|
||||
this.#pickerContext.openPicker({
|
||||
hideTreeRoot: true,
|
||||
});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbDataTypeItemModel) {
|
||||
this.#pickerContext.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max > 0 && this.selection.length >= this.max) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>${this._items?.map((item) => this._renderItem(item))}</uui-ref-list>
|
||||
<uui-button
|
||||
id="add-button"
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${() => this.#pickerContext.openPicker({ hideTreeRoot: true })}
|
||||
label=${this.localize.term('general_choose')}></uui-button>
|
||||
@click=${this.#openPicker}
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderItem(item: UmbDataTypeItemModel) {
|
||||
#renderItems() {
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => this.#renderItem(item),
|
||||
)}
|
||||
</uui-ref-list>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItem(item: UmbDataTypeItemModel) {
|
||||
if (!item.unique) return;
|
||||
return html`
|
||||
<uui-ref-node-data-type name=${item.name}>
|
||||
<uui-ref-node-data-type name=${item.name} id=${item.unique}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.unique)}
|
||||
label=${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-data-type>
|
||||
`;
|
||||
@@ -124,7 +168,7 @@ export class UmbDataTypeInputElement extends UUIFormControlMixin(UmbLitElement,
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#add-button {
|
||||
#btn-add {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
import type { UmbDocumentTypeItemModel } from '../../repository/index.js';
|
||||
import { UmbDocumentTypePickerContext } from './input-document-type.context.js';
|
||||
import {
|
||||
css,
|
||||
html,
|
||||
customElement,
|
||||
property,
|
||||
state,
|
||||
ifDefined,
|
||||
repeat,
|
||||
nothing,
|
||||
} from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { css, html, customElement, property, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbModalRouteRegistrationController, UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@customElement('umb-input-document-type')
|
||||
export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputDocumentType',
|
||||
itemSelector: 'uui-ref-node-document-type',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Limits to only select Element Types
|
||||
* @type {boolean}
|
||||
@@ -73,17 +82,17 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
@property({ type: Array })
|
||||
public set selection(ids: Array<string> | undefined) {
|
||||
this.#pickerContext.setSelection(ids ?? []);
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext.setSelection(uniques);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> {
|
||||
return this.#pickerContext.getSelection();
|
||||
}
|
||||
|
||||
@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 set value(uniques: string) {
|
||||
this.selection = splitStringToArray(uniques);
|
||||
}
|
||||
public get value(): string {
|
||||
return this.selection.join(',');
|
||||
@@ -93,7 +102,7 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
private _items?: Array<UmbDocumentTypeItemModel>;
|
||||
|
||||
@state()
|
||||
private _editDocumentTypePath = '';
|
||||
private _editPath = '';
|
||||
|
||||
#pickerContext = new UmbDocumentTypePickerContext(this);
|
||||
|
||||
@@ -106,7 +115,7 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
return { data: { entityType: 'document-type', preset: {} } };
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this._editDocumentTypePath = routeBuilder({});
|
||||
this._editPath = routeBuilder({});
|
||||
});
|
||||
|
||||
this.addValidator(
|
||||
@@ -121,8 +130,8 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
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), '_observerItems');
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
@@ -130,64 +139,53 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
}
|
||||
|
||||
#openPicker() {
|
||||
if (this.elementTypesOnly) {
|
||||
this.#pickerContext.openPicker({
|
||||
hideTreeRoot: true,
|
||||
pickableFilter: (x) => x.isElement,
|
||||
});
|
||||
} else {
|
||||
this.#pickerContext.openPicker({
|
||||
hideTreeRoot: true,
|
||||
});
|
||||
}
|
||||
this.#pickerContext.openPicker({
|
||||
hideTreeRoot: true,
|
||||
pickableFilter: this.elementTypesOnly ? (x) => x.isElement : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbDocumentTypeItemModel) {
|
||||
this.#pickerContext.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` ${this.#renderItems()} ${this.#renderAddButton()} `;
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list
|
||||
>${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => this.#renderItem(item),
|
||||
)}</uui-ref-list
|
||||
>
|
||||
`;
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max > 0 && this.selection.length >= this.max) return nothing;
|
||||
return html`
|
||||
<uui-button
|
||||
id="add-button"
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => this.#renderItem(item),
|
||||
)}
|
||||
</uui-ref-list>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItem(item: UmbDocumentTypeItemModel) {
|
||||
if (!item.unique) return;
|
||||
const href = `${this._editPath}edit/${item.unique}`;
|
||||
return html`
|
||||
<uui-ref-node-document-type name=${ifDefined(item.name)}>
|
||||
<uui-ref-node-document-type name=${item.name} id=${item.unique}>
|
||||
${this.#renderIcon(item)}
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
compact
|
||||
href=${this._editDocumentTypePath + 'edit/' + item.unique}
|
||||
label=${this.localize.term('general_edit') + ` ${item.name}`}>
|
||||
<uui-icon name="icon-edit"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.unique)}
|
||||
label="Edit Document Type ${item.name}">
|
||||
<uui-icon name="icon-trash"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button href=${href} label=${this.localize.term('general_open')}></uui-button>
|
||||
<uui-button @click=${() => this.#removeItem(item)} label=${this.localize.term('general_remove')}></uui-button>
|
||||
</uui-action-bar>
|
||||
</uui-ref-node-document-type>
|
||||
`;
|
||||
@@ -200,7 +198,7 @@ export class UmbInputDocumentTypeElement extends UUIFormControlMixin(UmbLitEleme
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#add-button {
|
||||
#btn-add {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -1,12 +1,30 @@
|
||||
import type { UmbLanguageItemModel } from '../../repository/index.js';
|
||||
import { UmbLanguagePickerContext } from './input-language.context.js';
|
||||
import { css, html, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { css, html, customElement, property, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@customElement('umb-input-language')
|
||||
export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputLanguage',
|
||||
itemSelector: 'uui-ref-node',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
* @type {number}
|
||||
@@ -56,8 +74,10 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
@property({ type: Object, attribute: false })
|
||||
public filter: (language: UmbLanguageItemModel) => boolean = () => true;
|
||||
|
||||
@property({ type: Array })
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext.setSelection(uniques);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> {
|
||||
return this.#pickerContext.getSelection();
|
||||
@@ -65,7 +85,6 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
|
||||
@property()
|
||||
public set value(uniques: 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(uniques);
|
||||
}
|
||||
public get value(): string {
|
||||
@@ -92,8 +111,8 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
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), '_observerItems');
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
@@ -106,14 +125,35 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbLanguageItemModel) {
|
||||
this.#pickerContext.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max > 0 && this.selection.length >= this.max) return nothing;
|
||||
return html`
|
||||
<uui-ref-list> ${this._items.map((item) => this.#renderItem(item))} </uui-ref-list>
|
||||
<uui-button
|
||||
id="add-button"
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label=${this.localize.term('general_choose')}></uui-button>
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => this.#renderItem(item),
|
||||
)}
|
||||
</uui-ref-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -121,11 +161,9 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
if (!item.unique) return;
|
||||
return html`
|
||||
<!-- TODO: add language ref element -->
|
||||
<uui-ref-node name=${ifDefined(item.name === null ? undefined : item.name)} detail=${ifDefined(item.unique)}>
|
||||
<uui-ref-node name=${item.name} id=${item.unique} detail=${item.unique}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.unique)}
|
||||
label=${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>
|
||||
`;
|
||||
@@ -133,7 +171,7 @@ export class UmbInputLanguageElement extends UUIFormControlMixin(UmbLitElement,
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#add-button {
|
||||
#btn-add {
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
import type { UmbMediaTypeItemModel } from '../../repository/index.js';
|
||||
import { UmbMediaTypePickerContext } from './input-media-type.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 { css, html, customElement, property, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbModalRouteRegistrationController, UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@customElement('umb-input-media-type')
|
||||
export class UmbInputMediaTypeElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputMediaType',
|
||||
itemSelector: 'uui-ref-node-document-type',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
* @type {number}
|
||||
@@ -53,30 +72,43 @@ export class UmbInputMediaTypeElement extends UUIFormControlMixin(UmbLitElement,
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
public set selection(ids: Array<string>) {
|
||||
this.#pickerContext.setSelection(ids);
|
||||
@property({ type: Array })
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext.setSelection(uniques);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> {
|
||||
return this.#pickerContext.getSelection();
|
||||
}
|
||||
|
||||
@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 set value(uniques: string) {
|
||||
this.selection = splitStringToArray(uniques);
|
||||
}
|
||||
public get value() {
|
||||
public get value(): string {
|
||||
return this.selection.join(',');
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items?: Array<UmbMediaTypeItemModel>;
|
||||
|
||||
@state()
|
||||
private _editPath = '';
|
||||
|
||||
#pickerContext = new UmbMediaTypePickerContext(this);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL)
|
||||
.addAdditionalPath('media-type')
|
||||
.onSetup(() => {
|
||||
return { data: { entityType: 'media-type', preset: {} } };
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this._editPath = routeBuilder({});
|
||||
});
|
||||
|
||||
this.addValidator(
|
||||
'rangeUnderflow',
|
||||
() => this.minMessage,
|
||||
@@ -89,8 +121,8 @@ export class UmbInputMediaTypeElement extends UUIFormControlMixin(UmbLitElement,
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
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), '_observerItems');
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
@@ -103,12 +135,27 @@ export class UmbInputMediaTypeElement extends UUIFormControlMixin(UmbLitElement,
|
||||
});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbMediaTypeItemModel) {
|
||||
this.#pickerContext.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` ${this.#renderItems()} ${this.#renderAddButton()} `;
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max > 0 && this.selection.length >= this.max) return nothing;
|
||||
return html`
|
||||
<uui-button
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items) return;
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
@@ -120,26 +167,15 @@ export class UmbInputMediaTypeElement extends UUIFormControlMixin(UmbLitElement,
|
||||
`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max === 1 && this.selection.length >= this.max) return;
|
||||
return html`
|
||||
<uui-button
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItem(item: UmbMediaTypeItemModel) {
|
||||
if (!item.unique) return;
|
||||
const href = `${this._editPath}edit/${item.unique}`;
|
||||
return html`
|
||||
<uui-ref-node-document-type name=${ifDefined(item.name)}>
|
||||
<uui-ref-node-document-type name=${item.name} id=${item.unique}>
|
||||
${this.#renderIcon(item)}
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.unique)}
|
||||
label="${this.localize.term('general_remove')} ${item.name}"></uui-button>
|
||||
<uui-button href=${href} label=${this.localize.term('general_open')}></uui-button>
|
||||
<uui-button @click=${() => this.#removeItem(item)} label=${this.localize.term('general_remove')}></uui-button>
|
||||
</uui-action-bar>
|
||||
</uui-ref-node-document-type>
|
||||
`;
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
import type { UmbStylesheetRule } from '../../types.js';
|
||||
import { UMB_STYLESHEET_RULE_SETTINGS_MODAL } from './stylesheet-rule-settings-modal.token.js';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { css, html, customElement, repeat, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
// TODO: add sorting when we have a generic sorting component/functionality for ref lists
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
@customElement('umb-stylesheet-rule-input')
|
||||
export class UmbStylesheetRuleInputElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
#sorter = new UmbSorterController<UmbStylesheetRule>(this, {
|
||||
getUniqueOfElement: (element) => element.id,
|
||||
getUniqueOfModel: (modelEntry) => modelEntry.name,
|
||||
identifier: 'Umb.SorterIdentifier.InputStylesheetRule',
|
||||
itemSelector: 'umb-stylesheet-rule-ref',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.rules = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
@property({ type: Array, attribute: false })
|
||||
rules: UmbStylesheetRule[] = [];
|
||||
|
||||
@@ -57,6 +68,10 @@ export class UmbStylesheetRuleInputElement extends UUIFormControlMixin(UmbLitEle
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
};
|
||||
|
||||
firstUpdated() {
|
||||
this.#sorter.setModel(this.rules);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
@@ -64,16 +79,20 @@ export class UmbStylesheetRuleInputElement extends UUIFormControlMixin(UmbLitEle
|
||||
this.rules,
|
||||
(rule, index) => rule.name + index,
|
||||
(rule, index) => html`
|
||||
<umb-stylesheet-rule-ref name=${rule.name} detail=${rule.selector}>
|
||||
<umb-stylesheet-rule-ref name=${rule.name} id=${rule.name} detail=${rule.selector}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button @click=${() => this.#editRule(rule, index)} label="Edit ${rule.name}">Edit</uui-button>
|
||||
<uui-button @click=${() => this.#removeRule(rule)} label="Remove ${rule.name}">Remove</uui-button>
|
||||
<uui-button
|
||||
label=${this.localize.term('general_edit')}
|
||||
@click=${() => this.#editRule(rule, index)}></uui-button>
|
||||
<uui-button
|
||||
label=${this.localize.term('general_remove')}
|
||||
@click=${() => this.#removeRule(rule)}></uui-button>
|
||||
</uui-action-bar>
|
||||
</umb-stylesheet-rule-ref>
|
||||
`,
|
||||
)}
|
||||
</uui-ref-list>
|
||||
<uui-button label="Add rule" look="placeholder" @click=${this.#appendRule}>Add</uui-button>
|
||||
<uui-button label=${this.localize.term('general_add')} look="placeholder" @click=${this.#appendRule}></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
import type { UmbUserItemModel } from '../../repository/index.js';
|
||||
import { UmbUserPickerContext } from './user-input.context.js';
|
||||
import { css, html, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
|
||||
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
// TODO: Shall we rename to 'umb-input-user'? [LK]
|
||||
@customElement('umb-user-input')
|
||||
export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '') {
|
||||
// TODO: [LK] Add sorting!
|
||||
#sorter = new UmbSorterController<string>(this, {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.id;
|
||||
},
|
||||
getUniqueOfModel: (modelEntry) => {
|
||||
return modelEntry;
|
||||
},
|
||||
identifier: 'Umb.SorterIdentifier.InputUser',
|
||||
itemSelector: 'uui-ref-node-user',
|
||||
containerSelector: 'uui-ref-list',
|
||||
onChange: ({ model }) => {
|
||||
this.selection = model;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
@@ -55,17 +72,18 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '')
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
@property({ type: Array })
|
||||
public set selection(uniques: Array<string>) {
|
||||
this.#pickerContext.setSelection(uniques);
|
||||
this.#sorter.setModel(uniques);
|
||||
}
|
||||
public get selection(): Array<string> {
|
||||
return this.#pickerContext.getSelection();
|
||||
}
|
||||
public set selection(ids: Array<string>) {
|
||||
this.#pickerContext.setSelection(ids);
|
||||
}
|
||||
|
||||
@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 set value(uniques: string) {
|
||||
this.selection = splitStringToArray(uniques);
|
||||
}
|
||||
public get value(): string {
|
||||
return this.selection.join(',');
|
||||
@@ -91,16 +109,8 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '')
|
||||
() => !!this.max && this.#pickerContext.getSelection().length > this.max,
|
||||
);
|
||||
|
||||
this.observe(
|
||||
this.#pickerContext.selection,
|
||||
(selection) => (this.value = selection.join(',')),
|
||||
'umbUserInputSelectionObserver',
|
||||
);
|
||||
this.observe(
|
||||
this.#pickerContext.selectedItems,
|
||||
(selectedItems) => (this._items = selectedItems),
|
||||
'umbUserInputItemsObserver',
|
||||
);
|
||||
this.observe(this.#pickerContext.selection, (selection) => (this.value = selection.join(',')), '_observeSelection');
|
||||
this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems), '_observerItems');
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
@@ -111,35 +121,49 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '')
|
||||
this.#pickerContext.openPicker({});
|
||||
}
|
||||
|
||||
#removeItem(item: UmbUserItemModel) {
|
||||
this.#pickerContext.requestRemoveItem(item.unique);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`${this.#renderItems()} ${this.#renderAddButton()}`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max > 0 && this.selection.length >= this.max) return nothing;
|
||||
return html`
|
||||
<uui-ref-list> ${this._items?.map((item) => this.#renderItem(item))} </uui-ref-list>
|
||||
${this.#renderAddButton()}
|
||||
<uui-button
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label="${this.localize.term('general_choose')}"></uui-button>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items) return nothing;
|
||||
return html`
|
||||
<uui-ref-list>
|
||||
${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => this.#renderItem(item),
|
||||
)}
|
||||
</uui-ref-list>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderItem(item: UmbUserItemModel) {
|
||||
if (!item.unique) return;
|
||||
return html`
|
||||
<uui-ref-node-user name=${item.name}>
|
||||
<uui-ref-node-user name=${item.name} id=${item.unique}>
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button
|
||||
@click=${() => this.#pickerContext.requestRemoveItem(item.unique)}
|
||||
label=${this.localize.term('general_remove')}></uui-button>
|
||||
<uui-button label=${this.localize.term('general_remove')} @click=${() => this.#removeItem(item)}></uui-button>
|
||||
</uui-action-bar>
|
||||
</uui-ref-node-user>
|
||||
`;
|
||||
}
|
||||
|
||||
#renderAddButton() {
|
||||
if (this.max === 1 && this.selection.length >= this.max) return nothing;
|
||||
return html`<uui-button
|
||||
id="btn-add"
|
||||
look="placeholder"
|
||||
@click=${this.#openPicker}
|
||||
label=${this.localize.term('general_add')}></uui-button>`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
#btn-add {
|
||||
|
||||
Reference in New Issue
Block a user