add property editor picker

This commit is contained in:
Mads Rasmussen
2022-09-19 09:58:14 +02:00
parent ca7bb6dc51
commit 2e1d93bae4
12 changed files with 419 additions and 76 deletions

View File

@@ -544,6 +544,10 @@ components:
MetaPropertyEditorUI: MetaPropertyEditorUI:
type: object type: object
properties: properties:
propertyEditors:
type: array
items:
type: string
icon: icon:
type: string type: string
group: group:
@@ -560,6 +564,7 @@ components:
defaultConfig: defaultConfig:
type: object type: object
required: required:
- propertyEditors
- icon - icon
- group - group
IManifestPropertyEditorUI: IManifestPropertyEditorUI:

View File

@@ -174,6 +174,7 @@ export interface components {
view: string; view: string;
}; };
MetaPropertyEditorUI: { MetaPropertyEditorUI: {
propertyEditors: string[];
icon: string; icon: string;
group: string; group: string;
prevalues?: { prevalues?: {

View File

@@ -11,6 +11,7 @@ export class UmbDataTypeContext {
hasChildren: false, hasChildren: false,
parentKey: '', parentKey: '',
isTrashed: false, isTrashed: false,
propertyEditorAlias: '',
propertyEditorUIAlias: '', propertyEditorUIAlias: '',
}); });
public readonly data: Observable<DataTypeEntity> = this._data.asObservable(); public readonly data: Observable<DataTypeEntity> = this._data.asObservable();

View File

@@ -1,16 +1,17 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit'; import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js'; import { customElement, state } from 'lit/decorators.js';
import { Subscription, distinctUntilChanged } from 'rxjs'; import { when } from 'lit-html/directives/when.js';
import { ifDefined } from 'lit-html/directives/if-defined.js'; import { Subscription, distinctUntilChanged, map } from 'rxjs';
import { UmbModalService } from '../../../../../core/services/modal'; import { UmbModalService } from '../../../../../core/services/modal';
import { UmbContextConsumerMixin } from '../../../../../core/context'; import { UmbContextConsumerMixin } from '../../../../../core/context';
import type { ManifestPropertyEditorUI } from '../../../../../core/models';
import { UmbDataTypeContext } from '../../data-type.context'; import { UmbDataTypeContext } from '../../data-type.context';
import type { DataTypeEntity } from '../../../../../mocks/data/data-type.data'; import type { DataTypeEntity } from '../../../../../mocks/data/data-type.data';
import type { UmbExtensionRegistry } from '../../../../../core/extension'; import type { UmbExtensionRegistry } from '../../../../../core/extension';
import type { UmbPropertyEditorStore } from '../../../../../core/stores/property-editor.store';
import type { ManifestPropertyEditorUI } from '../../../../../core/models';
@customElement('umb-editor-view-data-type-edit') @customElement('umb-editor-view-data-type-edit')
export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(LitElement) { export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(LitElement) {
static styles = [UUITextStyles, css``]; static styles = [UUITextStyles, css``];
@@ -19,25 +20,55 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li
_dataType?: DataTypeEntity; _dataType?: DataTypeEntity;
@state() @state()
private _propertyEditorUIs: Array<ManifestPropertyEditorUI> = []; private _propertyEditorIcon = '';
@state()
private _propertyEditorName = '';
@state()
private _propertyEditorAlias = '';
@state()
private _propertyEditorUIIcon = '';
@state()
private _propertyEditorUIName = '';
@state()
private _propertyEditorUIAlias = '';
private _extensionRegistry?: UmbExtensionRegistry;
private _dataTypeContext?: UmbDataTypeContext; private _dataTypeContext?: UmbDataTypeContext;
private _extensionRegistry?: UmbExtensionRegistry;
private _propertyEditorStore?: UmbPropertyEditorStore;
private _dataTypeSubscription?: Subscription; private _dataTypeSubscription?: Subscription;
private _propertyEditorSubscription?: Subscription;
private _propertyEditorUISubscription?: Subscription;
private _availablePropertyEditorUIsSubscription?: Subscription;
private _modalService?: UmbModalService; private _modalService?: UmbModalService;
constructor() { constructor() {
super(); super();
this.consumeContext('umbModalService', (modalService) => {
this._modalService = modalService;
});
// TODO: wait for more contexts
this.consumeContext('umbDataTypeContext', (dataTypeContext) => { this.consumeContext('umbDataTypeContext', (dataTypeContext) => {
this._dataTypeContext = dataTypeContext; this._dataTypeContext = dataTypeContext;
this._observeDataType(); this._observeDataType();
}); });
this.consumeContext('umbModalService', (modalService) => { this.consumeContext('umbPropertyEditorStore', (propertyEditorStore) => {
this._modalService = modalService; this._propertyEditorStore = propertyEditorStore;
this._observeDataType();
});
this.consumeContext('umbExtensionRegistry', (extensionRegistry) => {
this._extensionRegistry = extensionRegistry;
this._observeDataType();
}); });
} }
@@ -48,6 +79,61 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li
.pipe(distinctUntilChanged()) .pipe(distinctUntilChanged())
.subscribe((dataType: DataTypeEntity) => { .subscribe((dataType: DataTypeEntity) => {
this._dataType = dataType; this._dataType = dataType;
if (!this._dataType) return;
this._observePropertyEditor(this._dataType.propertyEditorAlias);
this._observeAvailablePropertyEditorUIs(this._dataType.propertyEditorAlias);
this._observePropertyEditorUI(this._dataType.propertyEditorUIAlias);
});
}
private _observePropertyEditor(propertyEditorAlias: string) {
if (!propertyEditorAlias) return;
this._propertyEditorSubscription?.unsubscribe();
this._propertyEditorSubscription = this._propertyEditorStore
?.getByAlias(propertyEditorAlias)
.subscribe((propertyEditor) => {
this._propertyEditorName = propertyEditor?.name ?? '';
this._propertyEditorAlias = propertyEditor?.alias ?? '';
this._propertyEditorIcon = propertyEditor?.icon ?? '';
});
}
private _observeAvailablePropertyEditorUIs(propertyEditorAlias: string) {
if (!propertyEditorAlias) return;
this._availablePropertyEditorUIsSubscription?.unsubscribe();
this._availablePropertyEditorUIsSubscription = this._extensionRegistry
?.extensionsOfType('propertyEditorUI')
.pipe(
map((propertyEditorUIs) =>
propertyEditorUIs.filter((propertyEditorUI) =>
propertyEditorUI?.meta?.propertyEditors?.includes(propertyEditorAlias)
)
)
)
.subscribe((availablePropertyEditorUIs) => {
if (availablePropertyEditorUIs?.length === 1) {
this._selectPropertyEditorUI(availablePropertyEditorUIs[0].alias);
}
});
}
private _observePropertyEditorUI(propertyEditorUIAlias: string) {
if (!propertyEditorUIAlias) return;
this._propertyEditorUISubscription?.unsubscribe();
this._propertyEditorSubscription = this._extensionRegistry
?.getByAlias<ManifestPropertyEditorUI>(propertyEditorUIAlias)
.subscribe((propertyEditorUI) => {
this._propertyEditorUIName = propertyEditorUI?.name ?? '';
this._propertyEditorUIAlias = propertyEditorUI?.alias ?? '';
this._propertyEditorUIIcon = propertyEditorUI?.meta?.icon ?? '';
}); });
} }
@@ -58,14 +144,20 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li
const modalHandler = this._modalService?.propertyEditorPicker({ selection }); const modalHandler = this._modalService?.propertyEditorPicker({ selection });
modalHandler?.onClose().then((returnValue) => { modalHandler?.onClose().then((returnValue) => {
if (!this._dataType || !returnValue.selection) return; if (!returnValue.selection) return;
const propertyEditorAlias = returnValue.selection[0]; const propertyEditorAlias = returnValue.selection[0];
this._dataType.propertyEditorAlias = propertyEditorAlias; this._selectPropertyEditor(propertyEditorAlias);
this._dataTypeContext?.update({ propertyEditorAlias });
}); });
} }
private _selectPropertyEditor(propertyEditorAlias: string) {
if (!this._dataType) return;
this._dataType.propertyEditorAlias = propertyEditorAlias;
this._dataTypeContext?.update({ propertyEditorAlias });
}
private _openPropertyEditorUIPicker() { private _openPropertyEditorUIPicker() {
if (!this._dataType) return; if (!this._dataType) return;
@@ -73,38 +165,81 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li
const modalHandler = this._modalService?.propertyEditorUIPicker({ selection }); const modalHandler = this._modalService?.propertyEditorUIPicker({ selection });
modalHandler?.onClose().then((returnValue) => { modalHandler?.onClose().then((returnValue) => {
if (!this._dataType || !returnValue.selection) return; if (!returnValue.selection) return;
const propertyEditorUIAlias = returnValue.selection[0]; const propertyEditorUIAlias = returnValue.selection[0];
this._dataType.propertyEditorUIAlias = propertyEditorUIAlias; this._selectPropertyEditorUI(propertyEditorUIAlias);
this._dataTypeContext?.update({ propertyEditorUIAlias });
}); });
} }
private _selectPropertyEditorUI(propertyEditorUIAlias: string) {
if (!this._dataType) return;
this._dataType.propertyEditorUIAlias = propertyEditorUIAlias;
this._dataTypeContext?.update({ propertyEditorUIAlias });
}
disconnectedCallback(): void { disconnectedCallback(): void {
super.disconnectedCallback(); super.disconnectedCallback();
this._dataTypeSubscription?.unsubscribe(); this._dataTypeSubscription?.unsubscribe();
this._propertyEditorSubscription?.unsubscribe();
this._propertyEditorUISubscription?.unsubscribe();
this._availablePropertyEditorUIsSubscription?.unsubscribe();
} }
render() { render() {
return html` return html`
<uui-box> <uui-box>
<h3>Property Editor</h3> ${this._renderPropertyEditor()}
<!-- TODO: border is a bit weird attribute name. Maybe single or standalone would be better? --> ${when(this._dataType?.propertyEditorAlias, () => html` ${this._renderPropertyEditorUI()} `)}</uui-box
<umb-ref-property-editor alias="${ifDefined(this._dataType?.propertyEditorAlias)}" border> >
<uui-action-bar slot="actions"> `;
<uui-button label="Change" @click=${this._openPropertyEditorPicker}></uui-button> }
</uui-action-bar>
</umb-ref-property-editor>
<h3>Property Editor UI</h3> private _renderPropertyEditor() {
<!-- TODO: border is a bit weird attribute name. Maybe single or standalone would be better? --> return html`
<umb-ref-property-editor-ui alias="${ifDefined(this._dataType?.propertyEditorUIAlias)}" border> <h3>Property Editor</h3>
<uui-action-bar slot="actions">
<uui-button label="Change" @click=${this._openPropertyEditorUIPicker}></uui-button> ${this._dataType?.propertyEditorAlias
</uui-action-bar> ? html`
</umb-ref-property-editor-ui> <!-- TODO: border is a bit weird attribute name. Maybe single or standalone would be better? -->
</uui-box> <umb-ref-property-editor .name=${this._propertyEditorName} .alias=${this._propertyEditorAlias} border>
<uui-icon name="${this._propertyEditorIcon}" slot="icon"></uui-icon>
<uui-action-bar slot="actions">
<uui-button label="Change" @click=${this._openPropertyEditorPicker}></uui-button>
</uui-action-bar>
</umb-ref-property-editor>
`
: html`<uui-button
label="Select Property Editor"
look="placeholder"
color="default"
@click=${this._openPropertyEditorPicker}></uui-button>`}
`;
}
private _renderPropertyEditorUI() {
return html`
<h3>Property Editor UI</h3>
${this._dataType?.propertyEditorUIAlias
? html`
<!-- TODO: border is a bit weird attribute name. Maybe single or standalone would be better? -->
<umb-ref-property-editor-ui
.name=${this._propertyEditorUIName}
.alias=${this._propertyEditorUIAlias}
border>
<uui-icon name="${this._propertyEditorUIIcon}" slot="icon"></uui-icon>
<uui-action-bar slot="actions">
<uui-button label="Change" @click=${this._openPropertyEditorUIPicker}></uui-button>
</uui-action-bar>
</umb-ref-property-editor-ui>
`
: html`<uui-button
label="Select Property Editor UI"
look="placeholder"
color="default"
@click=${this._openPropertyEditorUIPicker}></uui-button>`}
`; `;
} }
} }

