From f2da2c718685b4f576e618709efddbc134d881d0 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 22 May 2024 14:31:37 +0200 Subject: [PATCH] types, sending data --- .../components/input-rich-media/index.ts | 7 ++++ .../input-rich-media.context.ts | 33 +++++++-------- .../input-rich-media.element.ts | 42 ++++++++++++------- .../image-cropper-editor-modal.element.ts | 14 +++++-- .../image-cropper-editor-modal.token.ts | 1 + .../media/media/modals/media-picker/types.ts | 2 +- .../property-editors/media-picker/index.ts | 14 ++++++- ...property-editor-ui-media-picker.element.ts | 25 +---------- 8 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/index.ts index 0c7c12b80e..e36a9397af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/index.ts @@ -1 +1,8 @@ +import type { UmbMediaCardItemModel } from '../../modals/index.js'; +import type { UmbMediaPickerPropertyValue } from '../../property-editors/index.js'; + export * from './input-rich-media.element.js'; + +export interface UmbRichMediaItemModel extends UmbMediaCardItemModel, UmbMediaPickerPropertyValue { + src: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.context.ts index 30ae775328..bca98a0956 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.context.ts @@ -1,32 +1,27 @@ -import { UMB_MEDIA_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js'; -import type { UmbCropModel } from '../../property-editors/index.js'; +import { UMB_MEDIA_ITEM_REPOSITORY_ALIAS, type UmbMediaItemModel } from '../../repository/index.js'; +import type { UmbCropModel, UmbMediaPickerPropertyValue } from '../../property-editors/index.js'; import { UMB_MEDIA_PICKER_MODAL, - type UmbMediaCardItemModel, type UmbMediaPickerModalData, type UmbMediaPickerModalValue, } from '../../modals/index.js'; import type { UmbImageCropperCrop, UmbImageCropperCrops } from '../input-image-cropper/types.js'; +import type { UmbRichMediaItemModel } from './index.js'; import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbArrayState, UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging'; import { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; -interface UmbRichMediaItemModel extends UmbMediaCardItemModel { - crops: UmbImageCropperCrops; - focalPoint?: { left: number; top: number }; -} - export class UmbRichMediaPickerContext extends UmbPickerInputContext< - UmbRichMediaItemModel, - UmbRichMediaItemModel, - UmbMediaPickerModalData, + UmbMediaItemModel, + UmbMediaItemModel, + UmbMediaPickerModalData, UmbMediaPickerModalValue > { #imagingRepository: UmbImagingRepository; - #selectedRichItems = new UmbArrayState([], (x) => x.unique); + #selectedRichItems = new UmbArrayState([], (x) => x.key); readonly richItems = this.#selectedRichItems.asObservable(); #preselectedCrops = new UmbArrayState([], (x) => x.alias); @@ -35,8 +30,12 @@ export class UmbRichMediaPickerContext extends UmbPickerInputContext< #focalPointEnabled = new UmbBooleanState(false); readonly focalPointEnabled = this.#focalPointEnabled.asObservable(); + #mediaPickerValue = new UmbArrayState([], (x) => x.key); + readonly mediaPickerValue = this.#mediaPickerValue.asObservable(); + constructor(host: UmbControllerHost) { super(host, UMB_MEDIA_ITEM_REPOSITORY_ALIAS, UMB_MEDIA_PICKER_MODAL); + this.#imagingRepository = new UmbImagingRepository(host); this.observe(this.selectedItems, async (selectedItems) => { @@ -59,9 +58,9 @@ export class UmbRichMediaPickerContext extends UmbPickerInputContext< return { ...item, - url: url ?? '', + src: url ?? '', crops: previous?.crops ?? [], - focalPoint: previous?.focalPoint, + focalPoint: previous?.focalPoint ?? null, }; }); @@ -85,15 +84,15 @@ export class UmbRichMediaPickerContext extends UmbPickerInputContext< return this.#preselectedCrops.getValue(); } - updateFocalPointOfSelectedRichItem(unique: string, focalPoint: { left: number; top: number }) { + updateFocalPointOf(unique: string, focalPoint: { left: number; top: number }) { this.#selectedRichItems.updateOne(unique, { focalPoint }); } - updateCropsOfSelectedRichItem(unique: string, crops: UmbImageCropperCrops) { + updateCropsOf(unique: string, crops: UmbImageCropperCrops) { this.#selectedRichItems.updateOne(unique, { crops }); } - updateOneCropOfSelectedRichItem(unique: string, alias: string, newCrop: UmbImageCropperCrop) { + updateOneCropOf(unique: string, alias: string, newCrop: UmbImageCropperCrop) { const item = this.#selectedRichItems.getValue().find((item) => item.unique); if (!item) return; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts index e693d8eb49..1cf032f82c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts @@ -1,10 +1,13 @@ -import type { UmbCropModel, UmbFocalPointModel, UmbMediaPickerPropertyValue } from '../../property-editors/index.js'; +import type { UmbCropModel, UmbMediaPickerPropertyValue } from '../../property-editors/index.js'; import { UMB_IMAGE_CROPPER_EDITOR_MODAL, type UmbMediaCardItemModel } from '../../modals/index.js'; import { UmbRichMediaPickerContext } from './input-rich-media.context.js'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { customElement, html, ifDefined, property, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbInputMediaElement } from '@umbraco-cms/backoffice/media'; -import type { UmbUploadableFileModel } from '@umbraco-cms/backoffice/media'; +import { + UmbInputMediaElement, + type UmbRichMediaItemModel, + type UmbUploadableFileModel, +} from '@umbraco-cms/backoffice/media'; import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -15,13 +18,15 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { #modal: UmbModalRouteRegistrationController; #pickerContext = new UmbRichMediaPickerContext(this); - private _value: Array = []; - @property() - public set value(value: any) { - this._value = value as Array; + @state() + private _items: Array = []; + + @property({ type: Array }) + public set richValue(value: Array) { + this.#pickerContext.setSelection(value); } - public get value() { - return this._value; + public get richValue(): Array { + return this.#pickerContext.getSelection(); } @property({ type: Array }) @@ -40,9 +45,6 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { return this.#pickerContext.getFocalPointEnabled(); } - @state() - private _modalRoute?: UmbModalRouteBuilder; - @property() public set alias(value: string | undefined) { this.#modal.setUniquePathValue('propertyAlias', value); @@ -59,6 +61,8 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { return this.#modal.getUniquePathValue('variantId'); } + @state() + private _modalRoute?: UmbModalRouteBuilder; constructor() { super(); this.#modal = new UmbModalRouteRegistrationController(this, UMB_IMAGE_CROPPER_EDITOR_MODAL) @@ -75,11 +79,13 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { return { data: { cropOptions: this.preselectedCrops, focalPointEnabled: this.focalPointEnabled, unique }, - value: { crops: [], focalPoint: { left: 0.5, top: 0.5 }, src: '' }, + value: { crops: [], focalPoint: { left: 0.5, top: 0.5 }, src: '', unique: unique }, }; }) .onSubmit((value) => { - console.log('callback', value); + this.#pickerContext.updateFocalPointOf(value.unique, value.focalPoint); + this.#pickerContext.updateCropsOf(value.unique, value.crops); + this.dispatchEvent(new UmbChangeEvent()); }) .observeRouteBuilder((routeBuilder) => { this._modalRoute = routeBuilder; @@ -89,6 +95,10 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { this.addValidators(); } + connectedCallback(): void { + super.connectedCallback(); + } + async #onUploadCompleted(e: CustomEvent) { const completed = e.detail?.completed as Array; const uploaded = completed.map((file) => file.unique); @@ -113,8 +123,8 @@ export class UmbInputRichMediaElement extends UmbInputMediaElement { name=${ifDefined(item.name === null ? undefined : item.name)} detail=${ifDefined(item.unique)} .href=${href}> - ${item.url - ? html`${item.name}` + ${item.src + ? html`${item.name}` : html``} ${this.renderIsTrashed(item)} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/image-cropper-editor/image-cropper-editor-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/image-cropper-editor/image-cropper-editor-modal.element.ts index 8f4b95af43..5a91e40c6f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/image-cropper-editor/image-cropper-editor-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/image-cropper-editor/image-cropper-editor-modal.element.ts @@ -1,5 +1,5 @@ +import type { UmbInputImageCropperFieldElement } from '../../components/input-image-cropper/image-cropper-field.element.js'; import type { UmbImageCropperPropertyEditorValue } from '../../components/index.js'; -import type { UmbImagingModel } from '../../../../core/imaging/types.js'; import { UmbMediaUrlRepository } from '../../repository/index.js'; import type { UmbCropModel } from '../../property-editors/index.js'; import type { @@ -8,8 +8,6 @@ import type { } from './image-cropper-editor-modal.token.js'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging'; -import { ImageCropModeModel } from '@umbraco-cms/backoffice/external/backend-api'; /** TODO Make some of the components from property editor image cropper reuseable for this modal... */ @@ -28,6 +26,7 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement< @state() private _focalPointEnabled = false; + /** TODO allow to enable/disable focalpoint */ @state() private _crops: Array = []; @@ -56,10 +55,17 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement< this._imageCropperValue = value; } + #onChange(e: CustomEvent) { + const value = (e.target as UmbInputImageCropperFieldElement).value; + if (!value) return; + + this.value = { unique: this._unique, crops: value.crops, focalPoint: value.focalPoint }; + } + render() { return html` - +
; focalPoint: { left: number; top: number }; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts index 9209e33c72..f429ad1eca 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/types.ts @@ -2,7 +2,7 @@ import type { UmbMediaItemModel } from '../../repository/index.js'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; export interface UmbMediaCardItemModel extends UmbMediaItemModel { - url?: string; + src?: string; } export interface UmbMediaPathModel extends UmbEntityModel { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts index 789e05d645..b246c984b2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/index.ts @@ -8,7 +8,19 @@ export type UmbMediaPickerPropertyValue = { crops: Array; }; -export interface UmbCropModel { +export type UmbCropModel = { + alias: string; + height: number; + width: number; + coordinates?: { + x1: number; + x2: number; + y1: number; + y2: number; + }; +}; + +export interface UmbConfiguredCropModel { label: string; alias: string; width: number; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts index a7d5e26f8c..c7ecf5bf2b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/property-editor-ui-media-picker.element.ts @@ -1,8 +1,6 @@ import type { UmbInputRichMediaElement } from '../../components/input-rich-media/input-rich-media.element.js'; - import type { UmbCropModel, UmbMediaPickerPropertyValue } from './index.js'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbId } from '@umbraco-cms/backoffice/id'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import type { NumberRangeValueType } from '@umbraco-cms/backoffice/models'; @@ -23,9 +21,7 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme @property({ attribute: false }) public set value(value: Array) { this.#value = value; - this._items = this.value ? this.value.map((x) => x.mediaKey) : []; } - //TODO: Add support for document specific crops. The server side already supports this. public get value() { return this.#value; } @@ -64,9 +60,6 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme @state() private _multiple: boolean = false; - @state() - _items: Array = []; - @state() private _limitMin: number = 0; @@ -89,20 +82,7 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme } #onChange(event: CustomEvent & { target: UmbInputRichMediaElement }) { - const selection = event.target.selection; - - const result = selection.map((mediaKey) => { - return { - key: UmbId.new(), - mediaKey, - mediaTypeAlias: '', - focalPoint: null, - crops: [], - }; - }); - - this.value = result; - this._items = this.value ? this.value.map((x) => x.mediaKey) : []; + this.value = event.target.richValue; this.dispatchEvent(new UmbPropertyValueChangeEvent()); } @@ -111,14 +91,13 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme