Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Readonly mode for Content Picker Property Editor UI #2229

Merged
merged 12 commits into from
Sep 2, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,17 @@ export class UmbInputDocumentElement extends UmbFormControlMixin<string | undefi
}

#renderAddButton() {
if (this.selection.length >= this.max) return;
return html`
<uui-button
if (this.selection.length >= this.max) return nothing;
if (this.readonly && this.selection.length > 0) {
return nothing;
} else {
return html` <uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}></uui-button>
`;
?disabled=${this.readonly}></uui-button>`;
}
}

#renderItems() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import type { UmbMediaCardItemModel } from '../../modals/index.js';
import type { UmbMediaItemModel } from '../../repository/index.js';
import { UmbMediaPickerInputContext } from './input-media.context.js';
import { css, customElement, html, ifDefined, property, repeat, state } from '@umbraco-cms/backoffice/external/lit';
import {
css,
customElement,
html,
ifDefined,
nothing,
property,
repeat,
state,
} from '@umbraco-cms/backoffice/external/lit';
import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
Expand All @@ -13,7 +22,6 @@ import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
import '@umbraco-cms/backoffice/imaging';

const elementName = 'umb-input-media';

@customElement(elementName)
export class UmbInputMediaElement extends UmbFormControlMixin<string | undefined, typeof UmbLitElement>(UmbLitElement) {
#sorter = new UmbSorterController<string>(this, {
Expand Down Expand Up @@ -116,6 +124,27 @@ export class UmbInputMediaElement extends UmbFormControlMixin<string | undefined
return this.selection.length > 0 ? this.selection.join(',') : undefined;
}

/**
* Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content.
* @type {boolean}
* @attr
* @default
*/
@property({ type: Boolean, reflect: true })
public get readonly() {
return this.#readonly;
}
public set readonly(value) {
this.#readonly = value;

if (this.#readonly) {
this.#sorter.disable();
} else {
this.#sorter.enable();
}
}
#readonly = false;

@state()
private _editMediaPath = '';

Expand Down Expand Up @@ -182,7 +211,7 @@ export class UmbInputMediaElement extends UmbFormControlMixin<string | undefined
}

#renderItems() {
if (!this._cards?.length) return;
if (!this._cards?.length) return nothing;
return html`
${repeat(
this._cards,
Expand All @@ -193,44 +222,54 @@ export class UmbInputMediaElement extends UmbFormControlMixin<string | undefined
}

#renderAddButton() {
if (this._cards && this.max && this._cards.length >= this.max) return;
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}>
<uui-icon name="icon-add"></uui-icon>
${this.localize.term('general_choose')}
</uui-button>
`;
// TODO: Stop preventing adding more, instead implement proper validation for user feedback. [NL]
if (this._cards && this.max && this._cards.length >= this.max) return nothing;
if (this.readonly && this._cards.length > 0) {
return nothing;
} else {
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}>
<uui-icon name="icon-add"></uui-icon>
${this.localize.term('general_choose')}
</uui-button>
`;
}
}

#renderItem(item: UmbMediaCardItemModel) {
const href = this.readonly ? undefined : `${this._editMediaPath}edit/${item.unique}`;
return html`
<uui-card-media
name=${ifDefined(item.name === null ? undefined : item.name)}
detail=${ifDefined(item.unique)}
href="${this._editMediaPath}edit/${item.unique}">
href="${ifDefined(href)}"
?readonly=${this.readonly}>
<umb-imaging-thumbnail
unique=${item.unique}
alt=${item.name}
icon=${item.mediaType.icon}></umb-imaging-thumbnail>
${this.#renderIsTrashed(item)}
<uui-action-bar slot="actions">
<uui-button
label=${this.localize.term('general_remove')}
look="secondary"
@click=${() => this.#onRemove(item)}>
<uui-icon name="icon-trash"></uui-icon>
</uui-button>
</uui-action-bar>
<uui-action-bar slot="actions"> ${this.#renderRemoveAction(item)}</uui-action-bar>
</uui-card-media>
`;
}

#renderRemoveAction(item: UmbMediaCardItemModel) {
if (this.readonly) return nothing;
return html`
<uui-button label=${this.localize.term('general_remove')} look="secondary" @click=${() => this.#onRemove(item)}>
<uui-icon name="icon-trash"></uui-icon>
</uui-button>
`;
}

#renderIsTrashed(item: UmbMediaCardItemModel) {
if (!item.isTrashed) return;
if (!item.isTrashed) return nothing;
return html`
<uui-tag size="s" slot="tag" color="danger">
<umb-localize key="mediaPicker_trashed">Trashed</umb-localize>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,18 +361,23 @@ export class UmbInputRichMediaElement extends UUIFormControlMixin(UmbLitElement,
}

#renderAddButton() {
// TODO: Stop preventing adding more, instead implement proper validation for user feedback. [NL]
if ((this._cards && this.max && this._cards.length >= this.max) || (this._cards.length && !this.multiple)) return;
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}>
<uui-icon name="icon-add"></uui-icon>
${this.localize.term('general_choose')}
</uui-button>
`;
if (this.readonly && this._cards.length > 0) {
return nothing;
} else {
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}>
<uui-icon name="icon-add"></uui-icon>
${this.localize.term('general_choose')}
</uui-button>
`;
}
}

#renderItem(item: UmbRichMediaCardModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export const manifest: ManifestPropertyEditorUi = {
label: 'Media Entity Picker',
icon: 'icon-picture',
group: 'pickers',
supportsReadOnly: true,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ export class UmbPropertyEditorUIMediaEntityPickerElement extends UmbLitElement i
this._max = minMax?.max ?? Infinity;
}

/**
* Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content.
* @type {boolean}
* @attr
* @default false
*/
@property({ type: Boolean, reflect: true })
readonly = false;

@state()
_min: number = 0;

Expand All @@ -36,6 +45,7 @@ export class UmbPropertyEditorUIMediaEntityPickerElement extends UmbLitElement i
.min=${this._min}
.max=${this._max}
.value=${this.value}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-media>
`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,16 @@ export class UmbInputMemberGroupElement extends UmbFormControlMixin<string | und

#renderAddButton() {
if (this.max === 1 && this.selection.length >= this.max) return nothing;
return html`<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}></uui-button>`;
if (this.readonly && this.selection.length > 0) {
return nothing;
} else {
return html`<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}></uui-button>`;
}
}

#renderItem(item: UmbMemberGroupItemModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,18 @@ export class UmbInputMemberElement extends UmbFormControlMixin<string | undefine

#renderAddButton() {
if (this.selection.length >= this.max) return nothing;
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}></uui-button>
`;
if (this.readonly && this.selection.length > 0) {
return nothing;
} else {
return html`
<uui-button
id="btn-add"
look="placeholder"
@click=${this.#openPicker}
label=${this.localize.term('general_choose')}
?disabled=${this.readonly}></uui-button>
`;
}
}

#renderItem(item: UmbMemberItemModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,19 @@ export class UmbInputMultiUrlElement extends UUIFormControlMixin(UmbLitElement,
}

#renderAddButton() {
if (this.max === 1 && this.urls && this.urls.length >= this.max) return;
return html`
<uui-button
id="btn-add"
look="placeholder"
label=${this.localize.term('general_add')}
.href=${this._modalRoute?.({ index: -1 })}
?disabled=${this.readonly}></uui-button>
`;
if (this.max === 1 && this.urls && this.urls.length >= this.max) return nothing;
if (this.readonly && this.urls.length > 0) {
return nothing;
} else {
return html`
<uui-button
id="btn-add"
look="placeholder"
label=${this.localize.term('general_add')}
.href=${this._modalRoute?.({ index: -1 })}
?disabled=${this.readonly}></uui-button>
`;
}
}

#renderItems() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { splitStringToArray } from '@umbraco-cms/backoffice/utils';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';

const elementName = 'umb-input-content';

@customElement(elementName)
export class UmbInputContentElement extends UmbFormControlMixin<string | undefined, typeof UmbLitElement>(
UmbLitElement,
Expand Down Expand Up @@ -79,6 +78,15 @@ export class UmbInputContentElement extends UmbFormControlMixin<string | undefin
return this.#selection.length > 0 ? this.#selection.join(',') : undefined;
}

/**
* Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content.
* @type {boolean}
* @attr
* @default false
*/
@property({ type: Boolean, reflect: true })
readonly = false;

#entityTypeLookup = { content: 'document', media: 'media', member: 'member' };

#selection: Array<string> = [];
Expand Down Expand Up @@ -117,6 +125,7 @@ export class UmbInputContentElement extends UmbFormControlMixin<string | undefin
.max=${this.max}
.maxMessage=${this.maxMessage}
?showOpenButton=${this.showOpenButton}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-document>
`;
}
Expand All @@ -131,6 +140,7 @@ export class UmbInputContentElement extends UmbFormControlMixin<string | undefin
.max=${this.max}
.maxMessage=${this.maxMessage}
?showOpenButton=${this.showOpenButton}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-media>
`;
}
Expand All @@ -145,6 +155,7 @@ export class UmbInputContentElement extends UmbFormControlMixin<string | undefin
.max=${this.max}
.maxMessage=${this.maxMessage}
?showOpenButton=${this.showOpenButton}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-member>
`;
}
Expand Down
1 change: 1 addition & 0 deletions src/packages/property-editors/content-picker/manifests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const manifest: ManifestPropertyEditorUi = {
icon: 'icon-page-add',
group: 'pickers',
propertyEditorSchemaAlias: 'Umbraco.MultiNodeTreePicker',
supportsReadOnly: true,
settings: {
properties: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ export class UmbPropertyEditorUIContentPickerElement
}
#value?: UmbContentPickerValueType = [];

/**
* Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content.
* @type {boolean}
* @attr
* @default false
*/
@property({ type: Boolean, reflect: true })
readonly = false;

@state()
_type: UmbContentPickerSource['type'] = 'content';

Expand Down Expand Up @@ -150,6 +159,7 @@ export class UmbPropertyEditorUIContentPickerElement
.startNode=${startNode}
.allowedContentTypeIds=${this._allowedContentTypeUniques ?? ''}
?showOpenButton=${this._showOpenButton}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-content>
`;
}
Expand Down
Loading