View File

@@ -1,4 +1,5 @@
import { css, html, LitElement } from 'lit'; import { css, html, LitElement } from 'lit';
import { repeat } from 'lit/directives/repeat.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { UmbContextConsumerMixin } from '../../../../context'; import { UmbContextConsumerMixin } from '../../../../context';
@@ -6,15 +7,76 @@ import { UmbContextConsumerMixin } from '../../../../context';
import type { Subscription } from 'rxjs'; import type { Subscription } from 'rxjs';
import type { UmbModalHandler } from '../../modal-handler'; import type { UmbModalHandler } from '../../modal-handler';
import type { PropertyEditor } from '../../../../../mocks/data/property-editor.data'; import type { PropertyEditor } from '../../../../../mocks/data/property-editor.data';
import { UmbPropertyEditorStore } from '../../../../stores/property-editor.store'; import type { UmbPropertyEditorStore } from '../../../../stores/property-editor.store';
import { UUIInputEvent } from '@umbraco-ui/uui';
export interface UmbModalPropertyEditorPickerData { export interface UmbModalPropertyEditorPickerData {
selection?: Array<string>; selection?: Array<string>;
multiple?: boolean;
submitLabel?: string;
} }
@customElement('umb-modal-layout-property-editor-picker') @customElement('umb-modal-layout-property-editor-picker')
export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsumerMixin(LitElement) { export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsumerMixin(LitElement) {
static styles = [UUITextStyles, css``]; static styles = [
UUITextStyles,
css`
#filter {
width: 100%;
margin-bottom: var(--uui-size-space-4);
}
#filter-icon {
padding-left: var(--uui-size-space-2);
}
#item-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
margin: 0;
padding: 0;
grid-gap: var(--uui-size-space-4);
}
#item-grid .item {
display: flex;
align-items: flex-start;
justify-content: center;
list-style: none;
height: 100%;
border: 1px solid transparent;
}
#item-grid .item:hover {
background: whitesmoke;
cursor: pointer;
}
#item-grid .item[selected] button {
background: var(--uui-color-selected);
color: var(--uui-color-selected-contrast);
}
#item-grid .item button {
background: none;
border: none;
cursor: pointer;
padding: var(--uui-size-space-3);
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
font-size: 0.8rem;
height: 100%;
width: 100%;
}
#item-grid .item .icon {
font-size: 2em;
margin-bottom: var(--uui-size-space-2);
}
`,
];
@property({ attribute: false }) @property({ attribute: false })
modalHandler?: UmbModalHandler; modalHandler?: UmbModalHandler;
@@ -23,10 +85,15 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume
data?: UmbModalPropertyEditorPickerData; data?: UmbModalPropertyEditorPickerData;
@state() @state()
private _propertyEditors: Array<PropertyEditor> = []; private _filteredPropertyEditors: Array<PropertyEditor> = [];
@state() @state()
private _selection?: Array<string>; private _selection: Array<string> = [];
@state()
private _submitLabel = 'Select';
private _propertyEditors: Array<PropertyEditor> = [];
private _propertyEditorStore?: UmbPropertyEditorStore; private _propertyEditorStore?: UmbPropertyEditorStore;
private _propertyEditorsSubscription?: Subscription; private _propertyEditorsSubscription?: Subscription;
@@ -42,17 +109,52 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume
connectedCallback(): void { connectedCallback(): void {
super.connectedCallback(); super.connectedCallback();
this._selection = this.data?.selection || []; this._selection = this.data?.selection ?? [];
this._submitLabel = this.data?.submitLabel ?? this._submitLabel;
} }
private _observePropertyEditors() { private _observePropertyEditors() {
this._propertyEditorsSubscription = this._propertyEditorStore?.getAll().subscribe((propertyEditors) => { this._propertyEditorsSubscription = this._propertyEditorStore?.getAll().subscribe((propertyEditors) => {
this._propertyEditors = propertyEditors; this._propertyEditors = propertyEditors;
this._filteredPropertyEditors = propertyEditors;
}); });
} }
private _handleClick(propertyEditor: PropertyEditor) {
if (this.data?.multiple) {
this._multiSelect(propertyEditor.alias);
} else {
this._select(propertyEditor.alias);
}
}
private _select(alias: string) {
this._selection = [alias];
}
private _multiSelect(alias: string) {
if (this._selection?.includes(alias)) {
this._selection = this._selection.filter((item) => item !== alias);
} else {
this._selection = [...this._selection, alias];
}
}
private _handleFilterInput(event: UUIInputEvent) {
let query = (event.target.value as string) || '';
query = query.toLowerCase();
this._filteredPropertyEditors = !query
? this._propertyEditors
: this._propertyEditors.filter((propertyEditor) => {
return (
propertyEditor.name.toLowerCase().includes(query) || propertyEditor.alias.toLowerCase().includes(query)
);
});
}
private _close() { private _close() {
this.modalHandler?.close({ selection: this._selection }); this.modalHandler?.close();
} }
private _submit() { private _submit() {
@@ -67,14 +169,39 @@ export class UmbModalLayoutPropertyEditorPickerElement extends UmbContextConsume
render() { render() {
return html` return html`
<umb-editor-entity-layout headline="Select Property Editor UI"> <umb-editor-entity-layout headline="Select Property Editor UI">
<uui-box>${this._propertyEditors.map((propertyEditor) => html`<div>${propertyEditor.name}</div>`)}</uui-box> <uui-box> ${this._renderFilter()} ${this._renderGrid()} </uui-box>
<div slot="actions"> <div slot="actions">
<uui-button label="Close" @click=${this._close}></uui-button> <uui-button label="Close" @click=${this._close}></uui-button>
<uui-button label="Submit" look="primary" color="positive" @click=${this._submit}></uui-button> <uui-button label="${this._submitLabel}" look="primary" color="positive" @click=${this._submit}></uui-button>
</div> </div>
</umb-editor-entity-layout> </umb-editor-entity-layout>
`; `;
} }
private _renderFilter() {
return html` <uui-input
id="filter"
@input="${this._handleFilterInput}"
placeholder="Type to filter..."
label="Type to filter icons">
<uui-icon name="search" slot="prepend" id="filter-icon"></uui-icon>
</uui-input>`;
}
private _renderGrid() {
return html`<ul id="item-grid">
${repeat(
this._filteredPropertyEditors,
(propertyEditor) => propertyEditor.alias,
(propertyEditor) => html` <li class="item" ?selected=${this._selection.includes(propertyEditor.alias)}>
<button type="button" @click="${() => this._handleClick(propertyEditor)}">
<uui-icon name="document" class="icon"></uui-icon>
${propertyEditor.name}
</button>
</li>`
)}
</ul>`;
}
} }
declare global { declare global {

View File

@@ -1,4 +1,4 @@
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, map, Observable } from 'rxjs';
import { PropertyEditor } from '../../mocks/data/property-editor.data'; import { PropertyEditor } from '../../mocks/data/property-editor.data';
export class UmbPropertyEditorStore { export class UmbPropertyEditorStore {
@@ -16,4 +16,48 @@ export class UmbPropertyEditorStore {
return this.items; return this.items;
} }
getByAlias(alias: string): Observable<PropertyEditor | undefined> {
// TODO: use Fetcher API.
// TODO: only fetch if the data type is not in the store?
fetch(`/umbraco/backoffice/property-editors/${alias}`)
.then((res) => res.json())
.then((data) => {
this.update(data);
});
return this.items.pipe(map((items) => items.find((item) => item.alias === alias)));
}
public update(updatedItems: Array<PropertyEditor>) {
const storedItems = this._items.getValue();
const updated: PropertyEditor[] = [...storedItems];
updatedItems.forEach((updatedItem) => {
const index = storedItems.map((storedItem) => storedItem.alias).indexOf(updatedItem.alias);
if (index !== -1) {
const itemKeys = Object.keys(storedItems[index]);
const newItem = {};
for (const [key] of Object.entries(updatedItem)) {
if (itemKeys.indexOf(key) !== -1) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
newItem[key] = updatedItem[key];
}
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
updated[index] = newItem;
} else {
// If the node is not in the store, add it
updated.push(updatedItem);
}
});
this._items.next([...updated]);
}
} }

View File

@@ -16,8 +16,10 @@ export const data: Array<DataTypeEntity> = [
isTrashed: false, isTrashed: false,
hasChildren: false, hasChildren: false,
icon: '', icon: '',
propertyEditorAlias: 'Umb.PropertyEditor.Text', propertyEditorAlias: '',
propertyEditorUIAlias: 'Umb.PropertyEditorUI.Text', propertyEditorUIAlias: '',
//propertyEditorAlias: 'Umbraco.TextBox',
//propertyEditorUIAlias: 'Umb.PropertyEditorUI.Text',
}, },
{ {
key: 'dt-2', key: 'dt-2',
@@ -27,7 +29,7 @@ export const data: Array<DataTypeEntity> = [
isTrashed: false, isTrashed: false,
hasChildren: false, hasChildren: false,
icon: '', icon: '',
propertyEditorAlias: 'Umb.PropertyEditor.Textarea', propertyEditorAlias: 'Umbraco.TextArea',
propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea', propertyEditorUIAlias: 'Umb.PropertyEditorUI.Textarea',
}, },
{ {
@@ -38,7 +40,7 @@ export const data: Array<DataTypeEntity> = [
isTrashed: false, isTrashed: false,
hasChildren: false, hasChildren: false,
icon: '', icon: '',
propertyEditorAlias: 'Umb.PropertyEditor.Custom', propertyEditorAlias: 'Umbraco.Custom',
propertyEditorUIAlias: 'My.PropertyEditorUI.Custom', propertyEditorUIAlias: 'My.PropertyEditorUI.Custom',
}, },
{ {
@@ -49,7 +51,7 @@ export const data: Array<DataTypeEntity> = [
isTrashed: false, isTrashed: false,
hasChildren: false, hasChildren: false,
icon: '', icon: '',
propertyEditorAlias: 'Umb.PropertyEditor.ContextExample', propertyEditorAlias: 'Umbraco.Custom',
propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContextExample', propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContextExample',
}, },
{ {
@@ -60,7 +62,7 @@ export const data: Array<DataTypeEntity> = [
isTrashed: false, isTrashed: false,
hasChildren: false, hasChildren: false,
icon: '', icon: '',
propertyEditorAlias: 'Umb.PropertyEditor.ContentPicker', propertyEditorAlias: 'Umbraco.ContentPicker',
propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContentPicker', propertyEditorUIAlias: 'Umb.PropertyEditorUI.ContentPicker',
}, },
]; ];

View File

@@ -15,7 +15,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.BlockGrid', alias: 'Umbraco.BlockGrid',
name: 'Block Grid', name: 'Block Grid',
icon: 'icon-thumbnail-list', icon: 'umb:thumbnail-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -23,7 +23,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.BlockList', alias: 'Umbraco.BlockList',
name: 'Block List', name: 'Block List',
icon: 'icon-thumbnail-list', icon: 'umb:thumbnail-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -31,7 +31,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.CheckBoxList', alias: 'Umbraco.CheckBoxList',
name: 'Checkbox list', name: 'Checkbox list',
icon: 'icon-bulleted-list', icon: 'umb:bulleted-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -39,7 +39,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.ColorPicker', alias: 'Umbraco.ColorPicker',
name: 'Color Picker', name: 'Color Picker',
icon: 'icon-colorpicker', icon: 'umb:colorpicker',
editor: { editor: {
view: '', view: '',
}, },
@@ -47,7 +47,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.ContentPicker', alias: 'Umbraco.ContentPicker',
name: 'Content Picker', name: 'Content Picker',
icon: 'icon-autofill', icon: 'umb:autofill',
editor: { editor: {
view: '', view: '',
}, },
@@ -55,7 +55,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.DateTime', alias: 'Umbraco.DateTime',
name: 'Date/Time', name: 'Date/Time',
icon: 'icon-time', icon: 'umb:time',
editor: { editor: {
view: '', view: '',
}, },
@@ -63,7 +63,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Decimal', alias: 'Umbraco.Decimal',
name: 'Decimal', name: 'Decimal',
icon: 'icon-autofill', icon: 'umb:autofill',
editor: { editor: {
view: '', view: '',
}, },
@@ -71,7 +71,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.DropDown.Flexible', alias: 'Umbraco.DropDown.Flexible',
name: 'Dropdown', name: 'Dropdown',
icon: 'icon-indent', icon: 'umb:indent',
editor: { editor: {
view: '', view: '',
}, },
@@ -79,7 +79,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.EmailAddress', alias: 'Umbraco.EmailAddress',
name: 'Email address', name: 'Email address',
icon: 'icon-message', icon: 'umb:message',
editor: { editor: {
view: '', view: '',
}, },
@@ -87,7 +87,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.ColorPicker.EyeDropper', alias: 'Umbraco.ColorPicker.EyeDropper',
name: 'Eye Dropper Color Picker', name: 'Eye Dropper Color Picker',
icon: 'icon-colorpicker', icon: 'umb:colorpicker',
editor: { editor: {
view: '', view: '',
}, },
@@ -95,7 +95,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.UploadField', alias: 'Umbraco.UploadField',
name: 'File upload', name: 'File upload',
icon: 'icon-download-alt', icon: 'umb:download-alt',
editor: { editor: {
view: '', view: '',
}, },
@@ -103,7 +103,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Grid', alias: 'Umbraco.Grid',
name: 'Grid layout', name: 'Grid layout',
icon: 'icon-layout', icon: 'umb:layout',
editor: { editor: {
view: '', view: '',
}, },
@@ -111,7 +111,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.ImageCropper', alias: 'Umbraco.ImageCropper',
name: 'Image Cropper', name: 'Image Cropper',
icon: 'icon-crop', icon: 'umb:crop',
editor: { editor: {
view: '', view: '',
}, },
@@ -119,7 +119,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Label', alias: 'Umbraco.Label',
name: 'Label', name: 'Label',
icon: 'icon-readonly', icon: 'umb:readonly',
editor: { editor: {
view: '', view: '',
}, },
@@ -127,7 +127,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.ListView', alias: 'Umbraco.ListView',
name: 'List view', name: 'List view',
icon: 'icon-thumbnail-list', icon: 'umb:thumbnail-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -135,7 +135,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MarkdownEditor', alias: 'Umbraco.MarkdownEditor',
name: 'Markdown editor', name: 'Markdown editor',
icon: 'icon-code', icon: 'umb:code',
editor: { editor: {
view: '', view: '',
}, },
@@ -143,7 +143,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MediaPicker3', alias: 'Umbraco.MediaPicker3',
name: 'Media Picker', name: 'Media Picker',
icon: 'icon-picture', icon: 'umb:picture',
editor: { editor: {
view: '', view: '',
}, },
@@ -151,7 +151,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MediaPicker', alias: 'Umbraco.MediaPicker',
name: 'Media Picker (legacy)', name: 'Media Picker (legacy)',
icon: 'icon-picture', icon: 'umb:picture',
editor: { editor: {
view: '', view: '',
}, },
@@ -159,7 +159,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MemberGroupPicker', alias: 'Umbraco.MemberGroupPicker',
name: 'Member Group Picker', name: 'Member Group Picker',
icon: 'icon-users-alt', icon: 'umb:users-alt',
editor: { editor: {
view: '', view: '',
}, },
@@ -167,7 +167,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MemberPicker', alias: 'Umbraco.MemberPicker',
name: 'Member Picker', name: 'Member Picker',
icon: 'icon-user', icon: 'umb:user',
editor: { editor: {
view: '', view: '',
}, },
@@ -175,7 +175,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MultiUrlPicker', alias: 'Umbraco.MultiUrlPicker',
name: 'Multi URL Picker', name: 'Multi URL Picker',
icon: 'icon-link', icon: 'umb:link',
editor: { editor: {
view: '', view: '',
}, },
@@ -183,7 +183,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MultiNodeTreePicker', alias: 'Umbraco.MultiNodeTreePicker',
name: 'Multinode Treepicker', name: 'Multinode Treepicker',
icon: 'icon-page-add', icon: 'umb:page-add',
editor: { editor: {
view: '', view: '',
}, },
@@ -191,7 +191,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.NestedContent', alias: 'Umbraco.NestedContent',
name: 'Nested Content', name: 'Nested Content',
icon: 'icon-thumbnail-list', icon: 'umb:thumbnail-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -199,7 +199,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Integer', alias: 'Umbraco.Integer',
name: 'Numeric', name: 'Numeric',
icon: 'icon-autofill', icon: 'umb:autofill',
editor: { editor: {
view: '', view: '',
}, },
@@ -207,7 +207,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.RadioButtonList', alias: 'Umbraco.RadioButtonList',
name: 'Radio button list', name: 'Radio button list',
icon: 'icon-target', icon: 'umb:target',
editor: { editor: {
view: '', view: '',
}, },
@@ -215,7 +215,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.MultipleTextstring', alias: 'Umbraco.MultipleTextstring',
name: 'Repeatable textstrings', name: 'Repeatable textstrings',
icon: 'icon-ordered-list', icon: 'umb:ordered-list',
editor: { editor: {
view: '', view: '',
}, },
@@ -223,7 +223,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.TinyMCE', alias: 'Umbraco.TinyMCE',
name: 'Rich Text Editor', name: 'Rich Text Editor',
icon: 'icon-browser-window', icon: 'umb:browser-window',
editor: { editor: {
view: '', view: '',
}, },
@@ -231,7 +231,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Slider', alias: 'Umbraco.Slider',
name: 'Slider', name: 'Slider',
icon: 'icon-navigation-horizontal', icon: 'umb:navigation-horizontal',
editor: { editor: {
view: '', view: '',
}, },
@@ -239,7 +239,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.Tags', alias: 'Umbraco.Tags',
name: 'Tags', name: 'Tags',
icon: 'icon-tags', icon: 'umb:tags',
editor: { editor: {
view: '', view: '',
}, },
@@ -247,7 +247,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.TextArea', alias: 'Umbraco.TextArea',
name: 'Textarea', name: 'Textarea',
icon: 'icon-application-window-alt', icon: 'umb:application-window-alt',
editor: { editor: {
view: '', view: '',
}, },
@@ -255,7 +255,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.TextBox', alias: 'Umbraco.TextBox',
name: 'Textbox', name: 'Textbox',
icon: 'icon-autofill', icon: 'umb:autofill',
editor: { editor: {
view: '', view: '',
}, },
@@ -263,7 +263,7 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.TrueFalse', alias: 'Umbraco.TrueFalse',
name: 'Toggle', name: 'Toggle',
icon: 'icon-checkbox', icon: 'umb:checkbox',
editor: { editor: {
view: '', view: '',
}, },
@@ -271,7 +271,15 @@ export const data: Array<PropertyEditor> = [
{ {
alias: 'Umbraco.UserPicker', alias: 'Umbraco.UserPicker',
name: 'User Picker', name: 'User Picker',
icon: 'icon-user', icon: 'umb:user',
editor: {
view: '',
},
},
{
alias: 'Umbraco.Custom',
name: 'Custom Property Editor',
icon: 'umb:document',
editor: { editor: {
view: '', view: '',
}, },
@@ -287,6 +295,10 @@ class UmbPropertyEditorData extends UmbData<PropertyEditor> {
getAll() { getAll() {
return this.data; return this.data;
} }
getByAlias(alias: string) {
return this.data.find((x) => x.alias === alias);
}
} }
export const umbPropertyEditorData = new UmbPropertyEditorData(); export const umbPropertyEditorData = new UmbPropertyEditorData();

View File

@@ -30,6 +30,7 @@ export const manifestDevelopmentHandler = rest.get(umbracoPath('/manifests'), (_
meta: { meta: {
icon: 'document', icon: 'document',
group: 'common', group: 'common',
propertyEditors: ['Umbraco.Custom'],
}, },
}, },
{ {

View File

@@ -9,4 +9,14 @@ export const handlers = [
return res(ctx.status(200), ctx.json(propertyEditors)); return res(ctx.status(200), ctx.json(propertyEditors));
}), }),
rest.get('/umbraco/backoffice/property-editors/:alias', (req, res, ctx) => {
console.warn('Please move to schema');
const alias = req.params.alias as string;
if (!alias) return;
const propertyEditor = umbPropertyEditorData.getByAlias(alias);
return res(ctx.status(200), ctx.json([propertyEditor]));
}),
]; ];

View File

@@ -138,6 +138,7 @@ export const internalManifests: Array<ManifestTypes & { loader: () => Promise<ob
meta: { meta: {
icon: 'edit', icon: 'edit',
group: 'common', group: 'common',
propertyEditors: ['Umbraco.TextBox'],
}, },
}, },
{ {
@@ -149,6 +150,7 @@ export const internalManifests: Array<ManifestTypes & { loader: () => Promise<ob
meta: { meta: {
icon: 'edit', icon: 'edit',
group: 'common', group: 'common',
propertyEditors: ['Umbraco.TextArea'],
}, },
}, },
{ {
@@ -159,6 +161,7 @@ export const internalManifests: Array<ManifestTypes & { loader: () => Promise<ob
meta: { meta: {
icon: 'favorite', icon: 'favorite',
group: 'common', group: 'common',
propertyEditors: ['Umbraco.Custom'],
}, },
}, },
{ {
@@ -294,6 +297,7 @@ export const internalManifests: Array<ManifestTypes & { loader: () => Promise<ob
elementName: 'umb-property-editor-content-picker', elementName: 'umb-property-editor-content-picker',
loader: () => import('./backoffice/property-editors/content-picker/property-editor-content-picker.element'), loader: () => import('./backoffice/property-editors/content-picker/property-editor-content-picker.element'),
meta: { meta: {
propertyEditors: ['Umbraco.ContentPicker'],
icon: 'document', icon: 'document',
group: 'common', group: 'common',
}, },

View File

@@ -113,6 +113,7 @@ export interface MetaTreeItemAction {
weight: number; weight: number;
} }
export interface MetaPropertyEditorUI extends IPrevalues { export interface MetaPropertyEditorUI extends IPrevalues {
propertyEditors: Array<string>;
icon: string; icon: string;
group: string; group: string;
} }