image crop modal links
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging';
|
||||
import { UMB_IMAGE_CROPPER_EDITOR_MODAL, UMB_MEDIA_PICKER_MODAL } from '../../modals/index.js';
|
||||
import type { UmbCropModel, UmbMediaPickerPropertyValue } from '../../property-editors/index.js';
|
||||
import { customElement, html, ifDefined, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging';
|
||||
import { UmbInputMediaElement, UmbMediaItemRepository } from '@umbraco-cms/backoffice/media';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import {
|
||||
@@ -190,6 +190,7 @@ export class UmbInputRichMediaElement extends UUIFormControlMixin(UmbLitElement,
|
||||
focalPointEnabled: this.focalPointEnabled,
|
||||
key,
|
||||
unique: item.mediaKey,
|
||||
pickableFilter: this.#pickableFilter,
|
||||
},
|
||||
value: {
|
||||
crops: item.crops ?? [],
|
||||
@@ -202,8 +203,16 @@ export class UmbInputRichMediaElement extends UUIFormControlMixin(UmbLitElement,
|
||||
})
|
||||
.onSubmit((value) => {
|
||||
this.items = this.items.map((item) => {
|
||||
if (item.key !== value.key) return item;
|
||||
|
||||
const focalPoint = this.focalPointEnabled ? value.focalPoint : null;
|
||||
return item.key === value.key ? { ...item, ...value, focalPoint } : item;
|
||||
const crops = value.crops;
|
||||
const mediaKey = value.unique;
|
||||
|
||||
// if the key changes, the card will update
|
||||
const key = mediaKey === item.mediaKey ? item.key : UmbId.new();
|
||||
|
||||
return { ...item, crops, mediaKey, focalPoint, key };
|
||||
});
|
||||
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
@@ -303,12 +312,8 @@ export class UmbInputRichMediaElement extends UUIFormControlMixin(UmbLitElement,
|
||||
confirmLabel: this.localize.term('actions_remove'),
|
||||
});
|
||||
|
||||
const index = this.items.findIndex((x) => x.key === item.unique);
|
||||
if (index == -1) return;
|
||||
|
||||
const tmpItems = [...this.items];
|
||||
tmpItems.splice(index, 1);
|
||||
this.#items = tmpItems;
|
||||
this.#items = this.#items.filter((x) => x.key !== item.unique);
|
||||
this._cards = this._cards.filter((x) => x.unique !== item.unique);
|
||||
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
}
|
||||
|
||||
@@ -2,18 +2,25 @@ import { UmbMediaUrlRepository } from '../../repository/index.js';
|
||||
import type { UmbCropModel } from '../../property-editors/index.js';
|
||||
import type { UmbInputImageCropperFieldElement } from '../../components/input-image-cropper/image-cropper-field.element.js';
|
||||
import type { UmbImageCropperPropertyEditorValue } from '../../components/index.js';
|
||||
import { UMB_MEDIA_PICKER_MODAL } from '../media-picker/media-picker-modal.token.js';
|
||||
import type {
|
||||
UmbImageCropperEditorModalData,
|
||||
UmbImageCropperEditorModalValue,
|
||||
} from './image-cropper-editor-modal.token.js';
|
||||
import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import {
|
||||
UMB_MODAL_MANAGER_CONTEXT,
|
||||
UMB_WORKSPACE_MODAL,
|
||||
UmbModalBaseElement,
|
||||
type UmbModalManagerContext,
|
||||
UmbModalRouteRegistrationController,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
/** TODO Make some of the components from property editor image cropper reuseable for this modal... */
|
||||
|
||||
@customElement('umb-image-cropper-editor-modal')
|
||||
export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
UmbImageCropperEditorModalData,
|
||||
UmbImageCropperEditorModalData<any>,
|
||||
UmbImageCropperEditorModalValue
|
||||
> {
|
||||
#urlRepository = new UmbMediaUrlRepository(this);
|
||||
@@ -34,6 +41,30 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
@state()
|
||||
private _crops: Array<UmbCropModel> = [];
|
||||
|
||||
@state()
|
||||
private _editMediaPath = '';
|
||||
|
||||
@state()
|
||||
private _pickableFilter?: (item: any) => boolean;
|
||||
|
||||
#modalManager?: UmbModalManagerContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (context) => {
|
||||
this.#modalManager = context;
|
||||
});
|
||||
|
||||
new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL)
|
||||
.addAdditionalPath('media')
|
||||
.onSetup(() => {
|
||||
return { data: { entityType: 'media', preset: {} } };
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this._editMediaPath = routeBuilder({});
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
@@ -42,6 +73,7 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
|
||||
this._focalPointEnabled = this.data?.focalPointEnabled ?? false;
|
||||
this._crops = this.data?.cropOptions ?? [];
|
||||
this._pickableFilter = this.data?.pickableFilter;
|
||||
|
||||
this.#getSrc();
|
||||
}
|
||||
@@ -60,6 +92,19 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
this._imageCropperValue = value;
|
||||
}
|
||||
|
||||
async #openMediaPicker() {
|
||||
const modal = this.#modalManager?.open(this, UMB_MEDIA_PICKER_MODAL, {
|
||||
data: { multiple: false, pickableFilter: this._pickableFilter },
|
||||
value: { selection: [this._unique] },
|
||||
});
|
||||
const data = await modal?.onSubmit().catch(() => null);
|
||||
if (!data) return;
|
||||
|
||||
this._unique = data.selection[0];
|
||||
this.value = { ...this.value, unique: this._unique };
|
||||
this.#getSrc();
|
||||
}
|
||||
|
||||
#onChange(e: CustomEvent) {
|
||||
const value = (e.target as UmbInputImageCropperFieldElement).value;
|
||||
if (!value) return;
|
||||
@@ -70,7 +115,7 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
render() {
|
||||
return html`
|
||||
<umb-body-layout headline=${this.localize.term('defaultdialogs_selectMedia')}>
|
||||
<umb-image-cropper-field @change=${this.#onChange} .value=${this._imageCropperValue}></umb-image-cropper-field>
|
||||
${this.#renderBody()}
|
||||
<div slot="actions">
|
||||
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
|
||||
<uui-button
|
||||
@@ -83,12 +128,34 @@ export class UmbImageCropperEditorModalElement extends UmbModalBaseElement<
|
||||
`;
|
||||
}
|
||||
|
||||
#renderBody() {
|
||||
return html`<div id="layout">
|
||||
<umb-image-cropper-field @change=${this.#onChange} .value=${this._imageCropperValue}></umb-image-cropper-field>
|
||||
<div id="options">
|
||||
<uui-menu-item @click=${this.#openMediaPicker} label=${this.localize.term('mediaPicker_changeMedia')}>
|
||||
<umb-icon slot="icon" name="icon-search"></umb-icon>
|
||||
</uui-menu-item>
|
||||
<uui-menu-item
|
||||
href=${this._editMediaPath + 'edit/' + this._unique}
|
||||
label=${this.localize.term('mediaPicker_openMedia')}>
|
||||
<umb-icon slot="icon" name="icon-out"></umb-icon>
|
||||
</uui-menu-item>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
uui-tab {
|
||||
flex: 1;
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
#layout {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#options {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { UmbImageCropperCrop } from '../../components/index.js';
|
||||
import type { UmbCropModel } from '../../property-editors/index.js';
|
||||
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export interface UmbImageCropperEditorModalData {
|
||||
export interface UmbImageCropperEditorModalData<ItemType> {
|
||||
key: string;
|
||||
unique: string;
|
||||
focalPointEnabled: boolean;
|
||||
cropOptions: Array<UmbCropModel>;
|
||||
pickableFilter?: (item: ItemType) => boolean;
|
||||
}
|
||||
|
||||
export interface UmbImageCropperEditorModalValue {
|
||||
@@ -17,7 +18,7 @@ export interface UmbImageCropperEditorModalValue {
|
||||
}
|
||||
|
||||
export const UMB_IMAGE_CROPPER_EDITOR_MODAL = new UmbModalToken<
|
||||
UmbImageCropperEditorModalData,
|
||||
UmbImageCropperEditorModalData<any>,
|
||||
UmbImageCropperEditorModalValue
|
||||
>('Umb.Modal.ImageCropperEditor', {
|
||||
modal: {
|
||||
|
||||
Reference in New Issue
Block a user