types, sending data
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<UmbRichMediaItemModel>,
|
||||
UmbMediaItemModel,
|
||||
UmbMediaItemModel,
|
||||
UmbMediaPickerModalData<UmbMediaItemModel>,
|
||||
UmbMediaPickerModalValue
|
||||
> {
|
||||
#imagingRepository: UmbImagingRepository;
|
||||
|
||||
#selectedRichItems = new UmbArrayState<UmbRichMediaItemModel>([], (x) => x.unique);
|
||||
#selectedRichItems = new UmbArrayState<UmbRichMediaItemModel>([], (x) => x.key);
|
||||
readonly richItems = this.#selectedRichItems.asObservable();
|
||||
|
||||
#preselectedCrops = new UmbArrayState<UmbCropModel>([], (x) => x.alias);
|
||||
@@ -35,8 +30,12 @@ export class UmbRichMediaPickerContext extends UmbPickerInputContext<
|
||||
#focalPointEnabled = new UmbBooleanState<boolean>(false);
|
||||
readonly focalPointEnabled = this.#focalPointEnabled.asObservable();
|
||||
|
||||
#mediaPickerValue = new UmbArrayState<UmbMediaPickerPropertyValue>([], (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;
|
||||
|
||||
|
||||
@@ -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<UmbMediaPickerPropertyValue> = [];
|
||||
@property()
|
||||
public set value(value: any) {
|
||||
this._value = value as Array<UmbMediaPickerPropertyValue>;
|
||||
@state()
|
||||
private _items: Array<UmbRichMediaItemModel> = [];
|
||||
|
||||
@property({ type: Array })
|
||||
public set richValue(value: Array<UmbMediaPickerPropertyValue>) {
|
||||
this.#pickerContext.setSelection(value);
|
||||
}
|
||||
public get value() {
|
||||
return this._value;
|
||||
public get richValue(): Array<UmbMediaPickerPropertyValue> {
|
||||
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<UmbUploadableFileModel>;
|
||||
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`<img src=${item.url} alt=${item.name} />`
|
||||
${item.src
|
||||
? html`<img src=${item.src} alt=${item.name} />`
|
||||
: html`<umb-icon name=${ifDefined(item.mediaType.icon)}></umb-icon>`}
|
||||
${this.renderIsTrashed(item)}
|
||||
<uui-action-bar slot="actions">
|
||||
|
||||
@@ -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<UmbCropModel> = [];
|
||||
@@ -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`
|
||||
<umb-body-layout headline=${this.localize.term('defaultdialogs_selectMedia')}>
|
||||
<umb-image-cropper-field .value=${this._imageCropperValue}></umb-image-cropper-field>
|
||||
<umb-image-cropper-field @change=${this.#onChange} .value=${this._imageCropperValue}></umb-image-cropper-field>
|
||||
<div slot="actions">
|
||||
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
|
||||
<uui-button
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface UmbImageCropperEditorModalData {
|
||||
}
|
||||
|
||||
export interface UmbImageCropperEditorModalValue {
|
||||
unique: string;
|
||||
crops: Array<UmbImageCropperCrop>;
|
||||
focalPoint: { left: number; top: number };
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -8,7 +8,19 @@ export type UmbMediaPickerPropertyValue = {
|
||||
crops: Array<UmbCropModel>;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -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<UmbMediaPickerPropertyValue>) {
|
||||
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<string> = [];
|
||||
|
||||
@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
|
||||
<umb-input-rich-media
|
||||
@change=${this.#onChange}
|
||||
?multiple=${this._multiple}
|
||||
.value=${this.value}
|
||||
.richValue=${this.value}
|
||||
.variantId=${this._variantId}
|
||||
.alias=${this._alias}
|
||||
.allowedContentTypeIds=${this._allowedMediaTypes}
|
||||
.startNode=${this._startNode}
|
||||
.focalPointEnabled=${this._focalPointEnabled}
|
||||
.preselectedCrops=${this._preselectedCrops}
|
||||
.selection=${this._items}
|
||||
.min=${this._limitMin}
|
||||
.max=${this._limitMax}>
|
||||
</umb-input-rich-media>
|
||||
|
||||
Reference in New Issue
Block a user