diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 66b75fa2bc2f..5465bf79c530 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -89,6 +89,7 @@ "./property-action": "./dist-cms/packages/core/property-action/index.js", "./property-editor-data-source": "./dist-cms/packages/core/property-editor-data-source/index.js", "./property-editor": "./dist-cms/packages/core/property-editor/index.js", + "./property-value-presentation": "./dist-cms/packages/core/property-value-presentation/index.js", "./property-type": "./dist-cms/packages/content/property-type/index.js", "./property": "./dist-cms/packages/core/property/index.js", "./recycle-bin": "./dist-cms/packages/core/recycle-bin/index.js", diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/index.ts new file mode 100644 index 000000000000..f6294fdcc7fe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/index.ts @@ -0,0 +1,2 @@ +export { UmbPropertyValuePresentationBaseElement } from './property-value-presentation-base.element.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation-base.element.ts new file mode 100644 index 000000000000..e95024494c6d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation-base.element.ts @@ -0,0 +1,7 @@ +import { property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +export abstract class UmbPropertyValuePresentationBaseElement extends UmbLitElement { + @property({ type: Object }) + value?: TValue; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation.extension.ts new file mode 100644 index 000000000000..b7a5ac3d95fc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/property-value-presentation.extension.ts @@ -0,0 +1,12 @@ +import type { ManifestElement } from '@umbraco-cms/backoffice/extension-api'; + +export interface ManifestPropertyValuePresentation extends ManifestElement { + type: 'propertyValuePresentation'; + forPropertyEditorSchemaAlias: string | Array; +} + +declare global { + interface UmbExtensionManifestMap { + umbPropertyValuePresentation: ManifestPropertyValuePresentation; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/types.ts new file mode 100644 index 000000000000..e3f62b2daf8b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-value-presentation/types.ts @@ -0,0 +1 @@ +export type { ManifestPropertyValuePresentation } from './property-value-presentation.extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts b/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts index 5ba008ff3481..1278769689a1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts @@ -51,6 +51,7 @@ export default defineConfig({ 'property-action/index': './property-action/index.ts', 'property-editor-data-source/index': './property-editor-data-source/index.ts', 'property-editor/index': './property-editor/index.ts', + 'property-value-presentation/index': './property-value-presentation/index.ts', 'property/index': './property/index.ts', 'recycle-bin/index': './recycle-bin/index.ts', 'repository/index': './repository/index.ts', diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection-item-data-resolver.ts new file mode 100644 index 000000000000..81d6a225bf39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection-item-data-resolver.ts @@ -0,0 +1,51 @@ +import { UmbDocumentItemDataResolver } from '../item/document-item-data-resolver.js'; +import type { UmbDocumentCollectionItemModel, UmbDocumentCollectionItemPropertyValueModel } from './types.js'; +import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbItemDataResolver } from '@umbraco-cms/backoffice/entity-item'; + +export class UmbDocumentCollectionItemDataResolver + extends UmbDocumentItemDataResolver + implements UmbItemDataResolver +{ + getPropertyByAlias(alias: string): UmbDocumentCollectionItemPropertyValueModel | undefined { + const item = this.getData(); + const culture = this.getCulture(); + const prop = item?.values.find((x) => x.alias === alias && (!x.culture || x.culture === culture)); + return prop; + } + + getSystemValue(alias: string): string | number | null | undefined { + const item = this.getData(); + switch (alias) { + case 'contentTypeAlias': + return item?.documentType.alias; + + case 'createDate': { + const variant = this._getCurrentVariant(); + return variant?.createDate?.toLocaleString(); + } + + case 'creator': + case 'owner': + return item?.creator; + + case 'published': { + const variant = this._getCurrentVariant(); + return variant?.state !== DocumentVariantStateModel.DRAFT ? 'True' : 'False'; + } + + case 'sortOrder': + return item?.sortOrder; + + case 'updateDate': { + const variant = this._getCurrentVariant(); + return variant?.updateDate?.toLocaleString(); + } + case 'updater': + return item?.updater; + + default: + return null; + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts index 18c8a5bcf854..3ddcc0bfeb0f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/document-collection.context.ts @@ -1,10 +1,10 @@ -import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from './types.js'; import { UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS } from './constants.js'; +import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from './types.js'; import { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_VARIANT_CONTEXT } from '@umbraco-cms/backoffice/variant'; -import { UmbStringState } from '@umbraco-cms/backoffice/observable-api'; import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +import { UmbStringState } from '@umbraco-cms/backoffice/observable-api'; +import { UMB_VARIANT_CONTEXT } from '@umbraco-cms/backoffice/variant'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; export class UmbDocumentCollectionContext extends UmbDefaultCollectionContext< UmbDocumentCollectionItemModel, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts index 816687f36b9f..a666e8f112f3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts @@ -52,6 +52,7 @@ export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataS flags: item.flags, values: item.values.map((item) => { return { + editorAlias: item.editorAlias, alias: item.alias, culture: item.culture ?? undefined, segment: item.segment ?? undefined, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts index de40f79a2041..d6aa8219c962 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts @@ -27,10 +27,18 @@ export interface UmbDocumentCollectionItemModel extends UmbEntityWithFlags { sortOrder: number; unique: string; updater?: string | null; - values: Array<{ alias: string; culture?: string; segment?: string; value: string }>; + values: Array; variants: Array; } +export interface UmbDocumentCollectionItemPropertyValueModel { + alias: string; + editorAlias: string; + culture?: string; + segment?: string; + value: string; +} + export interface UmbEditableDocumentCollectionItemModel { item: UmbDocumentCollectionItemModel; editPath: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-card.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-card.element.ts index 0178ecd6258c..60c7c27361cf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-card.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-card.element.ts @@ -1,26 +1,21 @@ -import { UmbDocumentItemDataResolver } from '../../../item/document-item-data-resolver.js'; +import { UmbDocumentCollectionItemDataResolver } from '../../document-collection-item-data-resolver.js'; import type { UmbDocumentCollectionItemModel } from '../../types.js'; -import { css, customElement, html, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; -import { fromCamelCase } from '@umbraco-cms/backoffice/utils'; +import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { fromCamelCase, stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils'; import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; import { UUICardContentNodeElement } from '@umbraco-cms/backoffice/external/uui'; +import type { ManifestPropertyValuePresentation } from '@umbraco-cms/backoffice/property-value-presentation'; import type { UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection'; import type { UUIInterfaceColor } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-document-grid-collection-card') export class UmbDocumentGridCollectionCardElement extends UmbElementMixin(UUICardContentNodeElement) { - #resolver = new UmbDocumentItemDataResolver(this); - - @state() - private _createDate?: Date; + #resolver = new UmbDocumentCollectionItemDataResolver(this); @state() private _state?: string; - @state() - private _updateDate?: Date; - @property({ attribute: false }) columns?: Array; @@ -41,37 +36,6 @@ export class UmbDocumentGridCollectionCardElement extends UmbElementMixin(UUICar this.#resolver.observe(this.#resolver.name, (name) => (this.name = name || '')); this.#resolver.observe(this.#resolver.state, (state) => (this._state = state || '')); - this.#resolver.observe(this.#resolver.createDate, (createDate) => (this._createDate = createDate)); - this.#resolver.observe(this.#resolver.updateDate, (updateDate) => (this._updateDate = updateDate)); - } - - #getPropertyValueByAlias(alias: string) { - switch (alias) { - case 'contentTypeAlias': - return this.item.documentType.alias; - case 'createDate': - return this._createDate?.toLocaleString(); - case 'creator': - case 'owner': - return this.item.creator; - case 'name': - return this.name; - case 'state': - return this._state ? fromCamelCase(this._state) : ''; - case 'published': - return this._state !== DocumentVariantStateModel.DRAFT ? 'True' : 'False'; - case 'sortOrder': - return this.item.sortOrder; - case 'updateDate': - return this._updateDate?.toLocaleString(); - case 'updater': - return this.item.updater; - default: { - const culture = this.#resolver.getCulture(); - const prop = this.item.values.find((x) => x.alias === alias && (!x.culture || x.culture === culture)); - return prop?.value ?? ''; - } - } } #getStateTagConfig(): { color: UUIInterfaceColor; label: string } | undefined { @@ -121,14 +85,37 @@ export class UmbDocumentGridCollectionCardElement extends UmbElementMixin(UUICar } #renderProperty(column: UmbCollectionColumnConfiguration) { - const value = this.#getPropertyValueByAlias(column.alias); + let value: string | number | null | undefined; + let editorAlias: string | null | undefined; + + if (column.isSystem) { + value = this.#resolver.getSystemValue(column.alias); + } else { + const prop = this.#resolver.getPropertyByAlias(column.alias); + editorAlias = prop?.editorAlias; + value = prop?.value; + } + return html`
  • ${this.localize.string(column.header)}: ${when( column.nameTemplate, () => html``, - () => html`${value}`, + () => + when( + editorAlias, + (schemaAlias) => html` + + stringOrStringArrayContains(m.forPropertyEditorSchemaAlias, schemaAlias)} + .props=${{ value }}> + ${value ?? nothing} + + `, + () => (value ? html`${value}` : nothing), + ), )}
  • `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts index 6f8fdb04fabb..63d78ef93245 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/grid/document-grid-collection-view.element.ts @@ -3,8 +3,8 @@ import { UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../../types.js'; import { css, customElement, html, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbDefaultCollectionContext, UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbDefaultCollectionContext, UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection'; import '@umbraco-cms/backoffice/ufm'; import './document-grid-collection-card.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-property-value.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-property-value.element.ts index 1c616c5d72dc..3e06eb50e84f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-property-value.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-property-value.element.ts @@ -1,22 +1,14 @@ +import { UmbDocumentCollectionItemDataResolver } from '../../../document-collection-item-data-resolver.js'; import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; -import { UmbDocumentItemDataResolver } from '../../../../item/index.js'; -import { customElement, html, nothing, property, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, nothing, property, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { ManifestPropertyValuePresentation } from '@umbraco-cms/backoffice/property-value-presentation'; +import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils'; @customElement('umb-document-table-column-property-value') export class UmbDocumentTableColumnPropertyValueElement extends UmbLitElement implements UmbTableColumnLayoutElement { - #resolver = new UmbDocumentItemDataResolver(this); - - @state() - private _createDate?: Date; - - @state() - private _state?: string; - - @state() - private _updateDate?: Date; + #resolver = new UmbDocumentCollectionItemDataResolver(this); column!: UmbTableColumn; item!: UmbTableItem; @@ -34,48 +26,27 @@ export class UmbDocumentTableColumnPropertyValueElement extends UmbLitElement im } #value!: UmbEditableDocumentCollectionItemModel; - constructor() { - super(); - - this.#resolver.observe(this.#resolver.state, (state) => (this._state = state || '')); - this.#resolver.observe(this.#resolver.createDate, (createDate) => (this._createDate = createDate)); - this.#resolver.observe(this.#resolver.updateDate, (updateDate) => (this._updateDate = updateDate)); - } + override render() { + if (!this.value?.item) return nothing; + const prop = this.#resolver.getPropertyByAlias(this.column.alias); + const props = { value: prop?.value ?? '' }; - #getPropertyValueByAlias() { - const alias = this.column.alias; - const item = this.value.item; - switch (alias) { - case 'contentTypeAlias': - return item.documentType.alias; - case 'createDate': - return this._createDate?.toLocaleString(); - case 'creator': - case 'owner': - return item.creator; - case 'published': - return this._state !== DocumentVariantStateModel.DRAFT ? 'True' : 'False'; - case 'sortOrder': - return item.sortOrder; - case 'updateDate': - return this._updateDate?.toLocaleString(); - case 'updater': - return item.updater; - default: { - const culture = this.#resolver.getCulture(); - const prop = item.values.find((x) => x.alias === alias && (!x.culture || x.culture === culture)); - return prop?.value ?? ''; - } + if (this.column.labelTemplate) { + return html``; } - } - override render() { - if (!this.value) return nothing; - const value = this.#getPropertyValueByAlias(); return when( - this.column.labelTemplate, - () => html``, - () => html`${value}`, + prop?.editorAlias, + (schemaAlias) => html` + + stringOrStringArrayContains(m.forPropertyEditorSchemaAlias, schemaAlias)} + .props=${props}> + ${prop?.value ?? nothing} + + `, + () => (prop?.value ? html`${prop.value}` : nothing), ); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-system-value.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-system-value.element.ts new file mode 100644 index 000000000000..674ddeba45f6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-system-value.element.ts @@ -0,0 +1,43 @@ +import { UmbDocumentCollectionItemDataResolver } from '../../../document-collection-item-data-resolver.js'; +import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; +import { customElement, html, nothing, property, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; + +@customElement('umb-document-table-column-system-value') +export class UmbDocumentTableColumnSystemValueElement extends UmbLitElement implements UmbTableColumnLayoutElement { + #resolver = new UmbDocumentCollectionItemDataResolver(this); + + column!: UmbTableColumn; + item!: UmbTableItem; + + @property({ attribute: false }) + public set value(value: UmbEditableDocumentCollectionItemModel) { + this.#value = value; + if (value.item) { + this.#resolver.setData(value.item); + } + } + public get value(): UmbEditableDocumentCollectionItemModel { + return this.#value; + } + #value!: UmbEditableDocumentCollectionItemModel; + + override render() { + if (!this.value) return nothing; + const value = this.#resolver.getSystemValue(this.column.alias); + return when( + this.column.labelTemplate, + () => html``, + () => html`${value}`, + ); + } +} + +export default UmbDocumentTableColumnSystemValueElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-table-column-system-value': UmbDocumentTableColumnSystemValueElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index 98d0bd7138c1..90310d71f652 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -20,6 +20,7 @@ import './column-layouts/document-entity-actions-table-column-view.element.js'; import './column-layouts/document-table-column-name.element.js'; import './column-layouts/document-table-column-property-value.element.js'; import './column-layouts/document-table-column-state.element.js'; +import './column-layouts/document-table-column-system-value.element.js'; @customElement('umb-document-table-collection-view') export class UmbDocumentTableCollectionViewElement extends UmbLitElement { @@ -106,7 +107,9 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { return { name: this.localize.string(item.header), alias: item.alias, - elementName: item.elementName || 'umb-document-table-column-property-value', + elementName: + item.elementName || + (item.isSystem ? 'umb-document-table-column-system-value' : 'umb-document-table-column-property-value'), labelTemplate: item.nameTemplate, allowSorting: true, }; @@ -117,6 +120,8 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { ...userColumns, { name: '', alias: 'entityActions', align: 'right' }, ]; + } else { + this._tableColumns = [...this.#systemColumns, { name: '', alias: 'entityActions', align: 'right' }]; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index f27afee63bf7..6706d67ad42a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -1,19 +1,20 @@ import { UmbDocumentVariantState } from '../types.js'; import type { UmbDocumentItemModel } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbEntityFlag } from '@umbraco-cms/backoffice/entity-flag'; -import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbArrayState, UmbBasicState, UmbBooleanState, UmbObjectState, UmbStringState, - type Observable, } from '@umbraco-cms/backoffice/observable-api'; -import { type UmbVariantContext, UMB_VARIANT_CONTEXT } from '@umbraco-cms/backoffice/variant'; +import { UMB_VARIANT_CONTEXT } from '@umbraco-cms/backoffice/variant'; +import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { Observable } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbEntityFlag } from '@umbraco-cms/backoffice/entity-flag'; import type { UmbItemDataResolver } from '@umbraco-cms/backoffice/entity-item'; +import type { UmbVariantContext } from '@umbraco-cms/backoffice/variant'; type UmbDocumentItemDataResolverModel = Omit; @@ -228,7 +229,7 @@ export class UmbDocumentItemDataResolver { - return { alias: item.alias, value: item.value as string }; + return { alias: item.alias, editorAlias: item.editorAlias, value: item.value as string }; }), flags: item.flags, }; 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 9cb9332e6072..a800fdf60b7e 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 @@ -21,7 +21,7 @@ export interface UmbMediaCollectionItemModel extends UmbEntityWithFlags { sortOrder?: number; updateDate: Date; updater?: string | null; - values?: Array<{ alias: string; value: string }>; + values?: Array<{ alias: string; editorAlias: string; value: string }>; url?: string; status?: UmbFileDropzoneItemStatus; /** 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 1a4cf709ed8b..66f9eeff31d8 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,12 @@ 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 { UMB_MEDIA_COLLECTION_CONTEXT } from '../../media-collection.context-token.js'; import { UMB_MEDIA_PLACEHOLDER_ENTITY_TYPE } from '../../../entity.js'; +import type { UmbMediaCollectionContext } from '../../media-collection.context.js'; +import type { UmbMediaCollectionItemModel } from '../../types.js'; import { css, customElement, html, ifDefined, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbFileDropzoneItemStatus } from '@umbraco-cms/backoffice/dropzone'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import '@umbraco-cms/backoffice/imaging'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-entity-actions-table-column-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-entity-actions-table-column-view.element.ts new file mode 100644 index 000000000000..6f5810cb660f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-entity-actions-table-column-view.element.ts @@ -0,0 +1,24 @@ +import type { UmbMediaCollectionItemModel } from '../../../types.js'; +import { customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +@customElement('umb-media-entity-actions-table-column-view') +export class UmbMediaEntityActionsTableColumnViewElement extends UmbLitElement { + @property({ attribute: false }) + value?: UmbMediaCollectionItemModel; + + override render() { + if (!this.value) return nothing; + + return html` + + + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-entity-actions-table-column-view': UmbMediaEntityActionsTableColumnViewElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-property-value.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-property-value.element.ts new file mode 100644 index 000000000000..7d03f5b6bb49 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-property-value.element.ts @@ -0,0 +1,55 @@ +import type { UmbEditableMediaCollectionItemModel } from '../../../types.js'; +import { customElement, html, nothing, property, when } from '@umbraco-cms/backoffice/external/lit'; +import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { ManifestPropertyValuePresentation } from '@umbraco-cms/backoffice/property-value-presentation'; +import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; + +@customElement('umb-media-table-column-property-value') +export class UmbMediaTableColumnPropertyValueElement extends UmbLitElement implements UmbTableColumnLayoutElement { + column!: UmbTableColumn; + item!: UmbTableItem; + + @property({ attribute: false }) + value!: UmbEditableMediaCollectionItemModel; + + #getPropertyByAlias() { + const alias = this.column.alias; + const item = this.value.item; + const prop = item.values?.find((x) => x.alias === alias); + + return prop; + } + + override render() { + if (!this.value?.item) return nothing; + const prop = this.#getPropertyByAlias(); + const props = { value: prop?.value ?? '' }; + + if (this.column.labelTemplate) { + return html``; + } + + return when( + prop?.editorAlias, + (schemaAlias) => html` + + stringOrStringArrayContains(m.forPropertyEditorSchemaAlias, schemaAlias)} + .props=${props}> + ${prop?.value ?? nothing} + + `, + () => (prop?.value ? html`${prop.value}` : nothing), + ); + } +} + +export default UmbMediaTableColumnPropertyValueElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-table-column-property-value': UmbMediaTableColumnPropertyValueElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-system-value.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-system-value.element.ts new file mode 100644 index 000000000000..0809893306e6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/table/column-layouts/media-table-column-system-value.element.ts @@ -0,0 +1,55 @@ +import type { UmbEditableMediaCollectionItemModel } from '../../../types.js'; +import { customElement, html, nothing, property, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; + +@customElement('umb-media-table-column-system-value') +export class UmbMediaTableColumnSystemValueElement extends UmbLitElement implements UmbTableColumnLayoutElement { + column!: UmbTableColumn; + item!: UmbTableItem; + + @property({ attribute: false }) + value!: UmbEditableMediaCollectionItemModel; + + #getPropertyValueByAlias() { + const alias = this.column.alias; + const item = this.value.item; + switch (alias) { + case 'contentTypeAlias': + return item.contentTypeAlias; + case 'createDate': + return item.createDate.toLocaleString(); + case 'name': + return item.name; + case 'creator': + case 'owner': + return item.creator; + case 'sortOrder': + return item.sortOrder; + case 'updateDate': + return item.updateDate.toLocaleString(); + case 'updater': + return item.updater; + default: + return item.values?.find((value) => value.alias === alias)?.value ?? ''; + } + } + + override render() { + if (!this.value) return nothing; + const value = this.#getPropertyValueByAlias(); + return when( + this.column.labelTemplate, + () => html``, + () => html`${value}`, + ); + } +} + +export default UmbMediaTableColumnSystemValueElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-table-column-system-value': UmbMediaTableColumnSystemValueElement; + } +} 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 02afe0e68005..e1603d0bafe4 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 @@ -15,7 +15,10 @@ import type { UmbTableSelectedEvent, } from '@umbraco-cms/backoffice/components'; +import './column-layouts/media-entity-actions-table-column-view.element.js'; import './column-layouts/media-table-column-name.element.js'; +import './column-layouts/media-table-column-property-value.element.js'; +import './column-layouts/media-table-column-system-value.element.js'; @customElement('umb-media-table-collection-view') export class UmbMediaTableCollectionViewElement extends UmbLitElement { @@ -95,7 +98,9 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { return { name: this.localize.string(item.header), alias: item.alias, - elementName: item.elementName, + elementName: + item.elementName || + (item.isSystem ? 'umb-media-table-column-system-value' : 'umb-media-table-column-property-value'), labelTemplate: item.nameTemplate, allowSorting: true, }; @@ -128,12 +133,8 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { if (column.alias === 'entityActions') { return { columnAlias: 'entityActions', - value: html``, + value: html``, }; } @@ -143,7 +144,7 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { return { columnAlias: column.alias, - value: column.elementName ? { item, editPath } : this.#getPropertyValueByAlias(item, column.alias), + value: { item, editPath }, }; }) ?? []; @@ -156,28 +157,6 @@ 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': - return item.name; - case 'creator': - case 'owner': - return item.creator; - case 'sortOrder': - return item.sortOrder; - case 'updateDate': - return item.updateDate.toLocaleString(); - case 'updater': - return item.updater; - default: - return item.values?.find((value) => value.alias === alias)?.value ?? ''; - } - } - #handleSelect(event: UmbTableSelectedEvent) { event.stopPropagation(); const table = event.target as UmbTableElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/manifests.ts index a11b6a3d3c07..877c37ba5694 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/manifests.ts @@ -1,19 +1,26 @@ +import { manifest as editorSchema } from './Umbraco.ColorPicker.js'; import { UMB_COLOR_PICKER_PROPERTY_EDITOR_UI_ALIAS } from './constants.js'; -import { manifest as schemaManifest } from './Umbraco.ColorPicker.js'; -export const manifests: Array = [ - { - type: 'propertyEditorUi', - alias: UMB_COLOR_PICKER_PROPERTY_EDITOR_UI_ALIAS, - name: 'Color Picker Property Editor UI', - element: () => import('./property-editor-ui-color-picker.element.js'), - meta: { - label: 'Color Picker', - propertyEditorSchemaAlias: 'Umbraco.ColorPicker', - icon: 'icon-colorpicker', - group: 'pickers', - supportsReadOnly: true, - }, +const editorUi: UmbExtensionManifest = { + type: 'propertyEditorUi', + alias: UMB_COLOR_PICKER_PROPERTY_EDITOR_UI_ALIAS, + name: 'Color Picker Property Editor UI', + element: () => import('./property-editor-ui-color-picker.element.js'), + meta: { + label: 'Color Picker', + propertyEditorSchemaAlias: 'Umbraco.ColorPicker', + icon: 'icon-colorpicker', + group: 'pickers', + supportsReadOnly: true, }, - schemaManifest, -]; +}; + +const valuePresentation: UmbExtensionManifest = { + type: 'propertyValuePresentation', + alias: 'Umb.PropertyValuePresentation.ColorPicker', + name: 'Color Picker Property Value Presentation', + element: () => import('./property-value-presentation-color-picker.element.js'), + forPropertyEditorSchemaAlias: 'Umbraco.ColorPicker', +}; + +export const manifests: Array = [editorSchema, editorUi, valuePresentation]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/property-value-presentation-color-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/property-value-presentation-color-picker.element.ts new file mode 100644 index 000000000000..3fe068f27e48 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/property-value-presentation-color-picker.element.ts @@ -0,0 +1,27 @@ +import { customElement, html, nothing, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbPropertyValuePresentationBaseElement } from '@umbraco-cms/backoffice/property-value-presentation'; + +@customElement('umb-color-picker-property-value-presentation') +export class UmbColorPickerPropertyValuePresentationElement extends UmbPropertyValuePresentationBaseElement< + { value: string; label: string } | string +> { + override render() { + if (!this.value) return nothing; + const color = typeof this.value === 'string' ? this.value : this.value.value; + const label = typeof this.value === 'string' ? this.value : this.value.label; + return when( + color, + () => html``, + ); + } +} + +export { UmbColorPickerPropertyValuePresentationElement as element }; + +export default UmbColorPickerPropertyValuePresentationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-color-picker-property-value-presentation': UmbColorPickerPropertyValuePresentationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/manifests.ts index c42c8a78e8e2..c503dfce8753 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/manifests.ts @@ -1,18 +1,25 @@ -import { manifest as schemaManifest } from './Umbraco.DateOnly.js'; +import { manifest as editorSchema } from './Umbraco.DateOnly.js'; -export const manifests: Array = [ - { - type: 'propertyEditorUi', - alias: 'Umb.PropertyEditorUi.DateOnlyPicker', - name: 'Date Only Picker Property Editor UI', - element: () => import('./property-editor-ui-date-only-picker.element.js'), - meta: { - label: 'Date Only', - propertyEditorSchemaAlias: 'Umbraco.DateOnly', - icon: 'icon-calendar-alt', - group: 'date', - supportsReadOnly: true, - }, +const editorUi: UmbExtensionManifest = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.DateOnlyPicker', + name: 'Date Only Picker Property Editor UI', + element: () => import('./property-editor-ui-date-only-picker.element.js'), + meta: { + label: 'Date Only', + propertyEditorSchemaAlias: 'Umbraco.DateOnly', + icon: 'icon-calendar-alt', + group: 'date', + supportsReadOnly: true, }, - schemaManifest, -]; +}; + +const valuePresentation: UmbExtensionManifest = { + type: 'propertyValuePresentation', + alias: 'Umb.PropertyValuePresentation.DateOnlyPicker', + name: 'Date Only Picker Property Value Presentation', + element: () => import('./property-value-presentation-date-only-picker.element.js'), + forPropertyEditorSchemaAlias: 'Umbraco.DateOnly', +}; + +export const manifests: Array = [editorSchema, editorUi, valuePresentation]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/property-value-presentation-date-only-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/property-value-presentation-date-only-picker.element.ts new file mode 100644 index 000000000000..ac8d4ec8d586 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/property-value-presentation-date-only-picker.element.ts @@ -0,0 +1,23 @@ +import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { UmbPropertyValuePresentationBaseElement } from '@umbraco-cms/backoffice/property-value-presentation'; + +@customElement('umb-date-only-picker-property-value-presentation') +export class UmbDateOnlyPickerPropertyValuePresentationElement extends UmbPropertyValuePresentationBaseElement<{ + date?: string; +}> { + override render() { + if (!this.value || !this.value.date) return nothing; + const date = new Date(this.value.date).toLocaleDateString(); + return date ? html`${date}` : nothing; + } +} + +export { UmbDateOnlyPickerPropertyValuePresentationElement as element }; + +export default UmbDateOnlyPickerPropertyValuePresentationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-date-only-picker-property-value-presentation': UmbDateOnlyPickerPropertyValuePresentationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/manifests.ts index af73ef37f6bf..31974dfda138 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/manifests.ts @@ -1,42 +1,49 @@ -import { manifest as schemaManifest } from './Umbraco.DateTimeUnspecified.js'; +import { manifest as editorSchema } from './Umbraco.DateTimeUnspecified.js'; -export const manifests: Array = [ - { - type: 'propertyEditorUi', - alias: 'Umb.PropertyEditorUi.DateTimePicker', - name: 'Date Time Picker Property Editor UI', - element: () => import('./property-editor-ui-date-time-picker.element.js'), - meta: { - label: 'Date Time (unspecified)', - propertyEditorSchemaAlias: 'Umbraco.DateTimeUnspecified', - icon: 'icon-calendar-alt', - group: 'date', - supportsReadOnly: true, - settings: { - properties: [ - { - alias: 'timeFormat', - label: '#dateTimePicker_config_timeFormat', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', - config: [ - { - alias: 'items', - value: [ - { name: 'HH:mm', value: 'HH:mm' }, - { name: 'HH:mm:ss', value: 'HH:mm:ss' }, - ], - }, - ], - }, - ], - defaultData: [ - { - alias: 'timeFormat', - value: 'HH:mm', - }, - ], - }, +const editorUi: UmbExtensionManifest = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.DateTimePicker', + name: 'Date Time Picker Property Editor UI', + element: () => import('./property-editor-ui-date-time-picker.element.js'), + meta: { + label: 'Date Time (unspecified)', + propertyEditorSchemaAlias: 'Umbraco.DateTimeUnspecified', + icon: 'icon-calendar-alt', + group: 'date', + supportsReadOnly: true, + settings: { + properties: [ + { + alias: 'timeFormat', + label: '#dateTimePicker_config_timeFormat', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', + config: [ + { + alias: 'items', + value: [ + { name: 'HH:mm', value: 'HH:mm' }, + { name: 'HH:mm:ss', value: 'HH:mm:ss' }, + ], + }, + ], + }, + ], + defaultData: [ + { + alias: 'timeFormat', + value: 'HH:mm', + }, + ], }, }, - schemaManifest, -]; +}; + +const valuePresentation: UmbExtensionManifest = { + type: 'propertyValuePresentation', + alias: 'Umb.PropertyValuePresentation.DateTimePicker', + name: 'Date Time Picker Property Value Presentation', + element: () => import('./property-value-presentation-date-time-picker.element.js'), + forPropertyEditorSchemaAlias: 'Umbraco.DateTimeUnspecified', +}; + +export const manifests: Array = [editorSchema, editorUi, valuePresentation]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/property-value-presentation-date-time-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/property-value-presentation-date-time-picker.element.ts new file mode 100644 index 000000000000..b50f388afd18 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/property-value-presentation-date-time-picker.element.ts @@ -0,0 +1,23 @@ +import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { UmbPropertyValuePresentationBaseElement } from '@umbraco-cms/backoffice/property-value-presentation'; + +@customElement('umb-date-time-picker-property-value-presentation') +export class UmbDateTimePickerPropertyValuePresentationElement extends UmbPropertyValuePresentationBaseElement<{ + date: string; +}> { + override render() { + if (!this.value?.date) return nothing; + const date = new Date(this.value.date).toLocaleString(); + return date ? html`${date}` : nothing; + } +} + +export { UmbDateTimePickerPropertyValuePresentationElement as element }; + +export default UmbDateTimePickerPropertyValuePresentationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-date-time-picker-property-value-presentation': UmbDateTimePickerPropertyValuePresentationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/manifests.ts index d514e0b9eb31..6cbad83904ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/manifests.ts @@ -1,56 +1,63 @@ -import { manifest as schemaManifest } from './Umbraco.DateTimeWithTimeZone.js'; +import { manifest as editorSchema } from './Umbraco.DateTimeWithTimeZone.js'; -export const manifests: Array = [ - { - type: 'propertyEditorUi', - alias: 'Umb.PropertyEditorUi.DateTimeWithTimeZonePicker', - name: 'Date Time with Time Zone Picker Property Editor UI', - element: () => import('./property-editor-ui-date-time-with-time-zone-picker.element.js'), - meta: { - label: 'Date Time (with time zone)', - propertyEditorSchemaAlias: 'Umbraco.DateTimeWithTimeZone', - icon: 'icon-calendar-alt', - group: 'date', - supportsReadOnly: true, - settings: { - properties: [ - { - alias: 'timeFormat', - label: '#dateTimePicker_config_timeFormat', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', - config: [ - { - alias: 'items', - value: [ - { name: 'HH:mm', value: 'HH:mm' }, - { name: 'HH:mm:ss', value: 'HH:mm:ss' }, - ], - }, - ], - }, - { - alias: 'timeZones', - label: '#dateTimePicker_config_timeZones', - description: '{#dateTimePicker_config_timeZones_description}', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.TimeZonePicker', - config: [], - }, - ], - defaultData: [ - { - alias: 'timeFormat', - value: 'HH:mm', - }, - { - alias: 'timeZones', - value: { - mode: 'all', - timeZones: [], +const editorUi: UmbExtensionManifest = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.DateTimeWithTimeZonePicker', + name: 'Date Time with Time Zone Picker Property Editor UI', + element: () => import('./property-editor-ui-date-time-with-time-zone-picker.element.js'), + meta: { + label: 'Date Time (with time zone)', + propertyEditorSchemaAlias: 'Umbraco.DateTimeWithTimeZone', + icon: 'icon-calendar-alt', + group: 'date', + supportsReadOnly: true, + settings: { + properties: [ + { + alias: 'timeFormat', + label: '#dateTimePicker_config_timeFormat', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', + config: [ + { + alias: 'items', + value: [ + { name: 'HH:mm', value: 'HH:mm' }, + { name: 'HH:mm:ss', value: 'HH:mm:ss' }, + ], }, + ], + }, + { + alias: 'timeZones', + label: '#dateTimePicker_config_timeZones', + description: '{#dateTimePicker_config_timeZones_description}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.TimeZonePicker', + config: [], + }, + ], + defaultData: [ + { + alias: 'timeFormat', + value: 'HH:mm', + }, + { + alias: 'timeZones', + value: { + mode: 'all', + timeZones: [], }, - ], - }, + }, + ], }, }, - schemaManifest, -]; +}; + +const valuePresentation: UmbExtensionManifest = { + type: 'propertyValuePresentation', + alias: 'Umb.PropertyValuePresentation.DateTimeWithTimeZonePicker', + name: 'Date Time With Time Zone Picker Property Value Presentation', + element: () => import('./property-value-presentation-date-time-with-time-zone-picker.element.js'), + forPropertyEditorSchemaAlias: 'Umbraco.DateTimeWithTimeZone', +}; + +export const manifests = [editorSchema, editorUi, valuePresentation]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/property-value-presentation-date-time-with-time-zone-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/property-value-presentation-date-time-with-time-zone-picker.element.ts new file mode 100644 index 000000000000..be6c14ee83dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/property-value-presentation-date-time-with-time-zone-picker.element.ts @@ -0,0 +1,34 @@ +import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { UmbPropertyValuePresentationBaseElement } from '@umbraco-cms/backoffice/property-value-presentation'; + +@customElement('umb-date-time-with-time-zone-picker-property-value-presentation') +export class UmbDateTimePickerWithTimeZonePropertyValuePresentationElement extends UmbPropertyValuePresentationBaseElement<{ + date: string; + timeZone: string; +}> { + override render() { + if (!this.value) return nothing; + return html`${this.#renderDate()}${this.#renderTimeZone()}`; + } + + #renderDate() { + if (!this.value?.date) return nothing; + const date = new Date(this.value.date).toLocaleString(); + return html`${date}`; + } + + #renderTimeZone() { + if (!this.value?.timeZone) return nothing; + return html` (${this.value.timeZone})`; + } +} + +export { UmbDateTimePickerWithTimeZonePropertyValuePresentationElement as element }; + +export default UmbDateTimePickerWithTimeZonePropertyValuePresentationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-date-time-with-time-zone-picker-property-value-presentation': UmbDateTimePickerWithTimeZonePropertyValuePresentationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/manifests.ts index b06aca52f29d..0eef6b571c0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/manifests.ts @@ -1,42 +1,49 @@ -import { manifest as schemaManifest } from './Umbraco.TimeOnly.js'; +import { manifest as editorSchema } from './Umbraco.TimeOnly.js'; -export const manifests: Array = [ - { - type: 'propertyEditorUi', - alias: 'Umb.PropertyEditorUi.TimeOnlyPicker', - name: 'Time Only Picker Property Editor UI', - element: () => import('./property-editor-ui-time-only-picker.element.js'), - meta: { - label: 'Time Only', - propertyEditorSchemaAlias: 'Umbraco.TimeOnly', - icon: 'icon-time', - group: 'date', - supportsReadOnly: true, - settings: { - properties: [ - { - alias: 'timeFormat', - label: '#dateTimePicker_config_timeFormat', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', - config: [ - { - alias: 'items', - value: [ - { name: 'HH:mm', value: 'HH:mm' }, - { name: 'HH:mm:ss', value: 'HH:mm:ss' }, - ], - }, - ], - }, - ], - defaultData: [ - { - alias: 'timeFormat', - value: 'HH:mm', - }, - ], - }, +const editorUi: UmbExtensionManifest = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.TimeOnlyPicker', + name: 'Time Only Picker Property Editor UI', + element: () => import('./property-editor-ui-time-only-picker.element.js'), + meta: { + label: 'Time Only', + propertyEditorSchemaAlias: 'Umbraco.TimeOnly', + icon: 'icon-time', + group: 'date', + supportsReadOnly: true, + settings: { + properties: [ + { + alias: 'timeFormat', + label: '#dateTimePicker_config_timeFormat', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.RadioButtonList', + config: [ + { + alias: 'items', + value: [ + { name: 'HH:mm', value: 'HH:mm' }, + { name: 'HH:mm:ss', value: 'HH:mm:ss' }, + ], + }, + ], + }, + ], + defaultData: [ + { + alias: 'timeFormat', + value: 'HH:mm', + }, + ], }, }, - schemaManifest, -]; +}; + +const valuePresentation: UmbExtensionManifest = { + type: 'propertyValuePresentation', + alias: 'Umb.PropertyValuePresentation.TimeOnlyPicker', + name: 'Time Only Picker Property Value Presentation', + element: () => import('./property-value-presentation-time-only-picker.element.js'), + forPropertyEditorSchemaAlias: 'Umbraco.TimeOnly', +}; + +export const manifests: Array = [editorSchema, editorUi, valuePresentation]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/property-value-presentation-time-only-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/property-value-presentation-time-only-picker.element.ts new file mode 100644 index 000000000000..0a3d523ff083 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/property-value-presentation-time-only-picker.element.ts @@ -0,0 +1,22 @@ +import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { UmbPropertyValuePresentationBaseElement } from '@umbraco-cms/backoffice/property-value-presentation'; + +@customElement('umb-time-only-picker-property-value-presentation') +export class UmbTimeOnlyPickerPropertyValuePresentationElement extends UmbPropertyValuePresentationBaseElement<{ + date: string; +}> { + override render() { + if (!this.value?.date) return nothing; + return html`${this.value.date}`; + } +} + +export { UmbTimeOnlyPickerPropertyValuePresentationElement as element }; + +export default UmbTimeOnlyPickerPropertyValuePresentationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-time-only-picker-property-value-presentation': UmbTimeOnlyPickerPropertyValuePresentationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 16c2d20becbd..1f9c4f9be13e 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -120,6 +120,9 @@ DON'T EDIT THIS FILE DIRECTLY. It is generated by /devops/tsconfig/index.js "./src/packages/core/property-editor-data-source/index.ts" ], "@umbraco-cms/backoffice/property-editor": ["./src/packages/core/property-editor/index.ts"], + "@umbraco-cms/backoffice/property-value-presentation": [ + "./src/packages/core/property-value-presentation/index.ts" + ], "@umbraco-cms/backoffice/property-type": ["./src/packages/content/property-type/index.ts"], "@umbraco-cms/backoffice/property": ["./src/packages/core/property/index.ts"], "@umbraco-cms/backoffice/recycle-bin": ["./src/packages/core/recycle-bin/index.ts"],