Merge branch 'main' into v17/dev
# Conflicts: # src/Umbraco.Web.UI.Client/src/packages/content/property-type/workspace/views/settings/property-workspace-view-settings.element.ts
This commit is contained in:
8
.github/README.md
vendored
8
.github/README.md
vendored
@@ -38,6 +38,14 @@ Some important documentation links to get you started:
|
||||
- [Getting to know Umbraco](https://docs.umbraco.com/umbraco-cms/fundamentals/get-to-know-umbraco)
|
||||
- [Tutorials for creating a basic website and customizing the editing experience](https://docs.umbraco.com/umbraco-cms/tutorials/overview)
|
||||
|
||||
## Backoffice Preview
|
||||
|
||||
Want to see the latest backoffice UI in action? Check out our live preview:
|
||||
|
||||
**[backofficepreview.umbraco.com](https://backofficepreview.umbraco.com/)**
|
||||
|
||||
This preview is automatically deployed from the main branch and showcases the latest backoffice features and improvements. It runs from mock data and persistent edits are not supported.
|
||||
|
||||
## Get help
|
||||
|
||||
If you need a bit of feedback while building your Umbraco projects, we are [chatty on Discord](https://discord.umbraco.com). Our Discord server serves as a social space for all Umbracians. If you have any questions or need some help with a problem, head over to our [dedicated forum](https://forum.umbraco.com/) where the Umbraco Community will be happy to help.
|
||||
|
||||
@@ -175,7 +175,7 @@ internal sealed class MediaTypeEditingService : ContentTypeEditingServiceBase<IM
|
||||
continue;
|
||||
}
|
||||
|
||||
allowedFileExtensionsByMediaType[mediaType] = fileUploadConfiguration.FileExtensions;
|
||||
allowedFileExtensionsByMediaType[mediaType] = fileUploadConfiguration.FileExtensions ?? []; // Although we never expect null here, legacy data type configuration did allow it.
|
||||
}
|
||||
|
||||
return allowedFileExtensionsByMediaType;
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
This package contains the types for the Umbraco Backoffice.
|
||||
|
||||
## Preview
|
||||
|
||||
A live preview of the latest backoffice build from the main branch is available at:
|
||||
|
||||
**[backofficepreview.umbraco.com](https://backofficepreview.umbraco.com/)**
|
||||
|
||||
This preview is automatically deployed via GitHub Actions whenever changes are pushed to main or version branches.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
|
||||
@@ -30,6 +30,9 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
|
||||
@state()
|
||||
private _colorList = umbracoColors.filter((color) => !color.legacy);
|
||||
|
||||
@state()
|
||||
private _isSearching = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.consumeContext(UMB_ICON_REGISTRY_CONTEXT, (context) => {
|
||||
@@ -44,8 +47,10 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
|
||||
if (!this.#icons) return;
|
||||
const value = this._searchInput?.value;
|
||||
if (value) {
|
||||
this._isSearching = value.length > 0;
|
||||
this._iconsFiltered = this.#icons.filter((icon) => icon.name.toLowerCase().includes(value.toLowerCase()));
|
||||
} else {
|
||||
this._isSearching = false;
|
||||
this._iconsFiltered = this.#icons;
|
||||
}
|
||||
}
|
||||
@@ -54,8 +59,12 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
|
||||
const isActivate = e.type === 'click' || (e.type === 'keyup' && (e as KeyboardEvent).key === 'Enter');
|
||||
if (!isActivate) return;
|
||||
|
||||
const nextIcon = this.value.icon === iconName ? '' : iconName;
|
||||
this.modalContext?.updateValue({ icon: nextIcon });
|
||||
if (this.data?.showEmptyOption) {
|
||||
const nextIcon = this.value.icon === iconName ? '' : iconName;
|
||||
this.modalContext?.updateValue({ icon: nextIcon });
|
||||
} else {
|
||||
this.modalContext?.updateValue({ icon: iconName });
|
||||
}
|
||||
}
|
||||
|
||||
#onColorChange(e: UUIColorSwatchesEvent) {
|
||||
@@ -93,16 +102,21 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
|
||||
</uui-color-swatches>
|
||||
<hr />
|
||||
<uui-scroll-container id="icons">
|
||||
<uui-button
|
||||
class=${!this.value.icon ? 'selected' : ''}
|
||||
label=${this.localize.term('defaultdialogs_noIcon')}
|
||||
title=${this.localize.term('defaultdialogs_noIcon')}
|
||||
@click=${this.#clearIcon}
|
||||
@keyup=${(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') this.#clearIcon();
|
||||
}}>
|
||||
<uui-icon style="opacity:.35" name=${ifDefined(this.data?.placeholder)}></uui-icon> </uui-button
|
||||
>${this.renderIcons()}</uui-scroll-container
|
||||
${this.data?.showEmptyOption && !this._isSearching
|
||||
? html`
|
||||
<uui-button
|
||||
class=${!this.value.icon ? 'selected' : ''}
|
||||
label=${this.localize.term('defaultdialogs_noIcon')}
|
||||
title=${this.localize.term('defaultdialogs_noIcon')}
|
||||
@click=${this.#clearIcon}
|
||||
@keyup=${(e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') this.#clearIcon();
|
||||
}}>
|
||||
<uui-icon style="opacity:.35" name=${ifDefined(this.data?.placeholder)}></uui-icon>
|
||||
</uui-button>
|
||||
`
|
||||
: nothing}
|
||||
${this.renderIcons()}</uui-scroll-container
|
||||
>
|
||||
</div>
|
||||
<uui-button
|
||||
|
||||
@@ -2,6 +2,7 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export interface UmbIconPickerModalData {
|
||||
placeholder?: string;
|
||||
showEmptyOption?: boolean;
|
||||
}
|
||||
|
||||
export interface UmbIconPickerModalValue {
|
||||
|
||||
@@ -9,28 +9,45 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { extractUmbColorVariable } from '@umbraco-cms/backoffice/resources';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-icon-picker
|
||||
*/
|
||||
@customElement('umb-property-editor-ui-icon-picker')
|
||||
export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
|
||||
//
|
||||
export class UmbPropertyEditorUIIconPickerElement
|
||||
extends UmbFormControlMixin<string, typeof UmbLitElement, undefined>(UmbLitElement, undefined)
|
||||
implements UmbPropertyEditorUiElement
|
||||
{
|
||||
@property({ type: Boolean })
|
||||
mandatory = false;
|
||||
|
||||
protected override firstUpdated(): void {
|
||||
this.addValidator(
|
||||
'valueMissing',
|
||||
() => 'Icon is required',
|
||||
() => this.mandatory && !this._icon,
|
||||
);
|
||||
}
|
||||
|
||||
@property()
|
||||
public set value(v: string) {
|
||||
this._value = v ?? '';
|
||||
const parts = this._value.split(' ');
|
||||
public override set value(v: string) {
|
||||
const val = v ?? '';
|
||||
super.value = val;
|
||||
|
||||
const parts = val.split(' ');
|
||||
if (parts.length === 2) {
|
||||
this._icon = parts[0];
|
||||
this._color = parts[1].replace('color-', '');
|
||||
} else {
|
||||
this._icon = this._value;
|
||||
this._icon = val;
|
||||
this._color = '';
|
||||
}
|
||||
}
|
||||
public get value() {
|
||||
return this._value;
|
||||
|
||||
public override get value() {
|
||||
return (super.value as string) ?? '';
|
||||
}
|
||||
private _value = '';
|
||||
|
||||
@state()
|
||||
private _icon = '';
|
||||
@@ -53,7 +70,7 @@ export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implemen
|
||||
icon: this._icon,
|
||||
color: this._color,
|
||||
},
|
||||
data: { placeholder: this._placeholderIcon },
|
||||
data: { placeholder: this._placeholderIcon, showEmptyOption: !this.mandatory },
|
||||
}).catch(() => undefined);
|
||||
|
||||
if (!data) return;
|
||||
|
||||
Reference in New Issue
Block a user