diff --git a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.context.ts b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.context.ts index 76940d7d5a..f460ac4776 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.context.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.context.ts @@ -8,6 +8,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr import type { ManifestSection } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbExtensionManifestInitializer } from '@umbraco-cms/backoffice/extension-api'; +import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; export class UmbBackofficeContext extends UmbContextBase { #activeSectionAlias = new UmbStringState(undefined); @@ -26,7 +27,13 @@ export class UmbBackofficeContext extends UmbContextBase { this.#allowedSections.setValue([...sections]); }); - this.#getVersion(); + // TODO: We need to ensure this request is called every time the user logs in, but this should be done somewhere across the app and not here [JOV] + this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => { + this.observe(authContext.isAuthorized, (isAuthorized) => { + if (!isAuthorized) return; + this.#getVersion(); + }); + }); } async #getVersion() { diff --git a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts index 179676c253..d292fc9be4 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts @@ -7,6 +7,7 @@ import { } from '@umbraco-cms/backoffice/extension-registry'; import { UmbServerExtensionRegistrator } from '@umbraco-cms/backoffice/extension-api'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; import './components/index.js'; @@ -58,7 +59,15 @@ export class UmbBackofficeElement extends UmbLitElement { umbExtensionsRegistry.registerMany(packageModule.extensions); }); - new UmbServerExtensionRegistrator(this, umbExtensionsRegistry).registerPrivateExtensions(); + const serverExtensions = new UmbServerExtensionRegistrator(this, umbExtensionsRegistry); + + // TODO: We need to ensure this request is called every time the user logs in, but this should be done somewhere across the app and not here [JOV] + this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => { + this.observe(authContext.isAuthorized, (isAuthorized) => { + if (!isAuthorized) return; + serverExtensions.registerPrivateExtensions(); + }); + }); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts index 51ddde3466..509838185f 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts @@ -988,7 +988,7 @@ export const data: Array = [ id: 'dt-integer', parent: null, editorAlias: 'Umbraco.Integer', - editorUiAlias: 'Umb.PropertyEditorUi.Integer', + editorUiAlias: 'Umb.PropertyEditorUi.Number', hasChildren: false, isFolder: false, isDeletable: true, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts index 199908b6de..0b86ba4bf8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts @@ -1,4 +1,4 @@ -import type { UUIColorSwatchesEvent, UUIIconElement } from '@umbraco-cms/backoffice/external/uui'; +import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, state, repeat, query, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -64,12 +64,9 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement + @click=${(e: InputEvent) => this.#changeIcon(e, icon.name)} + @keyup=${(e: KeyboardEvent) => this.#changeIcon(e, icon.name)}> diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts index 8d4b2af962..2ba730a984 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/global-contexts/app-language.context.ts @@ -5,6 +5,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; +import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; // TODO: Make a store for the App Languages. // TODO: Implement default language end-point, in progress at backend team, so we can avoid getting all languages. @@ -28,7 +29,14 @@ export class UmbAppLanguageContext extends UmbContextBase constructor(host: UmbControllerHost) { super(host, UMB_APP_LANGUAGE_CONTEXT); this.#languageCollectionRepository = new UmbLanguageCollectionRepository(this); - this.#observeLanguages(); + + // TODO: We need to ensure this request is called every time the user logs in, but this should be done somewhere across the app and not here [JOV] + this.consumeContext(UMB_AUTH_CONTEXT, (authContext) => { + this.observe(authContext.isAuthorized, (isAuthorized) => { + if (!isAuthorized) return; + this.#observeLanguages(); + }); + }); } setLanguage(unique: string) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.server.data-source.ts index b75fadfff8..19c75cb63a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/repository/media-collection.server.data-source.ts @@ -32,12 +32,15 @@ export class UmbMediaCollectionServerDataSource implements UmbCollectionDataSour const model: UmbMediaCollectionItemModel = { unique: item.id, + entityType: 'media', + contentTypeAlias: item.mediaType.alias, createDate: new Date(variant.createDate), creator: item.creator, icon: item.mediaType.icon, name: variant.name, sortOrder: item.sortOrder, updateDate: new Date(variant.updateDate), + updater: item.creator, // TODO: Check if the `updater` is available for media items. [LK] values: item.values.map((item) => { return { alias: item.alias, value: item.value as string }; }), diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts index 1ae06b64f7..57d968794a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/types.ts @@ -10,11 +10,20 @@ export interface UmbMediaCollectionFilterModel extends UmbCollectionFilterModel export interface UmbMediaCollectionItemModel { unique: string; + entityType: string; + contentTypeAlias: string; createDate: Date; creator?: string | null; icon: string; name: string; sortOrder: number; updateDate: Date; + updater?: string | null; values: Array<{ alias: string; value: string }>; } + +export interface UmbEditableMediaCollectionItemModel { + item: UmbMediaCollectionItemModel; + editPath: string; +} + diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts index 6a77f11469..43201b8839 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts @@ -1,12 +1,17 @@ -import type { UmbMediaCollectionFilterModel, UmbMediaCollectionItemModel } from '../../types.js'; -import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; +import type { UmbMediaCollectionItemModel } from '../../types.js'; +import type { UmbMediaCollectionContext } from '../../media-collection.context.js'; +import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; -import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; +import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal'; @customElement('umb-media-grid-collection-view') export class UmbMediaGridCollectionViewElement extends UmbLitElement { + @state() + private _editMediaPath = ''; + @state() private _items: Array = []; @@ -16,7 +21,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { @state() private _selection: Array = []; - #collectionContext?: UmbDefaultCollectionContext; + #collectionContext?: UmbMediaCollectionContext; constructor() { super(); @@ -24,23 +29,43 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { this.#collectionContext = collectionContext; this.#observeCollectionContext(); }); + + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath('media') + .onSetup(() => { + return { data: { entityType: 'media', preset: {} } }; + }) + .onReject(() => { + this.#collectionContext?.requestCollection(); + }) + .onSubmit(() => { + this.#collectionContext?.requestCollection(); + }) + .observeRouteBuilder((routeBuilder) => { + this._editMediaPath = routeBuilder({}); + }); } #observeCollectionContext() { if (!this.#collectionContext) return; - this.observe(this.#collectionContext.items, (items) => (this._items = items), 'umbCollectionItemsObserver'); + this.observe(this.#collectionContext.loading, (loading) => (this._loading = loading), '_observeLoading'); + + this.observe(this.#collectionContext.items, (items) => (this._items = items), '_observeItems'); this.observe( this.#collectionContext.selection.selection, (selection) => (this._selection = selection), - 'umbCollectionSelectionObserver', + '_observeSelection', ); } - #onOpen(item: UmbMediaCollectionItemModel) { - //TODO: Fix when we have dynamic routing - history.pushState(null, '', 'section/media/workspace/media/edit/' + item.unique); + #onOpen(event: Event, unique: string) { + event.preventDefault(); + event.stopPropagation(); + + const url = this._editMediaPath + UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique }); + window.history.pushState(null, '', url); } #onSelect(item: UmbMediaCollectionItemModel) { @@ -60,26 +85,37 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { } render() { - if (this._loading) { - return html`
`; - } - - if (this._items.length === 0) { - return html`

${this.localize.term('content_listViewNoItems')}

`; - } + return this._items.length === 0 ? this.#renderEmpty() : this.#renderItems(); + } + #renderEmpty() { + if (this._items.length > 0) return nothing; return html` -
- ${repeat( - this._items, - (item) => item.unique, - (item) => this.#renderCard(item), +
+ ${when( + this._loading, + () => html``, + () => html`

${this.localize.term('content_listViewNoItems')}

`, )}
`; } - #renderCard(item: UmbMediaCollectionItemModel) { + #renderItems() { + if (this._items.length === 0) return nothing; + return html` +
+ ${repeat( + this._items, + (item) => item.unique, + (item) => this.#renderItem(item), + )} +
+ ${when(this._loading, () => html``)} + `; + } + + #renderItem(item: UmbMediaCollectionItemModel) { // TODO: Fix the file extension when media items have a file extension. [?] return html` 0} ?selected=${this.#isSelected(item)} - @open=${() => this.#onOpen(item)} + @open=${(event: Event) => this.#onOpen(event, item.unique)} @selected=${() => this.#onSelect(item)} @deselected=${() => this.#onDeselect(item)} class="media-item" diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-name.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-name.element.ts index b1a10fb899..688b2a90c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-name.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-name.element.ts @@ -1,50 +1,32 @@ -import type { UmbMediaCollectionItemModel } from '../../../types.js'; -import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbEditableMediaCollectionItemModel } from '../../../types.js'; +import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal'; import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; +import type { UUIButtonElement } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-media-table-column-name') export class UmbMediaTableColumnNameElement extends UmbLitElement implements UmbTableColumnLayoutElement { - @state() - private _editMediaPath = ''; - - @property({ type: Object, attribute: false }) column!: UmbTableColumn; - - @property({ type: Object, attribute: false }) item!: UmbTableItem; @property({ attribute: false }) - value!: UmbMediaCollectionItemModel; + value!: UmbEditableMediaCollectionItemModel; - constructor() { - super(); - - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath('media') - .onSetup(() => { - return { data: { entityType: 'media', preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editMediaPath = routeBuilder({}); - }); - } - - #onClick(event: Event) { - // TODO: [LK] Review the `stopPropagation` usage, as it causes a page reload. - // But we still need a say to prevent the `umb-table` from triggering a selection event. + #onClick(event: Event & { target: UUIButtonElement }) { + event.preventDefault(); event.stopPropagation(); + window.history.pushState(null, '', event.target.href); } render() { - return html``; + if (!this.value) return nothing; + return html` + + `; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts index a3a4cef9a6..86d2451247 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts @@ -1,6 +1,7 @@ +import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; import type { UmbCollectionColumnConfiguration } from '../../../../../core/collection/types.js'; import type { UmbMediaCollectionFilterModel, UmbMediaCollectionItemModel } from '../../types.js'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; @@ -14,6 +15,8 @@ import type { UmbTableOrderedEvent, UmbTableSelectedEvent, } from '@umbraco-cms/backoffice/components'; +import { UMB_WORKSPACE_MODAL, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal'; +import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/modal'; import './column-layouts/media-table-column-name.element.js'; @@ -51,29 +54,52 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { @state() private _selection: Array = []; - @state() - private _skip: number = 0; - #collectionContext?: UmbDefaultCollectionContext; + #routeBuilder?: UmbModalRouteBuilder; + constructor() { super(); this.consumeContext(UMB_COLLECTION_CONTEXT, (collectionContext) => { this.#collectionContext = collectionContext; - this.#observeCollectionContext(); }); + + this.#registerModalRoute(); + } + + #registerModalRoute() { + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(':entityType') + .onSetup((params) => { + return { data: { entityType: params.entityType, preset: {} } }; + }) + .onReject(() => { + this.#collectionContext?.requestCollection(); + }) + .onSubmit(() => { + this.#collectionContext?.requestCollection(); + }) + .observeRouteBuilder((routeBuilder) => { + this.#routeBuilder = routeBuilder; + + // NOTE: Configuring the observations AFTER the route builder is ready, + // otherwise there is a race condition and `#collectionContext.items` tends to win. [LK] + this.#observeCollectionContext(); + }); } #observeCollectionContext() { if (!this.#collectionContext) return; + this.observe(this.#collectionContext.loading, (loading) => (this._loading = loading), '_observeLoading'); + this.observe( this.#collectionContext.userDefinedProperties, (userDefinedProperties) => { this._userDefinedProperties = userDefinedProperties; this.#createTableHeadings(); }, - 'umbCollectionUserDefinedPropertiesObserver', + '_observeUserDefinedProperties', ); this.observe( @@ -82,7 +108,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { this._items = items; this.#createTableItems(this._items); }, - 'umbCollectionItemsObserver', + '_observeItems', ); this.observe( @@ -90,15 +116,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { (selection) => { this._selection = selection as string[]; }, - 'umbCollectionSelectionObserver', - ); - - this.observe( - this.#collectionContext.pagination.skip, - (skip) => { - this._skip = skip; - }, - 'umbCollectionSkipObserver', + '_observeSelection', ); } @@ -129,15 +147,21 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { const data = this._tableColumns?.map((column) => { + const editPath = this.#routeBuilder + ? this.#routeBuilder({ entityType: item.entityType }) + + UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) + : ''; + return { columnAlias: column.alias, - value: column.elementName ? item : this.#getPropertyValueByAlias(item, column.alias), + value: column.elementName ? { item, editPath } : this.#getPropertyValueByAlias(item, column.alias), }; }) ?? []; return { id: item.unique, icon: item.icon, + entityType: 'media', data: data, }; }); @@ -145,6 +169,8 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { #getPropertyValueByAlias(item: UmbMediaCollectionItemModel, alias: string) { switch (alias) { + case 'contentTypeAlias': + return item.contentTypeAlias; case 'createDate': return item.createDate.toLocaleString(); case 'name': @@ -156,6 +182,8 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { return item.sortOrder; case 'updateDate': return item.updateDate.toLocaleString(); + case 'updater': + return item.updater; default: return item.values.find((value) => value.alias === alias)?.value ?? ''; } @@ -186,23 +214,34 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { } render() { - if (this._loading) { - return html`
`; - } + return this._tableItems.length === 0 ? this.#renderEmpty() : this.#renderItems(); + } - if (this._tableItems.length === 0) { - return html`

${this.localize.term('content_listViewNoItems')}

`; - } + #renderEmpty() { + if (this._tableItems.length > 0) return nothing; + return html` +
+ ${when( + this._loading, + () => html``, + () => html`

${this.localize.term('content_listViewNoItems')}

`, + )} +
+ `; + } + #renderItems() { + if (this._tableItems.length === 0) return nothing; return html` + @selected=${this.#handleSelect} + @deselected=${this.#handleDeselect} + @ordered=${this.#handleOrdering}> + ${when(this._loading, () => html``)} `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/index.ts index 51a8792071..84b18a3c44 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/index.ts @@ -6,6 +6,7 @@ export * from './workspace/index.js'; export * from './reference/index.js'; export * from './components/index.js'; export * from './entity.js'; +export * from './paths.js'; export * from './utils/index.js'; export { UMB_MEDIA_TREE_ALIAS, UMB_MEDIA_TREE_PICKER_MODAL } from './tree/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/paths.ts new file mode 100644 index 0000000000..d5eb6fdfd5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/paths.ts @@ -0,0 +1,3 @@ +import { UmbPathPattern } from '@umbraco-cms/backoffice/router'; + +export const UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ unique: string }>('edit/:unique'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/order-by/order-by.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/order-by/order-by.element.ts index 39ccfe8ba2..977830cf4c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/order-by/order-by.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/order-by/order-by.element.ts @@ -1,34 +1,44 @@ -import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; -import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; -import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; -import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbCollectionColumnConfiguration } from '../../../../core/collection/types.js'; +import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; +import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; /** * @element umb-property-editor-ui-collection-order-by */ @customElement('umb-property-editor-ui-collection-order-by') export class UmbPropertyEditorUICollectionOrderByElement extends UmbLitElement implements UmbPropertyEditorUiElement { - private _value = ''; @property() - public set value(v: string) { - this._value = v; - this._options = this._options.map((option) => (option.value === v ? { ...option, selected: true } : option)); - } - public get value() { - return this._value; - } + public value: string = ''; + + public config?: UmbPropertyEditorConfigCollection; @state() - _options: Array